@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.
Files changed (195) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +34 -38
  3. package/dist/abi1/buildinfo.d.ts +40 -0
  4. package/dist/abi1/buildinfo.d.ts.map +1 -0
  5. package/dist/abi1/buildinfo.js +83 -0
  6. package/dist/abi1/buildinfo.js.map +1 -0
  7. package/dist/abi1/calls.gen.d.ts +55 -0
  8. package/dist/abi1/calls.gen.d.ts.map +1 -0
  9. package/dist/abi1/calls.gen.js +110 -0
  10. package/dist/abi1/calls.gen.js.map +1 -0
  11. package/dist/abi1/decls.gen.d.ts +115 -0
  12. package/dist/abi1/decls.gen.d.ts.map +1 -0
  13. package/dist/abi1/decls.gen.js +1613 -0
  14. package/dist/abi1/decls.gen.js.map +1 -0
  15. package/dist/abi1/errmap.gen.d.ts +18 -0
  16. package/dist/abi1/errmap.gen.d.ts.map +1 -0
  17. package/dist/abi1/errmap.gen.js +66 -0
  18. package/dist/abi1/errmap.gen.js.map +1 -0
  19. package/dist/abi1/errors.d.ts +107 -0
  20. package/dist/abi1/errors.d.ts.map +1 -0
  21. package/dist/abi1/errors.js +134 -0
  22. package/dist/abi1/errors.js.map +1 -0
  23. package/dist/abi1/handles.d.ts +31 -0
  24. package/dist/abi1/handles.d.ts.map +1 -0
  25. package/dist/abi1/handles.js +76 -0
  26. package/dist/abi1/handles.js.map +1 -0
  27. package/dist/abi1/index.d.ts +17 -0
  28. package/dist/abi1/index.d.ts.map +1 -0
  29. package/dist/abi1/index.js +17 -0
  30. package/dist/abi1/index.js.map +1 -0
  31. package/dist/abi1/libc.d.ts +54 -0
  32. package/dist/abi1/libc.d.ts.map +1 -0
  33. package/dist/abi1/libc.gen.d.ts +12 -0
  34. package/dist/abi1/libc.gen.d.ts.map +1 -0
  35. package/dist/abi1/libc.gen.js +75 -0
  36. package/dist/abi1/libc.gen.js.map +1 -0
  37. package/dist/abi1/libc.js +109 -0
  38. package/dist/abi1/libc.js.map +1 -0
  39. package/dist/abi1/loader.d.ts +99 -0
  40. package/dist/abi1/loader.d.ts.map +1 -0
  41. package/dist/abi1/loader.js +261 -0
  42. package/dist/abi1/loader.js.map +1 -0
  43. package/dist/abi1/raw.d.ts +104 -0
  44. package/dist/abi1/raw.d.ts.map +1 -0
  45. package/dist/abi1/raw.js +296 -0
  46. package/dist/abi1/raw.js.map +1 -0
  47. package/dist/abi1/strictjson.d.ts +19 -0
  48. package/dist/abi1/strictjson.d.ts.map +1 -0
  49. package/dist/abi1/strictjson.js +78 -0
  50. package/dist/abi1/strictjson.js.map +1 -0
  51. package/dist/abi1/vocab.gen.d.ts +169 -0
  52. package/dist/abi1/vocab.gen.d.ts.map +1 -0
  53. package/dist/abi1/vocab.gen.js +306 -0
  54. package/dist/abi1/vocab.gen.js.map +1 -0
  55. package/dist/cli.d.ts +25 -26
  56. package/dist/cli.d.ts.map +1 -1
  57. package/dist/cli.js +206 -218
  58. package/dist/cli.js.map +1 -1
  59. package/dist/documents.d.ts +195 -0
  60. package/dist/documents.d.ts.map +1 -0
  61. package/dist/documents.js +389 -0
  62. package/dist/documents.js.map +1 -0
  63. package/dist/env.d.ts +16 -0
  64. package/dist/env.d.ts.map +1 -0
  65. package/dist/env.js +57 -0
  66. package/dist/env.js.map +1 -0
  67. package/dist/index.d.ts +19 -24
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +17 -23
  70. package/dist/index.js.map +1 -1
  71. package/dist/json.d.ts +11 -89
  72. package/dist/json.d.ts.map +1 -1
  73. package/dist/json.js +16 -180
  74. package/dist/json.js.map +1 -1
  75. package/dist/library.d.ts +53 -309
  76. package/dist/library.d.ts.map +1 -1
  77. package/dist/library.js +77 -315
  78. package/dist/library.js.map +1 -1
  79. package/dist/ocifetch/constants.gen.d.ts +84 -0
  80. package/dist/ocifetch/constants.gen.d.ts.map +1 -0
  81. package/dist/ocifetch/constants.gen.js +92 -0
  82. package/dist/ocifetch/constants.gen.js.map +1 -0
  83. package/dist/ocifetch/dsse.d.ts +114 -0
  84. package/dist/ocifetch/dsse.d.ts.map +1 -0
  85. package/dist/ocifetch/dsse.js +331 -0
  86. package/dist/ocifetch/dsse.js.map +1 -0
  87. package/dist/ocifetch/ensure.d.ts +65 -0
  88. package/dist/ocifetch/ensure.d.ts.map +1 -0
  89. package/dist/ocifetch/ensure.js +775 -0
  90. package/dist/ocifetch/ensure.js.map +1 -0
  91. package/dist/ocifetch/errors.d.ts +92 -0
  92. package/dist/ocifetch/errors.d.ts.map +1 -0
  93. package/dist/ocifetch/errors.js +101 -0
  94. package/dist/ocifetch/errors.js.map +1 -0
  95. package/dist/ocifetch/goldens.d.ts +44 -0
  96. package/dist/ocifetch/goldens.d.ts.map +1 -0
  97. package/dist/ocifetch/goldens.js +62 -0
  98. package/dist/ocifetch/goldens.js.map +1 -0
  99. package/dist/ocifetch/http.d.ts +124 -0
  100. package/dist/ocifetch/http.d.ts.map +1 -0
  101. package/dist/ocifetch/http.js +549 -0
  102. package/dist/ocifetch/http.js.map +1 -0
  103. package/dist/ocifetch/index.d.ts +17 -0
  104. package/dist/ocifetch/index.d.ts.map +1 -0
  105. package/dist/ocifetch/index.js +14 -0
  106. package/dist/ocifetch/index.js.map +1 -0
  107. package/dist/ocifetch/layout.d.ts +126 -0
  108. package/dist/ocifetch/layout.d.ts.map +1 -0
  109. package/dist/ocifetch/layout.js +375 -0
  110. package/dist/ocifetch/layout.js.map +1 -0
  111. package/dist/ocifetch/localverify.d.ts +43 -0
  112. package/dist/ocifetch/localverify.d.ts.map +1 -0
  113. package/dist/ocifetch/localverify.js +164 -0
  114. package/dist/ocifetch/localverify.js.map +1 -0
  115. package/dist/ocifetch/lock.d.ts +39 -0
  116. package/dist/ocifetch/lock.d.ts.map +1 -0
  117. package/dist/ocifetch/lock.js +140 -0
  118. package/dist/ocifetch/lock.js.map +1 -0
  119. package/dist/ocifetch/oci.d.ts +100 -0
  120. package/dist/ocifetch/oci.d.ts.map +1 -0
  121. package/dist/ocifetch/oci.js +323 -0
  122. package/dist/ocifetch/oci.js.map +1 -0
  123. package/dist/ocifetch/referrers.d.ts +55 -0
  124. package/dist/ocifetch/referrers.d.ts.map +1 -0
  125. package/dist/ocifetch/referrers.js +132 -0
  126. package/dist/ocifetch/referrers.js.map +1 -0
  127. package/dist/ocifetch/types.d.ts +167 -0
  128. package/dist/ocifetch/types.d.ts.map +1 -0
  129. package/dist/ocifetch/types.js +88 -0
  130. package/dist/ocifetch/types.js.map +1 -0
  131. package/dist/ocifetch/unpack.d.ts +55 -0
  132. package/dist/ocifetch/unpack.d.ts.map +1 -0
  133. package/dist/ocifetch/unpack.js +205 -0
  134. package/dist/ocifetch/unpack.js.map +1 -0
  135. package/dist/registry.d.ts +38 -387
  136. package/dist/registry.d.ts.map +1 -1
  137. package/dist/registry.js +94 -819
  138. package/dist/registry.js.map +1 -1
  139. package/dist/schema.d.ts +77 -588
  140. package/dist/schema.d.ts.map +1 -1
  141. package/dist/schema.js +87 -549
  142. package/dist/schema.js.map +1 -1
  143. package/dist/settings.d.ts +27 -36
  144. package/dist/settings.d.ts.map +1 -1
  145. package/dist/settings.js +75 -25
  146. package/dist/settings.js.map +1 -1
  147. package/dist/setup.d.ts +37 -0
  148. package/dist/setup.d.ts.map +1 -0
  149. package/dist/setup.js +60 -0
  150. package/dist/setup.js.map +1 -0
  151. package/dist/tar.d.ts +27 -11
  152. package/dist/tar.d.ts.map +1 -1
  153. package/dist/tar.js +54 -32
  154. package/dist/tar.js.map +1 -1
  155. package/package.json +2 -2
  156. package/dist/discover.d.ts +0 -142
  157. package/dist/discover.d.ts.map +0 -1
  158. package/dist/discover.js +0 -288
  159. package/dist/discover.js.map +0 -1
  160. package/dist/error-codes.d.ts +0 -80
  161. package/dist/error-codes.d.ts.map +0 -1
  162. package/dist/error-codes.js +0 -139
  163. package/dist/error-codes.js.map +0 -1
  164. package/dist/errors.d.ts +0 -284
  165. package/dist/errors.d.ts.map +0 -1
  166. package/dist/errors.js +0 -321
  167. package/dist/errors.js.map +0 -1
  168. package/dist/fetch.d.ts +0 -382
  169. package/dist/fetch.d.ts.map +0 -1
  170. package/dist/fetch.js +0 -1498
  171. package/dist/fetch.js.map +0 -1
  172. package/dist/ffi.d.ts +0 -410
  173. package/dist/ffi.d.ts.map +0 -1
  174. package/dist/ffi.js +0 -1154
  175. package/dist/ffi.js.map +0 -1
  176. package/dist/format.d.ts +0 -128
  177. package/dist/format.d.ts.map +0 -1
  178. package/dist/format.js +0 -132
  179. package/dist/format.js.map +0 -1
  180. package/dist/numeric.d.ts +0 -20
  181. package/dist/numeric.d.ts.map +0 -1
  182. package/dist/numeric.js +0 -107
  183. package/dist/numeric.js.map +0 -1
  184. package/dist/paths.d.ts +0 -55
  185. package/dist/paths.d.ts.map +0 -1
  186. package/dist/paths.js +0 -87
  187. package/dist/paths.js.map +0 -1
  188. package/dist/results.d.ts +0 -495
  189. package/dist/results.d.ts.map +0 -1
  190. package/dist/results.js +0 -406
  191. package/dist/results.js.map +0 -1
  192. package/dist/transform.d.ts +0 -73
  193. package/dist/transform.d.ts.map +0 -1
  194. package/dist/transform.js +0 -533
  195. package/dist/transform.js.map +0 -1
@@ -0,0 +1,323 @@
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 { createHash } from 'node:crypto';
15
+ import { asString, field, items, parseJsonValue } from '../json.js';
16
+ import { MANIFEST_MAX_BYTES, MAX_UNPACKED_BYTES, MEDIA_TYPE_INDEX, MEDIA_TYPE_MANIFEST, SPELLING_REFUSE_HINT_REGEX } from './constants.gen.js';
17
+ import { ArtifactCorruptError, ArtifactUnpublishedError, SourceIncompatibleError, SourceUnreachableError } from './errors.js';
18
+ import { readFileUrl, requestBuffered, requestToSink } from './http.js';
19
+ import { digestOfHex, endpointUrl, hexOfDigest, MANIFEST_ACCEPT_HEADER, platformInfo } from './types.js';
20
+ /**
21
+ * Refuses the two documented spelling mistakes (a `v` prefix, a
22
+ * `-lts`/`-stable` channel suffix) before any network call (guide §3). A
23
+ * spelling that is simply not numeric is NOT refused here: the tag lookup
24
+ * answers for it (`CHTYPES_ARTIFACT_UNPUBLISHED` when nothing matches), the
25
+ * same path any arbitrary OCI tag takes — and the conformance trees publish
26
+ * symbolic tags such as `t-untrusted-key`. `SPELLING_REGEX` is a positive
27
+ * pattern used elsewhere (`versionWithinRequest`) to decide whether a
28
+ * resolved predicate's version is compared against the request at all.
29
+ */
30
+ export function checkSpelling(spelling) {
31
+ if (new RegExp(SPELLING_REFUSE_HINT_REGEX).test(spelling)) {
32
+ throw new Error(`chtypes: ${JSON.stringify(spelling)} is not a v1 version spelling (no "v" prefix, no "-lts"/"-stable" suffix); ` +
33
+ 'use the bare version, e.g. "26.8" or "26.8.15.10"');
34
+ }
35
+ }
36
+ /** A `GET …/manifests/<ref>` (the tag resolve) — always carries the manifest `Accept` header (delivery-side review: our host ignores it, a mirror may need it). */
37
+ async function getJsonAt(url, maxBytes, options) {
38
+ const res = url.startsWith('file:')
39
+ ? await readFileUrl(url, maxBytes)
40
+ : await requestBuffered(url, { ...options, maxBytes, headers: { ...options.headers, accept: MANIFEST_ACCEPT_HEADER } });
41
+ if (res.status !== 200)
42
+ return { status: res.status, body: res.body, json: null };
43
+ const json = parseJsonValue(res.body);
44
+ return { status: res.status, body: res.body, json };
45
+ }
46
+ function descriptorField(json, key) {
47
+ const d = field(json, key);
48
+ if (d === undefined)
49
+ return undefined;
50
+ const digest = asString(field(d, 'digest'));
51
+ if (digest === '')
52
+ return undefined;
53
+ return { mediaType: asString(field(d, 'mediaType')), digest, size: numberField(d, 'size') };
54
+ }
55
+ function numberField(json, key) {
56
+ const v = field(json, key);
57
+ if (v === undefined || v.kind !== 'number')
58
+ return 0;
59
+ const n = Number(v.raw.toString('utf8'));
60
+ return Number.isFinite(n) ? n : 0;
61
+ }
62
+ function sha256Hex(buf) {
63
+ return createHash('sha256').update(buf).digest('hex');
64
+ }
65
+ /**
66
+ * Parses an OCI image manifest's layer (exactly one, required) and config
67
+ * descriptors. `CHTYPES_SOURCE_INCOMPATIBLE` is reserved for a recognized-but-wrong
68
+ * media type (guide §3); unparseable JSON or a manifest that disagrees with
69
+ * its own shape (not exactly one layer) is `CORRUPT` — "a release that
70
+ * disagrees with itself", the same bucket a hash mismatch falls into.
71
+ */
72
+ export function parseManifest(digest, bytes) {
73
+ const json = parseJsonValue(bytes);
74
+ if (json === null)
75
+ throw new ArtifactCorruptError(`chtypes: manifest ${digest} is not valid JSON`);
76
+ const mediaType = asString(field(json, 'mediaType'));
77
+ if (mediaType !== '' && mediaType !== MEDIA_TYPE_MANIFEST) {
78
+ throw new SourceIncompatibleError(`chtypes: manifest ${digest} has mediaType ${JSON.stringify(mediaType)}, not ${MEDIA_TYPE_MANIFEST}`);
79
+ }
80
+ const layers = items(field(json, 'layers'));
81
+ if (layers.length !== 1) {
82
+ throw new ArtifactCorruptError(`chtypes: manifest ${digest} has ${layers.length} layers, expected exactly 1`);
83
+ }
84
+ const layerJson = layers[0];
85
+ const layerDigest = asString(field(layerJson, 'digest'));
86
+ if (layerDigest === '')
87
+ throw new ArtifactCorruptError(`chtypes: manifest ${digest}'s layer has no digest`);
88
+ const layer = {
89
+ mediaType: asString(field(layerJson, 'mediaType')),
90
+ digest: layerDigest,
91
+ size: numberField(layerJson, 'size'),
92
+ };
93
+ const config = descriptorField(json, 'config');
94
+ return { digest, bytes, layer, config };
95
+ }
96
+ /**
97
+ * Verifies fetched bytes against the descriptor that named them (OCI content
98
+ * addressing — independent of signature trust, and checked **before** any
99
+ * decompression or JSON parsing of untrusted content). `size` is checked
100
+ * only when the descriptor carries one — a lock pin (schema 3) has a digest
101
+ * only, never a size. A mismatch is `CORRUPT`: "any hash mismatch along the
102
+ * chain" (the same verdict v0's `ArtifactCorruptError` names), never
103
+ * `SOURCE_INCOMPATIBLE`, which is reserved for a wrong media type.
104
+ */
105
+ export function verifyDescriptor(descriptor, bytes, what) {
106
+ verifyDigestAndSize(descriptor, sha256Hex(bytes), bytes.length, what);
107
+ }
108
+ /**
109
+ * The same check as `verifyDescriptor`, for a caller that streamed the bytes
110
+ * through a hasher rather than holding them in one `Buffer` — `unpack.ts`'s
111
+ * layer download, which is never buffered whole in memory.
112
+ */
113
+ export function verifyDigestAndSize(descriptor, actualSha256Hex, actualSize, what) {
114
+ if (descriptor.size !== undefined && actualSize !== descriptor.size) {
115
+ throw new ArtifactCorruptError(`chtypes: ${what} is ${actualSize} bytes, descriptor named ${descriptor.size}`);
116
+ }
117
+ if (actualSha256Hex !== hexOfDigest(descriptor.digest)) {
118
+ throw new ArtifactCorruptError(`chtypes: ${what}'s sha256 does not match its own descriptor`);
119
+ }
120
+ }
121
+ async function fetchByDigestAcrossBases(bases, pathFor, descriptor, what, defaultMaxBytes, options, extraHeaders) {
122
+ if (bases.length === 0)
123
+ throw new Error('chtypes: no base URLs configured');
124
+ let lastUnreachable;
125
+ for (let i = 0; i < bases.length; i++) {
126
+ const base = bases[i];
127
+ const isLast = i === bases.length - 1;
128
+ const url = endpointUrl(base, pathFor(descriptor.digest));
129
+ const maxBytes = descriptor.size ?? defaultMaxBytes;
130
+ let res;
131
+ try {
132
+ res = url.startsWith('file:')
133
+ ? await readFileUrl(url, maxBytes)
134
+ : await requestBuffered(url, {
135
+ ...options,
136
+ maxBytes,
137
+ retryOn404: isLast,
138
+ headers: { ...options.headers, ...extraHeaders },
139
+ });
140
+ }
141
+ catch (err) {
142
+ // A temporary error (guide §2: a timeout, a 5xx exhausted, a dead
143
+ // host) moves to the next base — never a verification failure, which
144
+ // propagates immediately (`mirror-no-failover-on-verify-fail`).
145
+ if (err instanceof SourceUnreachableError && !isLast) {
146
+ lastUnreachable = err;
147
+ continue;
148
+ }
149
+ throw err;
150
+ }
151
+ if (res.status === 404)
152
+ continue;
153
+ if (res.status !== 200)
154
+ throw new SourceUnreachableError(`chtypes: ${url} returned status ${res.status}`);
155
+ verifyDescriptor(descriptor, res.body, what);
156
+ return res.body;
157
+ }
158
+ if (lastUnreachable !== undefined)
159
+ throw lastUnreachable;
160
+ // Unreachable through an ordinary persistent 404 on the last base: that
161
+ // already throws `SourceUnreachableError` from inside `requestBuffered`
162
+ // (via `retryOn404`) before control returns here. This covers only an
163
+ // empty `bases` list.
164
+ throw new SourceUnreachableError(`chtypes: ${what} (${descriptor.digest}) was not found on any configured base`);
165
+ }
166
+ /**
167
+ * `GET manifests/<digest>`, tried across every base (guide §6: `--frozen`'s
168
+ * manifest fetch; also `fetchSigned`'s referrer manifest hop), always with
169
+ * the manifest `Accept` header (delivery-side review).
170
+ */
171
+ export async function fetchManifestBytesByDigest(bases, descriptor, options) {
172
+ if (descriptor.size !== undefined && descriptor.size > MANIFEST_MAX_BYTES) {
173
+ throw new ArtifactCorruptError(`chtypes: manifest ${descriptor.digest}'s descriptor names ${descriptor.size} bytes, over the ${MANIFEST_MAX_BYTES}-byte manifest cap`);
174
+ }
175
+ return fetchByDigestAcrossBases(bases, (d) => `/manifests/${d}`, descriptor, `manifest ${descriptor.digest}`, MANIFEST_MAX_BYTES, options, {
176
+ accept: MANIFEST_ACCEPT_HEADER,
177
+ });
178
+ }
179
+ /** `GET blobs/<digest>`, tried across every base, fully buffered — a bundle, never the (potentially huge) library layer. */
180
+ export async function fetchBlobBytesByDigest(bases, descriptor, options) {
181
+ return fetchByDigestAcrossBases(bases, (d) => `/blobs/${d}`, descriptor, `blob ${descriptor.digest}`, MAX_UNPACKED_BYTES, options);
182
+ }
183
+ /**
184
+ * `GET blobs/<digest>` straight into `sink` (`unpack.ts`'s hashing temp
185
+ * file) — the library layer, which is never buffered whole in memory. Tries
186
+ * every base in order, same as every other by-digest fetch in this module. A
187
+ * `file://` base has no streaming primitive of its own, so it is read whole
188
+ * and written to the sink in one call — acceptable because fixture layers
189
+ * are small test artifacts, never the multi-hundred-megabyte real ones.
190
+ */
191
+ export async function fetchBlobToSink(bases, descriptor, options, sink) {
192
+ if (bases.length === 0)
193
+ throw new Error('chtypes: no base URLs configured');
194
+ const maxBytes = descriptor.size ?? MAX_UNPACKED_BYTES;
195
+ let lastUnreachable;
196
+ for (let i = 0; i < bases.length; i++) {
197
+ const base = bases[i];
198
+ const isLast = i === bases.length - 1;
199
+ const url = endpointUrl(base, `/blobs/${descriptor.digest}`);
200
+ try {
201
+ if (url.startsWith('file:')) {
202
+ const res = await readFileUrl(url, maxBytes);
203
+ if (res.status === 404)
204
+ continue;
205
+ if (res.status !== 200)
206
+ throw new SourceUnreachableError(`chtypes: ${url} returned status ${res.status}`);
207
+ sink.reset();
208
+ sink.write(res.body);
209
+ return;
210
+ }
211
+ const res = await requestToSink(url, { ...options, maxBytes, retryOn404: isLast }, sink);
212
+ if (res.status === 404)
213
+ continue;
214
+ if (res.status !== 200 && res.status !== 206)
215
+ throw new SourceUnreachableError(`chtypes: ${url} returned status ${res.status}`);
216
+ return;
217
+ }
218
+ catch (err) {
219
+ if (err instanceof SourceUnreachableError && !isLast) {
220
+ lastUnreachable = err;
221
+ continue;
222
+ }
223
+ throw err;
224
+ }
225
+ }
226
+ if (lastUnreachable !== undefined)
227
+ throw lastUnreachable;
228
+ throw new SourceUnreachableError(`chtypes: blob ${descriptor.digest} was not found on any configured base`);
229
+ }
230
+ /** `fetchManifestBytesByDigest` plus parsing — `--frozen`'s and `fetchSigned`'s "give me this manifest" primitive. */
231
+ export async function fetchManifestByDigest(bases, digest, options) {
232
+ const bytes = await fetchManifestBytesByDigest(bases, { mediaType: MEDIA_TYPE_MANIFEST, digest }, options);
233
+ return parseManifest(digest, bytes);
234
+ }
235
+ /**
236
+ * `GET manifests/<spelling>` across `bases` in order (guide §3, §7 A5's tag
237
+ * rule: a tag 404 moves to the next base, and every base 404ing is
238
+ * `UNPUBLISHED`), then the platform's manifest by digest across every base
239
+ * (mirrors may carry the same tag pointing at the same digest, so a base
240
+ * that served the index is not the only one asked for its blobs).
241
+ */
242
+ export async function resolveTag(bases, spelling, platform, options) {
243
+ checkSpelling(spelling);
244
+ if (bases.length === 0)
245
+ throw new Error('chtypes: no base URLs configured');
246
+ const info = platformInfo(platform);
247
+ const triedBases = [];
248
+ for (let baseIndex = 0; baseIndex < bases.length; baseIndex++) {
249
+ const base = bases[baseIndex];
250
+ const isLastBase = baseIndex === bases.length - 1;
251
+ const url = endpointUrl(base, `/manifests/${spelling}`);
252
+ let status;
253
+ let body;
254
+ let json;
255
+ try {
256
+ ({ status, body, json } = await getJsonAt(url, MANIFEST_MAX_BYTES, options));
257
+ }
258
+ catch (err) {
259
+ // A temporary error (guide §2: a timeout, a 5xx exhausted, a dead
260
+ // host) moves to the next base, same as a tag 404 — never a
261
+ // verification failure, which propagates immediately.
262
+ if (err instanceof SourceUnreachableError && !isLastBase) {
263
+ triedBases.push(base);
264
+ continue;
265
+ }
266
+ throw err;
267
+ }
268
+ if (status === 404) {
269
+ triedBases.push(base);
270
+ continue;
271
+ }
272
+ if (status !== 200) {
273
+ // A persistent retryable status on the last base already threw from
274
+ // inside `requestBuffered`; anything reaching here (400, 418, …) is an
275
+ // anomaly this fetcher does not have a specific verdict for.
276
+ throw new SourceUnreachableError(`chtypes: ${url} returned status ${status}`);
277
+ }
278
+ if (json === null) {
279
+ throw new ArtifactCorruptError(`chtypes: ${url} did not return valid JSON`);
280
+ }
281
+ const mediaType = asString(field(json, 'mediaType'));
282
+ if (mediaType !== '' && mediaType !== MEDIA_TYPE_INDEX) {
283
+ throw new SourceIncompatibleError(`chtypes: ${url} has mediaType ${JSON.stringify(mediaType)}, not ${MEDIA_TYPE_INDEX}`);
284
+ }
285
+ const manifests = items(field(json, 'manifests'));
286
+ const matches = manifests.filter((m) => {
287
+ const p = field(m, 'platform');
288
+ return asString(field(p, 'os')) === info.os && asString(field(p, 'architecture')) === info.architecture;
289
+ });
290
+ if (matches.length === 0) {
291
+ const offered = manifests
292
+ .map((m) => {
293
+ const p = field(m, 'platform');
294
+ return `${asString(field(p, 'os'))}-${asString(field(p, 'architecture'))}`;
295
+ })
296
+ .filter((k) => k !== '-');
297
+ throw new ArtifactUnpublishedError(`chtypes: ${spelling} offers no manifest for ${platform}; the index offers: ${offered.join(', ') || '(none)'}`);
298
+ }
299
+ if (matches.length > 1) {
300
+ // `index-duplicate-platform`: the index disagrees with itself about
301
+ // which manifest is this platform's — `CORRUPT`, the plan's own
302
+ // annotation for this case.
303
+ throw new ArtifactCorruptError(`chtypes: ${spelling}'s index names ${platform} more than once`);
304
+ }
305
+ const d = matches[0];
306
+ const manifestDigest = asString(field(d, 'digest'));
307
+ if (manifestDigest === '')
308
+ throw new ArtifactCorruptError(`chtypes: ${spelling}'s ${platform} descriptor has no digest`);
309
+ const manifestDescriptor = {
310
+ mediaType: asString(field(d, 'mediaType')),
311
+ digest: manifestDigest,
312
+ size: numberField(d, 'size'),
313
+ };
314
+ if (manifestDescriptor.mediaType !== MEDIA_TYPE_MANIFEST) {
315
+ throw new SourceIncompatibleError(`chtypes: ${spelling}'s ${platform} descriptor has mediaType ${JSON.stringify(manifestDescriptor.mediaType)}, not ${MEDIA_TYPE_MANIFEST}`);
316
+ }
317
+ const manifestBytes = await fetchManifestBytesByDigest(bases, manifestDescriptor, options);
318
+ const manifest = parseManifest(manifestDigest, manifestBytes);
319
+ return { repositoryRoot: base, indexDigest: digestOfHex(sha256Hex(body)), indexBytes: body, manifest };
320
+ }
321
+ throw new ArtifactUnpublishedError(`chtypes: ${spelling} is unpublished: every base 404d the tag (${triedBases.join(', ')})`);
322
+ }
323
+ //# sourceMappingURL=oci.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oci.js","sourceRoot":"","sources":["../../src/ocifetch/oci.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Referrer discovery (`docs/guides/fetch-v1.md` §4): the OCI referrers API,
3
+ * **and** the tag-schema fallback (`sha256-<hex>`) — both implemented, never
4
+ * only one, because which a host serves is a property of that host, not of
5
+ * this fetcher.
6
+ *
7
+ * **The fallback tag is consulted only when the referrers API's own answer
8
+ * has no bundle of the trusted signature artifactType** — an empty list, a
9
+ * list holding only other artifactTypes (goldens, say), or the API itself
10
+ * unsupported (errors, or any non-200). When the referrers API already
11
+ * names a candidate of that artifactType, the fallback tag is never fetched
12
+ * — this keeps the request count the same shape as Go, Python and Rust's
13
+ * lanes, which conformance cases assert on (a case can require "no fallback
14
+ * request" for a referrers-API-only host). A referrers-API 404 reads the
15
+ * same as "unsupported": fall back at once, with no retry — this is a
16
+ * discovery probe, not a promise that a specific digest exists (unlike a
17
+ * by-digest manifest/blob fetch, which does retry a 404 on the last base;
18
+ * `oci.ts`'s `retryOn404`).
19
+ */
20
+ import { type RequestOptions } from './http.js';
21
+ export interface ReferrerDescriptor {
22
+ readonly digest: string;
23
+ readonly mediaType: string;
24
+ readonly artifactType: string | undefined;
25
+ readonly size: number;
26
+ }
27
+ /** The fallback tag schema name for a digest, e.g. `sha256:ab12..` -> `sha256-ab12..`. */
28
+ export declare function fallbackTagFor(digest: string): string;
29
+ /**
30
+ * Every referrer of `artifactType` for `digest` within `repositoryRoot`,
31
+ * from the referrers API alone. `[]` whenever the API's own answer has no
32
+ * bundle of this `artifactType` — an empty list, a list of only other
33
+ * artifactTypes, a 404 (treated as "unsupported here", not retried — see
34
+ * this module's header), or any other error — and in every one of those
35
+ * cases `discoverSignatureCandidates` then also tries the fallback tag.
36
+ */
37
+ export declare function discoverReferrers(repositoryRoot: string, digest: string, artifactType: string, options: RequestOptions): Promise<ReferrerDescriptor[]>;
38
+ /**
39
+ * The fallback tag's own referrer list for `digest` (the tag-schema index,
40
+ * `GET manifests/<tag>` — always with the manifest `Accept` header), filtered
41
+ * the same way as the referrers API. Only ever called by
42
+ * `discoverSignatureCandidates` when the referrers API found nothing of the
43
+ * trusted artifactType.
44
+ */
45
+ export declare function discoverFallbackTag(repositoryRoot: string, digest: string, artifactType: string, options: RequestOptions): Promise<ReferrerDescriptor[]>;
46
+ /**
47
+ * The candidate list a caller should try verifying in order, stopping at
48
+ * the first success. Queries the referrers API first; the fallback tag is
49
+ * fetched **only** when the referrers API named no candidate of
50
+ * `artifactType` at all (see this module's header) — never unconditionally,
51
+ * so a referrers-API-only host sees exactly one discovery request, matching
52
+ * Go, Python and Rust.
53
+ */
54
+ export declare function discoverSignatureCandidates(repositoryRoot: string, digest: string, artifactType: string, options: RequestOptions): Promise<ReferrerDescriptor[]>;
55
+ //# sourceMappingURL=referrers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"referrers.d.ts","sourceRoot":"","sources":["../../src/ocifetch/referrers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAE,KAAK,cAAc,EAAgC,MAAM,WAAW,CAAC;AAG9E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMrD;AAkDD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAe/B;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAM/B;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAC/C,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAI/B"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Referrer discovery (`docs/guides/fetch-v1.md` §4): the OCI referrers API,
3
+ * **and** the tag-schema fallback (`sha256-<hex>`) — both implemented, never
4
+ * only one, because which a host serves is a property of that host, not of
5
+ * this fetcher.
6
+ *
7
+ * **The fallback tag is consulted only when the referrers API's own answer
8
+ * has no bundle of the trusted signature artifactType** — an empty list, a
9
+ * list holding only other artifactTypes (goldens, say), or the API itself
10
+ * unsupported (errors, or any non-200). When the referrers API already
11
+ * names a candidate of that artifactType, the fallback tag is never fetched
12
+ * — this keeps the request count the same shape as Go, Python and Rust's
13
+ * lanes, which conformance cases assert on (a case can require "no fallback
14
+ * request" for a referrers-API-only host). A referrers-API 404 reads the
15
+ * same as "unsupported": fall back at once, with no retry — this is a
16
+ * discovery probe, not a promise that a specific digest exists (unlike a
17
+ * by-digest manifest/blob fetch, which does retry a 404 on the last base;
18
+ * `oci.ts`'s `retryOn404`).
19
+ */
20
+ import { asString, field, items, parseJsonValue } from '../json.js';
21
+ import { MANIFEST_MAX_BYTES, MAX_REFERRERS } from './constants.gen.js';
22
+ import { ArtifactCorruptError } from './errors.js';
23
+ import { readFileUrl, requestBuffered } from './http.js';
24
+ import { endpointUrl, MANIFEST_ACCEPT_HEADER } from './types.js';
25
+ /** The fallback tag schema name for a digest, e.g. `sha256:ab12..` -> `sha256-ab12..`. */
26
+ export function fallbackTagFor(digest) {
27
+ const [algo, hex] = digest.split(':', 2);
28
+ if (algo !== 'sha256' || hex === undefined) {
29
+ throw new ArtifactCorruptError(`chtypes: cannot derive a fallback tag from digest ${JSON.stringify(digest)}`);
30
+ }
31
+ return `sha256-${hex}`;
32
+ }
33
+ async function getJson(url, maxBytes, options, extraHeaders) {
34
+ const res = url.startsWith('file:')
35
+ ? await readFileUrl(url, maxBytes)
36
+ : await requestBuffered(url, {
37
+ ...options,
38
+ maxBytes,
39
+ headers: { ...options.headers, ...extraHeaders },
40
+ });
41
+ if (res.status !== 200)
42
+ return { status: res.status, json: null };
43
+ const json = parseJsonValue(res.body);
44
+ if (json === null)
45
+ throw new ArtifactCorruptError(`chtypes: ${url} did not return valid JSON`);
46
+ return { status: res.status, json };
47
+ }
48
+ function descriptorsFromIndex(json) {
49
+ // A host may omit the index's own `mediaType`; the `manifests` array is
50
+ // read either way, so this is not itself a shape check (`oci.ts` checks
51
+ // media types where their presence is load-bearing).
52
+ const manifests = items(field(json, 'manifests'));
53
+ const out = [];
54
+ for (const m of manifests.slice(0, MAX_REFERRERS)) {
55
+ const digest = asString(field(m, 'digest'));
56
+ const descMediaType = asString(field(m, 'mediaType'));
57
+ const artifactTypeField = field(m, 'artifactType');
58
+ const size = numberField(m, 'size');
59
+ if (digest === '')
60
+ continue;
61
+ out.push({
62
+ digest,
63
+ mediaType: descMediaType,
64
+ artifactType: artifactTypeField === undefined ? undefined : asString(artifactTypeField),
65
+ size,
66
+ });
67
+ }
68
+ return out;
69
+ }
70
+ function numberField(json, key) {
71
+ const v = field(json, key);
72
+ if (v === undefined || v.kind !== 'number')
73
+ return 0;
74
+ const n = Number(v.raw.toString('utf8'));
75
+ return Number.isFinite(n) ? n : 0;
76
+ }
77
+ /**
78
+ * Every referrer of `artifactType` for `digest` within `repositoryRoot`,
79
+ * from the referrers API alone. `[]` whenever the API's own answer has no
80
+ * bundle of this `artifactType` — an empty list, a list of only other
81
+ * artifactTypes, a 404 (treated as "unsupported here", not retried — see
82
+ * this module's header), or any other error — and in every one of those
83
+ * cases `discoverSignatureCandidates` then also tries the fallback tag.
84
+ */
85
+ export async function discoverReferrers(repositoryRoot, digest, artifactType, options) {
86
+ const url = `${endpointUrl(repositoryRoot, `/referrers/${digest}`)}?artifactType=${encodeURIComponent(artifactType)}`;
87
+ const fromApi = [];
88
+ try {
89
+ const { status, json } = await getJson(url, MANIFEST_MAX_BYTES, options);
90
+ if (status === 200 && json !== null) {
91
+ for (const d of descriptorsFromIndex(json)) {
92
+ if (d.artifactType === artifactType)
93
+ fromApi.push(d);
94
+ }
95
+ }
96
+ }
97
+ catch {
98
+ // The referrers API is not guaranteed on every host (mirrors) — read as
99
+ // "no candidates here", exactly as an empty or goldens-only answer would.
100
+ }
101
+ return fromApi;
102
+ }
103
+ /**
104
+ * The fallback tag's own referrer list for `digest` (the tag-schema index,
105
+ * `GET manifests/<tag>` — always with the manifest `Accept` header), filtered
106
+ * the same way as the referrers API. Only ever called by
107
+ * `discoverSignatureCandidates` when the referrers API found nothing of the
108
+ * trusted artifactType.
109
+ */
110
+ export async function discoverFallbackTag(repositoryRoot, digest, artifactType, options) {
111
+ const tag = fallbackTagFor(digest);
112
+ const url = endpointUrl(repositoryRoot, `/manifests/${tag}`);
113
+ const { status, json } = await getJson(url, MANIFEST_MAX_BYTES, options, { accept: MANIFEST_ACCEPT_HEADER });
114
+ if (status !== 200 || json === null)
115
+ return [];
116
+ return descriptorsFromIndex(json).filter((d) => d.artifactType === artifactType);
117
+ }
118
+ /**
119
+ * The candidate list a caller should try verifying in order, stopping at
120
+ * the first success. Queries the referrers API first; the fallback tag is
121
+ * fetched **only** when the referrers API named no candidate of
122
+ * `artifactType` at all (see this module's header) — never unconditionally,
123
+ * so a referrers-API-only host sees exactly one discovery request, matching
124
+ * Go, Python and Rust.
125
+ */
126
+ export async function discoverSignatureCandidates(repositoryRoot, digest, artifactType, options) {
127
+ const fromApi = await discoverReferrers(repositoryRoot, digest, artifactType, options);
128
+ if (fromApi.length > 0)
129
+ return fromApi;
130
+ return discoverFallbackTag(repositoryRoot, digest, artifactType, options);
131
+ }
132
+ //# sourceMappingURL=referrers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"referrers.js","sourceRoot":"","sources":["../../src/ocifetch/referrers.ts"],"names":[],"mappings":"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"}