@pnpm/resolving.npm-resolver 1103.2.0 → 1103.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @pnpm/npm-resolver
2
2
 
3
+ ## 1103.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - `pnpm add` no longer re-resolves the dependency graph when `pnpm-lock.yaml` already holds a version satisfying the request — promoting a transitive dependency to a direct one, or adding to a second workspace package what a first one already depends on, now only saves the dependency in `package.json` and records its importer entry. A satisfying locked version is necessary but not sufficient: the install still falls back to a full resolution for a dist tag, an alias, a `workspace:`/`catalog:`/git/tarball specifier, `--save-peer`, an overridden package, a `catalogMode` other than `manual`, and — under `resolutionMode: time-based` or `lowest-direct`, which resolve a direct dependency to the low end of its range — a range several locked versions satisfy.
8
+
9
+ - `resolutionMode` is no longer ignored when `minimumReleaseAge` is in effect. `lowest-direct` and `time-based` pick the lowest satisfying version of a direct dependency again; previously any active release-age cutoff — including the built-in default — silently forced the highest, so `resolutionMode` only worked when `minimumReleaseAge: 0` was set explicitly [#13752](https://github.com/pnpm/pnpm/issues/13752).
10
+
11
+ - Updated dependencies:
12
+ - @pnpm/config.version-policy@1100.2.0
13
+ - @pnpm/error@1100.1.2
14
+ - @pnpm/pkg-manifest.utils@1100.4.0
15
+ - @pnpm/resolving.jsr-specifier-parser@1100.0.5
16
+ - @pnpm/store.cafs@1100.1.19
17
+ - @pnpm/store.index@1100.2.4
18
+
3
19
  ## 1103.2.0
4
20
 
5
21
  ### Minor Changes
package/lib/index.d.ts CHANGED
@@ -20,7 +20,6 @@ export declare class NoMatchingVersionError extends PnpmError {
20
20
  export declare function formatTimeAgo(date: Date): string | null;
21
21
  export { BUILTIN_NAMED_REGISTRIES, fetchMetadataFromFromRegistry, type FetchMetadataFromFromRegistryOptions, type PackageMeta, type PackageMetaCache, parseBareSpecifier, pickPackageFromMeta, pickVersionByVersionRange, type RegistryPackageSpec, RegistryResponseError, workspacePrefToNpm, };
22
22
  export { createNpmResolutionVerifier, type CreateNpmResolutionVerifierOptions } from './createNpmResolutionVerifier.js';
23
- export { inferRangeSpecStyle } from './inferRangeSpecStyle.js';
24
23
  export { MINIMUM_RELEASE_AGE_VIOLATION_CODE, TRUST_DOWNGRADE_VIOLATION_CODE, } from './violationCodes.js';
25
24
  export interface ResolverFactoryOptions {
26
25
  cacheDir: string;
package/lib/index.js CHANGED
@@ -3,7 +3,7 @@ import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
3
3
  import { isWellFormedRegistryName, RESERVED_VERSION_PREFIXES } from '@pnpm/deps.path';
4
4
  import { PnpmError } from '@pnpm/error';
5
5
  import { globalWarn } from '@pnpm/logger';
6
- import { rangeSpecGranularity, versionWithRangeSpecStyle } from '@pnpm/pkg-manifest.utils';
6
+ import { calcVersionRange, inferRangeSpecStyle, rangeSpecGranularity, versionWithRangeSpecStyle } from '@pnpm/pkg-manifest.utils';
7
7
  import { EXISTING_VERSION_SELECTOR_WEIGHT, } from '@pnpm/resolving.resolver-base';
8
8
  import { storeIndexKey } from '@pnpm/store.index';
9
9
  import { readPkgFromCafs, } from '@pnpm/worker';
@@ -16,7 +16,6 @@ import ssri from 'ssri';
16
16
  import versionSelectorType from 'version-selector-type';
17
17
  import { clearMeta, retainsFullMeta } from './clearMeta.js';
18
18
  import { fetchMetadataFromFromRegistry, RegistryResponseError } from './fetch.js';
19
- import { inferRangeSpecStyle } from './inferRangeSpecStyle.js';
20
19
  import { memoizeFetchMetadata } from './memoizeFetchMetadata.js';
21
20
  import { normalizeRegistryUrl } from './normalizeRegistryUrl.js';
22
21
  import { BUILTIN_NAMED_REGISTRIES, parseBareSpecifier, parseJsrSpecifierToRegistryPackageSpec, parseNamedRegistrySpecifierToRegistryPackageSpec, } from './parseBareSpecifier.js';
@@ -66,7 +65,6 @@ export function formatTimeAgo(date) {
66
65
  }
67
66
  export { BUILTIN_NAMED_REGISTRIES, fetchMetadataFromFromRegistry, parseBareSpecifier, pickPackageFromMeta, pickVersionByVersionRange, RegistryResponseError, workspacePrefToNpm, };
68
67
  export { createNpmResolutionVerifier } from './createNpmResolutionVerifier.js';
69
- export { inferRangeSpecStyle } from './inferRangeSpecStyle.js';
70
68
  export { MINIMUM_RELEASE_AGE_VIOLATION_CODE, TRUST_DOWNGRADE_VIOLATION_CODE, } from './violationCodes.js';
71
69
  export function createNpmResolver(fetchFromRegistry, getAuthHeader, opts) {
72
70
  if (typeof opts.cacheDir !== 'string') {
@@ -666,14 +664,13 @@ function calcSpecifier({ wantedDependency, spec, version, defaultRangeSpecStyle,
666
664
  return range;
667
665
  return `npm:${spec.name}@${range}`;
668
666
  }
667
+ /** The manifest range `version` is saved as; see {@link calcVersionRange}. */
669
668
  function calcRange(version, wantedDependency, defaultRangeSpecStyle) {
670
- if (semver.parse(version)?.prerelease.length) {
671
- return version;
672
- }
673
- const rangeSpecStyle = (wantedDependency.prevSpecifier ? inferRangeSpecStyle(wantedDependency.prevSpecifier) : undefined) ??
674
- (wantedDependency.bareSpecifier ? inferRangeSpecStyle(wantedDependency.bareSpecifier) : undefined) ??
675
- defaultRangeSpecStyle;
676
- return versionWithRangeSpecStyle(version, rangeSpecStyle ?? 'major');
669
+ return calcVersionRange(version, {
670
+ prevSpecifier: wantedDependency.prevSpecifier,
671
+ bareSpecifier: wantedDependency.bareSpecifier,
672
+ defaultRangeSpecStyle,
673
+ });
677
674
  }
678
675
  function tryResolveFromWorkspace(wantedDependency, opts) {
679
676
  if (!wantedDependency.bareSpecifier?.startsWith('workspace:')) {
@@ -58,15 +58,17 @@ function pickMax(a, b) {
58
58
  }
59
59
  const pickHighest = pickPackageFromMeta.bind(null, pickVersionByVersionRange);
60
60
  const pickLowest = pickPackageFromMeta.bind(null, pickLowestVersionByVersionRange);
61
- // When minimumReleaseAge is active: try the highest mature version; if none
62
- // satisfies the range, fall back to the lowest version regardless of maturity
63
- // so the resolver can report the violation inline and let the install layer
64
- // (or other caller) decide what to do never throw at this layer.
61
+ // `minimumReleaseAge` narrows which versions are on offer; `pickLowestVersion`
62
+ // decides which end of what is left to take. The fallback deliberately drops
63
+ // the maturity filter so a range no mature version satisfies still yields a
64
+ // pick, which the install layer reports as a violation rather than this layer
65
+ // throwing.
65
66
  function pickRespectingMinReleaseAge(pickerOpts, spec, meta) {
66
67
  return runPicker(pickerOpts, spec, (targetSpec) => {
67
- const highest = pickHighest(pickerOpts, meta, targetSpec);
68
- if (highest)
69
- return highest;
68
+ const pickMature = pickerOpts.pickLowestVersion ? pickLowest : pickHighest;
69
+ const mature = pickMature(pickerOpts, meta, targetSpec);
70
+ if (mature)
71
+ return mature;
70
72
  return pickLowest({
71
73
  preferredVersionSelectors: pickerOpts.preferredVersionSelectors,
72
74
  }, meta, targetSpec);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/resolving.npm-resolver",
3
- "version": "1103.2.0",
3
+ "version": "1103.2.1",
4
4
  "description": "Resolver for npm-hosted packages",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -31,21 +31,21 @@
31
31
  "dependencies": {
32
32
  "@pnpm/config.normalize-registries": "1100.1.0",
33
33
  "@pnpm/config.pick-registry-for-package": "1100.1.0",
34
- "@pnpm/config.version-policy": "1100.1.12",
34
+ "@pnpm/config.version-policy": "1100.2.0",
35
35
  "@pnpm/constants": "1101.0.0",
36
36
  "@pnpm/core-loggers": "1100.3.2",
37
37
  "@pnpm/crypto.hash": "1100.0.2",
38
38
  "@pnpm/deps.path": "1100.1.0",
39
- "@pnpm/error": "1100.1.1",
39
+ "@pnpm/error": "1100.1.2",
40
40
  "@pnpm/fetching.types": "1100.0.3",
41
41
  "@pnpm/fs.graceful-fs": "1100.1.1",
42
- "@pnpm/pkg-manifest.utils": "1100.3.1",
43
- "@pnpm/resolving.jsr-specifier-parser": "1100.0.4",
42
+ "@pnpm/pkg-manifest.utils": "1100.4.0",
43
+ "@pnpm/resolving.jsr-specifier-parser": "1100.0.5",
44
44
  "@pnpm/resolving.registry.pkg-metadata-filter": "1100.0.16",
45
45
  "@pnpm/resolving.registry.types": "1100.1.9",
46
46
  "@pnpm/resolving.resolver-base": "1101.1.0",
47
- "@pnpm/store.cafs": "1100.1.18",
48
- "@pnpm/store.index": "1100.2.3",
47
+ "@pnpm/store.cafs": "1100.1.19",
48
+ "@pnpm/store.index": "1100.2.4",
49
49
  "@pnpm/types": "1101.9.0",
50
50
  "@pnpm/workspace.range-resolver": "1100.0.3",
51
51
  "@pnpm/workspace.spec-parser": "1100.0.1",
@@ -59,20 +59,19 @@
59
59
  "ramda": "npm:@pnpm/ramda@0.28.1",
60
60
  "rename-overwrite": "^7.0.1",
61
61
  "semver": "^7.8.5",
62
- "semver-utils": "^1.1.4",
63
62
  "ssri": "13.0.1",
64
63
  "validate-npm-package-name": "7.0.2",
65
64
  "version-selector-type": "^3.0.0"
66
65
  },
67
66
  "peerDependencies": {
68
67
  "@pnpm/logger": "^1100.0.0",
69
- "@pnpm/worker": "^1100.2.10"
68
+ "@pnpm/worker": "^1100.2.11"
70
69
  },
71
70
  "devDependencies": {
72
71
  "@jest/globals": "30.4.1",
73
72
  "@pnpm/logger": "1100.0.0",
74
- "@pnpm/network.fetch": "1100.1.11",
75
- "@pnpm/resolving.npm-resolver": "1103.2.0",
73
+ "@pnpm/network.fetch": "1100.1.12",
74
+ "@pnpm/resolving.npm-resolver": "1103.2.1",
76
75
  "@pnpm/test-fixtures": "1100.0.1",
77
76
  "@pnpm/testing.mock-agent": "1101.0.7",
78
77
  "@types/normalize-path": "^3.0.2",
@@ -1,2 +0,0 @@
1
- import type { RangeSpecStyle } from '@pnpm/types';
2
- export declare function inferRangeSpecStyle(spec: string): RangeSpecStyle | undefined;
@@ -1,39 +0,0 @@
1
- import { parseRange } from 'semver-utils';
2
- export function inferRangeSpecStyle(spec) {
3
- // A catalog reference carries no version pinning of its own; the pinning is
4
- // defined by the catalog entry it points to. Bail out so a catalog name that
5
- // happens to look like a version (e.g. "catalog:express4-21") isn't misread
6
- // as a pinned version.
7
- if (spec.startsWith('catalog:'))
8
- return undefined;
9
- const colonIndex = spec.indexOf(':');
10
- if (colonIndex !== -1) {
11
- spec = spec.substring(colonIndex + 1);
12
- }
13
- const index = spec.lastIndexOf('@');
14
- if (index !== -1) {
15
- spec = spec.slice(index + 1);
16
- }
17
- if (spec === '*')
18
- return 'none';
19
- const parsedRange = parseRange(spec);
20
- if (parsedRange.length !== 1)
21
- return undefined;
22
- const versionObject = parsedRange[0];
23
- switch (versionObject.operator) {
24
- case '~': return 'minor';
25
- case '^': return 'major';
26
- // A bare '=' before a full version is an explicit exact pin; a partial
27
- // '=' pins the same way the plain version it prefixes does.
28
- case '=':
29
- case undefined:
30
- if (versionObject.patch)
31
- return versionObject.operator === '=' ? 'exact' : 'patch';
32
- if (versionObject.minor)
33
- return 'minor';
34
- if (versionObject.major)
35
- return 'major';
36
- }
37
- return undefined;
38
- }
39
- //# sourceMappingURL=inferRangeSpecStyle.js.map