@pnpm/releasing.commands 1000.0.0 → 1100.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/deploy/deploy.d.ts +1 -0
- package/lib/deploy/deploy.js +1 -9
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/publish/executeTokenHelper.js +4 -1
- package/lib/publish/oidc/authToken.js +2 -2
- package/lib/publish/oidc/provenance.js +2 -2
- package/lib/publish/otp.d.ts +3 -64
- package/lib/publish/otp.js +21 -153
- package/lib/publish/pack.d.ts +2 -2
- package/lib/publish/pack.js +1 -1
- package/lib/publish/publish.d.ts +3 -3
- package/lib/publish/publish.js +1 -1
- package/lib/publish/publishPackedPkg.d.ts +1 -5
- package/lib/publish/publishPackedPkg.js +27 -40
- package/lib/publish/recursivePublish.d.ts +3 -3
- package/lib/publish/recursivePublish.js +1 -2
- package/lib/publish/utils/shared-context.js +6 -1
- package/lib/version/index.d.ts +28 -0
- package/lib/version/index.js +163 -0
- package/package.json +48 -45
package/lib/deploy/deploy.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare const shorthands: {
|
|
|
6
6
|
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
7
7
|
export declare function cliOptionsTypes(): Record<string, unknown>;
|
|
8
8
|
export declare const commandNames: string[];
|
|
9
|
+
export declare const overridableByScript = true;
|
|
9
10
|
export declare function help(): string;
|
|
10
11
|
export type DeployOptions = Omit<install.InstallCommandOptions, 'useLockfile'> & Pick<Config, 'allowBuilds' | 'forceLegacyDeploy'>;
|
|
11
12
|
export declare function handler(opts: DeployOptions, params: string[]): Promise<void>;
|
package/lib/deploy/deploy.js
CHANGED
|
@@ -36,6 +36,7 @@ export function cliOptionsTypes() {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
export const commandNames = ['deploy'];
|
|
39
|
+
export const overridableByScript = true;
|
|
39
40
|
export function help() {
|
|
40
41
|
return renderHelp({
|
|
41
42
|
description: 'Experimental! Deploy a package from a workspace',
|
|
@@ -172,11 +173,6 @@ export async function handler(opts, params) {
|
|
|
172
173
|
saveLockfile: false,
|
|
173
174
|
virtualStoreDir: path.join(deployDir, 'node_modules/.pnpm'),
|
|
174
175
|
modulesDir: path.relative(opts.workspaceDir, path.join(deployDir, 'node_modules')),
|
|
175
|
-
rawLocalConfig: {
|
|
176
|
-
...opts.rawLocalConfig,
|
|
177
|
-
// This is a workaround to prevent frozen install in CI envs.
|
|
178
|
-
'frozen-lockfile': false,
|
|
179
|
-
},
|
|
180
176
|
includeOnlyPackageFiles,
|
|
181
177
|
});
|
|
182
178
|
}
|
|
@@ -252,10 +248,6 @@ async function deployFromSharedLockfile(opts, selectedProject, deployDir) {
|
|
|
252
248
|
],
|
|
253
249
|
calculatePnpmfileChecksum: undefined, // the effects of the pnpmfile should already be part of the package snapshots
|
|
254
250
|
},
|
|
255
|
-
rawLocalConfig: {
|
|
256
|
-
...opts.rawLocalConfig,
|
|
257
|
-
'frozen-lockfile': true,
|
|
258
|
-
},
|
|
259
251
|
});
|
|
260
252
|
}
|
|
261
253
|
catch (error) {
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -9,6 +9,9 @@ export function executeTokenHelper([cmd, ...args], opts) {
|
|
|
9
9
|
opts.globalWarn(`(tokenHelper stderr) ${line}`);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
const token = (execResult.stdout?.toString() ?? '').trim();
|
|
13
|
+
// If the token helper output includes an auth scheme prefix (e.g. "Bearer ..."),
|
|
14
|
+
// strip it since libnpmpublish adds the scheme itself.
|
|
15
|
+
return token.replace(/^Bearer\s+/i, '');
|
|
13
16
|
}
|
|
14
17
|
//# sourceMappingURL=executeTokenHelper.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PnpmError } from '@pnpm/error';
|
|
2
|
+
import npa from '@pnpm/npm-package-arg';
|
|
2
3
|
import { displayError } from '../displayError.js';
|
|
3
4
|
import { SHARED_CONTEXT } from '../utils/shared-context.js';
|
|
4
5
|
/**
|
|
@@ -12,10 +13,9 @@ import { SHARED_CONTEXT } from '../utils/shared-context.js';
|
|
|
12
13
|
* @see https://github.com/yarnpkg/berry/blob/bafbef55/packages/plugin-npm/sources/npmHttpUtils.ts#L626-L641 for yarn's implementation.
|
|
13
14
|
*/
|
|
14
15
|
export async function fetchAuthToken({ context: { fetch, } = SHARED_CONTEXT, options, idToken, packageName, registry, }) {
|
|
15
|
-
const escapedPackageName = encodeURIComponent(packageName);
|
|
16
16
|
let response;
|
|
17
17
|
try {
|
|
18
|
-
response = await fetch(new URL(`/-/npm/v1/oidc/token/exchange/package/${
|
|
18
|
+
response = await fetch(new URL(`/-/npm/v1/oidc/token/exchange/package/${npa(packageName).escapedName}`, registry).href, {
|
|
19
19
|
body: '',
|
|
20
20
|
headers: {
|
|
21
21
|
Accept: 'application/json',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PnpmError } from '@pnpm/error';
|
|
2
|
+
import npa from '@pnpm/npm-package-arg';
|
|
2
3
|
import { SHARED_CONTEXT } from '../utils/shared-context.js';
|
|
3
4
|
/**
|
|
4
5
|
* Determine `provenance` for a package from the CI context and the visibility of the package.
|
|
@@ -18,8 +19,7 @@ export async function determineProvenance({ authToken, idToken, options, package
|
|
|
18
19
|
(!GITLAB || payload.project_visibility !== 'public' || !env?.SIGSTORE_ID_TOKEN)) {
|
|
19
20
|
throw new ProvenanceInsufficientInformationError();
|
|
20
21
|
}
|
|
21
|
-
const
|
|
22
|
-
const visibilityUrl = new URL(`/-/package/${escapedPackageName}/visibility`, registry);
|
|
22
|
+
const visibilityUrl = new URL(`/-/package/${npa(packageName).escapedName}/visibility`, registry);
|
|
23
23
|
const response = await fetch(visibilityUrl, {
|
|
24
24
|
headers: {
|
|
25
25
|
Accept: 'application/json',
|
package/lib/publish/otp.d.ts
CHANGED
|
@@ -1,57 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type OtpContext as BaseOtpContext } from '@pnpm/network.web-auth';
|
|
2
2
|
import type { ExportedManifest } from '@pnpm/releasing.exportable-manifest';
|
|
3
3
|
import type { PublishOptions } from 'libnpmpublish';
|
|
4
|
-
import { SHARED_CONTEXT } from './utils/shared-context.js';
|
|
5
|
-
export interface OtpWebAuthFetchOptions {
|
|
6
|
-
method: 'GET';
|
|
7
|
-
retry?: {
|
|
8
|
-
factor?: number;
|
|
9
|
-
maxTimeout?: number;
|
|
10
|
-
minTimeout?: number;
|
|
11
|
-
randomize?: boolean;
|
|
12
|
-
retries?: number;
|
|
13
|
-
};
|
|
14
|
-
timeout?: number;
|
|
15
|
-
}
|
|
16
|
-
export interface OtpWebAuthFetchResponseHeaders {
|
|
17
|
-
get: (this: this, name: 'retry-after') => string | null;
|
|
18
|
-
}
|
|
19
|
-
export interface OtpWebAuthFetchResponse {
|
|
20
|
-
readonly headers: OtpWebAuthFetchResponseHeaders;
|
|
21
|
-
readonly json: (this: this) => Promise<unknown>;
|
|
22
|
-
readonly ok: boolean;
|
|
23
|
-
readonly status: number;
|
|
24
|
-
}
|
|
25
4
|
export interface OtpPublishResponse {
|
|
26
5
|
readonly ok: boolean;
|
|
27
6
|
readonly status: number;
|
|
28
7
|
readonly statusText: string;
|
|
29
8
|
readonly text: () => Promise<string>;
|
|
30
9
|
}
|
|
31
|
-
export interface OtpEnquirer {
|
|
32
|
-
prompt: (this: this, options: OtpEnquirerOptions) => Promise<OtpEnquirerResponse | undefined>;
|
|
33
|
-
}
|
|
34
|
-
export interface OtpEnquirerOptions {
|
|
35
|
-
message: string;
|
|
36
|
-
name: 'otp';
|
|
37
|
-
type: 'input';
|
|
38
|
-
}
|
|
39
|
-
export interface OtpEnquirerResponse {
|
|
40
|
-
otp?: string;
|
|
41
|
-
}
|
|
42
10
|
export type OtpPublishFn = (manifest: ExportedManifest, tarballData: Buffer, options: PublishOptions) => Promise<OtpPublishResponse>;
|
|
43
|
-
export interface
|
|
44
|
-
now: () => number;
|
|
45
|
-
}
|
|
46
|
-
export interface OtpContext {
|
|
47
|
-
Date: OtpDate;
|
|
48
|
-
setTimeout: (cb: () => void, ms: number) => void;
|
|
49
|
-
enquirer: OtpEnquirer;
|
|
50
|
-
fetch: (url: string, options: OtpWebAuthFetchOptions) => Promise<OtpWebAuthFetchResponse>;
|
|
51
|
-
globalInfo: (message: string) => void;
|
|
52
|
-
process: Record<'stdin' | 'stdout', {
|
|
53
|
-
isTTY?: boolean;
|
|
54
|
-
}>;
|
|
11
|
+
export interface OtpContext extends BaseOtpContext {
|
|
55
12
|
publish: OtpPublishFn;
|
|
56
13
|
}
|
|
57
14
|
export interface OtpParams {
|
|
@@ -60,30 +17,12 @@ export interface OtpParams {
|
|
|
60
17
|
publishOptions: PublishOptions;
|
|
61
18
|
tarballData: Buffer;
|
|
62
19
|
}
|
|
63
|
-
export { SHARED_CONTEXT };
|
|
64
20
|
/**
|
|
65
21
|
* Publish a package, handling OTP challenges:
|
|
66
22
|
* - Web based authentication flow (authUrl/doneUrl in error body with doneUrl polling)
|
|
67
23
|
* - Classic OTP prompt (manual code entry)
|
|
68
24
|
*
|
|
69
|
-
* @throws {@link OtpWebAuthTimeoutError} if the webauth browser flow times out.
|
|
70
|
-
* @throws {@link OtpNonInteractiveError} if OTP is required but the terminal is not interactive.
|
|
71
|
-
* @throws {@link OtpSecondChallengeError} if the registry requests OTP a second time after one was submitted.
|
|
72
|
-
* @throws the original error if OTP handling is not applicable.
|
|
73
|
-
*
|
|
74
25
|
* @see https://github.com/npm/cli/blob/7d900c46/lib/utils/otplease.js for npm's implementation.
|
|
75
26
|
* @see https://github.com/npm/npm-profile/blob/main/lib/index.js for the webauth polling flow.
|
|
76
27
|
*/
|
|
77
|
-
export declare function publishWithOtpHandling({ context
|
|
78
|
-
export declare class OtpWebAuthTimeoutError extends PnpmError {
|
|
79
|
-
readonly endTime: number;
|
|
80
|
-
readonly startTime: number;
|
|
81
|
-
readonly timeout: number;
|
|
82
|
-
constructor(endTime: number, startTime: number, timeout: number);
|
|
83
|
-
}
|
|
84
|
-
export declare class OtpNonInteractiveError extends PnpmError {
|
|
85
|
-
constructor();
|
|
86
|
-
}
|
|
87
|
-
export declare class OtpSecondChallengeError extends PnpmError {
|
|
88
|
-
constructor();
|
|
89
|
-
}
|
|
28
|
+
export declare function publishWithOtpHandling({ context, manifest, publishOptions, tarballData }: OtpParams): Promise<OtpPublishResponse>;
|
package/lib/publish/otp.js
CHANGED
|
@@ -1,165 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import qrcodeTerminal from 'qrcode-terminal';
|
|
1
|
+
import { withOtpHandling, } from '@pnpm/network.web-auth';
|
|
3
2
|
import { SHARED_CONTEXT } from './utils/shared-context.js';
|
|
4
|
-
export { SHARED_CONTEXT };
|
|
5
|
-
const isOtpError = (error) => error != null &&
|
|
6
|
-
typeof error === 'object' &&
|
|
7
|
-
'code' in error &&
|
|
8
|
-
error.code === 'EOTP';
|
|
9
3
|
/**
|
|
10
4
|
* Publish a package, handling OTP challenges:
|
|
11
5
|
* - Web based authentication flow (authUrl/doneUrl in error body with doneUrl polling)
|
|
12
6
|
* - Classic OTP prompt (manual code entry)
|
|
13
7
|
*
|
|
14
|
-
* @throws {@link OtpWebAuthTimeoutError} if the webauth browser flow times out.
|
|
15
|
-
* @throws {@link OtpNonInteractiveError} if OTP is required but the terminal is not interactive.
|
|
16
|
-
* @throws {@link OtpSecondChallengeError} if the registry requests OTP a second time after one was submitted.
|
|
17
|
-
* @throws the original error if OTP handling is not applicable.
|
|
18
|
-
*
|
|
19
8
|
* @see https://github.com/npm/cli/blob/7d900c46/lib/utils/otplease.js for npm's implementation.
|
|
20
9
|
* @see https://github.com/npm/npm-profile/blob/main/lib/index.js for the webauth polling flow.
|
|
21
10
|
*/
|
|
22
|
-
export async function publishWithOtpHandling({ context
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
};
|
|
43
|
-
let otp;
|
|
44
|
-
if (error.body?.authUrl && error.body?.doneUrl) {
|
|
45
|
-
otp = await webAuthOtp(error.body.authUrl, error.body.doneUrl, { Date, setTimeout, fetch, globalInfo }, fetchOptions);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
const enquirerResponse = await enquirer.prompt({
|
|
49
|
-
message: 'This operation requires a one-time password.\nEnter OTP:',
|
|
50
|
-
name: 'otp',
|
|
51
|
-
type: 'input',
|
|
52
|
-
});
|
|
53
|
-
// Use || (not ??) so that empty-string input is treated as "no OTP provided"
|
|
54
|
-
otp = enquirerResponse?.otp || undefined;
|
|
55
|
-
}
|
|
56
|
-
if (otp != null) {
|
|
57
|
-
try {
|
|
58
|
-
return await publish(manifest, tarballData, { ...publishOptions, otp });
|
|
59
|
-
}
|
|
60
|
-
catch (retryError) {
|
|
61
|
-
if (isOtpError(retryError)) {
|
|
62
|
-
throw new OtpSecondChallengeError();
|
|
63
|
-
}
|
|
64
|
-
throw retryError;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
throw error;
|
|
68
|
-
}
|
|
69
|
-
return response;
|
|
70
|
-
}
|
|
71
|
-
async function webAuthOtp(authUrl, doneUrl, { Date, setTimeout, fetch, globalInfo }, fetchOptions) {
|
|
72
|
-
const qrCode = generateQrCode(authUrl);
|
|
73
|
-
globalInfo(`Authenticate your account at:\n${authUrl}\n\n${qrCode}`);
|
|
74
|
-
const startTime = Date.now();
|
|
75
|
-
const timeout = 5 * 60 * 1000; // 5 minutes
|
|
76
|
-
const pollIntervalMs = 1000;
|
|
77
|
-
while (true) {
|
|
78
|
-
const now = Date.now();
|
|
79
|
-
if (now - startTime > timeout) {
|
|
80
|
-
throw new OtpWebAuthTimeoutError(now, startTime, timeout);
|
|
81
|
-
}
|
|
82
|
-
// eslint-disable-next-line no-await-in-loop
|
|
83
|
-
await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
|
|
84
|
-
let response;
|
|
85
|
-
try {
|
|
86
|
-
// eslint-disable-next-line no-await-in-loop
|
|
87
|
-
response = await fetch(doneUrl, fetchOptions);
|
|
88
|
-
}
|
|
89
|
-
catch {
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
if (!response.ok)
|
|
93
|
-
continue;
|
|
94
|
-
if (response.status === 202) {
|
|
95
|
-
// Registry is still waiting for authentication.
|
|
96
|
-
// Respect Retry-After header if present by waiting the additional time
|
|
97
|
-
// beyond the default poll interval already elapsed above, but do not
|
|
98
|
-
// exceed the overall timeout.
|
|
99
|
-
const retryAfterSeconds = Number(response.headers.get('retry-after'));
|
|
100
|
-
if (Number.isFinite(retryAfterSeconds)) {
|
|
101
|
-
const additionalMs = retryAfterSeconds * 1000 - pollIntervalMs;
|
|
102
|
-
if (additionalMs > 0) {
|
|
103
|
-
const nowAfterPoll = Date.now();
|
|
104
|
-
const remainingMs = timeout - (nowAfterPoll - startTime);
|
|
105
|
-
if (remainingMs <= 0) {
|
|
106
|
-
throw new OtpWebAuthTimeoutError(nowAfterPoll, startTime, timeout);
|
|
107
|
-
}
|
|
108
|
-
const sleepMs = Math.min(additionalMs, remainingMs);
|
|
109
|
-
// eslint-disable-next-line no-await-in-loop
|
|
110
|
-
await new Promise(resolve => setTimeout(resolve, sleepMs));
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
let body;
|
|
116
|
-
try {
|
|
117
|
-
// eslint-disable-next-line no-await-in-loop
|
|
118
|
-
body = await response.json();
|
|
119
|
-
}
|
|
120
|
-
catch {
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
if (body.token) {
|
|
124
|
-
return body.token;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
function generateQrCode(text) {
|
|
129
|
-
let qrCode;
|
|
130
|
-
qrcodeTerminal.generate(text, { small: true }, (code) => {
|
|
131
|
-
qrCode = code;
|
|
11
|
+
export async function publishWithOtpHandling({ context = SHARED_CONTEXT, manifest, publishOptions, tarballData, }) {
|
|
12
|
+
const { publish } = context;
|
|
13
|
+
const fetchOptions = {
|
|
14
|
+
method: 'GET',
|
|
15
|
+
retry: {
|
|
16
|
+
factor: publishOptions.fetchRetryFactor,
|
|
17
|
+
maxTimeout: publishOptions.fetchRetryMaxtimeout,
|
|
18
|
+
minTimeout: publishOptions.fetchRetryMintimeout,
|
|
19
|
+
retries: publishOptions.fetchRetries,
|
|
20
|
+
},
|
|
21
|
+
timeout: publishOptions.timeout,
|
|
22
|
+
};
|
|
23
|
+
return withOtpHandling({
|
|
24
|
+
context,
|
|
25
|
+
fetchOptions,
|
|
26
|
+
// When otp is undefined (first attempt), { ...publishOptions, otp } adds
|
|
27
|
+
// otp: undefined to the options. This is safe because libnpmpublish treats
|
|
28
|
+
// undefined the same as absent (unlike HTTP headers, where undefined gets
|
|
29
|
+
// coerced to the string "undefined").
|
|
30
|
+
operation: otp => publish(manifest, tarballData, { ...publishOptions, otp }),
|
|
132
31
|
});
|
|
133
|
-
if (qrCode != null)
|
|
134
|
-
return qrCode;
|
|
135
|
-
/* istanbul ignore next */
|
|
136
|
-
throw new Error('we were expecting qrcode-terminal to be fully synchronous, but it fails to execute the callback');
|
|
137
|
-
}
|
|
138
|
-
export class OtpWebAuthTimeoutError extends PnpmError {
|
|
139
|
-
endTime;
|
|
140
|
-
startTime;
|
|
141
|
-
timeout;
|
|
142
|
-
constructor(endTime, startTime, timeout) {
|
|
143
|
-
super('WEBAUTH_TIMEOUT', 'Web-based authentication timed out before it could be completed', {
|
|
144
|
-
hint: 'Re-run this command and complete the authentication step in your browser before the time limit is reached',
|
|
145
|
-
});
|
|
146
|
-
this.endTime = endTime;
|
|
147
|
-
this.startTime = startTime;
|
|
148
|
-
this.timeout = timeout;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
export class OtpNonInteractiveError extends PnpmError {
|
|
152
|
-
constructor() {
|
|
153
|
-
super('OTP_NON_INTERACTIVE', 'The registry requires additional authentication, but pnpm is not running in an interactive terminal', {
|
|
154
|
-
hint: 'Re-run this command in an interactive terminal to complete authentication, or provide the --otp option if you are using a classic one-time password (OTP)',
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
export class OtpSecondChallengeError extends PnpmError {
|
|
159
|
-
constructor() {
|
|
160
|
-
super('OTP_SECOND_CHALLENGE', 'The registry requested a one-time password (OTP) a second time after one was already provided', {
|
|
161
|
-
hint: 'This is unexpected behavior from the registry. Try the command again later and, if the issue persists, verify that your registry supports OTP-based authentication or contact the registry administrator.',
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
32
|
}
|
|
165
33
|
//# sourceMappingURL=otp.js.map
|
package/lib/publish/pack.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { type Config, type UniversalOptions } from '@pnpm/config.reader';
|
|
1
|
+
import { type Config, type ConfigContext, type UniversalOptions } from '@pnpm/config.reader';
|
|
2
2
|
import { type ExportedManifest } from '@pnpm/releasing.exportable-manifest';
|
|
3
3
|
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
4
4
|
export declare function cliOptionsTypes(): Record<string, unknown>;
|
|
5
5
|
export declare const commandNames: string[];
|
|
6
6
|
export declare function help(): string;
|
|
7
|
-
export type PackOptions = Pick<UniversalOptions, 'dir'> & Pick<Config, 'catalogs' | 'ignoreScripts' | '
|
|
7
|
+
export type PackOptions = Pick<UniversalOptions, 'dir'> & Pick<Config, 'catalogs' | 'ignoreScripts' | 'embedReadme' | 'packGzipLevel' | 'nodeLinker' | 'userAgent'> & Partial<Pick<Config, 'extraBinPaths' | 'extraEnv' | 'recursive' | 'workspaceConcurrency' | 'workspaceDir'>> & Partial<Pick<ConfigContext, 'hooks' | 'selectedProjectsGraph'>> & {
|
|
8
8
|
argv: {
|
|
9
9
|
original: string[];
|
|
10
10
|
};
|
package/lib/publish/pack.js
CHANGED
|
@@ -145,10 +145,10 @@ export async function api(opts) {
|
|
|
145
145
|
extraBinPaths: opts.extraBinPaths,
|
|
146
146
|
extraEnv: opts.extraEnv,
|
|
147
147
|
pkgRoot: opts.dir,
|
|
148
|
-
rawConfig: opts.rawConfig,
|
|
149
148
|
rootModulesDir: await realpathMissing(path.join(opts.dir, 'node_modules')),
|
|
150
149
|
stdio: 'inherit',
|
|
151
150
|
unsafePerm: true, // when running scripts explicitly, assume that they're trusted.
|
|
151
|
+
userAgent: opts.userAgent,
|
|
152
152
|
});
|
|
153
153
|
if (!opts.ignoreScripts) {
|
|
154
154
|
await _runScriptsIfPresent([
|
package/lib/publish/publish.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Config } from '@pnpm/config.reader';
|
|
1
|
+
import { type Config, type ConfigContext } from '@pnpm/config.reader';
|
|
2
2
|
import { type RunLifecycleHookOptions } from '@pnpm/exec.lifecycle';
|
|
3
3
|
import type { ProjectManifest } from '@pnpm/types';
|
|
4
4
|
import { type PublishRecursiveOpts } from './recursivePublish.js';
|
|
@@ -13,7 +13,7 @@ export declare function handler(opts: Omit<PublishRecursiveOpts, 'workspaceDir'>
|
|
|
13
13
|
engineStrict?: boolean;
|
|
14
14
|
recursive?: boolean;
|
|
15
15
|
workspaceDir?: string;
|
|
16
|
-
} & Pick<Config, '
|
|
16
|
+
} & Pick<Config, 'bin' | 'gitChecks' | 'ignoreScripts' | 'pnpmHomeDir' | 'publishBranch' | 'embedReadme'> & Pick<ConfigContext, 'allProjects'>, params: string[]): Promise<{
|
|
17
17
|
exitCode?: number;
|
|
18
18
|
} | undefined>;
|
|
19
19
|
export interface PublishResult {
|
|
@@ -27,5 +27,5 @@ export declare function publish(opts: Omit<PublishRecursiveOpts, 'workspaceDir'>
|
|
|
27
27
|
engineStrict?: boolean;
|
|
28
28
|
recursive?: boolean;
|
|
29
29
|
workspaceDir?: string;
|
|
30
|
-
} & Pick<Config, '
|
|
30
|
+
} & Pick<Config, 'bin' | 'gitChecks' | 'ignoreScripts' | 'pnpmHomeDir' | 'publishBranch' | 'embedReadme' | 'packGzipLevel'> & Pick<ConfigContext, 'allProjects'>, params: string[]): Promise<PublishResult>;
|
|
31
31
|
export declare function runScriptsIfPresent(opts: RunLifecycleHookOptions, scriptNames: string[], manifest: ProjectManifest): Promise<void>;
|
package/lib/publish/publish.js
CHANGED
|
@@ -168,10 +168,10 @@ Do you want to continue?`,
|
|
|
168
168
|
extraBinPaths: opts.extraBinPaths,
|
|
169
169
|
extraEnv: opts.extraEnv,
|
|
170
170
|
pkgRoot: dir,
|
|
171
|
-
rawConfig: opts.rawConfig,
|
|
172
171
|
rootModulesDir: await realpathMissing(path.join(dir, 'node_modules')),
|
|
173
172
|
stdio: 'inherit',
|
|
174
173
|
unsafePerm: true, // when running scripts explicitly, assume that they're trusted.
|
|
174
|
+
userAgent: opts.userAgent,
|
|
175
175
|
});
|
|
176
176
|
const { manifest } = await readProjectManifest(dir, opts);
|
|
177
177
|
// Unfortunately, we cannot support postpack at the moment
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import type { Config } from '@pnpm/config.reader';
|
|
2
2
|
import { PnpmError } from '@pnpm/error';
|
|
3
3
|
import type { PackResult } from './pack.js';
|
|
4
|
-
type
|
|
5
|
-
type SslConfigKey = 'ca' | 'cert' | 'key';
|
|
6
|
-
type AuthSslConfigKey = AuthConfigKey | SslConfigKey | 'authInfos' | 'sslConfigs';
|
|
7
|
-
export type PublishPackedPkgOptions = Pick<Config, AuthSslConfigKey | 'dryRun' | 'fetchRetries' | 'fetchRetryFactor' | 'fetchRetryMaxtimeout' | 'fetchRetryMintimeout' | 'fetchTimeout' | 'registries' | 'tag' | 'userAgent'> & {
|
|
4
|
+
export type PublishPackedPkgOptions = Pick<Config, 'configByUri' | 'dryRun' | 'fetchRetries' | 'fetchRetryFactor' | 'fetchRetryMaxtimeout' | 'fetchRetryMintimeout' | 'fetchTimeout' | 'registries' | 'tag' | 'userAgent'> & {
|
|
8
5
|
access?: 'public' | 'restricted';
|
|
9
6
|
ci?: boolean;
|
|
10
7
|
otp?: string;
|
|
@@ -16,4 +13,3 @@ export declare class PublishUnsupportedRegistryProtocolError extends PnpmError {
|
|
|
16
13
|
readonly registryUrl: string;
|
|
17
14
|
constructor(registryUrl: string);
|
|
18
15
|
}
|
|
19
|
-
export {};
|
|
@@ -28,7 +28,8 @@ export async function publishPackedPkg(packResult, opts) {
|
|
|
28
28
|
throw await createFailedToPublishError(packResult, response);
|
|
29
29
|
}
|
|
30
30
|
async function createPublishOptions(manifest, options) {
|
|
31
|
-
const { registry,
|
|
31
|
+
const { registry, config } = findRegistryInfo(manifest, options);
|
|
32
|
+
const { creds, tls } = config ?? {};
|
|
32
33
|
const { access, ci: isFromCI, fetchRetries, fetchRetryFactor, fetchRetryMaxtimeout, fetchRetryMintimeout, fetchTimeout: timeout, otp, provenance, provenanceFile, tag: defaultTag, userAgent, } = options;
|
|
33
34
|
const headers = {
|
|
34
35
|
'npm-auth-type': 'web',
|
|
@@ -54,20 +55,14 @@ async function createPublishOptions(manifest, options) {
|
|
|
54
55
|
// always fall back to prompting the user for an OTP code, even when the user
|
|
55
56
|
// has no OTP set up.
|
|
56
57
|
authType: 'web',
|
|
57
|
-
ca:
|
|
58
|
-
cert:
|
|
59
|
-
key:
|
|
58
|
+
ca: tls?.ca,
|
|
59
|
+
cert: tls?.cert,
|
|
60
|
+
key: tls?.key,
|
|
60
61
|
npmCommand: 'publish',
|
|
61
|
-
token:
|
|
62
|
-
username:
|
|
63
|
-
password:
|
|
62
|
+
token: creds && extractToken(creds),
|
|
63
|
+
username: creds?.basicAuth?.username,
|
|
64
|
+
password: creds?.basicAuth?.password,
|
|
64
65
|
};
|
|
65
|
-
// This is necessary because getNetworkConfigs initialized them as { cert: '', key: '' }
|
|
66
|
-
// which may be a problem.
|
|
67
|
-
// The real fix is to change the type `SslConfig` into that of partial properties, but that
|
|
68
|
-
// is out of scope for now.
|
|
69
|
-
removeEmptyStringProperty(publishOptions, 'cert');
|
|
70
|
-
removeEmptyStringProperty(publishOptions, 'key');
|
|
71
66
|
if (registry) {
|
|
72
67
|
const oidcTokenProvenance = await fetchTokenAndProvenanceByOidcIfApplicable(publishOptions, manifest.name, registry, options);
|
|
73
68
|
publishOptions.token ??= oidcTokenProvenance?.authToken;
|
|
@@ -78,11 +73,10 @@ async function createPublishOptions(manifest, options) {
|
|
|
78
73
|
return publishOptions;
|
|
79
74
|
}
|
|
80
75
|
/**
|
|
81
|
-
* Find
|
|
82
|
-
*
|
|
83
|
-
* The example `.npmrc` demonstrated inheritance.
|
|
76
|
+
* Find credentials and SSL info for a package's registry.
|
|
77
|
+
* Follows {@link https://docs.npmjs.com/cli/v10/configuring-npm/npmrc#auth-related-configuration}.
|
|
84
78
|
*/
|
|
85
|
-
function
|
|
79
|
+
function findRegistryInfo({ name }, { configByUri, registries }) {
|
|
86
80
|
// eslint-disable-next-line regexp/no-unused-capturing-group
|
|
87
81
|
const scopedMatches = /@(?<scope>[^/]+)\/(?<slug>[^/]+)/.exec(name);
|
|
88
82
|
const registryName = scopedMatches?.groups ? `@${scopedMatches.groups.scope}` : 'default';
|
|
@@ -92,28 +86,26 @@ function findAuthSslInfo({ name }, { authInfos, sslConfigs, registries, ...defau
|
|
|
92
86
|
throw new PublishUnsupportedRegistryProtocolError(nonNormalizedRegistry);
|
|
93
87
|
}
|
|
94
88
|
const { normalizedUrl: registry, longestConfigKey: initialRegistryConfigKey, } = supportedRegistryInfo;
|
|
95
|
-
|
|
89
|
+
let creds;
|
|
90
|
+
let tls = {};
|
|
96
91
|
for (const registryConfigKey of allRegistryConfigKeys(initialRegistryConfigKey)) {
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
registry
|
|
107
|
-
registry
|
|
108
|
-
|
|
92
|
+
const entry = configByUri[registryConfigKey];
|
|
93
|
+
if (!entry)
|
|
94
|
+
continue;
|
|
95
|
+
// Auth from longer path collectively overrides shorter path
|
|
96
|
+
creds ??= entry.creds;
|
|
97
|
+
// TLS from longer path individually overrides shorter path
|
|
98
|
+
tls = { ...entry.tls, ...tls };
|
|
99
|
+
}
|
|
100
|
+
const isDefaultRegistry = nonNormalizedRegistry === registries.default ||
|
|
101
|
+
registry === registries.default ||
|
|
102
|
+
registry === parseSupportedRegistryUrl(registries.default)?.normalizedUrl;
|
|
103
|
+
if (isDefaultRegistry) {
|
|
104
|
+
creds ??= configByUri['']?.creds;
|
|
109
105
|
}
|
|
110
106
|
return {
|
|
111
107
|
registry,
|
|
112
|
-
|
|
113
|
-
ssl: {
|
|
114
|
-
...defaultInfos,
|
|
115
|
-
...result.ssl, // old ssl from longer path individually overrides default ssl
|
|
116
|
-
},
|
|
108
|
+
config: { creds, tls },
|
|
117
109
|
};
|
|
118
110
|
}
|
|
119
111
|
function extractToken({ authToken, tokenHelper, }) {
|
|
@@ -218,11 +210,6 @@ function appendAuthOptionsForRegistry(targetPublishOptions, registry) {
|
|
|
218
210
|
targetPublishOptions[`${registryConfigKey}:username`] ??= targetPublishOptions.username;
|
|
219
211
|
targetPublishOptions[`${registryConfigKey}:_password`] ??= targetPublishOptions.password && btoa(targetPublishOptions.password);
|
|
220
212
|
}
|
|
221
|
-
function removeEmptyStringProperty(object, key) {
|
|
222
|
-
if (!object[key]) {
|
|
223
|
-
delete object[key];
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
213
|
function pruneUndefined(object) {
|
|
227
214
|
for (const key in object) {
|
|
228
215
|
if (object[key] === undefined) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { Config } from '@pnpm/config.reader';
|
|
1
|
+
import type { Config, ConfigContext } from '@pnpm/config.reader';
|
|
2
2
|
import type { PublishPackedPkgOptions } from './publishPackedPkg.js';
|
|
3
|
-
export type PublishRecursiveOpts = Required<Pick<Config, 'bin' | 'cacheDir' | '
|
|
3
|
+
export type PublishRecursiveOpts = Required<Pick<Config, 'bin' | 'cacheDir' | 'dir' | 'pnpmHomeDir' | 'configByUri' | 'registries' | 'workspaceDir'>> & Required<Pick<ConfigContext, 'cliOptions'>> & Partial<Pick<Config, 'tag' | 'ca' | 'catalogs' | 'cert' | 'fetchTimeout' | 'force' | 'dryRun' | 'extraBinPaths' | 'extraEnv' | 'fetchRetries' | 'fetchRetryFactor' | 'fetchRetryMaxtimeout' | 'fetchRetryMintimeout' | 'key' | 'httpProxy' | 'httpsProxy' | 'localAddress' | 'lockfileDir' | 'noProxy' | 'npmPath' | 'offline' | 'strictSsl' | 'unsafePerm' | 'userAgent' | 'verifyStoreIntegrity'>> & Partial<Pick<ConfigContext, 'selectedProjectsGraph'>> & {
|
|
4
4
|
access?: 'public' | 'restricted';
|
|
5
5
|
argv: {
|
|
6
6
|
original: string[];
|
|
7
7
|
};
|
|
8
8
|
reportSummary?: boolean;
|
|
9
9
|
} & PublishPackedPkgOptions;
|
|
10
|
-
export declare function recursivePublish(opts: PublishRecursiveOpts & Required<Pick<
|
|
10
|
+
export declare function recursivePublish(opts: PublishRecursiveOpts & Required<Pick<ConfigContext, 'selectedProjectsGraph'>>): Promise<{
|
|
11
11
|
exitCode: number;
|
|
12
12
|
}>;
|
|
@@ -11,8 +11,7 @@ export async function recursivePublish(opts) {
|
|
|
11
11
|
const pkgs = Object.values(opts.selectedProjectsGraph).map((wsPkg) => wsPkg.package);
|
|
12
12
|
const { resolve } = createResolver({
|
|
13
13
|
...opts,
|
|
14
|
-
|
|
15
|
-
userConfig: opts.userConfig,
|
|
14
|
+
configByUri: opts.configByUri,
|
|
16
15
|
retry: {
|
|
17
16
|
factor: opts.fetchRetryFactor,
|
|
18
17
|
maxTimeout: opts.fetchRetryMaxtimeout,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import readline from 'node:readline';
|
|
3
|
+
import { globalInfo, globalWarn } from '@pnpm/logger';
|
|
2
4
|
import { fetch } from '@pnpm/network.fetch';
|
|
3
5
|
import ciInfo from 'ci-info';
|
|
4
6
|
import enquirer from 'enquirer';
|
|
@@ -6,10 +8,13 @@ import { publish as _publish } from 'libnpmpublish';
|
|
|
6
8
|
const publish = _publish;
|
|
7
9
|
export const SHARED_CONTEXT = {
|
|
8
10
|
Date,
|
|
11
|
+
createReadlineInterface: readline.createInterface.bind(null, { input: process.stdin }),
|
|
9
12
|
ciInfo,
|
|
10
13
|
enquirer,
|
|
14
|
+
execFile,
|
|
11
15
|
fetch,
|
|
12
16
|
globalInfo,
|
|
17
|
+
globalWarn,
|
|
13
18
|
process,
|
|
14
19
|
publish,
|
|
15
20
|
setTimeout,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Config } from '@pnpm/config.reader';
|
|
2
|
+
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
3
|
+
export declare function cliOptionsTypes(): Record<string, unknown>;
|
|
4
|
+
export declare const commandNames: string[];
|
|
5
|
+
export declare function help(): string;
|
|
6
|
+
interface VersionHandlerOptions extends Config {
|
|
7
|
+
allowSameVersion?: boolean;
|
|
8
|
+
noGitChecks?: boolean;
|
|
9
|
+
noCommitHooks?: boolean;
|
|
10
|
+
noStrict?: boolean;
|
|
11
|
+
preid?: string;
|
|
12
|
+
tagVersionPrefix?: string;
|
|
13
|
+
recursive?: boolean;
|
|
14
|
+
json?: boolean;
|
|
15
|
+
ignoredPackages?: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function handler(opts: VersionHandlerOptions, params: string[]): Promise<string | {
|
|
18
|
+
output?: string;
|
|
19
|
+
exitCode: number;
|
|
20
|
+
}>;
|
|
21
|
+
export declare const version: {
|
|
22
|
+
handler: typeof handler;
|
|
23
|
+
help: typeof help;
|
|
24
|
+
commandNames: string[];
|
|
25
|
+
cliOptionsTypes: typeof cliOptionsTypes;
|
|
26
|
+
rcOptionsTypes: typeof rcOptionsTypes;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { readProjectManifest } from '@pnpm/cli.utils';
|
|
2
|
+
import { types as allTypes } from '@pnpm/config.reader';
|
|
3
|
+
import { PnpmError } from '@pnpm/error';
|
|
4
|
+
import { isGitRepo, isWorkingTreeClean } from '@pnpm/network.git-utils';
|
|
5
|
+
import { filterProjectsFromDir } from '@pnpm/workspace.projects-filter';
|
|
6
|
+
import { pick } from 'ramda';
|
|
7
|
+
import { renderHelp } from 'render-help';
|
|
8
|
+
import { inc, valid } from 'semver';
|
|
9
|
+
export function rcOptionsTypes() {
|
|
10
|
+
return pick([
|
|
11
|
+
'git-checks',
|
|
12
|
+
], allTypes);
|
|
13
|
+
}
|
|
14
|
+
export function cliOptionsTypes() {
|
|
15
|
+
return {
|
|
16
|
+
...rcOptionsTypes(),
|
|
17
|
+
'allow-same-version': Boolean,
|
|
18
|
+
'no-git-checks': Boolean,
|
|
19
|
+
'no-commit-hooks': Boolean,
|
|
20
|
+
'no-strict': Boolean,
|
|
21
|
+
'preid': String,
|
|
22
|
+
'tag-version-prefix': String,
|
|
23
|
+
recursive: Boolean,
|
|
24
|
+
json: Boolean,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export const commandNames = ['version'];
|
|
28
|
+
export function help() {
|
|
29
|
+
return renderHelp({
|
|
30
|
+
description: 'Bumps the version of a package.',
|
|
31
|
+
usages: [
|
|
32
|
+
'pnpm version <major|minor|patch|premajor|preminor|prepatch|prerelease>',
|
|
33
|
+
],
|
|
34
|
+
descriptionLists: [
|
|
35
|
+
{
|
|
36
|
+
title: 'Options',
|
|
37
|
+
list: [
|
|
38
|
+
{
|
|
39
|
+
description: "Don't check if working tree is clean",
|
|
40
|
+
name: '--no-git-checks',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
description: 'Sets the prerelease identifier (e.g. alpha, beta, rc)',
|
|
44
|
+
name: '--preid <preid>',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
description: 'Sets the tag prefix (default: v)',
|
|
48
|
+
name: '--tag-version-prefix <prefix>',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
description: 'Allow bumping to the same version',
|
|
52
|
+
name: '--allow-same-version',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
description: 'Skip running commit hooks',
|
|
56
|
+
name: '--no-commit-hooks',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
description: 'Filter packages by name (glob pattern)',
|
|
60
|
+
name: '--filter <pattern>',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
description: 'Show information in JSON format',
|
|
64
|
+
name: '--json',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
description: 'Apply command to all packages in workspace',
|
|
68
|
+
name: '--recursive',
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export async function handler(opts, params) {
|
|
76
|
+
const bumpType = params[0];
|
|
77
|
+
if (!bumpType || !['major', 'minor', 'patch', 'premajor', 'preminor', 'prepatch', 'prerelease'].includes(bumpType)) {
|
|
78
|
+
throw new PnpmError('INVALID_VERSION_BUMP', 'Invalid version bump type. Must be one of: major, minor, patch, premajor, preminor, prepatch, prerelease');
|
|
79
|
+
}
|
|
80
|
+
// Check git status if needed
|
|
81
|
+
if (!opts.noGitChecks && await isGitRepo()) {
|
|
82
|
+
if (!await isWorkingTreeClean()) {
|
|
83
|
+
throw new PnpmError('UNCLEAN_WORKING_TREE', 'Working tree is not clean. Commit or stash your changes.');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const changes = [];
|
|
87
|
+
if (opts.recursive) {
|
|
88
|
+
// Handle workspace versioning
|
|
89
|
+
const workspaceDir = opts.workspaceDir || opts.dir;
|
|
90
|
+
const filters = [];
|
|
91
|
+
if (opts.filter && opts.filter.length > 0) {
|
|
92
|
+
opts.filter.forEach(filterPattern => {
|
|
93
|
+
filters.push({
|
|
94
|
+
filter: filterPattern,
|
|
95
|
+
followProdDepsOnly: !!opts.filterProd && opts.filterProd.length > 0,
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const result = await filterProjectsFromDir(workspaceDir, filters, {
|
|
100
|
+
workspaceDir,
|
|
101
|
+
prefix: opts.dir,
|
|
102
|
+
});
|
|
103
|
+
const pkgDirs = Object.keys(result.selectedProjectsGraph);
|
|
104
|
+
const bumpResults = await Promise.all(pkgDirs.map(pkgDir => bumpPackageVersion(pkgDir, bumpType, opts)));
|
|
105
|
+
for (const change of bumpResults) {
|
|
106
|
+
if (change) {
|
|
107
|
+
changes.push(change);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// Handle single package versioning
|
|
113
|
+
const change = await bumpPackageVersion(opts.dir, bumpType, opts);
|
|
114
|
+
if (change) {
|
|
115
|
+
changes.push(change);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (changes.length === 0) {
|
|
119
|
+
throw new PnpmError('NO_PACKAGES_TO_VERSION', 'No packages to version');
|
|
120
|
+
}
|
|
121
|
+
// Output results
|
|
122
|
+
if (opts.json) {
|
|
123
|
+
return JSON.stringify(changes, null, 2);
|
|
124
|
+
}
|
|
125
|
+
let output = 'Version bumped successfully:\n';
|
|
126
|
+
for (const change of changes) {
|
|
127
|
+
output += `${change.name}: ${change.currentVersion} → ${change.newVersion}\n`;
|
|
128
|
+
}
|
|
129
|
+
return output;
|
|
130
|
+
}
|
|
131
|
+
async function bumpPackageVersion(pkgDir, bumpType, opts) {
|
|
132
|
+
const { manifest, writeProjectManifest } = await readProjectManifest(pkgDir);
|
|
133
|
+
if (!manifest.name || !manifest.version) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
const currentVersion = manifest.version;
|
|
137
|
+
if (!valid(currentVersion)) {
|
|
138
|
+
throw new PnpmError('INVALID_VERSION', `Invalid version in ${pkgDir}: ${currentVersion}`);
|
|
139
|
+
}
|
|
140
|
+
const newVersion = inc(currentVersion, bumpType, false, opts.preid);
|
|
141
|
+
if (!newVersion) {
|
|
142
|
+
throw new PnpmError('VERSION_BUMP_FAILED', `Failed to bump version from ${currentVersion} using ${bumpType}`);
|
|
143
|
+
}
|
|
144
|
+
if (newVersion === currentVersion && !opts.allowSameVersion) {
|
|
145
|
+
throw new PnpmError('VERSION_NOT_CHANGED', `Version was not changed: ${currentVersion}`);
|
|
146
|
+
}
|
|
147
|
+
manifest.version = newVersion;
|
|
148
|
+
await writeProjectManifest(manifest);
|
|
149
|
+
return {
|
|
150
|
+
name: manifest.name,
|
|
151
|
+
currentVersion,
|
|
152
|
+
newVersion,
|
|
153
|
+
path: pkgDir,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
export const version = {
|
|
157
|
+
handler,
|
|
158
|
+
help,
|
|
159
|
+
commandNames,
|
|
160
|
+
cliOptionsTypes,
|
|
161
|
+
rcOptionsTypes,
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/releasing.commands",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1100.0.0",
|
|
4
4
|
"description": "Commands for deploy, pack, and publish",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"!*.map"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
+
"@pnpm/npm-package-arg": "^2.0.0",
|
|
27
28
|
"@types/normalize-path": "^3.0.2",
|
|
28
29
|
"@zkochan/rimraf": "^4.0.0",
|
|
29
30
|
"chalk": "^5.6.0",
|
|
@@ -35,56 +36,58 @@
|
|
|
35
36
|
"normalize-registry-url": "2.0.1",
|
|
36
37
|
"p-filter": "^4.1.0",
|
|
37
38
|
"p-limit": "^7.1.0",
|
|
38
|
-
"qrcode-terminal": "^0.12.0",
|
|
39
39
|
"ramda": "npm:@pnpm/ramda@0.28.1",
|
|
40
40
|
"realpath-missing": "^2.0.0",
|
|
41
41
|
"render-help": "^2.0.0",
|
|
42
|
+
"semver": "^7.7.2",
|
|
42
43
|
"tar-stream": "^3.1.7",
|
|
43
44
|
"tempy": "3.0.0",
|
|
44
45
|
"tinyglobby": "^0.2.14",
|
|
45
46
|
"validate-npm-package-name": "7.0.2",
|
|
46
47
|
"write-json-file": "^7.0.0",
|
|
47
48
|
"write-yaml-file": "^6.0.0",
|
|
48
|
-
"@pnpm/bins.resolver": "
|
|
49
|
-
"@pnpm/catalogs.types": "
|
|
50
|
-
"@pnpm/cli.utils": "
|
|
51
|
-
"@pnpm/
|
|
52
|
-
"@pnpm/config.
|
|
53
|
-
"@pnpm/
|
|
54
|
-
"@pnpm/
|
|
55
|
-
"@pnpm/
|
|
56
|
-
"@pnpm/
|
|
57
|
-
"@pnpm/exec.lifecycle": "
|
|
58
|
-
"@pnpm/fetching.directory-fetcher": "
|
|
59
|
-
"@pnpm/fs.indexed-pkg-importer": "
|
|
60
|
-
"@pnpm/engine.runtime.commands": "
|
|
61
|
-
"@pnpm/fs.is-empty-dir-or-nothing": "
|
|
62
|
-
"@pnpm/fs.packlist": "
|
|
63
|
-
"@pnpm/installing.commands": "
|
|
64
|
-
"@pnpm/lockfile.fs": "
|
|
65
|
-
"@pnpm/lockfile.types": "
|
|
66
|
-
"@pnpm/network.fetch": "
|
|
67
|
-
"@pnpm/
|
|
68
|
-
"@pnpm/
|
|
69
|
-
"@pnpm/
|
|
70
|
-
"@pnpm/
|
|
71
|
-
"@pnpm/
|
|
72
|
-
"@pnpm/resolving.resolver-base": "
|
|
49
|
+
"@pnpm/bins.resolver": "1100.0.0",
|
|
50
|
+
"@pnpm/catalogs.types": "1100.0.0",
|
|
51
|
+
"@pnpm/cli.utils": "1100.0.0",
|
|
52
|
+
"@pnpm/config.pick-registry-for-package": "1100.0.0",
|
|
53
|
+
"@pnpm/config.reader": "1100.0.0",
|
|
54
|
+
"@pnpm/deps.path": "1100.0.0",
|
|
55
|
+
"@pnpm/cli.common-cli-options-help": "1100.0.0",
|
|
56
|
+
"@pnpm/constants": "1100.0.0",
|
|
57
|
+
"@pnpm/error": "1100.0.0",
|
|
58
|
+
"@pnpm/exec.lifecycle": "1100.0.0",
|
|
59
|
+
"@pnpm/fetching.directory-fetcher": "1100.0.0",
|
|
60
|
+
"@pnpm/fs.indexed-pkg-importer": "1100.0.0",
|
|
61
|
+
"@pnpm/engine.runtime.commands": "1100.0.0",
|
|
62
|
+
"@pnpm/fs.is-empty-dir-or-nothing": "1100.0.0",
|
|
63
|
+
"@pnpm/fs.packlist": "1100.0.0",
|
|
64
|
+
"@pnpm/installing.commands": "1100.0.0",
|
|
65
|
+
"@pnpm/lockfile.fs": "1100.0.0",
|
|
66
|
+
"@pnpm/lockfile.types": "1100.0.0",
|
|
67
|
+
"@pnpm/network.fetch": "1100.0.0",
|
|
68
|
+
"@pnpm/installing.client": "1100.0.0",
|
|
69
|
+
"@pnpm/network.git-utils": "1100.0.0",
|
|
70
|
+
"@pnpm/network.web-auth": "1100.0.0",
|
|
71
|
+
"@pnpm/releasing.exportable-manifest": "1100.0.0",
|
|
72
|
+
"@pnpm/workspace.projects-filter": "1100.0.0",
|
|
73
|
+
"@pnpm/resolving.resolver-base": "1100.0.0",
|
|
74
|
+
"@pnpm/types": "1100.0.0",
|
|
75
|
+
"@pnpm/workspace.projects-sorter": "1100.0.0"
|
|
73
76
|
},
|
|
74
77
|
"peerDependencies": {
|
|
75
78
|
"@pnpm/logger": ">=1001.0.0 <1002.0.0"
|
|
76
79
|
},
|
|
77
80
|
"devDependencies": {
|
|
78
|
-
"@jest/globals": "30.0
|
|
79
|
-
"@pnpm/registry-mock": "
|
|
81
|
+
"@jest/globals": "30.3.0",
|
|
82
|
+
"@pnpm/registry-mock": "6.0.0",
|
|
80
83
|
"@types/cross-spawn": "^6.0.6",
|
|
81
84
|
"@types/is-windows": "^1.0.2",
|
|
82
85
|
"@types/libnpmpublish": "^9.0.1",
|
|
83
86
|
"@types/proxyquire": "^1.3.31",
|
|
84
|
-
"@types/
|
|
85
|
-
"@types/
|
|
86
|
-
"@types/tar": "^
|
|
87
|
-
"@types/tar-stream": "^
|
|
87
|
+
"@types/ramda": "0.31.1",
|
|
88
|
+
"@types/semver": "7.7.1",
|
|
89
|
+
"@types/tar": "^7.0.87",
|
|
90
|
+
"@types/tar-stream": "^3.1.4",
|
|
88
91
|
"@types/validate-npm-package-name": "^4.0.2",
|
|
89
92
|
"ci-info": "^4.3.0",
|
|
90
93
|
"cross-spawn": "^7.0.6",
|
|
@@ -92,15 +95,15 @@
|
|
|
92
95
|
"load-json-file": "^7.0.1",
|
|
93
96
|
"tar": "^7.5.10",
|
|
94
97
|
"write-yaml-file": "^6.0.0",
|
|
95
|
-
"@pnpm/
|
|
96
|
-
"@pnpm/
|
|
97
|
-
"@pnpm/
|
|
98
|
-
"@pnpm/logger": "
|
|
99
|
-
"@pnpm/
|
|
100
|
-
"@pnpm/test-fixtures": "
|
|
101
|
-
"@pnpm/
|
|
102
|
-
"@pnpm/
|
|
103
|
-
"@pnpm/
|
|
98
|
+
"@pnpm/assert-project": "1100.0.0",
|
|
99
|
+
"@pnpm/catalogs.config": "1100.0.0",
|
|
100
|
+
"@pnpm/hooks.pnpmfile": "1100.0.0",
|
|
101
|
+
"@pnpm/logger": "1100.0.0",
|
|
102
|
+
"@pnpm/prepare": "1100.0.0",
|
|
103
|
+
"@pnpm/test-fixtures": "1100.0.0",
|
|
104
|
+
"@pnpm/testing.command-defaults": "1100.0.0",
|
|
105
|
+
"@pnpm/releasing.commands": "1100.0.0",
|
|
106
|
+
"@pnpm/test-ipc-server": "1100.0.0"
|
|
104
107
|
},
|
|
105
108
|
"engines": {
|
|
106
109
|
"node": ">=22.13"
|
|
@@ -111,8 +114,8 @@
|
|
|
111
114
|
"scripts": {
|
|
112
115
|
"start": "tsgo --watch",
|
|
113
116
|
"lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
114
|
-
"
|
|
115
|
-
"
|
|
116
|
-
"
|
|
117
|
+
"test": "pn compile && pn --filter=pnpm compile && pn .test",
|
|
118
|
+
"compile": "tsgo --build && pn lint --fix",
|
|
119
|
+
".test": "cross-env NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" jest"
|
|
117
120
|
}
|
|
118
121
|
}
|