@pnpm/installing.deps-installer 1101.1.1 → 1101.1.2

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.
@@ -472,8 +472,9 @@ export async function mutateModules(projects, maybeOpts) {
472
472
  defaultCatalog: opts.catalogs?.default,
473
473
  });
474
474
  if (opts.catalogMode !== 'manual') {
475
- const catalogBareSpecifier = `catalog:${opts.saveCatalogName == null || opts.saveCatalogName === 'default' ? '' : opts.saveCatalogName}`;
476
475
  for (const wantedDep of wantedDeps) {
476
+ const perDepCatalogName = getPerDepCatalogName(wantedDep, opts.saveCatalogName);
477
+ const catalogBareSpecifier = `catalog:${perDepCatalogName === 'default' ? '' : perDepCatalogName}`;
477
478
  const catalog = resolveFromCatalog(opts.catalogs, { ...wantedDep, bareSpecifier: catalogBareSpecifier });
478
479
  const catalogDepSpecifier = matchCatalogResolveResult(catalog, pickCatalogSpecifier);
479
480
  if (!catalogDepSpecifier ||
@@ -481,7 +482,7 @@ export async function mutateModules(projects, maybeOpts) {
481
482
  semver.validRange(wantedDep.bareSpecifier) &&
482
483
  semver.validRange(catalogDepSpecifier) &&
483
484
  semver.eq(wantedDep.bareSpecifier, catalogDepSpecifier)) {
484
- wantedDep.saveCatalogName = opts.saveCatalogName ?? 'default';
485
+ wantedDep.saveCatalogName = perDepCatalogName;
485
486
  continue;
486
487
  }
487
488
  switch (opts.catalogMode) {
@@ -791,6 +792,23 @@ function isWantedDepBareSpecifierSame(prevCatalogs, catalogsConfig, alias, prevB
791
792
  const nextCatalogEntrySpec = catalogsConfig?.[catalogName]?.[alias];
792
793
  return prevCatalogEntrySpec === nextCatalogEntrySpec;
793
794
  }
795
+ /**
796
+ * Determines the catalog name for a dependency during installSome.
797
+ *
798
+ * If the dependency's previous specifier already uses a named catalog
799
+ * (e.g. "catalog:foo"), that catalog name takes priority over the global
800
+ * saveCatalogName option. This ensures that interactive updates and
801
+ * `--latest` upgrades preserve the per-dependency catalog group.
802
+ */
803
+ function getPerDepCatalogName(wantedDep, globalSaveCatalogName) {
804
+ if (wantedDep.prevSpecifier) {
805
+ const catalogFromPrev = parseCatalogProtocol(wantedDep.prevSpecifier);
806
+ if (catalogFromPrev != null) {
807
+ return catalogFromPrev;
808
+ }
809
+ }
810
+ return globalSaveCatalogName ?? 'default';
811
+ }
794
812
  export async function addDependenciesToPackage(manifest, dependencySelectors, opts) {
795
813
  const rootDir = (opts.dir ?? process.cwd());
796
814
  const { updatedCatalogs, updatedProjects: projects, ignoredBuilds } = await mutateModules([
@@ -2,29 +2,37 @@ import { packageManifestLogger } from '@pnpm/core-loggers';
2
2
  import { DEPENDENCIES_FIELDS, } from '@pnpm/types';
3
3
  export async function removeDeps(packageManifest, removedPackages, opts) {
4
4
  if (opts.saveType) {
5
- if (packageManifest[opts.saveType] == null)
5
+ // `Object.hasOwn` rules out `__proto__`, `constructor`, etc. on `opts.saveType`,
6
+ // so the dynamic read can never land on `Object.prototype`.
7
+ if (!Object.hasOwn(packageManifest, opts.saveType))
8
+ return packageManifest;
9
+ const targetDeps = packageManifest[opts.saveType];
10
+ if (targetDeps == null)
6
11
  return packageManifest;
7
12
  for (const dependency of removedPackages) {
8
- delete packageManifest[opts.saveType][dependency];
13
+ removeOwnEntry(targetDeps, dependency);
9
14
  }
10
15
  }
11
16
  else {
12
17
  for (const depField of DEPENDENCIES_FIELDS) {
13
- if (!packageManifest[depField])
18
+ const fieldDeps = packageManifest[depField];
19
+ if (!fieldDeps)
14
20
  continue;
15
21
  for (const dependency of removedPackages) {
16
- delete packageManifest[depField][dependency];
22
+ removeOwnEntry(fieldDeps, dependency);
17
23
  }
18
24
  }
19
25
  }
20
26
  if (packageManifest.peerDependencies != null) {
27
+ const peerDeps = packageManifest.peerDependencies;
21
28
  for (const removedDependency of removedPackages) {
22
- delete packageManifest.peerDependencies[removedDependency];
29
+ removeOwnEntry(peerDeps, removedDependency);
23
30
  }
24
31
  }
25
32
  if (packageManifest.dependenciesMeta != null) {
33
+ const depsMeta = packageManifest.dependenciesMeta;
26
34
  for (const removedDependency of removedPackages) {
27
- delete packageManifest.dependenciesMeta[removedDependency];
35
+ removeOwnEntry(depsMeta, removedDependency);
28
36
  }
29
37
  }
30
38
  packageManifestLogger.debug({
@@ -33,4 +41,15 @@ export async function removeDeps(packageManifest, removedPackages, opts) {
33
41
  });
34
42
  return packageManifest;
35
43
  }
44
+ /**
45
+ * Remove an entry from a dependency-like record by its key, but only when the
46
+ * key is an own property. The `Object.hasOwn` guard keeps the `delete` from
47
+ * reaching into the prototype chain even when the dependency name matches an
48
+ * inherited property like `__proto__` or `constructor`.
49
+ */
50
+ function removeOwnEntry(target, key) {
51
+ if (Object.hasOwn(target, key)) {
52
+ delete target[key];
53
+ }
54
+ }
36
55
  //# sourceMappingURL=removeDeps.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/installing.deps-installer",
3
- "version": "1101.1.1",
3
+ "version": "1101.1.2",
4
4
  "description": "Fast, disk space efficient installation engine",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -62,60 +62,60 @@
62
62
  "ramda": "npm:@pnpm/ramda@0.28.1",
63
63
  "run-groups": "^5.0.0",
64
64
  "semver": "^7.7.2",
65
- "@pnpm/agent.client": "1.0.4",
66
- "@pnpm/bins.linker": "1100.0.5",
65
+ "@pnpm/bins.linker": "1100.0.6",
66
+ "@pnpm/agent.client": "1.0.5",
67
+ "@pnpm/building.after-install": "1101.0.12",
67
68
  "@pnpm/bins.remover": "1100.0.3",
68
- "@pnpm/building.after-install": "1101.0.11",
69
- "@pnpm/building.during-install": "1101.0.9",
70
69
  "@pnpm/building.policy": "1100.0.4",
70
+ "@pnpm/building.during-install": "1101.0.10",
71
71
  "@pnpm/catalogs.protocol-parser": "1100.0.0",
72
72
  "@pnpm/catalogs.resolver": "1100.0.0",
73
- "@pnpm/catalogs.types": "1100.0.0",
74
73
  "@pnpm/config.matcher": "1100.0.1",
74
+ "@pnpm/catalogs.types": "1100.0.0",
75
75
  "@pnpm/config.normalize-registries": "1100.0.3",
76
- "@pnpm/config.parse-overrides": "1100.0.1",
77
76
  "@pnpm/constants": "1100.0.0",
78
- "@pnpm/core-loggers": "1100.0.2",
77
+ "@pnpm/config.parse-overrides": "1100.0.1",
79
78
  "@pnpm/crypto.hash": "1100.0.1",
79
+ "@pnpm/core-loggers": "1100.0.2",
80
80
  "@pnpm/crypto.object-hasher": "1100.0.0",
81
81
  "@pnpm/deps.graph-hasher": "1100.1.5",
82
82
  "@pnpm/deps.graph-sequencer": "1100.0.0",
83
83
  "@pnpm/deps.path": "1100.0.3",
84
84
  "@pnpm/error": "1100.0.0",
85
- "@pnpm/exec.lifecycle": "1100.0.9",
85
+ "@pnpm/exec.lifecycle": "1100.0.10",
86
86
  "@pnpm/fs.read-modules-dir": "1100.0.1",
87
87
  "@pnpm/fs.symlink-dependency": "1100.0.3",
88
88
  "@pnpm/hooks.read-package-hook": "1100.0.3",
89
89
  "@pnpm/hooks.types": "1100.0.6",
90
- "@pnpm/installing.context": "1100.0.9",
91
- "@pnpm/installing.deps-resolver": "1100.0.9",
92
- "@pnpm/installing.deps-restorer": "1101.1.1",
90
+ "@pnpm/installing.deps-resolver": "1100.0.10",
91
+ "@pnpm/installing.deps-restorer": "1101.1.2",
93
92
  "@pnpm/installing.linking.direct-dep-linker": "1100.0.3",
94
- "@pnpm/installing.linking.hoist": "1100.0.5",
95
- "@pnpm/installing.linking.modules-cleaner": "1100.1.0",
93
+ "@pnpm/installing.context": "1100.0.10",
94
+ "@pnpm/installing.linking.modules-cleaner": "1100.1.1",
95
+ "@pnpm/installing.linking.hoist": "1100.0.6",
96
96
  "@pnpm/installing.modules-yaml": "1100.0.4",
97
- "@pnpm/installing.package-requester": "1101.0.5",
97
+ "@pnpm/installing.package-requester": "1101.0.6",
98
98
  "@pnpm/lockfile.filtering": "1100.1.0",
99
- "@pnpm/lockfile.fs": "1100.0.7",
100
- "@pnpm/lockfile.preferred-versions": "1100.0.8",
99
+ "@pnpm/lockfile.fs": "1100.0.8",
100
+ "@pnpm/lockfile.preferred-versions": "1100.0.9",
101
101
  "@pnpm/lockfile.pruner": "1100.0.5",
102
- "@pnpm/lockfile.settings-checker": "1100.0.9",
103
- "@pnpm/lockfile.to-pnp": "1100.0.7",
102
+ "@pnpm/lockfile.to-pnp": "1100.0.8",
103
+ "@pnpm/lockfile.settings-checker": "1100.0.10",
104
104
  "@pnpm/lockfile.utils": "1100.0.7",
105
- "@pnpm/lockfile.verification": "1100.0.9",
105
+ "@pnpm/lockfile.verification": "1100.0.10",
106
106
  "@pnpm/lockfile.walker": "1100.0.5",
107
107
  "@pnpm/patching.config": "1100.0.3",
108
- "@pnpm/pkg-manifest.utils": "1100.1.2",
109
- "@pnpm/resolving.parse-wanted-dependency": "1100.0.1",
110
108
  "@pnpm/resolving.resolver-base": "1100.1.3",
111
- "@pnpm/store.controller-types": "1100.0.6",
109
+ "@pnpm/store.controller-types": "1100.0.7",
110
+ "@pnpm/resolving.parse-wanted-dependency": "1100.0.1",
112
111
  "@pnpm/types": "1101.1.0",
113
112
  "@pnpm/store.index": "1100.1.0",
114
- "@pnpm/workspace.project-manifest-reader": "1100.0.4"
113
+ "@pnpm/pkg-manifest.utils": "1100.1.3",
114
+ "@pnpm/workspace.project-manifest-reader": "1100.0.5"
115
115
  },
116
116
  "peerDependencies": {
117
117
  "@pnpm/logger": ">=1001.0.0 <1002.0.0",
118
- "@pnpm/worker": "^1100.1.4"
118
+ "@pnpm/worker": "^1100.1.5"
119
119
  },
120
120
  "devDependencies": {
121
121
  "@jest/globals": "30.3.0",
@@ -138,21 +138,21 @@
138
138
  "symlink-dir": "^10.0.1",
139
139
  "write-json-file": "^7.0.0",
140
140
  "write-yaml-file": "^6.0.0",
141
- "@pnpm/assert-project": "1100.0.7",
142
- "@pnpm/assert-store": "1100.0.7",
143
- "@pnpm/installing.deps-installer": "1101.1.1",
141
+ "@pnpm/assert-project": "1100.0.8",
142
+ "@pnpm/installing.deps-installer": "1101.1.2",
143
+ "@pnpm/assert-store": "1100.0.8",
144
144
  "@pnpm/lockfile.types": "1100.0.5",
145
- "@pnpm/logger": "1100.0.0",
146
145
  "@pnpm/network.git-utils": "1100.0.1",
147
- "@pnpm/pkg-manifest.reader": "1100.0.3",
148
- "@pnpm/prepare": "1100.0.7",
146
+ "@pnpm/logger": "1100.0.0",
149
147
  "@pnpm/resolving.registry.types": "1100.0.3",
150
- "@pnpm/store.cafs": "1100.1.3",
148
+ "@pnpm/pkg-manifest.reader": "1100.0.3",
149
+ "@pnpm/store.cafs": "1100.1.4",
150
+ "@pnpm/prepare": "1100.0.8",
151
151
  "@pnpm/store.path": "1100.0.1",
152
152
  "@pnpm/test-fixtures": "1100.0.0",
153
153
  "@pnpm/test-ipc-server": "1100.0.0",
154
- "@pnpm/testing.mock-agent": "1100.0.3",
155
- "@pnpm/testing.temp-store": "1100.0.15"
154
+ "@pnpm/testing.mock-agent": "1100.0.4",
155
+ "@pnpm/testing.temp-store": "1100.0.16"
156
156
  },
157
157
  "engines": {
158
158
  "node": ">=22.13"