@vltpkg/cli-sdk 1.0.0-rc.23 → 1.0.0-rc.24

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.
Files changed (103) hide show
  1. package/dist/commands/bugs.d.ts +17 -0
  2. package/dist/commands/bugs.js +163 -0
  3. package/dist/commands/build.d.ts +24 -0
  4. package/dist/commands/build.js +101 -0
  5. package/dist/commands/cache.d.ts +64 -0
  6. package/dist/commands/cache.js +256 -0
  7. package/dist/commands/ci.d.ts +10 -0
  8. package/dist/commands/ci.js +40 -0
  9. package/dist/commands/config.d.ts +5 -0
  10. package/dist/commands/config.js +429 -0
  11. package/dist/commands/create.d.ts +8 -0
  12. package/dist/commands/create.js +102 -0
  13. package/dist/commands/docs.d.ts +17 -0
  14. package/dist/commands/docs.js +153 -0
  15. package/dist/commands/exec-cache.d.ts +48 -0
  16. package/dist/commands/exec-cache.js +145 -0
  17. package/dist/commands/exec-local.d.ts +5 -0
  18. package/dist/commands/exec-local.js +46 -0
  19. package/dist/commands/exec.d.ts +8 -0
  20. package/dist/commands/exec.js +161 -0
  21. package/dist/commands/help.d.ts +3 -0
  22. package/dist/commands/help.js +43 -0
  23. package/dist/commands/init.d.ts +7 -0
  24. package/dist/commands/init.js +116 -0
  25. package/dist/commands/install/reporter.d.ts +10 -0
  26. package/dist/commands/install/reporter.js +93 -0
  27. package/dist/commands/install.d.ts +27 -0
  28. package/dist/commands/install.js +80 -0
  29. package/dist/commands/list.d.ts +17 -0
  30. package/dist/commands/list.js +197 -0
  31. package/dist/commands/login.d.ts +3 -0
  32. package/dist/commands/login.js +22 -0
  33. package/dist/commands/logout.d.ts +3 -0
  34. package/dist/commands/logout.js +22 -0
  35. package/dist/commands/pack.d.ts +31 -0
  36. package/dist/commands/pack.js +205 -0
  37. package/dist/commands/ping.d.ts +17 -0
  38. package/dist/commands/ping.js +114 -0
  39. package/dist/commands/pkg.d.ts +6 -0
  40. package/dist/commands/pkg.js +232 -0
  41. package/dist/commands/publish.d.ts +21 -0
  42. package/dist/commands/publish.js +282 -0
  43. package/dist/commands/query.d.ts +18 -0
  44. package/dist/commands/query.js +216 -0
  45. package/dist/commands/repo.d.ts +17 -0
  46. package/dist/commands/repo.js +157 -0
  47. package/dist/commands/run-exec.d.ts +5 -0
  48. package/dist/commands/run-exec.js +40 -0
  49. package/dist/commands/run.d.ts +5 -0
  50. package/dist/commands/run.js +62 -0
  51. package/dist/commands/token.d.ts +3 -0
  52. package/dist/commands/token.js +39 -0
  53. package/dist/commands/uninstall.d.ts +15 -0
  54. package/dist/commands/uninstall.js +39 -0
  55. package/dist/commands/update.d.ts +13 -0
  56. package/dist/commands/update.js +46 -0
  57. package/dist/commands/version.d.ts +25 -0
  58. package/dist/commands/version.js +252 -0
  59. package/dist/commands/view.d.ts +22 -0
  60. package/dist/commands/view.js +334 -0
  61. package/dist/commands/whoami.d.ts +12 -0
  62. package/dist/commands/whoami.js +28 -0
  63. package/dist/config/definition.d.ts +407 -0
  64. package/dist/config/definition.js +684 -0
  65. package/dist/config/index.d.ts +218 -0
  66. package/dist/config/index.js +488 -0
  67. package/dist/config/merge.d.ts +3 -0
  68. package/dist/config/merge.js +27 -0
  69. package/dist/config/usage.d.ts +18 -0
  70. package/dist/config/usage.js +39 -0
  71. package/dist/custom-help.d.ts +8 -0
  72. package/dist/custom-help.js +419 -0
  73. package/dist/exec-command.d.ts +52 -0
  74. package/dist/exec-command.js +313 -0
  75. package/dist/index.d.ts +3 -0
  76. package/dist/index.js +72 -0
  77. package/dist/load-command.d.ts +15 -0
  78. package/dist/load-command.js +20 -0
  79. package/dist/mermaid-image-view.d.ts +18 -0
  80. package/dist/mermaid-image-view.js +36 -0
  81. package/dist/output.d.ts +20 -0
  82. package/dist/output.js +125 -0
  83. package/dist/pack-tarball.d.ts +23 -0
  84. package/dist/pack-tarball.js +256 -0
  85. package/dist/parse-add-remove-args.d.ts +28 -0
  86. package/dist/parse-add-remove-args.js +103 -0
  87. package/dist/print-err.d.ts +13 -0
  88. package/dist/print-err.js +193 -0
  89. package/dist/query-diff-files.d.ts +17 -0
  90. package/dist/query-diff-files.js +63 -0
  91. package/dist/query-host-contexts.d.ts +15 -0
  92. package/dist/query-host-contexts.js +136 -0
  93. package/dist/read-password.d.ts +7 -0
  94. package/dist/read-password.js +32 -0
  95. package/dist/read-project-folders.d.ts +17 -0
  96. package/dist/read-project-folders.js +100 -0
  97. package/dist/reload-config.d.ts +2 -0
  98. package/dist/reload-config.js +11 -0
  99. package/dist/render-mermaid.d.ts +22 -0
  100. package/dist/render-mermaid.js +68 -0
  101. package/dist/view.d.ts +29 -0
  102. package/dist/view.js +30 -0
  103. package/package.json +25 -25
@@ -0,0 +1,334 @@
1
+ import * as dotProp from '@vltpkg/dot-prop';
2
+ import { error } from '@vltpkg/error-cause';
3
+ import { PackageInfoClient } from '@vltpkg/package-info';
4
+ import { SecurityArchive } from '@vltpkg/security-archive';
5
+ import { Spec } from '@vltpkg/spec';
6
+ import { joinDepIDTuple } from '@vltpkg/dep-id';
7
+ import { commandUsage } from "../config/usage.js";
8
+ export const usage = () => commandUsage({
9
+ command: 'view',
10
+ usage: [
11
+ '<pkg>[@<version>] [<field>]',
12
+ '<pkg>[@<version>] [--view=human | json]',
13
+ ],
14
+ description: `View registry information about a package.
15
+
16
+ Fetches and displays packument and manifest data for a given
17
+ package from the registry.
18
+
19
+ When a specific field is provided, only that field value is
20
+ displayed. Use dot-prop syntax to access nested fields
21
+ (e.g., \`dist-tags.latest\`, \`dependencies.lodash\`).
22
+
23
+ Security data from the vlt security archive is shown when
24
+ available, including scores and alerts.`,
25
+ examples: {
26
+ express: {
27
+ description: 'View info about the latest version of express',
28
+ },
29
+ 'express@4.18.2': {
30
+ description: 'View info about a specific version',
31
+ },
32
+ 'express versions': {
33
+ description: 'List all published versions',
34
+ },
35
+ 'express dist-tags': {
36
+ description: 'Show all dist-tags',
37
+ },
38
+ 'express dependencies': {
39
+ description: 'Show dependencies of the latest version',
40
+ },
41
+ 'express dist-tags.latest': {
42
+ description: 'Show the latest dist-tag value',
43
+ },
44
+ },
45
+ options: {
46
+ view: {
47
+ value: '[human | json]',
48
+ description: 'Output format. Defaults to human-readable or json if no tty.',
49
+ },
50
+ },
51
+ });
52
+ const formatScore = (score) => `${Math.round(score * 100)}/100`;
53
+ const formatAlertSeverity = (severity) => {
54
+ switch (severity) {
55
+ case 'critical':
56
+ return '[CRITICAL]';
57
+ case 'high':
58
+ return '[HIGH]';
59
+ case 'medium':
60
+ return '[MEDIUM]';
61
+ case 'low':
62
+ return '[LOW]';
63
+ /* c8 ignore next 2 */
64
+ default:
65
+ return `[${String(severity).toUpperCase()}]`;
66
+ }
67
+ };
68
+ const formatSecurity = (report) => {
69
+ const lines = [];
70
+ const { score, alerts } = report;
71
+ lines.push('');
72
+ lines.push('security:');
73
+ lines.push(` score: ${formatScore(score.overall)}`);
74
+ lines.push(` license: ${formatScore(score.license)}`);
75
+ lines.push(` maintenance: ${formatScore(score.maintenance)}`);
76
+ lines.push(` quality: ${formatScore(score.quality)}`);
77
+ lines.push(` supply chain: ${formatScore(score.supplyChain)}`);
78
+ lines.push(` vulnerability: ${formatScore(score.vulnerability)}`);
79
+ if (alerts.length > 0) {
80
+ lines.push(` alerts: ${alerts.length}`);
81
+ for (const alert of alerts) {
82
+ lines.push(` ${formatAlertSeverity(alert.severity)} ${alert.type}: ${alert.key} (${alert.category})`);
83
+ }
84
+ }
85
+ else {
86
+ lines.push(' alerts: none');
87
+ }
88
+ return lines.join('\n');
89
+ };
90
+ const formatDependencyCount = (manifest) => {
91
+ const lines = [];
92
+ const deps = Object.keys(manifest.dependencies ?? {}).length;
93
+ const devDeps = Object.keys(manifest.devDependencies ?? {}).length;
94
+ const optDeps = Object.keys(manifest.optionalDependencies ?? {}).length;
95
+ const peerDeps = Object.keys(manifest.peerDependencies ?? {}).length;
96
+ const parts = [];
97
+ if (deps > 0)
98
+ parts.push(`${deps} dependencies`);
99
+ if (devDeps > 0)
100
+ parts.push(`${devDeps} dev`);
101
+ if (optDeps > 0)
102
+ parts.push(`${optDeps} optional`);
103
+ if (peerDeps > 0)
104
+ parts.push(`${peerDeps} peer`);
105
+ if (parts.length > 0) {
106
+ lines.push(`deps: ${parts.join(', ')}`);
107
+ }
108
+ return lines;
109
+ };
110
+ const formatHuman = (result) => {
111
+ const { packument, manifest, security } = result;
112
+ const lines = [];
113
+ // Name and version
114
+ const name = manifest.name ?? packument.name;
115
+ const version = manifest.version ?? '';
116
+ lines.push(`${name}@${version}`);
117
+ // Description
118
+ if (manifest.description) {
119
+ lines.push(manifest.description);
120
+ }
121
+ lines.push('');
122
+ // License
123
+ if (manifest.license) {
124
+ lines.push(`license: ${manifest.license}`);
125
+ }
126
+ // Homepage
127
+ if (manifest.homepage) {
128
+ lines.push(`homepage: ${manifest.homepage}`);
129
+ }
130
+ // Repository
131
+ if (manifest.repository) {
132
+ const repo = typeof manifest.repository === 'string' ?
133
+ manifest.repository
134
+ : manifest.repository.url;
135
+ if (repo) {
136
+ lines.push(`repository: ${repo}`);
137
+ }
138
+ }
139
+ // Author
140
+ if (manifest.author) {
141
+ const author = typeof manifest.author === 'string' ?
142
+ manifest.author
143
+ : manifest.author.name;
144
+ if (author) {
145
+ lines.push(`author: ${author}`);
146
+ }
147
+ }
148
+ // Keywords
149
+ if (manifest.keywords) {
150
+ const kw = Array.isArray(manifest.keywords) ?
151
+ manifest.keywords
152
+ : [manifest.keywords];
153
+ if (kw.length > 0) {
154
+ lines.push(`keywords: ${kw.join(', ')}`);
155
+ }
156
+ }
157
+ // Dist-tags
158
+ const tagEntries = Object.entries(packument['dist-tags']);
159
+ if (tagEntries.length > 0) {
160
+ lines.push('');
161
+ lines.push('dist-tags:');
162
+ for (const [tag, ver] of tagEntries) {
163
+ lines.push(` ${tag}: ${ver}`);
164
+ }
165
+ }
166
+ // Dependencies count
167
+ const depLines = formatDependencyCount(manifest);
168
+ if (depLines.length > 0) {
169
+ lines.push('');
170
+ lines.push(...depLines);
171
+ }
172
+ // Maintainers
173
+ if (packument.maintainers && packument.maintainers.length > 0) {
174
+ lines.push('');
175
+ lines.push('maintainers:');
176
+ for (const m of packument.maintainers) {
177
+ const mName = typeof m === 'string' ? m : m.name;
178
+ lines.push(` - ${mName}`);
179
+ }
180
+ }
181
+ // Published time
182
+ if (packument.time && version && packument.time[version]) {
183
+ lines.push('');
184
+ lines.push(`published: ${packument.time[version]}`);
185
+ }
186
+ // Security info
187
+ if (security) {
188
+ lines.push(formatSecurity(security));
189
+ }
190
+ // Versions count
191
+ const versionCount = Object.keys(packument.versions).length;
192
+ if (versionCount > 0) {
193
+ lines.push('');
194
+ lines.push(`versions: ${versionCount} total`);
195
+ }
196
+ return lines.join('\n');
197
+ };
198
+ export const views = {
199
+ human: (result, _options, _conf) => {
200
+ // Field access mode: just return the value
201
+ if (result.fieldPath !== undefined) {
202
+ const val = result.fieldValue;
203
+ if (Array.isArray(val)) {
204
+ return val.join('\n');
205
+ }
206
+ if (typeof val === 'object' && val !== null) {
207
+ return JSON.stringify(val, null, 2);
208
+ }
209
+ if (val === undefined || val === null)
210
+ return '';
211
+ return typeof val === 'string' ? val : JSON.stringify(val);
212
+ }
213
+ // Full view mode
214
+ return formatHuman(result);
215
+ },
216
+ json: (result, _options, _conf) => {
217
+ if (result.fieldPath !== undefined) {
218
+ return result.fieldValue;
219
+ }
220
+ return {
221
+ ...result.manifest,
222
+ 'dist-tags': result.packument['dist-tags'],
223
+ time: result.packument.time,
224
+ maintainers: result.packument.maintainers,
225
+ ...(result.security ? { security: result.security } : {}),
226
+ };
227
+ },
228
+ };
229
+ /**
230
+ * Create a minimal NodeLike for SecurityArchive lookup.
231
+ * Only the fields used by SecurityArchive.start() are needed.
232
+ */
233
+ const createFakeNode = (name, version) => ({
234
+ id: joinDepIDTuple(['registry', '', `${name}@${version}`]),
235
+ name,
236
+ version,
237
+ confused: false,
238
+ edgesIn: new Set(),
239
+ edgesOut: new Map(),
240
+ workspaces: undefined,
241
+ importer: false,
242
+ mainImporter: false,
243
+ projectRoot: '',
244
+ dev: false,
245
+ optional: false,
246
+ graph: {},
247
+ options: {},
248
+ /* c8 ignore next 5 - stub methods for NodeLike interface */
249
+ toJSON: () => ({}),
250
+ toString: () => `${name}@${version}`,
251
+ setResolved: () => { },
252
+ setConfusedManifest: () => { },
253
+ maybeSetConfusedManifest: () => { },
254
+ });
255
+ /**
256
+ * Lookup fields from a combined packument+manifest view.
257
+ *
258
+ * The lookup searches in this order:
259
+ * 1. Top-level packument fields (name, dist-tags, versions, time,
260
+ * readme, maintainers)
261
+ * 2. Manifest fields for the resolved version
262
+ * 3. Security data (security.score, security.alerts)
263
+ */
264
+ const lookupField = (result, path) => {
265
+ // Special handling for packument-level fields
266
+ const packumentFields = [
267
+ 'dist-tags',
268
+ 'versions',
269
+ 'time',
270
+ 'readme',
271
+ 'maintainers',
272
+ 'modified',
273
+ 'contributors',
274
+ ];
275
+ /* c8 ignore next - split always returns at least one element */
276
+ const topLevel = path.split('.')[0] ?? path;
277
+ if (packumentFields.includes(topLevel)) {
278
+ return dotProp.get(result.packument, path);
279
+ }
280
+ // Check security namespace
281
+ if (topLevel === 'security' && result.security) {
282
+ const subPath = path.slice('security.'.length);
283
+ if (subPath === '' || path === 'security') {
284
+ return result.security;
285
+ }
286
+ return dotProp.get(result.security, subPath);
287
+ }
288
+ // Default: look up in manifest
289
+ return dotProp.get(result.manifest, path);
290
+ };
291
+ export const command = async (conf) => {
292
+ const specArg = conf.positionals[0];
293
+ if (!specArg) {
294
+ throw error('view requires a package spec argument', {
295
+ code: 'EUSAGE',
296
+ });
297
+ }
298
+ const fieldPath = conf.positionals[1];
299
+ const spec = Spec.parseArgs(specArg, conf.options);
300
+ const pic = new PackageInfoClient(conf.options);
301
+ // Fetch the packument and resolved manifest
302
+ const [packument, resolvedManifest] = await Promise.all([
303
+ pic.packument(spec),
304
+ pic.manifest(spec),
305
+ ]);
306
+ const manifest = resolvedManifest;
307
+ // Try to get security data for this package
308
+ let security;
309
+ const name = manifest.name ?? packument.name;
310
+ const version = manifest.version;
311
+ if (name && version) {
312
+ try {
313
+ const node = createFakeNode(name, version);
314
+ const archive = await SecurityArchive.start({
315
+ nodes: [node],
316
+ });
317
+ security = archive.get(node.id);
318
+ }
319
+ catch {
320
+ // Security data is optional, don't fail the command
321
+ }
322
+ }
323
+ const result = {
324
+ packument,
325
+ manifest,
326
+ security,
327
+ };
328
+ // If a field path is provided, resolve it
329
+ if (fieldPath !== undefined) {
330
+ result.fieldPath = fieldPath;
331
+ result.fieldValue = lookupField(result, fieldPath);
332
+ }
333
+ return result;
334
+ };
@@ -0,0 +1,12 @@
1
+ import type { JSONField } from '@vltpkg/types';
2
+ import type { CommandFn, CommandUsage } from '../index.ts';
3
+ export declare const usage: CommandUsage;
4
+ type CommandResult = {
5
+ username?: JSONField;
6
+ };
7
+ export declare const views: {
8
+ readonly human: (r: CommandResult) => JSONField;
9
+ readonly json: (r: CommandResult) => CommandResult;
10
+ };
11
+ export declare const command: CommandFn<CommandResult>;
12
+ export {};
@@ -0,0 +1,28 @@
1
+ import { RegistryClient } from '@vltpkg/registry-client';
2
+ import { commandUsage } from "../config/usage.js";
3
+ export const usage = () => commandUsage({
4
+ command: 'whoami',
5
+ usage: [''],
6
+ description: `Look up the username for the currently active token,
7
+ when logged into a registry.`,
8
+ options: {
9
+ registry: {
10
+ value: '<url>',
11
+ description: 'Registry URL to query for authenticated user info.',
12
+ },
13
+ identity: {
14
+ value: '<name>',
15
+ description: 'Identity namespace used to look up auth tokens.',
16
+ },
17
+ },
18
+ });
19
+ export const views = {
20
+ human: r => r.username,
21
+ json: r => r,
22
+ };
23
+ export const command = async (conf) => {
24
+ const rc = new RegistryClient(conf.options);
25
+ const response = await rc.request(new URL('-/whoami', conf.options.registry), { useCache: false });
26
+ const { username } = response.json();
27
+ return { username };
28
+ };