@pnpm/releasing.commands 1100.6.0 → 1100.6.1
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/CHANGELOG.md +23 -0
- package/package.json +22 -22
- package/lib/change/index.d.ts +0 -41
- package/lib/change/index.js +0 -245
- package/lib/deploy/createDeployFiles.d.ts +0 -26
- package/lib/deploy/createDeployFiles.js +0 -255
- package/lib/deploy/deploy.d.ts +0 -12
- package/lib/deploy/deploy.js +0 -398
- package/lib/deploy/deployHook.d.ts +0 -2
- package/lib/deploy/deployHook.js +0 -15
- package/lib/deploy/index.d.ts +0 -2
- package/lib/deploy/index.js +0 -3
- package/lib/index.d.ts +0 -7
- package/lib/lane/index.d.ts +0 -24
- package/lib/lane/index.js +0 -157
- package/lib/pack-app/index.d.ts +0 -2
- package/lib/pack-app/index.js +0 -3
- package/lib/pack-app/packApp.d.ts +0 -22
- package/lib/pack-app/packApp.js +0 -558
- package/lib/publish/FailedToPublishError.d.ts +0 -22
- package/lib/publish/FailedToPublishError.js +0 -40
- package/lib/publish/batchPublish.d.ts +0 -20
- package/lib/publish/batchPublish.js +0 -201
- package/lib/publish/displayError.d.ts +0 -1
- package/lib/publish/displayError.js +0 -23
- package/lib/publish/executeTokenHelper.d.ts +0 -4
- package/lib/publish/executeTokenHelper.js +0 -17
- package/lib/publish/extractManifestFromPacked.d.ts +0 -19
- package/lib/publish/extractManifestFromPacked.js +0 -110
- package/lib/publish/index.d.ts +0 -3
- package/lib/publish/index.js +0 -4
- package/lib/publish/oidc/authToken.d.ts +0 -73
- package/lib/publish/oidc/authToken.js +0 -97
- package/lib/publish/oidc/idToken.d.ts +0 -76
- package/lib/publish/oidc/idToken.js +0 -90
- package/lib/publish/oidc/provenance.d.ts +0 -73
- package/lib/publish/oidc/provenance.js +0 -91
- package/lib/publish/otp.d.ts +0 -38
- package/lib/publish/otp.js +0 -41
- package/lib/publish/otpEnv.d.ts +0 -7
- package/lib/publish/otpEnv.js +0 -5
- package/lib/publish/pack.d.ts +0 -34
- package/lib/publish/pack.js +0 -408
- package/lib/publish/previousChangelog.d.ts +0 -19
- package/lib/publish/previousChangelog.js +0 -182
- package/lib/publish/publish.d.ts +0 -40
- package/lib/publish/publish.js +0 -256
- package/lib/publish/publishPackedPkg.d.ts +0 -79
- package/lib/publish/publishPackedPkg.js +0 -298
- package/lib/publish/recursivePublish.d.ts +0 -18
- package/lib/publish/recursivePublish.js +0 -132
- package/lib/publish/registryConfigKeys.d.ts +0 -30
- package/lib/publish/registryConfigKeys.js +0 -50
- package/lib/publish/utils/shared-context.d.ts +0 -7
- package/lib/publish/utils/shared-context.js +0 -20
- package/lib/stage/approve.d.ts +0 -2
- package/lib/stage/approve.js +0 -14
- package/lib/stage/context.d.ts +0 -14
- package/lib/stage/context.js +0 -25
- package/lib/stage/download.d.ts +0 -2
- package/lib/stage/download.js +0 -32
- package/lib/stage/errors.d.ts +0 -15
- package/lib/stage/errors.js +0 -17
- package/lib/stage/help.d.ts +0 -1
- package/lib/stage/help.js +0 -84
- package/lib/stage/index.d.ts +0 -13
- package/lib/stage/index.js +0 -57
- package/lib/stage/list.d.ts +0 -2
- package/lib/stage/list.js +0 -49
- package/lib/stage/parsing.d.ts +0 -6
- package/lib/stage/parsing.js +0 -27
- package/lib/stage/publish.d.ts +0 -7
- package/lib/stage/publish.js +0 -38
- package/lib/stage/reject.d.ts +0 -2
- package/lib/stage/reject.js +0 -16
- package/lib/stage/rendering.d.ts +0 -11
- package/lib/stage/rendering.js +0 -50
- package/lib/stage/request.d.ts +0 -29
- package/lib/stage/request.js +0 -110
- package/lib/stage/types.d.ts +0 -38
- package/lib/stage/types.js +0 -3
- package/lib/stage/view.d.ts +0 -2
- package/lib/stage/view.js +0 -14
- package/lib/tarball/index.d.ts +0 -2
- package/lib/tarball/index.js +0 -3
- package/lib/tarball/publishSummary.d.ts +0 -47
- package/lib/tarball/publishSummary.js +0 -36
- package/lib/tarball/safeTarballFilename.d.ts +0 -8
- package/lib/tarball/safeTarballFilename.js +0 -21
- package/lib/tarball/summarizeTarball.d.ts +0 -12
- package/lib/tarball/summarizeTarball.js +0 -84
- package/lib/version/index.d.ts +0 -33
- package/lib/version/index.js +0 -337
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import url from 'node:url';
|
|
3
|
-
import * as dp from '@pnpm/deps.path';
|
|
4
|
-
import normalizePath from 'normalize-path';
|
|
5
|
-
const DEPENDENCIES_FIELD = ['dependencies', 'devDependencies', 'optionalDependencies'];
|
|
6
|
-
export function createDeployFiles({ allProjects, deployDir, include, lockfile, lockfileDir, patchedDependencies, selectedProjectManifest, projectId, rootProjectManifestDir, allowBuilds, }) {
|
|
7
|
-
const deployedProjectRealPath = path.resolve(lockfileDir, projectId);
|
|
8
|
-
const inputSnapshot = lockfile.importers[projectId];
|
|
9
|
-
const targetSnapshot = {
|
|
10
|
-
...inputSnapshot,
|
|
11
|
-
specifiers: {},
|
|
12
|
-
dependencies: {},
|
|
13
|
-
devDependencies: {},
|
|
14
|
-
optionalDependencies: {},
|
|
15
|
-
};
|
|
16
|
-
const targetPackageSnapshots = {};
|
|
17
|
-
for (const name in lockfile.packages) {
|
|
18
|
-
const inputDepPath = name;
|
|
19
|
-
const inputSnapshot = lockfile.packages[inputDepPath];
|
|
20
|
-
const resolveResult = resolveLinkOrFile(inputDepPath, {
|
|
21
|
-
lockfileDir,
|
|
22
|
-
projectRootDirRealPath: rootProjectManifestDir,
|
|
23
|
-
});
|
|
24
|
-
const outputDepPath = resolveResult
|
|
25
|
-
? createFileUrlDepPath(resolveResult, allProjects)
|
|
26
|
-
: inputDepPath;
|
|
27
|
-
targetPackageSnapshots[outputDepPath] = convertPackageSnapshot(inputSnapshot, {
|
|
28
|
-
allProjects,
|
|
29
|
-
deployDir,
|
|
30
|
-
deployedProjectRealPath,
|
|
31
|
-
lockfileDir,
|
|
32
|
-
projectRootDirRealPath: rootProjectManifestDir,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
for (const importerPath in lockfile.importers) {
|
|
36
|
-
if (importerPath === projectId)
|
|
37
|
-
continue;
|
|
38
|
-
const projectSnapshot = lockfile.importers[importerPath];
|
|
39
|
-
const projectRootDirRealPath = path.resolve(lockfileDir, importerPath);
|
|
40
|
-
const packageSnapshot = convertProjectSnapshotToPackageSnapshot(projectSnapshot, {
|
|
41
|
-
allProjects,
|
|
42
|
-
deployDir,
|
|
43
|
-
lockfileDir,
|
|
44
|
-
deployedProjectRealPath,
|
|
45
|
-
projectRootDirRealPath,
|
|
46
|
-
});
|
|
47
|
-
const depPath = createFileUrlDepPath({ resolvedPath: projectRootDirRealPath }, allProjects);
|
|
48
|
-
targetPackageSnapshots[depPath] = packageSnapshot;
|
|
49
|
-
}
|
|
50
|
-
for (const field of DEPENDENCIES_FIELD) {
|
|
51
|
-
const targetDependencies = targetSnapshot[field] ?? {};
|
|
52
|
-
const targetSpecifiers = targetSnapshot.specifiers;
|
|
53
|
-
const inputDependencies = inputSnapshot[field] ?? {};
|
|
54
|
-
for (const name in inputDependencies) {
|
|
55
|
-
const version = inputDependencies[name];
|
|
56
|
-
const resolveResult = resolveLinkOrFile(version, {
|
|
57
|
-
lockfileDir,
|
|
58
|
-
projectRootDirRealPath: path.resolve(lockfileDir, projectId),
|
|
59
|
-
});
|
|
60
|
-
if (!resolveResult) {
|
|
61
|
-
targetSpecifiers[name] = targetDependencies[name] = version;
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
resolveResult.packageName ??= name;
|
|
65
|
-
targetSpecifiers[name] = targetDependencies[name] =
|
|
66
|
-
resolveResult.resolvedPath === deployedProjectRealPath ? 'link:.' : createFileUrlDepPath(resolveResult, allProjects);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
const deployPackageSnapshots = filterDeployPackageSnapshots(targetSnapshot, targetPackageSnapshots, include);
|
|
70
|
-
const result = {
|
|
71
|
-
lockfile: {
|
|
72
|
-
...lockfile,
|
|
73
|
-
// The deployed manifest contains concrete versions, and catalogs are not copied to the target.
|
|
74
|
-
catalogs: undefined,
|
|
75
|
-
patchedDependencies: undefined,
|
|
76
|
-
overrides: undefined, // the effects of the overrides should already be part of the package snapshots
|
|
77
|
-
packageExtensionsChecksum: undefined, // the effects of the package extensions should already be part of the package snapshots
|
|
78
|
-
pnpmfileChecksum: undefined, // the effects of the pnpmfile should already be part of the package snapshots
|
|
79
|
-
settings: {
|
|
80
|
-
...lockfile.settings,
|
|
81
|
-
injectWorkspacePackages: undefined, // the effects of injecting workspace packages should already be part of the lockfile
|
|
82
|
-
},
|
|
83
|
-
importers: {
|
|
84
|
-
['.']: targetSnapshot,
|
|
85
|
-
},
|
|
86
|
-
packages: deployPackageSnapshots,
|
|
87
|
-
},
|
|
88
|
-
manifest: {
|
|
89
|
-
...selectedProjectManifest,
|
|
90
|
-
dependencies: targetSnapshot.dependencies,
|
|
91
|
-
devDependencies: targetSnapshot.devDependencies,
|
|
92
|
-
optionalDependencies: targetSnapshot.optionalDependencies,
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
if (lockfile.patchedDependencies && patchedDependencies) {
|
|
96
|
-
result.lockfile.patchedDependencies = { ...lockfile.patchedDependencies };
|
|
97
|
-
const deployManifestPatchedDeps = {};
|
|
98
|
-
for (const name in patchedDependencies) {
|
|
99
|
-
const absolutePath = patchedDependencies[name];
|
|
100
|
-
const relativePath = normalizePath(path.relative(deployDir, absolutePath));
|
|
101
|
-
deployManifestPatchedDeps[name] = relativePath;
|
|
102
|
-
}
|
|
103
|
-
result.workspaceManifest = {
|
|
104
|
-
...result.workspaceManifest,
|
|
105
|
-
patchedDependencies: deployManifestPatchedDeps,
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
if (allowBuilds) {
|
|
109
|
-
result.workspaceManifest = {
|
|
110
|
-
...result.workspaceManifest,
|
|
111
|
-
allowBuilds,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
return result;
|
|
115
|
-
}
|
|
116
|
-
function filterDeployPackageSnapshots(importer, packages, include) {
|
|
117
|
-
const queue = [];
|
|
118
|
-
const enqueue = (dependencies) => {
|
|
119
|
-
for (const [alias, reference] of Object.entries(dependencies ?? {})) {
|
|
120
|
-
const depPath = dp.refToRelative(reference, alias);
|
|
121
|
-
if (depPath != null && packages[depPath] != null)
|
|
122
|
-
queue.push(depPath);
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
if (include.dependencies)
|
|
126
|
-
enqueue(importer.dependencies);
|
|
127
|
-
if (include.devDependencies)
|
|
128
|
-
enqueue(importer.devDependencies);
|
|
129
|
-
if (include.optionalDependencies)
|
|
130
|
-
enqueue(importer.optionalDependencies);
|
|
131
|
-
const reachable = new Set();
|
|
132
|
-
let head = 0;
|
|
133
|
-
while (head < queue.length) {
|
|
134
|
-
const depPath = queue[head++];
|
|
135
|
-
if (reachable.has(depPath))
|
|
136
|
-
continue;
|
|
137
|
-
reachable.add(depPath);
|
|
138
|
-
const snapshot = packages[depPath];
|
|
139
|
-
if (snapshot == null)
|
|
140
|
-
continue;
|
|
141
|
-
enqueue(snapshot.dependencies);
|
|
142
|
-
if (include.optionalDependencies)
|
|
143
|
-
enqueue(snapshot.optionalDependencies);
|
|
144
|
-
}
|
|
145
|
-
return Object.fromEntries(Array.from(reachable, (depPath) => [depPath, packages[depPath]]));
|
|
146
|
-
}
|
|
147
|
-
function convertPackageSnapshot(inputSnapshot, opts) {
|
|
148
|
-
const inputResolution = inputSnapshot.resolution;
|
|
149
|
-
let outputResolution;
|
|
150
|
-
if ('integrity' in inputResolution) {
|
|
151
|
-
outputResolution = inputResolution;
|
|
152
|
-
}
|
|
153
|
-
else if ('tarball' in inputResolution && typeof inputResolution.tarball === 'string') {
|
|
154
|
-
outputResolution = { ...inputResolution };
|
|
155
|
-
if (inputResolution.tarball.startsWith('file:')) {
|
|
156
|
-
const inputPath = inputResolution.tarball.slice('file:'.length);
|
|
157
|
-
const resolvedPath = path.resolve(opts.lockfileDir, inputPath);
|
|
158
|
-
const outputPath = normalizePath(path.relative(opts.deployDir, resolvedPath));
|
|
159
|
-
outputResolution.tarball = `file:${outputPath}`;
|
|
160
|
-
if ('path' in inputResolution && typeof inputResolution.path === 'string') {
|
|
161
|
-
outputResolution.path = outputPath;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else if (inputResolution.type === 'directory') {
|
|
166
|
-
const dirResolution = inputResolution;
|
|
167
|
-
const resolvedPath = path.resolve(opts.lockfileDir, dirResolution.directory);
|
|
168
|
-
const directory = normalizePath(path.relative(opts.deployDir, resolvedPath));
|
|
169
|
-
outputResolution = { ...dirResolution, directory };
|
|
170
|
-
}
|
|
171
|
-
else if (inputResolution.type === 'git' || inputResolution.type === 'variations') {
|
|
172
|
-
outputResolution = inputResolution;
|
|
173
|
-
}
|
|
174
|
-
else if (inputResolution.type && typeof inputResolution.type === 'string') {
|
|
175
|
-
// Custom resolution type - pass through as-is
|
|
176
|
-
outputResolution = inputResolution;
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
throw new Error(`Unknown resolution type: ${JSON.stringify(inputResolution)}`);
|
|
180
|
-
}
|
|
181
|
-
return {
|
|
182
|
-
...inputSnapshot,
|
|
183
|
-
resolution: outputResolution,
|
|
184
|
-
dependencies: convertResolvedDependencies(inputSnapshot.dependencies, opts),
|
|
185
|
-
optionalDependencies: convertResolvedDependencies(inputSnapshot.optionalDependencies, opts),
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
function convertProjectSnapshotToPackageSnapshot(projectSnapshot, opts) {
|
|
189
|
-
const resolution = {
|
|
190
|
-
type: 'directory',
|
|
191
|
-
directory: normalizePath(path.relative(opts.deployDir, opts.projectRootDirRealPath)),
|
|
192
|
-
};
|
|
193
|
-
const dependencies = convertResolvedDependencies(projectSnapshot.dependencies, opts);
|
|
194
|
-
const optionalDependencies = convertResolvedDependencies(projectSnapshot.optionalDependencies, opts);
|
|
195
|
-
return {
|
|
196
|
-
dependencies,
|
|
197
|
-
optionalDependencies,
|
|
198
|
-
resolution,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
function convertResolvedDependencies(input, opts) {
|
|
202
|
-
if (!input)
|
|
203
|
-
return undefined;
|
|
204
|
-
const output = {};
|
|
205
|
-
for (const key in input) {
|
|
206
|
-
const version = input[key];
|
|
207
|
-
const resolveResult = resolveLinkOrFile(version, opts);
|
|
208
|
-
if (!resolveResult) {
|
|
209
|
-
output[key] = version;
|
|
210
|
-
continue;
|
|
211
|
-
}
|
|
212
|
-
if (resolveResult.resolvedPath === opts.deployedProjectRealPath) {
|
|
213
|
-
output[key] = 'link:.'; // the path is relative to the lockfile dir, which means '.' would reference the deploy dir
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
resolveResult.packageName ??= key;
|
|
217
|
-
output[key] = createFileUrlDepPath(resolveResult, opts.allProjects);
|
|
218
|
-
}
|
|
219
|
-
return output;
|
|
220
|
-
}
|
|
221
|
-
function resolveLinkOrFile(pkgVer, opts) {
|
|
222
|
-
const { lockfileDir, projectRootDirRealPath } = opts;
|
|
223
|
-
function resolveScheme(scheme, base) {
|
|
224
|
-
if (!pkgVer.startsWith(scheme))
|
|
225
|
-
return undefined;
|
|
226
|
-
const { id, peerDepGraphHash: suffix } = dp.parseDepPath(pkgVer.slice(scheme.length));
|
|
227
|
-
const resolvedPath = path.resolve(base, id);
|
|
228
|
-
return { scheme, resolvedPath, suffix };
|
|
229
|
-
}
|
|
230
|
-
const resolveSchemeResult = resolveScheme('file:', lockfileDir) ?? resolveScheme('link:', projectRootDirRealPath);
|
|
231
|
-
if (resolveSchemeResult)
|
|
232
|
-
return resolveSchemeResult;
|
|
233
|
-
const { name, nonSemverVersion, patchHash, peerDepGraphHash, version } = dp.parse(pkgVer);
|
|
234
|
-
if (!nonSemverVersion)
|
|
235
|
-
return undefined;
|
|
236
|
-
if (version) {
|
|
237
|
-
throw new Error(`Something goes wrong, version should be undefined but isn't: ${version}`);
|
|
238
|
-
}
|
|
239
|
-
const parseResult = resolveLinkOrFile(nonSemverVersion, opts);
|
|
240
|
-
if (!parseResult)
|
|
241
|
-
return undefined;
|
|
242
|
-
if (parseResult.suffix) {
|
|
243
|
-
throw new Error(`Something goes wrong, suffix should be undefined but isn't: ${parseResult.suffix}`);
|
|
244
|
-
}
|
|
245
|
-
parseResult.suffix = `${patchHash ?? ''}${peerDepGraphHash ?? ''}`;
|
|
246
|
-
parseResult.packageName = name;
|
|
247
|
-
return parseResult;
|
|
248
|
-
}
|
|
249
|
-
function createFileUrlDepPath({ resolvedPath, suffix, packageName }, allProjects) {
|
|
250
|
-
const depFileUrl = url.pathToFileURL(resolvedPath).toString();
|
|
251
|
-
const project = allProjects.find(project => project.rootDirRealPath === resolvedPath);
|
|
252
|
-
const name = project?.manifest.name ?? packageName ?? path.basename(resolvedPath);
|
|
253
|
-
return `${name}@${depFileUrl}${suffix ?? ''}`;
|
|
254
|
-
}
|
|
255
|
-
//# sourceMappingURL=createDeployFiles.js.map
|
package/lib/deploy/deploy.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { type Config } from '@pnpm/config.reader';
|
|
2
|
-
import { install } from '@pnpm/installing.commands';
|
|
3
|
-
export declare const shorthands: {
|
|
4
|
-
legacy: string[];
|
|
5
|
-
};
|
|
6
|
-
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
7
|
-
export declare function cliOptionsTypes(): Record<string, unknown>;
|
|
8
|
-
export declare const commandNames: string[];
|
|
9
|
-
export declare const overridableByScript = true;
|
|
10
|
-
export declare function help(): string;
|
|
11
|
-
export type DeployOptions = Omit<install.InstallCommandOptions, 'useLockfile'> & Pick<Config, 'allowBuilds' | 'forceLegacyDeploy'>;
|
|
12
|
-
export declare function handler(opts: DeployOptions, params: string[]): Promise<void>;
|
package/lib/deploy/deploy.js
DELETED
|
@@ -1,398 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { FILTERING } from '@pnpm/cli.common-cli-options-help';
|
|
4
|
-
import { docsUrl } from '@pnpm/cli.utils';
|
|
5
|
-
import { types as configTypes } from '@pnpm/config.reader';
|
|
6
|
-
import { WORKSPACE_MANIFEST_FILENAME } from '@pnpm/constants';
|
|
7
|
-
import { PnpmError } from '@pnpm/error';
|
|
8
|
-
import { fetchFromDir } from '@pnpm/fetching.directory-fetcher';
|
|
9
|
-
import { createIndexedPkgImporter } from '@pnpm/fs.indexed-pkg-importer';
|
|
10
|
-
import { isEmptyDirOrNothing } from '@pnpm/fs.is-empty-dir-or-nothing';
|
|
11
|
-
import { install } from '@pnpm/installing.commands';
|
|
12
|
-
import { getLockfileImporterId, readWantedLockfile, writeWantedLockfile } from '@pnpm/lockfile.fs';
|
|
13
|
-
import { globalWarn, logger } from '@pnpm/logger';
|
|
14
|
-
import { rimraf } from '@zkochan/rimraf';
|
|
15
|
-
import { isSubdir } from 'is-subdir';
|
|
16
|
-
import { pick } from 'ramda';
|
|
17
|
-
import { renderHelp } from 'render-help';
|
|
18
|
-
import { writeYamlFile } from 'write-yaml-file';
|
|
19
|
-
import { createDeployFiles } from './createDeployFiles.js';
|
|
20
|
-
import { deployHook } from './deployHook.js';
|
|
21
|
-
const FORCE_LEGACY_DEPLOY = 'force-legacy-deploy';
|
|
22
|
-
export const shorthands = {
|
|
23
|
-
...install.shorthands,
|
|
24
|
-
legacy: [`--config.${FORCE_LEGACY_DEPLOY}=true`],
|
|
25
|
-
};
|
|
26
|
-
const DEPLOY_OWN_OPTIONS = pick([FORCE_LEGACY_DEPLOY], configTypes);
|
|
27
|
-
export function rcOptionsTypes() {
|
|
28
|
-
return {
|
|
29
|
-
...install.rcOptionsTypes(),
|
|
30
|
-
...DEPLOY_OWN_OPTIONS,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
export function cliOptionsTypes() {
|
|
34
|
-
return {
|
|
35
|
-
...install.cliOptionsTypes(),
|
|
36
|
-
...DEPLOY_OWN_OPTIONS,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
export const commandNames = ['deploy'];
|
|
40
|
-
export const overridableByScript = true;
|
|
41
|
-
export function help() {
|
|
42
|
-
return renderHelp({
|
|
43
|
-
description: 'Experimental! Deploy a package from a workspace',
|
|
44
|
-
url: docsUrl('deploy'),
|
|
45
|
-
usages: ['pnpm --filter=<deployed project name> deploy <target directory>'],
|
|
46
|
-
descriptionLists: [
|
|
47
|
-
{
|
|
48
|
-
title: 'Options',
|
|
49
|
-
list: [
|
|
50
|
-
{
|
|
51
|
-
description: "Packages in `devDependencies` won't be installed",
|
|
52
|
-
name: '--prod',
|
|
53
|
-
shortAlias: '-P',
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
description: 'Only `devDependencies` are installed',
|
|
57
|
-
name: '--dev',
|
|
58
|
-
shortAlias: '-D',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
description: '`optionalDependencies` are not installed',
|
|
62
|
-
name: '--no-optional',
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
description: 'Force legacy deploy implementation',
|
|
66
|
-
name: '--legacy',
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
},
|
|
70
|
-
FILTERING,
|
|
71
|
-
],
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
export async function handler(opts, params) {
|
|
75
|
-
if (!opts.workspaceDir) {
|
|
76
|
-
let hint;
|
|
77
|
-
if (opts.rootProjectManifest?.scripts?.['deploy'] != null) {
|
|
78
|
-
hint = 'Maybe you wanted to invoke "pnpm run deploy"';
|
|
79
|
-
}
|
|
80
|
-
throw new PnpmError('CANNOT_DEPLOY', 'A deploy is only possible from inside a workspace', { hint });
|
|
81
|
-
}
|
|
82
|
-
const selectedProjects = Object.values(opts.selectedProjectsGraph ?? {});
|
|
83
|
-
if (selectedProjects.length === 0) {
|
|
84
|
-
throw new PnpmError('NOTHING_TO_DEPLOY', 'No project was selected for deployment');
|
|
85
|
-
}
|
|
86
|
-
if (selectedProjects.length > 1) {
|
|
87
|
-
throw new PnpmError('CANNOT_DEPLOY_MANY', 'Cannot deploy more than 1 project');
|
|
88
|
-
}
|
|
89
|
-
if (params.length !== 1) {
|
|
90
|
-
throw new PnpmError('INVALID_DEPLOY_TARGET', 'This command requires one parameter');
|
|
91
|
-
}
|
|
92
|
-
const selectedProject = selectedProjects[0].package;
|
|
93
|
-
const deployDirParam = params[0];
|
|
94
|
-
const deployDir = path.isAbsolute(deployDirParam) ? deployDirParam : path.join(opts.dir, deployDirParam);
|
|
95
|
-
validateDeployTarget(deployDir, {
|
|
96
|
-
dir: opts.dir,
|
|
97
|
-
force: opts.force,
|
|
98
|
-
projectDir: selectedProject.rootDir,
|
|
99
|
-
workspaceDir: opts.workspaceDir,
|
|
100
|
-
});
|
|
101
|
-
const normalizedDeployDir = path.resolve(deployDir);
|
|
102
|
-
const normalizedWorkspaceDir = path.resolve(opts.workspaceDir);
|
|
103
|
-
const workspaceChildTarget = isChildPath(normalizedDeployDir, normalizedWorkspaceDir);
|
|
104
|
-
if (workspaceChildTarget) {
|
|
105
|
-
createWorkspaceChildTargetParents(normalizedWorkspaceDir, normalizedDeployDir);
|
|
106
|
-
}
|
|
107
|
-
if (!isEmptyDirOrNothing(deployDir)) {
|
|
108
|
-
if (!opts.force) {
|
|
109
|
-
throw new PnpmError('DEPLOY_DIR_NOT_EMPTY', `Deploy path ${deployDir} is not empty`);
|
|
110
|
-
}
|
|
111
|
-
logger.warn({ message: 'using --force, deleting deploy path', prefix: deployDir });
|
|
112
|
-
}
|
|
113
|
-
if (workspaceChildTarget) {
|
|
114
|
-
validateWorkspaceChildTargetComponents(normalizedWorkspaceDir, normalizedDeployDir);
|
|
115
|
-
}
|
|
116
|
-
await rimraf(deployDir);
|
|
117
|
-
if (workspaceChildTarget) {
|
|
118
|
-
createWorkspaceChildTargetParents(normalizedWorkspaceDir, normalizedDeployDir);
|
|
119
|
-
createWorkspaceChildTargetDir(normalizedWorkspaceDir, normalizedDeployDir);
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
await fs.promises.mkdir(deployDir, { recursive: true });
|
|
123
|
-
}
|
|
124
|
-
const includeOnlyPackageFiles = !opts.deployAllFiles;
|
|
125
|
-
await copyProject(selectedProject.rootDir, deployDir, { includeOnlyPackageFiles });
|
|
126
|
-
if (opts.sharedWorkspaceLockfile) {
|
|
127
|
-
const warning = opts.forceLegacyDeploy
|
|
128
|
-
? 'Shared workspace lockfile detected but configuration forces legacy deploy implementation.'
|
|
129
|
-
: await deployFromSharedLockfile(opts, selectedProject, deployDir);
|
|
130
|
-
if (warning) {
|
|
131
|
-
globalWarn(warning);
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
const deployedProject = opts.allProjects?.find(({ rootDir }) => rootDir === selectedProject.rootDir);
|
|
138
|
-
if (deployedProject) {
|
|
139
|
-
deployedProject.modulesDir = path.relative(selectedProject.rootDir, path.join(deployDir, 'node_modules'));
|
|
140
|
-
}
|
|
141
|
-
await install.handler({
|
|
142
|
-
...opts,
|
|
143
|
-
confirmModulesPurge: false,
|
|
144
|
-
// Deploy doesn't work with dedupePeerDependents=true currently as for deploy
|
|
145
|
-
// we need to select a single project for install, while dedupePeerDependents
|
|
146
|
-
// doesn't work with filters right now.
|
|
147
|
-
// Related issue: https://github.com/pnpm/pnpm/issues/6858
|
|
148
|
-
dedupePeerDependents: false,
|
|
149
|
-
// If enabled, dedupe-injected-deps will symlink workspace packages in the
|
|
150
|
-
// deployed dir to their original (non-deployed) directory in an attempt to
|
|
151
|
-
// dedupe workspace packages that don't need to be injected. The deployed
|
|
152
|
-
// dir shouldn't have symlinks to the original workspace. Disable
|
|
153
|
-
// dedupe-injected-deps to always inject workspace packages since copying is
|
|
154
|
-
// desirable.
|
|
155
|
-
dedupeInjectedDeps: false,
|
|
156
|
-
// Compute the wanted lockfile correctly by setting pruneLockfileImporters.
|
|
157
|
-
// Since pnpm deploy only installs dependencies for a single selected
|
|
158
|
-
// project, other projects in the "importers" lockfile section will be
|
|
159
|
-
// empty when node-linker=hoisted.
|
|
160
|
-
//
|
|
161
|
-
// For example, when deploying project-1, project-2 may not be populated,
|
|
162
|
-
// even if it has dependencies.
|
|
163
|
-
//
|
|
164
|
-
// importers:
|
|
165
|
-
// project-1:
|
|
166
|
-
// dependencies:
|
|
167
|
-
// foo:
|
|
168
|
-
// specifier: ^1.0.0
|
|
169
|
-
// version: ^1.0.0
|
|
170
|
-
// project-2: {}
|
|
171
|
-
//
|
|
172
|
-
// Avoid including these empty importers in the in-memory wanted lockfile.
|
|
173
|
-
// This is important when node-linker=hoisted to prevent project-2 from
|
|
174
|
-
// being included in the hoisted install. If project-2 is errantly hoisted
|
|
175
|
-
// to the root node_modules dir, downstream logic will fail to inject it to
|
|
176
|
-
// the deploy directory. It's also just weird to include empty importers
|
|
177
|
-
// that don't matter to the filtered lockfile generated for pnpm deploy.
|
|
178
|
-
pruneLockfileImporters: true,
|
|
179
|
-
// The node_modules for a pnpm deploy should be self-contained. The global
|
|
180
|
-
// virtual store would create symlinks outside of the deploy directory.
|
|
181
|
-
enableGlobalVirtualStore: false,
|
|
182
|
-
depth: Infinity,
|
|
183
|
-
hooks: {
|
|
184
|
-
...opts.hooks,
|
|
185
|
-
readPackage: [
|
|
186
|
-
...(opts.hooks?.readPackage ?? []),
|
|
187
|
-
deployHook,
|
|
188
|
-
],
|
|
189
|
-
},
|
|
190
|
-
frozenLockfile: false,
|
|
191
|
-
preferFrozenLockfile: false,
|
|
192
|
-
// Deploy doesn't work currently with hoisted node_modules.
|
|
193
|
-
// TODO: make it work as we need to prefer packages from the lockfile during deployment.
|
|
194
|
-
useLockfile: opts.nodeLinker !== 'hoisted',
|
|
195
|
-
saveLockfile: false,
|
|
196
|
-
virtualStoreDir: path.join(deployDir, 'node_modules/.pnpm'),
|
|
197
|
-
modulesDir: path.relative(opts.workspaceDir, path.join(deployDir, 'node_modules')),
|
|
198
|
-
includeOnlyPackageFiles,
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
async function copyProject(src, dest, opts) {
|
|
202
|
-
const { filesMap } = await fetchFromDir(src, opts);
|
|
203
|
-
const importPkg = createIndexedPkgImporter('clone-or-copy');
|
|
204
|
-
importPkg(dest, { filesMap, force: true, resolvedFrom: 'local-dir' });
|
|
205
|
-
}
|
|
206
|
-
function validateDeployTarget(deployDir, opts) {
|
|
207
|
-
const normalizedDeployDir = path.resolve(deployDir);
|
|
208
|
-
const workspaceDir = path.resolve(opts.workspaceDir);
|
|
209
|
-
const projectDir = path.resolve(opts.projectDir);
|
|
210
|
-
const dir = path.resolve(opts.dir);
|
|
211
|
-
if (samePath(normalizedDeployDir, workspaceDir)) {
|
|
212
|
-
throw unsafeDeployTarget(normalizedDeployDir, 'target is the workspace root');
|
|
213
|
-
}
|
|
214
|
-
if (isAncestorPath(normalizedDeployDir, workspaceDir)) {
|
|
215
|
-
throw unsafeDeployTarget(normalizedDeployDir, 'target contains the workspace root');
|
|
216
|
-
}
|
|
217
|
-
if (samePath(normalizedDeployDir, projectDir)) {
|
|
218
|
-
throw unsafeDeployTarget(normalizedDeployDir, 'target is the selected project root');
|
|
219
|
-
}
|
|
220
|
-
if (isAncestorPath(normalizedDeployDir, projectDir)) {
|
|
221
|
-
throw unsafeDeployTarget(normalizedDeployDir, 'target contains the selected project');
|
|
222
|
-
}
|
|
223
|
-
if (samePath(normalizedDeployDir, dir)) {
|
|
224
|
-
throw unsafeDeployTarget(normalizedDeployDir, 'target is the current directory');
|
|
225
|
-
}
|
|
226
|
-
if (isAncestorPath(normalizedDeployDir, dir)) {
|
|
227
|
-
throw unsafeDeployTarget(normalizedDeployDir, 'target contains the current directory');
|
|
228
|
-
}
|
|
229
|
-
if (opts.force && !isChildPath(normalizedDeployDir, workspaceDir)) {
|
|
230
|
-
throw unsafeDeployTarget(normalizedDeployDir, 'target is outside the workspace');
|
|
231
|
-
}
|
|
232
|
-
if (isChildPath(normalizedDeployDir, workspaceDir)) {
|
|
233
|
-
validateWorkspaceChildTargetComponents(workspaceDir, normalizedDeployDir);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
function validateWorkspaceChildTargetComponents(workspaceDir, deployDir) {
|
|
237
|
-
const relative = path.relative(workspaceDir, deployDir);
|
|
238
|
-
let current = workspaceDir;
|
|
239
|
-
for (const component of relative.split(path.sep)) {
|
|
240
|
-
if (!component)
|
|
241
|
-
continue;
|
|
242
|
-
current = path.join(current, component);
|
|
243
|
-
let stat;
|
|
244
|
-
try {
|
|
245
|
-
stat = fs.lstatSync(current);
|
|
246
|
-
}
|
|
247
|
-
catch (error) {
|
|
248
|
-
if (isENOENT(error))
|
|
249
|
-
return;
|
|
250
|
-
throw error;
|
|
251
|
-
}
|
|
252
|
-
if (stat.isSymbolicLink()) {
|
|
253
|
-
throw unsafeDeployTarget(current, 'target path contains a symlink');
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
function createWorkspaceChildTargetParents(workspaceDir, deployDir) {
|
|
258
|
-
const parent = path.dirname(deployDir);
|
|
259
|
-
const relative = path.relative(workspaceDir, parent);
|
|
260
|
-
let current = workspaceDir;
|
|
261
|
-
for (const component of relative.split(path.sep)) {
|
|
262
|
-
if (!component)
|
|
263
|
-
continue;
|
|
264
|
-
current = path.join(current, component);
|
|
265
|
-
createWorkspaceChildTargetComponent(current);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
function createWorkspaceChildTargetDir(workspaceDir, deployDir) {
|
|
269
|
-
try {
|
|
270
|
-
fs.mkdirSync(deployDir);
|
|
271
|
-
}
|
|
272
|
-
catch (error) {
|
|
273
|
-
if (isEEXIST(error)) {
|
|
274
|
-
throw unsafeDeployTarget(deployDir, 'target changed during deploy preparation');
|
|
275
|
-
}
|
|
276
|
-
throw error;
|
|
277
|
-
}
|
|
278
|
-
validateWorkspaceChildTargetComponents(workspaceDir, deployDir);
|
|
279
|
-
}
|
|
280
|
-
function createWorkspaceChildTargetComponent(component) {
|
|
281
|
-
try {
|
|
282
|
-
fs.mkdirSync(component);
|
|
283
|
-
}
|
|
284
|
-
catch (error) {
|
|
285
|
-
if (!isEEXIST(error))
|
|
286
|
-
throw error;
|
|
287
|
-
}
|
|
288
|
-
const stat = fs.lstatSync(component);
|
|
289
|
-
if (stat.isSymbolicLink()) {
|
|
290
|
-
throw unsafeDeployTarget(component, 'target path contains a symlink');
|
|
291
|
-
}
|
|
292
|
-
if (!stat.isDirectory()) {
|
|
293
|
-
throw unsafeDeployTarget(component, 'target path contains a non-directory');
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
function unsafeDeployTarget(deployDir, reason) {
|
|
297
|
-
return new PnpmError('INVALID_DEPLOY_TARGET', `Refusing to deploy to unsafe target ${deployDir}: ${reason}`);
|
|
298
|
-
}
|
|
299
|
-
function samePath(left, right) {
|
|
300
|
-
return path.normalize(left) === path.normalize(right);
|
|
301
|
-
}
|
|
302
|
-
function isAncestorPath(parent, child) {
|
|
303
|
-
return isChildPath(child, parent);
|
|
304
|
-
}
|
|
305
|
-
function isChildPath(child, parent) {
|
|
306
|
-
return !samePath(child, parent) && isSubdir(parent, child);
|
|
307
|
-
}
|
|
308
|
-
function isENOENT(error) {
|
|
309
|
-
return typeof error === 'object' && error != null && 'code' in error && error.code === 'ENOENT';
|
|
310
|
-
}
|
|
311
|
-
function isEEXIST(error) {
|
|
312
|
-
return typeof error === 'object' && error != null && 'code' in error && error.code === 'EEXIST';
|
|
313
|
-
}
|
|
314
|
-
async function deployFromSharedLockfile(opts, selectedProject, deployDir) {
|
|
315
|
-
if (!opts.injectWorkspacePackages) {
|
|
316
|
-
throw new PnpmError('DEPLOY_NONINJECTED_WORKSPACE', 'By default, starting from pnpm v10, we only deploy from workspaces that have "inject-workspace-packages=true" set', {
|
|
317
|
-
hint: 'If you want to deploy without using injected dependencies, run "pnpm deploy" with the "--legacy" flag or set "force-legacy-deploy" to true',
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
const { allProjects, lockfileDir, rootProjectManifestDir, workspaceDir, } = opts;
|
|
321
|
-
// The following errors should not be possible. It is a programmer error if they are reached.
|
|
322
|
-
if (!allProjects)
|
|
323
|
-
throw new Error('opts.allProjects is undefined.');
|
|
324
|
-
if (!lockfileDir)
|
|
325
|
-
throw new Error('opts.lockfileDir is undefined.');
|
|
326
|
-
if (!workspaceDir)
|
|
327
|
-
throw new Error('opts.workspaceDir is undefined.');
|
|
328
|
-
const lockfile = await readWantedLockfile(lockfileDir, { ignoreIncompatible: false });
|
|
329
|
-
if (!lockfile) {
|
|
330
|
-
return 'Shared lockfile not found. Falling back to installing without a lockfile.';
|
|
331
|
-
}
|
|
332
|
-
const projectId = getLockfileImporterId(lockfileDir, selectedProject.rootDir);
|
|
333
|
-
const deployFiles = createDeployFiles({
|
|
334
|
-
allProjects,
|
|
335
|
-
deployDir,
|
|
336
|
-
include: {
|
|
337
|
-
dependencies: opts.production !== false,
|
|
338
|
-
devDependencies: opts.dev !== false,
|
|
339
|
-
optionalDependencies: opts.optional !== false,
|
|
340
|
-
},
|
|
341
|
-
lockfile,
|
|
342
|
-
lockfileDir,
|
|
343
|
-
patchedDependencies: opts.patchedDependencies,
|
|
344
|
-
selectedProjectManifest: selectedProject.manifest,
|
|
345
|
-
projectId,
|
|
346
|
-
rootProjectManifestDir,
|
|
347
|
-
allowBuilds: opts.allowBuilds,
|
|
348
|
-
});
|
|
349
|
-
const filesToWrite = [
|
|
350
|
-
fs.promises.writeFile(path.join(deployDir, 'package.json'), JSON.stringify(deployFiles.manifest, undefined, 2) + '\n'),
|
|
351
|
-
writeWantedLockfile(deployDir, deployFiles.lockfile),
|
|
352
|
-
];
|
|
353
|
-
if (deployFiles.workspaceManifest) {
|
|
354
|
-
filesToWrite.push(writeYamlFile(path.join(deployDir, WORKSPACE_MANIFEST_FILENAME), deployFiles.workspaceManifest));
|
|
355
|
-
}
|
|
356
|
-
await Promise.all(filesToWrite);
|
|
357
|
-
try {
|
|
358
|
-
await install.handler({
|
|
359
|
-
...opts,
|
|
360
|
-
allProjects: undefined,
|
|
361
|
-
allProjectsGraph: undefined,
|
|
362
|
-
selectedProjectsGraph: undefined,
|
|
363
|
-
rootProjectManifest: deployFiles.manifest,
|
|
364
|
-
// The node_modules for a pnpm deploy should be self-contained. The global
|
|
365
|
-
// virtual store would create symlinks outside of the deploy directory.
|
|
366
|
-
enableGlobalVirtualStore: false,
|
|
367
|
-
rootProjectManifestDir: deployDir,
|
|
368
|
-
dir: deployDir,
|
|
369
|
-
lockfileDir: deployDir,
|
|
370
|
-
workspaceDir: undefined,
|
|
371
|
-
virtualStoreDir: undefined,
|
|
372
|
-
modulesDir: undefined,
|
|
373
|
-
confirmModulesPurge: false,
|
|
374
|
-
frozenLockfile: true,
|
|
375
|
-
injectWorkspacePackages: undefined, // the effects of injecting workspace packages should already be part of the package snapshots
|
|
376
|
-
overrides: undefined, // the effects of the overrides should already be part of the package snapshots
|
|
377
|
-
packageExtensions: undefined, // the effects of the package extensions should already be part of the package snapshots
|
|
378
|
-
configDependencies: undefined, // configDependencies (e.g. pacquet) are not installed into the deploy dir, so the install engine they designate isn't on disk to invoke
|
|
379
|
-
hooks: {
|
|
380
|
-
...opts.hooks,
|
|
381
|
-
readPackage: [
|
|
382
|
-
...(opts.hooks?.readPackage ?? []),
|
|
383
|
-
deployHook,
|
|
384
|
-
],
|
|
385
|
-
calculatePnpmfileChecksum: undefined, // the effects of the pnpmfile should already be part of the package snapshots
|
|
386
|
-
},
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
catch (error) {
|
|
390
|
-
globalWarn(`Deployment with a shared lockfile has failed. If this is a bug, please report it at <https://github.com/pnpm/pnpm/issues>.
|
|
391
|
-
As a workaround, add the following to pnpm-workspace.yaml:
|
|
392
|
-
|
|
393
|
-
forceLegacyDeploy: true`);
|
|
394
|
-
throw error;
|
|
395
|
-
}
|
|
396
|
-
return undefined;
|
|
397
|
-
}
|
|
398
|
-
//# sourceMappingURL=deploy.js.map
|
package/lib/deploy/deployHook.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { DEPENDENCIES_FIELDS } from '@pnpm/types';
|
|
2
|
-
export function deployHook(pkg) {
|
|
3
|
-
pkg.dependenciesMeta = pkg.dependenciesMeta ?? {};
|
|
4
|
-
for (const depField of DEPENDENCIES_FIELDS) {
|
|
5
|
-
for (const [depName, depVersion] of Object.entries(pkg[depField] ?? {})) {
|
|
6
|
-
if (depVersion.startsWith('workspace:')) {
|
|
7
|
-
pkg.dependenciesMeta[depName] = {
|
|
8
|
-
injected: true,
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
return pkg;
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=deployHook.js.map
|