Commit 82ee345
chore(deps): update pnpm to v11.10.0 (#75)
> ℹ️ **Note**
>
> This PR body was truncated due to platform limits.
This PR contains the following updates:
| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Adoption](https://docs.renovatebot.com/merge-confidence/) |
[Passing](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|---|---|
| [pnpm](https://pnpm.io)
([source](https://redirect.github.com/pnpm/pnpm/tree/HEAD/pnpm11/pnpm))
| [`11.5.1` →
`11.10.0`](https://renovatebot.com/diffs/npm/pnpm/11.5.1/11.10.0) |

|

|

|

|
| [pnpm](https://pnpm.io)
([source](https://redirect.github.com/pnpm/pnpm/tree/HEAD/pnpm11/pnpm))
| `11.5.1` → `11.10.0` |

|

|

|

|
---
### Release Notes
<details>
<summary>pnpm/pnpm (pnpm)</summary>
###
[`v11.10.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#11100)
[Compare
Source](https://redirect.github.com/pnpm/pnpm/compare/v11.9.0...v11.10.0)
##### Minor Changes
- [`e2e3c81`](https://redirect.github.com/pnpm/pnpm/commit/e2e3c81):
Added the `issues` command as an alias of `bugs`, so `pnpm issues` opens
the package's bug tracker URL in the browser.
- [`8491f8e`](https://redirect.github.com/pnpm/pnpm/commit/8491f8e):
Added the `prefix` command which prints the current package prefix
directory (or global prefix directory if `-g` / `--global` is used).
- [`3425e80`](https://redirect.github.com/pnpm/pnpm/commit/3425e80):
Added an `_auth` setting for configuring registry authentication as a
single structured (URL-keyed) value. It can be set in the **global**
pnpm config (`config.yaml`) or, for CI, via the `pnpm_config__auth`
environment variable. The env form sidesteps the GitHub Actions / bash /
zsh limitation that broke the existing
`pnpm_config_//host/:_authToken=…` form (env var names containing `/`,
`:`, or `.` are silently dropped). Closes
[#​12314](https://redirect.github.com/pnpm/pnpm/issues/12314).
The value is keyed by registry URL so each secret is explicitly bound to
the host that may receive it. Registry URL keys must use `http` or
`https` and must not include credentials, query strings, or fragments:
```sh
export
pnpm_config__auth='{"https://registry.npmjs.org":{"@​":{"authToken":"npm-token"},"@​org":{"authToken":"org-token"}}}'
```
The equivalent in the global `config.yaml`:
```yaml
_auth:
https://registry.npmjs.org:
"@​":
authToken: npm-token
"@​org":
authToken: org-token
```
Within each registry URL, `@` means registry-wide/default credentials
and package scopes like `@org` bind credentials to that scope on the
same host. The only supported credential field is `authToken` (maps to
`_authToken` / bearer auth); the deprecated `basicAuth` / `username` +
`password` forms are intentionally not accepted here.
Each entry also infers a trusted registry route: `@` routes the default
registry (and `pnpm add <pkg>` resolves there), and `@org` routes that
scope. Because the credential and destination host arrive in one trusted
value, repo-controlled `pnpm-workspace.yaml` or project `.npmrc` cannot
redirect the token to a different host. `_auth` is honored **only** from
the env var and the global config — it is ignored in a project
`pnpm-workspace.yaml` / `.npmrc`, so repo-controlled config can never
supply registry auth. Precedence: CLI flags (`--registry`,
`--@​scope:registry`) > `pnpm_config__auth` > global `config.yaml`
`_auth` > `pnpm-workspace.yaml`.
Both `pnpm_config__auth` (lowercase, documented form) and
`PNPM_CONFIG__AUTH` (all-caps, the shell convention some CI runners
apply) are honored. If both are set, lowercase wins unless it is empty,
in which case uppercase is used. The env var wins over the global
`config.yaml` `_auth` on a conflicting key. `tokenHelper` is not
supported in `_auth`. Parsing is strict: a malformed value (bad JSON,
wrong shape, invalid registry URL or scope, an unsupported credential
field) fails fast with an error rather than being silently dropped.
**Pacquet parity note:** the pacquet (Rust) port supports the same
single credential field as the TS CLI: `authToken`.
- [`a33eeec`](https://redirect.github.com/pnpm/pnpm/commit/a33eeec):
`pnpm self-update` and `packageManager` version-switching can now
install and link pnpm v12 (the Rust port), published with equal content
under both the `pnpm` and `@pnpm/exe` names on the `next-12` dist-tag.
Its native binaries ship as `@pnpm/exe.<platform>-<arch>` packages,
which pnpm's built-in installer links directly — no Node.js launcher, so
the command pays no Node startup cost. v12 is initialized exactly like
`@pnpm/exe`, including per-platform global-virtual-store hashing. From
v12 onward the install converges on the unscoped `pnpm` package (the
Rust exe) — even when updating from the SEA `@pnpm/exe` build.
- [`1dd12bd`](https://redirect.github.com/pnpm/pnpm/commit/1dd12bd):
When resolving through a pnpr install-accelerator server, pnpm no longer
forwards its own upstream registry credentials in the resolve request.
Only the `Authorization` header identifying the caller to pnpr is sent.
The pnpr server now selects upstream credentials from its own route
policy (operator-configured upstream credential aliases), so private
dependencies resolve through a pnpr-managed alias the caller is
authorized to use, rather than by sending the client's registry tokens
to the server.
- [`1e81761`](https://redirect.github.com/pnpm/pnpm/commit/1e81761):
Expose web authentication `authUrl` and `doneUrl` in JSON error output
when OTP is required in a non-interactive terminal
[#​12724](https://redirect.github.com/pnpm/pnpm/issues/12724).
##### Patch Changes
- [`2f389d6`](https://redirect.github.com/pnpm/pnpm/commit/2f389d6):
Added the Node.js release team's new signing key (Stewart X Addison,
`655F3B5C1FB3FA8D1A0CA6BDE4A7D232B936D2FD`) to the embedded Node.js
release keys, so runtimes whose `SHASUMS256.txt` is signed by the new
releaser verify successfully.
- [`acbdb94`](https://redirect.github.com/pnpm/pnpm/commit/acbdb94):
Fixed shell tab completion not suggesting workspaces after the `-F`
alias for `--filter` option.
- [`dcabb78`](https://redirect.github.com/pnpm/pnpm/commit/dcabb78):
Fixed `pnpm up -r <pkg>` bumping unrelated packages that have open
semver ranges. Previously, any update mutation nullified the
lockfile-derived `preferredVersions` globally, so packages with `^x.y.z`
ranges could re-resolve to newer compatible versions even though the
user only asked to update a specific package. The install layer now
always seeds `preferredVersions` from the lockfile, and caller-supplied
preferred versions (such as the vulnerability penalties of `pnpm audit
--fix`) layer on top of the seed instead of replacing it. The targeted
package still bumps: the per-resolve `updateRequested` flag makes the
resolver ignore the target's own lockfile pins.
Closes
[#​10662](https://redirect.github.com/pnpm/pnpm/issues/10662).
- [`d539172`](https://redirect.github.com/pnpm/pnpm/commit/d539172):
Fixed pnpm pack and pnpm publish failing when prepack generates files
that are included in the package and postpack cleans them up.
- [`be6505a`](https://redirect.github.com/pnpm/pnpm/commit/be6505a):
Hardened global package management:
- On Windows, removing or updating a global package now also cleans up
the `node.exe` flavor of a bin, so a stale `node.exe` no longer survives
on `PATH` after uninstall, and a new global install no longer silently
overwrites an existing `node.exe`.
- `pnpm add -g pnpm@<version>` (and `@pnpm/exe@<version>`) is now
rejected like the bare `pnpm` form, pointing to `pnpm self-update`.
- Dependency aliases read from a global package's manifest are validated
before being joined onto `node_modules` paths, preventing a tampered
manifest from escaping the install directory.
- Each global install group is created in its own freshly-made directory
(no longer reusing a colliding or pre-existing path).
- Removing or updating a global package no longer unlinks a bin that
belongs to a different globally installed package.
- [`25c7388`](https://redirect.github.com/pnpm/pnpm/commit/25c7388):
pnpm now rejects `jsr:` specifiers whose package name is not a valid npm
package name — an empty scope or name (e.g. `jsr:@​scope/`), path
separators inside the name, or any other shape
`validate-npm-package-name` rejects — with
`ERR_PNPM_INVALID_JSR_PACKAGE_NAME` instead of silently converting them
into a malformed `@jsr/...` npm package name.
- [`25c7388`](https://redirect.github.com/pnpm/pnpm/commit/25c7388):
pnpm now rejects named-registry specifiers (e.g. `gh:`) whose package
name is not a valid npm package name — an empty scope (e.g.
`gh:@​/bar`), path separators inside the name (e.g.
`gh:@​scope/../name`), or any other shape
`validate-npm-package-name` rejects — with
`ERR_PNPM_INVALID_NAMED_REGISTRY_PACKAGE_NAME` instead of passing the
name through to registry URLs and metadata cache file paths.
- [`96da7c5`](https://redirect.github.com/pnpm/pnpm/commit/96da7c5):
node-gyp's `gyp_main.py` and `gyp` entrypoints are now packed with the
executable bit in the `pnpm` and `@pnpm/exe` tarballs. Without it,
building native addons from source could fail with a permission error.
- [`99982b9`](https://redirect.github.com/pnpm/pnpm/commit/99982b9):
Sped up resolution and reduced memory use against registries that ignore
npm's abbreviated metadata format and always return the full package
document (for example, Azure DevOps Artifacts). pnpm now strips such
documents down to the abbreviated field set before caching them.
Resolution output is unchanged, and registries that honor the
abbreviated format (such as the npm registry) pay no extra cost.
- [`11a7fdd`](https://redirect.github.com/pnpm/pnpm/commit/11a7fdd):
Sped up offline and `--prefer-offline` resolution on large workspaces
(e.g. `pnpm dedupe --offline`, `pnpm install --offline`). Package
metadata loaded from the local cache is now kept in memory, so each
package's metadata is parsed once per command instead of once per
dependent that references it.
- [`2c7369d`](https://redirect.github.com/pnpm/pnpm/commit/2c7369d):
`pnpm pack-app` now rejects `--entry` / `pnpm.app.entry` and
`--output-dir` / `pnpm.app.outputDir` values that are absolute paths or
escape the project directory via `..` (or a symlink that resolves
outside it), and refuses to write the produced executable when its
target path already exists as a symlink (or other non-regular file).
This prevents a repository-controlled `package.json` from embedding host
files (such as an SSH key) into the produced executable, writing build
artifacts outside the project, or overwriting an arbitrary file through
a committed symlink. The new error codes are
`ERR_PNPM_PACK_APP_ENTRY_OUTSIDE_PROJECT`,
`ERR_PNPM_PACK_APP_OUTPUT_DIR_OUTSIDE_PROJECT`, and
`ERR_PNPM_PACK_APP_OUTPUT_FILE_NOT_REGULAR`.
When ad-hoc signing macOS targets, `pnpm pack-app` now runs the system
`codesign` by absolute path and resolves `ldid` to a location outside
the project, so a repository-controlled `node_modules/.bin` on `PATH`
cannot hijack the signer.
- [`ce5d5a5`](https://redirect.github.com/pnpm/pnpm/commit/ce5d5a5):
Relative paths in `patchedDependencies` are now resolved against the
lockfile directory when computing patch file hashes, so running `pnpm
install` from a subdirectory no longer fails with `ENOENT` looking for
the patch file in the wrong location
[#​12762](https://redirect.github.com/pnpm/pnpm/pull/12762).
- [`ebb4096`](https://redirect.github.com/pnpm/pnpm/commit/ebb4096):
`pnpm peers` no longer reports a conflict for a missing peer dependency
that is ignored via `pnpm.peerDependencyRules.ignoreMissing`.
- [`dcabb78`](https://redirect.github.com/pnpm/pnpm/commit/dcabb78):
Fixed a prototype-pollution hazard when seeding preferred versions: a
dependency named `__proto__` in a manifest or in `pnpm-lock.yaml` could
write through `Object.prototype` (or crash the install) while the
preferred-versions map was being built. The maps are now null-prototype
objects, so crafted package names land as plain keys.
- [`f38e696`](https://redirect.github.com/pnpm/pnpm/commit/f38e696):
Hardened `pnpm deploy --force` so it refuses unsafe deploy targets such
as workspace roots, parent directories, out-of-workspace paths, and
symlinked target parents.
- [`806c3ec`](https://redirect.github.com/pnpm/pnpm/commit/806c3ec):
pnpm no longer warns about ignored project-level auth settings when
`PNPM_CONFIG_NPMRC_AUTH_FILE` points at the project `.npmrc` — setting
it to that file is an explicit opt-in to trusting it, so auth env
variables in it are expanded
[pnpm/pnpm#12480](https://redirect.github.com/pnpm/pnpm/issues/12480).
- [`991405e`](https://redirect.github.com/pnpm/pnpm/commit/991405e):
Restore differential rendering (`ansi-diff`) to fix duplicated output
lines introduced by
[#​12351](https://redirect.github.com/pnpm/pnpm/issues/12351).
- [`c121235`](https://redirect.github.com/pnpm/pnpm/commit/c121235):
Fixed the topological order of `--filter`ed commands (`pnpm run`, `pnpm
exec`, `pnpm publish`, `pnpm pack`, `pnpm rebuild`) when the selected
projects depend on each other only transitively through projects that
were not selected. Previously such selected projects could run
concurrently or in the wrong order; now a project always runs after the
selected projects it transitively depends on, while projects without a
real dependency relationship still run concurrently. This now also holds
for prod-only filters (`--filter-prod`), which resolve order through the
production dependency graph so transitive production dependencies are
respected without pulling back the dev dependencies the filter drops,
and for selections that mix `--filter` with `--filter-prod`
[#​8335](https://redirect.github.com/pnpm/pnpm/issues/8335).
- [`d539172`](https://redirect.github.com/pnpm/pnpm/commit/d539172):
`pnpm pack` and `pnpm publish` no longer follow a symlinked workspace
`LICENSE` file when injecting it into a package that has no license of
its own. Following the symlink could pack bytes from outside the
workspace into the published tarball.
- [`dcabb78`](https://redirect.github.com/pnpm/pnpm/commit/dcabb78):
Fixed `pnpm up <pkg>` producing a different result than a fresh install
of the same manifests would. The resolver now distinguishes
`updateRequested` (true only for packages that match the user's update
target) from the broader `update` flag, and for the targeted package
ignores only its own lockfile-derived preferred-version pins — so the
target re-resolves exactly as if its lockfile entries were deleted and
`pnpm install` ran. Preferred versions a fresh install applies (manifest
pins, versions propagated down the dependency chain, and the
vulnerability-avoidance penalties of `pnpm audit --fix`) stay in effect,
so an update never installs duplicate versions that a reinstall from
scratch would not reproduce. When a preferred version holds the update
target below the newest version its range admits, pnpm now prints a
warning explaining that reaching the newer version everywhere requires
an override.
- [`dcabb78`](https://redirect.github.com/pnpm/pnpm/commit/dcabb78):
`pnpm update <dep>@​<version>` now prints a warning when `<dep>`
is only present as a transitive dependency: the requested version cannot
be applied there (updates resolve the target the way a fresh install
would), and the warning recommends adding the version to
`pnpm.overrides` instead, which is the mechanism that does pin
transitive dependencies. Closes
[#​12744](https://redirect.github.com/pnpm/pnpm/issues/12744).
- [`a6c4d5f`](https://redirect.github.com/pnpm/pnpm/commit/a6c4d5f):
When a dependency cannot be found in the registry (404) or the registry
has no matching version, and a workspace project with the same name
exists only at non-matching versions, the error now reports the
available workspace versions
(`ERR_PNPM_NO_MATCHING_VERSION_INSIDE_WORKSPACE`) instead of the raw
registry failure
[pnpm/pnpm#1379](https://redirect.github.com/pnpm/pnpm/issues/1379).
Other registry failures (authorization, network, server errors) still
propagate unchanged. The pacquet (Rust) resolver applies the same
behavior.
###
[`v11.9.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1190)
[Compare
Source](https://redirect.github.com/pnpm/pnpm/compare/v11.8.0...v11.9.0)
##### Minor Changes
- [`bae694f`](https://redirect.github.com/pnpm/pnpm/commit/bae694f):
Some registries generate tarballs on-demand and cannot provide an
integrity checksum in their package metadata. In that case pnpm now
computes the integrity from the downloaded tarball and stores it in the
lockfile, so the entry is verifiable on subsequent installs instead of
being written without an integrity (which would fail the next install).
This also applies to `--lockfile-only`: the tarball is downloaded so its
integrity can be computed. A lockfile entry that is still missing its
integrity is rejected as a `ERR_PNPM_MISSING_TARBALL_INTEGRITY` lockfile
verification violation (the install fails closed) rather than being
silently re-fetched.
- [`6c35a43`](https://redirect.github.com/pnpm/pnpm/commit/6c35a43):
Added `--exclude-peers` to `pnpm sbom`. With `auto-install-peers` (the
default), peer dependencies resolve into the lockfile and are otherwise
indistinguishable from the package's own dependencies. The flag drops
peer dependencies (and any transitive subtree reachable only through
them) from the SBOM. CycloneDX 1.7 has no scope or relationship that
expresses "consumer-provided peer", so omission is the only spec-clean
handling. The flag name matches `pnpm list --exclude-peers`; note the
SBOM flag prunes a peer's exclusive subtree, which is stricter than
`pnpm list` (which only hides leaf peers).
##### Patch Changes
- [`25a829e`](https://redirect.github.com/pnpm/pnpm/commit/25a829e):
`pnpm audit --fix` now writes a single combined
`minimumReleaseAgeExclude` entry per package (e.g. `axios@0.18.1 ||
0.21.1`) instead of one entry per version, matching the format
documented for the setting. Existing per-version entries in
`pnpm-workspace.yaml` are merged into the combined form rather than left
as duplicates. Installs that auto-collect immature versions into
`minimumReleaseAgeExclude` now report the same combined entries, so the
"Added N entries" message matches what is written to the manifest
[#​12534](https://redirect.github.com/pnpm/pnpm/issues/12534).
- [`1cbb5f2`](https://redirect.github.com/pnpm/pnpm/commit/1cbb5f2):
Fixed non-deterministic peer resolution that could add or remove an
optional transitive peer — for example `@babel/core`, reached through
`styled-jsx` — from a package's peer-dependency suffix across otherwise
identical installs, churning the lockfile and causing intermittent `pnpm
dedupe --check` failures in CI. When a package's children are resolved
by one occurrence (the "owner") and reused by a deeper consumer, whether
that consumer inherited the owner's missing peers depended on whether
the owner's resolution had finished yet — a race under concurrent
resolution. The decision is now a function of the dependency graph's
structure rather than resolution-completion order.
- [`d577eea`](https://redirect.github.com/pnpm/pnpm/commit/d577eea):
Fixed a Windows flakiness in `pnpm dlx` where a failed install could
surface a spurious `EBUSY: resource busy or locked` error. The cleanup
of a partially-populated dlx cache is now best-effort with retries and
no longer masks the original error.
- [`ec7cf70`](https://redirect.github.com/pnpm/pnpm/commit/ec7cf70):
Shortened the `pnpm dlx` cache path so deep dependency trees no longer
overflow Windows' `MAX_PATH`, which could make a dependency's lifecycle
script fail with `spawn cmd.exe ENOENT`.
- [`05b95ab`](https://redirect.github.com/pnpm/pnpm/commit/05b95ab):
Fixed `pnpm` hanging (and crashing with an unhandled promise rejection)
when a non-retryable network error such as `SELF_SIGNED_CERT_IN_CHAIN`
occurs while fetching from a registry. The error is now rejected through
the returned promise instead of being thrown inside the detached retry
callback.
- [`d3f68e2`](https://redirect.github.com/pnpm/pnpm/commit/d3f68e2): Fix
a `pnpm audit` performance regression on lockfiles that contain
dependency cycles. The reachable-vulnerability pruning added in pnpm
11.5.1 only memoized acyclic subtrees, so any node whose subtree touched
a cycle — together with all of its ancestors — was recomputed on every
query, making the path walk quadratic. Reachability is now computed once
per node using Tarjan's strongly-connected-components algorithm, so
cyclic graphs are handled in linear time
[#​12212](https://redirect.github.com/pnpm/pnpm/issues/12212).
The audit path walk also no longer recurses, so a deeply nested
dependency graph can no longer overflow the call stack, and the install
path to each finding is tracked without per-node copying, keeping memory
linear in the graph depth.
- [`322f88f`](https://redirect.github.com/pnpm/pnpm/commit/322f88f): Fix
failed optional dependency updates so they don't rewrite unrelated
dependency specs
[#​11267](https://redirect.github.com/pnpm/pnpm/issues/11267).
- [`1488db1`](https://redirect.github.com/pnpm/pnpm/commit/1488db1):
When `enableGlobalVirtualStore` is toggled on for a project that was
previously installed without it, stale hoisted symlinks under
`node_modules/.pnpm/node_modules` are now replaced instead of being left
pointing at the old per-project virtual store location
[#​9739](https://redirect.github.com/pnpm/pnpm/issues/9739).
- [`6545793`](https://redirect.github.com/pnpm/pnpm/commit/6545793):
Fixed `pnpm install --ignore-workspace` overwriting the `allowBuilds`
map in `pnpm-workspace.yaml`. The ignored builds of a package with a
build script were auto-populated into `allowBuilds` even though
`--ignore-workspace` was passed, clobbering committed `true`/`false`
values with the `set this to true or false` placeholder
[#​12469](https://redirect.github.com/pnpm/pnpm/issues/12469).
- [`fbdc0eb`](https://redirect.github.com/pnpm/pnpm/commit/fbdc0eb):
Fixed `minimumReleaseAgeExclude` and `trustPolicyExclude` so multiple
exact-version entries for the same package behave the same as a single
`||` disjunction entry. Previously only the first matching rule's
versions were honored, so a config like `[form-data@4.0.6,
form-data@2.5.6]` could still flag `form-data@2.5.6` as violating
`minimumReleaseAge`, while `[form-data@4.0.6 || 2.5.6]` worked as
expected
[#​12463](https://redirect.github.com/pnpm/pnpm/issues/12463).
- [`fa7004b`](https://redirect.github.com/pnpm/pnpm/commit/fa7004b): The
in-memory package metadata cache is now populated on the exact-version
disk fast path, so repeated resolutions of the same package within one
install no longer re-read and re-parse the on-disk metadata. In large
monorepos this brings the time for adding a new package down from
minutes to seconds. The in-memory cache key now also includes the
registry, so a package of the same name served by two different
registries in a single install can no longer share a cache slot and
resolve the wrong tarball.
- [`0a154b1`](https://redirect.github.com/pnpm/pnpm/commit/0a154b1):
Fixed `pnpm patch` dropping the package name (and leaking internal
option fields) when the patched dependency resolves to a single
git-hosted version.
- [`4d3fe4b`](https://redirect.github.com/pnpm/pnpm/commit/4d3fe4b): The
pnpr resolver endpoints moved under the reserved `/-/pnpr` namespace:
`POST /v1/resolve` is now `POST /-/pnpr/v0/resolve` and `POST
/v1/verify-lockfile` is now `POST /-/pnpr/v0/verify-lockfile`. The
capability handshake at `GET /-/pnpr` advertises protocol version `0` to
match. This keeps every pnpr-proprietary route in npm's reserved
namespace, so it can never collide with a package path.
- [`0ec878d`](https://redirect.github.com/pnpm/pnpm/commit/0ec878d):
Removing a runtime dependency now removes the matching
`devEngines.runtime` or `engines.runtime` entry that was materialized
from it. Blank runtime selectors are normalized to `latest`.
- [`17e7f2c`](https://redirect.github.com/pnpm/pnpm/commit/17e7f2c):
`pnpm sbom` now emits a CycloneDX `issue-tracker` external reference for
components (and the root) whose `package.json` declares a `bugs` URL.
Email-only `bugs` entries are skipped, since the reference requires a
URL.
- [`a84d2a1`](https://redirect.github.com/pnpm/pnpm/commit/a84d2a1): Add
`@pnpm/resolving.tarball-url`, which builds and recognizes the canonical
npm tarball URL of a package. It vendors `getNpmTarballUrl` (previously
the external `get-npm-tarball-url` package) and adds
`isCanonicalRegistryTarballUrl`, the predicate the lockfile writer uses
to decide whether a tarball URL is derivable from name+version+registry
(and can therefore be omitted from `pnpm-lock.yaml`).
Exposing `isCanonicalRegistryTarballUrl` lets a custom resolver
(pnpmfile `resolvers`) fronting a proxy that serves tarballs on a
non-canonical path (e.g. an ephemeral `localhost:<port>`) rewrite the
resolved tarball to the canonical form, so nothing host-specific is
persisted to the lockfile. Previously this logic was private to
`@pnpm/lockfile.utils`.
Two correctness fixes are included while consolidating the logic: the
scoped-package unescape now handles uppercase `%2F` as well as `%2f`
(percent-encoding is case-insensitive), and protocol-insensitive
comparison strips only a leading `http(s)://` scheme instead of
splitting on the first `://` (which could truncate URLs containing a
later `://`).
- [`852d537`](https://redirect.github.com/pnpm/pnpm/commit/852d537):
Lockfile verification no longer reports a registry metadata fetch
failure (for example a `403`/`401` on a private registry, or a network
error) as `ERR_PNPM_TARBALL_URL_MISMATCH`. When the registry can't be
reached to verify an entry, the install now aborts with the registry's
own fetch error (such as `ERR_PNPM_FETCH_403`, which already explains
the authentication situation) instead of mislabeling a transport failure
as lockfile tampering. Registry fetch errors no longer leak basic-auth
credentials embedded in the registry URL (`https://user:pass@host/`)
into their message.
###
[`v11.8.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1180)
[Compare
Source](https://redirect.github.com/pnpm/pnpm/compare/v11.7.0...v11.8.0)
##### Minor Changes
- [`c112b61`](https://redirect.github.com/pnpm/pnpm/commit/c112b61):
Added a `--dry-run` option to `pnpm install`. It runs a full dependency
resolution and reports what an install would change, but writes nothing
to disk (no lockfile, no `node_modules`) and always exits with code 0.
This mirrors the preview semantics of `npm install --dry-run`
[#​7340](https://redirect.github.com/pnpm/pnpm/issues/7340).
- [`179ebc4`](https://redirect.github.com/pnpm/pnpm/commit/179ebc4):
`pnpm run --no-bail` now exits with a non-zero exit code when any of the
executed scripts fail, while still running every matched script to
completion. This makes the exit-code behavior of `--no-bail` consistent
between recursive and non-recursive runs (recursive runs already failed
at the end). Previously, a non-recursive `pnpm run --no-bail` always
exited with code 0, even when a script failed
[#​8013](https://redirect.github.com/pnpm/pnpm/issues/8013).
- [`0474a9c`](https://redirect.github.com/pnpm/pnpm/commit/0474a9c):
Added support for generating Node.js package maps at
`node_modules/.package-map.json` during isolated and hoisted installs.
Added the `node-experimental-package-map` setting to inject the
generated map into pnpm-managed Node.js script environments, and the
`node-package-map-type` setting to choose between `standard` and `loose`
package maps.
- [`dcededc`](https://redirect.github.com/pnpm/pnpm/commit/dcededc):
`pnpm sbom` now marks components reachable only through
`devDependencies` with CycloneDX `scope: "excluded"` and the
`cdx:npm:package:development` property. The `excluded` scope documents
"component usage for test and other non-runtime purposes", which matches
the semantics of a devDependency; the property is the CycloneDX
npm-taxonomy marker emitted by `@cyclonedx/cyclonedx-npm`, so both
modern (scope) and existing (property) consumers are covered. Components
reachable at runtime (including installed `optionalDependencies`) omit
`scope` and default to `required`.
- [`1495cb0`](https://redirect.github.com/pnpm/pnpm/commit/1495cb0):
Added per-package SBOM generation with `--out` and `--split` flags. Use
`--out out/%s.cdx.json` to write one SBOM per workspace package to
individual files, or `--split` for NDJSON output to stdout. When
`--filter` selects a single package, the SBOM root component now uses
that package's metadata. Workspace inter-dependencies (`workspace:`
protocol) and their transitive dependencies are included. Author,
repository, and license fall back to the root manifest when the package
doesn't define them.
- [`293921a`](https://redirect.github.com/pnpm/pnpm/commit/293921a):
feat(view): support searching project manifest upward when package name
is omitted
When running `pnpm view` without a package name, the command now
searches
upward for the nearest project manifest (`package.json`, `package.yaml`,
or `package.json5`) and uses its `name` field.
If the manifest exists but lacks a `name` field, an error is thrown.
This change also replaces the `find-up` dependency with `empathic` for
improved performance and consistency across workspace tools.
##### Patch Changes
- [`29ab905`](https://redirect.github.com/pnpm/pnpm/commit/29ab905):
Fixed `pnpm update` overriding the version range policy of a named
catalog whose name parses as a version (e.g. `catalog:express4-21`). The
`catalog:` reference carries no pinning of its own, so the prefix from
the catalog entry (such as `~`) is now preserved instead of being
widened to `^`
[#​10321](https://redirect.github.com/pnpm/pnpm/issues/10321).
- [`bee4bf4`](https://redirect.github.com/pnpm/pnpm/commit/bee4bf4):
Security: validate config dependency names and versions from the env
lockfile (`pnpm-lock.yaml`) before using them to build filesystem paths.
A committed lockfile with a traversal-shaped `configDependencies` name
(such as `../../PWNED`) or version (such as `../../../PWNED`) could
previously cause `pnpm install` to create symlinks or write package
files outside `node_modules/.pnpm-config` and the store. Names must now
be valid npm package names and versions must be exact semver versions;
the same validation is applied to optional subdependencies of config
dependencies, and to the legacy workspace-manifest format before any
lockfile is written. See
[GHSA-qrv3-253h-g69c](https://redirect.github.com/pnpm/pnpm/security/advisories/GHSA-qrv3-253h-g69c).
- [`96bdd57`](https://redirect.github.com/pnpm/pnpm/commit/96bdd57): Fix
`link:` workspace protocol switching to `file:` after `pnpm rm` is run
from inside a workspace package whose target workspace dependency has
its own dependencies, when `injectWorkspacePackages: true` is set.
Follow-up to
[#​10575](https://redirect.github.com/pnpm/pnpm/pull/10575), which
fixed the same symptom for workspace packages without dependencies.
- [`302a2f7`](https://redirect.github.com/pnpm/pnpm/commit/302a2f7): No
longer warn about using both `packageManager` and
`devEngines.packageManager` when the two fields pin the same package
manager at the same version with the same integrity hash (e.g. both
`pnpm@11.5.1+sha512.…`). Previously the hash was stripped from the
legacy `packageManager` field but not from `devEngines.packageManager`,
so even identical specifications looked like a mismatch
[#​12028](https://redirect.github.com/pnpm/pnpm/issues/12028).
The warning still fires on any genuine divergence, and several cases now
state the specific reason instead of a single generic message: a
different package manager, a different version, or contradictory
integrity hashes for the same version.
- [`3f0fb21`](https://redirect.github.com/pnpm/pnpm/commit/3f0fb21):
Fixed the progress line showing leftover characters from external
processes that write to the terminal between progress updates (e.g. an
SSH passphrase prompt would leave a fragment like `added 0sa':`). The
interactive reporter now redraws each frame in place, erasing to the end
of the display before reprinting, so any such remnants are cleared
[#​12350](https://redirect.github.com/pnpm/pnpm/issues/12350).
- [`564619f`](https://redirect.github.com/pnpm/pnpm/commit/564619f):
Fixed `pnpm approve-builds` reporting "no packages awaiting approval"
when a build-script dependency whose approval was revoked (e.g. after
`git stash` drops the `allowBuilds` from `pnpm-workspace.yaml`) is
re-added. The revoked packages are now correctly recorded in
`.modules.yaml` so `approve-builds` can find them.
[#​12221](https://redirect.github.com/pnpm/pnpm/issues/12221)
- [`3d1fd20`](https://redirect.github.com/pnpm/pnpm/commit/3d1fd20):
Skip the redundant "target bin directory already contains an exe called
node" warning on Windows when the existing `node.exe` already matches
the target (same hard link or identical content)
[pnpm/pnpm#12203](https://redirect.github.com/pnpm/pnpm/issues/12203).
- [`1b02b47`](https://redirect.github.com/pnpm/pnpm/commit/1b02b47): Fix
macOS Gatekeeper blocking native binaries (`.node`, `.dylib`, `.so`) by
removing the `com.apple.quarantine` extended attribute after importing
them from the store.
When pnpm imports files from its content-addressable store into
`node_modules`, macOS preserves extended attributes, including
`com.apple.quarantine`. If this xattr is present on a store blob (e.g.
it was first written under a Gatekeeper-enabled app such as a Git
client), it propagates to `node_modules`, and Gatekeeper blocks the
native binary from loading even though pnpm already verified the file's
integrity against the lockfile.
After importing a package, pnpm now strips `com.apple.quarantine` from
its native binaries, matching Homebrew's behaviour of dropping
quarantine from verified downloads. The cleanup is macOS-only, runs in a
single batched `xattr` call per package, is restricted to native
binaries (other files are untouched), and is non-fatal (it logs a
warning on unexpected errors).
Fixes
[#​11056](https://redirect.github.com/pnpm/pnpm/issues/11056)
- [`61969fb`](https://redirect.github.com/pnpm/pnpm/commit/61969fb): Fix
`pnpm install` with `optimisticRepeatInstall` incorrectly reporting
`Already up to date` when `pnpm-lock.yaml` changed but project manifests
did not. This affected workflows such as checking out or restoring only
the lockfile
[#​12100](https://redirect.github.com/pnpm/pnpm/issues/12100).
Also fixes `checkDepsStatus` to use the correct lockfile path when
`useGitBranchLockfile` is enabled, so the optimistic fast-path and
lockfile modification detection work with `pnpm-lock.<branch>.yaml`
files instead of always stat'ing `pnpm-lock.yaml`. Merge-conflict
detection now reads the resolved lockfile name as well, and with
`mergeGitBranchLockfiles` enabled every `pnpm-lock.*.yaml` is scanned
for modifications and conflicts. The git branch is now resolved by
reading `.git/HEAD` directly (no process spawn) and uses the workspace
directory rather than `process.cwd()`.
- [`5c12968`](https://redirect.github.com/pnpm/pnpm/commit/5c12968): Fix
recursive updates of transitive dependencies when the update command
mixes transitive dependency patterns with direct dependency selectors.
For example, `pnpm up -r "@​babel/core" uuid` now updates matching
transitive `@babel/core` dependencies even when `uuid` is a direct
dependency selector
[#​12103](https://redirect.github.com/pnpm/pnpm/issues/12103).
- [`9d79ba1`](https://redirect.github.com/pnpm/pnpm/commit/9d79ba1):
Register the `pnpm update --no-save` flag in the CLI help and option
parser.
- [`0474a9c`](https://redirect.github.com/pnpm/pnpm/commit/0474a9c):
Fixed `pnpm import` for Yarn v2 lockfiles when `js-yaml` v4 is
installed.
- [`9e0c375`](https://redirect.github.com/pnpm/pnpm/commit/9e0c375):
Fixed `pnpm install` repeatedly prompting to remove and reinstall
`node_modules` in a workspace package when `enableGlobalVirtualStore` is
enabled. The post-install build step recorded a per-project
`node_modules/.pnpm` virtual store directory in
`node_modules/.modules.yaml`, overwriting the global `<storeDir>/links`
value the install step had written. The next install then detected a
virtual-store mismatch (`ERR_PNPM_UNEXPECTED_VIRTUAL_STORE`). The build
step now derives the same global virtual store directory as the install
step
[#​12307](https://redirect.github.com/pnpm/pnpm/issues/12307).
- [`223d060`](https://redirect.github.com/pnpm/pnpm/commit/223d060):
Document the `--cpu`, `--os` and `--libc` flags in the output of `pnpm
install --help`. These flags were already supported but were only
documented on the website
[#​12359](https://redirect.github.com/pnpm/pnpm/issues/12359).
- [`e85aea2`](https://redirect.github.com/pnpm/pnpm/commit/e85aea2):
Avoid reading `README.md` from disk when publishing if the publish
manifest already provides a `readme` field. The README is now only read
lazily, inside `createExportableManifest`, when it is actually needed.
- [`3188ae7`](https://redirect.github.com/pnpm/pnpm/commit/3188ae7):
Fixed `pnpm peers check` to accept loose peer dependency ranges such as
`>=3.16.0 || >=4.0.0-` when the installed peer version satisfies the
range
[#​12149](https://redirect.github.com/pnpm/pnpm/issues/12149).
- [`531f2a3`](https://redirect.github.com/pnpm/pnpm/commit/531f2a3):
Fixed `pnpm update` rewriting a `workspace:` dependency that points at a
local path (e.g. `workspace:../packages/foo/dist`) into a normalized
`link:` or version-range specifier. Such specifiers are now preserved
verbatim when the workspace protocol is preserved
[#​3902](https://redirect.github.com/pnpm/pnpm/issues/3902).
- [`fe66535`](https://redirect.github.com/pnpm/pnpm/commit/fe66535):
Fixed a lockfile non-convergence bug where an incremental install kept a
duplicate transitive dependency that a fresh install would not produce.
When a package is reused from the lockfile, its child edges are taken
verbatim and bypass the preferred-versions walk, so a transitive
dependency could stay pinned to an older version even after a direct
dependency resolved to a higher version that satisfies the same range.
The resolver now refreshes such a stale pin to the higher
direct-dependency version during resolution — so the older version is
never resolved or fetched, and the incremental result converges to the
fresh one.
- [`6d35338`](https://redirect.github.com/pnpm/pnpm/commit/6d35338):
`pnpm install` detects changes inside local file dependencies again. The
optimistic repeat-install fast path only tracks manifest and lockfile
modification times, so edits inside a local dependency's directory (or a
repacked local tarball) were reported as "Already up to date". Projects
with local file dependencies (`file:` and bare local path or tarball
specifiers, declared directly or through `pnpm.overrides`) now always
run a full install, which refetches those dependencies, matching pnpm
v10 behavior
[#​11795](https://redirect.github.com/pnpm/pnpm/issues/11795).
- [`4ca9247`](https://redirect.github.com/pnpm/pnpm/commit/4ca9247):
Preserve the existing Node.js runtime version prefix when resolving
`node@runtime:<range>` to a concrete version.
- [`30c7590`](https://redirect.github.com/pnpm/pnpm/commit/30c7590):
Create shorter CAFS temporary package directories to leave room for
lifecycle scripts that create IPC socket paths under TMPDIR.
- [`13815ad`](https://redirect.github.com/pnpm/pnpm/commit/13815ad):
Reporter output (warnings, progress) for `pnpm store` and `pnpm config`
subcommands now goes to stderr instead of stdout. This fixes scripts
that capture their stdout (e.g. `PNPM_STORE=$(pnpm store path)`, `pnpm
config list --json | jq`) from getting warnings mixed into the result.
- [`1c05876`](https://redirect.github.com/pnpm/pnpm/commit/1c05876):
Avoid relinking unchanged child dependencies and remove stale child
links during warm installs.
- [`817f99d`](https://redirect.github.com/pnpm/pnpm/commit/817f99d):
Fixed lockfile churn where a package's `transitivePeerDependencies`
could be dropped (and shift between packages) when the package
participates in a dependency cycle. A cycle re-entry resolves against
truncated children, so it must not be cached as "pure"; otherwise
sibling occurrences of the same package short-circuit and lose
transitive peers depending on traversal order
[#​5108](https://redirect.github.com/pnpm/pnpm/issues/5108).
- [`eba03e0`](https://redirect.github.com/pnpm/pnpm/commit/eba03e0): Fix
`pnpm install` reporting "Already up to date" after a catalog entry in
`pnpm-workspace.yaml` was reverted to a previous version. After an
update modified a catalog, the workspace state cache stored the
pre-update catalog versions, so reverting the entry back to its original
version was not detected as an outdated state
[#​12418](https://redirect.github.com/pnpm/pnpm/issues/12418).
- [`3b54d79`](https://redirect.github.com/pnpm/pnpm/commit/3b54d79):
`pnpm update` now keeps lockfile `overrides` that resolve through a
catalog in sync with the catalog. Previously, when an override
referenced a catalog (e.g. `overrides: { foo: 'catalog:' }`) and `pnpm
update` bumped that catalog entry, the lockfile's `catalogs` advanced
while the resolved `overrides` kept the old version. The resulting
lockfile was internally inconsistent, so a later `pnpm install
--frozen-lockfile` failed with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH`.
- [`9d0a300`](https://redirect.github.com/pnpm/pnpm/commit/9d0a300):
Fixed `pnpm version --recursive` so it honors the workspace selection.
In recursive mode the version bump now applies to the packages resolved
from the workspace filter (`selectedProjectsGraph`), matching the
behavior of `pnpm publish --recursive`, instead of always bumping every
workspace package
[#​11348](https://redirect.github.com/pnpm/pnpm/issues/11348).
###
[`v11.7.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1170)
[Compare
Source](https://redirect.github.com/pnpm/pnpm/compare/v11.6.0...v11.7.0)
##### Minor Changes
- Added a new setting `frozenStore` (`--frozen-store`) that lets `pnpm
install` run against a package store on a read-only filesystem (e.g. a
Nix store, a read-only bind mount, an OCI layer). When enabled, pnpm
opens the store's SQLite `index.db` through the `immutable=1` URI —
bypassing the WAL/`-shm` sidecar creation that otherwise fails on a
read-only directory — and suppresses every store-write path (the
`index.db` writer and the project-registry write). Pair it with
`--offline --frozen-lockfile` against a fully-populated store. Under the
global virtual store, package directories live inside the store, so if
the store is missing the build output of a package whose lifecycle
scripts are approved (or that has a patch), pnpm fails up front with
`ERR_PNPM_FROZEN_STORE_NEEDS_BUILD` rather than crashing mid-build on a
read-only write — seed the store with those builds first. Incompatible
with `--force` and with a configured pnpr server, since both write into
the store; the side-effects cache is likewise not written under
`frozenStore`. If the store is missing its content directory, the
install fails fast with `ERR_PNPM_FROZEN_STORE_INCOMPLETE` rather than
attempting to initialize it. The read-only `immutable=1` open requires
Node.js >=22.15.0, >=23.11.0, or >=24.0.0; on older runtimes
`--frozen-store` fails with a clear
`ERR_PNPM_FROZEN_STORE_UNSUPPORTED_NODE` error. Bin-linking also
tolerates a read-only store: under the global virtual store a package's
bin source lives inside the store, so the `chmod` that makes it
executable would be refused — with `EPERM`/`EACCES`, or with `EROFS` on
a genuinely read-only filesystem. That `chmod` is redundant when the
seed already ships its bins executable with a normalized shebang, so it
is now skipped in that case, while a non-executable bin (or one still
carrying a Windows CRLF shebang) on a read-only store still errors.
- When
[`pacquet`](https://redirect.github.com/pnpm/pnpm/tree/main/pacquet)
(the Rust port of pnpm) is declared in `configDependencies`, pnpm now
delegates dependency **resolution** to it too — not just materialization
— provided the installed pacquet is new enough to support full resolving
installs (>= 0.11.7).
Previously pacquet only ran in frozen-install mode: pnpm always resolved
the dependency graph itself (writing `pnpm-lock.yaml`) and handed
pacquet a finished lockfile to fetch / import / link. With pacquet >=
0.11.7, a non-frozen `pnpm install` (default isolated `nodeLinker`,
plain install) is delegated to pacquet end-to-end in a single pass —
pacquet resolves the manifests, writes the lockfile, and materializes
`node_modules`. pnpm detects the capability from the installed pacquet's
version; older pacquet releases keep the resolve-then-materialize split,
and `add` / `update` / `remove` still resolve in pnpm (it has to mutate
the manifests first). This remains an opt-in preview of the Rust install
engine
[#​11723](https://redirect.github.com/pnpm/pnpm/issues/11723).
- Added a new opt-in `--batch` flag to `pnpm publish --recursive` that
sends all selected packages to the registry in a single `PUT
/-/pnpm/v1/publish` request instead of one request per package. The
target registry has to implement the batch publish endpoint (pnpr does);
registries that don't are reported with a clear
`ERR_PNPM_BATCH_PUBLISH_UNSUPPORTED` error. The batch is processed
all-or-nothing by pnpr: if any package in the batch fails validation,
none of the packages are published.
##### Patch Changes
- Reject path-traversal and reserved dependency aliases (such as
`../../../escape`, `.bin`, `.pnpm`, or `node_modules`) that come from a
lockfile rather than a freshly resolved manifest. A crafted lockfile
alias could otherwise be joined directly under a hoisted `node_modules`
directory, letting package files be written outside the intended install
root or overwrite pnpm-owned layout.
The fix adds two layers:
- The `nodeLinker: hoisted` graph builder now validates each alias at
the directory sink (`safeJoinModulesDir`), matching the validation pnpm
already performs when resolving aliases from manifests.
- The lockfile verification gate (`verifyLockfileResolutions`) now runs
an always-on, policy-independent check that rejects any importer or
snapshot dependency alias that is not a valid package name, failing the
install early — before any fetch or filesystem work — for every node
linker at once.
- Made shared package child resolution deterministic when the same
package is reached through multiple contexts. pnpm now chooses the
shallowest occurrence, then importer order, then parent path, instead of
letting request timing decide the child context and missing-peer report
[pnpm/pnpm#12358](https://redirect.github.com/pnpm/pnpm/issues/12358).
- Fix garbled summary line after submitting `pnpm update -i` and `pnpm
audit --fix -i`. The interactive checkbox prompt previously printed
every selected choice's full table row (label, current/target versions,
workspace, URL) joined by commas, producing a wall of text after
pressing Enter. The summary now lists only the selected package names
(or vulnerability keys) by setting an explicit `short` per choice; the
in-progress selection UI is unchanged.
- Prevent `pnpm patch-remove` from removing files outside the configured
patches directory.
- Fixed `pnpm publish` ignoring `strictSsl: false` when publishing to
registries with self-signed certificates. The `strictSSL` option is now
forwarded to `libnpmpublish` / `npm-registry-fetch` so that
`strict-ssl=false` in `.npmrc` or `strictSsl: false` in
`pnpm-workspace.yaml` is respected during publish, the same way it is
for `pnpm install`
[pnpm/pnpm#12012](https://redirect.github.com/pnpm/pnpm/issues/12012).
- Fixed `Cannot destructure property 'manifest' of
'manifestsByPath[rootDir]' as it is undefined` regression introduced in
11.6.0 when running `pnpm add <pkg>` outside a workspace on Windows.
`selectProjectByDir` was keying the resulting `ProjectsGraph` by
`opts.dir` instead of `project.rootDir`, so downstream `manifestsByPath`
lookups missed when the two paths normalized differently (typically
drive-letter casing).
[pnpm/pnpm#12379](https://redirect.github.com/pnpm/pnpm/issues/12379)
- Git dependencies that point to a subdirectory of a repository
(`repo#commit&path:/sub/dir`) keep their `path` in the lockfile again.
Since the integrity of git-hosted tarballs started being pinned in the
lockfile, any install that actually downloaded the tarball rebuilt the
lockfile resolution as `{ integrity, tarball, gitHosted }` and dropped
the `path` field, while installs served from the store kept it — so the
field disappeared seemingly at random. Without `path`, later installs
from that lockfile silently unpacked the repository root instead of the
subdirectory
[#​12304](https://redirect.github.com/pnpm/pnpm/issues/12304).
- Fixed nondeterministic lockfile output that made `pnpm dedupe --check`
fail intermittently in CI. When a locked peer provider was pinned for a
dependency that has no child dependencies of its own, the pinned
provider leaked into the shared parent scope, so siblings resolved after
it could pick up an optional peer they should not see. Which siblings
were affected depended on resolution order, which varies with network
timing.
- Sped up `pnpm install` with a frozen lockfile by running lockfile
verification (the policy revalidation gate added for
`minimumReleaseAge`/`trustPolicy` and the tarball-URL anti-tamper check)
concurrently with fetching and linking instead of blocking the whole
install on it. Dependency lifecycle scripts are still held back until
verification succeeds, so no script runs on an unverified lockfile: if
verification fails the install aborts before any dependency build, and
if linking finishes first the install waits for the verification verdict
before completing.
- User-defined `npm_config_*` environment variables are now preserved
during lifecycle script execution. Previously, all `npm_`-prefixed env
vars were stripped, which caused user-set variables like
`npm_config_platform_arch` to be lost
[pnpm/pnpm#12399](https://redirect.github.com/pnpm/pnpm/issues/12399).
- pnpm can now use different auth tokens for different package scopes,
even when those scopes use the same registry URL.
Previously, auth was selected only by registry URL. If `@org-a` and
`@org-b` both used `https://npm.pkg.github.com/`, they had to share the
same token. This caused problems for registries that issue tokens per
organization or per scope.
Configure a scope-specific token by adding the package scope after the
registry URL in the auth key:
```ini
@​org-a:registry=https://npm.pkg.github.com/
@​org-b:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:@​org-a:_authToken=${ORG_A_TOKEN}
//npm.pkg.github.com/:@​org-b:_authToken=${ORG_B_TOKEN}
//npm.pkg.github.com/:_authToken=${FALLBACK_TOKEN}
```
`pnpm login --registry=https://npm.pkg.github.com --scope=@​org-a`
writes the token to the same scope-specific auth key.
When installing or publishing `@org-a/*`, pnpm uses `ORG_A_TOKEN`. For
`@org-b/*`, pnpm uses `ORG_B_TOKEN`. Packages without a matching scope
continue to use the registry-wide fallback token.
- `pnpm setup` no longer prompts to approve build scripts for
`@pnpm/exe` when installing the standalone executable. pnpm links the
platform-specific binary itself, so the package's install scripts are
skipped during the global self-install
[#​12377](https://redirect.github.com/pnpm/pnpm/issues/12377).
- Close lockfile reads deterministically before rewriting lockfiles and
keep pacquet's virtual store directory length aligned with pnpm on
Windows.
- A `304 Not Modified` answer from the registry now renews the cached
metadata file's mtime, so the `minimumReleaseAge` freshness shortcut
keeps serving resolutions from the cache. Previously, once a cached
packument grew older than `minimumReleaseAge`, every subsequent install
re-validated it against the registry forever, because a 304 never
rewrites the file.
- Updated dependency ranges. Notably:
- `@pnpm/logger` peer dependency range moved to `^1100.0.0`.
- `msgpackr` 1.11.8 → 2.0.4 (store index files remain byte-compatible in
both directions).
- `open` ^7.4.2 → ^11.0.0, `memoize` ^10 → ^11, `cli-truncate` ^5 → ^6,
`pidtree` ^0.6 → ^1.
- `@yarnpkg/core` 4.5.0 → 4.8.0, `@rushstack/worker-pool` 0.7.7 →
0.7.18, `@cyclonedx/cyclonedx-library` 10.0.0 → 10.1.0,
`@pnpm/config.nerf-dart` ^1 → ^2, `@pnpm/log.group` 3.0.2 → 4.0.1,
`@pnpm/util.lex-comparator` ^3 → ^4.
- Updated `@zkochan/cmd-shim` to v9.0.6.
- Fixed a Windows-only hang where a failed command could take 20–46
seconds to exit. On error, pnpm enumerates descendant processes (via
`pidtree`) to terminate them, which on Windows shells out to
`wmic`/PowerShell `Get-CimInstance Win32_Process` — a lookup that is
extremely slow on some machines. The lookup is now bounded by a short
timeout so it can no longer stall the process exit.
###
[`v11.6.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1160)
[Compare
Source](https://redirect.github.com/pnpm/pnpm/compare/v11.5.3...v11.6.0)
##### Minor Changes
- `pnpm install` completes without re-resolving when `pnpm-lock.yaml`
was deleted but `node_modules` is intact: the up-to-date check now
treats the current lockfile (`node_modules/.pnpm/lock.yaml`) — the
record of what the previous install materialized — as the wanted
lockfile, verifies the manifests still match it, restores
`pnpm-lock.yaml` from it, and reports "Already up to date". Previously
this scenario triggered a full resolution and a re-verification of every
locked package against the registry.
- [`615c669`](https://redirect.github.com/pnpm/pnpm/commit/615c669):
Added support for configuring URL-scoped registry settings through
`npm_config_//…` and `pnpm_config_//…` environment variables, for
example:
```text
npm_config_//registry.npmjs.org/:_authToken=<token>
pnpm_config_//registry.npmjs.org/:_authToken=<token>
```
This provides a file-free way to supply registry authentication. Because
the registry a value applies to is encoded in the (trusted) environment
variable name, it is host-scoped by construction and cannot be
redirected to another registry by repository-controlled config. The
environment value is treated as trusted config: it takes precedence over
a project/workspace `.npmrc` but is still overridden by command-line
options. When the same key is provided through both prefixes,
`pnpm_config_` wins.
- Raised the default network concurrency from `min(64, max(cpuCores * 3,
16))` to `min(96, max(cpuCores * 3, 64))`. Package downloads are
I/O-bound, not CPU-bound, so deriving the floor from the core count left
machines with few cores (for example 4-vCPU CI runners) downloading only
16 tarballs at a time and unable to saturate a low-latency registry. The
`networkConcurrency` setting still overrides the default.
##### Patch Changes
- Improved the warning printed when a project `.npmrc` uses an
environment variable in a registry/proxy URL or in registry credentials.
The message now explains why the setting was ignored and how to migrate
it to a trusted source — for example by moving the line to the
user-level `~/.npmrc` or running `pnpm config set "<key>" <value>` —
with a link to <https://pnpm.io/npmrc>. The `pnpm config set` example is
only suggested when the key has no `${...}` placeholder, so the snippet
is always safe to copy-paste.
- Print a "Lockfile passes supply-chain policies (verified 2h ago)"
message when lockfile verification is skipped bec
> ✂ **Note**
>
> PR body was truncated to here.
</details>
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/formatjs/rules_formatjs).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMTkuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI0Mi4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Long Ho <longlho@users.noreply.github.com>1 parent c0c6c54 commit 82ee345
2 files changed
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
15 | 15 | | |
0 commit comments