@vltpkg/cli-sdk 1.0.10 → 1.1.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/dist/commands/access.js +40 -4
- package/dist/commands/cache.js +7 -2
- package/dist/commands/deprecate.js +9 -9
- package/dist/commands/dist-tag.js +15 -19
- package/dist/commands/install/reporter.js +7 -0
- package/dist/commands/install.d.ts +6 -0
- package/dist/commands/install.js +20 -2
- package/dist/commands/list.js +25 -13
- package/dist/commands/profile.js +19 -1
- package/dist/commands/publish.js +25 -32
- package/dist/commands/query.js +20 -7
- package/dist/commands/setup.d.ts +7 -0
- package/dist/commands/setup.js +33 -8
- package/dist/commands/token.js +3 -1
- package/dist/commands/unpublish.js +35 -30
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.js +18 -1
- package/dist/commands/whoami.js +20 -2
- package/dist/config/definition.d.ts +4 -0
- package/dist/config/definition.js +21 -0
- package/dist/config/index.d.ts +14 -0
- package/dist/config/index.js +110 -5
- package/dist/is-vlt-installed.d.ts +18 -0
- package/dist/is-vlt-installed.js +46 -0
- package/dist/parse-add-remove-args.js +14 -1
- package/dist/persist-spec-config.d.ts +27 -0
- package/dist/persist-spec-config.js +212 -0
- package/dist/print-err.js +14 -2
- package/dist/query-host-contexts.js +2 -6
- package/dist/require-registry.d.ts +12 -0
- package/dist/require-registry.js +29 -0
- package/package.json +25 -25
- package/dist/registry-error-message.d.ts +0 -2
- package/dist/registry-error-message.js +0 -29
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* With `--save-config`, save registry and git host config given on the
|
|
3
|
+
* command line or via `VLT_*` env to `install` / `update`, so that the
|
|
4
|
+
* config files plus the lockfile can reproduce the install.
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import type { WhichConfig } from '@vltpkg/vlt-json';
|
|
8
|
+
import type { ConfigFileData, LoadedConfig } from './config/index.ts';
|
|
9
|
+
/** The config fields that change how specs are parsed. */
|
|
10
|
+
export declare const specConfigFields: readonly ["registry", "registries", "default-registry-alias", "scoped-registries", "jsr-registries", "git-hosts", "git-host-archives"];
|
|
11
|
+
export type SpecConfigPersistPlan = {
|
|
12
|
+
which: WhichConfig;
|
|
13
|
+
values: ConfigFileData;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The spec config set on the cli / env that the target config file (the
|
|
17
|
+
* project `vlt.json`, unless `--config=user`) should get. `undefined`
|
|
18
|
+
* unless `--save-config` is set. Values already in effect from a config
|
|
19
|
+
* file or builtin are left alone. Throws `ECONFIG` when the target file
|
|
20
|
+
* (or its `command.<cmd>` block) sets a value to something else, or a
|
|
21
|
+
* value is invalid.
|
|
22
|
+
*
|
|
23
|
+
* Call before installing, write the result after it succeeds.
|
|
24
|
+
*/
|
|
25
|
+
export declare const planSpecConfigPersist: (conf: LoadedConfig) => SpecConfigPersistPlan | undefined;
|
|
26
|
+
/** `field=value` / `field.key=value` lines for a plan's values. */
|
|
27
|
+
export declare const persistedEntries: (values: ConfigFileData) => string[];
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* With `--save-config`, save registry and git host config given on the
|
|
3
|
+
* command line or via `VLT_*` env to `install` / `update`, so that the
|
|
4
|
+
* config files plus the lockfile can reproduce the install.
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { error } from '@vltpkg/error-cause';
|
|
8
|
+
import { defaultGitHostArchives, defaultGitHosts, defaultJsrRegistries, defaultRegistries, defaultRegistryName, } from '@vltpkg/spec';
|
|
9
|
+
import { isObject } from '@vltpkg/types';
|
|
10
|
+
import { find } from '@vltpkg/vlt-json';
|
|
11
|
+
import { assertRegistryKeys, configWriteTarget, isRecordField, pairsToRecords, } from "./config/index.js";
|
|
12
|
+
import { getCommand } from "./config/definition.js";
|
|
13
|
+
import { registrySelectionFields, registrySelectors, } from "./config/merge-layers.js";
|
|
14
|
+
import { normalizeRegistryURL } from "./require-registry.js";
|
|
15
|
+
/** The config fields that change how specs are parsed. */
|
|
16
|
+
export const specConfigFields = [
|
|
17
|
+
'registry',
|
|
18
|
+
'registries',
|
|
19
|
+
'default-registry-alias',
|
|
20
|
+
'scoped-registries',
|
|
21
|
+
'jsr-registries',
|
|
22
|
+
'git-hosts',
|
|
23
|
+
'git-host-archives',
|
|
24
|
+
];
|
|
25
|
+
const builtins = {
|
|
26
|
+
registries: defaultRegistries,
|
|
27
|
+
'jsr-registries': defaultJsrRegistries,
|
|
28
|
+
'git-hosts': defaultGitHosts,
|
|
29
|
+
'git-host-archives': defaultGitHostArchives,
|
|
30
|
+
};
|
|
31
|
+
// git host templates are not urls
|
|
32
|
+
const urlFields = new Set([
|
|
33
|
+
'registry',
|
|
34
|
+
'registries',
|
|
35
|
+
'scoped-registries',
|
|
36
|
+
'jsr-registries',
|
|
37
|
+
]);
|
|
38
|
+
const norm = (field, v) => urlFields.has(field) ? normalizeRegistryURL(v) : v;
|
|
39
|
+
// printed values end up in CI logs, and a url can carry a token
|
|
40
|
+
const redact = (value) => {
|
|
41
|
+
if (!URL.canParse(value))
|
|
42
|
+
return value;
|
|
43
|
+
const url = new URL(value);
|
|
44
|
+
if (!url.username && !url.password)
|
|
45
|
+
return value;
|
|
46
|
+
url.username = '';
|
|
47
|
+
url.password = '';
|
|
48
|
+
return url.href.replace('://', '://***@');
|
|
49
|
+
};
|
|
50
|
+
// a layer's (or command block's) value, `null` meaning absent
|
|
51
|
+
const fromLayer = (layer, field, key) => {
|
|
52
|
+
const v = layer?.[field];
|
|
53
|
+
const r = key === undefined ? v
|
|
54
|
+
: v && typeof v === 'object' ? v[key]
|
|
55
|
+
: undefined;
|
|
56
|
+
return typeof r === 'string' ? r : undefined;
|
|
57
|
+
};
|
|
58
|
+
// set to `null`, removing the value from outer layers
|
|
59
|
+
const isNulled = (layer, field, key) => {
|
|
60
|
+
const v = layer?.[field];
|
|
61
|
+
return key === undefined ?
|
|
62
|
+
v === null
|
|
63
|
+
: isObject(v) && v[key] === null;
|
|
64
|
+
};
|
|
65
|
+
const conflictError = (field, key, current, wanted, file, block) => {
|
|
66
|
+
const name = (block ? `command.${block}.` : '') +
|
|
67
|
+
(key === undefined ? field : `${field}.${key}`);
|
|
68
|
+
const cur = redact(current);
|
|
69
|
+
const flag = key === undefined ?
|
|
70
|
+
`--${field}=${cur}`
|
|
71
|
+
: `--${field} ${key}=${cur}`;
|
|
72
|
+
return error([
|
|
73
|
+
`${name} is already set to ${cur} in ${file}.`,
|
|
74
|
+
'',
|
|
75
|
+
`Pass \`${flag}\`${key === undefined ? '' : ', use another name,'} or run`,
|
|
76
|
+
block ?
|
|
77
|
+
'`vlt config edit` to change it first.'
|
|
78
|
+
: `\`vlt config set ${name}=${redact(wanted)}\` first.`,
|
|
79
|
+
].join('\n'), { code: 'ECONFIG', found: wanted, wanted: current });
|
|
80
|
+
};
|
|
81
|
+
const ownsSelection = (layer) => registrySelectionFields.some(f => f in (layer ?? {}));
|
|
82
|
+
/**
|
|
83
|
+
* The spec config set on the cli / env that the target config file (the
|
|
84
|
+
* project `vlt.json`, unless `--config=user`) should get. `undefined`
|
|
85
|
+
* unless `--save-config` is set. Values already in effect from a config
|
|
86
|
+
* file or builtin are left alone. Throws `ECONFIG` when the target file
|
|
87
|
+
* (or its `command.<cmd>` block) sets a value to something else, or a
|
|
88
|
+
* value is invalid.
|
|
89
|
+
*
|
|
90
|
+
* Call before installing, write the result after it succeeds.
|
|
91
|
+
*/
|
|
92
|
+
export const planSpecConfigPersist = (conf) => {
|
|
93
|
+
if (!conf.get('save-config'))
|
|
94
|
+
return undefined;
|
|
95
|
+
const explicit = pairsToRecords(conf.explicit);
|
|
96
|
+
if (!specConfigFields.some(f => f in explicit))
|
|
97
|
+
return undefined;
|
|
98
|
+
const which = configWriteTarget(conf, 'project');
|
|
99
|
+
const target = conf.layers[which];
|
|
100
|
+
const other = conf.layers[which === 'project' ? 'user' : 'project'];
|
|
101
|
+
// a project that owns selection drops the user's selectors
|
|
102
|
+
const otherSelectors = which === 'user' || !ownsSelection(target);
|
|
103
|
+
// a command block beats the top level for its command (names like
|
|
104
|
+
// `add` canonicalized, last wins). a record field in the block replaces
|
|
105
|
+
// the top level one, so keys it lacks go in the block.
|
|
106
|
+
const blocks = (target?.command ?? {});
|
|
107
|
+
const blockName = Object.keys(blocks)
|
|
108
|
+
.filter(n => getCommand(n) === conf.command)
|
|
109
|
+
.at(-1);
|
|
110
|
+
const block = blockName ? blocks[blockName] : undefined;
|
|
111
|
+
const staged = {};
|
|
112
|
+
for (const field of specConfigFields) {
|
|
113
|
+
const v = explicit[field];
|
|
114
|
+
if (v === undefined)
|
|
115
|
+
continue;
|
|
116
|
+
const entries = isRecordField(field) ?
|
|
117
|
+
Object.entries(v)
|
|
118
|
+
: [[undefined, v]];
|
|
119
|
+
for (const [key, raw] of entries) {
|
|
120
|
+
if (key === '') {
|
|
121
|
+
throw error(`${field} has an entry with no name.`, {
|
|
122
|
+
code: 'ECONFIG',
|
|
123
|
+
found: `=${raw}`,
|
|
124
|
+
wanted: `<name>=${raw}`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (key !== undefined && field === 'registries') {
|
|
128
|
+
assertRegistryKeys({ [key]: raw }, `--${field}`);
|
|
129
|
+
}
|
|
130
|
+
if (key !== undefined && !raw) {
|
|
131
|
+
throw error(`${field}.${key} has no value.`, {
|
|
132
|
+
code: 'ECONFIG',
|
|
133
|
+
found: key,
|
|
134
|
+
wanted: `${key}=<value>`,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
// eg an empty VLT_REGISTRY
|
|
138
|
+
if (!raw)
|
|
139
|
+
continue;
|
|
140
|
+
const value = norm(field, raw);
|
|
141
|
+
const inBlock = fromLayer(block, field, key);
|
|
142
|
+
if (inBlock !== undefined) {
|
|
143
|
+
if (norm(field, inBlock) === value)
|
|
144
|
+
continue;
|
|
145
|
+
throw conflictError(field, key, inBlock, value, find(which), blockName);
|
|
146
|
+
}
|
|
147
|
+
const toBlock = key !== undefined && isObject(block?.[field]) ?
|
|
148
|
+
blockName
|
|
149
|
+
: undefined;
|
|
150
|
+
const current = toBlock === undefined ?
|
|
151
|
+
fromLayer(target, field, key)
|
|
152
|
+
: undefined;
|
|
153
|
+
if (current !== undefined) {
|
|
154
|
+
if (norm(field, current) === value)
|
|
155
|
+
continue;
|
|
156
|
+
throw conflictError(field, key, current, value, find(which));
|
|
157
|
+
}
|
|
158
|
+
// in effect without saving: the other file's value, unless the
|
|
159
|
+
// target drops it, else the builtin
|
|
160
|
+
const inOther = (toBlock !== undefined ||
|
|
161
|
+
isNulled(target, field, key) ||
|
|
162
|
+
(key === undefined && !otherSelectors)) ?
|
|
163
|
+
undefined
|
|
164
|
+
: fromLayer(other, field, key);
|
|
165
|
+
const builtin = key !== undefined ? builtins[field]?.[key]
|
|
166
|
+
: field === 'default-registry-alias' ? defaultRegistryName
|
|
167
|
+
: undefined;
|
|
168
|
+
const inEffect = inOther ?? builtin;
|
|
169
|
+
if (inEffect !== undefined && norm(field, inEffect) === value) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
let dest = staged;
|
|
173
|
+
if (toBlock !== undefined) {
|
|
174
|
+
const cmds = (staged.command ??= {});
|
|
175
|
+
dest = cmds[toBlock] ??= {};
|
|
176
|
+
}
|
|
177
|
+
if (key === undefined)
|
|
178
|
+
dest[field] = value;
|
|
179
|
+
else {
|
|
180
|
+
const rec = (dest[field] ??= {});
|
|
181
|
+
rec[key] = value;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (!Object.keys(staged).length)
|
|
186
|
+
return undefined;
|
|
187
|
+
// a project layer that sets any selection field owns selection, which
|
|
188
|
+
// would drop the user's registry / default-registry-alias. keep them,
|
|
189
|
+
// with the alias url, so the project file is self contained.
|
|
190
|
+
const { user } = conf.layers;
|
|
191
|
+
if (which === 'project' &&
|
|
192
|
+
ownsSelection(staged) &&
|
|
193
|
+
!ownsSelection(target)) {
|
|
194
|
+
for (const f of registrySelectors) {
|
|
195
|
+
const v = fromLayer(user, f);
|
|
196
|
+
if (v !== undefined && !(f in staged))
|
|
197
|
+
staged[f] = v;
|
|
198
|
+
}
|
|
199
|
+
const alias = staged['default-registry-alias'];
|
|
200
|
+
const url = alias && fromLayer(user, 'registries', alias);
|
|
201
|
+
const regs = (staged.registries ?? {});
|
|
202
|
+
if (url && !(alias in regs)) {
|
|
203
|
+
staged.registries = { ...regs, [alias]: url };
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return { which, values: staged };
|
|
207
|
+
};
|
|
208
|
+
const entries = (path, v) => isObject(v) ?
|
|
209
|
+
Object.entries(v).flatMap(([k, x]) => entries(`${path}.${k}`, x))
|
|
210
|
+
: [`${path}=${redact(String(v))}`];
|
|
211
|
+
/** `field=value` / `field.key=value` lines for a plan's values. */
|
|
212
|
+
export const persistedEntries = (values) => Object.entries(values).flatMap(([f, v]) => entries(f, v));
|
package/dist/print-err.js
CHANGED
|
@@ -167,15 +167,22 @@ const printCode = (err, usage, stderr, format) => {
|
|
|
167
167
|
return { file: true };
|
|
168
168
|
}
|
|
169
169
|
case 'ENEEDAUTH': {
|
|
170
|
-
const { url } = err.cause;
|
|
170
|
+
const { url, method, status } = err.cause;
|
|
171
171
|
stderr(`Authentication Error: ${err.message}`);
|
|
172
172
|
if (url) {
|
|
173
173
|
stderr(indent(`URL: ${formatURL(url, format)}`));
|
|
174
174
|
}
|
|
175
|
+
if (method) {
|
|
176
|
+
stderr(indent(`Method: ${format(method)}`));
|
|
177
|
+
}
|
|
178
|
+
// a 401 and a 403 mean very different things to a user
|
|
179
|
+
if (status) {
|
|
180
|
+
stderr(indent(`Status: ${format(status)}`));
|
|
181
|
+
}
|
|
175
182
|
return {};
|
|
176
183
|
}
|
|
177
184
|
case 'EREQUEST': {
|
|
178
|
-
const { url, method } = err.cause;
|
|
185
|
+
const { url, method, status } = err.cause;
|
|
179
186
|
const { code, syscall } = err.cause.cause ?? {};
|
|
180
187
|
stderr(`Request Error: ${err.message}`);
|
|
181
188
|
if (code) {
|
|
@@ -190,6 +197,11 @@ const printCode = (err, usage, stderr, format) => {
|
|
|
190
197
|
if (method) {
|
|
191
198
|
stderr(indent(`Method: ${format(method)}`));
|
|
192
199
|
}
|
|
200
|
+
// set whenever the registry actually answered; its absence is
|
|
201
|
+
// what distinguishes a transport failure from a response.
|
|
202
|
+
if (status) {
|
|
203
|
+
stderr(indent(`Status: ${format(status)}`));
|
|
204
|
+
}
|
|
193
205
|
return { file: true };
|
|
194
206
|
}
|
|
195
207
|
case 'EQUERY': {
|
|
@@ -5,6 +5,7 @@ import { reloadConfig } from "./reload-config.js";
|
|
|
5
5
|
import { actual, createVirtualRoot } from '@vltpkg/graph';
|
|
6
6
|
import { SecurityArchive } from '@vltpkg/security-archive';
|
|
7
7
|
import { error } from '@vltpkg/error-cause';
|
|
8
|
+
import { isVltInstalled } from "./is-vlt-installed.js";
|
|
8
9
|
// In restricted environments (like locked-down Codespaces),
|
|
9
10
|
// homedir() might fail. Fall back to parent directory.
|
|
10
11
|
let foundHome;
|
|
@@ -14,11 +15,6 @@ try {
|
|
|
14
15
|
}
|
|
15
16
|
catch { }
|
|
16
17
|
const home = foundHome ?? posix.dirname(posix.format(parse(process.cwd())));
|
|
17
|
-
const isVltInstalled = (folder) => !!folder.resolve('node_modules/.vlt').lstatSync()?.isDirectory() ||
|
|
18
|
-
!!folder
|
|
19
|
-
.resolve('node_modules/.vlt-lock.json')
|
|
20
|
-
.lstatSync()
|
|
21
|
-
?.isFile();
|
|
22
18
|
/**
|
|
23
19
|
* Generates possible project keys for a given folder.
|
|
24
20
|
*/
|
|
@@ -96,7 +92,7 @@ export const createHostContextsMap = async (conf) => {
|
|
|
96
92
|
try {
|
|
97
93
|
const config = await reloadConfig(folder.fullpath());
|
|
98
94
|
// only include projects that are vlt-installed
|
|
99
|
-
if (!isVltInstalled(folder)) {
|
|
95
|
+
if (!isVltInstalled(folder.fullpath())) {
|
|
100
96
|
continue;
|
|
101
97
|
}
|
|
102
98
|
// load each individual graph
|
|
@@ -5,6 +5,18 @@ import type { LoadedConfig } from './config/index.ts';
|
|
|
5
5
|
* everywhere a registry is required but missing.
|
|
6
6
|
*/
|
|
7
7
|
export declare const missingRegistryError: () => Error;
|
|
8
|
+
/** Ensure a registry URL ends with a single trailing slash. */
|
|
9
|
+
export declare const normalizeRegistryURL: (url: string) => string;
|
|
10
|
+
/**
|
|
11
|
+
* A spec used a `name:` prefix that no registry alias or git host
|
|
12
|
+
* defines.
|
|
13
|
+
*/
|
|
14
|
+
export declare const unknownSpecPrefixError: (prefix: string, spec: string, validOptions?: unknown[]) => Error;
|
|
15
|
+
/**
|
|
16
|
+
* Turn a spec parse error about an unknown `name:` prefix into
|
|
17
|
+
* {@link unknownSpecPrefixError}. Other values are returned as is.
|
|
18
|
+
*/
|
|
19
|
+
export declare const asUnknownSpecPrefix: (er: unknown) => unknown;
|
|
8
20
|
/**
|
|
9
21
|
* Install-related commands need the alias that bare specs resolve
|
|
10
22
|
* through (not merely some other configured registry) so packages and
|
package/dist/require-registry.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { error } from '@vltpkg/error-cause';
|
|
2
|
+
import { isErrorWithCause, isObject } from '@vltpkg/types';
|
|
2
3
|
import { defaultRegistries, defaultRegistryName } from '@vltpkg/spec';
|
|
3
4
|
import { selectRegistry } from "./select-registry.js";
|
|
4
5
|
/**
|
|
@@ -12,6 +13,34 @@ export const missingRegistryError = () => error([
|
|
|
12
13
|
'',
|
|
13
14
|
'See https://docs.vlt.sh/cli for other ways to set a registry.',
|
|
14
15
|
].join('\n'), { code: 'ECONFIG' });
|
|
16
|
+
/** Ensure a registry URL ends with a single trailing slash. */
|
|
17
|
+
export const normalizeRegistryURL = (url) => url.replace(/\/*$/, '/');
|
|
18
|
+
/**
|
|
19
|
+
* A spec used a `name:` prefix that no registry alias or git host
|
|
20
|
+
* defines.
|
|
21
|
+
*/
|
|
22
|
+
export const unknownSpecPrefixError = (prefix, spec, validOptions) => error([
|
|
23
|
+
`Unknown spec prefix "${prefix}:" in "${spec}".`,
|
|
24
|
+
'',
|
|
25
|
+
`Define it with \`--registries ${prefix}=<url>\` or`,
|
|
26
|
+
`\`--git-hosts ${prefix}=<template>\` (add \`--save-config\` to keep`,
|
|
27
|
+
`it in vlt.json), or run \`vlt config set registries.${prefix}=<url>\`.`,
|
|
28
|
+
].join('\n'), { code: 'ECONFIG', found: `${prefix}:`, validOptions });
|
|
29
|
+
/**
|
|
30
|
+
* Turn a spec parse error about an unknown `name:` prefix into
|
|
31
|
+
* {@link unknownSpecPrefixError}. Other values are returned as is.
|
|
32
|
+
*/
|
|
33
|
+
export const asUnknownSpecPrefix = (er) => {
|
|
34
|
+
const { found, spec, validOptions } = (isErrorWithCause(er) && isObject(er.cause) ?
|
|
35
|
+
er.cause
|
|
36
|
+
: {});
|
|
37
|
+
return (typeof found === 'string' &&
|
|
38
|
+
/^[^:]+:$/.test(found) &&
|
|
39
|
+
typeof spec === 'string' &&
|
|
40
|
+
er.message.startsWith('Protocol ')) ?
|
|
41
|
+
unknownSpecPrefixError(found.slice(0, -1), spec, validOptions)
|
|
42
|
+
: er;
|
|
43
|
+
};
|
|
15
44
|
/**
|
|
16
45
|
* Install-related commands need the alias that bare specs resolve
|
|
17
46
|
* through (not merely some other configured registry) so packages and
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vltpkg/cli-sdk",
|
|
3
3
|
"description": "The source for the vlt CLI",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.1",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/vltpkg/vltpkg.git",
|
|
@@ -14,30 +14,30 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@resvg/resvg-wasm": "^2.6.2",
|
|
17
|
-
"@vltpkg/config": "1.
|
|
18
|
-
"@vltpkg/dep-id": "1.
|
|
19
|
-
"@vltpkg/dot-prop": "1.
|
|
20
|
-
"@vltpkg/error-cause": "1.
|
|
21
|
-
"@vltpkg/git": "1.
|
|
22
|
-
"@vltpkg/graph": "1.
|
|
23
|
-
"@vltpkg/graph-run": "1.
|
|
24
|
-
"@vltpkg/init": "1.
|
|
25
|
-
"@vltpkg/output": "1.
|
|
26
|
-
"@vltpkg/package-info": "1.
|
|
27
|
-
"@vltpkg/package-json": "1.
|
|
28
|
-
"@vltpkg/promise-spawn": "1.
|
|
29
|
-
"@vltpkg/query": "1.
|
|
30
|
-
"@vltpkg/registry-client": "1.
|
|
31
|
-
"@vltpkg/rollback-remove": "1.
|
|
32
|
-
"@vltpkg/run": "1.
|
|
33
|
-
"@vltpkg/security-archive": "1.
|
|
34
|
-
"@vltpkg/spec": "1.
|
|
35
|
-
"@vltpkg/types": "1.
|
|
36
|
-
"@vltpkg/url-open": "1.
|
|
37
|
-
"@vltpkg/vlt-json": "1.
|
|
38
|
-
"@vltpkg/vlx": "1.
|
|
39
|
-
"@vltpkg/workspaces": "1.
|
|
40
|
-
"@vltpkg/xdg": "1.
|
|
17
|
+
"@vltpkg/config": "1.1.1",
|
|
18
|
+
"@vltpkg/dep-id": "1.1.1",
|
|
19
|
+
"@vltpkg/dot-prop": "1.1.1",
|
|
20
|
+
"@vltpkg/error-cause": "1.1.1",
|
|
21
|
+
"@vltpkg/git": "1.1.1",
|
|
22
|
+
"@vltpkg/graph": "1.1.1",
|
|
23
|
+
"@vltpkg/graph-run": "1.1.1",
|
|
24
|
+
"@vltpkg/init": "1.1.1",
|
|
25
|
+
"@vltpkg/output": "1.1.1",
|
|
26
|
+
"@vltpkg/package-info": "1.1.1",
|
|
27
|
+
"@vltpkg/package-json": "1.1.1",
|
|
28
|
+
"@vltpkg/promise-spawn": "1.1.1",
|
|
29
|
+
"@vltpkg/query": "1.1.1",
|
|
30
|
+
"@vltpkg/registry-client": "1.1.1",
|
|
31
|
+
"@vltpkg/rollback-remove": "1.1.1",
|
|
32
|
+
"@vltpkg/run": "1.1.1",
|
|
33
|
+
"@vltpkg/security-archive": "1.1.1",
|
|
34
|
+
"@vltpkg/spec": "1.1.1",
|
|
35
|
+
"@vltpkg/types": "1.1.1",
|
|
36
|
+
"@vltpkg/url-open": "1.1.1",
|
|
37
|
+
"@vltpkg/vlt-json": "1.1.1",
|
|
38
|
+
"@vltpkg/vlx": "1.1.1",
|
|
39
|
+
"@vltpkg/workspaces": "1.1.1",
|
|
40
|
+
"@vltpkg/xdg": "1.1.1",
|
|
41
41
|
"ansi-to-pre": "^1.0.6",
|
|
42
42
|
"beautiful-mermaid": "^1.1.3",
|
|
43
43
|
"chalk": "^5.6.2",
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { STATUS_CODES } from 'node:http';
|
|
2
|
-
export const registryErrorMessage = (response) => {
|
|
3
|
-
const statusMessage = STATUS_CODES[response.statusCode];
|
|
4
|
-
const status = `${response.statusCode}${statusMessage ? ` ${statusMessage}` : ''}`;
|
|
5
|
-
let text;
|
|
6
|
-
try {
|
|
7
|
-
text = response.text().trim();
|
|
8
|
-
}
|
|
9
|
-
catch {
|
|
10
|
-
return status;
|
|
11
|
-
}
|
|
12
|
-
if (!text)
|
|
13
|
-
return status;
|
|
14
|
-
let detail = text;
|
|
15
|
-
try {
|
|
16
|
-
const body = JSON.parse(text);
|
|
17
|
-
if (body &&
|
|
18
|
-
typeof body === 'object' &&
|
|
19
|
-
'error' in body &&
|
|
20
|
-
typeof body.error === 'string' &&
|
|
21
|
-
body.error) {
|
|
22
|
-
detail = body.error;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
// A non-JSON response body is itself the most useful error detail.
|
|
27
|
-
}
|
|
28
|
-
return `${status} — ${detail}`;
|
|
29
|
-
};
|