@pnpm/installing.commands 1004.6.10
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/LICENSE +22 -0
- package/README.md +15 -0
- package/lib/add.d.ts +17 -0
- package/lib/add.js +285 -0
- package/lib/ci.d.ts +6 -0
- package/lib/ci.js +20 -0
- package/lib/createProjectManifestWriter.d.ts +2 -0
- package/lib/createProjectManifestWriter.js +17 -0
- package/lib/dedupe.d.ts +9 -0
- package/lib/dedupe.js +59 -0
- package/lib/fetch.d.ts +10 -0
- package/lib/fetch.js +75 -0
- package/lib/getFetchFullMetadata.d.ts +8 -0
- package/lib/getFetchFullMetadata.js +7 -0
- package/lib/getPinnedVersion.d.ts +4 -0
- package/lib/getPinnedVersion.js +6 -0
- package/lib/getSaveType.d.ts +3 -0
- package/lib/getSaveType.js +10 -0
- package/lib/import/index.d.ts +9 -0
- package/lib/import/index.js +238 -0
- package/lib/import/yarnUtil.d.ts +8 -0
- package/lib/import/yarnUtil.js +65 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +13 -0
- package/lib/install.d.ts +28 -0
- package/lib/install.js +281 -0
- package/lib/installDeps.d.ts +41 -0
- package/lib/installDeps.js +349 -0
- package/lib/link.d.ts +9 -0
- package/lib/link.js +130 -0
- package/lib/nodeExecPath.d.ts +1 -0
- package/lib/nodeExecPath.js +16 -0
- package/lib/prune.d.ts +6 -0
- package/lib/prune.js +49 -0
- package/lib/recursive.d.ts +41 -0
- package/lib/recursive.js +406 -0
- package/lib/remove.d.ts +12 -0
- package/lib/remove.js +189 -0
- package/lib/unlink.d.ts +6 -0
- package/lib/unlink.js +62 -0
- package/lib/update/getUpdateChoices.d.ts +14 -0
- package/lib/update/getUpdateChoices.js +126 -0
- package/lib/update/index.d.ts +15 -0
- package/lib/update/index.js +295 -0
- package/lib/updateWorkspaceDependencies.d.ts +4 -0
- package/lib/updateWorkspaceDependencies.js +27 -0
- package/package.json +134 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { docsUrl } from '@pnpm/cli.utils';
|
|
4
|
+
import { WANTED_LOCKFILE } from '@pnpm/constants';
|
|
5
|
+
import { PnpmError } from '@pnpm/error';
|
|
6
|
+
import gfs from '@pnpm/fs.graceful-fs';
|
|
7
|
+
import { install } from '@pnpm/installing.deps-installer';
|
|
8
|
+
import { logger } from '@pnpm/logger';
|
|
9
|
+
import { createStoreController, } from '@pnpm/store.connection-manager';
|
|
10
|
+
import { readProjectManifestOnly } from '@pnpm/workspace.project-manifest-reader';
|
|
11
|
+
import { findWorkspaceProjects } from '@pnpm/workspace.projects-reader';
|
|
12
|
+
import { sequenceGraph } from '@pnpm/workspace.projects-sorter';
|
|
13
|
+
import * as structUtils from '@yarnpkg/core/structUtils';
|
|
14
|
+
import yarnLockfileLib from '@yarnpkg/lockfile';
|
|
15
|
+
import { parseSyml } from '@yarnpkg/parsers';
|
|
16
|
+
import { rimraf } from '@zkochan/rimraf';
|
|
17
|
+
import { loadJsonFile } from 'load-json-file';
|
|
18
|
+
import { map as mapValues } from 'ramda';
|
|
19
|
+
import { renderHelp } from 'render-help';
|
|
20
|
+
import { recursive } from '../recursive.js';
|
|
21
|
+
import { yarnLockFileKeyNormalizer } from './yarnUtil.js';
|
|
22
|
+
const YarnLockType = {
|
|
23
|
+
yarn: 'yarn',
|
|
24
|
+
yarn2: 'yarn2',
|
|
25
|
+
};
|
|
26
|
+
export const rcOptionsTypes = cliOptionsTypes;
|
|
27
|
+
export function cliOptionsTypes() {
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
export function help() {
|
|
31
|
+
return renderHelp({
|
|
32
|
+
description: `Generates ${WANTED_LOCKFILE} from an npm package-lock.json (or npm-shrinkwrap.json, yarn.lock) file.`,
|
|
33
|
+
url: docsUrl('import'),
|
|
34
|
+
usages: [
|
|
35
|
+
'pnpm import',
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
export const commandNames = ['import'];
|
|
40
|
+
export async function handler(opts, params) {
|
|
41
|
+
// Removing existing pnpm lockfile
|
|
42
|
+
// it should not influence the new one
|
|
43
|
+
await rimraf(path.join(opts.dir, WANTED_LOCKFILE));
|
|
44
|
+
const versionsByPackageNames = {};
|
|
45
|
+
let preferredVersions = {};
|
|
46
|
+
if (fs.existsSync(path.join(opts.dir, 'yarn.lock'))) {
|
|
47
|
+
const yarnPackageLockFile = await readYarnLockFile(opts.dir);
|
|
48
|
+
getAllVersionsFromYarnLockFile(yarnPackageLockFile, versionsByPackageNames);
|
|
49
|
+
}
|
|
50
|
+
else if (fs.existsSync(path.join(opts.dir, 'package-lock.json')) ||
|
|
51
|
+
fs.existsSync(path.join(opts.dir, 'npm-shrinkwrap.json'))) {
|
|
52
|
+
const npmPackageLock = await readNpmLockfile(opts.dir);
|
|
53
|
+
if (npmPackageLock.lockfileVersion < 3) {
|
|
54
|
+
getAllVersionsByPackageNamesPreV3(npmPackageLock, versionsByPackageNames);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
getAllVersionsByPackageNames(npmPackageLock, versionsByPackageNames);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
throw new PnpmError('LOCKFILE_NOT_FOUND', 'No lockfile found');
|
|
62
|
+
}
|
|
63
|
+
preferredVersions = getPreferredVersions(versionsByPackageNames);
|
|
64
|
+
// For a workspace with shared lockfile
|
|
65
|
+
if (opts.workspaceDir) {
|
|
66
|
+
const allProjects = opts.allProjects ?? await findWorkspaceProjects(opts.workspaceDir, {
|
|
67
|
+
...opts,
|
|
68
|
+
patterns: opts.workspacePackagePatterns,
|
|
69
|
+
});
|
|
70
|
+
const selectedProjectsGraph = opts.selectedProjectsGraph ?? selectProjectByDir(allProjects, opts.dir);
|
|
71
|
+
if (selectedProjectsGraph != null) {
|
|
72
|
+
const sequencedGraph = sequenceGraph(selectedProjectsGraph);
|
|
73
|
+
// Check and warn if there are cyclic dependencies
|
|
74
|
+
if (!opts.ignoreWorkspaceCycles && !sequencedGraph.safe) {
|
|
75
|
+
const cyclicDependenciesInfo = sequencedGraph.cycles.length > 0
|
|
76
|
+
? `: ${sequencedGraph.cycles.map(deps => deps.join(', ')).join('; ')}`
|
|
77
|
+
: '';
|
|
78
|
+
if (opts.disallowWorkspaceCycles) {
|
|
79
|
+
throw new PnpmError('DISALLOW_WORKSPACE_CYCLES', `There are cyclic workspace dependencies${cyclicDependenciesInfo}`);
|
|
80
|
+
}
|
|
81
|
+
logger.warn({
|
|
82
|
+
message: `There are cyclic workspace dependencies${cyclicDependenciesInfo}`,
|
|
83
|
+
prefix: opts.workspaceDir,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
await recursive(allProjects, params,
|
|
87
|
+
// @ts-expect-error
|
|
88
|
+
{
|
|
89
|
+
...opts,
|
|
90
|
+
lockfileOnly: true,
|
|
91
|
+
selectedProjectsGraph,
|
|
92
|
+
preferredVersions,
|
|
93
|
+
workspaceDir: opts.workspaceDir,
|
|
94
|
+
}, 'import');
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const store = await createStoreController(opts);
|
|
99
|
+
const manifest = await readProjectManifestOnly(opts.dir);
|
|
100
|
+
const installOpts = {
|
|
101
|
+
...opts,
|
|
102
|
+
lockfileOnly: true,
|
|
103
|
+
preferredVersions,
|
|
104
|
+
storeController: store.ctrl,
|
|
105
|
+
storeDir: store.dir,
|
|
106
|
+
};
|
|
107
|
+
await install(manifest, installOpts);
|
|
108
|
+
}
|
|
109
|
+
async function readYarnLockFile(dir) {
|
|
110
|
+
try {
|
|
111
|
+
const yarnLockFile = await gfs.readFile(path.join(dir, 'yarn.lock'), 'utf8');
|
|
112
|
+
const yarnLockFileType = getYarnLockfileType(yarnLockFile);
|
|
113
|
+
if (yarnLockFileType === YarnLockType.yarn) {
|
|
114
|
+
const lockJsonFile = yarnLockfileLib.parse(yarnLockFile);
|
|
115
|
+
if (lockJsonFile.type === 'success') {
|
|
116
|
+
return lockJsonFile.object;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
throw new PnpmError('YARN_LOCKFILE_PARSE_FAILED', `Yarn.lock file was ${lockJsonFile.type}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if (yarnLockFileType === YarnLockType.yarn2) {
|
|
123
|
+
const lockJsonFile = parseYarn2Lock(yarnLockFile);
|
|
124
|
+
if (lockJsonFile.type === YarnLockType.yarn2) {
|
|
125
|
+
return lockJsonFile.object;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (err) { // eslint-disable-line
|
|
130
|
+
if (err['code'] !== 'ENOENT')
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
throw new PnpmError('YARN_LOCKFILE_NOT_FOUND', 'No yarn.lock found');
|
|
134
|
+
}
|
|
135
|
+
function parseYarn2Lock(lockFileContents) {
|
|
136
|
+
const parseYarnLock = parseSyml(lockFileContents);
|
|
137
|
+
delete parseYarnLock.__metadata;
|
|
138
|
+
const dependencies = {};
|
|
139
|
+
const { parseDescriptor, parseRange } = structUtils;
|
|
140
|
+
const keyNormalizer = yarnLockFileKeyNormalizer(parseDescriptor, parseRange);
|
|
141
|
+
for (const fullDescriptor in parseYarnLock) {
|
|
142
|
+
const versionData = parseYarnLock[fullDescriptor];
|
|
143
|
+
for (const descriptor of keyNormalizer(fullDescriptor)) {
|
|
144
|
+
dependencies[descriptor] = versionData;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
object: dependencies,
|
|
149
|
+
type: YarnLockType.yarn2,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
async function readNpmLockfile(dir) {
|
|
153
|
+
try {
|
|
154
|
+
return await loadJsonFile(path.join(dir, 'package-lock.json'));
|
|
155
|
+
}
|
|
156
|
+
catch (err) { // eslint-disable-line
|
|
157
|
+
if (err['code'] !== 'ENOENT')
|
|
158
|
+
throw err;
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
return await loadJsonFile(path.join(dir, 'npm-shrinkwrap.json'));
|
|
162
|
+
}
|
|
163
|
+
catch (err) { // eslint-disable-line
|
|
164
|
+
if (err['code'] !== 'ENOENT')
|
|
165
|
+
throw err;
|
|
166
|
+
}
|
|
167
|
+
throw new PnpmError('NPM_LOCKFILE_NOT_FOUND', 'No package-lock.json or npm-shrinkwrap.json found');
|
|
168
|
+
}
|
|
169
|
+
function getPreferredVersions(versionsByPackageNames) {
|
|
170
|
+
const preferredVersions = mapValues((versions) => Object.fromEntries(Array.from(versions).map((version) => [version, 'version'])), versionsByPackageNames);
|
|
171
|
+
return preferredVersions;
|
|
172
|
+
}
|
|
173
|
+
function getAllVersionsByPackageNamesPreV3(npmPackageLock, versionsByPackageNames) {
|
|
174
|
+
if (npmPackageLock.dependencies == null)
|
|
175
|
+
return;
|
|
176
|
+
for (const [packageName, { version }] of Object.entries(npmPackageLock.dependencies)) {
|
|
177
|
+
if (!versionsByPackageNames[packageName]) {
|
|
178
|
+
versionsByPackageNames[packageName] = new Set();
|
|
179
|
+
}
|
|
180
|
+
versionsByPackageNames[packageName].add(version);
|
|
181
|
+
}
|
|
182
|
+
for (const dep of Object.values(npmPackageLock.dependencies)) {
|
|
183
|
+
getAllVersionsByPackageNamesPreV3(dep, versionsByPackageNames);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function getAllVersionsByPackageNames(pkg, versionsByPackageNames) {
|
|
187
|
+
if (pkg.dependencies) {
|
|
188
|
+
extractDependencies(versionsByPackageNames, pkg.dependencies);
|
|
189
|
+
}
|
|
190
|
+
if ('packages' in pkg && pkg.packages) {
|
|
191
|
+
extractDependencies(versionsByPackageNames, pkg.packages);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function extractDependencies(versionsByPackageNames, dependencies) {
|
|
195
|
+
for (let [pkgName, pkgDetails] of Object.entries(dependencies)) {
|
|
196
|
+
if (pkgName.includes('node_modules')) {
|
|
197
|
+
pkgName = pkgName.substring(pkgName.lastIndexOf('node_modules/') + 13);
|
|
198
|
+
}
|
|
199
|
+
if (!versionsByPackageNames[pkgName]) {
|
|
200
|
+
versionsByPackageNames[pkgName] = new Set();
|
|
201
|
+
}
|
|
202
|
+
if (pkgDetails.version) {
|
|
203
|
+
versionsByPackageNames[pkgName].add(pkgDetails.version);
|
|
204
|
+
}
|
|
205
|
+
if (pkgDetails.packages) {
|
|
206
|
+
extractDependencies(versionsByPackageNames, pkgDetails.packages);
|
|
207
|
+
}
|
|
208
|
+
if (pkgDetails.dependencies) {
|
|
209
|
+
for (const [pkgName1, version] of Object.entries(pkgDetails.dependencies)) {
|
|
210
|
+
if (!versionsByPackageNames[pkgName1]) {
|
|
211
|
+
versionsByPackageNames[pkgName1] = new Set();
|
|
212
|
+
}
|
|
213
|
+
versionsByPackageNames[pkgName1].add(version);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function getAllVersionsFromYarnLockFile(yarnPackageLock, versionsByPackageNames) {
|
|
219
|
+
for (const [packageName, { version }] of Object.entries(yarnPackageLock)) {
|
|
220
|
+
const pkgName = packageName.substring(0, packageName.lastIndexOf('@'));
|
|
221
|
+
if (!versionsByPackageNames[pkgName]) {
|
|
222
|
+
versionsByPackageNames[pkgName] = new Set();
|
|
223
|
+
}
|
|
224
|
+
versionsByPackageNames[pkgName].add(version);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function selectProjectByDir(projects, searchedDir) {
|
|
228
|
+
const project = projects.find(({ rootDir }) => path.relative(rootDir, searchedDir) === '');
|
|
229
|
+
if (project == null)
|
|
230
|
+
return undefined;
|
|
231
|
+
return { [searchedDir]: { dependencies: [], package: project } };
|
|
232
|
+
}
|
|
233
|
+
function getYarnLockfileType(lockFileContents) {
|
|
234
|
+
return lockFileContents.includes('__metadata')
|
|
235
|
+
? YarnLockType.yarn2
|
|
236
|
+
: YarnLockType.yarn;
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* https://github.com/snyk/nodejs-lockfile-parser/blob/master/lib/parsers/yarn-utils.ts
|
|
3
|
+
*/
|
|
4
|
+
import type { structUtils } from '@yarnpkg/core';
|
|
5
|
+
export type ParseDescriptor = typeof structUtils.parseDescriptor;
|
|
6
|
+
export type ParseRange = typeof structUtils.parseRange;
|
|
7
|
+
export type YarnLockFileKeyNormalizer = (fullDescriptor: string) => Set<string>;
|
|
8
|
+
export declare const yarnLockFileKeyNormalizer: (parseDescriptor: typeof structUtils.parseDescriptor, parseRange: typeof structUtils.parseRange) => YarnLockFileKeyNormalizer;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const BUILTIN_PLACEHOLDER = 'builtin';
|
|
2
|
+
const MULTIPLE_KEYS_REGEXP = / *, */;
|
|
3
|
+
const keyNormalizer = (parseDescriptor, parseRange) => (rawDescriptor) => {
|
|
4
|
+
// See https://yarnpkg.com/features/protocols
|
|
5
|
+
const descriptors = [rawDescriptor];
|
|
6
|
+
const descriptor = parseDescriptor(rawDescriptor);
|
|
7
|
+
const name = `${descriptor.scope ? '@' + descriptor.scope + '/' : ''}${descriptor.name}`;
|
|
8
|
+
const range = parseRange(descriptor.range);
|
|
9
|
+
const protocol = range.protocol;
|
|
10
|
+
switch (protocol) {
|
|
11
|
+
case 'npm:':
|
|
12
|
+
case 'file:':
|
|
13
|
+
descriptors.push(`${name}@${range.selector}`);
|
|
14
|
+
descriptors.push(`${name}@${protocol}${range.selector}`);
|
|
15
|
+
break;
|
|
16
|
+
case 'git:':
|
|
17
|
+
case 'git+ssh:':
|
|
18
|
+
case 'git+http:':
|
|
19
|
+
case 'git+https:':
|
|
20
|
+
case 'github:':
|
|
21
|
+
if (range.source) {
|
|
22
|
+
descriptors.push(`${name}@${protocol}${range.source}${range.selector ? '#' + range.selector : ''}`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
descriptors.push(`${name}@${protocol}${range.selector}`);
|
|
26
|
+
}
|
|
27
|
+
break;
|
|
28
|
+
case 'patch:':
|
|
29
|
+
if (range.source && range.selector.startsWith(BUILTIN_PLACEHOLDER)) {
|
|
30
|
+
descriptors.push(range.source);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
descriptors.push(`${name}@${protocol}${range.source}${range.selector ? '#' + range.selector : ''}`);
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
case null:
|
|
37
|
+
case undefined:
|
|
38
|
+
if (range.source) {
|
|
39
|
+
descriptors.push(`${name}@${range.source}#${range.selector}`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
descriptors.push(`${name}@${range.selector}`);
|
|
43
|
+
}
|
|
44
|
+
break;
|
|
45
|
+
case 'http:':
|
|
46
|
+
case 'https:':
|
|
47
|
+
case 'link:':
|
|
48
|
+
case 'portal:':
|
|
49
|
+
case 'exec:':
|
|
50
|
+
case 'workspace:':
|
|
51
|
+
case 'virtual:':
|
|
52
|
+
default:
|
|
53
|
+
// For user defined plugins
|
|
54
|
+
descriptors.push(`${name}@${protocol}${range.selector}`);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
return descriptors;
|
|
58
|
+
};
|
|
59
|
+
export const yarnLockFileKeyNormalizer = (parseDescriptor, parseRange) => (fullDescriptor) => {
|
|
60
|
+
const allKeys = fullDescriptor
|
|
61
|
+
.split(MULTIPLE_KEYS_REGEXP)
|
|
62
|
+
.map(keyNormalizer(parseDescriptor, parseRange));
|
|
63
|
+
return new Set(allKeys.flat(5));
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=yarnUtil.js.map
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as add from './add.js';
|
|
2
|
+
import * as ci from './ci.js';
|
|
3
|
+
import * as dedupe from './dedupe.js';
|
|
4
|
+
import * as fetch from './fetch.js';
|
|
5
|
+
import * as importCommand from './import/index.js';
|
|
6
|
+
import type { InstallCommandOptions } from './install.js';
|
|
7
|
+
import * as install from './install.js';
|
|
8
|
+
import * as link from './link.js';
|
|
9
|
+
import * as prune from './prune.js';
|
|
10
|
+
import * as remove from './remove.js';
|
|
11
|
+
import * as unlink from './unlink.js';
|
|
12
|
+
import * as update from './update/index.js';
|
|
13
|
+
export { add, ci, dedupe, fetch, importCommand, install, type InstallCommandOptions, link, prune, remove, unlink, update };
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as add from './add.js';
|
|
2
|
+
import * as ci from './ci.js';
|
|
3
|
+
import * as dedupe from './dedupe.js';
|
|
4
|
+
import * as fetch from './fetch.js';
|
|
5
|
+
import * as importCommand from './import/index.js';
|
|
6
|
+
import * as install from './install.js';
|
|
7
|
+
import * as link from './link.js';
|
|
8
|
+
import * as prune from './prune.js';
|
|
9
|
+
import * as remove from './remove.js';
|
|
10
|
+
import * as unlink from './unlink.js';
|
|
11
|
+
import * as update from './update/index.js';
|
|
12
|
+
export { add, ci, dedupe, fetch, importCommand, install, link, prune, remove, unlink, update };
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
package/lib/install.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Config } from '@pnpm/config.reader';
|
|
2
|
+
import type { CreateStoreControllerOptions } from '@pnpm/store.connection-manager';
|
|
3
|
+
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
4
|
+
export declare const cliOptionsTypes: () => Record<string, unknown>;
|
|
5
|
+
export declare const shorthands: Record<string, string>;
|
|
6
|
+
export declare const commandNames: string[];
|
|
7
|
+
export declare function help(): string;
|
|
8
|
+
export type InstallCommandOptions = Pick<Config, 'allProjects' | 'autoInstallPeers' | 'bail' | 'bin' | 'catalogs' | 'cliOptions' | 'configDependencies' | 'dedupeInjectedDeps' | 'dedupeDirectDeps' | 'dedupePeerDependents' | 'deployAllFiles' | 'depth' | 'dev' | 'enableGlobalVirtualStore' | 'engineStrict' | 'excludeLinksFromLockfile' | 'frozenLockfile' | 'global' | 'globalPnpmfile' | 'hooks' | 'ignorePnpmfile' | 'ignoreScripts' | 'injectWorkspacePackages' | 'linkWorkspacePackages' | 'rawLocalConfig' | 'lockfileDir' | 'lockfileOnly' | 'modulesDir' | 'nodeLinker' | 'patchedDependencies' | 'preferFrozenLockfile' | 'preferWorkspacePackages' | 'production' | 'registries' | 'rootProjectManifest' | 'rootProjectManifestDir' | 'save' | 'saveDev' | 'saveExact' | 'saveOptional' | 'savePeer' | 'savePrefix' | 'saveProd' | 'saveCatalogName' | 'saveWorkspaceProtocol' | 'lockfileIncludeTarballUrl' | 'allProjectsGraph' | 'selectedProjectsGraph' | 'sideEffectsCache' | 'sideEffectsCacheReadonly' | 'sort' | 'sharedWorkspaceLockfile' | 'tag' | 'allowBuilds' | 'optional' | 'virtualStoreDir' | 'workspaceConcurrency' | 'workspaceDir' | 'workspacePackagePatterns' | 'extraEnv' | 'resolutionMode' | 'ignoreWorkspaceCycles' | 'disallowWorkspaceCycles' | 'updateConfig' | 'overrides' | 'packageExtensions' | 'supportedArchitectures' | 'packageConfigs'> & CreateStoreControllerOptions & Partial<Pick<Config, 'globalPkgDir'>> & {
|
|
9
|
+
argv: {
|
|
10
|
+
original: string[];
|
|
11
|
+
};
|
|
12
|
+
fixLockfile?: boolean;
|
|
13
|
+
frozenLockfileIfExists?: boolean;
|
|
14
|
+
useBetaCli?: boolean;
|
|
15
|
+
pruneDirectDependencies?: boolean;
|
|
16
|
+
pruneLockfileImporters?: boolean;
|
|
17
|
+
pruneStore?: boolean;
|
|
18
|
+
recursive?: boolean;
|
|
19
|
+
resolutionOnly?: boolean;
|
|
20
|
+
saveLockfile?: boolean;
|
|
21
|
+
workspace?: boolean;
|
|
22
|
+
includeOnlyPackageFiles?: boolean;
|
|
23
|
+
confirmModulesPurge?: boolean;
|
|
24
|
+
pnpmfile: string[];
|
|
25
|
+
} & Partial<Pick<Config, 'ci' | 'modulesCacheMaxAge' | 'pnpmHomeDir' | 'preferWorkspacePackages' | 'useLockfile' | 'symlink'>>;
|
|
26
|
+
export declare function handler(opts: InstallCommandOptions & {
|
|
27
|
+
_calledFromLink?: boolean;
|
|
28
|
+
}): Promise<void>;
|
package/lib/install.js
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { FILTERING, OPTIONS, OUTPUT_OPTIONS, UNIVERSAL_OPTIONS } from '@pnpm/cli.common-cli-options-help';
|
|
2
|
+
import { docsUrl } from '@pnpm/cli.utils';
|
|
3
|
+
import { types as allTypes } from '@pnpm/config.reader';
|
|
4
|
+
import { WANTED_LOCKFILE } from '@pnpm/constants';
|
|
5
|
+
import { PnpmError } from '@pnpm/error';
|
|
6
|
+
import { pick } from 'ramda';
|
|
7
|
+
import { renderHelp } from 'render-help';
|
|
8
|
+
import { getFetchFullMetadata } from './getFetchFullMetadata.js';
|
|
9
|
+
import { installDeps } from './installDeps.js';
|
|
10
|
+
export function rcOptionsTypes() {
|
|
11
|
+
return pick([
|
|
12
|
+
'cache-dir',
|
|
13
|
+
'child-concurrency',
|
|
14
|
+
'cpu',
|
|
15
|
+
'dangerously-allow-all-builds',
|
|
16
|
+
'dev',
|
|
17
|
+
'engine-strict',
|
|
18
|
+
'fetch-retries',
|
|
19
|
+
'fetch-retry-factor',
|
|
20
|
+
'fetch-retry-maxtimeout',
|
|
21
|
+
'fetch-retry-mintimeout',
|
|
22
|
+
'fetch-timeout',
|
|
23
|
+
'frozen-lockfile',
|
|
24
|
+
'global-dir',
|
|
25
|
+
'global-pnpmfile',
|
|
26
|
+
'global',
|
|
27
|
+
'hoist',
|
|
28
|
+
'hoist-pattern',
|
|
29
|
+
'https-proxy',
|
|
30
|
+
'ignore-pnpmfile',
|
|
31
|
+
'ignore-scripts',
|
|
32
|
+
'optimistic-repeat-install',
|
|
33
|
+
'os',
|
|
34
|
+
'libc',
|
|
35
|
+
'link-workspace-packages',
|
|
36
|
+
'lockfile-dir',
|
|
37
|
+
'lockfile-directory',
|
|
38
|
+
'lockfile-only',
|
|
39
|
+
'lockfile',
|
|
40
|
+
'merge-git-branch-lockfiles',
|
|
41
|
+
'merge-git-branch-lockfiles-branch-pattern',
|
|
42
|
+
'modules-dir',
|
|
43
|
+
'network-concurrency',
|
|
44
|
+
'node-linker',
|
|
45
|
+
'noproxy',
|
|
46
|
+
'package-import-method',
|
|
47
|
+
'pnpmfile',
|
|
48
|
+
'prefer-frozen-lockfile',
|
|
49
|
+
'prefer-offline',
|
|
50
|
+
'production',
|
|
51
|
+
'proxy',
|
|
52
|
+
'public-hoist-pattern',
|
|
53
|
+
'registry',
|
|
54
|
+
'reporter',
|
|
55
|
+
'save-workspace-protocol',
|
|
56
|
+
'scripts-prepend-node-path',
|
|
57
|
+
'shamefully-flatten',
|
|
58
|
+
'shamefully-hoist',
|
|
59
|
+
'shared-workspace-lockfile',
|
|
60
|
+
'side-effects-cache-readonly',
|
|
61
|
+
'side-effects-cache',
|
|
62
|
+
'store-dir',
|
|
63
|
+
'strict-peer-dependencies',
|
|
64
|
+
'trust-policy',
|
|
65
|
+
'trust-policy-exclude',
|
|
66
|
+
'trust-policy-ignore-after',
|
|
67
|
+
'offline',
|
|
68
|
+
'only',
|
|
69
|
+
'optional',
|
|
70
|
+
'unsafe-perm',
|
|
71
|
+
'verify-store-integrity',
|
|
72
|
+
'virtual-store-dir',
|
|
73
|
+
'virtual-store-only',
|
|
74
|
+
], allTypes);
|
|
75
|
+
}
|
|
76
|
+
export const cliOptionsTypes = () => ({
|
|
77
|
+
...rcOptionsTypes(),
|
|
78
|
+
...pick(['force'], allTypes),
|
|
79
|
+
'fix-lockfile': Boolean,
|
|
80
|
+
'resolution-only': Boolean,
|
|
81
|
+
recursive: Boolean,
|
|
82
|
+
});
|
|
83
|
+
export const shorthands = {
|
|
84
|
+
D: '--dev',
|
|
85
|
+
P: '--production',
|
|
86
|
+
};
|
|
87
|
+
export const commandNames = ['install', 'i'];
|
|
88
|
+
export function help() {
|
|
89
|
+
return renderHelp({
|
|
90
|
+
aliases: ['i'],
|
|
91
|
+
description: 'Installs all dependencies of the project in the current working directory. \
|
|
92
|
+
When executed inside a workspace, installs all dependencies of all projects.',
|
|
93
|
+
descriptionLists: [
|
|
94
|
+
{
|
|
95
|
+
title: 'Options',
|
|
96
|
+
list: [
|
|
97
|
+
{
|
|
98
|
+
description: 'Run installation recursively in every package found in subdirectories. \
|
|
99
|
+
For options that may be used with `-r`, see "pnpm help recursive"',
|
|
100
|
+
name: '--recursive',
|
|
101
|
+
shortAlias: '-r',
|
|
102
|
+
},
|
|
103
|
+
OPTIONS.ignoreScripts,
|
|
104
|
+
OPTIONS.offline,
|
|
105
|
+
OPTIONS.preferOffline,
|
|
106
|
+
OPTIONS.globalDir,
|
|
107
|
+
{
|
|
108
|
+
description: "Packages in `devDependencies` won't be installed",
|
|
109
|
+
name: '--prod',
|
|
110
|
+
shortAlias: '-P',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
description: 'Only `devDependencies` are installed',
|
|
114
|
+
name: '--dev',
|
|
115
|
+
shortAlias: '-D',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
description: 'Skip reinstall if the workspace state is up-to-date',
|
|
119
|
+
name: '--optimistic-repeat-install',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
description: '`optionalDependencies` are not installed',
|
|
123
|
+
name: '--no-optional',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
description: `Don't read or generate a \`${WANTED_LOCKFILE}\` file`,
|
|
127
|
+
name: '--no-lockfile',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
description: `Dependencies are not downloaded. Only \`${WANTED_LOCKFILE}\` is updated`,
|
|
131
|
+
name: '--lockfile-only',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
description: "Don't generate a lockfile and fail if an update is needed. This setting is on by default in CI environments, so use --no-frozen-lockfile if you need to disable it for some reason",
|
|
135
|
+
name: '--[no-]frozen-lockfile',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
description: `If the available \`${WANTED_LOCKFILE}\` satisfies the \`package.json\` then perform a headless installation`,
|
|
139
|
+
name: '--prefer-frozen-lockfile',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
description: `The directory in which the ${WANTED_LOCKFILE} of the package will be created. Several projects may share a single lockfile.`,
|
|
143
|
+
name: '--lockfile-dir <dir>',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
description: 'Fix broken lockfile entries automatically',
|
|
147
|
+
name: '--fix-lockfile',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
description: 'Merge lockfiles were generated on git branch',
|
|
151
|
+
name: '--merge-git-branch-lockfiles',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
description: 'The directory in which dependencies will be installed (instead of node_modules)',
|
|
155
|
+
name: '--modules-dir <dir>',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
description: 'Dependencies inside the modules directory will have access only to their listed dependencies',
|
|
159
|
+
name: '--no-hoist',
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
description: 'All the subdeps will be hoisted into the root node_modules. Your code will have access to them',
|
|
163
|
+
name: '--shamefully-hoist',
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
description: 'Hoist all dependencies matching the pattern to `node_modules/.pnpm/node_modules`. \
|
|
167
|
+
The default pattern is * and matches everything. Hoisted packages can be required \
|
|
168
|
+
by any dependencies, so it is an emulation of a flat node_modules',
|
|
169
|
+
name: '--hoist-pattern <pattern>',
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
description: 'Hoist all dependencies matching the pattern to the root of the modules directory',
|
|
173
|
+
name: '--public-hoist-pattern <pattern>',
|
|
174
|
+
},
|
|
175
|
+
OPTIONS.storeDir,
|
|
176
|
+
OPTIONS.virtualStoreDir,
|
|
177
|
+
{
|
|
178
|
+
description: 'Maximum number of concurrent network requests',
|
|
179
|
+
name: '--network-concurrency <number>',
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
description: 'Controls the number of child processes run parallelly to build node modules',
|
|
183
|
+
name: '--child-concurrency <number>',
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
description: 'Disable pnpm hooks defined in .pnpmfile.cjs',
|
|
187
|
+
name: '--ignore-pnpmfile',
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
description: 'Ignore pnpm-workspace.yaml if exists in the parent directory, and treat the installation as normal non-workspace installation.',
|
|
191
|
+
name: '--ignore-workspace',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
description: "If false, doesn't check whether packages in the store were mutated",
|
|
195
|
+
name: '--[no-]verify-store-integrity',
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
description: 'Fail on missing or invalid peer dependencies',
|
|
199
|
+
name: '--strict-peer-dependencies',
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
description: "Fail when a package's trust level is downgraded (e.g., from a trusted publisher to provenance only or no trust evidence)",
|
|
203
|
+
name: '--trust-policy no-downgrade',
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
description: 'Exclude specific packages from trust policy checks',
|
|
207
|
+
name: '--trust-policy-exclude <package-spec>',
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
description: 'Ignore trust downgrades for packages published more than specified minutes ago',
|
|
211
|
+
name: '--trust-policy-ignore-after <minutes>',
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
description: 'Clones/hardlinks or copies packages. The selected method depends from the file system',
|
|
215
|
+
name: '--package-import-method auto',
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
description: 'Hardlink packages from the store',
|
|
219
|
+
name: '--package-import-method hardlink',
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
description: 'Copy packages from the store',
|
|
223
|
+
name: '--package-import-method copy',
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
description: 'Clone (aka copy-on-write) packages from the store',
|
|
227
|
+
name: '--package-import-method clone',
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
description: 'Force reinstall dependencies: refetch packages modified in store, \
|
|
231
|
+
recreate a lockfile and/or modules directory created by a non-compatible version of pnpm. \
|
|
232
|
+
Install all optionalDependencies even when they don\'t satisfy the current environment(cpu, os, arch)',
|
|
233
|
+
name: '--force',
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
description: 'Use or cache the results of (pre/post)install hooks',
|
|
237
|
+
name: '--side-effects-cache',
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
description: 'Only use the side effects cache if present, do not create it for new packages',
|
|
241
|
+
name: '--side-effects-cache-readonly',
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
description: 'Re-runs resolution: useful for printing out peer dependency issues',
|
|
245
|
+
name: '--resolution-only',
|
|
246
|
+
},
|
|
247
|
+
...UNIVERSAL_OPTIONS,
|
|
248
|
+
],
|
|
249
|
+
},
|
|
250
|
+
OUTPUT_OPTIONS,
|
|
251
|
+
FILTERING,
|
|
252
|
+
],
|
|
253
|
+
url: docsUrl('install'),
|
|
254
|
+
usages: ['pnpm install [options]'],
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
export async function handler(opts) {
|
|
258
|
+
if (opts.global && !opts._calledFromLink) {
|
|
259
|
+
throw new PnpmError('GLOBAL_INSTALL_NOT_SUPPORTED', '"pnpm install -g" is not supported. Use "pnpm add -g <pkg>" to install global packages.');
|
|
260
|
+
}
|
|
261
|
+
const include = {
|
|
262
|
+
dependencies: opts.production !== false,
|
|
263
|
+
devDependencies: opts.dev !== false,
|
|
264
|
+
optionalDependencies: opts.optional !== false,
|
|
265
|
+
};
|
|
266
|
+
const installDepsOptions = {
|
|
267
|
+
...opts,
|
|
268
|
+
frozenLockfileIfExists: opts.frozenLockfileIfExists ?? (opts.ci && !opts.lockfileOnly &&
|
|
269
|
+
typeof opts.frozenLockfile === 'undefined' &&
|
|
270
|
+
typeof opts.preferFrozenLockfile === 'undefined'),
|
|
271
|
+
include,
|
|
272
|
+
includeDirect: include,
|
|
273
|
+
fetchFullMetadata: getFetchFullMetadata(opts),
|
|
274
|
+
};
|
|
275
|
+
if (opts.resolutionOnly) {
|
|
276
|
+
installDepsOptions.lockfileOnly = true;
|
|
277
|
+
installDepsOptions.forceFullResolution = true;
|
|
278
|
+
}
|
|
279
|
+
return installDeps(installDepsOptions, []);
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=install.js.map
|