@vltpkg/package-info 1.0.0-rc.32 → 1.0.0-rc.34
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/index.js +49 -44
- package/package.json +21 -14
package/dist/index.js
CHANGED
|
@@ -18,6 +18,13 @@ const xdg = new XDG('vlt');
|
|
|
18
18
|
export const delimiter = '~';
|
|
19
19
|
// the maximum duration of a manifest cache file
|
|
20
20
|
const manifestCacheMaxAge = 5 * 60 * 1000;
|
|
21
|
+
/**
|
|
22
|
+
* There is no default registry. Anything that needs to build a registry
|
|
23
|
+
* URL fails with a `ECONFIG` error when none has been configured.
|
|
24
|
+
*/
|
|
25
|
+
const noRegistryError = (spec) => error('No registry configured to resolve this spec. Set "registry" in ' +
|
|
26
|
+
'vlt.json, pass --registry, or run `vlt login --registry=<url>`. ' +
|
|
27
|
+
'See https://docs.vlt.sh/cli', { code: 'ECONFIG', spec });
|
|
21
28
|
export class PackageInfoClient {
|
|
22
29
|
#registryClient;
|
|
23
30
|
#projectRoot;
|
|
@@ -29,6 +36,7 @@ export class PackageInfoClient {
|
|
|
29
36
|
#trustedIntegrities = new Map();
|
|
30
37
|
#manifestCacheMinAge = Date.now() - manifestCacheMaxAge;
|
|
31
38
|
#cachePath;
|
|
39
|
+
#packumentPromises = new Map();
|
|
32
40
|
get registryClient() {
|
|
33
41
|
if (!this.#registryClient) {
|
|
34
42
|
this.#registryClient = new RegistryClient(this.options);
|
|
@@ -109,7 +117,10 @@ export class PackageInfoClient {
|
|
|
109
117
|
...(useCache === false ? { useCache } : {}),
|
|
110
118
|
});
|
|
111
119
|
if (response.statusCode !== 200) {
|
|
112
|
-
throw this.#resolveError(spec, options,
|
|
120
|
+
throw this.#resolveError(spec, options, `Registry returned HTTP ${response.statusCode} when ` +
|
|
121
|
+
`fetching the tarball for ${spec}. The resolved version ` +
|
|
122
|
+
`may have been unpublished, or the registry may be ` +
|
|
123
|
+
`misconfigured or unreachable.`, {
|
|
113
124
|
url: r.resolved,
|
|
114
125
|
response,
|
|
115
126
|
});
|
|
@@ -272,7 +283,7 @@ export class PackageInfoClient {
|
|
|
272
283
|
if (options.arch) {
|
|
273
284
|
extra += `${delimiter}arch:${options.arch}`;
|
|
274
285
|
}
|
|
275
|
-
return encodeURIComponent(`${spec.registry}${delimiter}${spec}${extra}`);
|
|
286
|
+
return encodeURIComponent(`${spec.registry ?? ''}${delimiter}${spec}${extra}`);
|
|
276
287
|
}
|
|
277
288
|
/**
|
|
278
289
|
* Conditionally return the path to the manifest cache file. The logic
|
|
@@ -293,30 +304,6 @@ export class PackageInfoClient {
|
|
|
293
304
|
const key = this.#manifestCacheKey(f, options);
|
|
294
305
|
return pathResolve(this.#cachePath, 'package-info', key);
|
|
295
306
|
}
|
|
296
|
-
async #registryManifestRequest(spec, options) {
|
|
297
|
-
const { registry, name, registrySpec } = spec.final;
|
|
298
|
-
/* c8 ignore start */
|
|
299
|
-
if (!spec.range?.isSingle || !registrySpec) {
|
|
300
|
-
throw this.#resolveError(spec, options, 'failed to request manifest', { spec });
|
|
301
|
-
}
|
|
302
|
-
/* c8 ignore stop */
|
|
303
|
-
const possibleLeadingChars = ['=', '^', '~', 'v'];
|
|
304
|
-
const hasLeadingRange = possibleLeadingChars.some(char => registrySpec.startsWith(char));
|
|
305
|
-
const version = hasLeadingRange ? registrySpec.slice(1) : registrySpec;
|
|
306
|
-
const pakuURL = new URL(`${name}/${version}`, registry);
|
|
307
|
-
const response = await this.registryClient.request(pakuURL, {
|
|
308
|
-
headers: {
|
|
309
|
-
accept: 'application/json',
|
|
310
|
-
},
|
|
311
|
-
});
|
|
312
|
-
if (response.statusCode !== 200) {
|
|
313
|
-
throw this.#resolveError(spec, options, 'failed to fetch manifest', {
|
|
314
|
-
url: pakuURL,
|
|
315
|
-
response,
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
return response.json();
|
|
319
|
-
}
|
|
320
307
|
async tarball(spec, options = {}) {
|
|
321
308
|
if (typeof spec === 'string')
|
|
322
309
|
spec = Spec.parse(spec, this.options);
|
|
@@ -325,10 +312,14 @@ export class PackageInfoClient {
|
|
|
325
312
|
case 'registry': {
|
|
326
313
|
const { dist } = await this.manifest(spec, options);
|
|
327
314
|
if (!dist)
|
|
328
|
-
throw this.#resolveError(spec, options,
|
|
315
|
+
throw this.#resolveError(spec, options, `The registry manifest for ${spec} has no "dist" section, ` +
|
|
316
|
+
`so no tarball can be resolved. The package version may be ` +
|
|
317
|
+
`malformed or unpublished.`);
|
|
329
318
|
const { tarball, integrity } = dist;
|
|
330
319
|
if (!tarball) {
|
|
331
|
-
throw this.#resolveError(spec, options,
|
|
320
|
+
throw this.#resolveError(spec, options, `The registry manifest for ${spec} is missing a tarball URL ` +
|
|
321
|
+
`(dist.tarball). The package version may be malformed or ` +
|
|
322
|
+
`unpublished in this registry.`);
|
|
332
323
|
}
|
|
333
324
|
const fetchTarball = async (useCache) => {
|
|
334
325
|
const trustIntegrity = this.#trustedIntegrities.get(tarball) === integrity;
|
|
@@ -339,7 +330,10 @@ export class PackageInfoClient {
|
|
|
339
330
|
...(useCache === false ? { useCache } : {}),
|
|
340
331
|
});
|
|
341
332
|
if (response.statusCode !== 200) {
|
|
342
|
-
throw this.#resolveError(spec, options,
|
|
333
|
+
throw this.#resolveError(spec, options, `Registry returned HTTP ${response.statusCode} when ` +
|
|
334
|
+
`fetching the tarball for ${spec} at ${tarball}. The ` +
|
|
335
|
+
`version may have been unpublished, or the registry may ` +
|
|
336
|
+
`be misconfigured or unreachable.`, { response, url: tarball });
|
|
343
337
|
}
|
|
344
338
|
// if we don't already trust it, but it's valid, start
|
|
345
339
|
// trusting it
|
|
@@ -474,9 +468,7 @@ export class PackageInfoClient {
|
|
|
474
468
|
// Cache miss, fetch from packument
|
|
475
469
|
}
|
|
476
470
|
}
|
|
477
|
-
const mani =
|
|
478
|
-
await this.#registryManifestRequest(spec, options)
|
|
479
|
-
: pickManifest(await this.packument(f, options), spec, options);
|
|
471
|
+
const mani = pickManifest(await this.packument(f, options), spec, options);
|
|
480
472
|
if (!mani)
|
|
481
473
|
throw this.#resolveError(spec, options);
|
|
482
474
|
// Cache the manifest data
|
|
@@ -606,22 +598,35 @@ export class PackageInfoClient {
|
|
|
606
598
|
}
|
|
607
599
|
case 'registry': {
|
|
608
600
|
const { registry, name } = f;
|
|
601
|
+
if (!registry)
|
|
602
|
+
throw noRegistryError(spec);
|
|
603
|
+
const packumentKey = `${registry}${name}`;
|
|
604
|
+
const inflight = this.#packumentPromises.get(packumentKey);
|
|
605
|
+
if (inflight)
|
|
606
|
+
return inflight;
|
|
609
607
|
const pakuURL = new URL(name, registry);
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
url: pakuURL,
|
|
618
|
-
response,
|
|
619
|
-
});
|
|
620
|
-
}
|
|
621
|
-
return response.json();
|
|
608
|
+
const promise = this.#fetchPackument(spec, options, pakuURL);
|
|
609
|
+
this.#packumentPromises.set(packumentKey, promise);
|
|
610
|
+
// Clean up once settled so we don't leak memory.
|
|
611
|
+
// Use .then/.catch instead of .finally to avoid creating
|
|
612
|
+
// an unhandled rejection from the derived promise.
|
|
613
|
+
promise.then(() => this.#packumentPromises.delete(packumentKey), () => this.#packumentPromises.delete(packumentKey));
|
|
614
|
+
return promise;
|
|
622
615
|
}
|
|
623
616
|
}
|
|
624
617
|
}
|
|
618
|
+
async #fetchPackument(spec, options, pakuURL) {
|
|
619
|
+
const response = await this.registryClient.request(pakuURL, {
|
|
620
|
+
headers: { accept: 'application/json' },
|
|
621
|
+
});
|
|
622
|
+
if (response.statusCode !== 200) {
|
|
623
|
+
throw this.#resolveError(spec, options, 'failed to fetch packument', {
|
|
624
|
+
url: pakuURL,
|
|
625
|
+
response,
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
return response.json();
|
|
629
|
+
}
|
|
625
630
|
async resolve(spec, options = {}) {
|
|
626
631
|
const memoKey = String(spec);
|
|
627
632
|
if (typeof spec === 'string')
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vltpkg/package-info",
|
|
3
3
|
"description": "Resolve and fetch package metadata and tarballs",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.34",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/vltpkg/vltpkg.git",
|
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
"url": "http://vlt.sh"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@vltpkg/error-cause": "1.0.0-rc.
|
|
17
|
-
"@vltpkg/git": "1.0.0-rc.
|
|
18
|
-
"@vltpkg/package-json": "1.0.0-rc.
|
|
19
|
-
"@vltpkg/pick-manifest": "1.0.0-rc.
|
|
20
|
-
"@vltpkg/registry-client": "1.0.0-rc.
|
|
21
|
-
"@vltpkg/spec": "1.0.0-rc.
|
|
22
|
-
"@vltpkg/tar": "1.0.0-rc.
|
|
23
|
-
"@vltpkg/types": "1.0.0-rc.
|
|
24
|
-
"@vltpkg/workspaces": "1.0.0-rc.
|
|
25
|
-
"@vltpkg/xdg": "1.0.0-rc.
|
|
16
|
+
"@vltpkg/error-cause": "1.0.0-rc.34",
|
|
17
|
+
"@vltpkg/git": "1.0.0-rc.34",
|
|
18
|
+
"@vltpkg/package-json": "1.0.0-rc.34",
|
|
19
|
+
"@vltpkg/pick-manifest": "1.0.0-rc.34",
|
|
20
|
+
"@vltpkg/registry-client": "1.0.0-rc.34",
|
|
21
|
+
"@vltpkg/spec": "1.0.0-rc.34",
|
|
22
|
+
"@vltpkg/tar": "1.0.0-rc.34",
|
|
23
|
+
"@vltpkg/types": "1.0.0-rc.34",
|
|
24
|
+
"@vltpkg/workspaces": "1.0.0-rc.34",
|
|
25
|
+
"@vltpkg/xdg": "1.0.0-rc.34",
|
|
26
26
|
"ssri": "^13.0.0",
|
|
27
27
|
"tar": "^7.5.2"
|
|
28
28
|
},
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"@types/node": "^22.19.2",
|
|
32
32
|
"@types/pacote": "^11.1.8",
|
|
33
33
|
"@vltpkg/benchmark": "0.0.0",
|
|
34
|
-
"@vltpkg/cache-unzip": "1.0.0-rc.
|
|
35
|
-
"@vltpkg/vlt-json": "1.0.0-rc.
|
|
34
|
+
"@vltpkg/cache-unzip": "1.0.0-rc.34",
|
|
35
|
+
"@vltpkg/vlt-json": "1.0.0-rc.34",
|
|
36
36
|
"eslint": "^9.39.1",
|
|
37
37
|
"pacote": "^21.0.4",
|
|
38
38
|
"prettier": "^3.7.4",
|
|
@@ -73,5 +73,12 @@
|
|
|
73
73
|
},
|
|
74
74
|
"files": [
|
|
75
75
|
"dist"
|
|
76
|
-
]
|
|
76
|
+
],
|
|
77
|
+
"bugs": [
|
|
78
|
+
{
|
|
79
|
+
"type": "link",
|
|
80
|
+
"url": "https://github.com/vltpkg/vltpkg/issues"
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"homepage": "https://github.com/vltpkg/vltpkg/tree/main/src/package-info#readme"
|
|
77
84
|
}
|