| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Ecluse.Core.Registry.Npm.Route
Contents
Description
The npm path grammar: the request router that maps an npm-native request path to a shared Ecluse.Core.Server.Route.
classify turns an npm request -- its HTTP method and the already-mount-stripped,
percent-decoded path segments -- into a Route, so the whole npm routing table is
unit-testable with no server: feed it a method and segments, assert the
Route. The agnostic dispatcher carries a route classifier per mount; this module
is npm's, wired in at the composition root.
A PUT /{pkg} is the npm publish request, so the method is part of the match:
a PUT over a bare-package path is a Publish, while every read method (GET,
HEAD, …) over the same path is a Packument. The read grammar below is otherwise
method-independent -- a HEAD classifies like its GET, the dispatcher answering it
bodiless.
The model is deny by default: anything not explicitly recognised is
Unsupported (a 404 at the edge). Three npm-specific facts shape the matching,
all from the protocol research (see docs/research/reverse-engineering/npm.md
§2 and §7):
- Reserved meta-routes (
/-/…) are matched first. A real package name can never begin with'-', so a leading"-"segment is unambiguously a meta-route; an unknown one isUnsupportedrather than a package. - Scoped names arrive in two encodings. The path is percent-decoded before it
reaches us, so a scoped name arrives either as one decoded segment
(
@scope/pkg) or as two (@scope,pkg). Both are normalised to the samePackageNamehere, so nothing downstream re-checks the encoding. - A tarball path is
/{pkg}/-/{file}.tgz. The interior"-"segment and the.tgzsuffix distinguish it from a packument request (/{pkg}); for a scoped package the basename drops the scope (@babel/code-frame→code-frame-7.0.0.tgz).classifyis the npm-side parse of the artifact coordinate: it checks thefile's basename is exactly{unscoped-name}-{rest}for the requested package and readsrestas the version (mkVersion, total), yieldingwith the file __preserved verbatim__. A basename that does not match the package is a path-confusion attempt and denies (deny by default), never a fabricated coordinate.Tarballname version (Filenamefile)
Mount dispatch / prefix-stripping and the liveness/readiness routes are handled
in the agnostic web layer (see docs/architecture/web-layer.md); classify
only ever sees the npm-native request, so it models exactly the Routes the
proxy serves.
Synopsis
Classification
classify :: Classifier Source #
Classify an npm-native request (its method and path) into a shared Route.
A PUT is the publish method, so it is dispatched first: a PUT over a
bare-package path is a Publish, everything else under PUT denies. Every other
method reads, taking the path through the read grammar where matching order is
significant -- reserved meta-routes (a leading "-" segment) are tried first, since
a real package name can never begin with '-'; only then is the path read as a
package request. See the module header for the npm conventions this encodes.