Skip to content

fix(cli): honor .npmrc auth keys written without a trailing slash [RED-897] [ship] - #1448

Merged
sorccu merged 1 commit into
mainfrom
simo/red-897-npmrc-slashless-auth-keys
Aug 25, 2026
Merged

fix(cli): honor .npmrc auth keys written without a trailing slash [RED-897] [ship]#1448
sorccu merged 1 commit into
mainfrom
simo/red-897-npmrc-slashless-auth-keys

Conversation

@sorccu

@sorccu sorccu commented Aug 25, 2026

Copy link
Copy Markdown
Member

Linear: RED-897

Follow-up deferred from RED-891 (#1444).

Affected Components

  • CLI
  • Test

What

resolveAuthHeader only probed the canonical slash-terminated nerf dart spellings (//host/path/:_authToken), so a hand-written key without the trailing slash (//host/path:_authToken) was invisible to the walk and embedded-package downloads went out unauthenticated even with the credential right there in .npmrc. Both package managers tolerate the slashless spelling — npm probes both forms at each depth of its walk, pnpm normalises the slashless one to canonical at config load — so the CLI now does too.

nerfDarts() keeps producing only canonical darts (the path form's ${dart}${scope}/ composition relies on the trailing-slash invariant); a small dartSpellings helper expands each finalised lookup candidate — unscoped, scope-qualified, and path-form — into both spellings, canonical first at each depth. The RED-891 scoped/unscoped/path-form ordering logic is untouched.

The AI-context credentials reference documents the accepted spellings accordingly.

Notes for the Reviewer

Behaviour flip worth knowing: a slashless key that was previously ignored is now honored, so one that references an unset ${VAR} now fails the download and names the variable — instead of silently falling through to a shallower working credential (i.e. authenticating as an identity the config asked to replace). A new test pins this deliberately.

Deliberate non-parity at one edge: at the request's own path depth npm probes only the URL's literal spelling, while this walk still tries canonical first there. Only observable with a key at exactly the request's full path — not a key anything writes; documented in the resolveAuthHeader doc comment.

New fixtures cover slashless keys at multiple depths, spelling precedence both ways, blank fall-through to the other spelling, scoped and path forms, no cross-spelling username/_password pairing, and skipUnexpandable tolerance for the slashless path form.

🤖 Generated with Claude Code

…D-897]

resolveAuthHeader only probed the canonical slash-terminated nerf dart
spellings, so a hand-written //host/path:_authToken was invisible and the
embedded-package download went out unauthenticated. npm probes both
spellings at each depth of its walk and pnpm normalises the slashless one
at config load, so both are now probed, canonical first per depth. The
nerf-dart generator stays canonical; a dartSpellings helper expands each
finalised lookup candidate — unscoped, scope-qualified and path-form —
into both spellings, leaving the scoped/unscoped/path-form ordering
untouched.

Behaviour note: a slashless key that was previously ignored is now
honored, so one that references an unset ${VAR} now fails the download
and names the variable instead of silently falling through to a
shallower credential.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sorccu sorccu changed the title fix(cli): honor .npmrc auth keys written without a trailing slash [RED-897] fix(cli): honor .npmrc auth keys written without a trailing slash [RED-897] [ship] Aug 25, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved: ship/show PR from a same-repo branch.

@sorccu
sorccu merged commit a2cd5bf into main Aug 25, 2026
17 checks passed
@sorccu
sorccu deleted the simo/red-897-npmrc-slashless-auth-keys branch August 25, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant