@pnpm/exec.commands 1100.2.4 → 1100.3.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/buildCommandNotFoundHint.d.ts +1 -1
- package/lib/exec.d.ts +2 -2
- package/lib/exec.js +13 -3
- package/lib/run.d.ts +1 -1
- package/lib/run.js +33 -13
- package/lib/runRecursive.d.ts +1 -1
- package/lib/runRecursive.js +11 -2
- package/package.json +29 -29
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PackageScripts } from '@pnpm/types';
|
|
2
|
-
export declare function getNearestProgram({ dir, modulesDir, programName, workspaceDir }: {
|
|
2
|
+
export declare function getNearestProgram({ dir, modulesDir, programName, workspaceDir, }: {
|
|
3
3
|
dir: string;
|
|
4
4
|
modulesDir: string;
|
|
5
5
|
programName: string;
|
package/lib/exec.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare const commandNames: string[];
|
|
|
7
7
|
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
8
8
|
export declare const cliOptionsTypes: () => Record<string, unknown>;
|
|
9
9
|
export declare function help(): string;
|
|
10
|
-
export declare function getResumedPackageChunks({ resumeFrom, chunks, selectedProjectsGraph }: {
|
|
10
|
+
export declare function getResumedPackageChunks({ resumeFrom, chunks, selectedProjectsGraph, }: {
|
|
11
11
|
resumeFrom: string;
|
|
12
12
|
chunks: ProjectRootDir[][];
|
|
13
13
|
selectedProjectsGraph: ProjectsGraph;
|
|
@@ -28,7 +28,7 @@ export type ExecOpts = Required<Pick<ConfigContext, 'selectedProjectsGraph'>> &
|
|
|
28
28
|
resumeFrom?: string;
|
|
29
29
|
reportSummary?: boolean;
|
|
30
30
|
implicitlyFellbackFromRun?: boolean;
|
|
31
|
-
} & Pick<Config, 'bin' | 'dir' | 'extraBinPaths' | 'extraEnv' | 'lockfileDir' | 'modulesDir' | 'nodeOptions' | 'pnpmHomeDir' | 'recursive' | 'reporter' | 'reporterHidePrefix' | 'userAgent' | 'verifyDepsBeforeRun' | 'workspaceDir'> & Pick<ConfigContext, 'cliOptions'> & CheckDepsStatusOptions;
|
|
31
|
+
} & Pick<Config, 'bin' | 'dir' | 'extraBinPaths' | 'extraEnv' | 'lockfileDir' | 'modulesDir' | 'nodeOptions' | 'nodeExperimentalPackageMap' | 'pnpmHomeDir' | 'recursive' | 'reporter' | 'reporterHidePrefix' | 'userAgent' | 'verifyDepsBeforeRun' | 'workspaceDir'> & Pick<ConfigContext, 'cliOptions'> & CheckDepsStatusOptions;
|
|
32
32
|
export declare function handler(opts: ExecOpts, params: string[]): Promise<{
|
|
33
33
|
exitCode: number;
|
|
34
34
|
}>;
|
package/lib/exec.js
CHANGED
|
@@ -4,7 +4,7 @@ import { docsUrl, readProjectManifestOnly, throwOnCommandFail } from '@pnpm/cli.
|
|
|
4
4
|
import { getWorkspaceConcurrency, types } from '@pnpm/config.reader';
|
|
5
5
|
import { lifecycleLogger } from '@pnpm/core-loggers';
|
|
6
6
|
import { PnpmError } from '@pnpm/error';
|
|
7
|
-
import { makeNodeRequireOption } from '@pnpm/exec.lifecycle';
|
|
7
|
+
import { makeNodePackageMapOption, makeNodeRequireOption } from '@pnpm/exec.lifecycle';
|
|
8
8
|
import { logger } from '@pnpm/logger';
|
|
9
9
|
import { prependDirsToPath } from '@pnpm/shell.path';
|
|
10
10
|
import { tryReadProjectManifest } from '@pnpm/workspace.project-manifest-reader';
|
|
@@ -33,6 +33,8 @@ export function rcOptionsTypes() {
|
|
|
33
33
|
'unsafe-perm',
|
|
34
34
|
'workspace-concurrency',
|
|
35
35
|
'reporter-hide-prefix',
|
|
36
|
+
'node-experimental-package-map',
|
|
37
|
+
'node-package-map-type',
|
|
36
38
|
], types),
|
|
37
39
|
'shell-mode': Boolean,
|
|
38
40
|
'resume-from': String,
|
|
@@ -156,6 +158,8 @@ export async function handler(opts, params) {
|
|
|
156
158
|
const result = createEmptyRecursiveSummary(chunks);
|
|
157
159
|
const existsPnp = existsInDir.bind(null, '.pnp.cjs');
|
|
158
160
|
const workspacePnpPath = opts.workspaceDir && existsPnp(opts.workspaceDir);
|
|
161
|
+
const existsPackageMap = existsInDir.bind(null, path.join(opts.modulesDir ?? 'node_modules', '.package-map.json'));
|
|
162
|
+
const workspacePackageMapPath = opts.nodeExperimentalPackageMap && opts.workspaceDir && existsPackageMap(opts.workspaceDir);
|
|
159
163
|
let exitCode = 0;
|
|
160
164
|
const prependPaths = [
|
|
161
165
|
'./node_modules/.bin',
|
|
@@ -169,15 +173,21 @@ export async function handler(opts, params) {
|
|
|
169
173
|
const startTime = process.hrtime();
|
|
170
174
|
try {
|
|
171
175
|
const pnpPath = workspacePnpPath ?? existsPnp(prefix);
|
|
176
|
+
const packageMapPath = workspacePackageMapPath || (opts.nodeExperimentalPackageMap && existsPackageMap(prefix));
|
|
172
177
|
const extraEnv = {
|
|
173
178
|
...opts.extraEnv,
|
|
174
|
-
...(
|
|
179
|
+
...(opts.nodeOptions ? { NODE_OPTIONS: opts.nodeOptions } : {}),
|
|
175
180
|
};
|
|
181
|
+
if (pnpPath) {
|
|
182
|
+
Object.assign(extraEnv, makeNodeRequireOption(pnpPath, extraEnv));
|
|
183
|
+
}
|
|
184
|
+
if (packageMapPath) {
|
|
185
|
+
Object.assign(extraEnv, makeNodePackageMapOption(packageMapPath, extraEnv));
|
|
186
|
+
}
|
|
176
187
|
const env = makeEnv({
|
|
177
188
|
extraEnv: {
|
|
178
189
|
...extraEnv,
|
|
179
190
|
PNPM_PACKAGE_NAME: opts.selectedProjectsGraph[prefix]?.package.manifest.name,
|
|
180
|
-
...(opts.nodeOptions ? { NODE_OPTIONS: opts.nodeOptions } : {}),
|
|
181
191
|
},
|
|
182
192
|
prependPaths,
|
|
183
193
|
userAgent: opts.userAgent,
|
package/lib/run.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare const commandNames: string[];
|
|
|
24
24
|
export declare function help(): string;
|
|
25
25
|
export type RunOpts = Omit<RecursiveRunOpts, 'allProjects' | 'selectedProjectsGraph' | 'workspaceDir'> & {
|
|
26
26
|
recursive?: boolean;
|
|
27
|
-
} & Pick<Config, 'bin' | 'verifyDepsBeforeRun' | 'dir' | 'enablePrePostScripts' | 'engineStrict' | 'extraBinPaths' | 'extraEnv' | 'nodeOptions' | 'pnpmHomeDir' | 'reporter' | 'scriptShell' | 'scriptsPrependNodePath' | 'shellEmulator' | 'syncInjectedDepsAfterScripts' | 'userAgent'> & Pick<ConfigContext, 'cliOptions'> & (({
|
|
27
|
+
} & Pick<Config, 'bin' | 'verifyDepsBeforeRun' | 'dir' | 'enablePrePostScripts' | 'engineStrict' | 'extraBinPaths' | 'extraEnv' | 'nodeOptions' | 'nodeExperimentalPackageMap' | 'pnpmHomeDir' | 'reporter' | 'scriptShell' | 'scriptsPrependNodePath' | 'shellEmulator' | 'syncInjectedDepsAfterScripts' | 'userAgent'> & Pick<ConfigContext, 'cliOptions'> & (({
|
|
28
28
|
recursive?: false;
|
|
29
29
|
} & Partial<Pick<ConfigContext, 'allProjects' | 'selectedProjectsGraph'> & Pick<Config, 'workspaceDir'>>) | ({
|
|
30
30
|
recursive: true;
|
package/lib/run.js
CHANGED
|
@@ -3,7 +3,7 @@ import { FILTERING, UNIVERSAL_OPTIONS } from '@pnpm/cli.common-cli-options-help'
|
|
|
3
3
|
import { docsUrl, readProjectManifestOnly, tryReadProjectManifest, } from '@pnpm/cli.utils';
|
|
4
4
|
import { getWorkspaceConcurrency, types as allTypes } from '@pnpm/config.reader';
|
|
5
5
|
import { PnpmError } from '@pnpm/error';
|
|
6
|
-
import { makeNodeRequireOption, runLifecycleHook, } from '@pnpm/exec.lifecycle';
|
|
6
|
+
import { makeNodePackageMapOption, makeNodeRequireOption, runLifecycleHook, } from '@pnpm/exec.lifecycle';
|
|
7
7
|
import { syncInjectedDeps } from '@pnpm/workspace.injected-deps-syncer';
|
|
8
8
|
import pLimit from 'p-limit';
|
|
9
9
|
import { pick } from 'ramda';
|
|
@@ -60,6 +60,8 @@ export function rcOptionsTypes() {
|
|
|
60
60
|
return {
|
|
61
61
|
...pick([
|
|
62
62
|
'npm-path',
|
|
63
|
+
'node-experimental-package-map',
|
|
64
|
+
'node-package-map-type',
|
|
63
65
|
], allTypes),
|
|
64
66
|
};
|
|
65
67
|
}
|
|
@@ -104,7 +106,7 @@ For options that may be used with `-r`, see "pnpm help recursive"',
|
|
|
104
106
|
shortAlias: '-r',
|
|
105
107
|
},
|
|
106
108
|
{
|
|
107
|
-
description: 'The command
|
|
109
|
+
description: 'Continue running the remaining scripts even if one of them fails, instead of aborting on the first failure. The command still exits with a non-zero exit code if any script failed',
|
|
108
110
|
name: '--no-bail',
|
|
109
111
|
},
|
|
110
112
|
IF_PRESENT_OPTION_HELP,
|
|
@@ -214,22 +216,40 @@ so you may run "pnpm -w run ${scriptName}"`,
|
|
|
214
216
|
if (pnpPath) {
|
|
215
217
|
lifecycleOpts.extraEnv = {
|
|
216
218
|
...lifecycleOpts.extraEnv,
|
|
217
|
-
...makeNodeRequireOption(pnpPath),
|
|
219
|
+
...makeNodeRequireOption(pnpPath, lifecycleOpts.extraEnv),
|
|
218
220
|
};
|
|
219
221
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
222
|
+
const existsPackageMap = existsInDir.bind(null, path.join(opts.modulesDir ?? 'node_modules', '.package-map.json'));
|
|
223
|
+
const packageMapPath = opts.nodeExperimentalPackageMap
|
|
224
|
+
? (opts.workspaceDir && existsPackageMap(opts.workspaceDir)) ?? existsPackageMap(dir)
|
|
225
|
+
: undefined;
|
|
226
|
+
if (packageMapPath) {
|
|
227
|
+
lifecycleOpts.extraEnv = {
|
|
228
|
+
...lifecycleOpts.extraEnv,
|
|
229
|
+
...makeNodePackageMapOption(packageMapPath, lifecycleOpts.extraEnv),
|
|
226
230
|
};
|
|
227
|
-
|
|
231
|
+
}
|
|
232
|
+
const limitRun = pLimit(concurrency);
|
|
233
|
+
const runScriptOptions = {
|
|
234
|
+
enablePrePostScripts: opts.enablePrePostScripts ?? false,
|
|
235
|
+
syncInjectedDepsAfterScripts: opts.syncInjectedDepsAfterScripts,
|
|
236
|
+
workspaceDir: opts.workspaceDir,
|
|
237
|
+
};
|
|
238
|
+
const _runScript = runScript.bind(null, { manifest, lifecycleOpts, runScriptOptions, passedThruArgs });
|
|
239
|
+
if (opts.bail !== false) {
|
|
228
240
|
await Promise.all(specifiedScripts.map(script => limitRun(() => _runScript(script))));
|
|
229
241
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
242
|
+
else {
|
|
243
|
+
const results = await Promise.allSettled(specifiedScripts.map(script => limitRun(() => _runScript(script))));
|
|
244
|
+
const failures = results
|
|
245
|
+
.map((result, index) => ({ result, script: specifiedScripts[index] }))
|
|
246
|
+
.filter((entry) => entry.result.status === 'rejected');
|
|
247
|
+
if (failures.length > 0) {
|
|
248
|
+
throw new PnpmError('RUN_FAILED', `Some scripts failed: ${failures.length} of ${specifiedScripts.length}`, {
|
|
249
|
+
hint: failures
|
|
250
|
+
.map(({ script, result }) => `${script}: ${result.reason?.message ?? String(result.reason)}`)
|
|
251
|
+
.join('\n'),
|
|
252
|
+
});
|
|
233
253
|
}
|
|
234
254
|
}
|
|
235
255
|
return undefined;
|
package/lib/runRecursive.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Config, type ConfigContext } from '@pnpm/config.reader';
|
|
2
2
|
import type { PackageScripts } from '@pnpm/types';
|
|
3
|
-
export type RecursiveRunOpts = Pick<Config, 'bin' | 'enablePrePostScripts' | 'unsafePerm' | 'pnpmHomeDir' | 'requiredScripts' | 'userAgent' | 'scriptsPrependNodePath' | 'scriptShell' | 'shellEmulator' | 'stream' | 'syncInjectedDepsAfterScripts' | 'workspaceDir'> & Pick<ConfigContext, 'rootProjectManifest'> & Required<Pick<ConfigContext, 'allProjects' | 'selectedProjectsGraph'> & Pick<Config, 'workspaceDir' | 'dir'>> & Partial<Pick<Config, 'extraBinPaths' | 'extraEnv' | 'bail' | 'reporter' | 'reverse' | 'sort' | 'workspaceConcurrency'>> & {
|
|
3
|
+
export type RecursiveRunOpts = Pick<Config, 'bin' | 'enablePrePostScripts' | 'unsafePerm' | 'pnpmHomeDir' | 'requiredScripts' | 'userAgent' | 'scriptsPrependNodePath' | 'scriptShell' | 'shellEmulator' | 'stream' | 'syncInjectedDepsAfterScripts' | 'workspaceDir' | 'nodeExperimentalPackageMap' | 'modulesDir'> & Pick<ConfigContext, 'rootProjectManifest'> & Required<Pick<ConfigContext, 'allProjects' | 'selectedProjectsGraph'> & Pick<Config, 'workspaceDir' | 'dir'>> & Partial<Pick<Config, 'extraBinPaths' | 'extraEnv' | 'bail' | 'reporter' | 'reverse' | 'sort' | 'workspaceConcurrency'>> & {
|
|
4
4
|
ifPresent?: boolean;
|
|
5
5
|
resumeFrom?: string;
|
|
6
6
|
reportSummary?: boolean;
|
package/lib/runRecursive.js
CHANGED
|
@@ -4,7 +4,7 @@ import util from 'node:util';
|
|
|
4
4
|
import { throwOnCommandFail } from '@pnpm/cli.utils';
|
|
5
5
|
import { getWorkspaceConcurrency } from '@pnpm/config.reader';
|
|
6
6
|
import { PnpmError } from '@pnpm/error';
|
|
7
|
-
import { makeNodeRequireOption, } from '@pnpm/exec.lifecycle';
|
|
7
|
+
import { makeNodePackageMapOption, makeNodeRequireOption, } from '@pnpm/exec.lifecycle';
|
|
8
8
|
import { groupStart } from '@pnpm/log.group';
|
|
9
9
|
import { sortProjects } from '@pnpm/workspace.projects-sorter';
|
|
10
10
|
import pLimit from 'p-limit';
|
|
@@ -39,6 +39,8 @@ export async function runRecursive(params, opts) {
|
|
|
39
39
|
: 'pipe';
|
|
40
40
|
const existsPnp = existsInDir.bind(null, '.pnp.cjs');
|
|
41
41
|
const workspacePnpPath = opts.workspaceDir && existsPnp(opts.workspaceDir);
|
|
42
|
+
const existsPackageMap = existsInDir.bind(null, path.join(opts.modulesDir ?? 'node_modules', '.package-map.json'));
|
|
43
|
+
const workspacePackageMapPath = opts.nodeExperimentalPackageMap && opts.workspaceDir && existsPackageMap(opts.workspaceDir);
|
|
42
44
|
const requiredScripts = opts.requiredScripts ?? [];
|
|
43
45
|
if (requiredScripts.includes(scriptName)) {
|
|
44
46
|
const missingScriptPackages = packageChunks
|
|
@@ -93,7 +95,14 @@ export async function runRecursive(params, opts) {
|
|
|
93
95
|
if (pnpPath) {
|
|
94
96
|
lifecycleOpts.extraEnv = {
|
|
95
97
|
...lifecycleOpts.extraEnv,
|
|
96
|
-
...makeNodeRequireOption(pnpPath),
|
|
98
|
+
...makeNodeRequireOption(pnpPath, lifecycleOpts.extraEnv),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const packageMapPath = workspacePackageMapPath || (opts.nodeExperimentalPackageMap && existsPackageMap(prefix));
|
|
102
|
+
if (packageMapPath) {
|
|
103
|
+
lifecycleOpts.extraEnv = {
|
|
104
|
+
...lifecycleOpts.extraEnv,
|
|
105
|
+
...makeNodePackageMapOption(packageMapPath, lifecycleOpts.extraEnv),
|
|
97
106
|
};
|
|
98
107
|
}
|
|
99
108
|
const runScriptOptions = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/exec.commands",
|
|
3
|
-
"version": "1100.
|
|
3
|
+
"version": "1100.3.0",
|
|
4
4
|
"description": "Commands for running scripts",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@inquirer/prompts": "^8.4.3",
|
|
32
|
-
"@pnpm/log.group": "
|
|
33
|
-
"@pnpm/util.lex-comparator": "^
|
|
32
|
+
"@pnpm/log.group": "4.0.1",
|
|
33
|
+
"@pnpm/util.lex-comparator": "^4.0.1",
|
|
34
34
|
"@zkochan/rimraf": "^4.0.0",
|
|
35
35
|
"didyoumean2": "^7.0.4",
|
|
36
36
|
"execa": "npm:safe-execa@0.3.0",
|
|
@@ -41,49 +41,49 @@
|
|
|
41
41
|
"symlink-dir": "^10.0.1",
|
|
42
42
|
"which": "npm:@pnpm/which@^3.0.1",
|
|
43
43
|
"write-json-file": "^7.0.0",
|
|
44
|
+
"@pnpm/building.commands": "1100.1.6",
|
|
44
45
|
"@pnpm/catalogs.resolver": "1100.0.0",
|
|
45
|
-
"@pnpm/
|
|
46
|
-
"@pnpm/bins.resolver": "1100.0.7",
|
|
46
|
+
"@pnpm/bins.resolver": "1100.0.8",
|
|
47
47
|
"@pnpm/cli.command": "1100.0.1",
|
|
48
|
-
"@pnpm/config.reader": "1101.8.0",
|
|
49
|
-
"@pnpm/config.version-policy": "1100.1.4",
|
|
50
|
-
"@pnpm/crypto.hash": "1100.0.1",
|
|
51
|
-
"@pnpm/deps.status": "1100.1.0",
|
|
52
|
-
"@pnpm/core-loggers": "1100.2.0",
|
|
53
48
|
"@pnpm/cli.common-cli-options-help": "1100.0.2",
|
|
54
|
-
"@pnpm/
|
|
55
|
-
"@pnpm/
|
|
56
|
-
"@pnpm/
|
|
49
|
+
"@pnpm/config.version-policy": "1100.1.5",
|
|
50
|
+
"@pnpm/cli.utils": "1101.0.12",
|
|
51
|
+
"@pnpm/config.reader": "1101.10.0",
|
|
52
|
+
"@pnpm/core-loggers": "1100.2.1",
|
|
57
53
|
"@pnpm/error": "1100.0.0",
|
|
58
|
-
"@pnpm/
|
|
59
|
-
"@pnpm/
|
|
60
|
-
"@pnpm/
|
|
61
|
-
"@pnpm/
|
|
62
|
-
"@pnpm/
|
|
54
|
+
"@pnpm/crypto.hash": "1100.0.1",
|
|
55
|
+
"@pnpm/exec.pnpm-cli-runner": "1100.0.1",
|
|
56
|
+
"@pnpm/installing.client": "1100.2.9",
|
|
57
|
+
"@pnpm/exec.lifecycle": "1100.1.0",
|
|
58
|
+
"@pnpm/installing.commands": "1100.10.0",
|
|
59
|
+
"@pnpm/pkg-manifest.reader": "1100.0.8",
|
|
63
60
|
"@pnpm/shell.path": "1100.0.1",
|
|
64
|
-
"@pnpm/
|
|
65
|
-
"@pnpm/workspace.
|
|
61
|
+
"@pnpm/resolving.parse-wanted-dependency": "1100.0.1",
|
|
62
|
+
"@pnpm/workspace.injected-deps-syncer": "1100.0.20",
|
|
63
|
+
"@pnpm/types": "1101.3.2",
|
|
66
64
|
"@pnpm/store.path": "1100.0.1",
|
|
67
|
-
"@pnpm/
|
|
68
|
-
"@pnpm/
|
|
65
|
+
"@pnpm/deps.status": "1100.1.2",
|
|
66
|
+
"@pnpm/workspace.project-manifest-reader": "1100.0.13",
|
|
67
|
+
"@pnpm/workspace.projects-sorter": "1100.0.7",
|
|
68
|
+
"@pnpm/engine.runtime.commands": "1100.1.6"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"@pnpm/logger": "^
|
|
71
|
+
"@pnpm/logger": "^1100.0.0"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
|
-
"@jest/globals": "30.
|
|
74
|
+
"@jest/globals": "30.4.1",
|
|
75
75
|
"@types/is-windows": "^1.0.2",
|
|
76
76
|
"@types/ramda": "0.31.1",
|
|
77
77
|
"@types/which": "^3.0.4",
|
|
78
78
|
"is-windows": "^1.0.2",
|
|
79
79
|
"write-yaml-file": "^6.0.0",
|
|
80
|
+
"@pnpm/exec.commands": "1100.3.0",
|
|
80
81
|
"@pnpm/logger": "1100.0.0",
|
|
81
|
-
"@pnpm/
|
|
82
|
-
"@pnpm/
|
|
83
|
-
"@pnpm/
|
|
82
|
+
"@pnpm/prepare": "1100.0.16",
|
|
83
|
+
"@pnpm/engine.runtime.system-version": "1100.0.3",
|
|
84
|
+
"@pnpm/workspace.projects-filter": "1100.0.22",
|
|
84
85
|
"@pnpm/test-ipc-server": "1100.0.0",
|
|
85
|
-
"@pnpm/
|
|
86
|
-
"@pnpm/testing.command-defaults": "1100.0.5"
|
|
86
|
+
"@pnpm/testing.command-defaults": "1100.0.6"
|
|
87
87
|
},
|
|
88
88
|
"engines": {
|
|
89
89
|
"node": ">=22.13"
|