SIGN IN SIGN UP

feat(arborist): extend replace-registry-host with URL prefix matching (#6110) (#9672)

Resolves where registries with a path component (e.g.
https://myregistry.example.com/npm/b) caused resolved URLs in the
lockfile to have their path duplicated when reify rewrote them.

Rewrote `#registryResolved` to unify all match-and-rewrite logic into a
single pass. A single `new URL()` parse of `replaceRegistryHost` now
drives all three match modes:
- **Keyword / bare hostname** (`never`, `always`, `npmjs`,
`registry.npmjs.org`): behaviour unchanged. `new URL()` throws for
keywords, leaving `matchURL` null and falling through to the existing
host-comparison or keyword short-circuit.
- **Host-only URL** (e.g. `https://old.example.com/`): trailing slash
normalises to an empty `matchPath`; treated identically to a bare
hostname — only the host is replaced, and the registry path is prepended
if not already present.
- **Full URL with path** (e.g. `https://old.example.com/npm/b`): when
the resolved URL's host and path both match the prefix, the entire
matched prefix is replaced with the configured registry's full URL (host
+ path). The remainder of the resolved path is appended without
duplication. If the resolved URL's path does not start with the
configured prefix, `#registryResolved` returns the URL unchanged.

Updated the `hint` and `description` for `replace-registry-host` to
document the new full-URL-with-path mode and the host-only-URL mode.

Added three integration tests using `tnock` (mismatched URL → nock
throws, making URL assertions implicit and precise):
1. Full URL prefix match:
`replaceRegistryHost=https://old.example.com/npm/b`, registry
`https://new.example.com/npm/a` — verifies the old `/npm/b` prefix is
replaced with `/npm/a`, not doubled to `/npm/a/npm/b/…`.
2. Host-only URL: `replaceRegistryHost=https://old.example.com/` —
verifies only the host is swapped and the resolved path is preserved.
3. Path mismatch: `replaceRegistryHost=https://old.example.com/npm/c`
but tarball under `/npm/b` — verifies the URL is left unchanged when the
path prefix does not match.

<!-- What / Why -->
<!-- Describe the request in detail. What it does and why it's being
changed. -->


## References
- Fixes #6110
J
Justin Clark committed
b51d156fd9858f418775df9c70859377eba1fa0c
Parent: 024e6d9
Committed by GitHub <noreply@github.com> on 6/29/2026, 3:27:30 PM