keepset 0.2.0 → 0.3.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.
@@ -0,0 +1,960 @@
1
+ import { Crosswalk } from "twindex";
2
+ import { z } from "zod";
3
+ //#region src/entry.d.ts
4
+ /** A stable identifier: an entry id, a catalogue id. It starts with a letter or digit, so no id can be `__proto__` or any other name that begins with an underscore. Entry ids stay the same across forks, which is what lets two catalogues be compared entry by entry. */
5
+ declare const IdSchema: z.ZodString;
6
+ /** An http or https URL: the only schemes a recipe may download from. Any host is allowed, an address or a single-label name included, so a fork can point a recipe at a server on its own network. */
7
+ declare const HttpUrlSchema: z.ZodURL;
8
+ /** A Wayback Machine timestamp, `YYYYMMDD` or `YYYYMMDDhhmmss`: the moment the snapshot is pinned to. */
9
+ declare const WaybackTimestampSchema: z.ZodString;
10
+ /**
11
+ * The Wayback Machine URL of a snapshot of `url` at `timestamp`: the page form a person follows. The raw bytes a recipe downloads come from the `id_` form, which `fetchDataset` derives from this one.
12
+ * @param timestamp - A Wayback timestamp.
13
+ * @param url - The original URL.
14
+ * @returns The snapshot URL.
15
+ */
16
+ declare function waybackUrl(timestamp: string, url: string): string;
17
+ /** A pinned Wayback Machine snapshot of a source. The timestamp is part of the recipe's reproducibility, not incidental metadata, so it travels with the URL and the two are checked against each other. */
18
+ declare const SnapshotSchema: z.ZodObject<{
19
+ url: z.ZodURL;
20
+ timestamp: z.ZodString;
21
+ }, z.core.$strict>;
22
+ type Snapshot = z.infer<typeof SnapshotSchema>;
23
+ /**
24
+ * Where a dataset's bytes come from. A `dead` source no longer serves the bytes the recipe was written against and must carry the snapshot the recipe fetches instead; a `live` source may also carry one, as the pinned record of what it served. The snapshot URL must be exactly `waybackUrl(timestamp, url)`.
25
+ */
26
+ declare const SourceSchema: z.ZodObject<{
27
+ url: z.ZodURL;
28
+ retrieved: z.ZodISODate;
29
+ status: z.ZodEnum<{
30
+ live: "live";
31
+ dead: "dead";
32
+ }>;
33
+ snapshot: z.ZodOptional<z.ZodObject<{
34
+ url: z.ZodURL;
35
+ timestamp: z.ZodString;
36
+ }, z.core.$strict>>;
37
+ }, z.core.$strict>;
38
+ type Source = z.infer<typeof SourceSchema>;
39
+ /** The licence a dataset is published under: an SPDX identifier, a named licence with the URL of its terms, or a statement that the source records none. A licence the source does not state is recorded as unrecorded rather than guessed. */
40
+ declare const LicenceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
41
+ kind: z.ZodLiteral<"spdx">;
42
+ id: z.ZodString;
43
+ }, z.core.$strict>, z.ZodObject<{
44
+ kind: z.ZodLiteral<"custom">;
45
+ name: z.ZodString;
46
+ url: z.ZodURL;
47
+ }, z.core.$strict>, z.ZodObject<{
48
+ kind: z.ZodLiteral<"unrecorded">;
49
+ }, z.core.$strict>], "kind">;
50
+ type Licence = z.infer<typeof LicenceSchema>;
51
+ /** A work to cite for the dataset: a formatted reference, with its DOI or URL where the source records one. */
52
+ declare const CitationSchema: z.ZodObject<{
53
+ text: z.ZodString;
54
+ doi: z.ZodOptional<z.ZodString>;
55
+ url: z.ZodOptional<z.ZodURL>;
56
+ }, z.core.$strict>;
57
+ type Citation = z.infer<typeof CitationSchema>;
58
+ /** A relative path inside an archive or a catalogue: `/`-separated segments, none empty, `.` or `..`, so it can never climb out of the directory it is resolved against. */
59
+ declare const RelativePathSchema: z.ZodString;
60
+ /** Which file of an archive to read: a member path, matched against a member's whole path or its trailing segments (so `net.gml` finds `net/net.gml`), or the member whose name ends with an extension. Either must match exactly one member when the recipe runs; macOS resource-fork members (`__MACOSX/` and `._` files) never match. */
61
+ declare const ArchiveMemberSchema: z.ZodUnion<readonly [z.ZodObject<{
62
+ path: z.ZodString;
63
+ }, z.core.$strict>, z.ZodObject<{
64
+ extension: z.ZodString;
65
+ }, z.core.$strict>]>;
66
+ type ArchiveMember = z.infer<typeof ArchiveMemberSchema>;
67
+ /** How the downloaded bytes unpack into the one file the parser reads. */
68
+ declare const ArchiveSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
69
+ kind: z.ZodLiteral<"none">;
70
+ }, z.core.$strict>, z.ZodObject<{
71
+ kind: z.ZodLiteral<"gzip">;
72
+ }, z.core.$strict>, z.ZodObject<{
73
+ kind: z.ZodLiteral<"zip">;
74
+ member: z.ZodUnion<readonly [z.ZodObject<{
75
+ path: z.ZodString;
76
+ }, z.core.$strict>, z.ZodObject<{
77
+ extension: z.ZodString;
78
+ }, z.core.$strict>]>;
79
+ }, z.core.$strict>, z.ZodObject<{
80
+ kind: z.ZodLiteral<"tar">;
81
+ member: z.ZodUnion<readonly [z.ZodObject<{
82
+ path: z.ZodString;
83
+ }, z.core.$strict>, z.ZodObject<{
84
+ extension: z.ZodString;
85
+ }, z.core.$strict>]>;
86
+ }, z.core.$strict>, z.ZodObject<{
87
+ kind: z.ZodLiteral<"tar.gz">;
88
+ member: z.ZodUnion<readonly [z.ZodObject<{
89
+ path: z.ZodString;
90
+ }, z.core.$strict>, z.ZodObject<{
91
+ extension: z.ZodString;
92
+ }, z.core.$strict>]>;
93
+ }, z.core.$strict>], "kind">;
94
+ type Archive = z.infer<typeof ArchiveSchema>;
95
+ /** The parser that reads the unpacked file into the dataset's native JSON shape, with the options that format needs. Every option is stated in the entry, so a recipe reads the same way wherever it runs. */
96
+ declare const ParserSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
97
+ format: z.ZodLiteral<"edge-list">;
98
+ encoding: z.ZodEnum<{
99
+ "utf-8": "utf-8";
100
+ latin1: "latin1";
101
+ }>;
102
+ delimiter: z.ZodEnum<{
103
+ detect: "detect";
104
+ whitespace: "whitespace";
105
+ tab: "tab";
106
+ comma: "comma";
107
+ space: "space";
108
+ }>;
109
+ skipLines: z.ZodInt;
110
+ commentPrefixes: z.ZodArray<z.ZodString>;
111
+ sourceColumn: z.ZodInt;
112
+ targetColumn: z.ZodInt;
113
+ }, z.core.$strict>, z.ZodObject<{
114
+ format: z.ZodLiteral<"matrix-market">;
115
+ encoding: z.ZodEnum<{
116
+ "utf-8": "utf-8";
117
+ latin1: "latin1";
118
+ }>;
119
+ }, z.core.$strict>, z.ZodObject<{
120
+ format: z.ZodLiteral<"gml">;
121
+ encoding: z.ZodEnum<{
122
+ "utf-8": "utf-8";
123
+ latin1: "latin1";
124
+ }>;
125
+ }, z.core.$strict>, z.ZodObject<{
126
+ format: z.ZodLiteral<"pajek">;
127
+ encoding: z.ZodEnum<{
128
+ "utf-8": "utf-8";
129
+ latin1: "latin1";
130
+ }>;
131
+ }, z.core.$strict>], "format">;
132
+ type Parser = z.infer<typeof ParserSchema>;
133
+ /** How to obtain the dataset: a fetchable recipe naming the source (by index into `sources`), the archive layout and the parser, or a statement that no declarative recipe exists yet and why. */
134
+ declare const RecipeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
135
+ status: z.ZodLiteral<"fetchable">;
136
+ source: z.ZodInt;
137
+ archive: z.ZodDiscriminatedUnion<[z.ZodObject<{
138
+ kind: z.ZodLiteral<"none">;
139
+ }, z.core.$strict>, z.ZodObject<{
140
+ kind: z.ZodLiteral<"gzip">;
141
+ }, z.core.$strict>, z.ZodObject<{
142
+ kind: z.ZodLiteral<"zip">;
143
+ member: z.ZodUnion<readonly [z.ZodObject<{
144
+ path: z.ZodString;
145
+ }, z.core.$strict>, z.ZodObject<{
146
+ extension: z.ZodString;
147
+ }, z.core.$strict>]>;
148
+ }, z.core.$strict>, z.ZodObject<{
149
+ kind: z.ZodLiteral<"tar">;
150
+ member: z.ZodUnion<readonly [z.ZodObject<{
151
+ path: z.ZodString;
152
+ }, z.core.$strict>, z.ZodObject<{
153
+ extension: z.ZodString;
154
+ }, z.core.$strict>]>;
155
+ }, z.core.$strict>, z.ZodObject<{
156
+ kind: z.ZodLiteral<"tar.gz">;
157
+ member: z.ZodUnion<readonly [z.ZodObject<{
158
+ path: z.ZodString;
159
+ }, z.core.$strict>, z.ZodObject<{
160
+ extension: z.ZodString;
161
+ }, z.core.$strict>]>;
162
+ }, z.core.$strict>], "kind">;
163
+ parser: z.ZodDiscriminatedUnion<[z.ZodObject<{
164
+ format: z.ZodLiteral<"edge-list">;
165
+ encoding: z.ZodEnum<{
166
+ "utf-8": "utf-8";
167
+ latin1: "latin1";
168
+ }>;
169
+ delimiter: z.ZodEnum<{
170
+ detect: "detect";
171
+ whitespace: "whitespace";
172
+ tab: "tab";
173
+ comma: "comma";
174
+ space: "space";
175
+ }>;
176
+ skipLines: z.ZodInt;
177
+ commentPrefixes: z.ZodArray<z.ZodString>;
178
+ sourceColumn: z.ZodInt;
179
+ targetColumn: z.ZodInt;
180
+ }, z.core.$strict>, z.ZodObject<{
181
+ format: z.ZodLiteral<"matrix-market">;
182
+ encoding: z.ZodEnum<{
183
+ "utf-8": "utf-8";
184
+ latin1: "latin1";
185
+ }>;
186
+ }, z.core.$strict>, z.ZodObject<{
187
+ format: z.ZodLiteral<"gml">;
188
+ encoding: z.ZodEnum<{
189
+ "utf-8": "utf-8";
190
+ latin1: "latin1";
191
+ }>;
192
+ }, z.core.$strict>, z.ZodObject<{
193
+ format: z.ZodLiteral<"pajek">;
194
+ encoding: z.ZodEnum<{
195
+ "utf-8": "utf-8";
196
+ latin1: "latin1";
197
+ }>;
198
+ }, z.core.$strict>], "format">;
199
+ }, z.core.$strict>, z.ZodObject<{
200
+ status: z.ZodLiteral<"not-fetchable">;
201
+ reason: z.ZodString;
202
+ }, z.core.$strict>], "status">;
203
+ type Recipe = z.infer<typeof RecipeSchema>;
204
+ /** The twindex crosswalk from the native shape to the category target: the document inline, or a `.json` file path relative to the catalogue root, so entries that share a native shape share one crosswalk. */
205
+ declare const CrosswalkReferenceSchema: z.ZodUnion<readonly [z.ZodType<import("twindex").Crosswalk, unknown, z.core.$ZodTypeInternals<import("twindex").Crosswalk, unknown>> & {
206
+ is: (value: unknown) => value is import("twindex").Crosswalk;
207
+ }, z.ZodObject<{
208
+ file: z.ZodString;
209
+ }, z.core.$strict>]>;
210
+ type CrosswalkReference = z.infer<typeof CrosswalkReferenceSchema>;
211
+ /** The meta keys a fetched result takes from the entry's own descriptor, which its `properties` therefore may not also set. */
212
+ declare const RESERVED_META_KEYS: readonly ["id", "name"];
213
+ /**
214
+ * One catalogue entry: the descriptor (id, name, description, domain, tags), the category whose target the entry resolves to, where the bytes come from, the licence and citations, the recipe, the crosswalk, the counts a fetched result is expected to have and the dataset's recorded properties. The kind of data is the category's (`kindOf(category)`), never a second field that could disagree with it.
215
+ */
216
+ declare const EntrySchema: z.ZodObject<{
217
+ id: z.ZodString;
218
+ name: z.ZodString;
219
+ description: z.ZodOptional<z.ZodString>;
220
+ domain: z.ZodOptional<z.ZodString>;
221
+ tags: z.ZodArray<z.ZodString>;
222
+ category: z.ZodEnum<{
223
+ "graph/v1": "graph/v1";
224
+ }>;
225
+ sources: z.ZodArray<z.ZodObject<{
226
+ url: z.ZodURL;
227
+ retrieved: z.ZodISODate;
228
+ status: z.ZodEnum<{
229
+ live: "live";
230
+ dead: "dead";
231
+ }>;
232
+ snapshot: z.ZodOptional<z.ZodObject<{
233
+ url: z.ZodURL;
234
+ timestamp: z.ZodString;
235
+ }, z.core.$strict>>;
236
+ }, z.core.$strict>>;
237
+ licence: z.ZodDiscriminatedUnion<[z.ZodObject<{
238
+ kind: z.ZodLiteral<"spdx">;
239
+ id: z.ZodString;
240
+ }, z.core.$strict>, z.ZodObject<{
241
+ kind: z.ZodLiteral<"custom">;
242
+ name: z.ZodString;
243
+ url: z.ZodURL;
244
+ }, z.core.$strict>, z.ZodObject<{
245
+ kind: z.ZodLiteral<"unrecorded">;
246
+ }, z.core.$strict>], "kind">;
247
+ citations: z.ZodArray<z.ZodObject<{
248
+ text: z.ZodString;
249
+ doi: z.ZodOptional<z.ZodString>;
250
+ url: z.ZodOptional<z.ZodURL>;
251
+ }, z.core.$strict>>;
252
+ recipe: z.ZodDiscriminatedUnion<[z.ZodObject<{
253
+ status: z.ZodLiteral<"fetchable">;
254
+ source: z.ZodInt;
255
+ archive: z.ZodDiscriminatedUnion<[z.ZodObject<{
256
+ kind: z.ZodLiteral<"none">;
257
+ }, z.core.$strict>, z.ZodObject<{
258
+ kind: z.ZodLiteral<"gzip">;
259
+ }, z.core.$strict>, z.ZodObject<{
260
+ kind: z.ZodLiteral<"zip">;
261
+ member: z.ZodUnion<readonly [z.ZodObject<{
262
+ path: z.ZodString;
263
+ }, z.core.$strict>, z.ZodObject<{
264
+ extension: z.ZodString;
265
+ }, z.core.$strict>]>;
266
+ }, z.core.$strict>, z.ZodObject<{
267
+ kind: z.ZodLiteral<"tar">;
268
+ member: z.ZodUnion<readonly [z.ZodObject<{
269
+ path: z.ZodString;
270
+ }, z.core.$strict>, z.ZodObject<{
271
+ extension: z.ZodString;
272
+ }, z.core.$strict>]>;
273
+ }, z.core.$strict>, z.ZodObject<{
274
+ kind: z.ZodLiteral<"tar.gz">;
275
+ member: z.ZodUnion<readonly [z.ZodObject<{
276
+ path: z.ZodString;
277
+ }, z.core.$strict>, z.ZodObject<{
278
+ extension: z.ZodString;
279
+ }, z.core.$strict>]>;
280
+ }, z.core.$strict>], "kind">;
281
+ parser: z.ZodDiscriminatedUnion<[z.ZodObject<{
282
+ format: z.ZodLiteral<"edge-list">;
283
+ encoding: z.ZodEnum<{
284
+ "utf-8": "utf-8";
285
+ latin1: "latin1";
286
+ }>;
287
+ delimiter: z.ZodEnum<{
288
+ detect: "detect";
289
+ whitespace: "whitespace";
290
+ tab: "tab";
291
+ comma: "comma";
292
+ space: "space";
293
+ }>;
294
+ skipLines: z.ZodInt;
295
+ commentPrefixes: z.ZodArray<z.ZodString>;
296
+ sourceColumn: z.ZodInt;
297
+ targetColumn: z.ZodInt;
298
+ }, z.core.$strict>, z.ZodObject<{
299
+ format: z.ZodLiteral<"matrix-market">;
300
+ encoding: z.ZodEnum<{
301
+ "utf-8": "utf-8";
302
+ latin1: "latin1";
303
+ }>;
304
+ }, z.core.$strict>, z.ZodObject<{
305
+ format: z.ZodLiteral<"gml">;
306
+ encoding: z.ZodEnum<{
307
+ "utf-8": "utf-8";
308
+ latin1: "latin1";
309
+ }>;
310
+ }, z.core.$strict>, z.ZodObject<{
311
+ format: z.ZodLiteral<"pajek">;
312
+ encoding: z.ZodEnum<{
313
+ "utf-8": "utf-8";
314
+ latin1: "latin1";
315
+ }>;
316
+ }, z.core.$strict>], "format">;
317
+ }, z.core.$strict>, z.ZodObject<{
318
+ status: z.ZodLiteral<"not-fetchable">;
319
+ reason: z.ZodString;
320
+ }, z.core.$strict>], "status">;
321
+ crosswalk: z.ZodUnion<readonly [z.ZodType<import("twindex").Crosswalk, unknown, z.core.$ZodTypeInternals<import("twindex").Crosswalk, unknown>> & {
322
+ is: (value: unknown) => value is import("twindex").Crosswalk;
323
+ }, z.ZodObject<{
324
+ file: z.ZodString;
325
+ }, z.core.$strict>]>;
326
+ expectedCounts: z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodInt>, unknown>;
327
+ properties: z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>, unknown>;
328
+ }, z.core.$strict> & {
329
+ is: (value: unknown) => value is {
330
+ id: string;
331
+ name: string;
332
+ tags: string[];
333
+ category: "graph/v1";
334
+ sources: {
335
+ url: string;
336
+ retrieved: string;
337
+ status: "live" | "dead";
338
+ snapshot?: {
339
+ url: string;
340
+ timestamp: string;
341
+ } | undefined;
342
+ }[];
343
+ licence: {
344
+ kind: "spdx";
345
+ id: string;
346
+ } | {
347
+ kind: "custom";
348
+ name: string;
349
+ url: string;
350
+ } | {
351
+ kind: "unrecorded";
352
+ };
353
+ citations: {
354
+ text: string;
355
+ doi?: string | undefined;
356
+ url?: string | undefined;
357
+ }[];
358
+ recipe: {
359
+ status: "fetchable";
360
+ source: number;
361
+ archive: {
362
+ kind: "none";
363
+ } | {
364
+ kind: "gzip";
365
+ } | {
366
+ kind: "zip";
367
+ member: {
368
+ path: string;
369
+ } | {
370
+ extension: string;
371
+ };
372
+ } | {
373
+ kind: "tar";
374
+ member: {
375
+ path: string;
376
+ } | {
377
+ extension: string;
378
+ };
379
+ } | {
380
+ kind: "tar.gz";
381
+ member: {
382
+ path: string;
383
+ } | {
384
+ extension: string;
385
+ };
386
+ };
387
+ parser: {
388
+ format: "edge-list";
389
+ encoding: "utf-8" | "latin1";
390
+ delimiter: "detect" | "whitespace" | "tab" | "comma" | "space";
391
+ skipLines: number;
392
+ commentPrefixes: string[];
393
+ sourceColumn: number;
394
+ targetColumn: number;
395
+ } | {
396
+ format: "matrix-market";
397
+ encoding: "utf-8" | "latin1";
398
+ } | {
399
+ format: "gml";
400
+ encoding: "utf-8" | "latin1";
401
+ } | {
402
+ format: "pajek";
403
+ encoding: "utf-8" | "latin1";
404
+ };
405
+ } | {
406
+ status: "not-fetchable";
407
+ reason: string;
408
+ };
409
+ crosswalk: import("twindex").Crosswalk | {
410
+ file: string;
411
+ };
412
+ expectedCounts: Record<string, number>;
413
+ properties: Record<string, string | number | boolean | null>;
414
+ description?: string | undefined;
415
+ domain?: string | undefined;
416
+ };
417
+ };
418
+ type Entry = z.infer<typeof EntrySchema>;
419
+ /**
420
+ * Parses an unknown value as a catalogue entry.
421
+ * @param doc - The candidate entry document.
422
+ * @returns The validated entry.
423
+ * @throws CatalogueSyntaxError carrying every issue found.
424
+ */
425
+ declare function parseEntry(doc: unknown): Entry;
426
+ //#endregion
427
+ //#region src/manifest.d.ts
428
+ /** A semantic version, `MAJOR.MINOR.PATCH` with optional pre-release and build parts (https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string). */
429
+ declare const SemVerSchema: z.ZodString;
430
+ /** Where a forked catalogue came from: the catalogue it was forked from, the version it forked at and the repository that holds it, which together are what lets a fork's entries be compared with, and brought back to, their origin. */
431
+ declare const LineageSchema: z.ZodObject<{
432
+ catalogue: z.ZodString;
433
+ version: z.ZodString;
434
+ repository: z.ZodURL;
435
+ }, z.core.$strict>;
436
+ type Lineage = z.infer<typeof LineageSchema>;
437
+ /**
438
+ * A catalogue manifest: the catalogue's own id and version, where it lives, and, for a fork, its lineage. A catalogue is a self-contained set of entry documents beside its manifest, and a fork is its own catalogue with its own id, so lineage may never name the catalogue itself.
439
+ */
440
+ declare const ManifestSchema: z.ZodObject<{
441
+ id: z.ZodString;
442
+ name: z.ZodString;
443
+ description: z.ZodString;
444
+ version: z.ZodString;
445
+ repository: z.ZodURL;
446
+ lineage: z.ZodOptional<z.ZodObject<{
447
+ catalogue: z.ZodString;
448
+ version: z.ZodString;
449
+ repository: z.ZodURL;
450
+ }, z.core.$strict>>;
451
+ }, z.core.$strict> & {
452
+ is: (value: unknown) => value is {
453
+ id: string;
454
+ name: string;
455
+ description: string;
456
+ version: string;
457
+ repository: string;
458
+ lineage?: {
459
+ catalogue: string;
460
+ version: string;
461
+ repository: string;
462
+ } | undefined;
463
+ };
464
+ };
465
+ type Manifest = z.infer<typeof ManifestSchema>;
466
+ /**
467
+ * Parses an unknown value as a catalogue manifest.
468
+ * @param doc - The candidate manifest document.
469
+ * @returns The validated manifest.
470
+ * @throws CatalogueSyntaxError carrying every issue found.
471
+ */
472
+ declare function parseManifest(doc: unknown): Manifest;
473
+ //#endregion
474
+ //#region src/catalogue.d.ts
475
+ /**
476
+ * A catalogue index: the manifest, every entry, and every crosswalk file of the catalogue, keyed by its catalogue-relative path. The build assembles it from a catalogue directory; a consumer holding its own catalogue (a fork, say) can pass one to `createCatalogue`. Entry ids are unique, every crosswalk passes twindex's structural validation, every crosswalk file reference resolves, and every crosswalk's target is the category of each entry that uses it.
477
+ */
478
+ declare const CatalogueIndexSchema: z.ZodObject<{
479
+ manifest: z.ZodObject<{
480
+ id: z.ZodString;
481
+ name: z.ZodString;
482
+ description: z.ZodString;
483
+ version: z.ZodString;
484
+ repository: z.ZodURL;
485
+ lineage: z.ZodOptional<z.ZodObject<{
486
+ catalogue: z.ZodString;
487
+ version: z.ZodString;
488
+ repository: z.ZodURL;
489
+ }, z.core.$strict>>;
490
+ }, z.core.$strict> & {
491
+ is: (value: unknown) => value is {
492
+ id: string;
493
+ name: string;
494
+ description: string;
495
+ version: string;
496
+ repository: string;
497
+ lineage?: {
498
+ catalogue: string;
499
+ version: string;
500
+ repository: string;
501
+ } | undefined;
502
+ };
503
+ };
504
+ crosswalks: z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodType<Crosswalk, unknown, z.core.$ZodTypeInternals<Crosswalk, unknown>> & {
505
+ is: (value: unknown) => value is Crosswalk;
506
+ }>, unknown>;
507
+ entries: z.ZodArray<z.ZodObject<{
508
+ id: z.ZodString;
509
+ name: z.ZodString;
510
+ description: z.ZodOptional<z.ZodString>;
511
+ domain: z.ZodOptional<z.ZodString>;
512
+ tags: z.ZodArray<z.ZodString>;
513
+ category: z.ZodEnum<{
514
+ "graph/v1": "graph/v1";
515
+ }>;
516
+ sources: z.ZodArray<z.ZodObject<{
517
+ url: z.ZodURL;
518
+ retrieved: z.ZodISODate;
519
+ status: z.ZodEnum<{
520
+ live: "live";
521
+ dead: "dead";
522
+ }>;
523
+ snapshot: z.ZodOptional<z.ZodObject<{
524
+ url: z.ZodURL;
525
+ timestamp: z.ZodString;
526
+ }, z.core.$strict>>;
527
+ }, z.core.$strict>>;
528
+ licence: z.ZodDiscriminatedUnion<[z.ZodObject<{
529
+ kind: z.ZodLiteral<"spdx">;
530
+ id: z.ZodString;
531
+ }, z.core.$strict>, z.ZodObject<{
532
+ kind: z.ZodLiteral<"custom">;
533
+ name: z.ZodString;
534
+ url: z.ZodURL;
535
+ }, z.core.$strict>, z.ZodObject<{
536
+ kind: z.ZodLiteral<"unrecorded">;
537
+ }, z.core.$strict>], "kind">;
538
+ citations: z.ZodArray<z.ZodObject<{
539
+ text: z.ZodString;
540
+ doi: z.ZodOptional<z.ZodString>;
541
+ url: z.ZodOptional<z.ZodURL>;
542
+ }, z.core.$strict>>;
543
+ recipe: z.ZodDiscriminatedUnion<[z.ZodObject<{
544
+ status: z.ZodLiteral<"fetchable">;
545
+ source: z.ZodInt;
546
+ archive: z.ZodDiscriminatedUnion<[z.ZodObject<{
547
+ kind: z.ZodLiteral<"none">;
548
+ }, z.core.$strict>, z.ZodObject<{
549
+ kind: z.ZodLiteral<"gzip">;
550
+ }, z.core.$strict>, z.ZodObject<{
551
+ kind: z.ZodLiteral<"zip">;
552
+ member: z.ZodUnion<readonly [z.ZodObject<{
553
+ path: z.ZodString;
554
+ }, z.core.$strict>, z.ZodObject<{
555
+ extension: z.ZodString;
556
+ }, z.core.$strict>]>;
557
+ }, z.core.$strict>, z.ZodObject<{
558
+ kind: z.ZodLiteral<"tar">;
559
+ member: z.ZodUnion<readonly [z.ZodObject<{
560
+ path: z.ZodString;
561
+ }, z.core.$strict>, z.ZodObject<{
562
+ extension: z.ZodString;
563
+ }, z.core.$strict>]>;
564
+ }, z.core.$strict>, z.ZodObject<{
565
+ kind: z.ZodLiteral<"tar.gz">;
566
+ member: z.ZodUnion<readonly [z.ZodObject<{
567
+ path: z.ZodString;
568
+ }, z.core.$strict>, z.ZodObject<{
569
+ extension: z.ZodString;
570
+ }, z.core.$strict>]>;
571
+ }, z.core.$strict>], "kind">;
572
+ parser: z.ZodDiscriminatedUnion<[z.ZodObject<{
573
+ format: z.ZodLiteral<"edge-list">;
574
+ encoding: z.ZodEnum<{
575
+ "utf-8": "utf-8";
576
+ latin1: "latin1";
577
+ }>;
578
+ delimiter: z.ZodEnum<{
579
+ detect: "detect";
580
+ whitespace: "whitespace";
581
+ tab: "tab";
582
+ comma: "comma";
583
+ space: "space";
584
+ }>;
585
+ skipLines: z.ZodInt;
586
+ commentPrefixes: z.ZodArray<z.ZodString>;
587
+ sourceColumn: z.ZodInt;
588
+ targetColumn: z.ZodInt;
589
+ }, z.core.$strict>, z.ZodObject<{
590
+ format: z.ZodLiteral<"matrix-market">;
591
+ encoding: z.ZodEnum<{
592
+ "utf-8": "utf-8";
593
+ latin1: "latin1";
594
+ }>;
595
+ }, z.core.$strict>, z.ZodObject<{
596
+ format: z.ZodLiteral<"gml">;
597
+ encoding: z.ZodEnum<{
598
+ "utf-8": "utf-8";
599
+ latin1: "latin1";
600
+ }>;
601
+ }, z.core.$strict>, z.ZodObject<{
602
+ format: z.ZodLiteral<"pajek">;
603
+ encoding: z.ZodEnum<{
604
+ "utf-8": "utf-8";
605
+ latin1: "latin1";
606
+ }>;
607
+ }, z.core.$strict>], "format">;
608
+ }, z.core.$strict>, z.ZodObject<{
609
+ status: z.ZodLiteral<"not-fetchable">;
610
+ reason: z.ZodString;
611
+ }, z.core.$strict>], "status">;
612
+ crosswalk: z.ZodUnion<readonly [z.ZodType<Crosswalk, unknown, z.core.$ZodTypeInternals<Crosswalk, unknown>> & {
613
+ is: (value: unknown) => value is Crosswalk;
614
+ }, z.ZodObject<{
615
+ file: z.ZodString;
616
+ }, z.core.$strict>]>;
617
+ expectedCounts: z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodInt>, unknown>;
618
+ properties: z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>, unknown>;
619
+ }, z.core.$strict> & {
620
+ is: (value: unknown) => value is {
621
+ id: string;
622
+ name: string;
623
+ tags: string[];
624
+ category: "graph/v1";
625
+ sources: {
626
+ url: string;
627
+ retrieved: string;
628
+ status: "live" | "dead";
629
+ snapshot?: {
630
+ url: string;
631
+ timestamp: string;
632
+ } | undefined;
633
+ }[];
634
+ licence: {
635
+ kind: "spdx";
636
+ id: string;
637
+ } | {
638
+ kind: "custom";
639
+ name: string;
640
+ url: string;
641
+ } | {
642
+ kind: "unrecorded";
643
+ };
644
+ citations: {
645
+ text: string;
646
+ doi?: string | undefined;
647
+ url?: string | undefined;
648
+ }[];
649
+ recipe: {
650
+ status: "fetchable";
651
+ source: number;
652
+ archive: {
653
+ kind: "none";
654
+ } | {
655
+ kind: "gzip";
656
+ } | {
657
+ kind: "zip";
658
+ member: {
659
+ path: string;
660
+ } | {
661
+ extension: string;
662
+ };
663
+ } | {
664
+ kind: "tar";
665
+ member: {
666
+ path: string;
667
+ } | {
668
+ extension: string;
669
+ };
670
+ } | {
671
+ kind: "tar.gz";
672
+ member: {
673
+ path: string;
674
+ } | {
675
+ extension: string;
676
+ };
677
+ };
678
+ parser: {
679
+ format: "edge-list";
680
+ encoding: "utf-8" | "latin1";
681
+ delimiter: "detect" | "whitespace" | "tab" | "comma" | "space";
682
+ skipLines: number;
683
+ commentPrefixes: string[];
684
+ sourceColumn: number;
685
+ targetColumn: number;
686
+ } | {
687
+ format: "matrix-market";
688
+ encoding: "utf-8" | "latin1";
689
+ } | {
690
+ format: "gml";
691
+ encoding: "utf-8" | "latin1";
692
+ } | {
693
+ format: "pajek";
694
+ encoding: "utf-8" | "latin1";
695
+ };
696
+ } | {
697
+ status: "not-fetchable";
698
+ reason: string;
699
+ };
700
+ crosswalk: Crosswalk | {
701
+ file: string;
702
+ };
703
+ expectedCounts: Record<string, number>;
704
+ properties: Record<string, string | number | boolean | null>;
705
+ description?: string | undefined;
706
+ domain?: string | undefined;
707
+ };
708
+ }>;
709
+ }, z.core.$strict> & {
710
+ is: (value: unknown) => value is {
711
+ manifest: {
712
+ id: string;
713
+ name: string;
714
+ description: string;
715
+ version: string;
716
+ repository: string;
717
+ lineage?: {
718
+ catalogue: string;
719
+ version: string;
720
+ repository: string;
721
+ } | undefined;
722
+ };
723
+ crosswalks: Record<string, Crosswalk>;
724
+ entries: {
725
+ id: string;
726
+ name: string;
727
+ tags: string[];
728
+ category: "graph/v1";
729
+ sources: {
730
+ url: string;
731
+ retrieved: string;
732
+ status: "live" | "dead";
733
+ snapshot?: {
734
+ url: string;
735
+ timestamp: string;
736
+ } | undefined;
737
+ }[];
738
+ licence: {
739
+ kind: "spdx";
740
+ id: string;
741
+ } | {
742
+ kind: "custom";
743
+ name: string;
744
+ url: string;
745
+ } | {
746
+ kind: "unrecorded";
747
+ };
748
+ citations: {
749
+ text: string;
750
+ doi?: string | undefined;
751
+ url?: string | undefined;
752
+ }[];
753
+ recipe: {
754
+ status: "fetchable";
755
+ source: number;
756
+ archive: {
757
+ kind: "none";
758
+ } | {
759
+ kind: "gzip";
760
+ } | {
761
+ kind: "zip";
762
+ member: {
763
+ path: string;
764
+ } | {
765
+ extension: string;
766
+ };
767
+ } | {
768
+ kind: "tar";
769
+ member: {
770
+ path: string;
771
+ } | {
772
+ extension: string;
773
+ };
774
+ } | {
775
+ kind: "tar.gz";
776
+ member: {
777
+ path: string;
778
+ } | {
779
+ extension: string;
780
+ };
781
+ };
782
+ parser: {
783
+ format: "edge-list";
784
+ encoding: "utf-8" | "latin1";
785
+ delimiter: "detect" | "whitespace" | "tab" | "comma" | "space";
786
+ skipLines: number;
787
+ commentPrefixes: string[];
788
+ sourceColumn: number;
789
+ targetColumn: number;
790
+ } | {
791
+ format: "matrix-market";
792
+ encoding: "utf-8" | "latin1";
793
+ } | {
794
+ format: "gml";
795
+ encoding: "utf-8" | "latin1";
796
+ } | {
797
+ format: "pajek";
798
+ encoding: "utf-8" | "latin1";
799
+ };
800
+ } | {
801
+ status: "not-fetchable";
802
+ reason: string;
803
+ };
804
+ crosswalk: Crosswalk | {
805
+ file: string;
806
+ };
807
+ expectedCounts: Record<string, number>;
808
+ properties: Record<string, string | number | boolean | null>;
809
+ description?: string | undefined;
810
+ domain?: string | undefined;
811
+ }[];
812
+ };
813
+ };
814
+ type CatalogueIndex = z.infer<typeof CatalogueIndexSchema>;
815
+ /** One dataset as the library returns it: the entry (descriptor, sources, licence, citations and recipe), the kind of data its category holds, its crosswalk resolved from a file reference where it has one, and the catalogue it came from. */
816
+ interface Dataset {
817
+ readonly entry: Entry;
818
+ readonly kind: string;
819
+ readonly crosswalk: Crosswalk;
820
+ readonly catalogue: Pick<Manifest, "id" | "version">;
821
+ }
822
+ /** Filters for `listDatasets`. Every filter given must match; none given lists everything. */
823
+ interface DatasetQuery {
824
+ /** The kind of data, such as `graph`: the part of the category id before the version. */
825
+ readonly kind?: string;
826
+ /** A category id, such as `graph/v1`. */
827
+ readonly category?: string;
828
+ /** The entry's domain, matched exactly. */
829
+ readonly domain?: string;
830
+ /** Text that must appear, ignoring case, in the entry's id, name, description, domain or one of its tags. */
831
+ readonly text?: string;
832
+ }
833
+ /** A queryable catalogue: the surface `listDatasets` and `getDataset` are bound to. */
834
+ interface Catalogue {
835
+ readonly manifest: Manifest;
836
+ /**
837
+ * Lists the datasets matching a query, in entry id order.
838
+ * @param query - The filters; all must match.
839
+ * @returns The matching datasets.
840
+ */
841
+ readonly listDatasets: (query?: DatasetQuery) => Dataset[];
842
+ /**
843
+ * Returns one dataset by entry id.
844
+ * @param id - The entry id; untrusted, so lookup never reaches inherited properties.
845
+ * @returns The dataset.
846
+ * @throws DatasetNotFoundError when no entry has that id.
847
+ */
848
+ readonly getDataset: (id: string) => Dataset;
849
+ }
850
+ /**
851
+ * Builds a queryable catalogue from an index. Pure and synchronous: no filesystem, no network, so it runs the same in a browser as in Node.
852
+ * @param index - A candidate catalogue index.
853
+ * @returns The catalogue.
854
+ * @throws CatalogueSyntaxError carrying every issue when the index is not a valid catalogue.
855
+ */
856
+ declare function createCatalogue(index: unknown): Catalogue;
857
+ //#endregion
858
+ //#region src/targets/graph-v1.d.ts
859
+ /** A JSON scalar: the only values graph/v1 metadata may hold, so `meta` stays a flat record any consumer can tabulate. `z.number()` already rejects NaN and the infinities, which JSON cannot carry. */
860
+ declare const JsonScalarSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>;
861
+ type JsonScalar = z.infer<typeof JsonScalarSchema>;
862
+ /** A node: an id, an optional type, and whatever else the dataset carries. The target fixes only what every graph consumer needs, so extra fields pass through untouched. */
863
+ declare const GraphNodeSchema: z.ZodObject<{
864
+ id: z.ZodString;
865
+ type: z.ZodOptional<z.ZodString>;
866
+ }, z.core.$loose>;
867
+ type GraphNode = z.infer<typeof GraphNodeSchema>;
868
+ /** An edge: source and target node ids, an optional type, and whatever else the dataset carries. Direction is the dataset's own: graph/v1 records it in `meta`, never by duplicating edges. */
869
+ declare const GraphEdgeSchema: z.ZodObject<{
870
+ source: z.ZodString;
871
+ target: z.ZodString;
872
+ type: z.ZodOptional<z.ZodString>;
873
+ }, z.core.$loose>;
874
+ type GraphEdge = z.infer<typeof GraphEdgeSchema>;
875
+ /**
876
+ * The graph/v1 normalisation target: `{ meta, nodes, edges }`, the shape the thesis pipeline's benchmark cache already uses. It describes the result `fetchDataset` resolves a graph entry to, not what a source file may contain. Beyond the field shapes it checks the two properties every consumer relies on: node ids are unique, and every edge endpoint names a node.
877
+ */
878
+ declare const GraphV1Schema: z.ZodObject<{
879
+ meta: z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>, unknown>;
880
+ nodes: z.ZodArray<z.ZodObject<{
881
+ id: z.ZodString;
882
+ type: z.ZodOptional<z.ZodString>;
883
+ }, z.core.$loose>>;
884
+ edges: z.ZodArray<z.ZodObject<{
885
+ source: z.ZodString;
886
+ target: z.ZodString;
887
+ type: z.ZodOptional<z.ZodString>;
888
+ }, z.core.$loose>>;
889
+ }, z.core.$strict> & {
890
+ is: (value: unknown) => value is {
891
+ meta: Record<string, string | number | boolean | null>;
892
+ nodes: {
893
+ [x: string]: unknown;
894
+ id: string;
895
+ type?: string | undefined;
896
+ }[];
897
+ edges: {
898
+ [x: string]: unknown;
899
+ source: string;
900
+ target: string;
901
+ type?: string | undefined;
902
+ }[];
903
+ };
904
+ };
905
+ type GraphV1 = z.infer<typeof GraphV1Schema>;
906
+ //#endregion
907
+ //#region src/categories.d.ts
908
+ /** Every category id the registry knows. A category id is `<kind>/v<version>`: the kind of data, and the version of its normalisation target, so a breaking change to a target is a new category rather than an edit to an old one. */
909
+ declare const CategoryIdSchema: z.ZodEnum<{
910
+ "graph/v1": "graph/v1";
911
+ }>;
912
+ type CategoryId = z.infer<typeof CategoryIdSchema>;
913
+ /** The normalisation target each category resolves to, keyed by category id. */
914
+ interface CategoryTargets {
915
+ readonly "graph/v1": GraphV1;
916
+ }
917
+ /** The normalised shape of any category: what `fetchDataset` can resolve to. */
918
+ type CategoryTarget = CategoryTargets[CategoryId];
919
+ /** The keys of a target whose values are arrays: the collections an entry's `expectedCounts` may name. */
920
+ type CountedKey<Target> = { readonly [Key in keyof Target]: Target[Key] extends readonly unknown[] ? Key : never; }[keyof Target] & string;
921
+ /** One category: its id, what it holds, the schema of its normalisation target, and which of the target's arrays an entry may record expected counts for. */
922
+ interface Category<Id extends CategoryId = CategoryId> {
923
+ readonly id: Id;
924
+ readonly description: string;
925
+ readonly target: z.ZodType<CategoryTargets[Id]>;
926
+ readonly counted: readonly CountedKey<CategoryTargets[Id]>[];
927
+ }
928
+ /**
929
+ * Looks up a category by id.
930
+ * @param id - Any string; category ids usually come from entry documents, so the argument is untrusted.
931
+ * @returns The category.
932
+ * @throws UnknownCategoryError when no category has that id.
933
+ */
934
+ declare function getCategory<Id extends CategoryId>(id: Id): Category<Id>;
935
+ declare function getCategory(id: string): Category;
936
+ /**
937
+ * Returns the schema of a category's normalisation target.
938
+ * @param id - Any string, as for `getCategory`.
939
+ * @returns The target schema.
940
+ * @throws UnknownCategoryError when no category has that id.
941
+ */
942
+ declare function getTarget<Id extends CategoryId>(id: Id): z.ZodType<CategoryTargets[Id]>;
943
+ declare function getTarget(id: string): z.ZodType<CategoryTarget>;
944
+ /**
945
+ * The kind of data a category holds: the part of its id before the version.
946
+ * @param id - A category id.
947
+ * @returns The kind, such as `graph`.
948
+ */
949
+ declare function kindOf(id: CategoryId): string;
950
+ /** @returns Every registered category, in id order. */
951
+ declare function listCategories(): readonly Category[];
952
+ /**
953
+ * Counts the collections an entry may record expected counts for, in a resolved target.
954
+ * @param id - The target's category.
955
+ * @param target - A resolved target of that category.
956
+ * @returns The length of each counted array, by key.
957
+ */
958
+ declare function countTarget(id: CategoryId, target: CategoryTarget): ReadonlyMap<string, number>;
959
+ //#endregion
960
+ export { SnapshotSchema as $, SemVerSchema as A, Entry as B, Dataset as C, LineageSchema as D, Lineage as E, ArchiveSchema as F, LicenceSchema as G, HttpUrlSchema as H, Citation as I, RESERVED_META_KEYS as J, Parser as K, CitationSchema as L, Archive as M, ArchiveMember as N, Manifest as O, ArchiveMemberSchema as P, Snapshot as Q, CrosswalkReference as R, CatalogueIndexSchema as S, createCatalogue as T, IdSchema as U, EntrySchema as V, Licence as W, RecipeSchema as X, Recipe as Y, RelativePathSchema as Z, GraphV1Schema as _, CategoryTargets as a, Catalogue as b, getCategory as c, listCategories as d, Source as et, GraphEdge as f, GraphV1 as g, GraphNodeSchema as h, CategoryTarget as i, waybackUrl as it, parseManifest as j, ManifestSchema as k, getTarget as l, GraphNode as m, CategoryId as n, WaybackTimestampSchema as nt, CountedKey as o, GraphEdgeSchema as p, ParserSchema as q, CategoryIdSchema as r, parseEntry as rt, countTarget as s, Category as t, SourceSchema as tt, kindOf as u, JsonScalar as v, DatasetQuery as w, CatalogueIndex as x, JsonScalarSchema as y, CrosswalkReferenceSchema as z };