@pnpm/registry-access.commands 1100.2.16 → 1100.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/distTag.js +83 -22
- package/package.json +25 -16
package/lib/distTag.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
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';
|
|
7
11
|
import { setDistTag } from '@pnpm/registry-access.client';
|
|
8
12
|
import { renderHelp } from 'render-help';
|
|
@@ -103,15 +107,21 @@ async function distTagAdd(opts, params) {
|
|
|
103
107
|
const registryUrl = pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, packageName);
|
|
104
108
|
const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl);
|
|
105
109
|
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
126
|
return `+${tag}: ${packageName}@${version}`;
|
|
117
127
|
}
|
|
@@ -127,24 +137,67 @@ async function distTagRm(opts, params) {
|
|
|
127
137
|
const registryUrl = pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, packageName);
|
|
128
138
|
const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl);
|
|
129
139
|
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
130
|
-
const
|
|
140
|
+
const cliOtp = opts.cliOptions?.otp;
|
|
131
141
|
// First check the tag exists
|
|
132
142
|
const distTags = await fetchDistTags(packageName, registryUrl, fetchFromRegistry, authHeader);
|
|
133
143
|
if (!(tag in distTags)) {
|
|
134
144
|
throw new PnpmError('DIST_TAG_NOT_FOUND', `dist-tag "${tag}" is not set on package "${packageName}"`);
|
|
135
145
|
}
|
|
136
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, }) {
|
|
137
163
|
const response = await fetchFromRegistry(distTagUrl, {
|
|
138
164
|
authHeaderValue: authHeader,
|
|
139
165
|
method: 'DELETE',
|
|
140
166
|
headers: {
|
|
167
|
+
'npm-auth-type': authType,
|
|
141
168
|
...(otp ? { 'npm-otp': otp } : {}),
|
|
142
169
|
},
|
|
143
170
|
});
|
|
144
|
-
if (
|
|
145
|
-
|
|
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);
|
|
146
177
|
}
|
|
147
|
-
|
|
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}`);
|
|
148
201
|
}
|
|
149
202
|
function getAuthHeaderForRegistry(configByUri, registryUrl) {
|
|
150
203
|
const getAuthHeader = createGetAuthHeaderByURI(configByUri ?? {});
|
|
@@ -168,14 +221,22 @@ async function fetchDistTags(packageName, registryUrl, fetchFromRegistry, authHe
|
|
|
168
221
|
}
|
|
169
222
|
return await response.json();
|
|
170
223
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
+
};
|
|
180
241
|
}
|
|
181
242
|
//# sourceMappingURL=distTag.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/registry-access.commands",
|
|
3
|
-
"version": "1100.
|
|
3
|
+
"version": "1100.3.1",
|
|
4
4
|
"description": "Commands for managing packages on the registry",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
],
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"funding": "https://opencollective.com/pnpm",
|
|
11
|
-
"repository":
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/pnpm/pnpm/tree/main/registry-access/commands"
|
|
14
|
+
},
|
|
12
15
|
"homepage": "https://github.com/pnpm/pnpm/tree/main/registry-access/commands#readme",
|
|
13
16
|
"bugs": {
|
|
14
17
|
"url": "https://github.com/pnpm/pnpm/issues"
|
|
@@ -24,32 +27,38 @@
|
|
|
24
27
|
"!*.map"
|
|
25
28
|
],
|
|
26
29
|
"dependencies": {
|
|
30
|
+
"@inquirer/prompts": "^8.4.3",
|
|
27
31
|
"@pnpm/npm-package-arg": "^2.0.0",
|
|
28
32
|
"chalk": "^5.6.2",
|
|
29
33
|
"ramda": "npm:@pnpm/ramda@0.28.1",
|
|
30
34
|
"render-help": "^2.0.0",
|
|
31
35
|
"semver": "^7.8.1",
|
|
32
|
-
"@pnpm/
|
|
33
|
-
"@pnpm/
|
|
36
|
+
"@pnpm/config.reader": "1101.6.0",
|
|
37
|
+
"@pnpm/network.auth-header": "1101.1.0",
|
|
38
|
+
"@pnpm/network.fetch": "1100.1.0",
|
|
34
39
|
"@pnpm/error": "1100.0.0",
|
|
35
|
-
"@pnpm/config.
|
|
36
|
-
"@pnpm/
|
|
37
|
-
"@pnpm/registry
|
|
38
|
-
"@pnpm/
|
|
39
|
-
"@pnpm/
|
|
40
|
-
"@pnpm/
|
|
40
|
+
"@pnpm/config.pick-registry-for-package": "1100.0.7",
|
|
41
|
+
"@pnpm/cli.utils": "1101.0.9",
|
|
42
|
+
"@pnpm/resolving.registry.types": "1100.1.1",
|
|
43
|
+
"@pnpm/types": "1101.3.0",
|
|
44
|
+
"@pnpm/network.web-auth": "1101.1.0",
|
|
45
|
+
"@pnpm/registry-access.client": "1100.1.1"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@pnpm/logger": "^1001.0.1"
|
|
41
49
|
},
|
|
42
50
|
"devDependencies": {
|
|
43
51
|
"@jest/globals": "30.3.0",
|
|
44
|
-
"@pnpm/registry-mock": "6.0.0",
|
|
45
52
|
"@types/ramda": "0.31.1",
|
|
46
53
|
"@types/semver": "7.7.1",
|
|
47
54
|
"execa": "npm:safe-execa@0.3.0",
|
|
48
|
-
"@pnpm/prepare": "1100.0.
|
|
49
|
-
"@pnpm/registry-access.commands": "1100.
|
|
50
|
-
"@pnpm/
|
|
51
|
-
"@pnpm/releasing.commands": "1100.
|
|
52
|
-
"@pnpm/testing.
|
|
55
|
+
"@pnpm/prepare": "1100.0.13",
|
|
56
|
+
"@pnpm/registry-access.commands": "1100.3.1",
|
|
57
|
+
"@pnpm/logger": "1100.0.0",
|
|
58
|
+
"@pnpm/releasing.commands": "1100.4.2",
|
|
59
|
+
"@pnpm/testing.mock-agent": "1101.0.0",
|
|
60
|
+
"@pnpm/testing.command-defaults": "1100.0.3",
|
|
61
|
+
"@pnpm/testing.registry-mock": "1100.0.3"
|
|
53
62
|
},
|
|
54
63
|
"engines": {
|
|
55
64
|
"node": ">=22.13"
|