@pnpm/releasing.commands 1000.0.0 → 1100.0.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.
@@ -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>;
@@ -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
@@ -1,2 +1,3 @@
1
1
  export { deploy } from './deploy/index.js';
2
2
  export { pack, publish } from './publish/index.js';
3
+ export { version } from './version/index.js';
package/lib/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { deploy } from './deploy/index.js';
2
2
  export { pack, publish } from './publish/index.js';
3
+ export { version } from './version/index.js';
3
4
  //# sourceMappingURL=index.js.map
@@ -9,6 +9,9 @@ export function executeTokenHelper([cmd, ...args], opts) {
9
9
  opts.globalWarn(`(tokenHelper stderr) ${line}`);
10
10
  }
11
11
  }
12
- return (execResult.stdout?.toString() ?? '').trim();
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/${escapedPackageName}`, registry).href, {
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 escapedPackageName = encodeURIComponent(packageName);
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',
@@ -1,57 +1,14 @@
1
- import { PnpmError } from '@pnpm/error';
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 OtpDate {
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: { Date, setTimeout, enquirer, fetch, globalInfo, process, publish }, manifest, publishOptions, tarballData }: OtpParams): Promise<OtpPublishResponse>;
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>;
@@ -1,165 +1,33 @@
1
- import { PnpmError } from '@pnpm/error';
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: { Date, setTimeout, enquirer, fetch, globalInfo, process, publish, } = SHARED_CONTEXT, manifest, publishOptions, tarballData, }) {
23
- let response;
24
- try {
25
- response = await publish(manifest, tarballData, publishOptions);
26
- }
27
- catch (error) {
28
- if (!isOtpError(error))
29
- throw error;
30
- if (!process.stdin.isTTY || !process.stdout.isTTY) {
31
- throw new OtpNonInteractiveError();
32
- }
33
- const fetchOptions = {
34
- method: 'GET',
35
- retry: {
36
- factor: publishOptions.fetchRetryFactor,
37
- maxTimeout: publishOptions.fetchRetryMaxtimeout,
38
- minTimeout: publishOptions.fetchRetryMintimeout,
39
- retries: publishOptions.fetchRetries,
40
- },
41
- timeout: publishOptions.timeout,
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
@@ -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' | 'rawConfig' | 'embedReadme' | 'packGzipLevel' | 'nodeLinker'> & Partial<Pick<Config, 'extraBinPaths' | 'extraEnv' | 'hooks' | 'recursive' | 'selectedProjectsGraph' | 'workspaceConcurrency' | 'workspaceDir'>> & {
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
  };
@@ -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([
@@ -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, 'allProjects' | 'bin' | 'gitChecks' | 'ignoreScripts' | 'pnpmHomeDir' | 'publishBranch' | 'embedReadme'>, params: string[]): Promise<{
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, 'allProjects' | 'bin' | 'gitChecks' | 'ignoreScripts' | 'pnpmHomeDir' | 'publishBranch' | 'embedReadme' | 'packGzipLevel'>, params: string[]): Promise<PublishResult>;
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>;
@@ -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 AuthConfigKey = 'authToken' | 'authUserPass' | 'tokenHelper';
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, auth, ssl } = findAuthSslInfo(manifest, options);
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: ssl?.ca,
58
- cert: Array.isArray(ssl?.cert) ? ssl.cert.join('\n') : ssl?.cert,
59
- key: ssl?.key,
58
+ ca: tls?.ca,
59
+ cert: tls?.cert,
60
+ key: tls?.key,
60
61
  npmCommand: 'publish',
61
- token: auth && extractToken(auth),
62
- username: auth?.authUserPass?.username,
63
- password: auth?.authUserPass?.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 auth and ssl information according to {@link https://docs.npmjs.com/cli/v10/configuring-npm/npmrc#auth-related-configuration}.
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 findAuthSslInfo({ name }, { authInfos, sslConfigs, registries, ...defaultInfos }) {
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
- const result = { registry };
89
+ let creds;
90
+ let tls = {};
96
91
  for (const registryConfigKey of allRegistryConfigKeys(initialRegistryConfigKey)) {
97
- const auth = authInfos[registryConfigKey];
98
- const ssl = sslConfigs[registryConfigKey];
99
- result.auth ??= auth; // old auth from longer path collectively overrides new auth from shorter path
100
- result.ssl = {
101
- ...ssl,
102
- ...result.ssl, // old ssl from longer path individually overrides new ssl from shorter path
103
- };
104
- }
105
- if (nonNormalizedRegistry !== registries.default &&
106
- registry !== registries.default &&
107
- registry !== parseSupportedRegistryUrl(registries.default)?.normalizedUrl) {
108
- return result;
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
- auth: result.auth ?? defaultInfos, // old auth from longer path collectively overrides default auth
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' | 'cliOptions' | 'dir' | 'pnpmHomeDir' | 'rawConfig' | 'registries' | 'workspaceDir'>> & Partial<Pick<Config, 'tag' | 'ca' | 'catalogs' | 'cert' | 'fetchTimeout' | 'force' | 'dryRun' | 'extraBinPaths' | 'extraEnv' | 'fetchRetries' | 'fetchRetryFactor' | 'fetchRetryMaxtimeout' | 'fetchRetryMintimeout' | 'key' | 'httpProxy' | 'httpsProxy' | 'localAddress' | 'lockfileDir' | 'noProxy' | 'npmPath' | 'offline' | 'selectedProjectsGraph' | 'strictSsl' | 'unsafePerm' | 'userAgent' | 'userConfig' | 'verifyStoreIntegrity'>> & {
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<Config, 'selectedProjectsGraph'>>): Promise<{
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
- authConfig: opts.rawConfig,
15
- userConfig: opts.userConfig,
14
+ configByUri: opts.configByUri,
16
15
  retry: {
17
16
  factor: opts.fetchRetryFactor,
18
17
  maxTimeout: opts.fetchRetryMaxtimeout,
@@ -1,4 +1,5 @@
1
- import { globalInfo } from '@pnpm/logger';
1
+ import readline from 'node:readline';
2
+ import { globalInfo, globalWarn } from '@pnpm/logger';
2
3
  import { fetch } from '@pnpm/network.fetch';
3
4
  import ciInfo from 'ci-info';
4
5
  import enquirer from 'enquirer';
@@ -6,10 +7,12 @@ import { publish as _publish } from 'libnpmpublish';
6
7
  const publish = _publish;
7
8
  export const SHARED_CONTEXT = {
8
9
  Date,
10
+ createReadlineInterface: readline.createInterface.bind(null, { input: process.stdin }),
9
11
  ciInfo,
10
12
  enquirer,
11
13
  fetch,
12
14
  globalInfo,
15
+ globalWarn,
13
16
  process,
14
17
  publish,
15
18
  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": "1000.0.0",
3
+ "version": "1100.0.1",
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": "1000.0.11",
49
- "@pnpm/catalogs.types": "1000.0.0",
50
- "@pnpm/cli.utils": "1001.2.8",
51
- "@pnpm/cli.common-cli-options-help": "1000.0.1",
52
- "@pnpm/config.pick-registry-for-package": "1000.0.11",
53
- "@pnpm/config.reader": "1004.4.2",
54
- "@pnpm/constants": "1001.3.1",
55
- "@pnpm/error": "1000.0.5",
56
- "@pnpm/deps.path": "1001.1.3",
57
- "@pnpm/exec.lifecycle": "1001.0.25",
58
- "@pnpm/fetching.directory-fetcher": "1000.1.14",
59
- "@pnpm/fs.indexed-pkg-importer": "1000.1.14",
60
- "@pnpm/engine.runtime.commands": "1000.0.0-0",
61
- "@pnpm/fs.is-empty-dir-or-nothing": "1000.0.0",
62
- "@pnpm/fs.packlist": "1000.0.0",
63
- "@pnpm/installing.commands": "1004.6.10",
64
- "@pnpm/lockfile.fs": "1001.1.21",
65
- "@pnpm/lockfile.types": "1002.0.2",
66
- "@pnpm/network.fetch": "1000.2.6",
67
- "@pnpm/network.git-utils": "1000.0.0",
68
- "@pnpm/releasing.exportable-manifest": "1000.1.7",
69
- "@pnpm/types": "1000.9.0",
70
- "@pnpm/workspace.projects-sorter": "1000.0.11",
71
- "@pnpm/installing.client": "1001.1.4",
72
- "@pnpm/resolving.resolver-base": "1005.1.0"
49
+ "@pnpm/bins.resolver": "1100.0.1",
50
+ "@pnpm/cli.common-cli-options-help": "1100.0.0",
51
+ "@pnpm/catalogs.types": "1100.0.0",
52
+ "@pnpm/cli.utils": "1100.0.1",
53
+ "@pnpm/config.reader": "1100.0.1",
54
+ "@pnpm/config.pick-registry-for-package": "1100.0.1",
55
+ "@pnpm/deps.path": "1100.0.1",
56
+ "@pnpm/constants": "1100.0.0",
57
+ "@pnpm/error": "1100.0.0",
58
+ "@pnpm/fetching.directory-fetcher": "1100.0.1",
59
+ "@pnpm/exec.lifecycle": "1100.0.1",
60
+ "@pnpm/fs.indexed-pkg-importer": "1100.0.1",
61
+ "@pnpm/engine.runtime.commands": "1100.0.1",
62
+ "@pnpm/fs.is-empty-dir-or-nothing": "1100.0.0",
63
+ "@pnpm/installing.client": "1100.0.1",
64
+ "@pnpm/fs.packlist": "1100.0.0",
65
+ "@pnpm/installing.commands": "1100.0.1",
66
+ "@pnpm/lockfile.types": "1100.0.1",
67
+ "@pnpm/network.fetch": "1100.0.1",
68
+ "@pnpm/lockfile.fs": "1100.0.1",
69
+ "@pnpm/network.git-utils": "1100.0.0",
70
+ "@pnpm/network.web-auth": "1101.0.0",
71
+ "@pnpm/releasing.exportable-manifest": "1100.0.1",
72
+ "@pnpm/types": "1101.0.0",
73
+ "@pnpm/resolving.resolver-base": "1100.0.1",
74
+ "@pnpm/workspace.projects-filter": "1100.0.1",
75
+ "@pnpm/workspace.projects-sorter": "1100.0.1"
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.5",
79
- "@pnpm/registry-mock": "5.2.4",
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/qrcode-terminal": "^0.12.2",
85
- "@types/ramda": "0.29.12",
86
- "@types/tar": "^6.1.13",
87
- "@types/tar-stream": "^2.2.3",
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/catalogs.config": "1000.0.5",
96
- "@pnpm/hooks.pnpmfile": "1002.1.3",
97
- "@pnpm/assert-project": "1000.0.4",
98
- "@pnpm/logger": "1001.0.1",
99
- "@pnpm/releasing.commands": "1000.0.0",
100
- "@pnpm/test-fixtures": "1000.0.0",
101
- "@pnpm/prepare": "1000.0.4",
102
- "@pnpm/test-ipc-server": "1000.0.0",
103
- "@pnpm/workspace.projects-filter": "1000.0.43"
98
+ "@pnpm/assert-project": "1100.0.1",
99
+ "@pnpm/catalogs.config": "1100.0.0",
100
+ "@pnpm/hooks.pnpmfile": "1100.0.1",
101
+ "@pnpm/logger": "1100.0.0",
102
+ "@pnpm/prepare": "1100.0.1",
103
+ "@pnpm/releasing.commands": "1100.0.1",
104
+ "@pnpm/test-fixtures": "1100.0.0",
105
+ "@pnpm/test-ipc-server": "1100.0.0",
106
+ "@pnpm/testing.command-defaults": "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
- "_test": "cross-env NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" jest",
115
- "test": "pnpm run compile && pnpm run _test",
116
- "compile": "tsgo --build && pnpm run lint --fix"
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
  }