@wavehouse/chtypes 0.5.2 → 1.0.0
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 +26 -0
- package/README.md +34 -38
- package/dist/abi1/buildinfo.d.ts +40 -0
- package/dist/abi1/buildinfo.d.ts.map +1 -0
- package/dist/abi1/buildinfo.js +83 -0
- package/dist/abi1/buildinfo.js.map +1 -0
- package/dist/abi1/calls.gen.d.ts +55 -0
- package/dist/abi1/calls.gen.d.ts.map +1 -0
- package/dist/abi1/calls.gen.js +110 -0
- package/dist/abi1/calls.gen.js.map +1 -0
- package/dist/abi1/decls.gen.d.ts +115 -0
- package/dist/abi1/decls.gen.d.ts.map +1 -0
- package/dist/abi1/decls.gen.js +1613 -0
- package/dist/abi1/decls.gen.js.map +1 -0
- package/dist/abi1/errmap.gen.d.ts +18 -0
- package/dist/abi1/errmap.gen.d.ts.map +1 -0
- package/dist/abi1/errmap.gen.js +66 -0
- package/dist/abi1/errmap.gen.js.map +1 -0
- package/dist/abi1/errors.d.ts +107 -0
- package/dist/abi1/errors.d.ts.map +1 -0
- package/dist/abi1/errors.js +134 -0
- package/dist/abi1/errors.js.map +1 -0
- package/dist/abi1/handles.d.ts +31 -0
- package/dist/abi1/handles.d.ts.map +1 -0
- package/dist/abi1/handles.js +76 -0
- package/dist/abi1/handles.js.map +1 -0
- package/dist/abi1/index.d.ts +17 -0
- package/dist/abi1/index.d.ts.map +1 -0
- package/dist/abi1/index.js +17 -0
- package/dist/abi1/index.js.map +1 -0
- package/dist/abi1/libc.d.ts +54 -0
- package/dist/abi1/libc.d.ts.map +1 -0
- package/dist/abi1/libc.gen.d.ts +12 -0
- package/dist/abi1/libc.gen.d.ts.map +1 -0
- package/dist/abi1/libc.gen.js +75 -0
- package/dist/abi1/libc.gen.js.map +1 -0
- package/dist/abi1/libc.js +109 -0
- package/dist/abi1/libc.js.map +1 -0
- package/dist/abi1/loader.d.ts +99 -0
- package/dist/abi1/loader.d.ts.map +1 -0
- package/dist/abi1/loader.js +261 -0
- package/dist/abi1/loader.js.map +1 -0
- package/dist/abi1/raw.d.ts +104 -0
- package/dist/abi1/raw.d.ts.map +1 -0
- package/dist/abi1/raw.js +296 -0
- package/dist/abi1/raw.js.map +1 -0
- package/dist/abi1/strictjson.d.ts +19 -0
- package/dist/abi1/strictjson.d.ts.map +1 -0
- package/dist/abi1/strictjson.js +78 -0
- package/dist/abi1/strictjson.js.map +1 -0
- package/dist/abi1/vocab.gen.d.ts +169 -0
- package/dist/abi1/vocab.gen.d.ts.map +1 -0
- package/dist/abi1/vocab.gen.js +306 -0
- package/dist/abi1/vocab.gen.js.map +1 -0
- package/dist/cli.d.ts +25 -26
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +206 -218
- package/dist/cli.js.map +1 -1
- package/dist/documents.d.ts +195 -0
- package/dist/documents.d.ts.map +1 -0
- package/dist/documents.js +389 -0
- package/dist/documents.js.map +1 -0
- package/dist/env.d.ts +16 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +57 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +19 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -23
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +11 -89
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js +16 -180
- package/dist/json.js.map +1 -1
- package/dist/library.d.ts +53 -309
- package/dist/library.d.ts.map +1 -1
- package/dist/library.js +77 -315
- package/dist/library.js.map +1 -1
- package/dist/ocifetch/constants.gen.d.ts +84 -0
- package/dist/ocifetch/constants.gen.d.ts.map +1 -0
- package/dist/ocifetch/constants.gen.js +92 -0
- package/dist/ocifetch/constants.gen.js.map +1 -0
- package/dist/ocifetch/dsse.d.ts +114 -0
- package/dist/ocifetch/dsse.d.ts.map +1 -0
- package/dist/ocifetch/dsse.js +331 -0
- package/dist/ocifetch/dsse.js.map +1 -0
- package/dist/ocifetch/ensure.d.ts +65 -0
- package/dist/ocifetch/ensure.d.ts.map +1 -0
- package/dist/ocifetch/ensure.js +775 -0
- package/dist/ocifetch/ensure.js.map +1 -0
- package/dist/ocifetch/errors.d.ts +92 -0
- package/dist/ocifetch/errors.d.ts.map +1 -0
- package/dist/ocifetch/errors.js +101 -0
- package/dist/ocifetch/errors.js.map +1 -0
- package/dist/ocifetch/goldens.d.ts +44 -0
- package/dist/ocifetch/goldens.d.ts.map +1 -0
- package/dist/ocifetch/goldens.js +62 -0
- package/dist/ocifetch/goldens.js.map +1 -0
- package/dist/ocifetch/http.d.ts +124 -0
- package/dist/ocifetch/http.d.ts.map +1 -0
- package/dist/ocifetch/http.js +549 -0
- package/dist/ocifetch/http.js.map +1 -0
- package/dist/ocifetch/index.d.ts +17 -0
- package/dist/ocifetch/index.d.ts.map +1 -0
- package/dist/ocifetch/index.js +14 -0
- package/dist/ocifetch/index.js.map +1 -0
- package/dist/ocifetch/layout.d.ts +126 -0
- package/dist/ocifetch/layout.d.ts.map +1 -0
- package/dist/ocifetch/layout.js +375 -0
- package/dist/ocifetch/layout.js.map +1 -0
- package/dist/ocifetch/localverify.d.ts +43 -0
- package/dist/ocifetch/localverify.d.ts.map +1 -0
- package/dist/ocifetch/localverify.js +164 -0
- package/dist/ocifetch/localverify.js.map +1 -0
- package/dist/ocifetch/lock.d.ts +39 -0
- package/dist/ocifetch/lock.d.ts.map +1 -0
- package/dist/ocifetch/lock.js +140 -0
- package/dist/ocifetch/lock.js.map +1 -0
- package/dist/ocifetch/oci.d.ts +100 -0
- package/dist/ocifetch/oci.d.ts.map +1 -0
- package/dist/ocifetch/oci.js +323 -0
- package/dist/ocifetch/oci.js.map +1 -0
- package/dist/ocifetch/referrers.d.ts +55 -0
- package/dist/ocifetch/referrers.d.ts.map +1 -0
- package/dist/ocifetch/referrers.js +132 -0
- package/dist/ocifetch/referrers.js.map +1 -0
- package/dist/ocifetch/types.d.ts +167 -0
- package/dist/ocifetch/types.d.ts.map +1 -0
- package/dist/ocifetch/types.js +88 -0
- package/dist/ocifetch/types.js.map +1 -0
- package/dist/ocifetch/unpack.d.ts +55 -0
- package/dist/ocifetch/unpack.d.ts.map +1 -0
- package/dist/ocifetch/unpack.js +205 -0
- package/dist/ocifetch/unpack.js.map +1 -0
- package/dist/registry.d.ts +38 -387
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +94 -819
- package/dist/registry.js.map +1 -1
- package/dist/schema.d.ts +77 -588
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +87 -549
- package/dist/schema.js.map +1 -1
- package/dist/settings.d.ts +27 -36
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +75 -25
- package/dist/settings.js.map +1 -1
- package/dist/setup.d.ts +37 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +60 -0
- package/dist/setup.js.map +1 -0
- package/dist/tar.d.ts +27 -11
- package/dist/tar.d.ts.map +1 -1
- package/dist/tar.js +54 -32
- package/dist/tar.js.map +1 -1
- package/package.json +2 -2
- package/dist/discover.d.ts +0 -142
- package/dist/discover.d.ts.map +0 -1
- package/dist/discover.js +0 -288
- package/dist/discover.js.map +0 -1
- package/dist/error-codes.d.ts +0 -80
- package/dist/error-codes.d.ts.map +0 -1
- package/dist/error-codes.js +0 -139
- package/dist/error-codes.js.map +0 -1
- package/dist/errors.d.ts +0 -284
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -321
- package/dist/errors.js.map +0 -1
- package/dist/fetch.d.ts +0 -382
- package/dist/fetch.d.ts.map +0 -1
- package/dist/fetch.js +0 -1498
- package/dist/fetch.js.map +0 -1
- package/dist/ffi.d.ts +0 -410
- package/dist/ffi.d.ts.map +0 -1
- package/dist/ffi.js +0 -1154
- package/dist/ffi.js.map +0 -1
- package/dist/format.d.ts +0 -128
- package/dist/format.d.ts.map +0 -1
- package/dist/format.js +0 -132
- package/dist/format.js.map +0 -1
- package/dist/numeric.d.ts +0 -20
- package/dist/numeric.d.ts.map +0 -1
- package/dist/numeric.js +0 -107
- package/dist/numeric.js.map +0 -1
- package/dist/paths.d.ts +0 -55
- package/dist/paths.d.ts.map +0 -1
- package/dist/paths.js +0 -87
- package/dist/paths.js.map +0 -1
- package/dist/results.d.ts +0 -495
- package/dist/results.d.ts.map +0 -1
- package/dist/results.js +0 -406
- package/dist/results.js.map +0 -1
- package/dist/transform.d.ts +0 -73
- package/dist/transform.d.ts.map +0 -1
- package/dist/transform.js +0 -533
- package/dist/transform.js.map +0 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verifying a pre-seeded cache entry from local blobs alone, zero network
|
|
3
|
+
* (`docs/guides/fetch-v1.md` §1, §6): "a pre-seeded layout has entries in
|
|
4
|
+
* `index.json` with no corresponding `unpacked/` directory yet; the first
|
|
5
|
+
* request for one verifies it against its signature exactly as a freshly
|
|
6
|
+
* downloaded layer would, then unpacks it." `--offline`/`resolve_installed`
|
|
7
|
+
* are the only callers — never `ensure`'s normal online path, which always
|
|
8
|
+
* has a live referrers API to ask.
|
|
9
|
+
*
|
|
10
|
+
* There is no referrers API to query here, so trust discovery is a local
|
|
11
|
+
* scan: every blob under `blobs/sha256/` that parses as an OCI manifest
|
|
12
|
+
* with the signature bundle's own `artifactType` is a *candidate* referrer
|
|
13
|
+
* of the platform manifest, tried the same way `dsse.ts`'s
|
|
14
|
+
* `verifyAnyReferrerBundle` tries referrers fetched over the network —
|
|
15
|
+
* stopping at the first whose signature verifies AND whose statement names
|
|
16
|
+
* this exact platform manifest's layer as its subject. `oras copy -r
|
|
17
|
+
* --to-oci-layout` is what populates these blobs when pulling from a real
|
|
18
|
+
* registry (guide §1); `index.json` itself carries no referrers listing (no
|
|
19
|
+
* such thing exists in the OCI image-layout spec), which is exactly why
|
|
20
|
+
* this is a scan rather than a lookup.
|
|
21
|
+
*/
|
|
22
|
+
import { rm } from 'node:fs/promises';
|
|
23
|
+
import path from 'node:path';
|
|
24
|
+
import { MEDIA_TYPE_BUNDLE, PREDICATE_TYPE_ARTIFACT } from './constants.gen.js';
|
|
25
|
+
import { checkArtifactStatement, parseStatement, verifyBundleSignature } from './dsse.js';
|
|
26
|
+
import { ArtifactCorruptError } from './errors.js';
|
|
27
|
+
import { buildRecord, commitStaging, freshStagingDir, listLocalBlobHexes, readLocalBlob, readVerifiedRecord, unpackedDir, writeVerifiedRecord, } from './layout.js';
|
|
28
|
+
import { parseManifest, verifyDescriptor } from './oci.js';
|
|
29
|
+
import { digestOfHex, hexOfDigest, platformInfo } from './types.js';
|
|
30
|
+
import { measureLibrary, verifyAndUnpackLayerBytes, verifyInstalledLibrary } from './unpack.js';
|
|
31
|
+
/**
|
|
32
|
+
* Verifies and installs the platform manifest named by `manifestDigest`,
|
|
33
|
+
* reading every blob it needs from `blobsSourceDir`'s `blobs/sha256/` but
|
|
34
|
+
* always **writing** the result (the unpacked library and its
|
|
35
|
+
* `verified.json`) under `writeRoot` — the two differ for a read-only
|
|
36
|
+
* system directory (guide §1: "never written to"), where `blobsSourceDir`
|
|
37
|
+
* is that system dir and `writeRoot` is the user's own cache.
|
|
38
|
+
*
|
|
39
|
+
* Idempotent and cheap on a repeat call: if `writeRoot` already has a
|
|
40
|
+
* `verified.json` for this digest, returns it without touching
|
|
41
|
+
* `blobsSourceDir` again. Returns `undefined` (never throws) when this
|
|
42
|
+
* specific entry cannot be locally verified — a bad or incomplete
|
|
43
|
+
* pre-seeded blob is "not usable", not a hard failure for whatever broader
|
|
44
|
+
* scan is trying several candidates. The caller decides whether the
|
|
45
|
+
* resulting predicate's own `clickhouse_version` fits whatever request
|
|
46
|
+
* prompted the scan — this function verifies the entry on its own terms,
|
|
47
|
+
* not against any one request.
|
|
48
|
+
*/
|
|
49
|
+
export async function verifyAndInstallFromLocalBlobs(blobsSourceDir, writeRoot, manifestDigest, platform, trustedKeys) {
|
|
50
|
+
const manifestHex = hexOfDigest(manifestDigest);
|
|
51
|
+
const existing = await readVerifiedRecord(unpackedDir(writeRoot, manifestHex));
|
|
52
|
+
if (existing !== undefined)
|
|
53
|
+
return existing;
|
|
54
|
+
try {
|
|
55
|
+
const manifestBytes = await readLocalBlob(blobsSourceDir, manifestHex);
|
|
56
|
+
if (manifestBytes === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
verifyDescriptor({ mediaType: '', digest: manifestDigest }, manifestBytes, `manifest ${manifestDigest}`);
|
|
59
|
+
const manifest = parseManifest(manifestDigest, manifestBytes);
|
|
60
|
+
const info = platformInfo(platform);
|
|
61
|
+
const found = await findLocalSignature(blobsSourceDir, manifest.layer, trustedKeys);
|
|
62
|
+
if (found === undefined)
|
|
63
|
+
return undefined;
|
|
64
|
+
const predicate = checkArtifactStatement(found.statement, PREDICATE_TYPE_ARTIFACT, manifest.layer.digest, {
|
|
65
|
+
os: info.os,
|
|
66
|
+
arch: info.architecture,
|
|
67
|
+
// No `requestedSpelling`: this entry is verified on its own terms,
|
|
68
|
+
// not against one request — see this function's own doc comment.
|
|
69
|
+
});
|
|
70
|
+
const layerBytes = await readLocalBlob(blobsSourceDir, hexOfDigest(manifest.layer.digest));
|
|
71
|
+
if (layerBytes === undefined)
|
|
72
|
+
return undefined;
|
|
73
|
+
const staging = await freshStagingDir(writeRoot);
|
|
74
|
+
try {
|
|
75
|
+
const entries = await verifyAndUnpackLayerBytes(layerBytes, manifest.layer, staging);
|
|
76
|
+
if (!entries.some((e) => e.name === predicate.library)) {
|
|
77
|
+
throw new ArtifactCorruptError(`chtypes: the local layer does not contain its own predicate's library ${JSON.stringify(predicate.library)}`);
|
|
78
|
+
}
|
|
79
|
+
await verifyInstalledLibrary(path.join(staging, predicate.library), predicate.library_sha256, predicate.library_bytes);
|
|
80
|
+
const record = buildRecord({
|
|
81
|
+
platform,
|
|
82
|
+
predicate,
|
|
83
|
+
library: await measureLibrary(path.join(staging, predicate.library)),
|
|
84
|
+
indexDigest: null,
|
|
85
|
+
manifestDigest,
|
|
86
|
+
layerDigest: manifest.layer.digest,
|
|
87
|
+
bundleDigest: found.bundleDigest,
|
|
88
|
+
bundleManifestDigest: found.bundleManifestDigest,
|
|
89
|
+
signedBy: found.signedBy,
|
|
90
|
+
});
|
|
91
|
+
await writeVerifiedRecord(staging, record);
|
|
92
|
+
await commitStaging(staging, unpackedDir(writeRoot, manifestHex));
|
|
93
|
+
return record;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
await rm(staging, { recursive: true, force: true }).catch(() => { });
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// Any failure anywhere in this local-only verification (malformed
|
|
102
|
+
// blob, bad signature, wrong subject) just means this candidate is not
|
|
103
|
+
// usable — never a hard error, since a scan may have other candidates
|
|
104
|
+
// to try, and `--offline` would otherwise crash on one bad bystander
|
|
105
|
+
// entry in an otherwise-healthy cache.
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Scans every local blob for one that is an OCI manifest of the signature
|
|
111
|
+
* bundle's `artifactType`, tries its own layer (the bundle JSON) against
|
|
112
|
+
* `trustedKeys`, and accepts the first whose verified statement names
|
|
113
|
+
* `layer`'s digest as its subject. Order is the filesystem's own
|
|
114
|
+
* `readdir` order — deterministic per run, immaterial to correctness since
|
|
115
|
+
* every candidate is checked.
|
|
116
|
+
*/
|
|
117
|
+
async function findLocalSignature(blobsSourceDir, layer, trustedKeys) {
|
|
118
|
+
const hexes = await listLocalBlobHexes(blobsSourceDir);
|
|
119
|
+
for (const hex of hexes) {
|
|
120
|
+
const bytes = await readLocalBlob(blobsSourceDir, hex);
|
|
121
|
+
if (bytes === undefined)
|
|
122
|
+
continue;
|
|
123
|
+
const artifactType = readArtifactType(bytes);
|
|
124
|
+
if (artifactType !== MEDIA_TYPE_BUNDLE)
|
|
125
|
+
continue;
|
|
126
|
+
let candidateManifest;
|
|
127
|
+
try {
|
|
128
|
+
candidateManifest = parseManifest(digestOfHex(hex), bytes);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
continue; // Names the bundle artifactType but is not a readable manifest — not a candidate.
|
|
132
|
+
}
|
|
133
|
+
const bundleBytes = await readLocalBlob(blobsSourceDir, hexOfDigest(candidateManifest.layer.digest));
|
|
134
|
+
if (bundleBytes === undefined)
|
|
135
|
+
continue;
|
|
136
|
+
const verified = verifyBundleSignature(bundleBytes, trustedKeys);
|
|
137
|
+
if (verified === undefined)
|
|
138
|
+
continue;
|
|
139
|
+
let statement;
|
|
140
|
+
try {
|
|
141
|
+
statement = parseStatement(verified.payload);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (statement.subject[0]?.digest.sha256 !== hexOfDigest(layer.digest))
|
|
147
|
+
continue;
|
|
148
|
+
return { statement, signedBy: verified.signedBy, bundleDigest: candidateManifest.layer.digest, bundleManifestDigest: digestOfHex(hex) };
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
function readArtifactType(manifestBytes) {
|
|
153
|
+
try {
|
|
154
|
+
const parsed = JSON.parse(manifestBytes.toString('utf8'));
|
|
155
|
+
if (parsed === null || typeof parsed !== 'object')
|
|
156
|
+
return undefined;
|
|
157
|
+
const v = parsed['artifactType'];
|
|
158
|
+
return typeof v === 'string' ? v : undefined;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=localverify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localverify.js","sourceRoot":"","sources":["../../src/ocifetch/localverify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lock schema 3 (`docs/guides/fetch-v1.md` §6, `spec/fetch-v1/schema/lock3.schema.json`):
|
|
3
|
+
* per declared platform, the request, the exact version and build, and the
|
|
4
|
+
* platform manifest/layer/bundle digests — never a hostname. Schema 1 and 2
|
|
5
|
+
* (v0) are refused outright, never silently reinterpreted, exactly as v0
|
|
6
|
+
* refuses a lock newer than it understands.
|
|
7
|
+
*/
|
|
8
|
+
import { type PlatformKey } from './types.js';
|
|
9
|
+
export interface LockPin {
|
|
10
|
+
readonly version: string;
|
|
11
|
+
readonly build: string;
|
|
12
|
+
readonly manifest: string;
|
|
13
|
+
readonly layer: string;
|
|
14
|
+
readonly bundle: string;
|
|
15
|
+
readonly index?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface LockFile {
|
|
18
|
+
readonly schema: 3;
|
|
19
|
+
readonly abi: 1;
|
|
20
|
+
readonly platforms: readonly PlatformKey[];
|
|
21
|
+
/** Keyed by the originally-requested spelling, then by platform key. */
|
|
22
|
+
readonly requests: Readonly<Record<string, Readonly<Record<string, LockPin>>>>;
|
|
23
|
+
}
|
|
24
|
+
export declare function emptyLock(): LockFile;
|
|
25
|
+
export declare function defaultLockPath(cwd?: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Validates and narrows a parsed JSON value into a `LockFile`. Any v0 lock
|
|
28
|
+
* (`schema: 1` or `schema: 2` in v0's own numbering) and any other
|
|
29
|
+
* malformed shape is `ArtifactPinnedError`, naming re-lock — `--frozen`
|
|
30
|
+
* reads this the same way a missing pin does (guide §6).
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateLock(parsed: unknown, path_: string): LockFile;
|
|
33
|
+
/** `undefined` when no lock file exists at `lockPath`. */
|
|
34
|
+
export declare function readLock(lockPath: string): Promise<LockFile | undefined>;
|
|
35
|
+
export declare function writeLock(lockPath: string, lock: LockFile): Promise<void>;
|
|
36
|
+
export declare function getPin(lock: LockFile, spelling: string, platform: PlatformKey): LockPin | undefined;
|
|
37
|
+
/** Returns a new lock with `pin` set for `spelling`/`platform`, adding `platform` to the declared list if new. */
|
|
38
|
+
export declare function withPin(lock: LockFile, spelling: string, platform: PlatformKey, pin: LockPin): LockFile;
|
|
39
|
+
//# sourceMappingURL=lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/ocifetch/lock.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE7D,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACnB,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;IAChB,QAAQ,CAAC,SAAS,EAAE,SAAS,WAAW,EAAE,CAAC;IAC3C,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;CAChF;AAID,wBAAgB,SAAS,IAAI,QAAQ,CAEpC;AAED,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAEnE;AAQD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAqErE;AAED,0DAA0D;AAC1D,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAe9E;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/E;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,GAAG,SAAS,CAEnG;AAED,kHAAkH;AAClH,wBAAgB,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,GAAG,QAAQ,CAOvG"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lock schema 3 (`docs/guides/fetch-v1.md` §6, `spec/fetch-v1/schema/lock3.schema.json`):
|
|
3
|
+
* per declared platform, the request, the exact version and build, and the
|
|
4
|
+
* platform manifest/layer/bundle digests — never a hostname. Schema 1 and 2
|
|
5
|
+
* (v0) are refused outright, never silently reinterpreted, exactly as v0
|
|
6
|
+
* refuses a lock newer than it understands.
|
|
7
|
+
*/
|
|
8
|
+
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { randomBytes } from 'node:crypto';
|
|
11
|
+
import { LOCK_DEFAULT_FILE, LOCK_SCHEMA, PLATFORMS } from './constants.gen.js';
|
|
12
|
+
import { ArtifactPinnedError } from './errors.js';
|
|
13
|
+
import { isPlatformKey } from './types.js';
|
|
14
|
+
const DIGEST_RE = /^sha256:[0-9a-f]{64}$/;
|
|
15
|
+
export function emptyLock() {
|
|
16
|
+
return { schema: LOCK_SCHEMA, abi: 1, platforms: [], requests: {} };
|
|
17
|
+
}
|
|
18
|
+
export function defaultLockPath(cwd = process.cwd()) {
|
|
19
|
+
return path.join(cwd, LOCK_DEFAULT_FILE);
|
|
20
|
+
}
|
|
21
|
+
function pinName(digest, field) {
|
|
22
|
+
if (!DIGEST_RE.test(digest)) {
|
|
23
|
+
throw new ArtifactPinnedError(`chtypes: lock pin's ${field} ${JSON.stringify(digest)} is not a sha256 digest`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validates and narrows a parsed JSON value into a `LockFile`. Any v0 lock
|
|
28
|
+
* (`schema: 1` or `schema: 2` in v0's own numbering) and any other
|
|
29
|
+
* malformed shape is `ArtifactPinnedError`, naming re-lock — `--frozen`
|
|
30
|
+
* reads this the same way a missing pin does (guide §6).
|
|
31
|
+
*/
|
|
32
|
+
export function validateLock(parsed, path_) {
|
|
33
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
34
|
+
throw new ArtifactPinnedError(`chtypes: ${path_} is not a lock file object; re-lock with \`fetch --lock\``);
|
|
35
|
+
}
|
|
36
|
+
const doc = parsed;
|
|
37
|
+
const schema = doc['schema'];
|
|
38
|
+
if (schema !== LOCK_SCHEMA) {
|
|
39
|
+
throw new ArtifactPinnedError(`chtypes: ${path_} is schema ${JSON.stringify(schema)}, not v1's schema ${LOCK_SCHEMA}` +
|
|
40
|
+
(schema === 1 || schema === 2 ? ' (a v0 lock is never reinterpreted)' : '') +
|
|
41
|
+
'; re-lock with `fetch --lock`');
|
|
42
|
+
}
|
|
43
|
+
if (doc['abi'] !== 1) {
|
|
44
|
+
throw new ArtifactPinnedError(`chtypes: ${path_}'s abi is ${JSON.stringify(doc['abi'])}, not 1; re-lock with \`fetch --lock\``);
|
|
45
|
+
}
|
|
46
|
+
const platformsRaw = doc['platforms'];
|
|
47
|
+
if (!Array.isArray(platformsRaw) || platformsRaw.length === 0) {
|
|
48
|
+
throw new ArtifactPinnedError(`chtypes: ${path_} names no platforms; re-lock with \`fetch --lock\``);
|
|
49
|
+
}
|
|
50
|
+
const platforms = [];
|
|
51
|
+
for (const p of platformsRaw) {
|
|
52
|
+
if (typeof p !== 'string' || !isPlatformKey(p)) {
|
|
53
|
+
throw new ArtifactPinnedError(`chtypes: ${path_} names an unknown platform ${JSON.stringify(p)}`);
|
|
54
|
+
}
|
|
55
|
+
platforms.push(p);
|
|
56
|
+
}
|
|
57
|
+
const requestsRaw = doc['requests'];
|
|
58
|
+
if (requestsRaw === null || typeof requestsRaw !== 'object' || Array.isArray(requestsRaw)) {
|
|
59
|
+
throw new ArtifactPinnedError(`chtypes: ${path_} has no readable requests table`);
|
|
60
|
+
}
|
|
61
|
+
const requests = {};
|
|
62
|
+
for (const [spelling, byPlatform] of Object.entries(requestsRaw)) {
|
|
63
|
+
if (byPlatform === null || typeof byPlatform !== 'object' || Array.isArray(byPlatform)) {
|
|
64
|
+
throw new ArtifactPinnedError(`chtypes: ${path_}'s request ${JSON.stringify(spelling)} is malformed`);
|
|
65
|
+
}
|
|
66
|
+
const row = {};
|
|
67
|
+
for (const [platform, pinRaw] of Object.entries(byPlatform)) {
|
|
68
|
+
if (!isPlatformKey(platform) || !platforms.includes(platform)) {
|
|
69
|
+
throw new ArtifactPinnedError(`chtypes: ${path_}'s request ${JSON.stringify(spelling)} names platform ${JSON.stringify(platform)}, not in its own platforms list`);
|
|
70
|
+
}
|
|
71
|
+
if (pinRaw === null || typeof pinRaw !== 'object' || Array.isArray(pinRaw)) {
|
|
72
|
+
throw new ArtifactPinnedError(`chtypes: ${path_}'s pin for ${spelling}/${platform} is malformed`);
|
|
73
|
+
}
|
|
74
|
+
const p = pinRaw;
|
|
75
|
+
const version = p['version'];
|
|
76
|
+
const build = p['build'];
|
|
77
|
+
const manifest = p['manifest'];
|
|
78
|
+
const layer = p['layer'];
|
|
79
|
+
const bundle = p['bundle'];
|
|
80
|
+
const index = p['index'];
|
|
81
|
+
if (typeof version !== 'string' || typeof build !== 'string') {
|
|
82
|
+
throw new ArtifactPinnedError(`chtypes: ${path_}'s pin for ${spelling}/${platform} is missing version or build`);
|
|
83
|
+
}
|
|
84
|
+
if (typeof manifest !== 'string' || typeof layer !== 'string' || typeof bundle !== 'string') {
|
|
85
|
+
throw new ArtifactPinnedError(`chtypes: ${path_}'s pin for ${spelling}/${platform} is missing a digest`);
|
|
86
|
+
}
|
|
87
|
+
pinName(manifest, 'manifest');
|
|
88
|
+
pinName(layer, 'layer');
|
|
89
|
+
pinName(bundle, 'bundle');
|
|
90
|
+
if (index !== undefined) {
|
|
91
|
+
if (typeof index !== 'string')
|
|
92
|
+
throw new ArtifactPinnedError(`chtypes: ${path_}'s pin for ${spelling}/${platform} has a non-string index`);
|
|
93
|
+
pinName(index, 'index');
|
|
94
|
+
}
|
|
95
|
+
row[platform] = { version, build, manifest, layer, bundle, ...(index !== undefined ? { index } : {}) };
|
|
96
|
+
}
|
|
97
|
+
requests[spelling] = row;
|
|
98
|
+
}
|
|
99
|
+
return { schema: LOCK_SCHEMA, abi: 1, platforms, requests };
|
|
100
|
+
}
|
|
101
|
+
/** `undefined` when no lock file exists at `lockPath`. */
|
|
102
|
+
export async function readLock(lockPath) {
|
|
103
|
+
let raw;
|
|
104
|
+
try {
|
|
105
|
+
raw = await readFile(lockPath, 'utf8');
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
if (err.code === 'ENOENT')
|
|
109
|
+
return undefined;
|
|
110
|
+
throw err;
|
|
111
|
+
}
|
|
112
|
+
let parsed;
|
|
113
|
+
try {
|
|
114
|
+
parsed = JSON.parse(raw);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
throw new ArtifactPinnedError(`chtypes: ${lockPath} is not valid JSON: ${err.message}`);
|
|
118
|
+
}
|
|
119
|
+
return validateLock(parsed, lockPath);
|
|
120
|
+
}
|
|
121
|
+
export async function writeLock(lockPath, lock) {
|
|
122
|
+
const serializable = { schema: LOCK_SCHEMA, abi: 1, platforms: lock.platforms, requests: lock.requests };
|
|
123
|
+
await mkdir(path.dirname(lockPath), { recursive: true });
|
|
124
|
+
const tmp = `${lockPath}.tmp-${process.pid}-${randomBytes(6).toString('hex')}`;
|
|
125
|
+
await writeFile(tmp, `${JSON.stringify(serializable, null, 2)}\n`);
|
|
126
|
+
await rename(tmp, lockPath);
|
|
127
|
+
}
|
|
128
|
+
export function getPin(lock, spelling, platform) {
|
|
129
|
+
return lock.requests[spelling]?.[platform];
|
|
130
|
+
}
|
|
131
|
+
/** Returns a new lock with `pin` set for `spelling`/`platform`, adding `platform` to the declared list if new. */
|
|
132
|
+
export function withPin(lock, spelling, platform, pin) {
|
|
133
|
+
// Platforms are kept in the contract's own order (`PLATFORMS`), never
|
|
134
|
+
// insertion order, so two writers that pinned the same set agree byte for byte.
|
|
135
|
+
const unsorted = lock.platforms.includes(platform) ? lock.platforms : [...lock.platforms, platform];
|
|
136
|
+
const platforms = PLATFORMS.map((p) => p.key).filter((k) => unsorted.includes(k));
|
|
137
|
+
const row = { ...(lock.requests[spelling] ?? {}), [platform]: pin };
|
|
138
|
+
return { ...lock, platforms, requests: { ...lock.requests, [spelling]: row } };
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/ocifetch/lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve (`docs/guides/fetch-v1.md` §3): the version spelling check, the
|
|
3
|
+
* multi-base tag GET returning an OCI image index, platform selection, and
|
|
4
|
+
* by-digest fetches (manifests and blobs) with their own integrity check
|
|
5
|
+
* (size + sha256 against the descriptor that named them — independent of,
|
|
6
|
+
* and prior to, the trust check in `dsse.ts`).
|
|
7
|
+
*
|
|
8
|
+
* Every by-digest fetch tries every configured base in order (guide §7 A5):
|
|
9
|
+
* a 404 moves to the next base, and on the **last** base a 404 is retried
|
|
10
|
+
* within the normal budget before `CHTYPES_SOURCE_UNREACHABLE` ("a listed
|
|
11
|
+
* digest that 404s is a host fault", never `UNPUBLISHED` — that verdict is
|
|
12
|
+
* for the tag alone).
|
|
13
|
+
*/
|
|
14
|
+
import { type RequestOptions } from './http.js';
|
|
15
|
+
import { type PlatformKey } from './types.js';
|
|
16
|
+
/**
|
|
17
|
+
* Refuses the two documented spelling mistakes (a `v` prefix, a
|
|
18
|
+
* `-lts`/`-stable` channel suffix) before any network call (guide §3). A
|
|
19
|
+
* spelling that is simply not numeric is NOT refused here: the tag lookup
|
|
20
|
+
* answers for it (`CHTYPES_ARTIFACT_UNPUBLISHED` when nothing matches), the
|
|
21
|
+
* same path any arbitrary OCI tag takes — and the conformance trees publish
|
|
22
|
+
* symbolic tags such as `t-untrusted-key`. `SPELLING_REGEX` is a positive
|
|
23
|
+
* pattern used elsewhere (`versionWithinRequest`) to decide whether a
|
|
24
|
+
* resolved predicate's version is compared against the request at all.
|
|
25
|
+
*/
|
|
26
|
+
export declare function checkSpelling(spelling: string): void;
|
|
27
|
+
/** A descriptor's `size` is absent when it comes from a lock pin (schema 3 stores digests only, never sizes). */
|
|
28
|
+
export interface Descriptor {
|
|
29
|
+
readonly mediaType: string;
|
|
30
|
+
readonly digest: string;
|
|
31
|
+
readonly size?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface ManifestInfo {
|
|
34
|
+
readonly digest: string;
|
|
35
|
+
readonly bytes: Buffer;
|
|
36
|
+
readonly layer: Descriptor;
|
|
37
|
+
readonly config: Descriptor | undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parses an OCI image manifest's layer (exactly one, required) and config
|
|
41
|
+
* descriptors. `CHTYPES_SOURCE_INCOMPATIBLE` is reserved for a recognized-but-wrong
|
|
42
|
+
* media type (guide §3); unparseable JSON or a manifest that disagrees with
|
|
43
|
+
* its own shape (not exactly one layer) is `CORRUPT` — "a release that
|
|
44
|
+
* disagrees with itself", the same bucket a hash mismatch falls into.
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseManifest(digest: string, bytes: Buffer): ManifestInfo;
|
|
47
|
+
/**
|
|
48
|
+
* Verifies fetched bytes against the descriptor that named them (OCI content
|
|
49
|
+
* addressing — independent of signature trust, and checked **before** any
|
|
50
|
+
* decompression or JSON parsing of untrusted content). `size` is checked
|
|
51
|
+
* only when the descriptor carries one — a lock pin (schema 3) has a digest
|
|
52
|
+
* only, never a size. A mismatch is `CORRUPT`: "any hash mismatch along the
|
|
53
|
+
* chain" (the same verdict v0's `ArtifactCorruptError` names), never
|
|
54
|
+
* `SOURCE_INCOMPATIBLE`, which is reserved for a wrong media type.
|
|
55
|
+
*/
|
|
56
|
+
export declare function verifyDescriptor(descriptor: Descriptor, bytes: Buffer, what: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* The same check as `verifyDescriptor`, for a caller that streamed the bytes
|
|
59
|
+
* through a hasher rather than holding them in one `Buffer` — `unpack.ts`'s
|
|
60
|
+
* layer download, which is never buffered whole in memory.
|
|
61
|
+
*/
|
|
62
|
+
export declare function verifyDigestAndSize(descriptor: Descriptor, actualSha256Hex: string, actualSize: number, what: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* `GET manifests/<digest>`, tried across every base (guide §6: `--frozen`'s
|
|
65
|
+
* manifest fetch; also `fetchSigned`'s referrer manifest hop), always with
|
|
66
|
+
* the manifest `Accept` header (delivery-side review).
|
|
67
|
+
*/
|
|
68
|
+
export declare function fetchManifestBytesByDigest(bases: readonly string[], descriptor: Descriptor, options: RequestOptions): Promise<Buffer>;
|
|
69
|
+
/** `GET blobs/<digest>`, tried across every base, fully buffered — a bundle, never the (potentially huge) library layer. */
|
|
70
|
+
export declare function fetchBlobBytesByDigest(bases: readonly string[], descriptor: Descriptor, options: RequestOptions): Promise<Buffer>;
|
|
71
|
+
export interface ByteSink {
|
|
72
|
+
reset(): void;
|
|
73
|
+
write(chunk: Buffer): void;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* `GET blobs/<digest>` straight into `sink` (`unpack.ts`'s hashing temp
|
|
77
|
+
* file) — the library layer, which is never buffered whole in memory. Tries
|
|
78
|
+
* every base in order, same as every other by-digest fetch in this module. A
|
|
79
|
+
* `file://` base has no streaming primitive of its own, so it is read whole
|
|
80
|
+
* and written to the sink in one call — acceptable because fixture layers
|
|
81
|
+
* are small test artifacts, never the multi-hundred-megabyte real ones.
|
|
82
|
+
*/
|
|
83
|
+
export declare function fetchBlobToSink(bases: readonly string[], descriptor: Descriptor, options: RequestOptions, sink: ByteSink): Promise<void>;
|
|
84
|
+
/** `fetchManifestBytesByDigest` plus parsing — `--frozen`'s and `fetchSigned`'s "give me this manifest" primitive. */
|
|
85
|
+
export declare function fetchManifestByDigest(bases: readonly string[], digest: string, options: RequestOptions): Promise<ManifestInfo>;
|
|
86
|
+
export interface IndexResolveResult {
|
|
87
|
+
readonly repositoryRoot: string;
|
|
88
|
+
readonly indexDigest: string;
|
|
89
|
+
readonly indexBytes: Buffer;
|
|
90
|
+
readonly manifest: ManifestInfo;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* `GET manifests/<spelling>` across `bases` in order (guide §3, §7 A5's tag
|
|
94
|
+
* rule: a tag 404 moves to the next base, and every base 404ing is
|
|
95
|
+
* `UNPUBLISHED`), then the platform's manifest by digest across every base
|
|
96
|
+
* (mirrors may carry the same tag pointing at the same digest, so a base
|
|
97
|
+
* that served the index is not the only one asked for its blobs).
|
|
98
|
+
*/
|
|
99
|
+
export declare function resolveTag(bases: readonly string[], spelling: string, platform: PlatformKey, options: RequestOptions): Promise<IndexResolveResult>;
|
|
100
|
+
//# sourceMappingURL=oci.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oci.d.ts","sourceRoot":"","sources":["../../src/ocifetch/oci.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,EAAE,KAAK,cAAc,EAA+C,MAAM,WAAW,CAAC;AAC7F,OAAO,EAAiE,KAAK,WAAW,EAAgB,MAAM,YAAY,CAAC;AAE3H;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAOpD;AAED,iHAAiH;AACjH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;CACzC;AAmCD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAqBzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAE1F;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAO3H;AAmDD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,4HAA4H;AAC5H,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,IAAI,IAAI,CAAC;IACd,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B9I;AAED,sHAAsH;AACtH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAGpI;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAiF7B"}
|