ecluse
Safe HaskellNone
LanguageGHC2021

Ecluse.Registry.Npm.Route

Description

The npm path grammar: the request router that maps an npm-native request path to a shared Ecluse.Server.Route.

classify turns an npm request path — 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 segments, assert the Route. The agnostic dispatcher carries a route classifier per mount; this module is npm's, wired in at the composition root.

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 is Unsupported rather 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 same PackageName here, so nothing downstream re-checks the encoding.
  • A tarball path is /{pkg}/-/{file}.tgz. The interior "-" segment and the .tgz suffix distinguish it from a packument request (/{pkg}); for a scoped package the basename drops the scope (@babel/code-framecode-frame-7.0.0.tgz). classify is the npm-side parse of the artifact coordinate: it checks the file's basename is exactly {unscoped-name}-{rest} for the requested package and reads rest as the version (mkVersion, total), yielding Tarball name version (Filename file) with 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.

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 path, so it models exactly the five Routes the proxy serves.

Synopsis

Classification

classify :: Classifier Source #

Classify an npm-native request path into a shared Route.

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.