@vltpkg/package-info 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/index.d.ts CHANGED
@@ -7,6 +7,20 @@ import type { Pool } from '@vltpkg/tar';
7
7
  import type { Integrity, Manifest, Packument } from '@vltpkg/types';
8
8
  import { Monorepo } from '@vltpkg/workspaces';
9
9
  export declare const delimiter = "~";
10
+ /**
11
+ * Accept header for packument requests. Prefers vlt's abbreviated
12
+ * packument and falls back to the full one on registries that do not
13
+ * know the type. See `PackageInfoClient.#fetchPackument`.
14
+ *
15
+ * The trailing wildcard range carries an explicit `q=0.1` so that it stays
16
+ * below `application/json`. A media range with no `q` defaults to `q=1.0`
17
+ * (RFC 9110 12.5.1), which on a registry that negotiates strictly by
18
+ * quality would let an unrelated representation — npm's corgi among them
19
+ * — outrank the full packument and drop `license`. The wildcard is kept
20
+ * only so a registry that rejects what it cannot satisfy exactly still
21
+ * has something to match.
22
+ */
23
+ export declare const PACKUMENT_ACCEPT = "application/vnd.vlt.packument-v1+json; q=1.0, application/json; q=0.8, */*; q=0.1";
10
24
  export type Resolution = {
11
25
  resolved: string;
12
26
  integrity?: Integrity;
package/dist/index.js CHANGED
@@ -3,6 +3,9 @@ import { clone, resolve as gitResolve, revs } from '@vltpkg/git';
3
3
  import { logRequest } from '@vltpkg/output';
4
4
  import { PackageJson } from '@vltpkg/package-json';
5
5
  import { pickManifest } from '@vltpkg/pick-manifest';
6
+ // subpath import: keeps the lazy `import('@vltpkg/registry-client')`
7
+ // below from becoming an eager dependency on the whole client.
8
+ import { registryErrorMessage } from '@vltpkg/registry-client/registry-error';
6
9
  import { Spec } from '@vltpkg/spec';
7
10
  import { asPackument } from '@vltpkg/types';
8
11
  import ssri from 'ssri';
@@ -17,6 +20,20 @@ import { rename } from "./rename.js";
17
20
  const debug = debuglog('vlt');
18
21
  const xdg = new XDG('vlt');
19
22
  export const delimiter = '~';
23
+ /**
24
+ * Accept header for packument requests. Prefers vlt's abbreviated
25
+ * packument and falls back to the full one on registries that do not
26
+ * know the type. See `PackageInfoClient.#fetchPackument`.
27
+ *
28
+ * The trailing wildcard range carries an explicit `q=0.1` so that it stays
29
+ * below `application/json`. A media range with no `q` defaults to `q=1.0`
30
+ * (RFC 9110 12.5.1), which on a registry that negotiates strictly by
31
+ * quality would let an unrelated representation — npm's corgi among them
32
+ * — outrank the full packument and drop `license`. The wildcard is kept
33
+ * only so a registry that rejects what it cannot satisfy exactly still
34
+ * has something to match.
35
+ */
36
+ export const PACKUMENT_ACCEPT = 'application/vnd.vlt.packument-v1+json; q=1.0, application/json; q=0.8, */*; q=0.1';
20
37
  // the maximum duration of a manifest cache file
21
38
  const manifestCacheMaxAge = 5 * 60 * 1000;
22
39
  /**
@@ -170,7 +187,7 @@ export class PackageInfoClient {
170
187
  ...(useCache === false ? { useCache } : {}),
171
188
  });
172
189
  if (response.statusCode !== 200) {
173
- throw this.#resolveError(spec, options, `Registry returned HTTP ${response.statusCode} when ` +
190
+ throw this.#resolveError(spec, options, `${registryErrorMessage(response)} when ` +
174
191
  `fetching the tarball for ${spec}. The resolved version ` +
175
192
  `may have been unpublished, or the registry may be ` +
176
193
  `misconfigured or unreachable.`, {
@@ -238,7 +255,7 @@ export class PackageInfoClient {
238
255
  case 'remote': {
239
256
  const response = await (await this.getRegistryClient()).request(r.resolved);
240
257
  if (response.statusCode !== 200) {
241
- throw this.#resolveError(spec, options, 'failed to fetch remote tarball', {
258
+ throw this.#resolveError(spec, options, `failed to fetch remote tarball: ${registryErrorMessage(response)}`, {
242
259
  url: r.resolved,
243
260
  response,
244
261
  });
@@ -407,7 +424,7 @@ export class PackageInfoClient {
407
424
  ...(useCache === false ? { useCache } : {}),
408
425
  });
409
426
  if (response.statusCode !== 200) {
410
- throw this.#resolveError(spec, options, `Registry returned HTTP ${response.statusCode} when ` +
427
+ throw this.#resolveError(spec, options, `${registryErrorMessage(response)} when ` +
411
428
  `fetching the tarball for ${spec} at ${tarball}. The ` +
412
429
  `version may have been unpublished, or the registry may ` +
413
430
  `be misconfigured or unreachable.`, { response, url: tarball });
@@ -487,7 +504,7 @@ export class PackageInfoClient {
487
504
  }
488
505
  const response = await (await this.getRegistryClient()).request(remoteURL);
489
506
  if (response.statusCode !== 200) {
490
- throw this.#resolveError(spec, options, 'failed to fetch URL', { response, url: remoteURL });
507
+ throw this.#resolveError(spec, options, `failed to fetch URL: ${registryErrorMessage(response)}`, { response, url: remoteURL });
491
508
  }
492
509
  return response.buffer();
493
510
  }
@@ -586,7 +603,7 @@ export class PackageInfoClient {
586
603
  return await this.#tmpdir(async (dir) => {
587
604
  const response = await (await this.getRegistryClient()).request(remoteURL);
588
605
  if (response.statusCode !== 200) {
589
- throw this.#resolveError(s, options, 'failed to fetch URL', { response, url: remoteURL });
606
+ throw this.#resolveError(s, options, `failed to fetch URL: ${registryErrorMessage(response)}`, { response, url: remoteURL });
590
607
  }
591
608
  const buf = response.buffer();
592
609
  // Compute integrity for remote/git-with-tarball deps
@@ -698,33 +715,27 @@ export class PackageInfoClient {
698
715
  }
699
716
  }
700
717
  async #fetchPackument(spec, options, pakuURL, useCache) {
701
- // Always request the full packument (`application/json`), never the
702
- // abbreviated "corgi" form:
703
- // accept: application/vnd.npm.install-v1+json; q=1.0,
704
- // application/json; q=0.8, */*
705
- //
706
- // Corgi is smaller (~−41% packument bytes, est. 1–3s on clean installs)
707
- // but is disabled for two load-bearing reasons:
708
- //
709
- // 1. Metadata loss reaches the lockfile. The version entry returned
710
- // here is `node.manifest` and is persisted to vlt-lock.json / the
711
- // hidden lockfile. Corgi drops `license` (also `time`, `readme`,
712
- // `maintainers`, `_rev`, `scripts`), so graph queries like
713
- // `[license=MPL-2.0]` cannot match a field that was never stored.
714
- // Shipped in 1.0.0-rc.33 via #1692 (8ba2b10c); 24 false-positive
715
- // edges in the dependency-check job on #1704
716
- // (`@resvg/resvg-wasm@2.6.2` MPL-2.0 in package.json, blank in the
717
- // stored graph); isolated in #1705; reverted in #1707.
718
+ // Request vlt's abbreviated packument, falling back to the full one:
719
+ // accept: application/vnd.vlt.packument-v1+json; q=1.0,
720
+ // application/json; q=0.8, */*; q=0.1
718
721
  //
719
- // 2. The RegistryClient disk cache key is method + URL only — no
720
- // accept, no Vary — so a full-packument request can be served a
721
- // cached abbreviated body (and vice versa).
722
+ // npm's corgi (`application/vnd.npm.install-v1+json`) is never
723
+ // requested. The version entry returned here becomes `node.manifest`
724
+ // and is persisted to the hidden lockfile, and corgi drops `license`
725
+ // and `time`, so graph queries like `[license=MPL-2.0]` could not
726
+ // match a field that was never stored (shipped in 1.0.0-rc.33 via
727
+ // #1692, reverted in #1707). The vlt type guarantees both, and a
728
+ // registry that does not know it ignores it and serves the full
729
+ // packument, so the graph gets every field it relies on either way.
730
+ // The one shape difference is `scripts`, which the vlt type replaces
731
+ // with `hasInstallScript`; reify reads the extracted package.json in
732
+ // that case.
722
733
  //
723
- // To revisit: put the requested representation on both the disk-cache
724
- // key and the in-flight coalescing key, and have the SWR child
725
- // (cache-revalidate / revalidate) re-request the same representation.
734
+ // The RegistryClient disk cache key is method + URL only, so every
735
+ // packument request must use this same accept header, and the SWR
736
+ // revalidation child re-requests the representation it was given.
726
737
  const response = await (await this.getRegistryClient()).request(pakuURL, {
727
- headers: { accept: 'application/json' },
738
+ headers: { accept: PACKUMENT_ACCEPT },
728
739
  ...(useCache === false ? { useCache } : {}),
729
740
  // costs a conditional GET per moving selector on an otherwise warm
730
741
  // cache, install included. 304s are cheap but not free; the
@@ -734,7 +745,7 @@ export class PackageInfoClient {
734
745
  : {}),
735
746
  });
736
747
  if (response.statusCode !== 200) {
737
- throw this.#resolveError(spec, options, 'failed to fetch packument', {
748
+ throw this.#resolveError(spec, options, `failed to fetch packument: ${registryErrorMessage(response)}`, {
738
749
  url: pakuURL,
739
750
  response,
740
751
  });
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.10",
4
+ "version": "1.1.1",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/vltpkg/vltpkg.git",
@@ -13,17 +13,17 @@
13
13
  "url": "http://vlt.sh"
14
14
  },
15
15
  "dependencies": {
16
- "@vltpkg/error-cause": "1.0.10",
17
- "@vltpkg/git": "1.0.10",
18
- "@vltpkg/output": "1.0.10",
19
- "@vltpkg/package-json": "1.0.10",
20
- "@vltpkg/pick-manifest": "1.0.10",
21
- "@vltpkg/registry-client": "1.0.10",
22
- "@vltpkg/spec": "1.0.10",
23
- "@vltpkg/tar": "1.0.10",
24
- "@vltpkg/types": "1.0.10",
25
- "@vltpkg/workspaces": "1.0.10",
26
- "@vltpkg/xdg": "1.0.10",
16
+ "@vltpkg/error-cause": "1.1.1",
17
+ "@vltpkg/git": "1.1.1",
18
+ "@vltpkg/output": "1.1.1",
19
+ "@vltpkg/package-json": "1.1.1",
20
+ "@vltpkg/pick-manifest": "1.1.1",
21
+ "@vltpkg/registry-client": "1.1.1",
22
+ "@vltpkg/spec": "1.1.1",
23
+ "@vltpkg/tar": "1.1.1",
24
+ "@vltpkg/types": "1.1.1",
25
+ "@vltpkg/workspaces": "1.1.1",
26
+ "@vltpkg/xdg": "1.1.1",
27
27
  "ssri": "^13.0.0",
28
28
  "tar": "^7.5.2"
29
29
  },
@@ -32,8 +32,8 @@
32
32
  "@types/node": "^22.19.2",
33
33
  "@types/pacote": "^11.1.8",
34
34
  "@vltpkg/benchmark": "0.0.0",
35
- "@vltpkg/cache-unzip": "1.0.10",
36
- "@vltpkg/vlt-json": "1.0.10",
35
+ "@vltpkg/cache-unzip": "1.1.1",
36
+ "@vltpkg/vlt-json": "1.1.1",
37
37
  "eslint": "^9.39.1",
38
38
  "pacote": "^21.0.4",
39
39
  "prettier": "^3.7.4",