@wavehouse/chtypes 2.0.0-dev.0 → 2.0.0-dev.10
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/CHANGELOG.md +85 -0
- package/README.md +5 -1
- package/dist/abi2/buildinfo.d.ts +1 -1
- package/dist/abi2/buildinfo.js +3 -3
- package/dist/abi2/buildinfo.js.map +1 -1
- package/dist/abi2/calls.gen.d.ts +6 -1
- package/dist/abi2/calls.gen.d.ts.map +1 -1
- package/dist/abi2/calls.gen.js +8 -3
- package/dist/abi2/calls.gen.js.map +1 -1
- package/dist/abi2/decls.gen.d.ts +3 -1
- package/dist/abi2/decls.gen.d.ts.map +1 -1
- package/dist/abi2/decls.gen.js +104 -3
- package/dist/abi2/decls.gen.js.map +1 -1
- package/dist/abi2/errmap.gen.js +1 -1
- package/dist/abi2/errors.d.ts +16 -38
- package/dist/abi2/errors.d.ts.map +1 -1
- package/dist/abi2/errors.js +16 -42
- package/dist/abi2/errors.js.map +1 -1
- package/dist/abi2/index.d.ts +2 -2
- package/dist/abi2/index.d.ts.map +1 -1
- package/dist/abi2/index.js +1 -1
- package/dist/abi2/index.js.map +1 -1
- package/dist/abi2/libc.gen.d.ts +2 -0
- package/dist/abi2/libc.gen.d.ts.map +1 -1
- package/dist/abi2/libc.gen.js +11 -1
- package/dist/abi2/libc.gen.js.map +1 -1
- package/dist/abi2/loader.js +2 -2
- package/dist/abi2/loader.js.map +1 -1
- package/dist/abi2/vocab.gen.d.ts +41 -0
- package/dist/abi2/vocab.gen.d.ts.map +1 -1
- package/dist/abi2/vocab.gen.js +65 -1
- package/dist/abi2/vocab.gen.js.map +1 -1
- package/dist/cli.d.ts +11 -5
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +130 -20
- package/dist/cli.js.map +1 -1
- package/dist/documents.d.ts +63 -3
- package/dist/documents.d.ts.map +1 -1
- package/dist/documents.js +79 -4
- package/dist/documents.js.map +1 -1
- package/dist/env.d.ts +8 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +17 -8
- package/dist/env.js.map +1 -1
- package/dist/index.d.ts +9 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/library.d.ts +13 -2
- package/dist/library.d.ts.map +1 -1
- package/dist/library.js +23 -3
- package/dist/library.js.map +1 -1
- package/dist/ocifetch/channel.d.ts +84 -0
- package/dist/ocifetch/channel.d.ts.map +1 -1
- package/dist/ocifetch/channel.js +157 -2
- package/dist/ocifetch/channel.js.map +1 -1
- package/dist/ocifetch/constants.gen.d.ts +28 -0
- package/dist/ocifetch/constants.gen.d.ts.map +1 -1
- package/dist/ocifetch/constants.gen.js +30 -1
- package/dist/ocifetch/constants.gen.js.map +1 -1
- package/dist/ocifetch/dsse.d.ts +5 -1
- package/dist/ocifetch/dsse.d.ts.map +1 -1
- package/dist/ocifetch/dsse.js +10 -3
- package/dist/ocifetch/dsse.js.map +1 -1
- package/dist/ocifetch/ensure.d.ts +68 -8
- package/dist/ocifetch/ensure.d.ts.map +1 -1
- package/dist/ocifetch/ensure.js +305 -66
- package/dist/ocifetch/ensure.js.map +1 -1
- package/dist/ocifetch/errors.d.ts +101 -25
- package/dist/ocifetch/errors.d.ts.map +1 -1
- package/dist/ocifetch/errors.js +74 -36
- package/dist/ocifetch/errors.js.map +1 -1
- package/dist/ocifetch/hold.d.ts +66 -0
- package/dist/ocifetch/hold.d.ts.map +1 -0
- package/dist/ocifetch/hold.js +150 -0
- package/dist/ocifetch/hold.js.map +1 -0
- package/dist/ocifetch/http.d.ts +10 -2
- package/dist/ocifetch/http.d.ts.map +1 -1
- package/dist/ocifetch/http.js +31 -12
- package/dist/ocifetch/http.js.map +1 -1
- package/dist/ocifetch/index.d.ts +10 -5
- package/dist/ocifetch/index.d.ts.map +1 -1
- package/dist/ocifetch/index.js +8 -3
- package/dist/ocifetch/index.js.map +1 -1
- package/dist/ocifetch/localverify.d.ts +3 -1
- package/dist/ocifetch/localverify.d.ts.map +1 -1
- package/dist/ocifetch/localverify.js +6 -1
- package/dist/ocifetch/localverify.js.map +1 -1
- package/dist/ocifetch/lock.d.ts +2 -1
- package/dist/ocifetch/lock.d.ts.map +1 -1
- package/dist/ocifetch/lock.js +7 -5
- package/dist/ocifetch/lock.js.map +1 -1
- package/dist/ocifetch/oci.d.ts +45 -3
- package/dist/ocifetch/oci.d.ts.map +1 -1
- package/dist/ocifetch/oci.js +125 -58
- package/dist/ocifetch/oci.js.map +1 -1
- package/dist/ocifetch/prune.d.ts +48 -0
- package/dist/ocifetch/prune.d.ts.map +1 -0
- package/dist/ocifetch/prune.js +383 -0
- package/dist/ocifetch/prune.js.map +1 -0
- package/dist/ocifetch/referrers.d.ts +24 -0
- package/dist/ocifetch/referrers.d.ts.map +1 -1
- package/dist/ocifetch/referrers.js +92 -5
- package/dist/ocifetch/referrers.js.map +1 -1
- package/dist/ocifetch/resolve.d.ts +37 -0
- package/dist/ocifetch/resolve.d.ts.map +1 -0
- package/dist/ocifetch/resolve.js +90 -0
- package/dist/ocifetch/resolve.js.map +1 -0
- package/dist/ocifetch/retired.d.ts +61 -0
- package/dist/ocifetch/retired.d.ts.map +1 -0
- package/dist/ocifetch/retired.js +236 -0
- package/dist/ocifetch/retired.js.map +1 -0
- package/dist/ocifetch/revocation.d.ts +151 -0
- package/dist/ocifetch/revocation.d.ts.map +1 -0
- package/dist/ocifetch/revocation.js +481 -0
- package/dist/ocifetch/revocation.js.map +1 -0
- package/dist/ocifetch/types.d.ts +18 -2
- package/dist/ocifetch/types.d.ts.map +1 -1
- package/dist/ocifetch/types.js.map +1 -1
- package/dist/registry.d.ts +80 -3
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +168 -9
- package/dist/registry.js.map +1 -1
- package/dist/schema.d.ts +10 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js.map +1 -1
- package/dist/server.d.ts +27 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +35 -0
- package/dist/server.js.map +1 -0
- package/dist/settings.d.ts +21 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +35 -0
- package/dist/settings.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chtypes resolve` (`docs/guides/fetch-v1.md` §3, "What a request resolves
|
|
3
|
+
* to"; public issue #493): what a line, a patch or an exact version resolves
|
|
4
|
+
* to on every platform the registry offers, each verified exactly as a fetch
|
|
5
|
+
* verifies it (§4), and never a layer downloaded. Offline it is the cache's
|
|
6
|
+
* answer instead, the lookup an open makes.
|
|
7
|
+
*/
|
|
8
|
+
import { noteIgnoredOverrides, offlineMode } from './channel.js';
|
|
9
|
+
import { PLATFORMS } from './constants.gen.js';
|
|
10
|
+
import { missingNotes, requestOptionsFor, resolveBases, resolveInstalled, verifyManifestTrust, withNotes } from './ensure.js';
|
|
11
|
+
import { ArtifactMissingError, ArtifactUnpublishedError } from './errors.js';
|
|
12
|
+
import { unwritable } from './faults.js';
|
|
13
|
+
import { cacheRoot } from './layout.js';
|
|
14
|
+
import { checkSpelling, fetchManifestBytesByDigest, parseManifest, resolveIndex, selectPlatformDescriptor } from './oci.js';
|
|
15
|
+
/**
|
|
16
|
+
* What `spelling` resolves to, one `Resolution` per platform, in the
|
|
17
|
+
* constants' platform order. Online it resolves the index (through the dev
|
|
18
|
+
* channel's alias first, §3), and for each platform the index offers it
|
|
19
|
+
* fetches the manifest by digest and verifies its signed statement against the
|
|
20
|
+
* request (§4), exactly as `ensure` does; no layer is requested and nothing is
|
|
21
|
+
* written. A platform the index does not offer is left out, and an index that
|
|
22
|
+
* offers none of them is `ArtifactUnpublishedError`. Offline it answers from
|
|
23
|
+
* the cache: each platform's `resolveInstalled`, and `ArtifactMissingError`
|
|
24
|
+
* when no platform has an installed build. A refused spelling is refused
|
|
25
|
+
* first, before anything is read (`SpellingRefusedError`).
|
|
26
|
+
*/
|
|
27
|
+
export async function resolveBuilds(spelling, options = {}) {
|
|
28
|
+
noteIgnoredOverrides(options);
|
|
29
|
+
try {
|
|
30
|
+
return await resolveIn(spelling, options);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
// An offline lookup may verify a pre-seeded entry into the cache: a write
|
|
34
|
+
// that failed there is one class in every mode, as for `ensure`.
|
|
35
|
+
throw await unwritable(err, cacheRoot(options.cacheDir));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function resolveIn(spelling, options) {
|
|
39
|
+
checkSpelling(spelling);
|
|
40
|
+
if (offlineMode(options.offline)) {
|
|
41
|
+
const resolutions = [];
|
|
42
|
+
for (const p of PLATFORMS) {
|
|
43
|
+
const hit = await resolveInstalled(spelling, p.key, options);
|
|
44
|
+
if (hit !== undefined) {
|
|
45
|
+
resolutions.push({ platform: p.key, version: hit.version, build: hit.build, manifest: hit.digests.manifest });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (resolutions.length === 0) {
|
|
49
|
+
throw new ArtifactMissingError(withNotes(`chtypes: no installed artifact for ${spelling} on any platform, and --offline forbids a network fetch`, await missingNotes(options)));
|
|
50
|
+
}
|
|
51
|
+
return { resolutions, warnings: [] };
|
|
52
|
+
}
|
|
53
|
+
const bases = resolveBases(options);
|
|
54
|
+
const baseReqOptions = requestOptionsFor(options, bases);
|
|
55
|
+
const reqOptions = { ...baseReqOptions, maxBytes: 0 };
|
|
56
|
+
const index = await resolveIndex(bases, spelling, reqOptions);
|
|
57
|
+
const resolutions = [];
|
|
58
|
+
const warnings = [];
|
|
59
|
+
for (const p of PLATFORMS) {
|
|
60
|
+
let descriptor;
|
|
61
|
+
try {
|
|
62
|
+
descriptor = selectPlatformDescriptor(index, spelling, p.key);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
if (err instanceof ArtifactUnpublishedError)
|
|
66
|
+
continue; // the index does not offer this platform
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
const manifest = parseManifest(descriptor.digest, await fetchManifestBytesByDigest(bases, descriptor, reqOptions));
|
|
70
|
+
// Under allow-unsigned with no verified statement, the version and build
|
|
71
|
+
// are the config blob's, as an unsigned install records them.
|
|
72
|
+
const verified = await verifyManifestTrust(index.repositoryRoot, manifest, index.aliasAbsent, p.key, spelling, options, baseReqOptions);
|
|
73
|
+
warnings.push(...verified.warnings);
|
|
74
|
+
resolutions.push({
|
|
75
|
+
platform: p.key,
|
|
76
|
+
version: stringMember(verified.predicate.clickhouse_version),
|
|
77
|
+
build: stringMember(verified.predicate.build),
|
|
78
|
+
manifest: manifest.digest,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (resolutions.length === 0) {
|
|
82
|
+
throw new ArtifactUnpublishedError(`chtypes: the index for ${spelling} offers no platform this SDK knows`);
|
|
83
|
+
}
|
|
84
|
+
return { resolutions, warnings };
|
|
85
|
+
}
|
|
86
|
+
/** A predicate member read as the signed statement holds it: its text, or `''` for anything that is not a string. */
|
|
87
|
+
function stringMember(v) {
|
|
88
|
+
return typeof v === 'string' ? v : '';
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/ocifetch/resolve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A retired repository (`docs/guides/fetch-v1.md` §2, "A retired repository";
|
|
3
|
+
* public issue #571). The registry's operator answers every route of a
|
|
4
|
+
* retired repository with 410 Gone (`RETIRED_STATUSES`) and a short error
|
|
5
|
+
* document. That is permanent: `http.ts` never retries it and throws
|
|
6
|
+
* `SourceRetiredError`, which every loop over bases or candidates lets
|
|
7
|
+
* through, so the caller sees the URL that answered and the registry's own
|
|
8
|
+
* message, made safe to print by `retiredMessage`, the one function every
|
|
9
|
+
* binding has (`tests/fixtures/retired-message/cases.json` is the table all
|
|
10
|
+
* four answer alike).
|
|
11
|
+
*/
|
|
12
|
+
import type * as http from 'node:http';
|
|
13
|
+
import { type Advisory, ArtifactRevokedError, type FetchV1Error, SourceRetiredError } from './errors.js';
|
|
14
|
+
/** Is this status a retired repository's? */
|
|
15
|
+
export declare function isRetiredStatus(status: number): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The registry's own message in a retired repository's response body, made
|
|
18
|
+
* safe to print, or `null` when it sent none. `body` is what was read of it
|
|
19
|
+
* (at most `RETIRED_BODY_MAX_BYTES`). When it is UTF-8 JSON whose
|
|
20
|
+
* `errors[0].message` is a string, that string is the message: every code
|
|
21
|
+
* point in U+0000-U+001F, U+007F-U+009F, U+200E, U+200F, U+202A-U+202E and
|
|
22
|
+
* U+2066-U+2069 is removed, and the rest is cut to
|
|
23
|
+
* `RETIRED_MESSAGE_MAX_CODE_POINTS` code points, with U+2026 appended when it
|
|
24
|
+
* was cut. Nothing else is changed, and an empty result is no message.
|
|
25
|
+
*/
|
|
26
|
+
export declare function retiredMessage(body: Uint8Array): string | null;
|
|
27
|
+
/**
|
|
28
|
+
* `text` made safe to print, the retired message's rule for every served
|
|
29
|
+
* string: every code point in U+0000-U+001F, U+007F-U+009F, U+200E, U+200F,
|
|
30
|
+
* U+202A-U+202E and U+2066-U+2069 removed, then cut to
|
|
31
|
+
* `RETIRED_MESSAGE_MAX_CODE_POINTS` code points with U+2026 appended when it was
|
|
32
|
+
* cut. A string holding a lone surrogate is not Unicode text and is `''`, as is
|
|
33
|
+
* one that is empty once made safe.
|
|
34
|
+
*/
|
|
35
|
+
export declare function sanitizeRetiredText(text: string): string;
|
|
36
|
+
/** The error text for a retired repository's answer: the URL and status that answered, and the registry's message when it sent one. */
|
|
37
|
+
export declare function retiredText(url: string, status: number, body: Uint8Array): string;
|
|
38
|
+
/**
|
|
39
|
+
* A 410's body read as a revocation (guide, "Build-level revocation", "A `410`
|
|
40
|
+
* on a tag"): `undefined` unless it is UTF-8 JSON whose `errors[0].detail.revoked`
|
|
41
|
+
* is an object; otherwise that object's advisories, each field made safe, and one
|
|
42
|
+
* that is absent, not a string, empty once made safe or a lone surrogate left
|
|
43
|
+
* `''`. An entry that is not an object, or leaves every field empty, is skipped.
|
|
44
|
+
* A repeated key reads as its last value, and a byte order mark is not JSON.
|
|
45
|
+
* `tests/fixtures/revoked-410/cases.json` is the table all four bindings answer
|
|
46
|
+
* alike.
|
|
47
|
+
*/
|
|
48
|
+
export declare function revoked410(body: Uint8Array): readonly Advisory[] | undefined;
|
|
49
|
+
/** What follows `<url> answered 410 Gone: ` for a revoked tag. */
|
|
50
|
+
export declare function revoked410Text(advisories: readonly Advisory[]): string;
|
|
51
|
+
/**
|
|
52
|
+
* The error for a 410 (guide §2): `ArtifactRevokedError` when `revocation` is on
|
|
53
|
+
* (generation 2) and the body's `errors[0].detail.revoked` is an object, else a
|
|
54
|
+
* retired repository's `SourceRetiredError`. Both are permanent.
|
|
55
|
+
*/
|
|
56
|
+
export declare function goneError(url: string, status: number, body: Uint8Array, revocation: boolean): FetchV1Error;
|
|
57
|
+
/** Is `err` a 410's: `SourceRetiredError` or, under generation 2, `ArtifactRevokedError`? Either is permanent, so every loop over bases or candidates throws it at once. */
|
|
58
|
+
export declare function isGone(err: unknown): err is SourceRetiredError | ArtifactRevokedError;
|
|
59
|
+
/** At most `maxBytes` of a response body. A body that fails part way is no body. */
|
|
60
|
+
export declare function readRetiredBody(stream: http.IncomingMessage, maxBytes: number): Promise<Buffer>;
|
|
61
|
+
//# sourceMappingURL=retired.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retired.d.ts","sourceRoot":"","sources":["../../src/ocifetch/retired.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,KAAK,QAAQ,EAAE,oBAAoB,EAAE,KAAK,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEzG,6CAA6C;AAC7C,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEvD;AAkCD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAe9D;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYxD;AAED,uIAAuI;AACvI,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAIjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,QAAQ,EAAE,GAAG,SAAS,CAmC5E;AAsBD,kEAAkE;AAClE,wBAAgB,cAAc,CAAC,UAAU,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAGtE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,GAAG,YAAY,CAY1G;AAED,4KAA4K;AAC5K,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,kBAAkB,GAAG,oBAAoB,CAErF;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB/F"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A retired repository (`docs/guides/fetch-v1.md` §2, "A retired repository";
|
|
3
|
+
* public issue #571). The registry's operator answers every route of a
|
|
4
|
+
* retired repository with 410 Gone (`RETIRED_STATUSES`) and a short error
|
|
5
|
+
* document. That is permanent: `http.ts` never retries it and throws
|
|
6
|
+
* `SourceRetiredError`, which every loop over bases or candidates lets
|
|
7
|
+
* through, so the caller sees the URL that answered and the registry's own
|
|
8
|
+
* message, made safe to print by `retiredMessage`, the one function every
|
|
9
|
+
* binding has (`tests/fixtures/retired-message/cases.json` is the table all
|
|
10
|
+
* four answer alike).
|
|
11
|
+
*/
|
|
12
|
+
import { RETIRED_MESSAGE_MAX_CODE_POINTS, RETIRED_STATUSES } from './constants.gen.js';
|
|
13
|
+
import { ArtifactRevokedError, SourceRetiredError } from './errors.js';
|
|
14
|
+
/** Is this status a retired repository's? */
|
|
15
|
+
export function isRetiredStatus(status) {
|
|
16
|
+
return RETIRED_STATUSES.includes(status);
|
|
17
|
+
}
|
|
18
|
+
function removed(codePoint) {
|
|
19
|
+
return (codePoint <= 0x1f ||
|
|
20
|
+
(codePoint >= 0x7f && codePoint <= 0x9f) ||
|
|
21
|
+
codePoint === 0x200e ||
|
|
22
|
+
codePoint === 0x200f ||
|
|
23
|
+
(codePoint >= 0x202a && codePoint <= 0x202e) ||
|
|
24
|
+
(codePoint >= 0x2066 && codePoint <= 0x2069));
|
|
25
|
+
}
|
|
26
|
+
/** A UTF-16 surrogate that is not half of a high-then-low pair: not a Unicode string. */
|
|
27
|
+
function hasLoneSurrogate(s) {
|
|
28
|
+
for (let i = 0; i < s.length; i++) {
|
|
29
|
+
const c = s.charCodeAt(i);
|
|
30
|
+
if (c >= 0xd800 && c <= 0xdbff) {
|
|
31
|
+
const d = s.charCodeAt(i + 1);
|
|
32
|
+
if (d >= 0xdc00 && d <= 0xdfff) {
|
|
33
|
+
i++;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
if (c >= 0xdc00 && c <= 0xdfff)
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
function objectOrUndefined(v) {
|
|
44
|
+
return v !== null && typeof v === 'object' && !Array.isArray(v) ? v : undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The registry's own message in a retired repository's response body, made
|
|
48
|
+
* safe to print, or `null` when it sent none. `body` is what was read of it
|
|
49
|
+
* (at most `RETIRED_BODY_MAX_BYTES`). When it is UTF-8 JSON whose
|
|
50
|
+
* `errors[0].message` is a string, that string is the message: every code
|
|
51
|
+
* point in U+0000-U+001F, U+007F-U+009F, U+200E, U+200F, U+202A-U+202E and
|
|
52
|
+
* U+2066-U+2069 is removed, and the rest is cut to
|
|
53
|
+
* `RETIRED_MESSAGE_MAX_CODE_POINTS` code points, with U+2026 appended when it
|
|
54
|
+
* was cut. Nothing else is changed, and an empty result is no message.
|
|
55
|
+
*/
|
|
56
|
+
export function retiredMessage(body) {
|
|
57
|
+
let doc;
|
|
58
|
+
try {
|
|
59
|
+
// fatal: invalid UTF-8 is no message. ignoreBOM: a byte order mark stays
|
|
60
|
+
// in the text, so JSON.parse refuses it, as the other bindings' readers do.
|
|
61
|
+
doc = JSON.parse(new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(body));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const errors = objectOrUndefined(doc)?.['errors'];
|
|
67
|
+
if (!Array.isArray(errors) || errors.length === 0)
|
|
68
|
+
return null;
|
|
69
|
+
const message = objectOrUndefined(errors[0])?.['message'];
|
|
70
|
+
if (typeof message !== 'string')
|
|
71
|
+
return null;
|
|
72
|
+
const safe = sanitizeRetiredText(message);
|
|
73
|
+
return safe === '' ? null : safe;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* `text` made safe to print, the retired message's rule for every served
|
|
77
|
+
* string: every code point in U+0000-U+001F, U+007F-U+009F, U+200E, U+200F,
|
|
78
|
+
* U+202A-U+202E and U+2066-U+2069 removed, then cut to
|
|
79
|
+
* `RETIRED_MESSAGE_MAX_CODE_POINTS` code points with U+2026 appended when it was
|
|
80
|
+
* cut. A string holding a lone surrogate is not Unicode text and is `''`, as is
|
|
81
|
+
* one that is empty once made safe.
|
|
82
|
+
*/
|
|
83
|
+
export function sanitizeRetiredText(text) {
|
|
84
|
+
if (hasLoneSurrogate(text))
|
|
85
|
+
return '';
|
|
86
|
+
const kept = [];
|
|
87
|
+
for (const ch of text) {
|
|
88
|
+
// A string iterates by code point, so a character outside the BMP is one.
|
|
89
|
+
if (!removed(ch.codePointAt(0) ?? 0))
|
|
90
|
+
kept.push(ch);
|
|
91
|
+
}
|
|
92
|
+
if (kept.length > RETIRED_MESSAGE_MAX_CODE_POINTS) {
|
|
93
|
+
kept.length = RETIRED_MESSAGE_MAX_CODE_POINTS;
|
|
94
|
+
kept.push('…');
|
|
95
|
+
}
|
|
96
|
+
return kept.join('');
|
|
97
|
+
}
|
|
98
|
+
/** The error text for a retired repository's answer: the URL and status that answered, and the registry's message when it sent one. */
|
|
99
|
+
export function retiredText(url, status, body) {
|
|
100
|
+
const message = retiredMessage(body);
|
|
101
|
+
const text = `${url} answered ${status} Gone: the repository is retired`;
|
|
102
|
+
return message === null ? text : `${text}; the registry says: ${message}`;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A 410's body read as a revocation (guide, "Build-level revocation", "A `410`
|
|
106
|
+
* on a tag"): `undefined` unless it is UTF-8 JSON whose `errors[0].detail.revoked`
|
|
107
|
+
* is an object; otherwise that object's advisories, each field made safe, and one
|
|
108
|
+
* that is absent, not a string, empty once made safe or a lone surrogate left
|
|
109
|
+
* `''`. An entry that is not an object, or leaves every field empty, is skipped.
|
|
110
|
+
* A repeated key reads as its last value, and a byte order mark is not JSON.
|
|
111
|
+
* `tests/fixtures/revoked-410/cases.json` is the table all four bindings answer
|
|
112
|
+
* alike.
|
|
113
|
+
*/
|
|
114
|
+
export function revoked410(body) {
|
|
115
|
+
let doc;
|
|
116
|
+
try {
|
|
117
|
+
doc = JSON.parse(new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(body));
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
const errors = objectOrUndefined(doc)?.['errors'];
|
|
123
|
+
if (!Array.isArray(errors) || errors.length === 0)
|
|
124
|
+
return undefined;
|
|
125
|
+
const detail = objectOrUndefined(objectOrUndefined(errors[0])?.['detail']);
|
|
126
|
+
const revoked = objectOrUndefined(detail?.['revoked']);
|
|
127
|
+
if (revoked === undefined)
|
|
128
|
+
return undefined;
|
|
129
|
+
const entries = revoked['advisories'];
|
|
130
|
+
const advisories = [];
|
|
131
|
+
if (!Array.isArray(entries))
|
|
132
|
+
return advisories;
|
|
133
|
+
for (const e of entries) {
|
|
134
|
+
const obj = objectOrUndefined(e);
|
|
135
|
+
if (obj === undefined)
|
|
136
|
+
continue;
|
|
137
|
+
const field = (key) => {
|
|
138
|
+
const v = obj[key];
|
|
139
|
+
return typeof v === 'string' ? sanitizeRetiredText(v) : '';
|
|
140
|
+
};
|
|
141
|
+
const a = {
|
|
142
|
+
id: field('id'),
|
|
143
|
+
url: field('url'),
|
|
144
|
+
class: field('class'),
|
|
145
|
+
summary: field('summary'),
|
|
146
|
+
build: field('build'),
|
|
147
|
+
supersededBy: field('superseded_by'),
|
|
148
|
+
revokedAt: '',
|
|
149
|
+
};
|
|
150
|
+
if (a.id === '' && a.url === '' && a.class === '' && a.summary === '' && a.build === '' && a.supersededBy === '')
|
|
151
|
+
continue;
|
|
152
|
+
advisories.push(a);
|
|
153
|
+
}
|
|
154
|
+
return advisories;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* One 410 advisory: `<id> <url> (<class>) build <build>, superseded by build
|
|
158
|
+
* <superseded_by>: <summary>`, a part whose field is empty left out with the
|
|
159
|
+
* separator before it, and the first part present taking none.
|
|
160
|
+
*/
|
|
161
|
+
function advisoryText(a) {
|
|
162
|
+
let s = '';
|
|
163
|
+
const join = (sep, part) => {
|
|
164
|
+
if (s !== '')
|
|
165
|
+
s += sep;
|
|
166
|
+
s += part;
|
|
167
|
+
};
|
|
168
|
+
if (a.id !== '')
|
|
169
|
+
join(' ', a.id);
|
|
170
|
+
if (a.url !== '')
|
|
171
|
+
join(' ', a.url);
|
|
172
|
+
if (a.class !== '')
|
|
173
|
+
join(' ', `(${a.class})`);
|
|
174
|
+
if (a.build !== '')
|
|
175
|
+
join(' ', `build ${a.build}`);
|
|
176
|
+
if (a.supersededBy !== '')
|
|
177
|
+
join(', ', `superseded by build ${a.supersededBy}`);
|
|
178
|
+
if (a.summary !== '')
|
|
179
|
+
join(': ', a.summary);
|
|
180
|
+
return s;
|
|
181
|
+
}
|
|
182
|
+
/** What follows `<url> answered 410 Gone: ` for a revoked tag. */
|
|
183
|
+
export function revoked410Text(advisories) {
|
|
184
|
+
const parts = advisories.map(advisoryText).filter((t) => t !== '');
|
|
185
|
+
return parts.length === 0 ? 'revoked, and the registry names no advisory' : `revoked: ${parts.join('; ')}`;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* The error for a 410 (guide §2): `ArtifactRevokedError` when `revocation` is on
|
|
189
|
+
* (generation 2) and the body's `errors[0].detail.revoked` is an object, else a
|
|
190
|
+
* retired repository's `SourceRetiredError`. Both are permanent.
|
|
191
|
+
*/
|
|
192
|
+
export function goneError(url, status, body, revocation) {
|
|
193
|
+
if (revocation) {
|
|
194
|
+
const advisories = revoked410(body);
|
|
195
|
+
if (advisories !== undefined) {
|
|
196
|
+
return new ArtifactRevokedError(`chtypes: ${url} answered ${status} Gone: ${revoked410Text(advisories)}`, {
|
|
197
|
+
signed: false,
|
|
198
|
+
manifest: '',
|
|
199
|
+
advisories,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return new SourceRetiredError(`chtypes: ${retiredText(url, status, body)}`);
|
|
204
|
+
}
|
|
205
|
+
/** Is `err` a 410's: `SourceRetiredError` or, under generation 2, `ArtifactRevokedError`? Either is permanent, so every loop over bases or candidates throws it at once. */
|
|
206
|
+
export function isGone(err) {
|
|
207
|
+
return err instanceof SourceRetiredError || err instanceof ArtifactRevokedError;
|
|
208
|
+
}
|
|
209
|
+
/** At most `maxBytes` of a response body. A body that fails part way is no body. */
|
|
210
|
+
export function readRetiredBody(stream, maxBytes) {
|
|
211
|
+
return new Promise((resolve) => {
|
|
212
|
+
const chunks = [];
|
|
213
|
+
let total = 0;
|
|
214
|
+
let done = false;
|
|
215
|
+
const finish = (body) => {
|
|
216
|
+
if (done)
|
|
217
|
+
return;
|
|
218
|
+
done = true;
|
|
219
|
+
resolve(body);
|
|
220
|
+
};
|
|
221
|
+
stream.on('data', (chunk) => {
|
|
222
|
+
if (done)
|
|
223
|
+
return;
|
|
224
|
+
chunks.push(chunk);
|
|
225
|
+
total += chunk.length;
|
|
226
|
+
if (total >= maxBytes) {
|
|
227
|
+
finish(Buffer.concat(chunks).subarray(0, maxBytes));
|
|
228
|
+
stream.destroy();
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
stream.on('end', () => finish(Buffer.concat(chunks)));
|
|
232
|
+
stream.on('error', () => finish(Buffer.alloc(0)));
|
|
233
|
+
stream.on('close', () => finish(Buffer.alloc(0)));
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=retired.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retired.js","sourceRoot":"","sources":["../../src/ocifetch/retired.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-level revocation (`docs/guides/fetch-v1.md`, "Build-level revocation";
|
|
3
|
+
* public issue #625). A revocation is a signed referrer of a platform manifest,
|
|
4
|
+
* read from the listing its signature lookup reads; one that verifies refuses the
|
|
5
|
+
* build with `ArtifactRevokedError` and is stored in the build's cache entry, and
|
|
6
|
+
* one that does not is ignored with one warning. A 410 whose body's
|
|
7
|
+
* `errors[0].detail.revoked` is an object is the same code (`retired.ts`). A
|
|
8
|
+
* status that cannot be read fails open with one warning, or in strict mode is the
|
|
9
|
+
* transport's error. Generation 2 only (`Channel.revocation`): the v1 contract has
|
|
10
|
+
* none of it.
|
|
11
|
+
*
|
|
12
|
+
* Four paths check, each with its own budget, exactly as Go's `revocation.go`:
|
|
13
|
+
*
|
|
14
|
+
* - an install reads its revocation candidates from the trust listing it already
|
|
15
|
+
* made, under the retry table;
|
|
16
|
+
* - `--frozen` reads one listing, warm or cold, under the retry table;
|
|
17
|
+
* - a build already installed and used without a download (a registry open,
|
|
18
|
+
* preload, an ensure that finds it installed) is checked at most once per
|
|
19
|
+
* process (the memo below), one attempt per base, no backoff, and one deadline
|
|
20
|
+
* for the whole check;
|
|
21
|
+
* - `--lock` and `update` refuse a revoked build on every platform they pin.
|
|
22
|
+
*/
|
|
23
|
+
import { type FetchV1ErrorCode, type Revocation } from './errors.js';
|
|
24
|
+
import type { RequestOptions } from './http.js';
|
|
25
|
+
import { type ReferrerDescriptor } from './referrers.js';
|
|
26
|
+
import type { Resolved, Statement, TrustedKey } from './types.js';
|
|
27
|
+
/** What one revocation check reads from the call's options, derived once (`ensure.ts`'s `revocationContext`). */
|
|
28
|
+
export interface RevocationContext {
|
|
29
|
+
/** The configured bases, in order. */
|
|
30
|
+
readonly bases: readonly string[];
|
|
31
|
+
/** The trust list the build itself is checked under. */
|
|
32
|
+
readonly trustedKeys: readonly TrustedKey[];
|
|
33
|
+
/** The request options every fetch over `bases` sends (`requestOptionsFor`). */
|
|
34
|
+
readonly request: Omit<RequestOptions, 'maxBytes'>;
|
|
35
|
+
/** The cache root a writable entry lies under. */
|
|
36
|
+
readonly cacheRoot: string;
|
|
37
|
+
readonly offline: boolean;
|
|
38
|
+
/** Per call, and never with a lock or an update (`revocationContext` drops it). */
|
|
39
|
+
readonly allowRevoked: boolean;
|
|
40
|
+
/** A revocation status that cannot be read is the transport's error, not a warning. */
|
|
41
|
+
readonly requireRevocationCheck: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** Whether the active contract has revocation at all. */
|
|
44
|
+
export declare function revocationOn(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The build a check concerns: its own digests and signed predicate, and its
|
|
47
|
+
* installed entry (`dir`) when it has one, writable when that entry is in the
|
|
48
|
+
* user cache.
|
|
49
|
+
*/
|
|
50
|
+
export interface RevocationSubject {
|
|
51
|
+
readonly manifest: string;
|
|
52
|
+
readonly layer: string;
|
|
53
|
+
readonly predicate: Readonly<Record<string, unknown>>;
|
|
54
|
+
readonly version: string;
|
|
55
|
+
readonly platform: string;
|
|
56
|
+
readonly build: string;
|
|
57
|
+
readonly request: string;
|
|
58
|
+
readonly dir: string;
|
|
59
|
+
readonly writable: boolean;
|
|
60
|
+
}
|
|
61
|
+
/** The subject an installed build's `Resolved` names. */
|
|
62
|
+
export declare function subjectOf(ctx: RevocationContext, res: Resolved): RevocationSubject;
|
|
63
|
+
/** The subject of a build not yet installed: the signed statement verified for it. */
|
|
64
|
+
export declare function subjectOfStatement(statement: Statement, manifest: string, layer: string, platform: string, request: string): RevocationSubject;
|
|
65
|
+
/**
|
|
66
|
+
* One revocation bundle against `sub` (the guide's five rules): the signature
|
|
67
|
+
* under `keys`, the statement and predicate types, the subject and manifest, the
|
|
68
|
+
* build's identity, and the advisory's shape. The revocation, or why it does not
|
|
69
|
+
* verify. A signed payload that is not a statement is ignored, never CORRUPT.
|
|
70
|
+
*/
|
|
71
|
+
export declare function verifyRevocation(body: Buffer, keys: readonly TrustedKey[], sub: RevocationSubject): {
|
|
72
|
+
readonly revocation: Revocation;
|
|
73
|
+
} | {
|
|
74
|
+
readonly reason: string;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* The guide's message for a verified revocation: `<version> <platform> build
|
|
78
|
+
* <build> (manifest <digest>) is revoked: <id> <url> (<class>); superseded by
|
|
79
|
+
* build <superseded_by>: <summary>`, a part whose field is empty left out.
|
|
80
|
+
*/
|
|
81
|
+
export declare function revokedText(sub: RevocationSubject, rev: Revocation): string;
|
|
82
|
+
/** One verified revocation: the bundle, for the stored record, and what it says. */
|
|
83
|
+
export interface FoundRevocation {
|
|
84
|
+
readonly bundle: Buffer;
|
|
85
|
+
readonly revocation: Revocation;
|
|
86
|
+
}
|
|
87
|
+
/** Why a status could not be read: the text, and the code the transport's error carries in strict mode. */
|
|
88
|
+
export interface Unread {
|
|
89
|
+
readonly text: string;
|
|
90
|
+
readonly code: FetchV1ErrorCode;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* What one check learned: a verified revocation, the warnings for the candidates
|
|
94
|
+
* it ignored, and, when it could not read the status, why.
|
|
95
|
+
*/
|
|
96
|
+
export interface RevocationOutcome {
|
|
97
|
+
verified: FoundRevocation | undefined;
|
|
98
|
+
readonly warnings: string[];
|
|
99
|
+
unread: Unread | undefined;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Fetches and verifies each revocation candidate in turn; the first that
|
|
103
|
+
* verifies is the answer. A candidate whose bytes cannot be fetched leaves the
|
|
104
|
+
* status unread; one fetched but corrupt or not verifying is ignored with a
|
|
105
|
+
* warning. Its only error is a 410's.
|
|
106
|
+
*/
|
|
107
|
+
export declare function checkCandidates(ctx: RevocationContext, bases: readonly string[], cands: readonly ReferrerDescriptor[], sub: RevocationSubject, single: boolean, signal?: AbortSignal): Promise<RevocationOutcome>;
|
|
108
|
+
/**
|
|
109
|
+
* One network check of `sub`: its listing, then its candidates. A listing that
|
|
110
|
+
* names no signature referrer is an unread status.
|
|
111
|
+
*/
|
|
112
|
+
export declare function checkListing(ctx: RevocationContext, sub: RevocationSubject, single: boolean, signal?: AbortSignal): Promise<RevocationOutcome>;
|
|
113
|
+
/**
|
|
114
|
+
* Turns an outcome into the call's answer, its warnings pushed on `warn`: a
|
|
115
|
+
* verified revocation is stored in an installed, writable entry (when `store`)
|
|
116
|
+
* and refuses the build, or with the override becomes one warning; an unread
|
|
117
|
+
* status is one warning, or in strict mode the transport's error.
|
|
118
|
+
*/
|
|
119
|
+
export declare function settle(ctx: RevocationContext, sub: RevocationSubject, out: RevocationOutcome, store: boolean, warn: string[]): Promise<void>;
|
|
120
|
+
/** Stores a verified revocation's bundle, byte for byte, in an installed build's entry: a temporary file, then a rename. */
|
|
121
|
+
export declare function writeRevocationRecord(dir: string, bundle: Buffer): Promise<void>;
|
|
122
|
+
/** The revocation an install let through under the override, stored in the entry it installed (a failed write is ignored). */
|
|
123
|
+
export declare function storePending(ctx: RevocationContext, dir: string, pending: FoundRevocation | undefined): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Reads `sub`'s stored record, if its entry holds one: verified, it decides the
|
|
126
|
+
* call (returns `true`; a refusal is thrown); one that does not verify is a
|
|
127
|
+
* warning, and the call goes on.
|
|
128
|
+
*/
|
|
129
|
+
export declare function checkStored(ctx: RevocationContext, sub: RevocationSubject, warn: string[]): Promise<boolean>;
|
|
130
|
+
/** The revocation `res`'s stored record holds, when it verifies, and its message (`chtypes verify`'s). */
|
|
131
|
+
export declare function storedRevocation(ctx: RevocationContext, res: Resolved): Promise<{
|
|
132
|
+
readonly revocation: Revocation;
|
|
133
|
+
readonly text: string;
|
|
134
|
+
} | undefined>;
|
|
135
|
+
/** The check every call that answers from the cache with no request makes (`--offline`, `--frozen --offline`): the stored record. */
|
|
136
|
+
export declare function checkInstalledStored(ctx: RevocationContext, res: Resolved): Promise<readonly string[]>;
|
|
137
|
+
/** `--frozen`'s check of the build installed under its pin: the stored record, then one listing under the retry table. */
|
|
138
|
+
export declare function checkFrozenInstalled(ctx: RevocationContext, res: Resolved): Promise<readonly string[]>;
|
|
139
|
+
/** Forgets every kept outcome, as a new process would. A conformance runner calls it before every case. Test-only. */
|
|
140
|
+
export declare function resetRevocationMemoForTests(): void;
|
|
141
|
+
/** Shortens (or, with `undefined`, restores) the installed-build check's one deadline. Test-only. */
|
|
142
|
+
export declare function setRevocationCheckDeadlineForTests(seconds: number | undefined): void;
|
|
143
|
+
/**
|
|
144
|
+
* The installed-build check: the stored record, then, unless offline, the kept
|
|
145
|
+
* outcome or one check of its own, with one attempt per base, no backoff and one
|
|
146
|
+
* deadline. Concurrent checks of one build share one; a kept "not checked"
|
|
147
|
+
* answers only a call without strict mode, and a check that ends in an error
|
|
148
|
+
* keeps nothing. Warnings go on `warn`; a refusal is thrown.
|
|
149
|
+
*/
|
|
150
|
+
export declare function checkInstalledOnce(ctx: RevocationContext, res: Resolved, warn: string[]): Promise<void>;
|
|
151
|
+
//# sourceMappingURL=revocation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revocation.d.ts","sourceRoot":"","sources":["../../src/ocifetch/revocation.ts"],"names":[],"mappings":"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"}
|