| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Ecluse.Core.Registry.Npm.Publish
Description
The npm publish-document schema: the mirror-write side (document assembly,
request shaping, and the codec that carries them into the shared publish transport)
and the read side (declaredNames, the identity names the ecosystem-neutral publish
pipeline's anti-shadowing guard reads from a first-party publish body).
Everything here is pure. npmPublishCodec is npm's
PublishCodec: the composition root marries it to
the shared transport (newMirrorPublish), which
executes what this module forms. The first-party publish relay (a different
concern: a client's own document forwarded verbatim) lives in
Ecluse.Core.Registry.Npm.
Synopsis
- npmPublishCodec :: PublishCodec
- publishRequest :: Text -> Maybe Secret -> PackageName -> ByteString -> Either UrlFormationError Request
- npmPublishDocument :: PackageName -> Version -> Text -> Maybe Text -> Maybe Text -> ByteString -> ByteString
- declaredNames :: LByteString -> [Text]
Documentation
npmPublishCodec :: PublishCodec Source #
npm's mirror-write protocol codec: the presence probe reads the abbreviated
packument and projects its version list; the publish assembles the
packument-fragment PUT (npmPublishDocument under publishRequest), with the
dist digests picked from the re-admitted artifact's verified set; and a 409
answer is idempotent success (versions are immutable, so an already-present
version is the write's goal already met).
publishRequest :: Text -> Maybe Secret -> PackageName -> ByteString -> Either UrlFormationError Request Source #
Build the publish PUT /{pkg} request: the body is the npm publish
document (a packument carrying the version manifest and the base64 tarball under
_attachments), already serialised by the caller. Carries the bearer token and a
Content-Type: application/json header.
Fails with a UrlFormationError only when the URL cannot be formed; a genuine
write fault (a non-2xx, non-409 status) is the PublishError that
publishArtifact reports.
Arguments
| :: PackageName | The package being published. |
| -> Version | The version being published. |
| -> Text | The tarball's filename: the |
| -> Maybe Text | The |
| -> Maybe Text | The |
| -> ByteString | The verified tarball bytes. |
| -> ByteString |
Assemble the npm publish document for one version from its verified tarball
bytes: the serialised body publishRequest (hence
publishArtifact) PUTs to /{pkg}.
The document is the npm PUT /{pkg} shape: the package name and a single-version
versions map carrying the version manifest (name, version, and a dist with
the integrity digests), dist-tags.latest pointed at that version, and the tarball
itself base64-encoded under _attachments with its byte length. A managed npm
registry (CodeArtifact, Artifact Registry, Verdaccio) recomputes the served
dist.tarball location from the attachment, so the location is not carried.
The integrity digests written into dist are the caller's: the worker passes
the serve-time-admitted digests it has already verified the bytes against: so the
published manifest's integrity matches exactly the bytes attached. The tarball
length is taken from the actual byte count, never a caller-declared size, so the
attachment can never disagree with its own bytes.
This is the inverse of the read-side decode in Ecluse.Core.Registry.Npm.Wire, which
deliberately does not model _attachments: it is constructed only here, for the
write.
declaredNames :: LByteString -> [Text] Source #
Every package name a first-party npm publish body declares as its own identity:
the top-level _id and name, and each versions.<v>.name. Only string-valued
name slots are read (a non-string slot is no name claim); a body that does not decode
to a JSON object declares no readable name (the empty list). The base64 _attachments
are never decoded.
This is the read-side inverse of npmPublishDocument, which assembles the same
_id/name/versions shape for the mirror write. The ecosystem-neutral publish
pipeline injects it as its adapter's declared-name extractor, so the anti-shadowing
body-name guard (issue #391) can refuse a crafted body that names a package the scope
guard never authorised without the neutral pipeline knowing npm's document schema.