@pnpm/engine.pm.commands 1100.0.0 → 1101.0.0

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/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { selfUpdate } from './self-updater/index.js';
2
2
  export { installPnpm, installPnpmToStore, linkExePlatformBinary } from './self-updater/installPnpm.js';
3
3
  export { setup } from './setup/index.js';
4
+ export { withCmd } from './with/index.js';
package/lib/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { selfUpdate } from './self-updater/index.js';
2
2
  export { installPnpm, installPnpmToStore, linkExePlatformBinary } from './self-updater/installPnpm.js';
3
3
  export { setup } from './setup/index.js';
4
+ export { withCmd } from './with/index.js';
4
5
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
1
  import { type GlobalAddOptions } from '@pnpm/global.commands';
2
2
  import type { EnvLockfile } from '@pnpm/lockfile.types';
3
- import type { StoreController } from '@pnpm/store.controller';
3
+ import { type StoreController } from '@pnpm/store.controller';
4
4
  import type { Registries } from '@pnpm/types';
5
5
  export interface InstallPnpmResult {
6
6
  binDir: string;
@@ -8,6 +8,7 @@ import { iterateHashedGraphNodes, iteratePkgMeta, lockfileToDepGraph, } from '@p
8
8
  import { installGlobalPackages } from '@pnpm/global.commands';
9
9
  import { cleanOrphanedInstallDirs, createGlobalCacheKey, createInstallDir, findGlobalPackage, getHashLink, } from '@pnpm/global.packages';
10
10
  import { headlessInstall } from '@pnpm/installing.deps-restorer';
11
+ import { registerProject } from '@pnpm/store.controller';
11
12
  import { symlinkDir } from 'symlink-dir';
12
13
  // @pnpm/exe has platform-specific binaries, so its GVS hash must
13
14
  // include ENGINE_NAME for correct per-platform resolution.
@@ -123,6 +124,11 @@ async function installPnpmToGlobalDir(opts, pkgName, version, wantedLockfile) {
123
124
  virtualStoreDirMaxLength: opts.virtualStoreDirMaxLength,
124
125
  packageManager: opts.packageManager,
125
126
  });
127
+ // headlessInstall does not register the project, so we must do it
128
+ // explicitly. Without this, `pnpm store prune` would not know about
129
+ // this install directory and would remove its packages from the
130
+ // global virtual store.
131
+ await registerProject(opts.storeDir, installDir);
126
132
  }
127
133
  else {
128
134
  await installFromResolution(installDir, opts, [`${pkgName}@${version}`]);
@@ -5,5 +5,5 @@ export declare function cliOptionsTypes(): Record<string, unknown>;
5
5
  export declare const commandNames: string[];
6
6
  export declare const skipPackageManagerCheck = true;
7
7
  export declare function help(): string;
8
- export type SelfUpdateCommandOptions = CreateStoreControllerOptions & Pick<Config, 'globalPkgDir' | 'lockfileDir' | 'managePackageManagerVersions' | 'modulesDir' | 'pnpmHomeDir'> & Pick<ConfigContext, 'rootProjectManifestDir' | 'wantedPackageManager'>;
8
+ export type SelfUpdateCommandOptions = CreateStoreControllerOptions & Pick<Config, 'globalPkgDir' | 'lockfileDir' | 'modulesDir' | 'pnpmHomeDir'> & Pick<ConfigContext, 'rootProjectManifestDir' | 'wantedPackageManager'>;
9
9
  export declare function handler(opts: SelfUpdateCommandOptions, params: string[]): Promise<undefined | string>;
@@ -0,0 +1,2 @@
1
+ import * as withCmd from './with.js';
2
+ export { withCmd };
@@ -0,0 +1,3 @@
1
+ import * as withCmd from './with.js';
2
+ export { withCmd };
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,11 @@
1
+ import { type Config, type ConfigContext } from '@pnpm/config.reader';
2
+ import { type CreateStoreControllerOptions } from '@pnpm/store.connection-manager';
3
+ export declare const commandNames: string[];
4
+ export declare const skipPackageManagerCheck = true;
5
+ export declare const rcOptionsTypes: typeof cliOptionsTypes;
6
+ export declare function cliOptionsTypes(): Record<string, unknown>;
7
+ export declare function help(): string;
8
+ export type WithCommandOptions = CreateStoreControllerOptions & Pick<Config, 'dir' | 'lockfileDir' | 'pnpmHomeDir' | 'virtualStoreDirMaxLength'> & Pick<ConfigContext, 'rootProjectManifestDir'>;
9
+ export declare function handler(opts: WithCommandOptions, params: string[]): Promise<{
10
+ exitCode: number;
11
+ }>;
@@ -0,0 +1,101 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { isExecutedByCorepack, packageManager } from '@pnpm/cli.meta';
4
+ import { docsUrl } from '@pnpm/cli.utils';
5
+ import { types as allTypes } from '@pnpm/config.reader';
6
+ import { PnpmError } from '@pnpm/error';
7
+ import { resolvePackageManagerIntegrities } from '@pnpm/installing.env-installer';
8
+ import { prependDirsToPath } from '@pnpm/shell.path';
9
+ import { createStoreController } from '@pnpm/store.connection-manager';
10
+ import crossSpawn from 'cross-spawn';
11
+ import { pick } from 'ramda';
12
+ import { renderHelp } from 'render-help';
13
+ import { installPnpmToStore } from '../self-updater/installPnpm.js';
14
+ export const commandNames = ['with'];
15
+ export const skipPackageManagerCheck = true;
16
+ export const rcOptionsTypes = cliOptionsTypes;
17
+ export function cliOptionsTypes() {
18
+ return pick([], allTypes);
19
+ }
20
+ export function help() {
21
+ return renderHelp({
22
+ description: 'Run pnpm with a specific version (or the currently running one), ignoring the "packageManager" and "devEngines.packageManager" fields of the project manifest.',
23
+ descriptionLists: [],
24
+ url: docsUrl('with'),
25
+ usages: [
26
+ 'pnpm with current <pnpm args>',
27
+ 'pnpm with <version> <pnpm args>',
28
+ 'pnpm with next install',
29
+ 'pnpm with 10 install',
30
+ ],
31
+ });
32
+ }
33
+ export async function handler(opts, params) {
34
+ if (params.length === 0) {
35
+ throw new PnpmError('MISSING_WITH_SPEC', 'Missing version argument. Usage: pnpm with <version|current> <args...>');
36
+ }
37
+ if (isExecutedByCorepack()) {
38
+ throw new PnpmError('CANT_USE_WITH_IN_COREPACK', 'The "pnpm with" command does not work under corepack');
39
+ }
40
+ // `with current` is handled earlier in parseCliArgs.ts, which re-parses it
41
+ // for in-process execution, so this handler only ever sees version/dist-tag specs.
42
+ const [spec, ...args] = params;
43
+ fs.mkdirSync(opts.pnpmHomeDir, { recursive: true });
44
+ const store = await createStoreController(opts);
45
+ let binDir;
46
+ try {
47
+ // resolvePackageManagerIntegrities resolves ranges/dist-tags via the
48
+ // registry and writes the resolved exact version to the envLockfile.
49
+ const envLockfile = await resolvePackageManagerIntegrities(spec, {
50
+ rootDir: opts.pnpmHomeDir,
51
+ registries: opts.registries,
52
+ storeController: store.ctrl,
53
+ storeDir: store.dir,
54
+ });
55
+ const resolvedVersion = envLockfile.importers['.'].packageManagerDependencies?.['pnpm']?.version;
56
+ if (!resolvedVersion) {
57
+ throw new PnpmError('CANNOT_RESOLVE_PNPM', `Cannot resolve pnpm version for "${spec}"`);
58
+ }
59
+ ;
60
+ ({ binDir } = await installPnpmToStore(resolvedVersion, {
61
+ envLockfile,
62
+ storeController: store.ctrl,
63
+ storeDir: store.dir,
64
+ registries: opts.registries,
65
+ virtualStoreDirMaxLength: opts.virtualStoreDirMaxLength,
66
+ packageManager: { name: packageManager.name, version: packageManager.version },
67
+ }));
68
+ }
69
+ finally {
70
+ await store.ctrl.close();
71
+ }
72
+ // The child pnpm must skip the packageManager/devEngines check so the requested
73
+ // version stays active. Two keys are set for backward compatibility:
74
+ // - `COREPACK_ROOT` is honored by every pnpm release that supports corepack
75
+ // (older versions skip the pm check whenever this is set).
76
+ // - `pnpm_config_pm_on_fail=ignore` is the principled override recognized
77
+ // by pnpm releases that ship the `pmOnFail` setting.
78
+ const pnpmEnv = prependDirsToPath([binDir]);
79
+ const spawnEnv = {
80
+ ...process.env,
81
+ [pnpmEnv.name]: pnpmEnv.value,
82
+ COREPACK_ROOT: process.env.COREPACK_ROOT ?? 'pnpm-with',
83
+ pnpm_config_pm_on_fail: 'ignore',
84
+ };
85
+ const pnpmBinPath = path.join(binDir, 'pnpm');
86
+ const { status, signal, error } = crossSpawn.sync(pnpmBinPath, args, {
87
+ stdio: 'inherit',
88
+ env: spawnEnv,
89
+ });
90
+ if (error)
91
+ throw error;
92
+ if (signal) {
93
+ // Best-effort: try to terminate with the same signal the child received.
94
+ // If the signal is handled or ignored, fall back to a non-zero exit code
95
+ // so the caller doesn't mistake an interrupted run for a successful one.
96
+ process.kill(process.pid, signal);
97
+ return { exitCode: 1 };
98
+ }
99
+ return { exitCode: status ?? 0 };
100
+ }
101
+ //# sourceMappingURL=with.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/engine.pm.commands",
3
- "version": "1100.0.0",
3
+ "version": "1101.0.0",
4
4
  "description": "pnpm commands for self-updating and setting up pnpm",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -25,29 +25,31 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "@pnpm/os.env.path-extender": "^3.0.0",
28
+ "cross-spawn": "^7.0.6",
28
29
  "path-name": "^1.0.0",
29
30
  "ramda": "npm:@pnpm/ramda@0.28.1",
30
31
  "render-help": "^2.0.0",
31
32
  "semver": "^7.7.2",
32
33
  "symlink-dir": "^10.0.1",
33
- "@pnpm/bins.linker": "1100.0.0",
34
- "@pnpm/building.policy": "1100.0.0",
35
- "@pnpm/cli.meta": "1100.0.0",
36
- "@pnpm/cli.utils": "1100.0.0",
37
- "@pnpm/config.reader": "1100.0.0",
38
- "@pnpm/deps.graph-hasher": "1100.0.0",
39
- "@pnpm/global.commands": "1100.0.0",
34
+ "@pnpm/building.policy": "1100.0.1",
35
+ "@pnpm/bins.linker": "1100.0.2",
36
+ "@pnpm/cli.meta": "1100.0.1",
37
+ "@pnpm/cli.utils": "1101.0.0",
38
+ "@pnpm/config.reader": "1101.0.0",
39
+ "@pnpm/deps.graph-hasher": "1100.0.1",
40
40
  "@pnpm/error": "1100.0.0",
41
- "@pnpm/installing.client": "1100.0.0",
42
- "@pnpm/installing.deps-restorer": "1100.0.0",
43
- "@pnpm/installing.env-installer": "1100.0.0",
44
- "@pnpm/global.packages": "1100.0.0",
45
- "@pnpm/lockfile.types": "1100.0.0",
46
- "@pnpm/store.connection-manager": "1100.0.0",
47
- "@pnpm/types": "1100.0.0",
48
- "@pnpm/store.controller": "1100.0.0",
49
- "@pnpm/workspace.project-manifest-reader": "1100.0.0",
50
- "@pnpm/resolving.npm-resolver": "1100.0.0"
41
+ "@pnpm/installing.client": "1100.0.2",
42
+ "@pnpm/global.commands": "1100.0.2",
43
+ "@pnpm/global.packages": "1100.0.1",
44
+ "@pnpm/installing.deps-restorer": "1100.0.2",
45
+ "@pnpm/installing.env-installer": "1100.1.0",
46
+ "@pnpm/lockfile.types": "1100.0.1",
47
+ "@pnpm/shell.path": "1100.0.0",
48
+ "@pnpm/resolving.npm-resolver": "1100.0.1",
49
+ "@pnpm/store.connection-manager": "1100.0.2",
50
+ "@pnpm/store.controller": "1100.0.1",
51
+ "@pnpm/types": "1101.0.0",
52
+ "@pnpm/workspace.project-manifest-reader": "1100.0.2"
51
53
  },
52
54
  "peerDependencies": {
53
55
  "@pnpm/logger": ">=1001.0.0 <1002.0.0"
@@ -57,13 +59,12 @@
57
59
  "@types/cross-spawn": "^6.0.6",
58
60
  "@types/ramda": "0.31.1",
59
61
  "@types/semver": "7.7.1",
60
- "cross-spawn": "^7.0.6",
61
- "@pnpm/logger": "1100.0.0",
62
- "@pnpm/engine.pm.commands": "1100.0.0",
63
- "@pnpm/prepare": "1100.0.0",
62
+ "@pnpm/constants": "1100.0.0",
64
63
  "@pnpm/error": "1100.0.0",
65
- "@pnpm/shell.path": "1100.0.0",
66
- "@pnpm/testing.mock-agent": "1100.0.0"
64
+ "@pnpm/logger": "1100.0.0",
65
+ "@pnpm/engine.pm.commands": "1101.0.0",
66
+ "@pnpm/prepare": "1100.0.1",
67
+ "@pnpm/testing.mock-agent": "1100.0.1"
67
68
  },
68
69
  "engines": {
69
70
  "node": ">=22.13"