@pnpm/registry-access.commands 1100.0.0 → 1100.2.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/common.d.ts +2 -0
- package/lib/common.js +5 -2
- package/lib/index.d.ts +7 -1
- package/lib/index.js +7 -1
- package/lib/ping.d.ts +12 -0
- package/lib/ping.js +78 -0
- package/lib/search.d.ts +33 -0
- package/lib/search.js +100 -0
- package/lib/star/common.d.ts +15 -0
- package/lib/star/common.js +93 -0
- package/lib/star/star.d.ts +5 -0
- package/lib/star/star.js +20 -0
- package/lib/star/stars.d.ts +5 -0
- package/lib/star/stars.js +61 -0
- package/lib/star/unstar.d.ts +5 -0
- package/lib/star/unstar.js +20 -0
- package/lib/whoami.d.ts +12 -0
- package/lib/whoami.js +43 -0
- package/package.json +14 -12
package/lib/common.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
2
2
|
export declare function parsePackageSpec(spec: string): {
|
|
3
3
|
name: string;
|
|
4
|
+
escapedName: string;
|
|
4
5
|
versionRange: string | undefined;
|
|
5
6
|
};
|
|
7
|
+
export declare function normalizeRegistryUrl(registryUrl: string): string;
|
package/lib/common.js
CHANGED
|
@@ -15,10 +15,13 @@ export function parsePackageSpec(spec) {
|
|
|
15
15
|
catch {
|
|
16
16
|
throw new PnpmError('INVALID_PACKAGE_SPEC', `Invalid package spec: ${spec}`);
|
|
17
17
|
}
|
|
18
|
-
if (!parsed.name) {
|
|
18
|
+
if (!parsed.name || !parsed.escapedName) {
|
|
19
19
|
throw new PnpmError('INVALID_PACKAGE_SPEC', `Invalid package spec: ${spec}`);
|
|
20
20
|
}
|
|
21
21
|
const versionRange = parsed.rawSpec || undefined;
|
|
22
|
-
return { name: parsed.name, versionRange };
|
|
22
|
+
return { name: parsed.name, escapedName: parsed.escapedName, versionRange };
|
|
23
|
+
}
|
|
24
|
+
export function normalizeRegistryUrl(registryUrl) {
|
|
25
|
+
return registryUrl.endsWith('/') ? registryUrl : `${registryUrl}/`;
|
|
23
26
|
}
|
|
24
27
|
//# sourceMappingURL=common.js.map
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
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 ping from './ping.js';
|
|
5
|
+
import * as search from './search.js';
|
|
6
|
+
import * as star from './star/star.js';
|
|
7
|
+
import * as stars from './star/stars.js';
|
|
8
|
+
import * as unstar from './star/unstar.js';
|
|
4
9
|
import * as unpublish from './unpublish.js';
|
|
5
|
-
|
|
10
|
+
import * as whoami from './whoami.js';
|
|
11
|
+
export { deprecate, distTag, ping, search, star, stars, undeprecate, unpublish, unstar, whoami };
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
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 ping from './ping.js';
|
|
5
|
+
import * as search from './search.js';
|
|
6
|
+
import * as star from './star/star.js';
|
|
7
|
+
import * as stars from './star/stars.js';
|
|
8
|
+
import * as unstar from './star/unstar.js';
|
|
4
9
|
import * as unpublish from './unpublish.js';
|
|
5
|
-
|
|
10
|
+
import * as whoami from './whoami.js';
|
|
11
|
+
export { deprecate, distTag, ping, search, star, stars, undeprecate, unpublish, unstar, whoami };
|
|
6
12
|
//# sourceMappingURL=index.js.map
|
package/lib/ping.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CreateFetchFromRegistryOptions } from '@pnpm/network.fetch';
|
|
2
|
+
import type { Registries, RegistryConfig } from '@pnpm/types';
|
|
3
|
+
export declare function cliOptionsTypes(): Record<string, unknown>;
|
|
4
|
+
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
5
|
+
export interface PingOptions extends CreateFetchFromRegistryOptions {
|
|
6
|
+
registry?: string;
|
|
7
|
+
registries?: Registries;
|
|
8
|
+
configByUri?: Record<string, RegistryConfig>;
|
|
9
|
+
}
|
|
10
|
+
export declare const commandNames: string[];
|
|
11
|
+
export declare function help(): string;
|
|
12
|
+
export declare function handler(opts: PingOptions): Promise<string>;
|
package/lib/ping.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import util from 'node:util';
|
|
2
|
+
import { docsUrl } from '@pnpm/cli.utils';
|
|
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 { rcOptionsTypes as commonRcOptionsTypes } from './common.js';
|
|
8
|
+
export function cliOptionsTypes() {
|
|
9
|
+
return {
|
|
10
|
+
...commonRcOptionsTypes(),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function rcOptionsTypes() {
|
|
14
|
+
return commonRcOptionsTypes();
|
|
15
|
+
}
|
|
16
|
+
export const commandNames = ['ping'];
|
|
17
|
+
export function help() {
|
|
18
|
+
return renderHelp({
|
|
19
|
+
description: 'Test connectivity to the configured registry.',
|
|
20
|
+
descriptionLists: [
|
|
21
|
+
{
|
|
22
|
+
title: 'Options',
|
|
23
|
+
list: [
|
|
24
|
+
{
|
|
25
|
+
description: 'Test a specific registry URL',
|
|
26
|
+
name: '--registry <url>',
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
url: docsUrl('ping'),
|
|
32
|
+
usages: ['pnpm ping [--registry <url>]'],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export async function handler(opts) {
|
|
36
|
+
const registryUrl = opts.registry ?? opts.registries?.default ?? 'https://registry.npmjs.org/';
|
|
37
|
+
const normalizedRegistryUrl = registryUrl.endsWith('/') ? registryUrl : `${registryUrl}/`;
|
|
38
|
+
const pingUrlObject = new URL('./-/ping', normalizedRegistryUrl);
|
|
39
|
+
pingUrlObject.searchParams.set('write', 'true');
|
|
40
|
+
const pingUrl = pingUrlObject.toString();
|
|
41
|
+
const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {}, normalizedRegistryUrl);
|
|
42
|
+
const authHeaderValue = getAuthHeader(normalizedRegistryUrl);
|
|
43
|
+
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
44
|
+
const start = Date.now();
|
|
45
|
+
let response;
|
|
46
|
+
try {
|
|
47
|
+
response = await fetchFromRegistry(pingUrl, {
|
|
48
|
+
retry: { retries: 0 },
|
|
49
|
+
authHeaderValue,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
const errorMessage = util.types.isNativeError(err) ? err.message : String(err);
|
|
54
|
+
throw new PnpmError('PING_ERROR', `Failed to reach registry: ${errorMessage}`);
|
|
55
|
+
}
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
throw new PnpmError('PING_ERROR', `Failed to reach registry: ${response.status} ${response.statusText}`.trimEnd());
|
|
58
|
+
}
|
|
59
|
+
const body = await response.text();
|
|
60
|
+
const time = Date.now() - start;
|
|
61
|
+
let details = '';
|
|
62
|
+
if (body) {
|
|
63
|
+
try {
|
|
64
|
+
const parsed = JSON.parse(body);
|
|
65
|
+
if (parsed && typeof parsed === 'object' && Object.keys(parsed).length > 0) {
|
|
66
|
+
details = JSON.stringify(parsed, null, 2);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// non-JSON body — ignore
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const lines = [`PING ${registryUrl}`, `PONG ${time}ms`];
|
|
74
|
+
if (details)
|
|
75
|
+
lines.push(`PONG ${details}`);
|
|
76
|
+
return lines.join('\n');
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=ping.js.map
|
package/lib/search.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
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 SearchPackage {
|
|
9
|
+
name: string;
|
|
10
|
+
version: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
date?: string;
|
|
13
|
+
author?: {
|
|
14
|
+
name: string;
|
|
15
|
+
} | string;
|
|
16
|
+
publisher?: {
|
|
17
|
+
username: string;
|
|
18
|
+
};
|
|
19
|
+
maintainers?: Array<{
|
|
20
|
+
username: string;
|
|
21
|
+
}>;
|
|
22
|
+
keywords?: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface SearchResult {
|
|
25
|
+
package: SearchPackage;
|
|
26
|
+
}
|
|
27
|
+
export interface SearchOptions extends CreateFetchFromRegistryOptions {
|
|
28
|
+
configByUri?: Record<string, RegistryConfig>;
|
|
29
|
+
registries?: Registries;
|
|
30
|
+
json?: boolean;
|
|
31
|
+
searchLimit?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare function handler(opts: SearchOptions, params: string[]): Promise<string>;
|
package/lib/search.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { docsUrl } from '@pnpm/cli.utils';
|
|
2
|
+
import { PnpmError } from '@pnpm/error';
|
|
3
|
+
import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
|
|
4
|
+
import { createFetchFromRegistry } from '@pnpm/network.fetch';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { renderHelp } from 'render-help';
|
|
7
|
+
import { rcOptionsTypes } from './common.js';
|
|
8
|
+
export { rcOptionsTypes };
|
|
9
|
+
export function cliOptionsTypes() {
|
|
10
|
+
return {
|
|
11
|
+
...rcOptionsTypes(),
|
|
12
|
+
json: Boolean,
|
|
13
|
+
'search-limit': Number,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export const commandNames = ['search', 's', 'se', 'find'];
|
|
17
|
+
export function help() {
|
|
18
|
+
return renderHelp({
|
|
19
|
+
description: 'Search for packages in the registry.',
|
|
20
|
+
url: docsUrl('search'),
|
|
21
|
+
usages: [
|
|
22
|
+
'pnpm search <keyword> ...',
|
|
23
|
+
],
|
|
24
|
+
descriptionLists: [
|
|
25
|
+
{
|
|
26
|
+
title: 'Options',
|
|
27
|
+
list: [
|
|
28
|
+
{
|
|
29
|
+
description: 'Show search results in JSON format',
|
|
30
|
+
name: '--json',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
description: 'Maximum number of results to show (default: 20)',
|
|
34
|
+
name: '--search-limit <number>',
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export async function handler(opts, params) {
|
|
42
|
+
const query = params.join(' ');
|
|
43
|
+
if (!query) {
|
|
44
|
+
throw new PnpmError('MISSING_SEARCH_QUERY', 'Search query is required. Usage: pnpm search <keyword>');
|
|
45
|
+
}
|
|
46
|
+
const registry = opts.registries?.default ?? 'https://registry.npmjs.org/';
|
|
47
|
+
const registryUrl = new URL(registry);
|
|
48
|
+
if (!registryUrl.pathname.endsWith('/')) {
|
|
49
|
+
registryUrl.pathname = `${registryUrl.pathname}/`;
|
|
50
|
+
}
|
|
51
|
+
const searchUrl = new URL('./-/v1/search', registryUrl);
|
|
52
|
+
searchUrl.searchParams.set('text', query);
|
|
53
|
+
searchUrl.searchParams.set('size', (opts.searchLimit ?? 20).toString());
|
|
54
|
+
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
55
|
+
const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {}, opts.registries?.default);
|
|
56
|
+
const response = await fetchFromRegistry(searchUrl.toString(), {
|
|
57
|
+
authHeaderValue: getAuthHeader(registry),
|
|
58
|
+
});
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
const errorBody = (await response.text()).trim();
|
|
61
|
+
throw new PnpmError('SEARCH_FAILED', errorBody
|
|
62
|
+
? `Search failed with status ${response.status}: ${response.statusText}. ${errorBody}`
|
|
63
|
+
: `Search failed with status ${response.status}: ${response.statusText}`);
|
|
64
|
+
}
|
|
65
|
+
const data = await response.json();
|
|
66
|
+
if (opts.json) {
|
|
67
|
+
return JSON.stringify(data.objects.map(obj => obj.package), null, 2);
|
|
68
|
+
}
|
|
69
|
+
if (data.objects.length === 0) {
|
|
70
|
+
return 'No packages found';
|
|
71
|
+
}
|
|
72
|
+
return data.objects.map(obj => formatPackage(obj.package)).join('\n\n');
|
|
73
|
+
}
|
|
74
|
+
function formatPackage(pkg) {
|
|
75
|
+
const author = typeof pkg.author === 'object'
|
|
76
|
+
? pkg.author.name
|
|
77
|
+
: (pkg.author ?? pkg.publisher?.username ?? '');
|
|
78
|
+
const date = pkg.date ? pkg.date.split('T')[0] : '';
|
|
79
|
+
const lines = [
|
|
80
|
+
chalk.bold(pkg.name),
|
|
81
|
+
];
|
|
82
|
+
if (pkg.description) {
|
|
83
|
+
lines.push(pkg.description);
|
|
84
|
+
}
|
|
85
|
+
const versionLine = [`Version ${pkg.version}`];
|
|
86
|
+
if (date)
|
|
87
|
+
versionLine.push(`published ${date}`);
|
|
88
|
+
if (author)
|
|
89
|
+
versionLine.push(`by ${author}`);
|
|
90
|
+
lines.push(versionLine.join(' '));
|
|
91
|
+
if (pkg.maintainers?.length) {
|
|
92
|
+
lines.push(`Maintainers: ${pkg.maintainers.map(m => m.username).join(', ')}`);
|
|
93
|
+
}
|
|
94
|
+
if (pkg.keywords?.length) {
|
|
95
|
+
lines.push(`Keywords: ${pkg.keywords.join(', ')}`);
|
|
96
|
+
}
|
|
97
|
+
lines.push(chalk.blueBright(`https://npmx.dev/package/${pkg.name}`));
|
|
98
|
+
return lines.join('\n');
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type CreateFetchFromRegistryOptions } from '@pnpm/network.fetch';
|
|
2
|
+
import type { Registries, RegistryConfig } from '@pnpm/types';
|
|
3
|
+
export declare function cliOptionsTypes(): Record<string, unknown>;
|
|
4
|
+
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
5
|
+
export interface StarOptions extends CreateFetchFromRegistryOptions {
|
|
6
|
+
configByUri?: Record<string, RegistryConfig>;
|
|
7
|
+
registries?: Registries;
|
|
8
|
+
}
|
|
9
|
+
interface StarActionArgs {
|
|
10
|
+
packageName: string;
|
|
11
|
+
star: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function performStarAction(opts: StarOptions, { packageName, star }: StarActionArgs): Promise<void>;
|
|
14
|
+
export declare function getAuthHeaderForRegistry(configByUri: Record<string, RegistryConfig> | undefined, registryUrl: string): string | undefined;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
|
|
2
|
+
import { PnpmError } from '@pnpm/error';
|
|
3
|
+
import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
|
|
4
|
+
import { createFetchFromRegistry } from '@pnpm/network.fetch';
|
|
5
|
+
import { normalizeRegistryUrl, parsePackageSpec, rcOptionsTypes as commonRcOptionsTypes } from '../common.js';
|
|
6
|
+
import { fetchWhoami } from '../whoami.js';
|
|
7
|
+
export function cliOptionsTypes() {
|
|
8
|
+
return {
|
|
9
|
+
...commonRcOptionsTypes(),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function rcOptionsTypes() {
|
|
13
|
+
return commonRcOptionsTypes();
|
|
14
|
+
}
|
|
15
|
+
export async function performStarAction(opts, { packageName, star }) {
|
|
16
|
+
const { escapedName } = parsePackageSpec(packageName);
|
|
17
|
+
const registryUrl = normalizeRegistryUrl(pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, packageName));
|
|
18
|
+
const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl);
|
|
19
|
+
const action = star ? 'star' : 'unstar';
|
|
20
|
+
if (!authHeader) {
|
|
21
|
+
throw new PnpmError('STAR_UNAUTHORIZED', `You must be logged in to ${action} packages`);
|
|
22
|
+
}
|
|
23
|
+
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
24
|
+
const method = star ? 'PUT' : 'DELETE';
|
|
25
|
+
const starUrl = new URL('./-/user/v1/star', registryUrl).href;
|
|
26
|
+
let response = await fetchFromRegistry(starUrl, {
|
|
27
|
+
authHeaderValue: authHeader,
|
|
28
|
+
method,
|
|
29
|
+
headers: {
|
|
30
|
+
'content-type': 'application/json',
|
|
31
|
+
},
|
|
32
|
+
body: JSON.stringify({ name: packageName, package: packageName }),
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
const altStarUrl = new URL(`./-/user/package/${escapedName}/star`, registryUrl).href;
|
|
36
|
+
response = await fetchFromRegistry(altStarUrl, {
|
|
37
|
+
authHeaderValue: authHeader,
|
|
38
|
+
method,
|
|
39
|
+
headers: {
|
|
40
|
+
'content-type': 'application/json',
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
if (response.status === 404 || response.status === 405 || response.status === 400 || response.status === 500) {
|
|
46
|
+
return performLegacyStarAction({ packageName, escapedName, star, registryUrl, authHeader, fetchFromRegistry });
|
|
47
|
+
}
|
|
48
|
+
const errorBody = await response.text();
|
|
49
|
+
throw new PnpmError('REGISTRY_ERROR', `Failed to ${action} package: ${response.status} ${response.statusText}. ${errorBody}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function performLegacyStarAction(args) {
|
|
53
|
+
const { packageName, escapedName, star, registryUrl, authHeader, fetchFromRegistry } = args;
|
|
54
|
+
const action = star ? 'star' : 'unstar';
|
|
55
|
+
const username = await fetchWhoami(registryUrl, fetchFromRegistry, authHeader);
|
|
56
|
+
const pkgUrl = new URL(`./${escapedName}`, registryUrl).href;
|
|
57
|
+
const response = await fetchFromRegistry(pkgUrl, {
|
|
58
|
+
authHeaderValue: authHeader,
|
|
59
|
+
fullMetadata: true,
|
|
60
|
+
});
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
if (response.status === 404) {
|
|
63
|
+
throw new PnpmError('PACKAGE_NOT_FOUND', `Package "${packageName}" not found in registry`);
|
|
64
|
+
}
|
|
65
|
+
throw new PnpmError('REGISTRY_ERROR', `Failed to fetch package info: ${response.status} ${response.statusText}`);
|
|
66
|
+
}
|
|
67
|
+
const pkgData = await response.json();
|
|
68
|
+
pkgData.users = pkgData.users || {};
|
|
69
|
+
if (star) {
|
|
70
|
+
pkgData.users[username] = true;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
delete pkgData.users[username];
|
|
74
|
+
}
|
|
75
|
+
const updateUrl = pkgData._rev ? `${pkgUrl}/-rev/${pkgData._rev}` : pkgUrl;
|
|
76
|
+
const updateResponse = await fetchFromRegistry(updateUrl, {
|
|
77
|
+
authHeaderValue: authHeader,
|
|
78
|
+
method: 'PUT',
|
|
79
|
+
headers: {
|
|
80
|
+
'content-type': 'application/json',
|
|
81
|
+
},
|
|
82
|
+
body: JSON.stringify(pkgData),
|
|
83
|
+
});
|
|
84
|
+
if (!updateResponse.ok) {
|
|
85
|
+
const errorBody = await updateResponse.text();
|
|
86
|
+
throw new PnpmError('REGISTRY_ERROR', `Failed to ${action} package (legacy): ${updateResponse.status} ${updateResponse.statusText}. ${errorBody}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export function getAuthHeaderForRegistry(configByUri, registryUrl) {
|
|
90
|
+
const getAuthHeader = createGetAuthHeaderByURI(configByUri ?? {}, registryUrl);
|
|
91
|
+
return getAuthHeader(registryUrl);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { cliOptionsTypes, rcOptionsTypes, type StarOptions } from './common.js';
|
|
2
|
+
export { cliOptionsTypes, rcOptionsTypes };
|
|
3
|
+
export declare const commandNames: string[];
|
|
4
|
+
export declare function help(): string;
|
|
5
|
+
export declare function handler(opts: StarOptions, params: string[]): Promise<void>;
|
package/lib/star/star.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { docsUrl } from '@pnpm/cli.utils';
|
|
2
|
+
import { PnpmError } from '@pnpm/error';
|
|
3
|
+
import { renderHelp } from 'render-help';
|
|
4
|
+
import { cliOptionsTypes, performStarAction, rcOptionsTypes } from './common.js';
|
|
5
|
+
export { cliOptionsTypes, rcOptionsTypes };
|
|
6
|
+
export const commandNames = ['star'];
|
|
7
|
+
export function help() {
|
|
8
|
+
return renderHelp({
|
|
9
|
+
description: 'Marks a package as a favorite.',
|
|
10
|
+
url: docsUrl('star'),
|
|
11
|
+
usages: ['pnpm star <package>'],
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export async function handler(opts, params) {
|
|
15
|
+
if (params.length === 0) {
|
|
16
|
+
throw new PnpmError('STAR_PACKAGE_REQUIRED', 'Package name is required');
|
|
17
|
+
}
|
|
18
|
+
await performStarAction(opts, { packageName: params[0], star: true });
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=star.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { cliOptionsTypes, rcOptionsTypes, type StarOptions } from './common.js';
|
|
2
|
+
export { cliOptionsTypes, rcOptionsTypes };
|
|
3
|
+
export declare const commandNames: string[];
|
|
4
|
+
export declare function help(): string;
|
|
5
|
+
export declare function handler(opts: StarOptions, params: string[]): Promise<string>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { docsUrl } from '@pnpm/cli.utils';
|
|
2
|
+
import { PnpmError } from '@pnpm/error';
|
|
3
|
+
import { createFetchFromRegistry } from '@pnpm/network.fetch';
|
|
4
|
+
import { renderHelp } from 'render-help';
|
|
5
|
+
import { normalizeRegistryUrl } from '../common.js';
|
|
6
|
+
import { fetchWhoami } from '../whoami.js';
|
|
7
|
+
import { cliOptionsTypes, getAuthHeaderForRegistry, rcOptionsTypes } from './common.js';
|
|
8
|
+
export { cliOptionsTypes, rcOptionsTypes };
|
|
9
|
+
export const commandNames = ['stars'];
|
|
10
|
+
export function help() {
|
|
11
|
+
return renderHelp({
|
|
12
|
+
description: 'Lists all packages starred by a specific user.',
|
|
13
|
+
url: docsUrl('stars'),
|
|
14
|
+
usages: ['pnpm stars [<user>]'],
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export async function handler(opts, params) {
|
|
18
|
+
const registryUrl = normalizeRegistryUrl(opts.registries?.default ?? 'https://registry.npmjs.org/');
|
|
19
|
+
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
20
|
+
const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl);
|
|
21
|
+
let username = params[0];
|
|
22
|
+
if (!username) {
|
|
23
|
+
if (!authHeader) {
|
|
24
|
+
throw new PnpmError('STARS_UNAUTHORIZED', 'You must be logged in to list your starred packages');
|
|
25
|
+
}
|
|
26
|
+
username = await fetchWhoami(registryUrl, fetchFromRegistry, authHeader);
|
|
27
|
+
}
|
|
28
|
+
if (!params[0]) {
|
|
29
|
+
const starUrl = new URL('./-/user/v1/star', registryUrl).href;
|
|
30
|
+
const response = await fetchFromRegistry(starUrl, {
|
|
31
|
+
authHeaderValue: authHeader,
|
|
32
|
+
});
|
|
33
|
+
if (response.ok) {
|
|
34
|
+
const starsData = await response.json();
|
|
35
|
+
if (Array.isArray(starsData))
|
|
36
|
+
return starsData.join('\n');
|
|
37
|
+
if (typeof starsData === 'object' && starsData !== null) {
|
|
38
|
+
return Object.keys(starsData).join('\n');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const starsUrl = new URL(`./-/user/${encodeURIComponent(username)}/stars`, registryUrl).href;
|
|
43
|
+
let response = await fetchFromRegistry(starsUrl, {
|
|
44
|
+
authHeaderValue: authHeader,
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
const utilStarsUrl = new URL(`./-/util/user/${encodeURIComponent(username)}/stars`, registryUrl).href;
|
|
48
|
+
response = await fetchFromRegistry(utilStarsUrl, {
|
|
49
|
+
authHeaderValue: authHeader,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
if (response.status === 404) {
|
|
54
|
+
throw new PnpmError('USER_NOT_FOUND', `User "${username}" not found`);
|
|
55
|
+
}
|
|
56
|
+
throw new PnpmError('REGISTRY_ERROR', `Failed to fetch stars: ${response.status} ${response.statusText}`);
|
|
57
|
+
}
|
|
58
|
+
const starsData = await response.json();
|
|
59
|
+
return Object.keys(starsData).join('\n');
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=stars.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { cliOptionsTypes, rcOptionsTypes, type StarOptions } from './common.js';
|
|
2
|
+
export { cliOptionsTypes, rcOptionsTypes };
|
|
3
|
+
export declare const commandNames: string[];
|
|
4
|
+
export declare function help(): string;
|
|
5
|
+
export declare function handler(opts: StarOptions, params: string[]): Promise<void>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { docsUrl } from '@pnpm/cli.utils';
|
|
2
|
+
import { PnpmError } from '@pnpm/error';
|
|
3
|
+
import { renderHelp } from 'render-help';
|
|
4
|
+
import { cliOptionsTypes, performStarAction, rcOptionsTypes } from './common.js';
|
|
5
|
+
export { cliOptionsTypes, rcOptionsTypes };
|
|
6
|
+
export const commandNames = ['unstar'];
|
|
7
|
+
export function help() {
|
|
8
|
+
return renderHelp({
|
|
9
|
+
description: 'Removes a package from your favorites.',
|
|
10
|
+
url: docsUrl('unstar'),
|
|
11
|
+
usages: ['pnpm unstar <package>'],
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export async function handler(opts, params) {
|
|
15
|
+
if (params.length === 0) {
|
|
16
|
+
throw new PnpmError('UNSTAR_PACKAGE_REQUIRED', 'Package name is required');
|
|
17
|
+
}
|
|
18
|
+
await performStarAction(opts, { packageName: params[0], star: false });
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=unstar.js.map
|
package/lib/whoami.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CreateFetchFromRegistryOptions, type FetchFromRegistry } from '@pnpm/network.fetch';
|
|
2
|
+
import type { Registries, RegistryConfig } from '@pnpm/types';
|
|
3
|
+
export declare function cliOptionsTypes(): Record<string, unknown>;
|
|
4
|
+
export declare function rcOptionsTypes(): Record<string, unknown>;
|
|
5
|
+
export interface WhoamiOptions extends CreateFetchFromRegistryOptions {
|
|
6
|
+
configByUri?: Record<string, RegistryConfig>;
|
|
7
|
+
registries?: Registries;
|
|
8
|
+
}
|
|
9
|
+
export declare const commandNames: string[];
|
|
10
|
+
export declare function help(): string;
|
|
11
|
+
export declare function handler(opts: WhoamiOptions): Promise<string>;
|
|
12
|
+
export declare function fetchWhoami(registryUrl: string, fetchFromRegistry: FetchFromRegistry, authHeader: string): Promise<string>;
|
package/lib/whoami.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { docsUrl } from '@pnpm/cli.utils';
|
|
2
|
+
import { PnpmError } from '@pnpm/error';
|
|
3
|
+
import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
|
|
4
|
+
import { createFetchFromRegistry } from '@pnpm/network.fetch';
|
|
5
|
+
import { renderHelp } from 'render-help';
|
|
6
|
+
import { normalizeRegistryUrl, rcOptionsTypes as commonRcOptionsTypes } from './common.js';
|
|
7
|
+
export function cliOptionsTypes() {
|
|
8
|
+
return {
|
|
9
|
+
...commonRcOptionsTypes(),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function rcOptionsTypes() {
|
|
13
|
+
return commonRcOptionsTypes();
|
|
14
|
+
}
|
|
15
|
+
export const commandNames = ['whoami'];
|
|
16
|
+
export function help() {
|
|
17
|
+
return renderHelp({
|
|
18
|
+
description: 'Displays your pnpm username.',
|
|
19
|
+
url: docsUrl('whoami'),
|
|
20
|
+
usages: ['pnpm whoami'],
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export async function handler(opts) {
|
|
24
|
+
const registryUrl = normalizeRegistryUrl(opts.registries?.default ?? 'https://registry.npmjs.org/');
|
|
25
|
+
const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {}, registryUrl);
|
|
26
|
+
const authHeader = getAuthHeader(registryUrl);
|
|
27
|
+
if (!authHeader) {
|
|
28
|
+
throw new PnpmError('WHOAMI_UNAUTHORIZED', 'You must be logged in to use whoami');
|
|
29
|
+
}
|
|
30
|
+
return fetchWhoami(registryUrl, createFetchFromRegistry(opts), authHeader);
|
|
31
|
+
}
|
|
32
|
+
export async function fetchWhoami(registryUrl, fetchFromRegistry, authHeader) {
|
|
33
|
+
const whoamiUrl = new URL('./-/whoami', normalizeRegistryUrl(registryUrl)).href;
|
|
34
|
+
const response = await fetchFromRegistry(whoamiUrl, {
|
|
35
|
+
authHeaderValue: authHeader,
|
|
36
|
+
});
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
throw new PnpmError('WHOAMI_FAILED', `Failed to find the current user: ${response.status} ${response.statusText}`);
|
|
39
|
+
}
|
|
40
|
+
const { username } = await response.json();
|
|
41
|
+
return username;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=whoami.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.2.0",
|
|
4
4
|
"description": "Commands for managing packages on the registry",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -25,17 +25,18 @@
|
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@pnpm/npm-package-arg": "^2.0.0",
|
|
28
|
+
"chalk": "^5.6.0",
|
|
28
29
|
"ramda": "npm:@pnpm/ramda@0.28.1",
|
|
29
30
|
"render-help": "^2.0.0",
|
|
30
31
|
"semver": "^7.7.2",
|
|
31
|
-
"@pnpm/cli.utils": "
|
|
32
|
-
"@pnpm/config.
|
|
32
|
+
"@pnpm/cli.utils": "1101.0.0",
|
|
33
|
+
"@pnpm/config.reader": "1101.0.0",
|
|
34
|
+
"@pnpm/network.auth-header": "1100.0.1",
|
|
35
|
+
"@pnpm/network.fetch": "1100.0.1",
|
|
36
|
+
"@pnpm/config.pick-registry-for-package": "1100.0.1",
|
|
33
37
|
"@pnpm/error": "1100.0.0",
|
|
34
|
-
"@pnpm/
|
|
35
|
-
"@pnpm/
|
|
36
|
-
"@pnpm/resolving.registry.types": "1100.0.0",
|
|
37
|
-
"@pnpm/types": "1100.0.0",
|
|
38
|
-
"@pnpm/config.reader": "1100.0.0"
|
|
38
|
+
"@pnpm/resolving.registry.types": "1100.0.1",
|
|
39
|
+
"@pnpm/types": "1101.0.0"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
42
|
"@jest/globals": "30.3.0",
|
|
@@ -43,10 +44,11 @@
|
|
|
43
44
|
"@types/ramda": "0.31.1",
|
|
44
45
|
"@types/semver": "7.7.1",
|
|
45
46
|
"execa": "npm:safe-execa@0.3.0",
|
|
46
|
-
"@pnpm/prepare": "1100.0.
|
|
47
|
-
"@pnpm/
|
|
48
|
-
"@pnpm/
|
|
49
|
-
"@pnpm/testing.
|
|
47
|
+
"@pnpm/prepare": "1100.0.1",
|
|
48
|
+
"@pnpm/registry-access.commands": "1100.2.0",
|
|
49
|
+
"@pnpm/testing.command-defaults": "1100.0.0",
|
|
50
|
+
"@pnpm/testing.mock-agent": "1100.0.1",
|
|
51
|
+
"@pnpm/releasing.commands": "1100.0.2"
|
|
50
52
|
},
|
|
51
53
|
"engines": {
|
|
52
54
|
"node": ">=22.13"
|