`pnpm cache list-registries` printed the mirror directory name where `pnpm
cache view` printed a decoded registry URL, so the two disagreed about what a
registry is called and the listing gave no way to tell a live entry from a
stale one. Both stacks already exported the decoder beside the encoder; only
the listing never called it. Fixed in v11 and v12, since the inconsistency is
in both.
Keying the mirror on the scheme and path stranded every directory written
before it: the registry now resolves to a different name, and `list`, `view`
and `delete` all scope their glob to the configured registry's current key, so
nothing reads the leftover and nothing could remove it. `pnpm cache prune`
removes the directories this version can no longer read, across all three
metadata roots. New command, so v12 only.
`is_unreadable_registry_key` decides what goes. A name carrying no scheme
separator predates the current shape, with one exception it must not confuse
for staleness: `get_registry_name` collapses a key over 255 bytes to a bare
sha256, which carries no separator either. Those are spared, so one
unreachable directory can survive rather than a live mirror being deleted.
`--dry-run` lists what would go without removing it. The cache directory is
shared machine-wide and the scheme-in-key change shipped in v11.27.0 as well as
v12.4.0, so a pnpm at 11.26 or earlier still reads the host-only names this
removes; a user on both versions can check before paying that CLI a refetch.
The ephemeral-port directories the issue also mentions are in the current key
shape, so reclaiming them needs a retention policy rather than a mechanism,
and are left out. The descriptor-scoped roots under `v11/metadata-private`
accumulate equally unreadable directories and are also skipped, as `delete`,
`list` and `view` skip them.
Also stops `cacheList` and `cacheDelete` from asserting an exact cache
listing while the update check resolves `pnpm@latest` through the same cache
dir. That check is off under CI, so the stray `pnpm.jsonl` entry only failed
these tests locally.
Closespnpm/pnpm#15046.
---------
Co-authored-by: Zoltan Kochan <z@kochan.io>
Registry metadata mirrors were keyed on host[:port], so several registries
served from one host under different path prefixes shared one directory and
could answer with each other's versions, integrity hashes and tarball URLs.
Both stacks now key the mirror on
<scheme>%3A+<host>[+<port>][%2F<path>][%5F<sha256>]. The host and every path
segment are percent-escaped down to [A-Za-z0-9._-], so a `%` or `+` in a key
is always one the encoder wrote and the key can carry no path separator, no
character Windows rejects in a filename, and no glob metacharacter — the
cache commands feed the key to a glob whose matches `pnpm cache delete`
removes. The scheme is included because http and https at one host and path
are two different trust domains: metadata served over http can be rewritten
in transit and must never reach a resolution configured for https. The
separators are percent-escapes because every key pnpm wrote before this
change was a URL host, which can never hold a `%`; no new key can therefore
land on the stale directory of an unrelated one whose hostname held a
separator, which would otherwise let `https://nexus/npm/` read what was
cached for `https://nexus_npm/`. A path that is not all lowercase gets a
sha256 suffix, the guard encodePkgName already applies to package names, so
HFS+ and NTFS cannot merge two registries; a trailing `.` is escaped because
Win32 strips one; and a key too long for a 255-byte filename is replaced by
its own hash. Only the one trailing slash the resolver itself appends is
normalized away; a repeated slash reaches the registry as a distinct request
path and stays in the key.
Every cache directory is renamed, so the first install after upgrading
refetches registry metadata once. The package store is untouched.
`pnpm cache view` decodes the key back to the registry rather than replacing
`+` with `:`, the registry URL is redacted in both stacks' errors, and the
Rust diagnostic codes now match pnpm's.
Closespnpm/pnpm#13558.
---------
Co-authored-by: Zoltan Kochan <z@kochan.io>
Remove the legacy repository changelog files now that release changelog storage defaults to the registry. The publish path composes and injects CHANGELOG.md into release tarballs, so keeping historical copies in source control duplicates generated release data.
Update adm-zip to the patched 0.6 release and override vulnerable transitive versions after the dependency audit began rejecting versions below 0.6.0.
The TypeScript pnpm CLI freezes at v11; pnpm 12 will be the Rust pacquet
port. To make that split legible, all TypeScript source, test, and build
directories move under a new top-level pnpm11/ directory. The name states
the version boundary rather than implying a behavioral fork, since the two
stacks are meant to behave identically.
Scope is source-only: the shared workspace root stays at the repo root.
pnpm-workspace.yaml, package.json, pnpm-lock.yaml, .pnpmfile.cjs,
.meta-updater, __patches__, .changeset, .husky, and the lint/spell configs
remain in place, so one pnpm workspace and one Cargo workspace still span
all three products. pnpr/client and pacquet/tasks/registry-mock stay as
cross-product workspace members.
Rewiring the move required:
- pnpm-workspace.yaml globs prefixed with pnpm11/
- root package.json script paths, eslint.config.mjs, tsconfig.lint.json,
.gitignore, and CODEOWNERS updated
- .meta-updater/src/index.ts literals repointed (pnpm11/pnpm/package.json,
pnpm11/__utils__, pnpm11/__typings__, and the main package directory)
- regenerated every moved package's repository/homepage URL via meta-updater
- pnpm11/pnpm/bundle-deps.ts and __utils__/scripts/src/typecheck-only.ts
climb one more level to reach the repo root
.meta-updater stays at the repo root because @pnpm/meta-updater resolves
its config at <cwd>/.meta-updater/main.mjs.
TS CI (.github/workflows/ci.yml) now only runs when pnpm11/-relevant paths
change, via a dorny/paths-filter changes job plus a TS CI / Success
aggregate gate; branch protection should require only that gate.