@pnpm/installing.deps-resolver 1100.2.2 → 1100.2.4

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.
@@ -5,7 +5,7 @@ import type { PreferredVersions, Resolution, ResolutionPolicyViolation, Workspac
5
5
  import type { StoreController } from '@pnpm/store.controller-types';
6
6
  import type { AllowBuild, AllowedDeprecatedVersions, PinnedVersion, PkgResolutionId, ProjectId, ProjectManifest, ProjectRootDir, ReadPackageHook, Registries, SupportedArchitectures, TrustPolicy } from '@pnpm/types';
7
7
  import type { WantedDependency } from './getNonDevWantedDependencies.js';
8
- import { type NodeId } from './nextNodeId.js';
8
+ import type { NodeId } from './nextNodeId.js';
9
9
  import { type DependenciesTree, type LinkedDependency, type ResolvedPackage, type ResolvedPkgsById } from './resolveDependencies.js';
10
10
  export type { DependenciesTree, DependenciesTreeNode, LinkedDependency, ResolvedPackage } from './resolveDependencies.js';
11
11
  export interface ResolvedImporters {
@@ -3,9 +3,7 @@ import { createPackageVersionPolicyOrThrow, getPublishedByPolicy } from '@pnpm/c
3
3
  import { globalWarn } from '@pnpm/logger';
4
4
  import { BUILTIN_NAMED_REGISTRIES } from '@pnpm/resolving.npm-resolver';
5
5
  import { partition } from 'ramda';
6
- import { nextNodeId } from './nextNodeId.js';
7
- import { parentIdsContainSequence } from './parentIdsContainSequence.js';
8
- import { resolveRootDependencies, } from './resolveDependencies.js';
6
+ import { buildTree, resolveRootDependencies, } from './resolveDependencies.js';
9
7
  export async function resolveDependencyTree(importers, opts) {
10
8
  const wantedToBeSkippedPackageIds = new Set();
11
9
  const autoInstallPeers = opts.autoInstallPeers === true;
@@ -57,6 +55,14 @@ export async function resolveDependencyTree(importers, opts) {
57
55
  allPeerDepNames: new Set(),
58
56
  maximumPublishedBy: publishedBy,
59
57
  publishedByExclude,
58
+ packageResolutionBarrier: {
59
+ activeByDepth: new Map(),
60
+ waiters: [],
61
+ },
62
+ childrenResolutionByPkgId: {},
63
+ childrenResolutionId: 0,
64
+ importerResolutionOrder: Object.fromEntries(importers.map(({ id }, index) => [id, index])),
65
+ nodeResolutionContextByNodeId: new Map(),
60
66
  trustPolicy: opts.trustPolicy,
61
67
  trustPolicyExclude: opts.trustPolicyExclude ? createPackageVersionPolicyOrThrow(opts.trustPolicyExclude, 'trustPolicyExclude') : undefined,
62
68
  trustPolicyIgnoreAfter: opts.trustPolicyIgnoreAfter,
@@ -176,32 +182,6 @@ export async function resolveDependencyTree(importers, opts) {
176
182
  resolutionPolicyViolations: ctx.resolutionPolicyViolations,
177
183
  };
178
184
  }
179
- function buildTree(ctx, parentId, parentIds, children, depth, installable) {
180
- const childrenNodeIds = {};
181
- for (const child of children) {
182
- if (child.id.startsWith('link:')) {
183
- childrenNodeIds[child.alias] = child.id;
184
- continue;
185
- }
186
- if (parentIdsContainSequence(parentIds, parentId, child.id) || parentId === child.id) {
187
- continue;
188
- }
189
- if (ctx.resolvedPkgsById[child.id].isLeaf) {
190
- childrenNodeIds[child.alias] = child.id;
191
- continue;
192
- }
193
- const childNodeId = nextNodeId();
194
- childrenNodeIds[child.alias] = childNodeId;
195
- installable = installable || !ctx.skipped.has(child.id);
196
- ctx.dependenciesTree.set(childNodeId, {
197
- children: () => buildTree(ctx, child.id, [...parentIds, child.id], ctx.childrenByParentId[child.id], depth + 1, installable),
198
- depth,
199
- installable,
200
- resolvedPackage: ctx.resolvedPkgsById[child.id],
201
- });
202
- }
203
- return childrenNodeIds;
204
- }
205
185
  /**
206
186
  * There may be cases where multiple dependencies have the same alias in the directDeps array.
207
187
  * E.g., when there is "is-negative: github:kevva/is-negative#1.0.0" in the package.json dependencies,
@@ -259,10 +259,11 @@ async function resolvePeersOfNode(currentAlias, nodeId, parentParentPkgs, ctx) {
259
259
  parentPkgs = { ...parentParentPkgs };
260
260
  const parentPkgNodes = [];
261
261
  for (const [alias, nodeId] of Object.entries(children)) {
262
- if (ctx.allPeerDepNames.has(alias)) {
262
+ const childNode = ctx.dependenciesTree.get(nodeId);
263
+ if (ctx.allPeerDepNames.has(alias) || (alias !== childNode.resolvedPackage.name && ctx.allPeerDepNames.has(childNode.resolvedPackage.name))) {
263
264
  parentPkgNodes.push({
264
265
  alias,
265
- node: ctx.dependenciesTree.get(nodeId),
266
+ node: childNode,
266
267
  nodeId,
267
268
  parentNodeIds,
268
269
  });
@@ -320,6 +321,15 @@ async function resolvePeersOfNode(currentAlias, nodeId, parentParentPkgs, ctx) {
320
321
  ctx.pathsByNodeIdPromises.set(peerNodeId, peerPathPromise);
321
322
  ctx.pathsByNodeId.set(peerNodeId, previousPeerDepPath);
322
323
  peerPathPromise.resolve(previousPeerDepPath);
324
+ // Pinning writes into parentPkgs, and a childless node shares the object
325
+ // with its parent, so siblings processed later would see the pinned
326
+ // provider too. Copy before the first write to keep the pin scoped to
327
+ // this node — sibling order follows resolution order, so a leak makes the
328
+ // lockfile depend on network timing. Done here, not before the loop, so a
329
+ // pass whose guards skip every entry never allocates.
330
+ if (parentPkgs === parentParentPkgs) {
331
+ parentPkgs = { ...parentParentPkgs };
332
+ }
323
333
  parentPkgs[peerName] = lockedPeer;
324
334
  }
325
335
  }
@@ -382,7 +392,18 @@ async function resolvePeersOfNode(currentAlias, nodeId, parentParentPkgs, ctx) {
382
392
  }
383
393
  let cache;
384
394
  const isPure = allResolvedPeers.size === 0 && allMissingPeers.size === 0;
385
- if (isPure) {
395
+ // A cycle re-entry resolves against truncated children (the cycle is broken by
396
+ // dropping the repeated package's subtree), so its empty/partial peer sets are
397
+ // not authoritative for the package as a whole. Recording that verdict — as
398
+ // pure or in peersCache — lets it short-circuit other occurrences that *can*
399
+ // see the full subtree, dropping their transitivePeerDependencies depending on
400
+ // traversal order and churning the lockfile (https://github.com/pnpm/pnpm/issues/5108).
401
+ const resolvedThroughCycle = ctx.parentDepPathsChain.includes(resolvedPackage.pkgIdWithPatchHash);
402
+ if (resolvedThroughCycle) {
403
+ // Leave both caches untouched so later occurrences re-resolve (or hit the
404
+ // authoritative entry of the same package) instead of reusing this partial one.
405
+ }
406
+ else if (isPure) {
386
407
  ctx.purePkgs.add(resolvedPackage.pkgIdWithPatchHash);
387
408
  }
388
409
  else {
@@ -48,7 +48,7 @@ export async function toResolveImporter(opts, project) {
48
48
  ...project.wantedDependencies.map(defaultUpdateDepth < 0
49
49
  ? updateLocalTarballs
50
50
  : (dep) => ({ ...dep, updateDepth: defaultUpdateDepth })),
51
- ...existingDeps.map(opts.noDependencySelectors && project.updateMatching != null
51
+ ...existingDeps.map(project.updateMatching != null
52
52
  ? updateLocalTarballs
53
53
  : (dep) => ({ ...dep, updateDepth: -1 })),
54
54
  ];
@@ -10,7 +10,7 @@ export async function updateProjectManifest(importer, opts) {
10
10
  return {
11
11
  alias: rdd.alias,
12
12
  peer: importer.peer,
13
- bareSpecifier: rdd.catalogLookup?.userSpecifiedBareSpecifier ?? rdd.normalizedBareSpecifier ?? wantedDep.bareSpecifier,
13
+ bareSpecifier: getBareSpecifierToSave(wantedDep, rdd, opts.preserveWorkspaceProtocol),
14
14
  resolvedVersion: rdd.version,
15
15
  pinnedVersion: importer.pinnedVersion,
16
16
  saveType: importer.targetDependenciesField,
@@ -31,4 +31,19 @@ export async function updateProjectManifest(importer, opts) {
31
31
  : undefined;
32
32
  return [hookedManifest, originalManifest];
33
33
  }
34
+ function getBareSpecifierToSave(wantedDep, resolvedDep, preserveWorkspaceProtocol) {
35
+ if (resolvedDep.catalogLookup != null) {
36
+ return resolvedDep.catalogLookup.userSpecifiedBareSpecifier;
37
+ }
38
+ if (preserveWorkspaceProtocol && isWorkspaceLocalPathSpecifier(wantedDep.bareSpecifier)) {
39
+ return wantedDep.bareSpecifier;
40
+ }
41
+ return resolvedDep.normalizedBareSpecifier ?? wantedDep.bareSpecifier;
42
+ }
43
+ function isWorkspaceLocalPathSpecifier(bareSpecifier) {
44
+ if (!bareSpecifier.startsWith('workspace:'))
45
+ return false;
46
+ const pref = bareSpecifier.slice('workspace:'.length);
47
+ return pref.startsWith('.') || pref.startsWith('/') || pref.startsWith('~/') || /^[A-Z]:/i.test(pref);
48
+ }
34
49
  //# sourceMappingURL=updateProjectManifest.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/installing.deps-resolver",
3
- "version": "1100.2.2",
3
+ "version": "1100.2.4",
4
4
  "description": "Resolves dependency graph of a package",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -27,8 +27,8 @@
27
27
  "!*.map"
28
28
  ],
29
29
  "dependencies": {
30
- "@pnpm/util.lex-comparator": "^3.0.2",
31
- "@yarnpkg/core": "4.5.0",
30
+ "@pnpm/util.lex-comparator": "^4.0.1",
31
+ "@yarnpkg/core": "4.8.0",
32
32
  "graph-cycles": "3.0.0",
33
33
  "is-inner-link": "^5.0.0",
34
34
  "is-subdir": "^2.0.0",
@@ -39,46 +39,46 @@
39
39
  "ramda": "npm:@pnpm/ramda@0.28.1",
40
40
  "rename-overwrite": "^7.0.1",
41
41
  "safe-promise-defer": "^2.0.0",
42
- "semver": "^7.8.1",
42
+ "semver": "^7.8.4",
43
43
  "semver-range-intersect": "^0.3.1",
44
44
  "validate-npm-package-name": "7.0.2",
45
45
  "version-selector-type": "^3.0.0",
46
- "@pnpm/catalogs.types": "1100.0.0",
47
- "@pnpm/catalogs.resolver": "1100.0.0",
48
- "@pnpm/config.version-policy": "1100.1.4",
49
- "@pnpm/core-loggers": "1100.2.0",
50
46
  "@pnpm/constants": "1100.0.0",
51
- "@pnpm/deps.graph-hasher": "1100.2.4",
52
- "@pnpm/deps.path": "1100.0.7",
53
- "@pnpm/deps.peer-range": "1100.0.1",
47
+ "@pnpm/core-loggers": "1100.2.1",
48
+ "@pnpm/deps.graph-hasher": "1100.2.5",
54
49
  "@pnpm/error": "1100.0.0",
55
- "@pnpm/fetching.pick-fetcher": "1100.0.11",
56
- "@pnpm/hooks.types": "1100.0.11",
57
- "@pnpm/lockfile.preferred-versions": "1100.0.15",
58
- "@pnpm/lockfile.pruner": "1100.0.10",
59
- "@pnpm/lockfile.utils": "1100.0.12",
60
- "@pnpm/lockfile.types": "1100.0.10",
61
- "@pnpm/patching.config": "1100.0.7",
50
+ "@pnpm/fetching.pick-fetcher": "1100.0.12",
51
+ "@pnpm/deps.peer-range": "1100.0.2",
52
+ "@pnpm/hooks.types": "1100.0.12",
53
+ "@pnpm/deps.path": "1100.0.8",
54
+ "@pnpm/config.version-policy": "1100.1.5",
55
+ "@pnpm/lockfile.preferred-versions": "1100.0.16",
56
+ "@pnpm/lockfile.types": "1100.0.11",
57
+ "@pnpm/lockfile.utils": "1100.0.13",
58
+ "@pnpm/patching.config": "1100.0.8",
59
+ "@pnpm/catalogs.types": "1100.0.0",
60
+ "@pnpm/pkg-manifest.reader": "1100.0.8",
61
+ "@pnpm/pkg-manifest.utils": "1100.2.5",
62
+ "@pnpm/resolving.npm-resolver": "1102.0.1",
63
+ "@pnpm/resolving.resolver-base": "1100.4.2",
64
+ "@pnpm/store.controller-types": "1100.1.5",
65
+ "@pnpm/types": "1101.3.2",
66
+ "@pnpm/workspace.spec-parser": "1100.0.0",
62
67
  "@pnpm/patching.types": "1100.0.0",
63
- "@pnpm/pkg-manifest.reader": "1100.0.7",
64
- "@pnpm/pkg-manifest.utils": "1100.2.4",
65
- "@pnpm/resolving.npm-resolver": "1101.5.2",
66
- "@pnpm/store.controller-types": "1100.1.4",
67
- "@pnpm/resolving.resolver-base": "1100.4.1",
68
- "@pnpm/types": "1101.3.1",
69
- "@pnpm/workspace.spec-parser": "1100.0.0"
68
+ "@pnpm/catalogs.resolver": "1100.0.0",
69
+ "@pnpm/lockfile.pruner": "1100.0.11"
70
70
  },
71
71
  "peerDependencies": {
72
- "@pnpm/logger": "^1001.0.1"
72
+ "@pnpm/logger": "^1100.0.0"
73
73
  },
74
74
  "devDependencies": {
75
- "@jest/globals": "30.3.0",
75
+ "@jest/globals": "30.4.1",
76
76
  "@types/normalize-path": "^3.0.2",
77
77
  "@types/ramda": "0.31.1",
78
78
  "@types/semver": "7.7.1",
79
79
  "@types/validate-npm-package-name": "^4.0.2",
80
- "@pnpm/logger": "1100.0.0",
81
- "@pnpm/installing.deps-resolver": "1100.2.2"
80
+ "@pnpm/installing.deps-resolver": "1100.2.4",
81
+ "@pnpm/logger": "1100.0.0"
82
82
  },
83
83
  "engines": {
84
84
  "node": ">=22.13"