When lockfile-include-tarball-url is explicitly set to false, tarball URLs
are now always excluded from the lockfile. Previously, packages hosted under
non-standard tarball URLs would still have their tarball field written to the
lockfile even when the setting was false, causing flaky and inconsistent
behavior across environments.
The fix makes the option tri-state internally:
- true: always include tarball URLs
- false: never include tarball URLs
- undefined (not set): use the existing heuristic that includes tarball URLs
only for packages with non-standard registry URLs
close#6667
* fix: respect peer dep range in hoistPeers when preferred versions exist
Previously, hoistPeers used semver.maxSatisfying(versions, '*') which
picked the highest preferred version from the lockfile regardless of the
peer dep range. This caused overrides that narrow a peer dep range to be
ignored when a stale version existed in the lockfile.
Now hoistPeers first tries semver.maxSatisfying(versions, range) to find
a preferred version that satisfies the actual peer dep range. If none
satisfies it and autoInstallPeers is enabled, it falls back to the range
itself so pnpm resolves a matching version from the registry.
* fix: only fall back to exact-version range for overrides, handle workspace: protocol
- When no preferred version satisfies the peer dep range, only use the
range directly if it is an exact version (e.g. "4.3.0" from an override).
For semver ranges (e.g. "1", "^2.0.0"), fall back to the old behavior
of picking the highest preferred version for deduplication.
- Guard against workspace: protocol ranges that would cause
semver.maxSatisfying to throw.
- Add unit tests for hoisting deduplication and workspace: ranges.
* fix: only apply range-constrained peer selection for exact versions
The previous approach used semver.maxSatisfying(versions, range) for all
peer dep ranges, which broke aliased-dependency deduplication — e.g. when
three aliases of @pnpm.e2e/peer-c existed at 1.0.0, 1.0.1, and 2.0.0,
range ^1.0.0 would pick 1.0.1 instead of 2.0.0.
Now the range-aware logic only activates when the range is an exact
version (semver.valid), which is the override case (e.g. "4.3.0").
Regular semver ranges fall back to picking the highest preferred version.
* refactor: factor out a `getRealNameAndSpec` function
* test: `pnpm add` does not modify existing catalog entries
* fix: resolve preferred version without mutating bare specifier
close#9759
* refactor: factor out a `getRealNameAndSpec` function
* fix: handle npm aliases without a bare specifier in `unwrapPackageName`
* Fix formatting in unwrapPackageName.ts