pnpm update wrote the new version of an `=`-pinned dependency back as the bare version, dropping the explicit operator (`=3.5.1` became `3.5.2`). The two spellings are the same semver range, but the `=` form marks the pin as deliberate, so the update should keep it. The save-style enum (formerly PinnedVersion) gains an `exact` variant and is renamed to RangeSpecStyle: it selects the operator a specifier is saved with, not a pin granularity. inferRangeSpecStyle (formerly whichVersionIsPinned) classifies a bare `=` before a full version as `exact` (partial `=1.0` / `=1` keep pinning like the plain version they prefix), and the specifier formatters emit `=` for it. A granularity projection (rangeSpecGranularity / RangeSpecStyle::granularity) collapses `exact` to `patch` for consumers that only care about range width, such as the save-workspace-protocol: rolling mapping, where an `=` pin maps to `workspace:*` like other exact pins. `@pnpm/types` keeps PinnedVersion as a deprecated alias and stays declaration-only; the shared helpers live in `@pnpm/pkg-manifest.utils`. save-prefix now accepts `=`, saving new dependencies as `=x.y.z`; --save-exact still wins and saves the bare version. Implemented in both the TypeScript CLI and the Rust port. Closes pnpm/pnpm#13168 --------- Co-authored-by: Zoltan Kochan <z@kochan.io>
@pnpm/resolving.resolver-base
Types for pnpm-compatible resolvers
Installation
pnpm add @pnpm/resolving.resolver-base
Usage
Here's a template of a resolver using types from @pnpm/resolving.resolver-base:
import {
ResolveOptions,
ResolveResult,
WantedDependency,
} from '@pnpm/resolving.resolver-base'
export async function testResolver (
wantedDependency: WantedDependency,
opts: ResolveOptions,
): Promise<ResolveResult> {
// ...
return {
id,
resolution,
package,
latest,
normalizedBareSpecifier,
}
}
License
MIT