keepset 0.10.0 → 0.12.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.
@@ -3,6 +3,12 @@ import { z } from "zod";
3
3
  //#region src/entry.d.ts
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
+ /** 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
+ /** 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
+ declare const AliasSchema: z.ZodString;
9
+ /** 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. */
10
+ declare const NamespaceSchema: z.ZodArray<z.ZodString>;
11
+ type Namespace = z.infer<typeof NamespaceSchema>;
6
12
  /** 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
13
  declare const HttpUrlSchema: z.ZodURL;
8
14
  /** A Wayback Machine timestamp, `YYYYMMDD` or `YYYYMMDDhhmmss`: the moment the snapshot is pinned to. */
@@ -211,10 +217,12 @@ type CrosswalkReference = z.infer<typeof CrosswalkReferenceSchema>;
211
217
  /** The meta keys a fetched result takes from the entry's own descriptor, which its `properties` therefore may not also set. */
212
218
  declare const RESERVED_META_KEYS: readonly ["id", "name"];
213
219
  /**
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.
220
+ * 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.
215
221
  */
216
222
  declare const EntrySchema: z.ZodObject<{
217
223
  id: z.ZodString;
224
+ namespace: z.ZodOptional<z.ZodArray<z.ZodString>>;
225
+ aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
218
226
  name: z.ZodString;
219
227
  description: z.ZodOptional<z.ZodString>;
220
228
  domain: z.ZodOptional<z.ZodString>;
@@ -411,6 +419,8 @@ declare const EntrySchema: z.ZodObject<{
411
419
  };
412
420
  expectedCounts: Record<string, number>;
413
421
  properties: Record<string, string | number | boolean | null>;
422
+ namespace?: string[] | undefined;
423
+ aliases?: string[] | undefined;
414
424
  description?: string | undefined;
415
425
  domain?: string | undefined;
416
426
  };
@@ -435,7 +445,7 @@ declare const LineageSchema: z.ZodObject<{
435
445
  }, z.core.$strict>;
436
446
  type Lineage = z.infer<typeof LineageSchema>;
437
447
  /**
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.
448
+ * A catalogue manifest: the catalogue's own id and version, where it lives, the other names its namespace segments go by, 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. A segment alias is a name for a whole segment wherever it appears in a namespace, so it may not repeat, name itself, or be the segment of another alias.
439
449
  */
440
450
  declare const ManifestSchema: z.ZodObject<{
441
451
  id: z.ZodString;
@@ -448,6 +458,7 @@ declare const ManifestSchema: z.ZodObject<{
448
458
  version: z.ZodString;
449
459
  repository: z.ZodURL;
450
460
  }, z.core.$strict>>;
461
+ namespaceAliases: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>, unknown>>;
451
462
  }, z.core.$strict> & {
452
463
  is: (value: unknown) => value is {
453
464
  id: string;
@@ -460,6 +471,7 @@ declare const ManifestSchema: z.ZodObject<{
460
471
  version: string;
461
472
  repository: string;
462
473
  } | undefined;
474
+ namespaceAliases?: Record<string, string[]> | undefined;
463
475
  };
464
476
  };
465
477
  type Manifest = z.infer<typeof ManifestSchema>;
@@ -473,7 +485,7 @@ declare function parseManifest(doc: unknown): Manifest;
473
485
  //#endregion
474
486
  //#region src/catalogue.d.ts
475
487
  /**
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.
488
+ * 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 fully qualified name (the whole path of an id or alias) identifies one entry and is not another entry's id, every namespace segment the manifest gives aliases to is some entry's segment and no alias is itself one, 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
489
  */
478
490
  declare const CatalogueIndexSchema: z.ZodObject<{
479
491
  manifest: z.ZodObject<{
@@ -487,6 +499,7 @@ declare const CatalogueIndexSchema: z.ZodObject<{
487
499
  version: z.ZodString;
488
500
  repository: z.ZodURL;
489
501
  }, z.core.$strict>>;
502
+ namespaceAliases: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>, unknown>>;
490
503
  }, z.core.$strict> & {
491
504
  is: (value: unknown) => value is {
492
505
  id: string;
@@ -499,6 +512,7 @@ declare const CatalogueIndexSchema: z.ZodObject<{
499
512
  version: string;
500
513
  repository: string;
501
514
  } | undefined;
515
+ namespaceAliases?: Record<string, string[]> | undefined;
502
516
  };
503
517
  };
504
518
  crosswalks: z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodType<Crosswalk, unknown, z.core.$ZodTypeInternals<Crosswalk, unknown>> & {
@@ -506,6 +520,8 @@ declare const CatalogueIndexSchema: z.ZodObject<{
506
520
  }>, unknown>;
507
521
  entries: z.ZodArray<z.ZodObject<{
508
522
  id: z.ZodString;
523
+ namespace: z.ZodOptional<z.ZodArray<z.ZodString>>;
524
+ aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
509
525
  name: z.ZodString;
510
526
  description: z.ZodOptional<z.ZodString>;
511
527
  domain: z.ZodOptional<z.ZodString>;
@@ -702,6 +718,8 @@ declare const CatalogueIndexSchema: z.ZodObject<{
702
718
  };
703
719
  expectedCounts: Record<string, number>;
704
720
  properties: Record<string, string | number | boolean | null>;
721
+ namespace?: string[] | undefined;
722
+ aliases?: string[] | undefined;
705
723
  description?: string | undefined;
706
724
  domain?: string | undefined;
707
725
  };
@@ -719,6 +737,7 @@ declare const CatalogueIndexSchema: z.ZodObject<{
719
737
  version: string;
720
738
  repository: string;
721
739
  } | undefined;
740
+ namespaceAliases?: Record<string, string[]> | undefined;
722
741
  };
723
742
  crosswalks: Record<string, Crosswalk>;
724
743
  entries: {
@@ -806,6 +825,8 @@ declare const CatalogueIndexSchema: z.ZodObject<{
806
825
  };
807
826
  expectedCounts: Record<string, number>;
808
827
  properties: Record<string, string | number | boolean | null>;
828
+ namespace?: string[] | undefined;
829
+ aliases?: string[] | undefined;
809
830
  description?: string | undefined;
810
831
  domain?: string | undefined;
811
832
  }[];
@@ -827,10 +848,18 @@ interface DatasetQuery {
827
848
  readonly category?: string;
828
849
  /** The entry's domain, matched exactly. */
829
850
  readonly domain?: string;
830
- /** Text that must appear, ignoring case, in the entry's id, name, description, domain or one of its tags. */
851
+ /** 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. */
852
+ readonly namespace?: string;
853
+ /** 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. */
831
854
  readonly text?: string;
832
855
  }
833
- /** A queryable catalogue: the surface `listDatasets` and `getDataset` are bound to. */
856
+ /** 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. */
857
+ interface NamespaceNode {
858
+ readonly path: string;
859
+ readonly name: string;
860
+ readonly count: number;
861
+ }
862
+ /** A queryable catalogue: the surface `listDatasets`, `getDataset` and `listNamespaces` are bound to. */
834
863
  interface Catalogue {
835
864
  readonly manifest: Manifest;
836
865
  /**
@@ -840,12 +869,19 @@ interface Catalogue {
840
869
  */
841
870
  readonly listDatasets: (query?: DatasetQuery) => Dataset[];
842
871
  /**
843
- * Returns one dataset by entry id.
844
- * @param id - The entry id; untrusted, so lookup never reaches inherited properties.
872
+ * Returns one dataset by name. An entry's own id always resolves to it, ahead of any alias or shorter form; otherwise the name is an alias, or an id or alias with any trailing run of the entry's namespace before it (`b/c` or `a/b/c` for id `c` in namespace `a/b`), and resolves only when exactly one entry answers to it.
873
+ * @param name - An entry id, alias or qualified name; untrusted, so lookup never reaches inherited properties.
845
874
  * @returns The dataset.
846
- * @throws DatasetNotFoundError when no entry has that id.
875
+ * @throws DatasetAmbiguousError when more than one entry answers to the name and none has it as its id.
876
+ * @throws DatasetNotFoundError when no entry answers to the name.
877
+ */
878
+ readonly getDataset: (name: string) => Dataset;
879
+ /**
880
+ * Lists the namespaces directly beneath a path, or the outermost ones, with how many entries each holds. The tree is every group of every entry and each path above it, so an entry filed in `a/b` counts toward `a/b` and `a`.
881
+ * @param path - A group path whose children to list, in which any segment may be an alias the manifest gives it; absent for the outermost namespaces.
882
+ * @returns The child namespaces in path order; empty when the path has none, whether it is unknown or a leaf.
847
883
  */
848
- readonly getDataset: (id: string) => Dataset;
884
+ readonly listNamespaces: (path?: string) => NamespaceNode[];
849
885
  }
850
886
  /**
851
887
  * 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.
@@ -957,4 +993,4 @@ declare function listCategories(): readonly Category[];
957
993
  */
958
994
  declare function countTarget(id: CategoryId, target: CategoryTarget): ReadonlyMap<string, number>;
959
995
  //#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 };
996
+ export { Recipe as $, ManifestSchema as A, CrosswalkReference as B, Dataset as C, Lineage as D, createCatalogue as E, ArchiveMember as F, IdSchema as G, Entry as H, ArchiveMemberSchema as I, Namespace as J, Licence as K, ArchiveSchema as L, parseManifest as M, AliasSchema as N, LineageSchema as O, Archive as P, RESERVED_META_KEYS as Q, Citation as R, CatalogueIndexSchema as S, NamespaceNode as T, EntrySchema as U, CrosswalkReferenceSchema as V, HttpUrlSchema as W, Parser as X, NamespaceSchema as Y, ParserSchema as Z, GraphV1Schema as _, CategoryTargets as a, SourceSchema as at, Catalogue as b, getCategory as c, waybackUrl as ct, listCategories as d, RecipeSchema as et, GraphEdge as f, GraphV1 as g, GraphNodeSchema as h, CategoryTarget as i, Source as it, SemVerSchema as j, Manifest as k, getTarget as l, GraphNode as m, CategoryId as n, Snapshot as nt, CountedKey as o, WaybackTimestampSchema as ot, GraphEdgeSchema as p, LicenceSchema as q, CategoryIdSchema as r, SnapshotSchema as rt, countTarget as s, parseEntry as st, Category as t, RelativePathSchema as tt, kindOf as u, JsonScalar as v, DatasetQuery as w, CatalogueIndex as x, JsonScalarSchema as y, CitationSchema as z };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as SnapshotSchema, A as SemVerSchema, B as Entry, C as Dataset, D as LineageSchema, E as Lineage, F as ArchiveSchema, G as LicenceSchema, H as HttpUrlSchema, I as Citation, J as RESERVED_META_KEYS, K as Parser, L as CitationSchema, M as Archive, N as ArchiveMember, O as Manifest, P as ArchiveMemberSchema, Q as Snapshot, R as CrosswalkReference, S as CatalogueIndexSchema, T as createCatalogue, U as IdSchema, V as EntrySchema, W as Licence, X as RecipeSchema, Y as Recipe, Z as RelativePathSchema, _ as GraphV1Schema, a as CategoryTargets, b as Catalogue, c as getCategory, d as listCategories, et as Source, f as GraphEdge, g as GraphV1, h as GraphNodeSchema, i as CategoryTarget, it as waybackUrl, j as parseManifest, k as ManifestSchema, l as getTarget, m as GraphNode, n as CategoryId, nt as WaybackTimestampSchema, o as CountedKey, p as GraphEdgeSchema, q as ParserSchema, r as CategoryIdSchema, rt as parseEntry, s as countTarget, t as Category, tt as SourceSchema, u as kindOf, v as JsonScalar, w as DatasetQuery, x as CatalogueIndex, y as JsonScalarSchema, z as CrosswalkReferenceSchema } from "./categories-CUf1VecC.js";
1
+ import { $ as Recipe, A as ManifestSchema, B as CrosswalkReference, C as Dataset, D as Lineage, E as createCatalogue, F as ArchiveMember, G as IdSchema, H as Entry, I as ArchiveMemberSchema, J as Namespace, K as Licence, L as ArchiveSchema, M as parseManifest, N as AliasSchema, O as LineageSchema, P as Archive, Q as RESERVED_META_KEYS, R as Citation, S as CatalogueIndexSchema, T as NamespaceNode, U as EntrySchema, V as CrosswalkReferenceSchema, W as HttpUrlSchema, X as Parser, Y as NamespaceSchema, Z as ParserSchema, _ as GraphV1Schema, a as CategoryTargets, at as SourceSchema, b as Catalogue, c as getCategory, ct as waybackUrl, d as listCategories, et as RecipeSchema, f as GraphEdge, g as GraphV1, h as GraphNodeSchema, i as CategoryTarget, it as Source, j as SemVerSchema, k as Manifest, l as getTarget, m as GraphNode, n as CategoryId, nt as Snapshot, o as CountedKey, ot as WaybackTimestampSchema, p as GraphEdgeSchema, q as LicenceSchema, r as CategoryIdSchema, rt as SnapshotSchema, s as countTarget, st as parseEntry, t as Category, tt as RelativePathSchema, u as kindOf, v as JsonScalar, w as DatasetQuery, x as CatalogueIndex, y as JsonScalarSchema, z as CitationSchema } from "./categories-DzjLQ_fp.js";
2
2
  import { Crosswalk } from "twindex";
3
3
  //#region src/errors.d.ts
4
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. */
@@ -30,11 +30,17 @@ export declare class NativeParseError extends KeepsetError {
30
30
  }
31
31
  /** Thrown when an archive does not hold exactly one member the recipe's member selector matches, or is not a well-formed archive of its stated kind. */
32
32
  export declare class ArchiveError extends KeepsetError {}
33
- /** Thrown when no entry in the catalogue has the requested id. */
33
+ /** Thrown when no entry in the catalogue answers to the requested id, alias or qualified name. */
34
34
  export declare class DatasetNotFoundError extends KeepsetError {
35
35
  readonly datasetId: string;
36
36
  constructor(datasetId: string);
37
37
  }
38
+ /** Thrown when a name that is not an entry's own id is a valid way to address more than one entry. Carries the ids of the entries it could mean, so the message says how to be specific. */
39
+ export declare class DatasetAmbiguousError extends KeepsetError {
40
+ readonly requested: string;
41
+ readonly candidateIds: readonly string[];
42
+ constructor(name: string, candidateIds: readonly string[]);
43
+ }
38
44
  /** The step of a recipe that failed: the recipe itself (not fetchable), downloading the source, unpacking the archive, parsing the native shape, applying the crosswalk, or validating the result against the category target. */
39
45
  type RecipeStep = "recipe" | "download" | "extract" | "parse" | "crosswalk" | "validate";
40
46
  /** Thrown when running an entry's recipe fails. Names the entry and the failing step, and carries the underlying error as `cause`; a recipe never resolves to a partial or default-shaped result. */
@@ -58,9 +64,43 @@ export declare function listDatasets(query?: DatasetQuery): Dataset[];
58
64
  * @throws DatasetNotFoundError when no entry has that id.
59
65
  */
60
66
  export declare function getDataset(id: string): Dataset;
67
+ /**
68
+ * Lists the namespaces directly beneath a path of the bundled catalogue, or the outermost ones, with how many entries each holds. Browser-safe.
69
+ * @param path - A group path whose children to list; absent for the outermost namespaces.
70
+ * @returns The child namespaces in path order.
71
+ */
72
+ export declare function listNamespaces(path?: string): NamespaceNode[];
61
73
  /** @returns The bundled catalogue's manifest: its id, version and repository. */
62
74
  export declare function getManifest(): Manifest;
63
75
  //#endregion
76
+ //#region src/names.d.ts
77
+ /** The character that joins a namespace's segments to each other and to a name. It is not in an id's alphabet, so a name containing it is always a path and never a literal id. */
78
+ export declare const NAME_SEPARATOR = "/";
79
+ /** The other names namespace segments go by, as a catalogue manifest declares them: a segment mapped to its aliases. */
80
+ type SegmentAliases = Readonly<Record<string, readonly string[]>>;
81
+ /** The names an entry answers to: its fully qualified names, which must each identify it alone, and every name that resolves to it, which also includes the shorter forms. */
82
+ interface EntryNames {
83
+ /** Each address written out in full: the whole path of an address, with no segment alias substituted. */
84
+ readonly full: readonly string[];
85
+ /** Every trailing run of each address's path, the whole path and the bare name among them, with every combination of segment aliases for the namespace part. */
86
+ readonly all: readonly string[];
87
+ }
88
+ /** The entry fields that give it addresses and groups. */
89
+ type Addressed = Pick<Entry, "id" | "namespace" | "aliases">;
90
+ /**
91
+ * The groups an entry belongs to: the namespace its id and bare aliases sit in, and the group each alias that is a path names, each once, in order of first appearance. A group is a path of segments; an entry belongs to every group above it as well, which the caller reads off the path.
92
+ * @param entry - The entry.
93
+ * @returns The groups, empty for an entry with no namespace and no path aliases.
94
+ */
95
+ export declare function groupsOf(entry: Addressed): string[][];
96
+ /**
97
+ * Works out the names an entry answers to. Each address is a path of segments with the name last, and an address answers to every trailing run of its path, so id `c` in namespace `a/b` answers to `c`, `b/c` and `a/b/c`, and the alias `x/y/d` answers to `d`, `y/d` and `x/y/d`. Where the manifest gives a segment aliases, an address also answers with the alias in the segment's place.
98
+ * @param entry - The entry: only its id, namespace and aliases are read.
99
+ * @param segmentAliases - The manifest's aliases for namespace segments, if any.
100
+ * @returns The fully qualified names and every name that resolves to the entry.
101
+ */
102
+ export declare function namesOf(entry: Addressed, segmentAliases?: SegmentAliases): EntryNames;
103
+ //#endregion
64
104
  //#region src/serialise.d.ts
65
105
  /**
66
106
  * Serialises a catalogue document (an entry, a manifest or a crosswalk file) as its file holds it: two-space indented JSON with keys in ascending order and a trailing newline. The form depends only on the document's content, so parsing a file written this way and serialising the result reproduces the file byte for byte.
@@ -77,4 +117,4 @@ export declare function serialise(doc: Entry | Manifest | Crosswalk): string;
77
117
  */
78
118
  export declare function validateDataset(dataset: Dataset): SyntaxIssue[];
79
119
  //#endregion
80
- export { type Archive, type ArchiveMember, ArchiveMemberSchema, ArchiveSchema, type Catalogue, type CatalogueIndex, CatalogueIndexSchema, type Category, type CategoryId, CategoryIdSchema, type CategoryTarget, type CategoryTargets, type Citation, CitationSchema, type CountedKey, type CrosswalkReference, CrosswalkReferenceSchema, type Dataset, type DatasetQuery, type Entry, EntrySchema, type GraphEdge, GraphEdgeSchema, type GraphNode, GraphNodeSchema, type GraphV1, GraphV1Schema, HttpUrlSchema, IdSchema, type JsonScalar, JsonScalarSchema, type Licence, LicenceSchema, type Lineage, LineageSchema, type Manifest, ManifestSchema, type Parser, ParserSchema, RESERVED_META_KEYS, type Recipe, RecipeSchema, type RecipeStep, RelativePathSchema, SemVerSchema, type Snapshot, SnapshotSchema, type Source, SourceSchema, type SyntaxIssue, WaybackTimestampSchema, countTarget, createCatalogue, getCategory, getTarget, kindOf, listCategories, parseEntry, parseManifest, waybackUrl };
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 CountedKey, type CrosswalkReference, CrosswalkReferenceSchema, type Dataset, type DatasetQuery, type Entry, type EntryNames, EntrySchema, type GraphEdge, GraphEdgeSchema, type GraphNode, GraphNodeSchema, type GraphV1, GraphV1Schema, HttpUrlSchema, IdSchema, type JsonScalar, JsonScalarSchema, type Licence, LicenceSchema, type Lineage, LineageSchema, type Manifest, ManifestSchema, type Namespace, type NamespaceNode, NamespaceSchema, type Parser, ParserSchema, RESERVED_META_KEYS, type Recipe, RecipeSchema, type RecipeStep, RelativePathSchema, type SegmentAliases, SemVerSchema, type Snapshot, SnapshotSchema, type Source, SourceSchema, type SyntaxIssue, WaybackTimestampSchema, countTarget, createCatalogue, getCategory, getTarget, kindOf, listCategories, parseEntry, parseManifest, waybackUrl };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as countTarget, B as CatalogueSyntaxError, C as SnapshotSchema, D as toIssues, E as parseEntry, F as GraphEdgeSchema, G as UnknownCategoryError, H as KeepsetError, I as GraphNodeSchema, L as GraphV1Schema, M as getTarget, N as kindOf, O as waybackUrl, P as listCategories, R as JsonScalarSchema, S as RelativePathSchema, T as WaybackTimestampSchema, U as NativeParseError, V as DatasetNotFoundError, W as RecipeError, _ as IdSchema, a as createCatalogue, b as RESERVED_META_KEYS, c as ManifestSchema, d as ArchiveMemberSchema, f as ArchiveSchema, g as HttpUrlSchema, h as EntrySchema, i as CatalogueIndexSchema, j as getCategory, k as CategoryIdSchema, l as SemVerSchema, m as CrosswalkReferenceSchema, n as getManifest, p as CitationSchema, r as listDatasets, s as LineageSchema, t as getDataset, u as parseManifest, v as LicenceSchema, w as SourceSchema, x as RecipeSchema, y as ParserSchema, z as ArchiveError } from "./bundled-BIBLzetw.js";
1
+ import { A as waybackUrl, B as listCategories, C as RecipeSchema, D as WaybackTimestampSchema, E as SourceSchema, F as CategoryIdSchema, G as ArchiveError, H as GraphNodeSchema, I as countTarget, J as DatasetNotFoundError, K as CatalogueSyntaxError, L as getCategory, M as groupsOf, N as namesOf, O as parseEntry, Q as UnknownCategoryError, R as getTarget, S as RESERVED_META_KEYS, T as SnapshotSchema, U as GraphV1Schema, V as GraphEdgeSchema, W as JsonScalarSchema, X as NativeParseError, Y as KeepsetError, Z as RecipeError, _ as HttpUrlSchema, a as CatalogueIndexSchema, b as NamespaceSchema, c as ManifestSchema, d as AliasSchema, f as ArchiveMemberSchema, g as EntrySchema, h as CrosswalkReferenceSchema, i as listNamespaces, j as NAME_SEPARATOR, k as toIssues, l as SemVerSchema, m as CitationSchema, n as getManifest, o as createCatalogue, p as ArchiveSchema, q as DatasetAmbiguousError, r as listDatasets, s as LineageSchema, t as getDataset, u as parseManifest, v as IdSchema, w as RelativePathSchema, x as ParserSchema, y as LicenceSchema, z as kindOf } from "./bundled-DNLiwEcd.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 { ArchiveError, ArchiveMemberSchema, ArchiveSchema, CatalogueIndexSchema, CatalogueSyntaxError, CategoryIdSchema, CitationSchema, CrosswalkReferenceSchema, DatasetNotFoundError, EntrySchema, GraphEdgeSchema, GraphNodeSchema, GraphV1Schema, HttpUrlSchema, IdSchema, JsonScalarSchema, KeepsetError, LicenceSchema, LineageSchema, ManifestSchema, NativeParseError, ParserSchema, RESERVED_META_KEYS, RecipeError, RecipeSchema, RelativePathSchema, SemVerSchema, SnapshotSchema, SourceSchema, UnknownCategoryError, WaybackTimestampSchema, countTarget, createCatalogue, getCategory, getDataset, getManifest, getTarget, kindOf, listCategories, listDatasets, parseEntry, parseManifest, serialise, validateDataset, waybackUrl };
60
+ export { AliasSchema, ArchiveError, ArchiveMemberSchema, ArchiveSchema, CatalogueIndexSchema, CatalogueSyntaxError, CategoryIdSchema, CitationSchema, CrosswalkReferenceSchema, DatasetAmbiguousError, DatasetNotFoundError, EntrySchema, GraphEdgeSchema, GraphNodeSchema, GraphV1Schema, HttpUrlSchema, IdSchema, JsonScalarSchema, KeepsetError, LicenceSchema, LineageSchema, ManifestSchema, NAME_SEPARATOR, NamespaceSchema, NativeParseError, ParserSchema, RESERVED_META_KEYS, RecipeError, RecipeSchema, RelativePathSchema, SemVerSchema, SnapshotSchema, SourceSchema, UnknownCategoryError, WaybackTimestampSchema, countTarget, createCatalogue, getCategory, getDataset, getManifest, getTarget, groupsOf, kindOf, listCategories, listDatasets, listNamespaces, namesOf, parseEntry, parseManifest, serialise, validateDataset, waybackUrl };
@@ -1,4 +1,4 @@
1
- import { B as Entry, C as Dataset, Q as Snapshot, et as Source, i as CategoryTarget } from "../categories-CUf1VecC.js";
1
+ import { C as Dataset, H as Entry, i as CategoryTarget, it as Source, nt as Snapshot } from "../categories-DzjLQ_fp.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: {
@@ -1,4 +1,4 @@
1
- import { A as countTarget, H as KeepsetError, M as getTarget, U as NativeParseError, W as RecipeError, o as getOwn, t as getDataset, z as ArchiveError } from "../bundled-BIBLzetw.js";
1
+ import { G as ArchiveError, I as countTarget, P as getOwn, R as getTarget, X as NativeParseError, Y as KeepsetError, Z as RecipeError, t as getDataset } from "../bundled-DNLiwEcd.js";
2
2
  import { RoundTripMismatchError, assertRoundTrip, encode } from "twindex";
3
3
  import { createHash } from "node:crypto";
4
4
  import { gunzipSync } from "node:zlib";
@@ -1,33 +1,42 @@
1
1
  #!/usr/bin/env node
2
2
  import { writeFileSync } from "node:fs";
3
- import { KeepsetError, countTarget, getDataset, listDatasets, validateDataset } from "keepset";
3
+ import { KeepsetError, NAME_SEPARATOR, countTarget, getDataset, listDatasets, validateDataset } from "keepset";
4
4
  import { fetchDataset, roundTripDataset } from "keepset/node";
5
5
  import { parseArgs } from "node:util";
6
6
  //#region package.json
7
- var version = "0.10.0";
7
+ var version = "0.12.0";
8
8
  const usage = `Usage: keepset <command> [options]
9
9
 
10
10
  Commands:
11
- search [text] [--kind <kind>] [--domain <domain>] [--category <id>] [--json]
12
- list the datasets whose id, name, description, domain or
13
- tags contain the text, filtered by kind, domain or category
14
- show <id> [--json] print a dataset's metadata, recipe and crosswalk
15
- fetch <id> [--out <file>]
11
+ search [text] [--kind <kind>] [--domain <domain>] [--namespace <path>]
12
+ [--category <id>] [--json]
13
+ list the datasets whose id, alias, namespace, name,
14
+ description, domain or tags contain the text, filtered by
15
+ kind, domain, namespace (and every namespace beneath it,
16
+ segment aliases allowed) or category
17
+ show <dataset> [--json]
18
+ print a dataset's metadata, recipe and crosswalk
19
+ fetch <dataset> [--out <file>]
16
20
  run the dataset's recipe and write the normalised result
17
21
  to <file> (default <id>.json), with its provenance beside
18
22
  it in <file without .json>.provenance.json
19
- validate <id> check the entry against the entry schema and its
23
+ validate <dataset> check the entry against the entry schema and its
20
24
  crosswalk against twindex's validation
21
- roundtrip <id> fetch the dataset and check that decoding the encoded
25
+ roundtrip <dataset> fetch the dataset and check that decoding the encoded
22
26
  native document gives it back
23
27
 
28
+ A <dataset> is an entry id, an alias, or a qualified name such as
29
+ suitesparse/gset/g53, written with / between the namespace and the name. Any
30
+ leading part of the namespace may be dropped (gset/g53, g53) while the name
31
+ still means one dataset; an entry's own id always means that entry.
32
+
24
33
  Options:
25
34
  --help, -h print this help
26
35
  --version, -v print the version
27
36
 
28
37
  Exit status: 0 for a result, a valid entry or a round trip that holds; 1 for an
29
38
  invalid entry or a round trip that does not hold; 2 when there is no answer:
30
- bad usage, an unknown dataset or a recipe that failed.
39
+ bad usage, an unknown or ambiguous dataset or a recipe that failed.
31
40
  `;
32
41
  function parseCommandLine(args) {
33
42
  return parseArgs({
@@ -37,6 +46,7 @@ function parseCommandLine(args) {
37
46
  options: {
38
47
  kind: { type: "string" },
39
48
  domain: { type: "string" },
49
+ namespace: { type: "string" },
40
50
  category: { type: "string" },
41
51
  json: { type: "boolean" },
42
52
  out: { type: "string" },
@@ -77,6 +87,8 @@ function formatShow(dataset) {
77
87
  const lines = [`${entry.name} (${entry.id})`];
78
88
  if (entry.description !== void 0) lines.push("", entry.description);
79
89
  lines.push("", `category: ${entry.category} (kind ${dataset.kind})`, `catalogue: ${dataset.catalogue.id} ${dataset.catalogue.version}`);
90
+ if (entry.namespace !== void 0) lines.push(`namespace: ${entry.namespace.join(NAME_SEPARATOR)}`);
91
+ if (entry.aliases !== void 0) lines.push(`aliases: ${entry.aliases.join(", ")}`);
80
92
  if (entry.domain !== void 0) lines.push(`domain: ${entry.domain}`);
81
93
  if (entry.tags.length > 0) lines.push(`tags: ${entry.tags.join(", ")}`);
82
94
  const { licence } = entry;
@@ -164,13 +176,14 @@ async function run(args, library, io) {
164
176
  ...text === void 0 ? {} : { text },
165
177
  ...values.kind === void 0 ? {} : { kind: values.kind },
166
178
  ...values.domain === void 0 ? {} : { domain: values.domain },
179
+ ...values.namespace === void 0 ? {} : { namespace: values.namespace },
167
180
  ...values.category === void 0 ? {} : { category: values.category }
168
181
  };
169
182
  const datasets = library.listDatasets(query);
170
183
  io.writeStdout(values.json === true ? json(datasets.map((dataset) => dataset.entry)) : formatSearch(datasets));
171
184
  return 0;
172
185
  }
173
- const [id, ...extra] = rest;
186
+ const [name, ...extra] = rest;
174
187
  if (command === void 0) return reject("expected a command");
175
188
  if (![
176
189
  "show",
@@ -178,14 +191,15 @@ async function run(args, library, io) {
178
191
  "validate",
179
192
  "roundtrip"
180
193
  ].includes(command)) return reject(`unknown command ${command}`);
181
- if (id === void 0 || extra.length > 0) return reject(`${command} takes exactly one dataset id`);
194
+ if (name === void 0 || extra.length > 0) return reject(`${command} takes exactly one dataset`);
195
+ const dataset = library.getDataset(name);
196
+ const { id } = dataset.entry;
182
197
  if (command === "show") {
183
- const dataset = library.getDataset(id);
184
198
  io.writeStdout(values.json === true ? json(dataset) : formatShow(dataset));
185
199
  return 0;
186
200
  }
187
201
  if (command === "validate") {
188
- const issues = library.validateDataset(library.getDataset(id));
202
+ const issues = library.validateDataset(dataset);
189
203
  if (issues.length > 0) {
190
204
  io.writeStdout(formatIssues(issues));
191
205
  return 1;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "keepset",
3
3
  "description": "Library, CLI and statically generated catalogue for dataset fetch-and-normalise recipes",
4
- "version": "0.10.0",
4
+ "version": "0.12.0",
5
5
  "bin": {
6
6
  "keepset": "./dist-cli/keepset.mjs"
7
7
  },
@@ -1 +1 @@
1
- {"$defs":{"Crosswalk":{"$ref":"https://cdn.jsdelivr.net/npm/twindex@0.1.1/schemas/twindex.schema.json"},"Entry":{"additionalProperties":false,"properties":{"category":{"enum":["graph/v1"],"type":"string"},"citations":{"items":{"additionalProperties":false,"properties":{"doi":{"pattern":"^10\\.\\d{4,9}\\/\\S+$","type":"string"},"text":{"minLength":1,"type":"string"},"url":{"format":"uri","type":"string"}},"required":["text"],"type":"object"},"type":"array"},"crosswalk":{"anyOf":[{"$ref":"#/$defs/Crosswalk"},{"additionalProperties":false,"properties":{"file":{"type":"string"}},"required":["file"],"type":"object"}]},"description":{"minLength":1,"type":"string"},"domain":{"minLength":1,"type":"string"},"expectedCounts":{"additionalProperties":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"propertyNames":{"pattern":"^[A-Za-z][A-Za-z0-9]*$","type":"string"},"type":"object"},"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"licence":{"oneOf":[{"additionalProperties":false,"properties":{"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.+-]*$","type":"string"},"kind":{"const":"spdx","type":"string"}},"required":["kind","id"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"custom","type":"string"},"name":{"minLength":1,"type":"string"},"url":{"format":"uri","type":"string"}},"required":["kind","name","url"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"unrecorded","type":"string"}},"required":["kind"],"type":"object"}]},"name":{"minLength":1,"type":"string"},"properties":{"additionalProperties":{"type":["string","number","boolean","null"]},"propertyNames":{"pattern":"^[A-Za-z][A-Za-z0-9]*$","type":"string"},"type":"object"},"recipe":{"oneOf":[{"additionalProperties":false,"properties":{"archive":{"oneOf":[{"additionalProperties":false,"properties":{"kind":{"const":"none","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"zip","type":"string"},"member":{"anyOf":[{"additionalProperties":false,"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},{"additionalProperties":false,"properties":{"extensions":{"items":{"pattern":"^\\.[A-Za-z0-9][A-Za-z0-9.]*$","type":"string"},"minItems":1,"type":"array"}},"required":["extensions"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"tar","type":"string"},"member":{"anyOf":[{"additionalProperties":false,"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},{"additionalProperties":false,"properties":{"extensions":{"items":{"pattern":"^\\.[A-Za-z0-9][A-Za-z0-9.]*$","type":"string"},"minItems":1,"type":"array"}},"required":["extensions"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"tar.gz","type":"string"},"member":{"anyOf":[{"additionalProperties":false,"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},{"additionalProperties":false,"properties":{"extensions":{"items":{"pattern":"^\\.[A-Za-z0-9][A-Za-z0-9.]*$","type":"string"},"minItems":1,"type":"array"}},"required":["extensions"],"type":"object"}]}},"required":["kind","member"],"type":"object"}]},"parser":{"oneOf":[{"additionalProperties":false,"properties":{"commentPrefixes":{"items":{"minLength":1,"type":"string"},"type":"array"},"delimiter":{"enum":["detect","whitespace","tab","comma","space"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"edge-list","type":"string"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"sourceColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"targetColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","commentPrefixes","sourceColumn","targetColumn"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"matrix-market","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"gml","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"pajek","type":"string"}},"required":["format","encoding"],"type":"object"}]},"source":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"status":{"const":"fetchable","type":"string"}},"required":["status","source","archive","parser"],"type":"object"},{"additionalProperties":false,"properties":{"reason":{"minLength":1,"type":"string"},"status":{"const":"not-fetchable","type":"string"}},"required":["status","reason"],"type":"object"}]},"sources":{"items":{"additionalProperties":false,"properties":{"retrieved":{"format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","type":"string"},"snapshot":{"additionalProperties":false,"properties":{"timestamp":{"pattern":"^\\d{8}(?:\\d{6})?$","type":"string"},"url":{"format":"uri","type":"string"}},"required":["url","timestamp"],"type":"object"},"status":{"enum":["live","dead"],"type":"string"},"url":{"format":"uri","type":"string"}},"required":["url","retrieved","status"],"type":"object"},"minItems":1,"type":"array"},"tags":{"items":{"minLength":1,"type":"string"},"type":"array"}},"required":["id","name","tags","category","sources","licence","citations","recipe","crosswalk","expectedCounts","properties"],"type":"object"}},"$id":"https://cdn.jsdelivr.net/npm/keepset@0.10.0/schemas/entry.schema.json","$ref":"#/$defs/Entry","$schema":"https://json-schema.org/draft/2020-12/schema"}
1
+ {"$defs":{"Crosswalk":{"$ref":"https://cdn.jsdelivr.net/npm/twindex@0.1.1/schemas/twindex.schema.json"},"Entry":{"additionalProperties":false,"properties":{"aliases":{"items":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*(?:\\/[A-Za-z0-9][A-Za-z0-9._-]*)*$","type":"string"},"minItems":1,"type":"array"},"category":{"enum":["graph/v1"],"type":"string"},"citations":{"items":{"additionalProperties":false,"properties":{"doi":{"pattern":"^10\\.\\d{4,9}\\/\\S+$","type":"string"},"text":{"minLength":1,"type":"string"},"url":{"format":"uri","type":"string"}},"required":["text"],"type":"object"},"type":"array"},"crosswalk":{"anyOf":[{"$ref":"#/$defs/Crosswalk"},{"additionalProperties":false,"properties":{"file":{"type":"string"}},"required":["file"],"type":"object"}]},"description":{"minLength":1,"type":"string"},"domain":{"minLength":1,"type":"string"},"expectedCounts":{"additionalProperties":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"propertyNames":{"pattern":"^[A-Za-z][A-Za-z0-9]*$","type":"string"},"type":"object"},"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"licence":{"oneOf":[{"additionalProperties":false,"properties":{"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.+-]*$","type":"string"},"kind":{"const":"spdx","type":"string"}},"required":["kind","id"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"custom","type":"string"},"name":{"minLength":1,"type":"string"},"url":{"format":"uri","type":"string"}},"required":["kind","name","url"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"unrecorded","type":"string"}},"required":["kind"],"type":"object"}]},"name":{"minLength":1,"type":"string"},"namespace":{"items":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"minItems":1,"type":"array"},"properties":{"additionalProperties":{"type":["string","number","boolean","null"]},"propertyNames":{"pattern":"^[A-Za-z][A-Za-z0-9]*$","type":"string"},"type":"object"},"recipe":{"oneOf":[{"additionalProperties":false,"properties":{"archive":{"oneOf":[{"additionalProperties":false,"properties":{"kind":{"const":"none","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"zip","type":"string"},"member":{"anyOf":[{"additionalProperties":false,"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},{"additionalProperties":false,"properties":{"extensions":{"items":{"pattern":"^\\.[A-Za-z0-9][A-Za-z0-9.]*$","type":"string"},"minItems":1,"type":"array"}},"required":["extensions"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"tar","type":"string"},"member":{"anyOf":[{"additionalProperties":false,"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},{"additionalProperties":false,"properties":{"extensions":{"items":{"pattern":"^\\.[A-Za-z0-9][A-Za-z0-9.]*$","type":"string"},"minItems":1,"type":"array"}},"required":["extensions"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"tar.gz","type":"string"},"member":{"anyOf":[{"additionalProperties":false,"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},{"additionalProperties":false,"properties":{"extensions":{"items":{"pattern":"^\\.[A-Za-z0-9][A-Za-z0-9.]*$","type":"string"},"minItems":1,"type":"array"}},"required":["extensions"],"type":"object"}]}},"required":["kind","member"],"type":"object"}]},"parser":{"oneOf":[{"additionalProperties":false,"properties":{"commentPrefixes":{"items":{"minLength":1,"type":"string"},"type":"array"},"delimiter":{"enum":["detect","whitespace","tab","comma","space"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"edge-list","type":"string"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"sourceColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"targetColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","commentPrefixes","sourceColumn","targetColumn"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"matrix-market","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"gml","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"pajek","type":"string"}},"required":["format","encoding"],"type":"object"}]},"source":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"status":{"const":"fetchable","type":"string"}},"required":["status","source","archive","parser"],"type":"object"},{"additionalProperties":false,"properties":{"reason":{"minLength":1,"type":"string"},"status":{"const":"not-fetchable","type":"string"}},"required":["status","reason"],"type":"object"}]},"sources":{"items":{"additionalProperties":false,"properties":{"retrieved":{"format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","type":"string"},"snapshot":{"additionalProperties":false,"properties":{"timestamp":{"pattern":"^\\d{8}(?:\\d{6})?$","type":"string"},"url":{"format":"uri","type":"string"}},"required":["url","timestamp"],"type":"object"},"status":{"enum":["live","dead"],"type":"string"},"url":{"format":"uri","type":"string"}},"required":["url","retrieved","status"],"type":"object"},"minItems":1,"type":"array"},"tags":{"items":{"minLength":1,"type":"string"},"type":"array"}},"required":["id","name","tags","category","sources","licence","citations","recipe","crosswalk","expectedCounts","properties"],"type":"object"}},"$id":"https://cdn.jsdelivr.net/npm/keepset@0.12.0/schemas/entry.schema.json","$ref":"#/$defs/Entry","$schema":"https://json-schema.org/draft/2020-12/schema"}
@@ -1 +1 @@
1
- {"$defs":{"Manifest":{"additionalProperties":false,"properties":{"description":{"minLength":1,"type":"string"},"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"lineage":{"additionalProperties":false,"properties":{"catalogue":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"repository":{"format":"uri","type":"string"},"version":{"pattern":"^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$","type":"string"}},"required":["catalogue","version","repository"],"type":"object"},"name":{"minLength":1,"type":"string"},"repository":{"format":"uri","type":"string"},"version":{"pattern":"^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$","type":"string"}},"required":["id","name","description","version","repository"],"type":"object"}},"$id":"https://cdn.jsdelivr.net/npm/keepset@0.10.0/schemas/manifest.schema.json","$ref":"#/$defs/Manifest","$schema":"https://json-schema.org/draft/2020-12/schema"}
1
+ {"$defs":{"Manifest":{"additionalProperties":false,"properties":{"description":{"minLength":1,"type":"string"},"id":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"lineage":{"additionalProperties":false,"properties":{"catalogue":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"repository":{"format":"uri","type":"string"},"version":{"pattern":"^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$","type":"string"}},"required":["catalogue","version","repository"],"type":"object"},"name":{"minLength":1,"type":"string"},"namespaceAliases":{"additionalProperties":{"items":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"minItems":1,"type":"array"},"propertyNames":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]*$","type":"string"},"type":"object"},"repository":{"format":"uri","type":"string"},"version":{"pattern":"^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$","type":"string"}},"required":["id","name","description","version","repository"],"type":"object"}},"$id":"https://cdn.jsdelivr.net/npm/keepset@0.12.0/schemas/manifest.schema.json","$ref":"#/$defs/Manifest","$schema":"https://json-schema.org/draft/2020-12/schema"}