ecluse:ecluse-core
Safe HaskellNone
LanguageGHC2021

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

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.

npmPublishDocument Source #

Arguments

:: PackageName

The package being published.

-> Version

The version being published.

-> Text

The tarball's filename: the _attachments key and tarball file segment.

-> Maybe Text

The dist.integrity SRI string, if known (e.g. "sha512-…").

-> Maybe Text

The dist.shasum (SHA-1, hex), if known.

-> 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.