keepset 0.28.0 → 0.29.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/README.md +2 -2
- package/dist/{bundled-C52vPmf3.js → bundled-4MeSniHX.js} +372 -465
- package/dist/{categories-C7q-yLo-.d.ts → categories-DM2a8Esp.d.ts} +56 -92
- package/dist/index.d.ts +2 -8
- package/dist/index.js +2 -2
- package/dist/node/fetch-dataset.d.ts +3 -3
- package/dist/node/fetch-dataset.js +57 -30
- package/dist-cli/keepset.mjs +8 -5
- package/package.json +1 -1
- package/schemas/entry.schema.json +1 -1
- package/schemas/manifest.schema.json +1 -1
|
@@ -4,6 +4,8 @@ import { z } from "zod";
|
|
|
4
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
5
|
declare const IdSchema: z.ZodString;
|
|
6
6
|
/** A key of an entry's `properties` or `expectedCounts` record: an identifier that starts with a letter, so it can never be `__proto__` or another name Object.prototype reacts to on assignment. */
|
|
7
|
+
/** A subject: the field of study a dataset is relevant to, as a lowercase slug of words joined by hyphens, such as `operations-research`. It is separate from the entry's domain (its topic), its tags (the node fields it carries) and its namespace (the source it comes from), and it is the value a search filters by. */
|
|
8
|
+
declare const SubjectSchema: z.ZodString;
|
|
7
9
|
/** An alias: an id, or a path of ids joined by `/` such as `foo/graphs/bar`. A bare id is a name inside the entry's own namespace; a path is a name of its own, in the group its leading segments name. The segment pattern repeats the one in `IdSchema` so that each part of a path is an id. */
|
|
8
10
|
declare const AliasSchema: z.ZodString;
|
|
9
11
|
/** The path a dataset sits under in a collection, outermost segment first, such as `["suitesparse", "gset"]`. Each segment is an id, so a segment can never contain the `/` that joins a namespace to a name. */
|
|
@@ -401,7 +403,7 @@ type CrosswalkReference = z.infer<typeof CrosswalkReferenceSchema>;
|
|
|
401
403
|
/** The meta keys a fetched result takes from the entry's own descriptor, which its `properties` therefore may not also set. */
|
|
402
404
|
declare const RESERVED_META_KEYS: readonly ["id", "name"];
|
|
403
405
|
/**
|
|
404
|
-
* One catalogue entry: the descriptor (id, optional namespace and aliases, 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.
|
|
406
|
+
* One catalogue entry: the descriptor (id, optional namespace and aliases, name, description, domain, subjects, 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.
|
|
405
407
|
*/
|
|
406
408
|
declare const EntrySchema: z.ZodObject<{
|
|
407
409
|
id: z.ZodString;
|
|
@@ -410,11 +412,11 @@ declare const EntrySchema: z.ZodObject<{
|
|
|
410
412
|
name: z.ZodString;
|
|
411
413
|
description: z.ZodOptional<z.ZodString>;
|
|
412
414
|
domain: z.ZodOptional<z.ZodString>;
|
|
415
|
+
subjects: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
413
416
|
tags: z.ZodArray<z.ZodString>;
|
|
414
417
|
category: z.ZodEnum<{
|
|
415
418
|
"graph/v1": "graph/v1";
|
|
416
419
|
"or/v1": "or/v1";
|
|
417
|
-
"or-set/v1": "or-set/v1";
|
|
418
420
|
}>;
|
|
419
421
|
sources: z.ZodArray<z.ZodObject<{
|
|
420
422
|
url: z.ZodURL;
|
|
@@ -610,7 +612,7 @@ declare const EntrySchema: z.ZodObject<{
|
|
|
610
612
|
id: string;
|
|
611
613
|
name: string;
|
|
612
614
|
tags: string[];
|
|
613
|
-
category: "graph/v1" | "or/v1"
|
|
615
|
+
category: "graph/v1" | "or/v1";
|
|
614
616
|
sources: {
|
|
615
617
|
url: string;
|
|
616
618
|
retrieved: string;
|
|
@@ -751,6 +753,7 @@ declare const EntrySchema: z.ZodObject<{
|
|
|
751
753
|
aliases?: string[] | undefined;
|
|
752
754
|
description?: string | undefined;
|
|
753
755
|
domain?: string | undefined;
|
|
756
|
+
subjects?: string[] | undefined;
|
|
754
757
|
};
|
|
755
758
|
};
|
|
756
759
|
type Entry = z.infer<typeof EntrySchema>;
|
|
@@ -853,11 +856,11 @@ declare const CatalogueIndexSchema: z.ZodObject<{
|
|
|
853
856
|
name: z.ZodString;
|
|
854
857
|
description: z.ZodOptional<z.ZodString>;
|
|
855
858
|
domain: z.ZodOptional<z.ZodString>;
|
|
859
|
+
subjects: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
856
860
|
tags: z.ZodArray<z.ZodString>;
|
|
857
861
|
category: z.ZodEnum<{
|
|
858
862
|
"graph/v1": "graph/v1";
|
|
859
863
|
"or/v1": "or/v1";
|
|
860
|
-
"or-set/v1": "or-set/v1";
|
|
861
864
|
}>;
|
|
862
865
|
sources: z.ZodArray<z.ZodObject<{
|
|
863
866
|
url: z.ZodURL;
|
|
@@ -1053,7 +1056,7 @@ declare const CatalogueIndexSchema: z.ZodObject<{
|
|
|
1053
1056
|
id: string;
|
|
1054
1057
|
name: string;
|
|
1055
1058
|
tags: string[];
|
|
1056
|
-
category: "graph/v1" | "or/v1"
|
|
1059
|
+
category: "graph/v1" | "or/v1";
|
|
1057
1060
|
sources: {
|
|
1058
1061
|
url: string;
|
|
1059
1062
|
retrieved: string;
|
|
@@ -1194,6 +1197,7 @@ declare const CatalogueIndexSchema: z.ZodObject<{
|
|
|
1194
1197
|
aliases?: string[] | undefined;
|
|
1195
1198
|
description?: string | undefined;
|
|
1196
1199
|
domain?: string | undefined;
|
|
1200
|
+
subjects?: string[] | undefined;
|
|
1197
1201
|
};
|
|
1198
1202
|
}>;
|
|
1199
1203
|
}, z.core.$strict> & {
|
|
@@ -1216,7 +1220,7 @@ declare const CatalogueIndexSchema: z.ZodObject<{
|
|
|
1216
1220
|
id: string;
|
|
1217
1221
|
name: string;
|
|
1218
1222
|
tags: string[];
|
|
1219
|
-
category: "graph/v1" | "or/v1"
|
|
1223
|
+
category: "graph/v1" | "or/v1";
|
|
1220
1224
|
sources: {
|
|
1221
1225
|
url: string;
|
|
1222
1226
|
retrieved: string;
|
|
@@ -1357,6 +1361,7 @@ declare const CatalogueIndexSchema: z.ZodObject<{
|
|
|
1357
1361
|
aliases?: string[] | undefined;
|
|
1358
1362
|
description?: string | undefined;
|
|
1359
1363
|
domain?: string | undefined;
|
|
1364
|
+
subjects?: string[] | undefined;
|
|
1360
1365
|
}[];
|
|
1361
1366
|
};
|
|
1362
1367
|
};
|
|
@@ -1376,9 +1381,11 @@ interface DatasetQuery {
|
|
|
1376
1381
|
readonly category?: string;
|
|
1377
1382
|
/** The entry's domain, matched exactly. */
|
|
1378
1383
|
readonly domain?: string;
|
|
1384
|
+
/** A subject slug such as `operations-research`, matched exactly against the entry's subjects. */
|
|
1385
|
+
readonly subject?: string;
|
|
1379
1386
|
/** A group path such as `suitesparse` or `suitesparse/gset`, in which any segment may be an alias the manifest gives it: matches the entries in that group, in any group beneath it, and the entries a path alias files there. */
|
|
1380
1387
|
readonly namespace?: string;
|
|
1381
|
-
/** Text that must appear, ignoring case, in the entry's id, an alias, one of its groups, name, description, domain or one of its tags. */
|
|
1388
|
+
/** Text that must appear, ignoring case, in the entry's id, an alias, one of its groups, name, description, domain, one of its subjects or one of its tags. */
|
|
1382
1389
|
readonly text?: string;
|
|
1383
1390
|
}
|
|
1384
1391
|
/** One namespace in the tree of groups: its path, its last segment, and how many distinct entries sit in it or in any namespace beneath it. */
|
|
@@ -1465,84 +1472,29 @@ declare const GraphV1Schema: z.ZodObject<{
|
|
|
1465
1472
|
};
|
|
1466
1473
|
type GraphV1 = z.infer<typeof GraphV1Schema>;
|
|
1467
1474
|
//#endregion
|
|
1468
|
-
//#region src/targets/
|
|
1469
|
-
/**
|
|
1470
|
-
declare const
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
skill: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1484
|
-
territory: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1485
|
-
status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1486
|
-
opened: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1487
|
-
closed: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1488
|
-
deadline: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
|
|
1489
|
-
}, z.core.$loose>>;
|
|
1490
|
-
}, z.core.$strict>;
|
|
1491
|
-
type OrInstance = z.infer<typeof OrInstanceSchema>;
|
|
1475
|
+
//#region src/targets/json-scalar.d.ts
|
|
1476
|
+
/** A JSON scalar: the only values a target's 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. */
|
|
1477
|
+
declare const JsonScalarSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>;
|
|
1478
|
+
type JsonScalar = z.infer<typeof JsonScalarSchema>;
|
|
1479
|
+
//#endregion
|
|
1480
|
+
//#region src/targets/collection.d.ts
|
|
1481
|
+
/** One member of a collection: the id that names it within the set (for a collection read from an archive, the path of the member it came from) beside the fields of the category's own document, which are the instance's `meta`, nodes and so on. */
|
|
1482
|
+
type Instance<Document extends object> = {
|
|
1483
|
+
readonly id: string;
|
|
1484
|
+
} & Document;
|
|
1485
|
+
/** A collection of documents of one category: `{ meta, instances }`, where `meta` is the entry's own metadata and each instance is a document of the category under an id. */
|
|
1486
|
+
interface Collection<Document extends object> {
|
|
1487
|
+
readonly meta: Readonly<Record<string, JsonScalar>>;
|
|
1488
|
+
readonly instances: readonly Instance<Document>[];
|
|
1489
|
+
}
|
|
1492
1490
|
/**
|
|
1493
|
-
* The
|
|
1491
|
+
* The schema of a collection of documents of a category, derived from the category's own document schema, so a category needs nothing of its own to be collected. Beyond each instance being a valid document, the instance ids must be unique in the set; node ids and the like stay unique only within an instance, because every instance numbers its own.
|
|
1492
|
+
* @param document - The category's document schema.
|
|
1493
|
+
* @returns The collection schema, with the attached type guard.
|
|
1494
1494
|
*/
|
|
1495
|
-
declare
|
|
1496
|
-
|
|
1497
|
-
instances: z.ZodArray<z.ZodObject<{
|
|
1498
|
-
id: z.ZodString;
|
|
1499
|
-
meta: z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>, unknown>;
|
|
1500
|
-
nodes: z.ZodArray<z.ZodObject<{
|
|
1501
|
-
id: z.ZodString;
|
|
1502
|
-
lat: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1503
|
-
lon: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1504
|
-
x: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1505
|
-
y: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1506
|
-
prize: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1507
|
-
prizeProbability: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1508
|
-
duration: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1509
|
-
travelTime: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1510
|
-
skill: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1511
|
-
territory: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1512
|
-
status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1513
|
-
opened: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1514
|
-
closed: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1515
|
-
deadline: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
|
|
1516
|
-
}, z.core.$loose>>;
|
|
1517
|
-
}, z.core.$strict>>;
|
|
1518
|
-
}, z.core.$strict> & {
|
|
1519
|
-
is: (value: unknown) => value is {
|
|
1520
|
-
meta: Record<string, string | number | boolean | null>;
|
|
1521
|
-
instances: {
|
|
1522
|
-
id: string;
|
|
1523
|
-
meta: Record<string, string | number | boolean | null>;
|
|
1524
|
-
nodes: {
|
|
1525
|
-
[x: string]: unknown;
|
|
1526
|
-
id: string;
|
|
1527
|
-
lat?: number | null | undefined;
|
|
1528
|
-
lon?: number | null | undefined;
|
|
1529
|
-
x?: number | null | undefined;
|
|
1530
|
-
y?: number | null | undefined;
|
|
1531
|
-
prize?: number | null | undefined;
|
|
1532
|
-
prizeProbability?: number | null | undefined;
|
|
1533
|
-
duration?: number | null | undefined;
|
|
1534
|
-
travelTime?: number | null | undefined;
|
|
1535
|
-
skill?: string | null | undefined;
|
|
1536
|
-
territory?: string | null | undefined;
|
|
1537
|
-
status?: string | null | undefined;
|
|
1538
|
-
opened?: string | null | undefined;
|
|
1539
|
-
closed?: string | null | undefined;
|
|
1540
|
-
deadline?: string | number | null | undefined;
|
|
1541
|
-
}[];
|
|
1542
|
-
}[];
|
|
1543
|
-
};
|
|
1495
|
+
declare function collectionOf<Document extends object>(document: z.ZodType<Document>): z.ZodType<Collection<Document>> & {
|
|
1496
|
+
is: (value: unknown) => value is Collection<Document>;
|
|
1544
1497
|
};
|
|
1545
|
-
type OrSetV1 = z.infer<typeof OrSetV1Schema>;
|
|
1546
1498
|
//#endregion
|
|
1547
1499
|
//#region src/targets/or-v1.d.ts
|
|
1548
1500
|
/**
|
|
@@ -1618,27 +1570,25 @@ type OrV1 = z.infer<typeof OrV1Schema>;
|
|
|
1618
1570
|
declare const CategoryIdSchema: z.ZodEnum<{
|
|
1619
1571
|
"graph/v1": "graph/v1";
|
|
1620
1572
|
"or/v1": "or/v1";
|
|
1621
|
-
"or-set/v1": "or-set/v1";
|
|
1622
1573
|
}>;
|
|
1623
1574
|
type CategoryId = z.infer<typeof CategoryIdSchema>;
|
|
1624
1575
|
/** The normalisation target each category resolves to, keyed by category id. */
|
|
1625
1576
|
interface CategoryTargets {
|
|
1626
1577
|
readonly "graph/v1": GraphV1;
|
|
1627
1578
|
readonly "or/v1": OrV1;
|
|
1628
|
-
readonly "or-set/v1": OrSetV1;
|
|
1629
1579
|
}
|
|
1630
1580
|
/** The normalised shape of any category: what `fetchDataset` can resolve to. */
|
|
1631
1581
|
type CategoryTarget = CategoryTargets[CategoryId];
|
|
1632
1582
|
/** The keys of a target whose values are arrays: the collections an entry's `expectedCounts` may name. */
|
|
1633
1583
|
type CountedKey<Target> = { readonly [Key in keyof Target]: Target[Key] extends readonly unknown[] ? Key : never; }[keyof Target] & string;
|
|
1634
|
-
/** What
|
|
1635
|
-
type
|
|
1636
|
-
/** One category: its id, what it holds,
|
|
1584
|
+
/** What a fetch of a collection entry resolves to: the entry's metadata and one instance per archive member, each a document of the entry's category. */
|
|
1585
|
+
type CollectionTarget<Id extends CategoryId = CategoryId> = Id extends CategoryId ? Collection<CategoryTargets[Id]> : never;
|
|
1586
|
+
/** One category: its id, what it holds, the schema of its normalisation target (one document), the schema of a collection of such documents derived from it, and which of the target's arrays an entry may record expected counts for. */
|
|
1637
1587
|
interface CategoryOf<Id extends CategoryId> {
|
|
1638
1588
|
readonly id: Id;
|
|
1639
1589
|
readonly description: string;
|
|
1640
|
-
readonly shape: CategoryShape;
|
|
1641
1590
|
readonly target: z.ZodType<CategoryTargets[Id]>;
|
|
1591
|
+
readonly collection: z.ZodType<Collection<CategoryTargets[Id]>>;
|
|
1642
1592
|
readonly counted: readonly CountedKey<CategoryTargets[Id]>[];
|
|
1643
1593
|
}
|
|
1644
1594
|
/** A category, or with no argument any of them: a union over the ids, so each category keeps its own target and counted keys. */
|
|
@@ -1659,6 +1609,13 @@ declare function getCategory(id: string): Category;
|
|
|
1659
1609
|
*/
|
|
1660
1610
|
declare function getTarget<Id extends CategoryId>(id: Id): z.ZodType<CategoryTargets[Id]>;
|
|
1661
1611
|
declare function getTarget(id: string): z.ZodType<CategoryTarget>;
|
|
1612
|
+
/**
|
|
1613
|
+
* Returns the schema of a collection of documents of a category: `{ meta, instances }`, each instance a document of the category under an id, derived from the category's own target schema.
|
|
1614
|
+
* @param id - Any string, as for `getCategory`.
|
|
1615
|
+
* @returns The collection schema.
|
|
1616
|
+
* @throws UnknownCategoryError when no category has that id.
|
|
1617
|
+
*/
|
|
1618
|
+
declare function getCollectionTarget(id: string): z.ZodType<CollectionTarget>;
|
|
1662
1619
|
/**
|
|
1663
1620
|
* The kind of data a category holds: the part of its id before the version.
|
|
1664
1621
|
* @param id - A category id.
|
|
@@ -1668,11 +1625,18 @@ declare function kindOf(id: CategoryId): string;
|
|
|
1668
1625
|
/** @returns Every registered category, in id order. */
|
|
1669
1626
|
declare function listCategories(): readonly Category[];
|
|
1670
1627
|
/**
|
|
1671
|
-
*
|
|
1628
|
+
* The keys of a resolved target an entry may record expected counts for: a document's own arrays, or for a collection its instances.
|
|
1629
|
+
* @param id - The target's category.
|
|
1630
|
+
* @param collection - Whether the entry's recipe reads a collection.
|
|
1631
|
+
* @returns The countable keys.
|
|
1632
|
+
*/
|
|
1633
|
+
declare function countedKeys(id: CategoryId, collection: boolean): readonly string[];
|
|
1634
|
+
/**
|
|
1635
|
+
* Counts the arrays an entry may record expected counts for, in a resolved target.
|
|
1672
1636
|
* @param id - The target's category.
|
|
1673
|
-
* @param target - A resolved
|
|
1637
|
+
* @param target - A resolved document of that category, or a collection of them.
|
|
1674
1638
|
* @returns The length of each counted array, by key.
|
|
1675
1639
|
*/
|
|
1676
|
-
declare function countTarget(id: CategoryId, target: CategoryTarget): ReadonlyMap<string, number>;
|
|
1640
|
+
declare function countTarget(id: CategoryId, target: CategoryTarget | CollectionTarget): ReadonlyMap<string, number>;
|
|
1677
1641
|
//#endregion
|
|
1678
|
-
export {
|
|
1642
|
+
export { CrosswalkReference as $, Catalogue as A, ManifestSchema as B, JsonScalarSchema as C, waybackUrl as Ct, GraphNodeSchema as D, GraphNode as E, NamespaceNode as F, ArchiveMember as G, parseManifest as H, createCatalogue as I, Citation as J, ArchiveMemberSchema as K, Lineage as L, CatalogueIndexSchema as M, Dataset as N, GraphV1 as O, DatasetQuery as P, ColumnNameSchema as Q, LineageSchema as R, JsonScalar as S, parseEntry as St, GraphEdgeSchema as T, AliasSchema as U, SemVerSchema as V, Archive as W, CollectionArchive as X, CitationSchema as Y, CollectionArchiveSchema as Z, OrV1 as _, SnapshotSchema as _t, CategoryTargets as a, IdSchema as at, Instance as b, SubjectSchema as bt, countTarget as c, Namespace as ct, getCollectionTarget as d, ParserSchema as dt, CrosswalkReferenceSchema as et, getTarget as f, RESERVED_META_KEYS as ft, OrNodeSchema as g, Snapshot as gt, OrNode as h, RelativePathSchema as ht, CategoryTarget as i, HttpUrlSchema as it, CatalogueIndex as j, GraphV1Schema as k, countedKeys as l, NamespaceSchema as lt, listCategories as m, RecipeSchema as mt, CategoryId as n, Entry as nt, CollectionTarget as o, Licence as ot, kindOf as p, Recipe as pt, ArchiveSchema as q, CategoryIdSchema as r, EntrySchema as rt, CountedKey as s, LicenceSchema as st, Category as t, DocumentArchive as tt, getCategory as u, Parser as ut, OrV1Schema as v, Source as vt, GraphEdge as w, collectionOf as x, WaybackTimestampSchema as xt, Collection as y, SourceSchema as yt, Manifest as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as CrosswalkReference, A as Catalogue, B as ManifestSchema, C as JsonScalarSchema, Ct as waybackUrl, D as GraphNodeSchema, E as GraphNode, F as NamespaceNode, G as ArchiveMember, H as parseManifest, I as createCatalogue, J as Citation, K as ArchiveMemberSchema, L as Lineage, M as CatalogueIndexSchema, N as Dataset, O as GraphV1, P as DatasetQuery, Q as ColumnNameSchema, R as LineageSchema, S as JsonScalar, St as parseEntry, T as GraphEdgeSchema, U as AliasSchema, V as SemVerSchema, W as Archive, X as CollectionArchive, Y as CitationSchema, Z as CollectionArchiveSchema, _ as OrV1, _t as SnapshotSchema, a as CategoryTargets, at as IdSchema, b as Instance, bt as SubjectSchema, c as countTarget, ct as Namespace, d as getCollectionTarget, dt as ParserSchema, et as CrosswalkReferenceSchema, f as getTarget, ft as RESERVED_META_KEYS, g as OrNodeSchema, gt as Snapshot, h as OrNode, ht as RelativePathSchema, i as CategoryTarget, it as HttpUrlSchema, j as CatalogueIndex, k as GraphV1Schema, l as countedKeys, lt as NamespaceSchema, m as listCategories, mt as RecipeSchema, n as CategoryId, nt as Entry, o as CollectionTarget, ot as Licence, p as kindOf, pt as Recipe, q as ArchiveSchema, r as CategoryIdSchema, rt as EntrySchema, s as CountedKey, st as LicenceSchema, t as Category, tt as DocumentArchive, u as getCategory, ut as Parser, v as OrV1Schema, vt as Source, w as GraphEdge, x as collectionOf, xt as WaybackTimestampSchema, y as Collection, yt as SourceSchema, z as Manifest } from "./categories-DM2a8Esp.js";
|
|
2
2
|
import { Crosswalk } from "twindex";
|
|
3
|
-
import { z } from "zod";
|
|
4
3
|
//#region src/errors.d.ts
|
|
5
4
|
/** The root of this package's error taxonomy: every error keepset throws is a `KeepsetError`, so callers can catch the family with one check. */
|
|
6
5
|
export declare class KeepsetError extends Error {
|
|
@@ -110,11 +109,6 @@ export declare function namesOf(entry: Addressed, segmentAliases?: SegmentAliase
|
|
|
110
109
|
*/
|
|
111
110
|
export declare function serialise(doc: Entry | Manifest | Crosswalk): string;
|
|
112
111
|
//#endregion
|
|
113
|
-
//#region src/targets/json-scalar.d.ts
|
|
114
|
-
/** A JSON scalar: the only values a target's 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. */
|
|
115
|
-
export declare const JsonScalarSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>;
|
|
116
|
-
type JsonScalar = z.infer<typeof JsonScalarSchema>;
|
|
117
|
-
//#endregion
|
|
118
112
|
//#region src/validate.d.ts
|
|
119
113
|
/**
|
|
120
114
|
* Checks a dataset as the catalogue holds it: the entry against the entry schema, and its crosswalk against twindex's structural validation and the entry's category. A catalogue index is checked the same way when it is built, so a bundled dataset is valid unless the package itself is broken; the check is what a contributor runs on an entry they are writing.
|
|
@@ -123,4 +117,4 @@ type JsonScalar = z.infer<typeof JsonScalarSchema>;
|
|
|
123
117
|
*/
|
|
124
118
|
export declare function validateDataset(dataset: Dataset): SyntaxIssue[];
|
|
125
119
|
//#endregion
|
|
126
|
-
export { AliasSchema, type Archive, type ArchiveMember, ArchiveMemberSchema, ArchiveSchema, type Catalogue, type CatalogueIndex, CatalogueIndexSchema, type Category, type CategoryId, CategoryIdSchema, type
|
|
120
|
+
export { AliasSchema, type Archive, type ArchiveMember, ArchiveMemberSchema, ArchiveSchema, type Catalogue, type CatalogueIndex, CatalogueIndexSchema, type Category, type CategoryId, CategoryIdSchema, type CategoryTarget, type CategoryTargets, type Citation, CitationSchema, type Collection, type CollectionArchive, CollectionArchiveSchema, type CollectionTarget, ColumnNameSchema, type CountedKey, type CrosswalkReference, CrosswalkReferenceSchema, type Dataset, type DatasetQuery, type DocumentArchive, type Entry, type EntryNames, EntrySchema, type GraphEdge, GraphEdgeSchema, type GraphNode, GraphNodeSchema, type GraphV1, GraphV1Schema, HttpUrlSchema, IdSchema, type Instance, type JsonScalar, JsonScalarSchema, type Licence, LicenceSchema, type Lineage, LineageSchema, type Manifest, ManifestSchema, type Namespace, type NamespaceNode, NamespaceSchema, type OrNode, OrNodeSchema, type OrV1, OrV1Schema, type Parser, ParserSchema, RESERVED_META_KEYS, type Recipe, RecipeSchema, type RecipeStep, RelativePathSchema, type SegmentAliases, SemVerSchema, type Snapshot, SnapshotSchema, type Source, SourceSchema, SubjectSchema, type SyntaxIssue, WaybackTimestampSchema, collectionOf, countTarget, countedKeys, createCatalogue, getCategory, getCollectionTarget, getTarget, kindOf, listCategories, parseEntry, parseManifest, waybackUrl };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as ArchiveError, A as WaybackTimestampSchema, B as countedKeys, C as ParserSchema, D as SnapshotSchema, E as RelativePathSchema, F as groupsOf, G as listCategories, H as getCollectionTarget, I as namesOf, J as collectionOf, K as OrNodeSchema, M as toIssues, N as waybackUrl, O as SourceSchema, P as NAME_SEPARATOR, Q as JsonScalarSchema, R as CategoryIdSchema, S as NamespaceSchema, T as RecipeSchema, U as getTarget, V as getCategory, W as kindOf, X as GraphNodeSchema, Y as GraphEdgeSchema, Z as GraphV1Schema, _ as CrosswalkReferenceSchema, a as CatalogueIndexSchema, at as RecipeError, b as IdSchema, c as ManifestSchema, d as AliasSchema, et as CatalogueSyntaxError, f as ArchiveMemberSchema, g as ColumnNameSchema, h as CollectionArchiveSchema, i as listNamespaces, it as NativeParseError, j as parseEntry, k as SubjectSchema, l as SemVerSchema, m as CitationSchema, n as getManifest, nt as DatasetNotFoundError, o as createCatalogue, ot as UnknownCategoryError, p as ArchiveSchema, q as OrV1Schema, r as listDatasets, rt as KeepsetError, s as LineageSchema, t as getDataset, tt as DatasetAmbiguousError, u as parseManifest, v as EntrySchema, w as RESERVED_META_KEYS, x as LicenceSchema, y as HttpUrlSchema, z as countTarget } from "./bundled-4MeSniHX.js";
|
|
2
2
|
import { validateCrosswalk } from "twindex";
|
|
3
3
|
//#region src/serialise.ts
|
|
4
4
|
/**
|
|
@@ -57,4 +57,4 @@ function validateDataset(dataset) {
|
|
|
57
57
|
return issues;
|
|
58
58
|
}
|
|
59
59
|
//#endregion
|
|
60
|
-
export { AliasSchema, ArchiveError, ArchiveMemberSchema, ArchiveSchema, CatalogueIndexSchema, CatalogueSyntaxError, CategoryIdSchema, CitationSchema, CollectionArchiveSchema, ColumnNameSchema, CrosswalkReferenceSchema, DatasetAmbiguousError, DatasetNotFoundError, EntrySchema, GraphEdgeSchema, GraphNodeSchema, GraphV1Schema, HttpUrlSchema, IdSchema, JsonScalarSchema, KeepsetError, LicenceSchema, LineageSchema, ManifestSchema, NAME_SEPARATOR, NamespaceSchema, NativeParseError,
|
|
60
|
+
export { AliasSchema, ArchiveError, ArchiveMemberSchema, ArchiveSchema, CatalogueIndexSchema, CatalogueSyntaxError, CategoryIdSchema, CitationSchema, CollectionArchiveSchema, ColumnNameSchema, CrosswalkReferenceSchema, DatasetAmbiguousError, DatasetNotFoundError, EntrySchema, GraphEdgeSchema, GraphNodeSchema, GraphV1Schema, HttpUrlSchema, IdSchema, JsonScalarSchema, KeepsetError, LicenceSchema, LineageSchema, ManifestSchema, NAME_SEPARATOR, NamespaceSchema, NativeParseError, OrNodeSchema, OrV1Schema, ParserSchema, RESERVED_META_KEYS, RecipeError, RecipeSchema, RelativePathSchema, SemVerSchema, SnapshotSchema, SourceSchema, SubjectSchema, UnknownCategoryError, WaybackTimestampSchema, collectionOf, countTarget, countedKeys, createCatalogue, getCategory, getCollectionTarget, getDataset, getManifest, getTarget, groupsOf, kindOf, listCategories, listDatasets, listNamespaces, namesOf, parseEntry, parseManifest, serialise, validateDataset, waybackUrl };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { N as Dataset, gt as Snapshot, i as CategoryTarget, nt as Entry, o as CollectionTarget, vt as Source } from "../categories-DM2a8Esp.js";
|
|
2
2
|
//#region src/node/fetch-dataset.d.ts
|
|
3
3
|
/** The network port a recipe downloads through: `downloadRaw` by default, which returns the bytes exactly as served, or a stand-in under test. */
|
|
4
4
|
export type FetchPort = (url: string, init: {
|
|
@@ -29,10 +29,10 @@ export interface Provenance {
|
|
|
29
29
|
/** The archive members a collection was read from, in the order they were read. */
|
|
30
30
|
readonly members?: readonly string[];
|
|
31
31
|
}
|
|
32
|
-
/** A fetched dataset: the resolved category target, the provenance of the bytes it came from, and any warnings, such as a count that differs from the one the entry records. */
|
|
32
|
+
/** A fetched dataset: the resolved category target (one document, or for a recipe that selects archive members a collection of them), the provenance of the bytes it came from, and any warnings, such as a count that differs from the one the entry records. */
|
|
33
33
|
export interface FetchedDataset {
|
|
34
34
|
readonly dataset: Dataset;
|
|
35
|
-
readonly data: CategoryTarget;
|
|
35
|
+
readonly data: CategoryTarget | CollectionTarget;
|
|
36
36
|
readonly provenance: Provenance;
|
|
37
37
|
readonly warnings: readonly string[];
|
|
38
38
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as ArchiveError, H as getCollectionTarget, L as getOwn, U as getTarget, at as RecipeError, it as NativeParseError, rt as KeepsetError, t as getDataset, z as countTarget } from "../bundled-4MeSniHX.js";
|
|
2
2
|
import { RoundTripMismatchError, assertRoundTrip, encode } from "twindex";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
@@ -2858,10 +2858,22 @@ function metaOf(entry) {
|
|
|
2858
2858
|
};
|
|
2859
2859
|
}
|
|
2860
2860
|
/**
|
|
2861
|
-
*
|
|
2861
|
+
* Puts an instance's id beside the fields of its encoded document. A document that is not an object is left as it is, for the collection schema to refuse.
|
|
2862
|
+
* @param document - The crosswalk's output for one member.
|
|
2863
|
+
* @param id - The member's path.
|
|
2864
|
+
* @returns The instance.
|
|
2865
|
+
*/
|
|
2866
|
+
function withId(document, id) {
|
|
2867
|
+
return typeof document === "object" && document !== null && !Array.isArray(document) ? {
|
|
2868
|
+
...document,
|
|
2869
|
+
id
|
|
2870
|
+
} : document;
|
|
2871
|
+
}
|
|
2872
|
+
/**
|
|
2873
|
+
* Runs a recipe's download, extract and parse steps, and builds the native documents the crosswalk receives.
|
|
2862
2874
|
* @param dataset - The dataset.
|
|
2863
2875
|
* @param options - The network port, abort signal and clock.
|
|
2864
|
-
* @returns The native
|
|
2876
|
+
* @returns The native documents and the provenance of their bytes.
|
|
2865
2877
|
*/
|
|
2866
2878
|
async function runToNative(dataset, options) {
|
|
2867
2879
|
const { entry } = dataset;
|
|
@@ -2896,35 +2908,39 @@ async function runToNative(dataset, options) {
|
|
|
2896
2908
|
const { archive } = recipe;
|
|
2897
2909
|
if ("members" in archive) {
|
|
2898
2910
|
const files = await step(entry.id, "extract", () => unpackMembers(bytes, archive));
|
|
2899
|
-
const members = await step(entry.id, "parse", () => files.map((file) => {
|
|
2900
|
-
try {
|
|
2901
|
-
return {
|
|
2902
|
-
id: file.path,
|
|
2903
|
-
meta: {},
|
|
2904
|
-
...parseNative(file.bytes, recipe.parser)
|
|
2905
|
-
};
|
|
2906
|
-
} catch (error) {
|
|
2907
|
-
throw new KeepsetError(`member ${file.path}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
2908
|
-
}
|
|
2909
|
-
}));
|
|
2910
2911
|
return {
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2912
|
+
collection: true,
|
|
2913
|
+
documents: await step(entry.id, "parse", () => files.map((file) => {
|
|
2914
|
+
try {
|
|
2915
|
+
const parsed = parseNative(file.bytes, recipe.parser);
|
|
2916
|
+
return {
|
|
2917
|
+
id: file.path,
|
|
2918
|
+
native: {
|
|
2919
|
+
...parsed,
|
|
2920
|
+
meta: "meta" in parsed ? parsed.meta : {}
|
|
2921
|
+
}
|
|
2922
|
+
};
|
|
2923
|
+
} catch (error) {
|
|
2924
|
+
throw new KeepsetError(`member ${file.path}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
2925
|
+
}
|
|
2926
|
+
})),
|
|
2915
2927
|
provenance: provenanceOf({ members: files.map((file) => file.path) })
|
|
2916
2928
|
};
|
|
2917
2929
|
}
|
|
2918
2930
|
const unpacked = await step(entry.id, "extract", () => unpack(bytes, archive));
|
|
2919
2931
|
const parsed = await step(entry.id, "parse", () => parseNative(unpacked.bytes, recipe.parser));
|
|
2920
2932
|
return {
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
...
|
|
2933
|
+
collection: false,
|
|
2934
|
+
documents: [{
|
|
2935
|
+
id: void 0,
|
|
2936
|
+
native: {
|
|
2937
|
+
...parsed,
|
|
2938
|
+
meta: {
|
|
2939
|
+
..."meta" in parsed ? parsed.meta : {},
|
|
2940
|
+
...metaOf(entry)
|
|
2941
|
+
}
|
|
2926
2942
|
}
|
|
2927
|
-
},
|
|
2943
|
+
}],
|
|
2928
2944
|
provenance: provenanceOf(unpacked.member === void 0 ? {} : { member: unpacked.member })
|
|
2929
2945
|
};
|
|
2930
2946
|
}
|
|
@@ -2937,11 +2953,22 @@ async function runToNative(dataset, options) {
|
|
|
2937
2953
|
*/
|
|
2938
2954
|
async function fetchEntry(dataset, options = {}) {
|
|
2939
2955
|
const { entry, crosswalk } = dataset;
|
|
2940
|
-
const {
|
|
2941
|
-
const encoded = await step(entry.id, "crosswalk", () =>
|
|
2956
|
+
const { collection, documents, provenance } = await runToNative(dataset, options);
|
|
2957
|
+
const encoded = await step(entry.id, "crosswalk", () => documents.map(({ id, native }) => {
|
|
2958
|
+
try {
|
|
2959
|
+
return encode(crosswalk, native);
|
|
2960
|
+
} catch (error) {
|
|
2961
|
+
throw new KeepsetError(`${id === void 0 ? "" : `member ${id}: `}${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
2962
|
+
}
|
|
2963
|
+
}));
|
|
2942
2964
|
const data = await step(entry.id, "validate", () => {
|
|
2943
|
-
const
|
|
2944
|
-
|
|
2965
|
+
const [only] = encoded;
|
|
2966
|
+
const whole = collection ? {
|
|
2967
|
+
meta: metaOf(entry),
|
|
2968
|
+
instances: encoded.map((document, index) => withId(document, documents[index]?.id))
|
|
2969
|
+
} : only;
|
|
2970
|
+
const result = (collection ? getCollectionTarget(entry.category) : getTarget(entry.category)).safeParse(whole);
|
|
2971
|
+
if (!result.success) throw new KeepsetError(`the result is not ${collection ? "a collection of " : ""}${entry.category}: ${result.error.issues.map((issue) => `${issue.path.map(String).join(".") || "(root)"}: ${issue.message}`).join("; ")}`);
|
|
2945
2972
|
return result.data;
|
|
2946
2973
|
});
|
|
2947
2974
|
const counts = countTarget(entry.category, data);
|
|
@@ -2970,9 +2997,9 @@ async function fetchDataset(id, options = {}) {
|
|
|
2970
2997
|
* @throws RecipeError naming the entry and the failing step when the recipe fails before the comparison, or when the crosswalk cannot run.
|
|
2971
2998
|
*/
|
|
2972
2999
|
async function roundTripEntry(dataset, options = {}) {
|
|
2973
|
-
const {
|
|
3000
|
+
const { documents, provenance } = await runToNative(dataset, options);
|
|
2974
3001
|
try {
|
|
2975
|
-
assertRoundTrip(dataset.crosswalk,
|
|
3002
|
+
assertRoundTrip(dataset.crosswalk, documents.map(({ native }) => native));
|
|
2976
3003
|
} catch (error) {
|
|
2977
3004
|
if (error instanceof RoundTripMismatchError) return {
|
|
2978
3005
|
holds: false,
|
package/dist-cli/keepset.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { KeepsetError, NAME_SEPARATOR, countTarget, getDataset, listDatasets, li
|
|
|
4
4
|
import { fetchDataset, roundTripDataset } from "keepset/node";
|
|
5
5
|
import { parseArgs } from "node:util";
|
|
6
6
|
//#region package.json
|
|
7
|
-
var version = "0.
|
|
7
|
+
var version = "0.29.0";
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region cli/run.ts
|
|
10
10
|
/**
|
|
@@ -19,11 +19,11 @@ function selectorText(selector) {
|
|
|
19
19
|
const usage = `Usage: keepset <command> [options]
|
|
20
20
|
|
|
21
21
|
Commands:
|
|
22
|
-
search [text] [--kind <kind>] [--domain <domain>] [--
|
|
23
|
-
[--category <id>] [--json]
|
|
22
|
+
search [text] [--kind <kind>] [--domain <domain>] [--subject <subject>]
|
|
23
|
+
[--namespace <path>] [--category <id>] [--json]
|
|
24
24
|
list the datasets whose id, alias, namespace, name,
|
|
25
|
-
description, domain or tags contain the text,
|
|
26
|
-
kind, domain, namespace (and every namespace beneath it,
|
|
25
|
+
description, domain, subjects or tags contain the text,
|
|
26
|
+
filtered by kind, domain, subject, namespace (and every namespace beneath it,
|
|
27
27
|
segment aliases allowed) or category
|
|
28
28
|
namespaces [path] [--json]
|
|
29
29
|
list the namespaces directly beneath a path, or the
|
|
@@ -61,6 +61,7 @@ function parseCommandLine(args) {
|
|
|
61
61
|
options: {
|
|
62
62
|
kind: { type: "string" },
|
|
63
63
|
domain: { type: "string" },
|
|
64
|
+
subject: { type: "string" },
|
|
64
65
|
namespace: { type: "string" },
|
|
65
66
|
category: { type: "string" },
|
|
66
67
|
json: { type: "boolean" },
|
|
@@ -112,6 +113,7 @@ function formatShow(dataset) {
|
|
|
112
113
|
lines.push("", `category: ${entry.category} (kind ${dataset.kind})`, `catalogue: ${dataset.catalogue.id} ${dataset.catalogue.version}`);
|
|
113
114
|
if (entry.namespace !== void 0) lines.push(`namespace: ${entry.namespace.join(NAME_SEPARATOR)}`);
|
|
114
115
|
if (entry.aliases !== void 0) lines.push(`aliases: ${entry.aliases.join(", ")}`);
|
|
116
|
+
if (entry.subjects !== void 0) lines.push(`subjects: ${entry.subjects.join(", ")}`);
|
|
115
117
|
if (entry.domain !== void 0) lines.push(`domain: ${entry.domain}`);
|
|
116
118
|
if (entry.tags.length > 0) lines.push(`tags: ${entry.tags.join(", ")}`);
|
|
117
119
|
const { licence } = entry;
|
|
@@ -198,6 +200,7 @@ async function run(args, library, io) {
|
|
|
198
200
|
...text === void 0 ? {} : { text },
|
|
199
201
|
...values.kind === void 0 ? {} : { kind: values.kind },
|
|
200
202
|
...values.domain === void 0 ? {} : { domain: values.domain },
|
|
203
|
+
...values.subject === void 0 ? {} : { subject: values.subject },
|
|
201
204
|
...values.namespace === void 0 ? {} : { namespace: values.namespace },
|
|
202
205
|
...values.category === void 0 ? {} : { category: values.category }
|
|
203
206
|
};
|