@pnpm/installing.deps-resolver 1100.1.3 → 1100.1.5

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.
@@ -7,6 +7,9 @@ export interface WantedDependency {
7
7
  injected?: boolean;
8
8
  saveCatalogName?: string;
9
9
  }
10
- type GetNonDevWantedDependenciesManifest = Pick<DependencyManifest, 'bundleDependencies' | 'bundledDependencies' | 'optionalDependencies' | 'dependencies' | 'dependenciesMeta'>;
10
+ type GetNonDevWantedDependenciesManifest = Pick<DependencyManifest, 'bundleDependencies' | 'bundledDependencies' | 'optionalDependencies' | 'dependencies' | 'dependenciesMeta'> & {
11
+ name?: string;
12
+ version?: string;
13
+ };
11
14
  export declare function getNonDevWantedDependencies(pkg: GetNonDevWantedDependenciesManifest): WantedDependency[];
12
15
  export {};
@@ -1,5 +1,11 @@
1
1
  import { pickBy } from 'ramda';
2
+ import { assertValidDependencyAliases } from './validateDependencyAlias.js';
2
3
  export function getNonDevWantedDependencies(pkg) {
4
+ const pkgDescription = pkg.name != null
5
+ ? `Package "${pkg.name}${pkg.version != null ? `@${pkg.version}` : ''}"`
6
+ : 'Package';
7
+ assertValidDependencyAliases(pkg.dependencies, pkgDescription);
8
+ assertValidDependencyAliases(pkg.optionalDependencies, pkgDescription);
3
9
  let bd = pkg.bundledDependencies ?? pkg.bundleDependencies;
4
10
  if (bd === true) {
5
11
  bd = pkg.dependencies != null ? Object.keys(pkg.dependencies) : [];
@@ -1,5 +1,10 @@
1
1
  import { filterDependenciesByType } from '@pnpm/pkg-manifest.utils';
2
+ import { assertValidDependencyAliases } from './validateDependencyAlias.js';
2
3
  export function getWantedDependencies(pkg, opts) {
4
+ assertValidDependencyAliases(pkg.dependencies, 'The current package');
5
+ assertValidDependencyAliases(pkg.devDependencies, 'The current package');
6
+ assertValidDependencyAliases(pkg.optionalDependencies, 'The current package');
7
+ assertValidDependencyAliases(pkg.peerDependencies, 'The current package');
3
8
  let depsToInstall = filterDependenciesByType(pkg, opts?.includeDirect ?? {
4
9
  dependencies: true,
5
10
  devDependencies: true,
@@ -77,6 +77,7 @@ export interface ResolutionContext {
77
77
  defaultTag: string;
78
78
  dryRun: boolean;
79
79
  forceFullResolution: boolean;
80
+ updateChecksums?: boolean;
80
81
  ignoreScripts?: boolean;
81
82
  resolvedPkgsById: ResolvedPkgsById;
82
83
  resolvePeersFromWorkspaceRoot?: boolean;
@@ -450,6 +450,7 @@ async function resolveDependenciesOfDependency(ctx, preferredVersions, options,
450
450
  proceed: extendedWantedDep.proceed || updateShouldContinue || ctx.updatedSet.size > 0,
451
451
  publishedBy: options.publishedBy,
452
452
  update: update ? options.updateToLatest ? 'latest' : 'compatible' : false,
453
+ updateChecksums: ctx.updateChecksums,
453
454
  updateDepth,
454
455
  updateRequested,
455
456
  supportedArchitectures: options.supportedArchitectures,
@@ -785,6 +786,7 @@ async function resolveDependency(wantedDependency, ctx, options) {
785
786
  trustPolicyExclude: ctx.trustPolicyExclude,
786
787
  trustPolicyIgnoreAfter: ctx.trustPolicyIgnoreAfter,
787
788
  update: options.update,
789
+ updateChecksums: options.updateChecksums,
788
790
  workspacePackages: ctx.workspacePackages,
789
791
  supportedArchitectures: options.supportedArchitectures,
790
792
  onFetchError: (err) => {
@@ -76,6 +76,7 @@ export interface ResolveDependenciesOptions {
76
76
  engineStrict: boolean;
77
77
  force: boolean;
78
78
  forceFullResolution: boolean;
79
+ updateChecksums?: boolean;
79
80
  ignoreScripts?: boolean;
80
81
  hooks: {
81
82
  readPackage?: ReadPackageHook;
@@ -24,6 +24,7 @@ export async function resolveDependencyTree(importers, opts) {
24
24
  engineStrict: opts.engineStrict,
25
25
  force: opts.force,
26
26
  forceFullResolution: opts.forceFullResolution,
27
+ updateChecksums: opts.updateChecksums,
27
28
  ignoreScripts: opts.ignoreScripts,
28
29
  injectWorkspacePackages: opts.injectWorkspacePackages,
29
30
  linkWorkspacePackagesDepth: opts.linkWorkspacePackagesDepth ?? -1,
@@ -361,8 +361,15 @@ async function resolvePeersOfNode(currentAlias, nodeId, parentParentPkgs, ctx) {
361
361
  };
362
362
  async function calculateDepPath(peerIds, pendingPeerNodes, cycles) {
363
363
  const cyclicPeerAliases = new Set();
364
+ const pendingPeerAliases = new Set(pendingPeerNodes.map(({ alias }) => alias));
364
365
  for (const cycle of cycles) {
365
- if (cycle.includes(currentAlias)) {
366
+ // A cycle has to be short-circuited at this level whenever any of
367
+ // its members is involved in the current resolution — either as
368
+ // currentAlias or among the pending peers we are about to await.
369
+ // When a cycle member hits the `findHit` cache instead of running
370
+ // its own calculateDepPath, only the awaiting siblings at this
371
+ // level can release the cached promise. See pnpm/pnpm#11999.
372
+ if (cycle.includes(currentAlias) || cycle.some((alias) => pendingPeerAliases.has(alias))) {
366
373
  for (const peerAlias of cycle) {
367
374
  cyclicPeerAliases.add(peerAlias);
368
375
  }
@@ -0,0 +1,2 @@
1
+ export declare function isValidDependencyAlias(alias: string): boolean;
2
+ export declare function assertValidDependencyAliases(deps: Record<string, unknown> | undefined, parentPkgDescription: string): void;
@@ -0,0 +1,24 @@
1
+ import { PnpmError } from '@pnpm/error';
2
+ import validateNpmPackageName from 'validate-npm-package-name';
3
+ // An alias is the directory name pnpm creates inside `node_modules`, so
4
+ // it must be a valid npm package name. Anything else (path-traversal
5
+ // shapes such as `@x/../../../../../.git/hooks`, control characters,
6
+ // names that collide with pnpm's own `node_modules` layout such as
7
+ // `.bin` / `.pnpm` / `node_modules`) is rejected. Matches the
8
+ // `validForOldPackages` check `parseWantedDependency` applies to
9
+ // CLI-given names.
10
+ export function isValidDependencyAlias(alias) {
11
+ return typeof alias === 'string' && validateNpmPackageName(alias).validForOldPackages;
12
+ }
13
+ export function assertValidDependencyAliases(deps, parentPkgDescription) {
14
+ if (deps == null)
15
+ return;
16
+ for (const alias of Object.keys(deps)) {
17
+ if (!isValidDependencyAlias(alias)) {
18
+ throw new PnpmError('INVALID_DEPENDENCY_NAME', `${parentPkgDescription} contains a dependency with an invalid name: ${JSON.stringify(alias)}`, {
19
+ hint: 'A dependency name must be a valid npm package name — a single `name` or `@scope/name` consisting of URL-friendly characters, with no leading `.` or `_`, and not equal to reserved names such as `node_modules`.',
20
+ });
21
+ }
22
+ }
23
+ }
24
+ //# sourceMappingURL=validateDependencyAlias.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/installing.deps-resolver",
3
- "version": "1100.1.3",
3
+ "version": "1100.1.5",
4
4
  "description": "Resolves dependency graph of a package",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -36,44 +36,46 @@
36
36
  "ramda": "npm:@pnpm/ramda@0.28.1",
37
37
  "rename-overwrite": "^7.0.1",
38
38
  "safe-promise-defer": "^2.0.0",
39
- "semver": "^7.7.2",
39
+ "semver": "^7.8.1",
40
40
  "semver-range-intersect": "^0.3.1",
41
+ "validate-npm-package-name": "7.0.2",
41
42
  "version-selector-type": "^3.0.0",
43
+ "@pnpm/catalogs.types": "1100.0.0",
44
+ "@pnpm/config.version-policy": "1100.1.2",
42
45
  "@pnpm/catalogs.resolver": "1100.0.0",
43
- "@pnpm/config.version-policy": "1100.1.1",
44
- "@pnpm/core-loggers": "1100.1.1",
45
46
  "@pnpm/constants": "1100.0.0",
46
- "@pnpm/deps.path": "1100.0.4",
47
- "@pnpm/catalogs.types": "1100.0.0",
48
- "@pnpm/deps.graph-hasher": "1100.2.1",
47
+ "@pnpm/deps.graph-hasher": "1100.2.2",
48
+ "@pnpm/deps.path": "1100.0.5",
49
+ "@pnpm/core-loggers": "1100.1.2",
49
50
  "@pnpm/deps.peer-range": "1100.0.1",
51
+ "@pnpm/fetching.pick-fetcher": "1100.0.9",
50
52
  "@pnpm/error": "1100.0.0",
51
- "@pnpm/lockfile.preferred-versions": "1100.0.11",
52
- "@pnpm/hooks.types": "1100.0.8",
53
- "@pnpm/fetching.pick-fetcher": "1100.0.8",
54
- "@pnpm/lockfile.pruner": "1100.0.7",
55
- "@pnpm/lockfile.types": "1100.0.7",
56
- "@pnpm/patching.config": "1100.0.4",
57
- "@pnpm/lockfile.utils": "1100.0.9",
53
+ "@pnpm/hooks.types": "1100.0.9",
54
+ "@pnpm/lockfile.pruner": "1100.0.8",
55
+ "@pnpm/lockfile.preferred-versions": "1100.0.12",
56
+ "@pnpm/lockfile.types": "1100.0.8",
57
+ "@pnpm/patching.config": "1100.0.5",
58
58
  "@pnpm/patching.types": "1100.0.0",
59
- "@pnpm/pkg-manifest.reader": "1100.0.4",
60
- "@pnpm/pkg-manifest.utils": "1100.2.0",
61
- "@pnpm/resolving.npm-resolver": "1101.3.2",
62
- "@pnpm/resolving.resolver-base": "1100.3.0",
63
- "@pnpm/store.controller-types": "1100.1.1",
64
- "@pnpm/types": "1101.1.1",
65
- "@pnpm/workspace.spec-parser": "1100.0.0"
59
+ "@pnpm/lockfile.utils": "1100.0.10",
60
+ "@pnpm/pkg-manifest.reader": "1100.0.5",
61
+ "@pnpm/resolving.npm-resolver": "1101.4.0",
62
+ "@pnpm/pkg-manifest.utils": "1100.2.1",
63
+ "@pnpm/resolving.resolver-base": "1100.3.1",
64
+ "@pnpm/types": "1101.2.0",
65
+ "@pnpm/workspace.spec-parser": "1100.0.0",
66
+ "@pnpm/store.controller-types": "1100.1.2"
66
67
  },
67
68
  "peerDependencies": {
68
- "@pnpm/logger": ">=1001.0.0 <1002.0.0"
69
+ "@pnpm/logger": "^1001.0.1"
69
70
  },
70
71
  "devDependencies": {
71
72
  "@jest/globals": "30.3.0",
72
73
  "@types/normalize-path": "^3.0.2",
73
74
  "@types/ramda": "0.31.1",
74
75
  "@types/semver": "7.7.1",
75
- "@pnpm/logger": "1100.0.0",
76
- "@pnpm/installing.deps-resolver": "1100.1.3"
76
+ "@types/validate-npm-package-name": "^4.0.2",
77
+ "@pnpm/installing.deps-resolver": "1100.1.5",
78
+ "@pnpm/logger": "1100.0.0"
77
79
  },
78
80
  "engines": {
79
81
  "node": ">=22.13"