Documentation menu

Reference

Registry and authentication client

Flog's internal registry client is shared by installation, package metadata maintenance, and publishing. It uses HTTP directly and never shells out to another package manager. The command reference lists the public metadata and authentication commands.

Configuration#

The client defaults to https://registry.npmjs.org/ and supports compatible .npmrc settings for:

  • registry;
  • @scope:registry;
  • _authToken;
  • //host/path/:_authToken;
  • ${ENVIRONMENT_VARIABLE} substitutions; and
  • NPM_CONFIG_USERCONFIG and NPM_CONFIG_REGISTRY environment overrides.

Registry selection precedence is the npm default, the user npmrc, the nearest project npmrc, NPM_CONFIG_REGISTRY, and finally an auth command's explicit --registry. NPM_CONFIG_USERCONFIG selects the user file; otherwise flog uses the platform user's .npmrc. Project configuration can explicitly override user registry or credential settings. Authentication is matched by host and the longest configured path prefix, preventing a token for one registry from being sent to another.

Bearer tokens are never included in request errors. Configuration and OTP values are redacted from diagnostics. Request errors omit URL user information, query strings, and fragments; web-auth completion URLs are never displayed. The login URL itself is intentionally displayed so the operator can complete authentication.

Login, identity, and logout#

Use the npm-compatible web authentication flow proactively:

flog login
flog whoami
flog logout

Each command accepts --registry <url>. login prints the safe browser URL, polls cancellably, validates the returned token through /-/whoami, and only then stores it. whoami always asks the registry to verify the selected credential; it does not merely report that configuration exists. logout removes only the exact selected host/path credential.

Login writes a host/path-scoped //host/path/:_authToken entry to the user npmrc, never the project npmrc. It preserves unrelated bytes, comments, ordering, and newline style, writes through a restrictive atomic replacement, and refuses unsafe files, duplicate matching entries, or an environment-backed matching token that cannot safely be replaced. Login also refuses to guess how an unscoped _authToken should be migrated. Symlinks in either the npmrc itself or any existing parent directory are rejected before reading or staging a credential. Non-canonical userconfig paths containing lexical . or .. traversal are also rejected so configuration reads and credential writes cannot resolve the selected path differently. Logout applies the same checks. Cancellation, denial, timeout, validation failure, and file errors leave the original npmrc unchanged.

Because project credentials take precedence over user credentials, login refuses to authenticate when the nearest project npmrc contains an exact or more-specific credential for the selected registry. Remove or update that project entry first, or run login outside the project. Flog never silently rewrites the project npmrc. Since browser authentication can take time, flog rechecks the project file after authentication and again around the user-file commit; a credential added while login is in progress prevents a successful login report.

Login also refuses a more-specific user credential below the selected registry path. Such an entry would continue to win longest-prefix selection for some requests (including nested registry endpoints), so the diagnostic identifies the scoped entry that must be removed or updated. Unrelated hosts and sibling paths remain untouched.

HTTP authentication is rejected by default. FLOG_ALLOW_HTTP=1 exists only for isolated local testing and must not be used for real credentials.

For CI, continue supplying a host/path-scoped npmrc token, commonly through a ${TOKEN} environment substitution. login is an interactive bootstrap flow and does not overwrite environment variables. Revoking a token at the registry is separate from flog logout, which only removes the local entry.

Redirects are handled explicitly rather than delegated to Go's default client. Every metadata, tarball, and polling redirect re-runs host/path credential selection for its destination, and HTTPS-to-HTTP downgrades are rejected. State-changing requests such as publication, deprecation, and login are never replayed across redirects, preventing bearer tokens, OTP values, or upload bodies from being silently forwarded to a different endpoint.

Reads and publishing#

Dependency resolution requests npm's abbreviated install metadata media type. flog view requests the full application/json representation so published fields omitted from install metadata remain queryable. Tarball reads support SHA-512/SHA-1 Subresource Integrity values and legacy hexadecimal SHA-1 shasums, using constant-time digest comparison. A mismatch is a typed integrity error and downloaded bytes are not returned.

Publication sends the caller's complete npm publication document with PUT. The document is retained for safe replay only when web authentication succeeds; publishing therefore consumes the exact artifact metadata prepared by the publisher rather than repacking.

Transport failures and HTTP registry rejections have separate error types and retryability decisions. OTP challenges return a typed error so callers can prompt securely and resubmit using the npm-otp header.

Querying published metadata#

flog view reads one top-level scalar field from a selected published version:

flog view package-name version
flog view @scope/package@next version
flog view package-name@1.2.3 version --json

An omitted selector uses the latest dist-tag. Explicit selectors may be exact versions or dist-tags; version ranges are intentionally rejected because a read-only metadata query should not imply dependency resolution. Plain output is exactly one string, number, boolean, or null followed by a newline. --json emits that same scalar as JSON, for example "1.2.3".

Fields are literal top-level keys in the selected version document. Nested paths and expression syntax are not supported. Missing packages, tags, versions, and fields are reported separately, as are malformed documents, authentication rejections, and transport failures. The command uses the normal registry and credential selection above, but never writes a manifest, flog.lock, cache, installation, credential, or registry resource.

Managing deprecation messages#

flog deprecate sets or clears the deprecation message for one exact published version:

flog deprecate package-name@1.2.3 --message "Use 2.x instead" --dry-run
flog deprecate package-name@1.2.3 --message "Use 2.x instead"
flog deprecate package-name@1.2.3 --clear

The package name and complete semantic version are mandatory. Omitted versions, dist-tags, and npm-style ranges are rejected, so one command cannot silently expand to additional releases. --message and --clear are mutually exclusive; the set message must be non-empty. --dry-run reads writable metadata and shows the exact intended change without a PUT. --json emits the report version, package, exact version, selected registry, operation, previous and requested messages, outcome, mutation-attempt count, and verification state. Outcomes distinguish previews, confirmed updates, no-ops, missing metadata, authorization failures, conflicts, ambiguous transport results, and writes accepted but not verified.

Flog follows npm CLI 11's npm-compatible protocol: it fetches the full packument with ?write=true, preserves all unrelated fields and revision metadata, changes only versions[exact].deprecated, and PUTs the complete document with npm-command: deprecate. npmjs and compatible registries that implement this packument update protocol are supported. Registry-specific partial-update APIs are not used. Registries may reject stale _rev state with HTTP 409; Flog reports that conflict and never retries it automatically. The protocol has no documented universal conditional-write guarantee, so Flog does not claim that all third-party registries provide atomic race detection.

After a successful response, Flog performs cache-busted full-metadata reads and reports success only when the exact version exposes the requested message. A successful PUT whose result cannot be confirmed is reported as accepted-unverified with a nonzero exit; inspect current metadata before an explicit retry. A transport failure after upload is ambiguous unless a fresh read confirms the requested state. Cancellation or deadline expiry after the metadata PUT is dispatched is also ambiguous, because the registry may have applied the write before the client stopped waiting. Inspect the exact version's current metadata before a new invocation. Flog never blindly replays any of these cases.

OTP and web-auth challenges are also not replayed automatically. Flog first rechecks metadata. In an interactive terminal, entering an OTP or confirming a completed web challenge authorizes one explicit retry; Flog fetches writable metadata again, refuses the retry if that version's message changed, rebuilds the update with the latest revision, and never attempts a third PUT. In noninteractive use, rerun explicitly with a fresh NPM_CONFIG_OTP. This avoids reusing a potentially accepted or stale mutation body after authentication. Deprecation does not publish or unpublish a version, move dist-tags, or edit local manifests, locks, installations, caches, or credentials.

Web authentication#

Flog supports npm's /-/v1/login flow (including the npm-auth-type: web header required by npmjs to return the browser URL), requests web authentication on publication uploads with npm-command: publish and deprecation updates with npm-command: deprecate, and supports registry-requested authUrl / doneUrl challenges. It prints the login URL and, in a supported interactive terminal, offers to open it with the platform browser when Enter is pressed. Browser-launch failure retains the manual-link fallback. Polling handles pending, success, denial, and timeout responses.

Every request and polling delay observes the caller's context. Cancellation stops immediately and the original publication request is never replayed after an interrupted authentication flow. The client does not place the terminal in a special mode, so no terminal state needs to be recovered after Ctrl+C.