@pnpm/installing.commands 1100.10.1 → 1100.10.3
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/lib/add.js +7 -1
- package/lib/installDeps.d.ts +10 -0
- package/lib/installDeps.js +39 -4
- package/lib/runPacquet.js +19 -15
- package/lib/update/index.js +2 -3
- package/package.json +46 -46
package/lib/add.js
CHANGED
|
@@ -5,6 +5,7 @@ import { writeSettings } from '@pnpm/config.writer';
|
|
|
5
5
|
import { PnpmError } from '@pnpm/error';
|
|
6
6
|
import { handleGlobalAdd } from '@pnpm/global.commands';
|
|
7
7
|
import { resolveConfigDeps } from '@pnpm/installing.env-installer';
|
|
8
|
+
import { parseWantedDependency } from '@pnpm/resolving.parse-wanted-dependency';
|
|
8
9
|
import { createStoreController } from '@pnpm/store.connection-manager';
|
|
9
10
|
import { pick } from 'ramda';
|
|
10
11
|
import { renderHelp } from 'render-help';
|
|
@@ -230,7 +231,12 @@ export async function handler(opts, params, commands) {
|
|
|
230
231
|
hint: 'Run "pnpm setup" to create it automatically, or set the global-bin-dir setting, or the PNPM_HOME env variable. The global bin directory should be in the PATH.',
|
|
231
232
|
});
|
|
232
233
|
}
|
|
233
|
-
|
|
234
|
+
// Normalize each selector to its package name first, so versioned
|
|
235
|
+
// forms like `pnpm@9` or `@pnpm/exe@1` can't bypass the guard.
|
|
236
|
+
if (params.some((param) => {
|
|
237
|
+
const { alias } = parseWantedDependency(param);
|
|
238
|
+
return alias === 'pnpm' || alias === '@pnpm/exe';
|
|
239
|
+
})) {
|
|
234
240
|
throw new PnpmError('GLOBAL_PNPM_INSTALL', 'Use the "pnpm self-update" command to install or update pnpm');
|
|
235
241
|
}
|
|
236
242
|
return handleGlobalAdd({
|
package/lib/installDeps.d.ts
CHANGED
|
@@ -50,3 +50,13 @@ export type InstallDepsOptions = Pick<Config, 'autoInstallPeers' | 'bail' | 'bin
|
|
|
50
50
|
isInstallCommand?: boolean;
|
|
51
51
|
} & Partial<Pick<Config, 'dryRun' | 'pnpmHomeDir' | 'strictDepBuilds' | 'useLockfile' | 'useGitBranchLockfile' | 'mergeGitBranchLockfiles'>>;
|
|
52
52
|
export declare function installDeps(opts: InstallDepsOptions, params: string[]): Promise<DryRunInstallResult | undefined>;
|
|
53
|
+
/**
|
|
54
|
+
* The `updateMatching` predicate of `pnpm audit --fix`: a package is an
|
|
55
|
+
* update target when its resolved version is vulnerable. The resolver calls
|
|
56
|
+
* it without a version when the edge has no lockfile reference — e.g. after
|
|
57
|
+
* the vulnerable pin was widened, which forgets the reference — so a
|
|
58
|
+
* version-less call matches by name against the vulnerable set: such an
|
|
59
|
+
* edge belongs to a package under vulnerability management and must
|
|
60
|
+
* re-resolve without its seeded lockfile pins.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createVulnerabilityUpdateMatching(packageVulnerabilityAudit: PackageVulnerabilityAudit): UpdateMatchingFunction;
|
package/lib/installDeps.js
CHANGED
|
@@ -7,7 +7,7 @@ import { PnpmError } from '@pnpm/error';
|
|
|
7
7
|
import { arrayOfWorkspacePackagesToMap } from '@pnpm/installing.context';
|
|
8
8
|
import { install, mutateModulesInSingleProject, } from '@pnpm/installing.deps-installer';
|
|
9
9
|
import { writeWantedLockfile } from '@pnpm/lockfile.fs';
|
|
10
|
-
import { globalInfo, logger } from '@pnpm/logger';
|
|
10
|
+
import { globalInfo, globalWarn, logger } from '@pnpm/logger';
|
|
11
11
|
import { applyRuntimeOnFailOverride, filterDependenciesByType } from '@pnpm/pkg-manifest.utils';
|
|
12
12
|
import { createStoreController } from '@pnpm/store.connection-manager';
|
|
13
13
|
import { filterProjectsBySelectorObjects } from '@pnpm/workspace.projects-filter';
|
|
@@ -20,7 +20,7 @@ import { getPinnedVersion } from './getPinnedVersion.js';
|
|
|
20
20
|
import { getSaveType } from './getSaveType.js';
|
|
21
21
|
import { handleIgnoredBuilds } from './handleIgnoredBuilds.js';
|
|
22
22
|
import { setupPolicyHandlers } from './policyHandlers.js';
|
|
23
|
-
import { createMatcher, makeIgnorePatterns, matchDependencies, recursive, } from './recursive.js';
|
|
23
|
+
import { createMatcher, makeIgnorePatterns, matchDependencies, parseUpdateParam, recursive, } from './recursive.js';
|
|
24
24
|
import { makeRunPacquet } from './runPacquet.js';
|
|
25
25
|
import { createWorkspaceSpecs, updateToWorkspacePackagesFromManifest } from './updateWorkspaceDependencies.js';
|
|
26
26
|
import { verifyPacquetIdentity } from './verifyPacquetIdentity.js';
|
|
@@ -202,10 +202,10 @@ export async function installDeps(opts, params) {
|
|
|
202
202
|
}
|
|
203
203
|
if (opts.packageVulnerabilityAudit != null) {
|
|
204
204
|
updateMatch = null;
|
|
205
|
-
|
|
206
|
-
updateMatching = (pkgName, version) => version != null && packageVulnerabilityAudit.isVulnerable(pkgName, version);
|
|
205
|
+
updateMatching = createVulnerabilityUpdateMatching(opts.packageVulnerabilityAudit);
|
|
207
206
|
}
|
|
208
207
|
if (updateMatch != null) {
|
|
208
|
+
const updateSpecs = params;
|
|
209
209
|
params = matchDependencies(updateMatch, manifest, includeDirect);
|
|
210
210
|
if (params.length === 0) {
|
|
211
211
|
if (opts.latest)
|
|
@@ -217,6 +217,7 @@ export async function installDeps(opts, params) {
|
|
|
217
217
|
// Don't update package.json in this case, and limit updates to only matching dependencies
|
|
218
218
|
updatePackageManifest = false;
|
|
219
219
|
updateMatching = (pkgName) => updateMatch(pkgName) != null;
|
|
220
|
+
warnAboutIgnoredVersionsOfIndirectUpdateSpecs(updateSpecs);
|
|
220
221
|
}
|
|
221
222
|
}
|
|
222
223
|
if (opts.update && opts.latest && (!params || (params.length === 0))) {
|
|
@@ -402,6 +403,40 @@ function getVulnerabilityPenalty(severity) {
|
|
|
402
403
|
default: return -1100;
|
|
403
404
|
}
|
|
404
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* `pnpm update <dep>@<version>` where `<dep>` matches only transitive
|
|
408
|
+
* dependencies has no manifest entry to write the version into, and an
|
|
409
|
+
* update resolves the target the same way a fresh install would — which a
|
|
410
|
+
* command-line version cannot influence. Tell the user the version part is
|
|
411
|
+
* ignored, and that an override is the mechanism that does pin a
|
|
412
|
+
* transitive dependency. The recommended override is scoped to the
|
|
413
|
+
* dependents' declared range so it cannot violate any consumer's range;
|
|
414
|
+
* the range itself is not known at this layer (it lives in the dependents'
|
|
415
|
+
* manifests), hence the placeholder.
|
|
416
|
+
*/
|
|
417
|
+
function warnAboutIgnoredVersionsOfIndirectUpdateSpecs(updateSpecs) {
|
|
418
|
+
for (const spec of updateSpecs) {
|
|
419
|
+
const { pattern, versionSpec } = parseUpdateParam(spec);
|
|
420
|
+
if (versionSpec == null)
|
|
421
|
+
continue;
|
|
422
|
+
globalWarn(`"${pattern}" is not a direct dependency, so the requested version "${versionSpec}" is ignored — "${pattern}" is updated to what a fresh install would resolve. To force a version of a transitive dependency, add an override scoped to the range its dependents declare to pnpm-workspace.yaml, e.g.: overrides: { "${pattern}@<declared range>": "${versionSpec}" }`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* The `updateMatching` predicate of `pnpm audit --fix`: a package is an
|
|
427
|
+
* update target when its resolved version is vulnerable. The resolver calls
|
|
428
|
+
* it without a version when the edge has no lockfile reference — e.g. after
|
|
429
|
+
* the vulnerable pin was widened, which forgets the reference — so a
|
|
430
|
+
* version-less call matches by name against the vulnerable set: such an
|
|
431
|
+
* edge belongs to a package under vulnerability management and must
|
|
432
|
+
* re-resolve without its seeded lockfile pins.
|
|
433
|
+
*/
|
|
434
|
+
export function createVulnerabilityUpdateMatching(packageVulnerabilityAudit) {
|
|
435
|
+
const vulnerablePackageNames = new Set(packageVulnerabilityAudit.getVulnerabilities().keys());
|
|
436
|
+
return (pkgName, version) => version != null
|
|
437
|
+
? packageVulnerabilityAudit.isVulnerable(pkgName, version)
|
|
438
|
+
: vulnerablePackageNames.has(pkgName);
|
|
439
|
+
}
|
|
405
440
|
function preferNonvulnerablePackageVersions(packageVulnerabilityAudit) {
|
|
406
441
|
const preferredVersions = {};
|
|
407
442
|
for (const [packageName, vulnerabilities] of packageVulnerabilityAudit.getVulnerabilities()) {
|
package/lib/runPacquet.js
CHANGED
|
@@ -126,13 +126,14 @@ function makePacquetEnv(opts) {
|
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* Path of the platform-specific native pacquet binary for the host. The
|
|
129
|
-
* pacquet npm package
|
|
130
|
-
* `
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
129
|
+
* pacquet npm package declares the `@pacquet/<platform>-<arch>` binary as
|
|
130
|
+
* an `optionalDependency`, so it lands as a *sibling* of pacquet, not
|
|
131
|
+
* inside its own `node_modules` (pacquet's own `node_modules` is empty
|
|
132
|
+
* after configDependencies install). Resolve it directly here rather than
|
|
133
|
+
* through pacquet's `bin/pacquet`, which is only a placeholder until the
|
|
134
|
+
* package's preinstall relinks it to the native binary — a step that does
|
|
135
|
+
* not run for configDependencies. Use Node's resolver rooted at pacquet's
|
|
136
|
+
* own `package.json` so we find the same sibling package.
|
|
136
137
|
*
|
|
137
138
|
* The `realpathSync` is required: `.pnpm-config/pacquet` is a symlink
|
|
138
139
|
* into the global virtual store, and Node's `createRequire` builds its
|
|
@@ -197,16 +198,19 @@ function pacquetSupportsResolution(version) {
|
|
|
197
198
|
* surface pnpm itself accepts on `install`, so the flags don't need
|
|
198
199
|
* reshaping.
|
|
199
200
|
*
|
|
200
|
-
* Flags we
|
|
201
|
+
* Flags we manage ourselves (`--frozen-lockfile`,
|
|
201
202
|
* `--ignore-manifest-check`) are dropped in every form the user can
|
|
202
203
|
* type them — positive (`--frozen-lockfile`), negated
|
|
203
|
-
* (`--no-frozen-lockfile`), and any `=value` form.
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
204
|
+
* (`--no-frozen-lockfile`), and any `=value` form. pnpm resolves the
|
|
205
|
+
* frozen-lockfile setting itself and encodes the decision in the mode
|
|
206
|
+
* it hands pacquet: a resolving install (pacquet resolves and writes
|
|
207
|
+
* the lockfile, no `--frozen-lockfile` injected) or a frozen
|
|
208
|
+
* materialization (pacquet is pinned to the lockfile via an injected
|
|
209
|
+
* `--frozen-lockfile`) — see `frozenArgs` in `makeRun`. Forwarding the
|
|
210
|
+
* user's own token would contradict that choice: pacquet accepts a
|
|
211
|
+
* `--no-<flag>` negation for every boolean flag with last-one-wins
|
|
212
|
+
* override semantics, so a user `--no-frozen-lockfile` sitting next to
|
|
213
|
+
* our injected `--frozen-lockfile` would flip the pinning back off.
|
|
210
214
|
*
|
|
211
215
|
* `--reporter` is stripped in any form (`--reporter=foo`,
|
|
212
216
|
* `--reporter foo`): pacquet's `reporter` is a clap value option
|
package/lib/update/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { globalInfo } from '@pnpm/logger';
|
|
|
10
10
|
import chalk from 'chalk';
|
|
11
11
|
import { pick, unnest } from 'ramda';
|
|
12
12
|
import { renderHelp } from 'render-help';
|
|
13
|
-
import { installDeps } from '../installDeps.js';
|
|
13
|
+
import { createVulnerabilityUpdateMatching, installDeps } from '../installDeps.js';
|
|
14
14
|
import { parseUpdateParam } from '../recursive.js';
|
|
15
15
|
import { createGlobalPolicyCallbacks } from '../resolutionPolicyManifest.js';
|
|
16
16
|
import { getUpdateChoices } from './getUpdateChoices.js';
|
|
@@ -276,8 +276,7 @@ async function update(dependencies, opts, rebuildHandler) {
|
|
|
276
276
|
const depth = opts.depth ?? Infinity;
|
|
277
277
|
let updateMatching;
|
|
278
278
|
if (opts.packageVulnerabilityAudit != null) {
|
|
279
|
-
|
|
280
|
-
updateMatching = (pkgName, version) => version != null && packageVulnerabilityAudit.isVulnerable(pkgName, version);
|
|
279
|
+
updateMatching = createVulnerabilityUpdateMatching(opts.packageVulnerabilityAudit);
|
|
281
280
|
}
|
|
282
281
|
else if ((dependencies.length > 0) && dependencies.every(dep => !dep.substring(1).includes('@')) && depth > 0 && !opts.latest) {
|
|
283
282
|
updateMatching = createMatcher(dependencies);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/installing.commands",
|
|
3
|
-
"version": "1100.10.
|
|
3
|
+
"version": "1100.10.3",
|
|
4
4
|
"description": "Commands for installation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -47,54 +47,54 @@
|
|
|
47
47
|
"ramda": "npm:@pnpm/ramda@0.28.1",
|
|
48
48
|
"render-help": "^2.0.0",
|
|
49
49
|
"version-selector-type": "^3.0.0",
|
|
50
|
-
"@pnpm/building.policy": "1100.0.11",
|
|
51
50
|
"@pnpm/catalogs.types": "1100.0.0",
|
|
52
51
|
"@pnpm/catalogs.config": "1100.0.2",
|
|
53
|
-
"@pnpm/
|
|
54
|
-
"@pnpm/
|
|
55
|
-
"@pnpm/config.pick-registry-for-package": "1100.0.9",
|
|
52
|
+
"@pnpm/building.policy": "1100.0.12",
|
|
53
|
+
"@pnpm/building.after-install": "1102.0.4",
|
|
56
54
|
"@pnpm/cli.common-cli-options-help": "1100.0.2",
|
|
57
|
-
"@pnpm/config.reader": "1101.10.1",
|
|
58
|
-
"@pnpm/building.after-install": "1102.0.2",
|
|
59
|
-
"@pnpm/config.writer": "1100.0.14",
|
|
60
|
-
"@pnpm/constants": "1100.0.0",
|
|
61
|
-
"@pnpm/config.version-policy": "1100.1.6",
|
|
62
|
-
"@pnpm/deps.inspection.outdated": "1100.1.10",
|
|
63
55
|
"@pnpm/config.matcher": "1100.0.1",
|
|
56
|
+
"@pnpm/config.pick-registry-for-package": "1100.0.9",
|
|
57
|
+
"@pnpm/config.reader": "1101.11.1",
|
|
58
|
+
"@pnpm/config.version-policy": "1100.1.6",
|
|
59
|
+
"@pnpm/config.writer": "1100.0.15",
|
|
60
|
+
"@pnpm/cli.utils": "1101.0.13",
|
|
61
|
+
"@pnpm/constants": "1100.0.0",
|
|
64
62
|
"@pnpm/deps.path": "1100.0.8",
|
|
65
|
-
"@pnpm/error": "1100.0.1",
|
|
66
63
|
"@pnpm/deps.security.signatures": "1101.2.3",
|
|
64
|
+
"@pnpm/deps.inspection.outdated": "1100.1.12",
|
|
67
65
|
"@pnpm/fs.graceful-fs": "1100.1.0",
|
|
68
|
-
"@pnpm/
|
|
69
|
-
"@pnpm/
|
|
70
|
-
"@pnpm/hooks.pnpmfile": "1100.0.
|
|
71
|
-
"@pnpm/installing.context": "1100.0.
|
|
72
|
-
"@pnpm/installing.dedupe.check": "1100.1.
|
|
73
|
-
"@pnpm/
|
|
66
|
+
"@pnpm/fs.read-modules-dir": "1100.0.1",
|
|
67
|
+
"@pnpm/global.commands": "1100.0.32",
|
|
68
|
+
"@pnpm/hooks.pnpmfile": "1100.0.17",
|
|
69
|
+
"@pnpm/installing.context": "1100.0.22",
|
|
70
|
+
"@pnpm/installing.dedupe.check": "1100.1.2",
|
|
71
|
+
"@pnpm/deps.status": "1100.1.5",
|
|
72
|
+
"@pnpm/installing.deps-installer": "1102.2.1",
|
|
73
|
+
"@pnpm/installing.env-installer": "1102.0.4",
|
|
74
|
+
"@pnpm/lockfile.fs": "1100.1.9",
|
|
74
75
|
"@pnpm/installing.dedupe.issues-renderer": "1100.0.1",
|
|
75
|
-
"@pnpm/lockfile.types": "1100.0.12",
|
|
76
|
-
"@pnpm/lockfile.fs": "1100.1.7",
|
|
77
|
-
"@pnpm/network.fetch": "1100.1.4",
|
|
78
76
|
"@pnpm/network.auth-header": "1101.1.3",
|
|
77
|
+
"@pnpm/network.fetch": "1100.1.4",
|
|
78
|
+
"@pnpm/resolving.parse-wanted-dependency": "1100.0.1",
|
|
79
79
|
"@pnpm/pkg-manifest.reader": "1100.0.9",
|
|
80
|
-
"@pnpm/installing.env-installer": "1102.0.2",
|
|
81
80
|
"@pnpm/pkg-manifest.utils": "1100.2.6",
|
|
82
|
-
"@pnpm/
|
|
83
|
-
"@pnpm/store.controller": "1102.0.
|
|
84
|
-
"@pnpm/
|
|
85
|
-
"@pnpm/store.connection-manager": "1100.3.2",
|
|
86
|
-
"@pnpm/resolving.resolver-base": "1100.5.0",
|
|
87
|
-
"@pnpm/types": "1101.3.2",
|
|
88
|
-
"@pnpm/fs.read-modules-dir": "1100.0.1",
|
|
89
|
-
"@pnpm/workspace.project-manifest-writer": "1100.0.8",
|
|
90
|
-
"@pnpm/workspace.projects-filter": "1100.0.23",
|
|
81
|
+
"@pnpm/store.connection-manager": "1100.3.4",
|
|
82
|
+
"@pnpm/store.controller": "1102.0.3",
|
|
83
|
+
"@pnpm/lockfile.types": "1100.0.13",
|
|
91
84
|
"@pnpm/workspace.project-manifest-reader": "1100.0.14",
|
|
92
|
-
"@pnpm/workspace.
|
|
93
|
-
"@pnpm/workspace.projects-
|
|
94
|
-
"@pnpm/
|
|
95
|
-
"@pnpm/workspace.projects-sorter": "1100.0.
|
|
85
|
+
"@pnpm/workspace.project-manifest-writer": "1100.0.8",
|
|
86
|
+
"@pnpm/workspace.projects-filter": "1100.0.25",
|
|
87
|
+
"@pnpm/resolving.resolver-base": "1100.5.1",
|
|
88
|
+
"@pnpm/workspace.projects-sorter": "1100.0.8",
|
|
89
|
+
"@pnpm/resolving.npm-resolver": "1102.1.2",
|
|
96
90
|
"@pnpm/workspace.root-finder": "1100.0.3",
|
|
97
|
-
"@pnpm/
|
|
91
|
+
"@pnpm/types": "1101.3.2",
|
|
92
|
+
"@pnpm/workspace.projects-reader": "1101.0.13",
|
|
93
|
+
"@pnpm/workspace.state": "1100.0.26",
|
|
94
|
+
"@pnpm/error": "1100.0.1",
|
|
95
|
+
"@pnpm/workspace.workspace-manifest-writer": "1100.0.15",
|
|
96
|
+
"@pnpm/cli.command": "1100.0.1",
|
|
97
|
+
"@pnpm/workspace.projects-graph": "1100.0.22"
|
|
98
98
|
},
|
|
99
99
|
"peerDependencies": {
|
|
100
100
|
"@pnpm/logger": "^1100.0.0"
|
|
@@ -117,19 +117,19 @@
|
|
|
117
117
|
"write-json-file": "^7.0.0",
|
|
118
118
|
"write-package": "7.2.0",
|
|
119
119
|
"write-yaml-file": "^6.0.0",
|
|
120
|
-
"@pnpm/
|
|
121
|
-
"@pnpm/installing.commands": "1100.10.1",
|
|
122
|
-
"@pnpm/assert-project": "1100.0.17",
|
|
123
|
-
"@pnpm/store.index": "1100.2.1",
|
|
120
|
+
"@pnpm/assert-project": "1100.0.18",
|
|
124
121
|
"@pnpm/logger": "1100.0.0",
|
|
125
|
-
"@pnpm/
|
|
126
|
-
"@pnpm/
|
|
122
|
+
"@pnpm/store.index": "1100.2.1",
|
|
123
|
+
"@pnpm/prepare": "1100.0.18",
|
|
124
|
+
"@pnpm/installing.commands": "1100.10.3",
|
|
125
|
+
"@pnpm/testing.command-defaults": "1100.0.8",
|
|
127
126
|
"@pnpm/test-ipc-server": "1100.0.0",
|
|
127
|
+
"@pnpm/test-fixtures": "1100.0.0",
|
|
128
128
|
"@pnpm/testing.mock-agent": "1101.0.4",
|
|
129
|
-
"@pnpm/
|
|
130
|
-
"@pnpm/testing.
|
|
131
|
-
"@pnpm/workspace.projects-filter": "1100.0.
|
|
132
|
-
"@pnpm/
|
|
129
|
+
"@pnpm/worker": "1100.2.3",
|
|
130
|
+
"@pnpm/testing.registry-mock": "1100.0.8",
|
|
131
|
+
"@pnpm/workspace.projects-filter": "1100.0.25",
|
|
132
|
+
"@pnpm/installing.modules-yaml": "1100.0.9"
|
|
133
133
|
},
|
|
134
134
|
"engines": {
|
|
135
135
|
"node": ">=22.13"
|