@pnpm/registry-access.commands 1100.2.8 → 1100.2.10

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/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as deprecate from './deprecation/deprecate.js';
2
2
  import * as undeprecate from './deprecation/undeprecate.js';
3
3
  import * as distTag from './distTag.js';
4
+ import * as owner from './owner.js';
4
5
  import * as ping from './ping.js';
5
6
  import * as search from './search.js';
6
7
  import * as star from './star/star.js';
@@ -8,4 +9,4 @@ import * as stars from './star/stars.js';
8
9
  import * as unstar from './star/unstar.js';
9
10
  import * as unpublish from './unpublish.js';
10
11
  import * as whoami from './whoami.js';
11
- export { deprecate, distTag, ping, search, star, stars, undeprecate, unpublish, unstar, whoami };
12
+ export { deprecate, distTag, owner, ping, search, star, stars, undeprecate, unpublish, unstar, whoami };
package/lib/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as deprecate from './deprecation/deprecate.js';
2
2
  import * as undeprecate from './deprecation/undeprecate.js';
3
3
  import * as distTag from './distTag.js';
4
+ import * as owner from './owner.js';
4
5
  import * as ping from './ping.js';
5
6
  import * as search from './search.js';
6
7
  import * as star from './star/star.js';
@@ -8,5 +9,5 @@ import * as stars from './star/stars.js';
8
9
  import * as unstar from './star/unstar.js';
9
10
  import * as unpublish from './unpublish.js';
10
11
  import * as whoami from './whoami.js';
11
- export { deprecate, distTag, ping, search, star, stars, undeprecate, unpublish, unstar, whoami };
12
+ export { deprecate, distTag, owner, ping, search, star, stars, undeprecate, unpublish, unstar, whoami };
12
13
  //# sourceMappingURL=index.js.map
package/lib/owner.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { type CreateFetchFromRegistryOptions } from '@pnpm/network.fetch';
2
+ import type { Registries, RegistryConfig } from '@pnpm/types';
3
+ import { rcOptionsTypes } from './common.js';
4
+ export { rcOptionsTypes };
5
+ export declare function cliOptionsTypes(): Record<string, unknown>;
6
+ export declare const commandNames: string[];
7
+ export declare function help(): string;
8
+ export interface OwnerOptions extends CreateFetchFromRegistryOptions {
9
+ cliOptions?: {
10
+ otp?: string;
11
+ };
12
+ configByUri?: Record<string, RegistryConfig>;
13
+ registries?: Registries;
14
+ }
15
+ export declare function handler(opts: OwnerOptions, params: string[]): Promise<string>;
package/lib/owner.js ADDED
@@ -0,0 +1,172 @@
1
+ import { docsUrl } from '@pnpm/cli.utils';
2
+ import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
3
+ import { PnpmError } from '@pnpm/error';
4
+ import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
5
+ import { createFetchFromRegistry } from '@pnpm/network.fetch';
6
+ import { renderHelp } from 'render-help';
7
+ import { parsePackageSpec, rcOptionsTypes } from './common.js';
8
+ export { rcOptionsTypes };
9
+ export function cliOptionsTypes() {
10
+ return {
11
+ ...rcOptionsTypes(),
12
+ otp: String,
13
+ };
14
+ }
15
+ export const commandNames = ['owner', 'owners'];
16
+ export function help() {
17
+ return renderHelp({
18
+ description: 'Manages package owners on the registry.',
19
+ descriptionLists: [
20
+ {
21
+ title: 'Commands',
22
+ list: [
23
+ {
24
+ description: 'List all owners of a package. Default if no subcommand is given.',
25
+ name: 'ls',
26
+ },
27
+ {
28
+ description: 'Add an owner to a package.',
29
+ name: 'add',
30
+ },
31
+ {
32
+ description: 'Remove an owner from a package.',
33
+ name: 'rm',
34
+ },
35
+ ],
36
+ },
37
+ {
38
+ title: 'Options',
39
+ list: [
40
+ {
41
+ description: 'The base URL of the npm registry.',
42
+ name: '--registry <url>',
43
+ },
44
+ {
45
+ description: 'When publishing packages that require two-factor authentication, this option can specify a one-time password.',
46
+ name: '--otp',
47
+ },
48
+ ],
49
+ },
50
+ ],
51
+ url: docsUrl('owner'),
52
+ usages: [
53
+ 'pnpm owner ls <package>',
54
+ 'pnpm owner add <package> <user>',
55
+ 'pnpm owner rm <package> <user>',
56
+ ],
57
+ });
58
+ }
59
+ export async function handler(opts, params) {
60
+ switch (params[0]) {
61
+ case 'add':
62
+ return ownerAdd(opts, params.slice(1));
63
+ case 'rm':
64
+ return ownerRm(opts, params.slice(1));
65
+ case 'ls':
66
+ case 'list':
67
+ return ownerLs(opts, params.slice(1));
68
+ default:
69
+ return ownerLs(opts, params);
70
+ }
71
+ }
72
+ async function ownerLs(opts, params) {
73
+ if (params.length === 0) {
74
+ throw new PnpmError('OWNER_LS_PACKAGE_REQUIRED', 'Package name is required');
75
+ }
76
+ const { name: packageName, escapedName } = parsePackageSpec(params[0]);
77
+ const registryUrl = pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, packageName);
78
+ const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl);
79
+ const fetchFromRegistry = createFetchFromRegistry(opts);
80
+ const owners = await fetchOwners(packageName, escapedName, registryUrl, fetchFromRegistry, authHeader);
81
+ const lines = [];
82
+ for (const owner of owners) {
83
+ lines.push(`${owner.username} <${owner.email}>`);
84
+ }
85
+ return lines.join('\n');
86
+ }
87
+ async function ownerAdd(opts, params) {
88
+ if (params.length < 2) {
89
+ throw new PnpmError('OWNER_ADD_ARGS_REQUIRED', 'Package name and owner are required (e.g., pnpm owner add pkg username)');
90
+ }
91
+ const { name: packageName, escapedName } = parsePackageSpec(params[0]);
92
+ const owner = params[1];
93
+ const registryUrl = pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, packageName);
94
+ const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl);
95
+ const fetchFromRegistry = createFetchFromRegistry(opts);
96
+ const otp = opts.cliOptions?.otp;
97
+ const ownerUrl = getOwnerUrl(escapedName, registryUrl);
98
+ const response = await fetchFromRegistry(ownerUrl, {
99
+ authHeaderValue: authHeader,
100
+ method: 'PUT',
101
+ headers: {
102
+ 'content-type': 'application/json',
103
+ ...(otp ? { 'npm-otp': otp } : {}),
104
+ },
105
+ body: JSON.stringify({ user: owner }),
106
+ });
107
+ if (!response.ok) {
108
+ await throwRegistryError(response, `add owner "${owner}" to`);
109
+ }
110
+ return `+${owner}: ${packageName}`;
111
+ }
112
+ async function ownerRm(opts, params) {
113
+ if (params.length < 2) {
114
+ throw new PnpmError('OWNER_RM_ARGS_REQUIRED', 'Package name and owner are required (e.g., pnpm owner rm pkg username)');
115
+ }
116
+ const { name: packageName, escapedName } = parsePackageSpec(params[0]);
117
+ const owner = params[1];
118
+ const registryUrl = pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, packageName);
119
+ const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl);
120
+ const fetchFromRegistry = createFetchFromRegistry(opts);
121
+ const otp = opts.cliOptions?.otp;
122
+ const ownerUrl = getOwnerUrl(escapedName, registryUrl, owner);
123
+ const response = await fetchFromRegistry(ownerUrl, {
124
+ authHeaderValue: authHeader,
125
+ method: 'DELETE',
126
+ headers: {
127
+ ...(otp ? { 'npm-otp': otp } : {}),
128
+ },
129
+ });
130
+ if (!response.ok) {
131
+ await throwRegistryError(response, `remove owner "${owner}" from`);
132
+ }
133
+ return `-${owner}: ${packageName}`;
134
+ }
135
+ function getAuthHeaderForRegistry(configByUri, registryUrl) {
136
+ const getAuthHeader = createGetAuthHeaderByURI(configByUri ?? {}, registryUrl);
137
+ return getAuthHeader(registryUrl);
138
+ }
139
+ function getOwnerUrl(escapedName, registryUrl, owner) {
140
+ const base = new URL(`-/package/${escapedName}/owners`, registryUrl).href;
141
+ if (owner) {
142
+ return `${base}/${encodeURIComponent(owner)}`;
143
+ }
144
+ return base;
145
+ }
146
+ async function fetchOwners(packageName, escapedName, registryUrl, fetchFromRegistry, authHeader) {
147
+ const ownersUrl = new URL(`-/package/${escapedName}/owners`, registryUrl).href;
148
+ const response = await fetchFromRegistry(ownersUrl, {
149
+ authHeaderValue: authHeader,
150
+ });
151
+ if (!response.ok) {
152
+ if (response.status === 404) {
153
+ throw new PnpmError('PACKAGE_NOT_FOUND', `Package "${packageName}" not found in registry`);
154
+ }
155
+ throw new PnpmError('REGISTRY_ERROR', `Failed to fetch owners: ${response.status} ${response.statusText}`);
156
+ }
157
+ return await response.json();
158
+ }
159
+ async function throwRegistryError(response, action) {
160
+ const errorBody = await response.text();
161
+ if (response.status === 401) {
162
+ throw new PnpmError('UNAUTHORIZED', `You must be logged in to ${action} packages. ${errorBody}`);
163
+ }
164
+ if (response.status === 403) {
165
+ throw new PnpmError('FORBIDDEN', `You do not have permission to ${action} this package. ${errorBody}`);
166
+ }
167
+ if (response.status === 404) {
168
+ throw new PnpmError('PACKAGE_NOT_FOUND', `Package not found in registry. ${errorBody}`);
169
+ }
170
+ throw new PnpmError('REGISTRY_ERROR', `Failed to ${action} package: ${response.status} ${response.statusText}. ${errorBody}`);
171
+ }
172
+ //# sourceMappingURL=owner.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/registry-access.commands",
3
- "version": "1100.2.8",
3
+ "version": "1100.2.10",
4
4
  "description": "Commands for managing packages on the registry",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -25,18 +25,18 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "@pnpm/npm-package-arg": "^2.0.0",
28
- "chalk": "^5.6.2",
28
+ "chalk": "^5.6.0",
29
29
  "ramda": "npm:@pnpm/ramda@0.28.1",
30
30
  "render-help": "^2.0.0",
31
- "semver": "^7.7.4",
32
- "@pnpm/cli.utils": "1101.0.2",
33
- "@pnpm/config.pick-registry-for-package": "1100.0.2",
31
+ "semver": "^7.7.2",
32
+ "@pnpm/cli.utils": "1101.0.3",
33
+ "@pnpm/config.reader": "1101.3.0",
34
+ "@pnpm/config.pick-registry-for-package": "1100.0.3",
34
35
  "@pnpm/error": "1100.0.0",
35
- "@pnpm/config.reader": "1101.2.1",
36
- "@pnpm/network.auth-header": "1100.0.1",
37
- "@pnpm/network.fetch": "1100.0.2",
38
- "@pnpm/resolving.registry.types": "1100.0.2",
39
- "@pnpm/types": "1101.0.0"
36
+ "@pnpm/network.auth-header": "1100.0.2",
37
+ "@pnpm/network.fetch": "1100.0.3",
38
+ "@pnpm/resolving.registry.types": "1100.0.3",
39
+ "@pnpm/types": "1101.1.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@jest/globals": "30.3.0",
@@ -44,11 +44,11 @@
44
44
  "@types/ramda": "0.31.1",
45
45
  "@types/semver": "7.7.1",
46
46
  "execa": "npm:safe-execa@0.3.0",
47
- "@pnpm/prepare": "1100.0.5",
48
- "@pnpm/releasing.commands": "1100.2.9",
49
- "@pnpm/registry-access.commands": "1100.2.8",
47
+ "@pnpm/registry-access.commands": "1100.2.10",
48
+ "@pnpm/prepare": "1100.0.7",
49
+ "@pnpm/releasing.commands": "1100.2.12",
50
50
  "@pnpm/testing.command-defaults": "1100.0.1",
51
- "@pnpm/testing.mock-agent": "1100.0.2"
51
+ "@pnpm/testing.mock-agent": "1100.0.3"
52
52
  },
53
53
  "engines": {
54
54
  "node": ">=22.13"