@pnpm/registry-access.commands 1100.2.15 → 1100.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,7 +14,7 @@ export function cliOptionsTypes() {
14
14
  }
15
15
  export async function updateDeprecation(opts, { deprecated, packageName, versionRange }) {
16
16
  const registryUrl = pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, packageName);
17
- const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {}, registryUrl);
17
+ const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {});
18
18
  const authHeader = getAuthHeader(registryUrl);
19
19
  const packageUrl = new URL(npa(packageName).escapedName, registryUrl).href;
20
20
  const fetchFromRegistry = createFetchFromRegistry(opts);
package/lib/distTag.js CHANGED
@@ -1,9 +1,14 @@
1
+ import readline from 'node:readline';
2
+ import { input } from '@inquirer/prompts';
1
3
  import { docsUrl } from '@pnpm/cli.utils';
2
4
  import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
3
5
  import { PnpmError } from '@pnpm/error';
6
+ import { globalInfo, globalWarn } from '@pnpm/logger';
4
7
  import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
5
8
  import { createFetchFromRegistry } from '@pnpm/network.fetch';
9
+ import { SyntheticOtpError, withOtpHandling, } from '@pnpm/network.web-auth';
6
10
  import npa from '@pnpm/npm-package-arg';
11
+ import { setDistTag } from '@pnpm/registry-access.client';
7
12
  import { renderHelp } from 'render-help';
8
13
  import semver from 'semver';
9
14
  import { parsePackageSpec, rcOptionsTypes } from './common.js';
@@ -102,20 +107,22 @@ async function distTagAdd(opts, params) {
102
107
  const registryUrl = pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, packageName);
103
108
  const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl);
104
109
  const fetchFromRegistry = createFetchFromRegistry(opts);
105
- const otp = opts.cliOptions?.otp;
106
- const distTagUrl = getDistTagUrl(packageName, registryUrl, tag);
107
- const response = await fetchFromRegistry(distTagUrl, {
108
- authHeaderValue: authHeader,
109
- method: 'PUT',
110
- headers: {
111
- 'content-type': 'application/json',
112
- ...(otp ? { 'npm-otp': otp } : {}),
113
- },
114
- body: JSON.stringify(version),
110
+ const cliOtp = opts.cliOptions?.otp;
111
+ const authType = cliOtp ? 'legacy' : 'web';
112
+ await withOtpHandling({
113
+ context: createOtpContext(opts),
114
+ fetchOptions: WEB_AUTH_FETCH_OPTIONS,
115
+ operation: (otp) => setDistTag({
116
+ packageName,
117
+ version,
118
+ distTag: tag,
119
+ registryUrl,
120
+ authHeader,
121
+ authType,
122
+ fetchFromRegistry,
123
+ otp: otp ?? cliOtp,
124
+ }),
115
125
  });
116
- if (!response.ok) {
117
- await throwRegistryError(response, `set dist-tag "${tag}" on`);
118
- }
119
126
  return `+${tag}: ${packageName}@${version}`;
120
127
  }
121
128
  async function distTagRm(opts, params) {
@@ -130,27 +137,70 @@ async function distTagRm(opts, params) {
130
137
  const registryUrl = pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, packageName);
131
138
  const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl);
132
139
  const fetchFromRegistry = createFetchFromRegistry(opts);
133
- const otp = opts.cliOptions?.otp;
140
+ const cliOtp = opts.cliOptions?.otp;
134
141
  // First check the tag exists
135
142
  const distTags = await fetchDistTags(packageName, registryUrl, fetchFromRegistry, authHeader);
136
143
  if (!(tag in distTags)) {
137
144
  throw new PnpmError('DIST_TAG_NOT_FOUND', `dist-tag "${tag}" is not set on package "${packageName}"`);
138
145
  }
139
146
  const distTagUrl = getDistTagUrl(packageName, registryUrl, tag);
147
+ const authType = cliOtp ? 'legacy' : 'web';
148
+ await withOtpHandling({
149
+ context: createOtpContext(opts),
150
+ fetchOptions: WEB_AUTH_FETCH_OPTIONS,
151
+ operation: (otp) => deleteDistTag({
152
+ authHeader,
153
+ authType,
154
+ distTagUrl,
155
+ fetchFromRegistry,
156
+ otp: otp ?? cliOtp,
157
+ tag,
158
+ }),
159
+ });
160
+ return `-${tag}: ${packageName}@${distTags[tag]}`;
161
+ }
162
+ async function deleteDistTag({ authHeader, authType, distTagUrl, fetchFromRegistry, otp, tag, }) {
140
163
  const response = await fetchFromRegistry(distTagUrl, {
141
164
  authHeaderValue: authHeader,
142
165
  method: 'DELETE',
143
166
  headers: {
167
+ 'npm-auth-type': authType,
144
168
  ...(otp ? { 'npm-otp': otp } : {}),
145
169
  },
146
170
  });
147
- if (!response.ok) {
148
- await throwRegistryError(response, `remove dist-tag "${tag}" from`);
171
+ if (response.ok)
172
+ return;
173
+ const body = await response.text();
174
+ const action = `remove dist-tag "${tag}" from`;
175
+ if (response.status === 401) {
176
+ throw parseAuthError(body, action);
149
177
  }
150
- return `-${tag}: ${packageName}@${distTags[tag]}`;
178
+ if (response.status === 403) {
179
+ throw new PnpmError('FORBIDDEN', `You do not have permission to ${action} this package. ${body}`);
180
+ }
181
+ throw new PnpmError('REGISTRY_ERROR', `Failed to ${action} package: ${response.status} ${response.statusText}. ${body}`);
182
+ }
183
+ function parseAuthError(body, action) {
184
+ let parsed;
185
+ try {
186
+ parsed = JSON.parse(body);
187
+ }
188
+ catch {
189
+ parsed = undefined;
190
+ }
191
+ if (parsed != null && typeof parsed === 'object' && 'authUrl' in parsed && 'doneUrl' in parsed) {
192
+ return new SyntheticOtpError({
193
+ authUrl: typeof parsed.authUrl === 'string' ? parsed.authUrl : undefined,
194
+ doneUrl: typeof parsed.doneUrl === 'string' ? parsed.doneUrl : undefined,
195
+ });
196
+ }
197
+ if (/one-time pass/i.test(body)) {
198
+ return new SyntheticOtpError(undefined);
199
+ }
200
+ return new PnpmError('UNAUTHORIZED', `You must be logged in to ${action} packages. ${body}`);
151
201
  }
152
202
  function getAuthHeaderForRegistry(configByUri, registryUrl) {
153
- const getAuthHeader = createGetAuthHeaderByURI(configByUri ?? {}, registryUrl);
203
+ const getAuthHeader = createGetAuthHeaderByURI(configByUri ?? {});
154
204
  return getAuthHeader(registryUrl);
155
205
  }
156
206
  function getDistTagUrl(packageName, registryUrl, tag) {
@@ -171,14 +221,22 @@ async function fetchDistTags(packageName, registryUrl, fetchFromRegistry, authHe
171
221
  }
172
222
  return await response.json();
173
223
  }
174
- async function throwRegistryError(response, action) {
175
- const errorBody = await response.text();
176
- if (response.status === 401) {
177
- throw new PnpmError('UNAUTHORIZED', `You must be logged in to ${action} packages. ${errorBody}`);
178
- }
179
- if (response.status === 403) {
180
- throw new PnpmError('FORBIDDEN', `You do not have permission to ${action} this package. ${errorBody}`);
181
- }
182
- throw new PnpmError('REGISTRY_ERROR', `Failed to ${action} package: ${response.status} ${response.statusText}. ${errorBody}`);
224
+ const WEB_AUTH_FETCH_OPTIONS = {
225
+ method: 'GET',
226
+ };
227
+ // `withOtpHandling` polls `doneUrl` through `context.fetch`, so it must inherit
228
+ // the command's proxy/TLS/`configByUri` config — otherwise the write succeeds
229
+ // but the web-auth retry fails in custom-network environments.
230
+ function createOtpContext(opts) {
231
+ return {
232
+ Date,
233
+ createReadlineInterface: readline.createInterface.bind(null, { input: process.stdin }),
234
+ enquirer: { input },
235
+ fetch: createFetchFromRegistry(opts),
236
+ globalInfo,
237
+ globalWarn,
238
+ process,
239
+ setTimeout,
240
+ };
183
241
  }
184
242
  //# sourceMappingURL=distTag.js.map
package/lib/owner.js CHANGED
@@ -133,7 +133,7 @@ async function ownerRm(opts, params) {
133
133
  return `-${owner}: ${packageName}`;
134
134
  }
135
135
  function getAuthHeaderForRegistry(configByUri, registryUrl) {
136
- const getAuthHeader = createGetAuthHeaderByURI(configByUri ?? {}, registryUrl);
136
+ const getAuthHeader = createGetAuthHeaderByURI(configByUri ?? {});
137
137
  return getAuthHeader(registryUrl);
138
138
  }
139
139
  function getOwnerUrl(escapedName, registryUrl, owner) {
package/lib/ping.js CHANGED
@@ -38,7 +38,7 @@ export async function handler(opts) {
38
38
  const pingUrlObject = new URL('./-/ping', normalizedRegistryUrl);
39
39
  pingUrlObject.searchParams.set('write', 'true');
40
40
  const pingUrl = pingUrlObject.toString();
41
- const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {}, normalizedRegistryUrl);
41
+ const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {});
42
42
  const authHeaderValue = getAuthHeader(normalizedRegistryUrl);
43
43
  const fetchFromRegistry = createFetchFromRegistry(opts);
44
44
  const start = Date.now();
package/lib/search.js CHANGED
@@ -52,7 +52,7 @@ export async function handler(opts, params) {
52
52
  searchUrl.searchParams.set('text', query);
53
53
  searchUrl.searchParams.set('size', (opts.searchLimit ?? 20).toString());
54
54
  const fetchFromRegistry = createFetchFromRegistry(opts);
55
- const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {}, opts.registries?.default);
55
+ const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {});
56
56
  const response = await fetchFromRegistry(searchUrl.toString(), {
57
57
  authHeaderValue: getAuthHeader(registry),
58
58
  });
@@ -87,7 +87,7 @@ async function performLegacyStarAction(args) {
87
87
  }
88
88
  }
89
89
  export function getAuthHeaderForRegistry(configByUri, registryUrl) {
90
- const getAuthHeader = createGetAuthHeaderByURI(configByUri ?? {}, registryUrl);
90
+ const getAuthHeader = createGetAuthHeaderByURI(configByUri ?? {});
91
91
  return getAuthHeader(registryUrl);
92
92
  }
93
93
  //# sourceMappingURL=common.js.map
package/lib/unpublish.js CHANGED
@@ -54,7 +54,7 @@ export async function handler(opts, params) {
54
54
  }
55
55
  async function unpublishPackage(packageName, versionRange, opts) {
56
56
  const registryUrl = pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, packageName);
57
- const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {}, registryUrl);
57
+ const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {});
58
58
  const authHeader = getAuthHeader(registryUrl);
59
59
  const packageUrl = new URL(npa(packageName).escapedName, registryUrl).href;
60
60
  const fetchFromRegistry = createFetchFromRegistry(opts);
package/lib/whoami.js CHANGED
@@ -22,7 +22,7 @@ export function help() {
22
22
  }
23
23
  export async function handler(opts) {
24
24
  const registryUrl = normalizeRegistryUrl(opts.registries?.default ?? 'https://registry.npmjs.org/');
25
- const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {}, registryUrl);
25
+ const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {});
26
26
  const authHeader = getAuthHeader(registryUrl);
27
27
  if (!authHeader) {
28
28
  throw new PnpmError('WHOAMI_UNAUTHORIZED', 'You must be logged in to use whoami');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/registry-access.commands",
3
- "version": "1100.2.15",
3
+ "version": "1100.3.0",
4
4
  "description": "Commands for managing packages on the registry",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -24,31 +24,38 @@
24
24
  "!*.map"
25
25
  ],
26
26
  "dependencies": {
27
+ "@inquirer/prompts": "^8.4.3",
27
28
  "@pnpm/npm-package-arg": "^2.0.0",
28
- "chalk": "^5.6.0",
29
+ "chalk": "^5.6.2",
29
30
  "ramda": "npm:@pnpm/ramda@0.28.1",
30
31
  "render-help": "^2.0.0",
31
- "semver": "^7.7.2",
32
- "@pnpm/cli.utils": "1101.0.7",
33
- "@pnpm/config.reader": "1101.4.0",
32
+ "semver": "^7.8.1",
33
+ "@pnpm/cli.utils": "1101.0.8",
34
+ "@pnpm/config.pick-registry-for-package": "1100.0.6",
35
+ "@pnpm/config.reader": "1101.5.0",
34
36
  "@pnpm/error": "1100.0.0",
35
- "@pnpm/config.pick-registry-for-package": "1100.0.5",
36
- "@pnpm/network.auth-header": "1100.0.3",
37
- "@pnpm/resolving.registry.types": "1100.0.4",
38
- "@pnpm/types": "1101.1.1",
39
- "@pnpm/network.fetch": "1100.0.6"
37
+ "@pnpm/network.auth-header": "1101.0.0",
38
+ "@pnpm/network.fetch": "1100.0.8",
39
+ "@pnpm/network.web-auth": "1101.1.0",
40
+ "@pnpm/registry-access.client": "1100.1.0",
41
+ "@pnpm/types": "1101.2.0",
42
+ "@pnpm/resolving.registry.types": "1100.1.0"
43
+ },
44
+ "peerDependencies": {
45
+ "@pnpm/logger": "^1001.0.1"
40
46
  },
41
47
  "devDependencies": {
42
48
  "@jest/globals": "30.3.0",
43
- "@pnpm/registry-mock": "6.0.0",
44
49
  "@types/ramda": "0.31.1",
45
50
  "@types/semver": "7.7.1",
46
51
  "execa": "npm:safe-execa@0.3.0",
47
- "@pnpm/prepare": "1100.0.10",
48
- "@pnpm/registry-access.commands": "1100.2.15",
49
- "@pnpm/releasing.commands": "1100.3.0",
50
- "@pnpm/testing.command-defaults": "1100.0.1",
51
- "@pnpm/testing.mock-agent": "1100.0.6"
52
+ "@pnpm/logger": "1100.0.0",
53
+ "@pnpm/prepare": "1100.0.12",
54
+ "@pnpm/registry-access.commands": "1100.3.0",
55
+ "@pnpm/releasing.commands": "1100.4.0",
56
+ "@pnpm/testing.command-defaults": "1100.0.2",
57
+ "@pnpm/testing.registry-mock": "1100.0.2",
58
+ "@pnpm/testing.mock-agent": "1100.0.8"
52
59
  },
53
60
  "engines": {
54
61
  "node": ">=22.13"