keepset 0.45.0 → 0.46.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 CHANGED
@@ -25,6 +25,8 @@ provenance.sha256; // the hash of exactly those bytes
25
25
 
26
26
  `listDatasets` and `getDataset` read the catalogue bundled with the package and are browser-safe. `fetchDataset` downloads, extracts and parses, so it lives behind the `keepset/node` subpath: it needs the filesystem and the network, and takes an optional `{ fetch, signal, now }` so a caller can inject a stand-in, abort mid-download and pin the provenance clock.
27
27
 
28
+ A fetch resolves each source through a chain: its pinned Wayback snapshot first (the bytes the recipe was written against), then the closest capture the Wayback availability API names, then the live URL, which is never tried for a dead source. When the live URL is what was read, the provenance says so and the fetch asks the Internet Archive to capture it (a Save Page Now request made after the result is delivered, so it never delays one), which leaves the next fetcher a snapshot; `keepset fetch --no-archive` stops the request, and the library leaves it to the caller (`captureRequestsFor` and `requestCapture`, exported by `keepset/node` and `keepset/browser`). The browser entry point (`keepset/browser`) resolves the same way, and the site's preview asks for the capture too.
29
+
28
30
  ## The CLI
29
31
 
30
32
  ```sh
@@ -1,5 +1,6 @@
1
+ import { d as UnreachableSourceError, s as RecipeError } from "../errors-DkaEOcM6.js";
1
2
  import { z as Dataset } from "../categories-BG8lRjy8.js";
2
- import { a as FetchPort, c as Provenance, d as fetchDataset$1, f as fetchEntry$1, i as FetchOptions, l as RoundTripReport, n as Download, o as FetchedDataset, p as roundTripEntry$1, r as DownloadProvenance, s as FilesProvenance, t as DigestPort, u as downloadUrl } from "../fetch-HjZj2roj.js";
3
+ import { a as FetchOptions, c as FilesProvenance, d as downloadUrl, f as fetchDataset$1, i as DownloadProvenance, l as Provenance, m as roundTripEntry$1, n as DigestPort, o as FetchPort, p as fetchEntry$1, r as Download, s as FetchedDataset, t as captureRequestsFor, u as RoundTripReport } from "../resolve-B1F1vxr2.js";
3
4
  //#region src/browser/download.d.ts
4
5
  /** How long a request may take in all, at any point of a download, before it is given up as dead. The platform `fetch` reports progress to no one, so the stall watch of the Node downloader becomes a whole-request deadline here; a healthy server of the open data portals recipes read answers well inside it. */
5
6
  export declare const STALL_MILLISECONDS = 120000;
@@ -53,5 +54,11 @@ export declare function roundTripEntry(dataset: Dataset, options: BrowserFetchOp
53
54
  * @returns Whether the round trip holds.
54
55
  */
55
56
  export declare function roundTripDataset(id: string, options: BrowserFetchOptions): Promise<Awaited<ReturnType<typeof roundTripEntry$1>>>;
57
+ /**
58
+ * Asks the Archive to capture a URL a fetch read live; see `../resolve`'s `requestCapture`. The platform sends it without reading the answer, which the Archive's replies to a page on another origin do not allow.
59
+ * @param saveUrl - A request URL from `captureRequestsFor`.
60
+ * @param signal - Aborts the request.
61
+ */
62
+ export declare function requestCapture(saveUrl: string, signal?: AbortSignal): Promise<void>;
56
63
  //#endregion
57
- export { type DigestPort, type Download, type DownloadInit, type DownloadProvenance, type FetchOptions, type FetchPort, type FetchedDataset, type FilesProvenance, type Provenance, type RoundTripReport, downloadUrl };
64
+ export { type DigestPort, type Download, type DownloadInit, type DownloadProvenance, type FetchOptions, type FetchPort, type FetchedDataset, type FilesProvenance, type Provenance, RecipeError, type RoundTripReport, UnreachableSourceError, captureRequestsFor, downloadUrl };
@@ -1,5 +1,5 @@
1
- import { ft as KeepsetError } from "../bundled-OrF_TPDq.js";
2
- import { i as roundTripEntry$1, n as fetchDataset$1, r as fetchEntry$1, t as downloadUrl } from "../fetch-A4VG2QuN.js";
1
+ import { ft as KeepsetError, gt as UnreachableSourceError, mt as RecipeError } from "../bundled-B_PUAjMX.js";
2
+ import { a as captureRequestsFor, i as roundTripEntry$1, n as fetchDataset$1, o as requestCapture$1, r as fetchEntry$1, t as downloadUrl } from "../fetch-D9CizpRF.js";
3
3
  //#region src/browser/download.ts
4
4
  /** How long a request may take in all, at any point of a download, before it is given up as dead. The platform `fetch` reports progress to no one, so the stall watch of the Node downloader becomes a whole-request deadline here; a healthy server of the open data portals recipes read answers well inside it. */
5
5
  const STALL_MILLISECONDS = 12e4;
@@ -101,7 +101,18 @@ async function roundTripEntry(dataset, options) {
101
101
  * @returns Whether the round trip holds.
102
102
  */
103
103
  async function roundTripDataset(id, options) {
104
- return roundTripEntry$1((await import("../bundled-OrF_TPDq.js").then((n) => n.t)).getDataset(id), ports(options));
104
+ return roundTripEntry$1((await import("../bundled-B_PUAjMX.js").then((n) => n.t)).getDataset(id), ports(options));
105
+ }
106
+ /**
107
+ * Asks the Archive to capture a URL a fetch read live; see `../resolve`'s `requestCapture`. The platform sends it without reading the answer, which the Archive's replies to a page on another origin do not allow.
108
+ * @param saveUrl - A request URL from `captureRequestsFor`.
109
+ * @param signal - Aborts the request.
110
+ */
111
+ async function requestCapture(saveUrl, signal) {
112
+ await requestCapture$1(saveUrl, async (url, init) => await fetch(url, {
113
+ ...init,
114
+ mode: "no-cors"
115
+ }), signal);
105
116
  }
106
117
  //#endregion
107
- export { DOWNLOAD_ATTEMPTS, RETRY_DELAY_MILLISECONDS, STALL_MILLISECONDS, downloadRaw, downloadUrl, fetchDataset, fetchEntry, roundTripDataset, roundTripEntry };
118
+ export { DOWNLOAD_ATTEMPTS, RETRY_DELAY_MILLISECONDS, RecipeError, STALL_MILLISECONDS, UnreachableSourceError, captureRequestsFor, downloadRaw, downloadUrl, fetchDataset, fetchEntry, requestCapture, roundTripDataset, roundTripEntry };
@@ -20,6 +20,8 @@ var KeepsetError = class extends Error {
20
20
  this.name = new.target.name;
21
21
  }
22
22
  };
23
+ /** Thrown when no tier of a source's resolution chain gave an HTTP answer at all: the connection failed or the host refuses the request, which a page on another origin meets for every host without CORS headers. Telling it from a source that answered with an error is what lets a caller offer the file to be supplied by hand. */
24
+ var UnreachableSourceError = class extends KeepsetError {};
23
25
  /** Thrown when a category id names no category in the registry. Carries the ids that do exist, so the message says what would have been accepted. */
24
26
  var UnknownCategoryError = class extends KeepsetError {
25
27
  categoryId;
@@ -68866,4 +68868,4 @@ function getManifest() {
68866
68868
  return catalogue().manifest;
68867
68869
  }
68868
68870
  //#endregion
68869
- export { listCategories as $, SnapshotSchema as A, NAME_SEPARATOR as B, IdSchema as C, RESERVED_META_KEYS as D, ParserSchema as E, parseEntry as F, countTarget as G, namesOf as H, rawSnapshotUrl as I, getCollectionTarget as J, countedKeys as K, readsCollection as L, SourceSchema as M, SubjectSchema as N, RecipeSchema as O, WaybackTimestampSchema as P, kindOf as Q, toIssues as R, HttpUrlSchema as S, NamespaceSchema as T, getOwn as U, groupsOf as V, CategoryIdSchema as W, getTarget as X, getStreamedShape as Y, isStreamable as Z, CollectionFileSchema as _, listNamespaces as a, GraphNodeSchema as at, EntrySchema as b, LineageSchema as c, ArchiveError as ct, parseManifest as d, DatasetNotFoundError as dt, TaskSchema as et, AliasSchema as f, KeepsetError as ft, CollectionArchiveSchema as g, CitationSchema as h, UnknownCategoryError as ht, listDatasets as i, GraphEdgeSchema as it, SourceRecipeSchema as j, RelativePathSchema as k, ManifestSchema as l, CatalogueSyntaxError as lt, ArchiveSchema as m, RecipeError as mt, getDataset as n, TasksV1Schema as nt, CatalogueIndexSchema as o, GraphV1Schema as ot, ArchiveMemberSchema as p, NativeParseError as pt, getCategory as q, getManifest as r, collectionOf as rt, createCatalogue as s, JsonScalarSchema as st, bundled_exports as t, TasksMetaSchema as tt, SemVerSchema as u, DatasetAmbiguousError as ut, ColumnNameSchema as v, LicenceSchema as w, FilesRecipeSchema as x, CrosswalkReferenceSchema as y, waybackUrl as z };
68871
+ export { listCategories as $, SnapshotSchema as A, NAME_SEPARATOR as B, IdSchema as C, RESERVED_META_KEYS as D, ParserSchema as E, parseEntry as F, countTarget as G, namesOf as H, rawSnapshotUrl as I, getCollectionTarget as J, countedKeys as K, readsCollection as L, SourceSchema as M, SubjectSchema as N, RecipeSchema as O, WaybackTimestampSchema as P, kindOf as Q, toIssues as R, HttpUrlSchema as S, NamespaceSchema as T, getOwn as U, groupsOf as V, CategoryIdSchema as W, getTarget as X, getStreamedShape as Y, isStreamable as Z, CollectionFileSchema as _, listNamespaces as a, GraphNodeSchema as at, EntrySchema as b, LineageSchema as c, ArchiveError as ct, parseManifest as d, DatasetNotFoundError as dt, TaskSchema as et, AliasSchema as f, KeepsetError as ft, CollectionArchiveSchema as g, UnreachableSourceError as gt, CitationSchema as h, UnknownCategoryError as ht, listDatasets as i, GraphEdgeSchema as it, SourceRecipeSchema as j, RelativePathSchema as k, ManifestSchema as l, CatalogueSyntaxError as lt, ArchiveSchema as m, RecipeError as mt, getDataset as n, TasksV1Schema as nt, CatalogueIndexSchema as o, GraphV1Schema as ot, ArchiveMemberSchema as p, NativeParseError as pt, getCategory as q, getManifest as r, collectionOf as rt, createCatalogue as s, JsonScalarSchema as st, bundled_exports as t, TasksMetaSchema as tt, SemVerSchema as u, DatasetAmbiguousError as ut, ColumnNameSchema as v, LicenceSchema as w, FilesRecipeSchema as x, CrosswalkReferenceSchema as y, waybackUrl as z };
@@ -0,0 +1,53 @@
1
+ //#region src/errors.d.ts
2
+ /** The root of this package's error taxonomy: every error keepset throws is a `KeepsetError`, so callers can catch the family with one check. */
3
+ declare class KeepsetError extends Error {
4
+ constructor(message: string, options?: ErrorOptions);
5
+ }
6
+ /** Thrown when no tier of a source's resolution chain gave an HTTP answer at all: the connection failed or the host refuses the request, which a page on another origin meets for every host without CORS headers. Telling it from a source that answered with an error is what lets a caller offer the file to be supplied by hand. */
7
+ declare class UnreachableSourceError extends KeepsetError {}
8
+ /** Thrown when a category id names no category in the registry. Carries the ids that do exist, so the message says what would have been accepted. */
9
+ declare class UnknownCategoryError extends KeepsetError {
10
+ readonly categoryId: string;
11
+ readonly knownIds: readonly string[];
12
+ constructor(categoryId: string, knownIds: readonly string[]);
13
+ }
14
+ /** One reason a catalogue document failed its schema: the dotted path of the offending value and what is wrong with it. Zod's own issue objects are collapsed into these so the public error surface stays stable across Zod versions. */
15
+ interface SyntaxIssue {
16
+ readonly path: string;
17
+ readonly message: string;
18
+ }
19
+ /** Thrown when an entry, a catalogue manifest or a catalogue index fails its schema. Carries every issue found, not just the first, so one failed parse reports the whole document. */
20
+ declare class CatalogueSyntaxError extends KeepsetError {
21
+ readonly document: "entry" | "manifest" | "catalogue";
22
+ readonly issues: readonly SyntaxIssue[];
23
+ constructor(document: "entry" | "manifest" | "catalogue", issues: readonly SyntaxIssue[]);
24
+ }
25
+ /** Thrown by a parser when a file does not have the format its recipe names. `line` is 1-based, counting every line of the file, so it points at the offending line in an editor. */
26
+ declare class NativeParseError extends KeepsetError {
27
+ readonly format: string;
28
+ readonly line: number;
29
+ constructor(format: string, line: number, message: string);
30
+ }
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
+ declare class ArchiveError extends KeepsetError {}
33
+ /** Thrown when no entry in the catalogue answers to the requested id, alias or qualified name. */
34
+ declare class DatasetNotFoundError extends KeepsetError {
35
+ readonly datasetId: string;
36
+ constructor(datasetId: string);
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
+ declare class DatasetAmbiguousError extends KeepsetError {
40
+ readonly requested: string;
41
+ readonly candidateIds: readonly string[];
42
+ constructor(name: string, candidateIds: readonly string[]);
43
+ }
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. */
45
+ type RecipeStep = "recipe" | "download" | "extract" | "parse" | "crosswalk" | "validate";
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. */
47
+ declare class RecipeError extends KeepsetError {
48
+ readonly entryId: string;
49
+ readonly step: RecipeStep;
50
+ constructor(entryId: string, step: RecipeStep, message: string, options?: ErrorOptions);
51
+ }
52
+ //#endregion
53
+ export { KeepsetError as a, RecipeStep as c, UnreachableSourceError as d, DatasetNotFoundError as i, SyntaxIssue as l, CatalogueSyntaxError as n, NativeParseError as o, DatasetAmbiguousError as r, RecipeError as s, ArchiveError as t, UnknownCategoryError as u };
@@ -1,4 +1,4 @@
1
- import { G as countTarget, I as rawSnapshotUrl, J as getCollectionTarget, U as getOwn, X as getTarget, ct as ArchiveError, ft as KeepsetError, mt as RecipeError, n as getDataset, pt as NativeParseError } from "./bundled-OrF_TPDq.js";
1
+ import { G as countTarget, I as rawSnapshotUrl, J as getCollectionTarget, U as getOwn, X as getTarget, ct as ArchiveError, ft as KeepsetError, gt as UnreachableSourceError, mt as RecipeError, n as getDataset, pt as NativeParseError } from "./bundled-B_PUAjMX.js";
2
2
  import { RoundTripMismatchError, assertRoundTrip, encode } from "crossmap";
3
3
  import { z } from "zod";
4
4
  import { gunzipSync, unzipSync } from "fflate";
@@ -6068,6 +6068,140 @@ function metaOf(entry) {
6068
6068
  };
6069
6069
  }
6070
6070
  //#endregion
6071
+ //#region src/resolve.ts
6072
+ /** The availability API, which answers with the closest capture of a URL as JSON and, unlike the replay endpoints, sends CORS headers, so a browser can ask it. */
6073
+ const AVAILABILITY_URL = "https://archive.org/wayback/available";
6074
+ /** Save Page Now's endpoint: a request for `<this><url>` asks the Archive to capture the URL. */
6075
+ const SAVE_URL = "https://web.archive.org/save/";
6076
+ /** The status the availability API reports for a capture whose page answered successfully, the only kind worth reading. */
6077
+ const CAPTURED_OK = "200";
6078
+ /**
6079
+ * Requests one URL's bytes through the port.
6080
+ * @param port - The network port.
6081
+ * @param url - The URL.
6082
+ * @param signal - Aborts the request.
6083
+ * @returns The bytes.
6084
+ * @throws KeepsetError when the server does not answer successfully.
6085
+ */
6086
+ async function bytesOf(port, url, signal) {
6087
+ const response = await port(url, signal === void 0 ? {} : { signal });
6088
+ if (!response.ok) throw new KeepsetError(`${url} answered ${String(response.status)} ${response.statusText}`);
6089
+ return new Uint8Array(await response.arrayBuffer());
6090
+ }
6091
+ /**
6092
+ * The timestamp of the closest successful capture the availability API holds of a URL.
6093
+ * @param port - The network port.
6094
+ * @param url - The source URL.
6095
+ * @param signal - Aborts the request.
6096
+ * @returns The capture's timestamp, or undefined when the Archive holds none or its answer is not one this reads.
6097
+ */
6098
+ async function closestCapture(port, url, signal) {
6099
+ const response = await port(`${AVAILABILITY_URL}?${new URLSearchParams({ url }).toString()}`, signal === void 0 ? {} : { signal });
6100
+ if (!response.ok) return;
6101
+ const answer = await response.json();
6102
+ if (typeof answer !== "object" || answer === null || !("archived_snapshots" in answer)) return;
6103
+ const { archived_snapshots: snapshots } = answer;
6104
+ if (typeof snapshots !== "object" || snapshots === null || !("closest" in snapshots)) return;
6105
+ const { closest } = snapshots;
6106
+ if (typeof closest !== "object" || closest === null || !("available" in closest) || !("status" in closest) || !("timestamp" in closest)) return;
6107
+ return closest.available === true && closest.status === CAPTURED_OK && typeof closest.timestamp === "string" ? closest.timestamp : void 0;
6108
+ }
6109
+ /**
6110
+ * Resolves a source's bytes through the chain: its pinned snapshot, the closest capture the Archive names, then (for a live source) the live URL.
6111
+ * @param source - The entry's source.
6112
+ * @param options - The network port and the abort signal.
6113
+ * @returns The bytes with the URL and tier they came from.
6114
+ * @throws UnreachableSourceError when every tier that was tried failed without an HTTP answer, and KeepsetError otherwise, either naming every tier that was tried and why it gave nothing, when none gave the bytes; the abort's own reason when the signal aborts.
6115
+ */
6116
+ async function resolveSource(source, options) {
6117
+ const { port, signal } = options;
6118
+ const failures = [];
6119
+ const outcome = { answered: false };
6120
+ const fail = (tier, error) => {
6121
+ outcome.answered ||= !(error instanceof TypeError);
6122
+ failures.push(`${tier}: ${error instanceof Error ? error.message : String(error)}`);
6123
+ };
6124
+ const tryUrl = async (url, tier) => {
6125
+ try {
6126
+ return {
6127
+ bytes: await bytesOf(port, url, signal),
6128
+ url,
6129
+ tier
6130
+ };
6131
+ } catch (error) {
6132
+ if (signal?.aborted === true) throw error;
6133
+ fail(tier, error);
6134
+ return;
6135
+ }
6136
+ };
6137
+ if (source.snapshot !== void 0) {
6138
+ const pinned = await tryUrl(rawSnapshotUrl(source.snapshot.timestamp, source.url), "pinned snapshot");
6139
+ if (pinned !== void 0) return pinned;
6140
+ }
6141
+ let closest;
6142
+ try {
6143
+ closest = await closestCapture(port, source.url, signal);
6144
+ } catch (error) {
6145
+ if (signal?.aborted === true) throw error;
6146
+ fail("closest snapshot", error);
6147
+ }
6148
+ if (closest !== void 0 && closest !== source.snapshot?.timestamp) {
6149
+ const captured = await tryUrl(rawSnapshotUrl(closest, source.url), "closest snapshot");
6150
+ if (captured !== void 0) return captured;
6151
+ }
6152
+ if (source.status === "live") {
6153
+ const live = await tryUrl(source.url, "live source");
6154
+ if (live !== void 0) return live;
6155
+ }
6156
+ const message = `${source.url} could not be read from any source: ${failures.length === 0 ? "no snapshot is pinned or captured, and the source is dead" : failures.join("; ")}`;
6157
+ throw failures.length > 0 && !outcome.answered ? new UnreachableSourceError(message) : new KeepsetError(message);
6158
+ }
6159
+ /**
6160
+ * The Save Page Now request that would capture a source a fetch read live, so the next fetcher starts from the Archive: named only when the URL the bytes came from is the live source's own, which means the pinned snapshot and the Archive's closest capture gave nothing.
6161
+ * @param download - What a fetch recorded of one download: the entry's source and the URL requested.
6162
+ * @returns The capture request's URL, or undefined when the bytes came from a snapshot or the source is dead.
6163
+ */
6164
+ function captureRequestFor(download) {
6165
+ return download.source.status === "live" && download.fetchedUrl === download.source.url ? `${SAVE_URL}${download.source.url}` : void 0;
6166
+ }
6167
+ /**
6168
+ * The capture requests a whole fetch leaves to make: one per download the fetch read live, in the order they were read, each named once.
6169
+ * @param provenance - What the fetch recorded.
6170
+ * @returns The capture requests' URLs, none when every download came from a snapshot.
6171
+ */
6172
+ function captureRequestsFor(provenance) {
6173
+ const downloads = "files" in provenance ? provenance.files : [provenance];
6174
+ return [...new Set(downloads.flatMap((download) => captureRequestFor(download) ?? []))];
6175
+ }
6176
+ /** How long a capture request is held open before the client lets go of it: Save Page Now goes on capturing after the client disconnects (a request dropped after four seconds still left a capture, checked live), so a fetch never waits for the capture itself. */
6177
+ const CAPTURE_HAND_OFF_MILLISECONDS = 5e3;
6178
+ /**
6179
+ * Asks the Archive to capture a URL by sending a Save Page Now request and letting go of it after `CAPTURE_HAND_OFF_MILLISECONDS`, which is how the request is made, not a failure.
6180
+ * @param saveUrl - A request URL from `captureRequestFor`.
6181
+ * @param send - The network port; a browser's sends it without reading the answer.
6182
+ * @param signal - Aborts the request.
6183
+ * @throws The network failure when the request cannot be sent at all; the abort's own reason when the signal aborts.
6184
+ */
6185
+ async function requestCapture(saveUrl, send, signal) {
6186
+ const handOff = new AbortController();
6187
+ const timer = setTimeout(() => {
6188
+ handOff.abort();
6189
+ }, CAPTURE_HAND_OFF_MILLISECONDS);
6190
+ const abort = () => {
6191
+ handOff.abort(signal?.reason);
6192
+ };
6193
+ signal?.addEventListener("abort", abort, { once: true });
6194
+ try {
6195
+ await send(saveUrl, { signal: handOff.signal });
6196
+ } catch (error) {
6197
+ if (signal?.aborted === true) throw signal.reason;
6198
+ if (!handOff.signal.aborted) throw error;
6199
+ } finally {
6200
+ clearTimeout(timer);
6201
+ signal?.removeEventListener("abort", abort);
6202
+ }
6203
+ }
6204
+ //#endregion
6071
6205
  //#region src/fetch.ts
6072
6206
  /**
6073
6207
  * The URL a recipe downloads a source from. A dead source is fetched from its pinned snapshot in the Wayback Machine's `id_` form, which serves the archived bytes as they were captured rather than wrapped in the archive's page chrome.
@@ -6090,19 +6224,6 @@ function withId(document, id) {
6090
6224
  } : document;
6091
6225
  }
6092
6226
  /**
6093
- * Downloads one URL's bytes through the network port.
6094
- * @param port - The network port.
6095
- * @param url - The URL.
6096
- * @param signal - Aborts the download.
6097
- * @returns The bytes.
6098
- * @throws KeepsetError when the server does not answer successfully.
6099
- */
6100
- async function downloadBytes(port, url, signal) {
6101
- const response = await port(url, signal === void 0 ? {} : { signal });
6102
- if (!response.ok) throw new KeepsetError(`${url} answered ${String(response.status)} ${response.statusText}`);
6103
- return new Uint8Array(await response.arrayBuffer());
6104
- }
6105
- /**
6106
6227
  * The record of one download: the source, the URL requested and a hash of exactly the bytes that arrived.
6107
6228
  * @param source - The entry's source.
6108
6229
  * @param fetchedUrl - The URL requested.
@@ -6199,8 +6320,10 @@ async function runFiles(dataset, recipe, options) {
6199
6320
  if (file === void 0) return [];
6200
6321
  const source = entry.sources[file.source];
6201
6322
  if (source === void 0) throw new RecipeError(entry.id, "recipe", `file ${file.path} names source ${String(file.source)}, which the entry does not have`);
6202
- const fetchedUrl = sourceUrl(source);
6203
- const bytes = await step(entry.id, "download", async () => downloadBytes(port, fetchedUrl, signal));
6323
+ const { bytes, url: fetchedUrl } = await step(entry.id, "download", async () => resolveSource(source, {
6324
+ port,
6325
+ ...signal === void 0 ? {} : { signal }
6326
+ }));
6204
6327
  const documents = extractAndParse(entry.id, () => instancesOf(bytes, file.archive, recipe.parser, file.path));
6205
6328
  return [{
6206
6329
  documents,
@@ -6245,9 +6368,14 @@ async function runToNative(dataset, options) {
6245
6368
  if (recipe.stream === true) throw new RecipeError(entry.id, "recipe", "the table is too large to hold as one document, so its recipe streams: read it with streamDataset, which hands its nodes on a page at a time");
6246
6369
  const source = entry.sources[recipe.source];
6247
6370
  if (source === void 0) throw new RecipeError(entry.id, "recipe", `the recipe names source ${String(recipe.source)}, which the entry does not have`);
6248
- const fetchedUrl = sourceUrl(source);
6249
6371
  const retrievedAt = now().toISOString();
6250
- const bytes = await step(entry.id, "download", async () => recipe.paging === void 0 ? downloadBytes(fetchPort, fetchedUrl, signal) : downloadPaged(fetchedUrl, recipe.paging, fetchPort, signal));
6372
+ const { bytes, url: fetchedUrl } = await step(entry.id, "download", async () => recipe.paging === void 0 ? resolveSource(source, {
6373
+ port: fetchPort,
6374
+ ...signal === void 0 ? {} : { signal }
6375
+ }) : {
6376
+ bytes: await downloadPaged(sourceUrl(source), recipe.paging, fetchPort, signal),
6377
+ url: sourceUrl(source)
6378
+ });
6251
6379
  const provenanceOf = async (extra) => ({
6252
6380
  entryId: entry.id,
6253
6381
  catalogue: dataset.catalogue,
@@ -6381,4 +6509,4 @@ async function roundTripEntry(dataset, options) {
6381
6509
  };
6382
6510
  }
6383
6511
  //#endregion
6384
- export { metaOf as a, step as c, TableReader as d, roundTripEntry as i, csvPages as l, fetchDataset as n, sourceRecord as o, fetchEntry as r, sourceUrl as s, downloadUrl as t, PieceDecoder as u };
6512
+ export { captureRequestsFor as a, sourceRecord as c, csvPages as d, PieceDecoder as f, roundTripEntry as i, sourceUrl as l, fetchDataset as n, requestCapture as o, TableReader as p, fetchEntry as r, metaOf as s, downloadUrl as t, step as u };
package/dist/index.d.ts CHANGED
@@ -1,55 +1,6 @@
1
+ import { a as KeepsetError, c as RecipeStep, d as UnreachableSourceError, i as DatasetNotFoundError, l as SyntaxIssue, n as CatalogueSyntaxError, o as NativeParseError, r as DatasetAmbiguousError, s as RecipeError, t as ArchiveError, u as UnknownCategoryError } from "./errors-DkaEOcM6.js";
1
2
  import { $ as ArchiveSchema, A as GraphEdge, At as SourceRecipeSchema, B as DatasetQuery, C as TasksV1, Ct as Recipe, D as collectionOf, Dt as SnapshotSchema, E as Instance, Et as Snapshot, F as GraphV1Schema, Ft as readsCollection, G as Manifest, H as createCatalogue, I as Catalogue, It as waybackUrl, J as parseManifest, K as ManifestSchema, L as CatalogueIndex, M as GraphNode, Mt as SubjectSchema, N as GraphNodeSchema, Nt as WaybackTimestampSchema, O as JsonScalar, Ot as Source, P as GraphV1, Pt as parseEntry, Q as ArchiveMemberSchema, R as CatalogueIndexSchema, S as TasksMetaSchema, St as RESERVED_META_KEYS, T as Collection, Tt as RelativePathSchema, U as Lineage, V as NamespaceNode, W as LineageSchema, X as Archive, Y as AliasSchema, Z as ArchiveMember, _ as isStreamable, _t as LicenceSchema, a as CategoryTargets, at as CollectionFileSchema, b as Task, bt as Parser, c as StreamableId, ct as CrosswalkReferenceSchema, d as countTarget, dt as EntrySchema, et as Citation, f as countedKeys, ft as FilesRecipe, g as getTarget, gt as Licence, h as getStreamedShape, ht as IdSchema, i as CategoryTarget, it as CollectionFile, j as GraphEdgeSchema, jt as SourceSchema, k as JsonScalarSchema, kt as SourceRecipe, l as StreamedNodes, lt as DocumentArchive, m as getCollectionTarget, mt as HttpUrlSchema, n as CategoryId, nt as CollectionArchive, o as CollectionTarget, ot as ColumnNameSchema, p as getCategory, pt as FilesRecipeSchema, q as SemVerSchema, r as CategoryIdSchema, rt as CollectionArchiveSchema, s as CountedKey, st as CrosswalkReference, t as Category, tt as CitationSchema, u as StreamedShape, ut as Entry, v as kindOf, vt as Namespace, w as TasksV1Schema, wt as RecipeSchema, x as TaskSchema, xt as ParserSchema, y as listCategories, yt as NamespaceSchema, z as Dataset } from "./categories-BG8lRjy8.js";
2
3
  import { Crosswalk } from "crossmap";
3
- //#region src/errors.d.ts
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. */
5
- export declare class KeepsetError extends Error {
6
- constructor(message: string, options?: ErrorOptions);
7
- }
8
- /** Thrown when a category id names no category in the registry. Carries the ids that do exist, so the message says what would have been accepted. */
9
- export declare class UnknownCategoryError extends KeepsetError {
10
- readonly categoryId: string;
11
- readonly knownIds: readonly string[];
12
- constructor(categoryId: string, knownIds: readonly string[]);
13
- }
14
- /** One reason a catalogue document failed its schema: the dotted path of the offending value and what is wrong with it. Zod's own issue objects are collapsed into these so the public error surface stays stable across Zod versions. */
15
- interface SyntaxIssue {
16
- readonly path: string;
17
- readonly message: string;
18
- }
19
- /** Thrown when an entry, a catalogue manifest or a catalogue index fails its schema. Carries every issue found, not just the first, so one failed parse reports the whole document. */
20
- export declare class CatalogueSyntaxError extends KeepsetError {
21
- readonly document: "entry" | "manifest" | "catalogue";
22
- readonly issues: readonly SyntaxIssue[];
23
- constructor(document: "entry" | "manifest" | "catalogue", issues: readonly SyntaxIssue[]);
24
- }
25
- /** Thrown by a parser when a file does not have the format its recipe names. `line` is 1-based, counting every line of the file, so it points at the offending line in an editor. */
26
- export declare class NativeParseError extends KeepsetError {
27
- readonly format: string;
28
- readonly line: number;
29
- constructor(format: string, line: number, message: string);
30
- }
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
- export declare class ArchiveError extends KeepsetError {}
33
- /** Thrown when no entry in the catalogue answers to the requested id, alias or qualified name. */
34
- export declare class DatasetNotFoundError extends KeepsetError {
35
- readonly datasetId: string;
36
- constructor(datasetId: string);
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
- }
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. */
45
- type RecipeStep = "recipe" | "download" | "extract" | "parse" | "crosswalk" | "validate";
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. */
47
- export declare class RecipeError extends KeepsetError {
48
- readonly entryId: string;
49
- readonly step: RecipeStep;
50
- constructor(entryId: string, step: RecipeStep, message: string, options?: ErrorOptions);
51
- }
52
- //#endregion
53
4
  //#region src/bundled.d.ts
54
5
  /**
55
6
  * Lists the datasets in the bundled catalogue that match a query. Browser-safe: a pure read over the index bundled with the package.
@@ -117,4 +68,4 @@ export declare function serialise(doc: Entry | Manifest | Crosswalk): string;
117
68
  */
118
69
  export declare function validateDataset(dataset: Dataset): SyntaxIssue[];
119
70
  //#endregion
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 CollectionFile, CollectionFileSchema, type CollectionTarget, ColumnNameSchema, type CountedKey, type CrosswalkReference, CrosswalkReferenceSchema, type Dataset, type DatasetQuery, type DocumentArchive, type Entry, type EntryNames, EntrySchema, type FilesRecipe, FilesRecipeSchema, 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 Parser, ParserSchema, RESERVED_META_KEYS, type Recipe, RecipeSchema, type RecipeStep, RelativePathSchema, type SegmentAliases, SemVerSchema, type Snapshot, SnapshotSchema, type Source, type SourceRecipe, SourceRecipeSchema, SourceSchema, type StreamableId, type StreamedNodes, type StreamedShape, SubjectSchema, type SyntaxIssue, type Task, TaskSchema, TasksMetaSchema, type TasksV1, TasksV1Schema, WaybackTimestampSchema, collectionOf, countTarget, countedKeys, createCatalogue, getCategory, getCollectionTarget, getStreamedShape, getTarget, isStreamable, kindOf, listCategories, parseEntry, parseManifest, readsCollection, waybackUrl };
71
+ export { AliasSchema, type Archive, ArchiveError, type ArchiveMember, ArchiveMemberSchema, ArchiveSchema, type Catalogue, type CatalogueIndex, CatalogueIndexSchema, CatalogueSyntaxError, type Category, type CategoryId, CategoryIdSchema, type CategoryTarget, type CategoryTargets, type Citation, CitationSchema, type Collection, type CollectionArchive, CollectionArchiveSchema, type CollectionFile, CollectionFileSchema, type CollectionTarget, ColumnNameSchema, type CountedKey, type CrosswalkReference, CrosswalkReferenceSchema, type Dataset, DatasetAmbiguousError, DatasetNotFoundError, type DatasetQuery, type DocumentArchive, type Entry, type EntryNames, EntrySchema, type FilesRecipe, FilesRecipeSchema, type GraphEdge, GraphEdgeSchema, type GraphNode, GraphNodeSchema, type GraphV1, GraphV1Schema, HttpUrlSchema, IdSchema, type Instance, type JsonScalar, JsonScalarSchema, KeepsetError, type Licence, LicenceSchema, type Lineage, LineageSchema, type Manifest, ManifestSchema, type Namespace, type NamespaceNode, NamespaceSchema, NativeParseError, type Parser, ParserSchema, RESERVED_META_KEYS, type Recipe, RecipeError, RecipeSchema, type RecipeStep, RelativePathSchema, type SegmentAliases, SemVerSchema, type Snapshot, SnapshotSchema, type Source, type SourceRecipe, SourceRecipeSchema, SourceSchema, type StreamableId, type StreamedNodes, type StreamedShape, SubjectSchema, type SyntaxIssue, type Task, TaskSchema, TasksMetaSchema, type TasksV1, TasksV1Schema, UnknownCategoryError, UnreachableSourceError, WaybackTimestampSchema, collectionOf, countTarget, countedKeys, createCatalogue, getCategory, getCollectionTarget, getStreamedShape, getTarget, isStreamable, kindOf, listCategories, parseEntry, parseManifest, readsCollection, waybackUrl };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as listCategories, A as SnapshotSchema, B as NAME_SEPARATOR, C as IdSchema, D as RESERVED_META_KEYS, E as ParserSchema, F as parseEntry, G as countTarget, H as namesOf, J as getCollectionTarget, K as countedKeys, L as readsCollection, M as SourceSchema, N as SubjectSchema, O as RecipeSchema, P as WaybackTimestampSchema, Q as kindOf, R as toIssues, S as HttpUrlSchema, T as NamespaceSchema, V as groupsOf, W as CategoryIdSchema, X as getTarget, Y as getStreamedShape, Z as isStreamable, _ as CollectionFileSchema, a as listNamespaces, at as GraphNodeSchema, b as EntrySchema, c as LineageSchema, ct as ArchiveError, d as parseManifest, dt as DatasetNotFoundError, et as TaskSchema, f as AliasSchema, ft as KeepsetError, g as CollectionArchiveSchema, h as CitationSchema, ht as UnknownCategoryError, i as listDatasets, it as GraphEdgeSchema, j as SourceRecipeSchema, k as RelativePathSchema, l as ManifestSchema, lt as CatalogueSyntaxError, m as ArchiveSchema, mt as RecipeError, n as getDataset, nt as TasksV1Schema, o as CatalogueIndexSchema, ot as GraphV1Schema, p as ArchiveMemberSchema, pt as NativeParseError, q as getCategory, r as getManifest, rt as collectionOf, s as createCatalogue, st as JsonScalarSchema, tt as TasksMetaSchema, u as SemVerSchema, ut as DatasetAmbiguousError, v as ColumnNameSchema, w as LicenceSchema, x as FilesRecipeSchema, y as CrosswalkReferenceSchema, z as waybackUrl } from "./bundled-OrF_TPDq.js";
1
+ import { $ as listCategories, A as SnapshotSchema, B as NAME_SEPARATOR, C as IdSchema, D as RESERVED_META_KEYS, E as ParserSchema, F as parseEntry, G as countTarget, H as namesOf, J as getCollectionTarget, K as countedKeys, L as readsCollection, M as SourceSchema, N as SubjectSchema, O as RecipeSchema, P as WaybackTimestampSchema, Q as kindOf, R as toIssues, S as HttpUrlSchema, T as NamespaceSchema, V as groupsOf, W as CategoryIdSchema, X as getTarget, Y as getStreamedShape, Z as isStreamable, _ as CollectionFileSchema, a as listNamespaces, at as GraphNodeSchema, b as EntrySchema, c as LineageSchema, ct as ArchiveError, d as parseManifest, dt as DatasetNotFoundError, et as TaskSchema, f as AliasSchema, ft as KeepsetError, g as CollectionArchiveSchema, gt as UnreachableSourceError, h as CitationSchema, ht as UnknownCategoryError, i as listDatasets, it as GraphEdgeSchema, j as SourceRecipeSchema, k as RelativePathSchema, l as ManifestSchema, lt as CatalogueSyntaxError, m as ArchiveSchema, mt as RecipeError, n as getDataset, nt as TasksV1Schema, o as CatalogueIndexSchema, ot as GraphV1Schema, p as ArchiveMemberSchema, pt as NativeParseError, q as getCategory, r as getManifest, rt as collectionOf, s as createCatalogue, st as JsonScalarSchema, tt as TasksMetaSchema, u as SemVerSchema, ut as DatasetAmbiguousError, v as ColumnNameSchema, w as LicenceSchema, x as FilesRecipeSchema, y as CrosswalkReferenceSchema, z as waybackUrl } from "./bundled-B_PUAjMX.js";
2
2
  import { validateCrosswalk } from "crossmap";
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, CollectionFileSchema, ColumnNameSchema, CrosswalkReferenceSchema, DatasetAmbiguousError, DatasetNotFoundError, EntrySchema, FilesRecipeSchema, GraphEdgeSchema, GraphNodeSchema, GraphV1Schema, HttpUrlSchema, IdSchema, JsonScalarSchema, KeepsetError, LicenceSchema, LineageSchema, ManifestSchema, NAME_SEPARATOR, NamespaceSchema, NativeParseError, ParserSchema, RESERVED_META_KEYS, RecipeError, RecipeSchema, RelativePathSchema, SemVerSchema, SnapshotSchema, SourceRecipeSchema, SourceSchema, SubjectSchema, TaskSchema, TasksMetaSchema, TasksV1Schema, UnknownCategoryError, WaybackTimestampSchema, collectionOf, countTarget, countedKeys, createCatalogue, getCategory, getCollectionTarget, getDataset, getManifest, getStreamedShape, getTarget, groupsOf, isStreamable, kindOf, listCategories, listDatasets, listNamespaces, namesOf, parseEntry, parseManifest, readsCollection, serialise, validateDataset, waybackUrl };
60
+ export { AliasSchema, ArchiveError, ArchiveMemberSchema, ArchiveSchema, CatalogueIndexSchema, CatalogueSyntaxError, CategoryIdSchema, CitationSchema, CollectionArchiveSchema, CollectionFileSchema, ColumnNameSchema, CrosswalkReferenceSchema, DatasetAmbiguousError, DatasetNotFoundError, EntrySchema, FilesRecipeSchema, GraphEdgeSchema, GraphNodeSchema, GraphV1Schema, HttpUrlSchema, IdSchema, JsonScalarSchema, KeepsetError, LicenceSchema, LineageSchema, ManifestSchema, NAME_SEPARATOR, NamespaceSchema, NativeParseError, ParserSchema, RESERVED_META_KEYS, RecipeError, RecipeSchema, RelativePathSchema, SemVerSchema, SnapshotSchema, SourceRecipeSchema, SourceSchema, SubjectSchema, TaskSchema, TasksMetaSchema, TasksV1Schema, UnknownCategoryError, UnreachableSourceError, WaybackTimestampSchema, collectionOf, countTarget, countedKeys, createCatalogue, getCategory, getCollectionTarget, getDataset, getManifest, getStreamedShape, getTarget, groupsOf, isStreamable, kindOf, listCategories, listDatasets, listNamespaces, namesOf, parseEntry, parseManifest, readsCollection, serialise, validateDataset, waybackUrl };
@@ -1,5 +1,5 @@
1
1
  import { O as JsonScalar, c as StreamableId, l as StreamedNodes, z as Dataset } from "../categories-BG8lRjy8.js";
2
- import { a as FetchPort, c as Provenance, d as fetchDataset$1, f as fetchEntry$1, i as FetchOptions, l as RoundTripReport, n as Download, o as FetchedDataset, p as roundTripEntry$1, r as DownloadProvenance, s as FilesProvenance, t as DigestPort, u as downloadUrl } from "../fetch-HjZj2roj.js";
2
+ import { a as FetchOptions, c as FilesProvenance, d as downloadUrl, f as fetchDataset$1, i as DownloadProvenance, l as Provenance, m as roundTripEntry$1, n as DigestPort, o as FetchPort, p as fetchEntry$1, r as Download, s as FetchedDataset, t as captureRequestsFor, u as RoundTripReport } from "../resolve-B1F1vxr2.js";
3
3
  import { Crosswalk } from "crossmap";
4
4
  //#region src/node/stream-dataset.d.ts
5
5
  /** Where a streamed result goes: the meta once, before any node, then the nodes a page at a time, each already checked against the category's node shape and for an id no earlier node had. A sink that returns a promise is awaited before the next page is read, so a slow sink holds the stream back rather than letting pages pile up. */
@@ -88,5 +88,11 @@ export declare function roundTripDataset(id: string, options?: NodeFetchOptions)
88
88
  export declare function streamDataset(id: string, sink: NodeSink, options?: NodeFetchOptions): Promise<StreamedDataset>;
89
89
  /** Streams a dataset whose table is too large to hold as one document, a page at a time, as `streamTable` does. */
90
90
  export declare function streamEntry(dataset: Dataset, sink: NodeSink, options?: NodeFetchOptions): Promise<StreamedDataset>;
91
+ /**
92
+ * Asks the Archive to capture a URL a fetch read live; see `../resolve`'s `requestCapture`. Node's own `fetch` sends it.
93
+ * @param saveUrl - A request URL from `captureRequestsFor`.
94
+ * @param signal - Aborts the request.
95
+ */
96
+ export declare function requestCapture(saveUrl: string, signal?: AbortSignal): Promise<void>;
91
97
  //#endregion
92
- export { type DigestPort, type Download, type DownloadInit, type DownloadProvenance, type FetchOptions, type FetchPort, type FetchedDataset, type FilesProvenance, type NodeSink, type Provenance, type RoundTripReport, type StreamedDataset, type StreamedNode, downloadUrl };
98
+ export { type DigestPort, type Download, type DownloadInit, type DownloadProvenance, type FetchOptions, type FetchPort, type FetchedDataset, type FilesProvenance, type NodeSink, type Provenance, type RoundTripReport, type StreamedDataset, type StreamedNode, captureRequestsFor, downloadUrl };
@@ -1,5 +1,5 @@
1
- import { Y as getStreamedShape, Z as isStreamable, ft as KeepsetError, mt as RecipeError, n as getDataset } from "../bundled-OrF_TPDq.js";
2
- import { a as metaOf, c as step, d as TableReader, i as roundTripEntry$1, l as csvPages, n as fetchDataset$1, o as sourceRecord, r as fetchEntry$1, s as sourceUrl, t as downloadUrl, u as PieceDecoder } from "../fetch-A4VG2QuN.js";
1
+ import { Y as getStreamedShape, Z as isStreamable, ft as KeepsetError, mt as RecipeError, n as getDataset } from "../bundled-B_PUAjMX.js";
2
+ import { a as captureRequestsFor, c as sourceRecord, d as csvPages, f as PieceDecoder, i as roundTripEntry$1, l as sourceUrl, n as fetchDataset$1, o as requestCapture$1, p as TableReader, r as fetchEntry$1, s as metaOf, t as downloadUrl, u as step } from "../fetch-D9CizpRF.js";
3
3
  import { RoundTripMismatchError, assertRoundTrip, encode } from "crossmap";
4
4
  import { createHash } from "node:crypto";
5
5
  import { request } from "node:http";
@@ -540,5 +540,13 @@ async function streamDataset(id, sink, options = {}) {
540
540
  async function streamEntry(dataset, sink, options = {}) {
541
541
  return streamTable(dataset, sink, defaults(options));
542
542
  }
543
+ /**
544
+ * Asks the Archive to capture a URL a fetch read live; see `../resolve`'s `requestCapture`. Node's own `fetch` sends it.
545
+ * @param saveUrl - A request URL from `captureRequestsFor`.
546
+ * @param signal - Aborts the request.
547
+ */
548
+ async function requestCapture(saveUrl, signal) {
549
+ await requestCapture$1(saveUrl, async (url, init) => await fetch(url, init), signal);
550
+ }
543
551
  //#endregion
544
- export { DOWNLOAD_ATTEMPTS, RETRY_DELAY_MILLISECONDS, STALL_MILLISECONDS, downloadRaw, downloadUrl, fetchDataset, fetchEntry, roundTripDataset, roundTripEntry, streamDataset, streamEntry, streamTable };
552
+ export { DOWNLOAD_ATTEMPTS, RETRY_DELAY_MILLISECONDS, STALL_MILLISECONDS, captureRequestsFor, downloadRaw, downloadUrl, fetchDataset, fetchEntry, requestCapture, roundTripDataset, roundTripEntry, streamDataset, streamEntry, streamTable };
@@ -97,4 +97,12 @@ declare function fetchDataset(id: string, options: FetchOptions): Promise<Fetche
97
97
  */
98
98
  declare function roundTripEntry(dataset: Dataset, options: FetchOptions): Promise<RoundTripReport>;
99
99
  //#endregion
100
- export { FetchPort as a, Provenance as c, fetchDataset as d, fetchEntry as f, FetchOptions as i, RoundTripReport as l, Download as n, FetchedDataset as o, roundTripEntry as p, DownloadProvenance as r, FilesProvenance as s, DigestPort as t, downloadUrl as u };
100
+ //#region src/resolve.d.ts
101
+ /**
102
+ * The capture requests a whole fetch leaves to make: one per download the fetch read live, in the order they were read, each named once.
103
+ * @param provenance - What the fetch recorded.
104
+ * @returns The capture requests' URLs, none when every download came from a snapshot.
105
+ */
106
+ declare function captureRequestsFor(provenance: Provenance): readonly string[];
107
+ //#endregion
108
+ export { FetchOptions as a, FilesProvenance as c, downloadUrl as d, fetchDataset as f, DownloadProvenance as i, Provenance as l, roundTripEntry as m, DigestPort as n, FetchPort as o, fetchEntry as p, Download as r, FetchedDataset as s, captureRequestsFor as t, RoundTripReport as u };
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createWriteStream, writeFileSync } from "node:fs";
3
3
  import { KeepsetError, NAME_SEPARATOR, countTarget, getDataset, listDatasets, listNamespaces, validateDataset } from "keepset";
4
- import { fetchDataset, roundTripDataset, streamDataset } from "keepset/node";
4
+ import { captureRequestsFor, fetchDataset, requestCapture, roundTripDataset, streamDataset } from "keepset/node";
5
5
  import { parseArgs } from "node:util";
6
6
  //#region package.json
7
- var version = "0.45.0";
7
+ var version = "0.46.0";
8
8
  //#endregion
9
9
  //#region cli/run.ts
10
10
  /**
@@ -41,11 +41,16 @@ Commands:
41
41
  tab-separated
42
42
  show <dataset> [--json]
43
43
  print a dataset's metadata, recipe and crosswalk
44
- fetch <dataset> [--out <file>]
44
+ fetch <dataset> [--out <file>] [--no-archive]
45
45
  run the dataset's recipe and write the normalised result
46
46
  to <file> (default <id>.json), with its provenance beside
47
47
  it in <file without .json>.provenance.json; a table too
48
- large to hold is streamed into the file a page at a time
48
+ large to hold is streamed into the file a page at a time.
49
+ A source is read from its pinned Internet Archive snapshot
50
+ first, then the closest capture the Archive holds, then its
51
+ live URL; a source read live is also sent to the Archive to
52
+ capture, so the next fetch starts from a snapshot, unless
53
+ --no-archive is given
49
54
  validate <dataset> check the entry against the entry schema and its
50
55
  crosswalk against crossmap's validation
51
56
  roundtrip <dataset> fetch the dataset and check that decoding the encoded
@@ -77,6 +82,7 @@ function parseCommandLine(args) {
77
82
  category: { type: "string" },
78
83
  json: { type: "boolean" },
79
84
  out: { type: "string" },
85
+ "no-archive": { type: "boolean" },
80
86
  help: {
81
87
  type: "boolean",
82
88
  short: "h"
@@ -207,6 +213,22 @@ function formatIssues(issues) {
207
213
  return issues.map((issue) => `${issue.path}: ${issue.message}\n`).join("");
208
214
  }
209
215
  /**
216
+ * Asks the Internet Archive to capture each source a fetch had to read live, once the result is written so the request never delays it. Saying so on stderr is what lets a person who does not want it stop it next time; a request that cannot be sent is a warning, because the fetch itself succeeded.
217
+ * @param provenance - What the fetch recorded.
218
+ * @param library - The library calls.
219
+ * @param io - Output.
220
+ */
221
+ async function requestCaptures(provenance, library, io) {
222
+ await Promise.all(library.captureRequests(provenance).map(async (request) => {
223
+ io.writeStderr(`no snapshot was readable, so the source was read live: asking the Internet Archive to capture it (${request}); --no-archive stops this\n`);
224
+ try {
225
+ await library.requestCapture(request);
226
+ } catch (error) {
227
+ io.writeStderr(`warning: could not send the capture request: ${error instanceof Error ? error.message : String(error)}\n`);
228
+ }
229
+ }));
230
+ }
231
+ /**
210
232
  * Runs the command. A KeepsetError from the library (an unknown dataset, a failing recipe) is the command's failure to answer and becomes exit status 2 with its message; anything else is a bug and propagates.
211
233
  * @param args - The arguments after the command name.
212
234
  * @param library - The library calls.
@@ -296,6 +318,7 @@ async function run(args, library, io) {
296
318
  for (const warning of streamed.warnings) io.writeStderr(`warning: ${warning}\n`);
297
319
  const counts = [...streamed.counts].map(([key, count]) => `${key} ${String(count)}`).join(", ");
298
320
  io.writeStdout(`wrote ${out} (${counts}, streamed) and ${provenancePath(out)}\n`);
321
+ if (values["no-archive"] !== true) await requestCaptures(streamed.provenance, library, io);
299
322
  return 0;
300
323
  }
301
324
  if (command === "fetch") {
@@ -306,6 +329,7 @@ async function run(args, library, io) {
306
329
  for (const warning of fetched.warnings) io.writeStderr(`warning: ${warning}\n`);
307
330
  const counts = [...library.countTarget(fetched)].map(([key, count]) => `${key} ${String(count)}`).join(", ");
308
331
  io.writeStdout(`wrote ${out} (${counts}) and ${provenancePath(out)}\n`);
332
+ if (values["no-archive"] !== true) await requestCaptures(fetched.provenance, library, io);
309
333
  return 0;
310
334
  }
311
335
  const report = await library.roundTripDataset(id);
@@ -336,7 +360,9 @@ process.exitCode = await run(process.argv.slice(2), {
336
360
  fetchDataset: async (id) => fetchDataset(id),
337
361
  streamDataset: async (id, sink) => streamDataset(id, sink),
338
362
  roundTripDataset: async (id) => roundTripDataset(id),
339
- countTarget: (fetched) => countTarget(fetched.dataset.entry.category, fetched.data)
363
+ countTarget: (fetched) => countTarget(fetched.dataset.entry.category, fetched.data),
364
+ captureRequests: captureRequestsFor,
365
+ requestCapture: async (saveUrl) => requestCapture(saveUrl)
340
366
  }, {
341
367
  writeStdout: (text) => {
342
368
  process.stdout.write(text);
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.45.0",
4
+ "version": "0.46.0",
5
5
  "bin": {
6
6
  "keepset": "./dist-cli/keepset.mjs"
7
7
  },
@@ -1 +1 @@
1
- {"$defs":{"Crosswalk":{"$ref":"https://cdn.jsdelivr.net/npm/crossmap@0.2.0/schemas/crossmap.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","tasks/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":{"anyOf":[{"additionalProperties":false,"properties":{"archive":{"anyOf":[{"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":"bzip2","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"inner":{"anyOf":[{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["xlsx","xls","ods"],"type":"string"},"sheet":{"minLength":1,"type":"string"}},"required":["kind","sheet"],"type":"object"}]},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"inner":{"additionalProperties":false,"properties":{"kind":{"const":"xlsx","type":"string"},"sheets":{"minLength":1,"type":"string"}},"required":["kind"],"type":"object"},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"},"members":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","members"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"},"parts":{"items":{"additionalProperties":false,"properties":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]},"name":{"pattern":"^[a-z][a-z0-9]*$","type":"string"}},"required":["name","member"],"type":"object"},"minItems":1,"type":"array"}},"required":["kind","parts"],"type":"object"},{"additionalProperties":false,"properties":{"files":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]},"inner":{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"}},"required":["kind","files"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["xlsx","xls","ods"],"type":"string"},"sheet":{"minLength":1,"type":"string"}},"required":["kind","sheet"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"shapefile","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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"}]},"paging":{"oneOf":[{"additionalProperties":false,"properties":{"kind":{"const":"arcgis-query","type":"string"},"orderBy":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","type":"string"}},"required":["kind","orderBy"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"socrata-resource","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"},"select":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"minItems":1,"type":"array"}},"required":["kind","pageSize"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"ckan-datastore","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["kind","pageSize"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"openfema","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["kind","pageSize"],"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"},"keep":{"additionalProperties":false,"properties":{"column":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"values":{"items":{"minLength":1,"type":"string"},"minItems":1,"type":"array"}},"required":["column","values"],"type":"object"},"mirrored":{"const":true,"type":"boolean"},"multiplicityColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"sourceColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"targetColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"where":{"items":{"additionalProperties":false,"properties":{"column":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"equals":{"minLength":1,"type":"string"}},"required":["column","equals"],"type":"object"},"minItems":1,"type":"array"}},"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":{"delimiter":{"enum":["comma","tab","double-colon"],"type":"string"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"user-item-ratings","type":"string"},"itemType":{"enum":["movie","product"],"type":"string"},"maxRating":{"exclusiveMinimum":0,"type":"number"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","itemType","maxRating"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"konect","type":"string"},"timestamped":{"type":"boolean"},"weighted":{"type":"boolean"}},"required":["format","encoding","weighted","timestamped"],"type":"object"},{"additionalProperties":false,"properties":{"delimiter":{"enum":["tab"],"type":"string"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"user-item-counts","type":"string"},"itemType":{"enum":["artist"],"type":"string"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","itemType"],"type":"object"},{"additionalProperties":false,"properties":{"delimiter":{"enum":["tab","space"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"kg-triples","type":"string"},"header":{"enum":["none","names","count"],"type":"string"},"order":{"enum":["head-relation-tail","head-tail-relation"],"type":"string"},"quoted":{"type":"boolean"}},"required":["format","encoding","delimiter","order","header","quoted"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"hgb","type":"string"},"linkTypes":{"items":{"additionalProperties":false,"properties":{"name":{"minLength":1,"type":"string"},"source":{"minLength":1,"type":"string"},"target":{"minLength":1,"type":"string"}},"required":["name","source","target"],"type":"object"},"minItems":1,"type":"array"},"nodeTypes":{"items":{"minLength":1,"type":"string"},"minItems":1,"type":"array"}},"required":["format","encoding","nodeTypes","linkTypes"],"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"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"ucinet-dl","type":"string"},"matrix":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["format","encoding","matrix"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"gd-contest","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"witvliet-synapses","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"ogb","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"customer-points","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"solomon","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"top","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"toptw","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"tsplib","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"verolog-2019","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"vrp-rep","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"hhcrsp","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"mankowska","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"verolog-2017","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"tdc","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"delimiter":{"enum":["comma","tab","semicolon"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"csv-table","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"nullValues":{"items":{"minLength":1,"type":"string"},"type":"array"},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","idColumn","numericColumns"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"minItems":1,"type":"array"},"dateColumns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"geojson","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"}},"required":["format","encoding","idColumn","numericColumns","dateColumns","columns"],"type":"object"}]},"source":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"status":{"const":"fetchable","type":"string"},"stream":{"const":true,"type":"boolean"}},"required":["status","source","archive","parser"],"type":"object"},{"additionalProperties":false,"properties":{"files":{"items":{"additionalProperties":false,"properties":{"archive":{"anyOf":[{"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":"bzip2","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"inner":{"anyOf":[{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["xlsx","xls","ods"],"type":"string"},"sheet":{"minLength":1,"type":"string"}},"required":["kind","sheet"],"type":"object"}]},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"inner":{"additionalProperties":false,"properties":{"kind":{"const":"xlsx","type":"string"},"sheets":{"minLength":1,"type":"string"}},"required":["kind"],"type":"object"},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"},"members":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","members"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"},"parts":{"items":{"additionalProperties":false,"properties":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]},"name":{"pattern":"^[a-z][a-z0-9]*$","type":"string"}},"required":["name","member"],"type":"object"},"minItems":1,"type":"array"}},"required":["kind","parts"],"type":"object"},{"additionalProperties":false,"properties":{"files":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]},"inner":{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"}},"required":["kind","files"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["xlsx","xls","ods"],"type":"string"},"sheet":{"minLength":1,"type":"string"}},"required":["kind","sheet"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"shapefile","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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"}]},"path":{"type":"string"},"source":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["path","source","archive"],"type":"object"},"minItems":1,"type":"array"},"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"},"keep":{"additionalProperties":false,"properties":{"column":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"values":{"items":{"minLength":1,"type":"string"},"minItems":1,"type":"array"}},"required":["column","values"],"type":"object"},"mirrored":{"const":true,"type":"boolean"},"multiplicityColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"sourceColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"targetColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"where":{"items":{"additionalProperties":false,"properties":{"column":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"equals":{"minLength":1,"type":"string"}},"required":["column","equals"],"type":"object"},"minItems":1,"type":"array"}},"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":{"delimiter":{"enum":["comma","tab","double-colon"],"type":"string"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"user-item-ratings","type":"string"},"itemType":{"enum":["movie","product"],"type":"string"},"maxRating":{"exclusiveMinimum":0,"type":"number"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","itemType","maxRating"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"konect","type":"string"},"timestamped":{"type":"boolean"},"weighted":{"type":"boolean"}},"required":["format","encoding","weighted","timestamped"],"type":"object"},{"additionalProperties":false,"properties":{"delimiter":{"enum":["tab"],"type":"string"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"user-item-counts","type":"string"},"itemType":{"enum":["artist"],"type":"string"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","itemType"],"type":"object"},{"additionalProperties":false,"properties":{"delimiter":{"enum":["tab","space"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"kg-triples","type":"string"},"header":{"enum":["none","names","count"],"type":"string"},"order":{"enum":["head-relation-tail","head-tail-relation"],"type":"string"},"quoted":{"type":"boolean"}},"required":["format","encoding","delimiter","order","header","quoted"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"hgb","type":"string"},"linkTypes":{"items":{"additionalProperties":false,"properties":{"name":{"minLength":1,"type":"string"},"source":{"minLength":1,"type":"string"},"target":{"minLength":1,"type":"string"}},"required":["name","source","target"],"type":"object"},"minItems":1,"type":"array"},"nodeTypes":{"items":{"minLength":1,"type":"string"},"minItems":1,"type":"array"}},"required":["format","encoding","nodeTypes","linkTypes"],"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"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"ucinet-dl","type":"string"},"matrix":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["format","encoding","matrix"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"gd-contest","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"witvliet-synapses","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"ogb","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"customer-points","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"solomon","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"top","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"toptw","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"tsplib","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"verolog-2019","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"vrp-rep","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"hhcrsp","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"mankowska","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"verolog-2017","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"tdc","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"delimiter":{"enum":["comma","tab","semicolon"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"csv-table","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"nullValues":{"items":{"minLength":1,"type":"string"},"type":"array"},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","idColumn","numericColumns"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"minItems":1,"type":"array"},"dateColumns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"geojson","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"}},"required":["format","encoding","idColumn","numericColumns","dateColumns","columns"],"type":"object"}]},"status":{"const":"fetchable","type":"string"}},"required":["status","files","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"},"subjects":{"items":{"pattern":"^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$","type":"string"},"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.45.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/crossmap@0.2.0/schemas/crossmap.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","tasks/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":{"anyOf":[{"additionalProperties":false,"properties":{"archive":{"anyOf":[{"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":"bzip2","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"inner":{"anyOf":[{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["xlsx","xls","ods"],"type":"string"},"sheet":{"minLength":1,"type":"string"}},"required":["kind","sheet"],"type":"object"}]},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"inner":{"additionalProperties":false,"properties":{"kind":{"const":"xlsx","type":"string"},"sheets":{"minLength":1,"type":"string"}},"required":["kind"],"type":"object"},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"},"members":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","members"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"},"parts":{"items":{"additionalProperties":false,"properties":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]},"name":{"pattern":"^[a-z][a-z0-9]*$","type":"string"}},"required":["name","member"],"type":"object"},"minItems":1,"type":"array"}},"required":["kind","parts"],"type":"object"},{"additionalProperties":false,"properties":{"files":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]},"inner":{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"}},"required":["kind","files"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["xlsx","xls","ods"],"type":"string"},"sheet":{"minLength":1,"type":"string"}},"required":["kind","sheet"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"shapefile","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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"}]},"paging":{"oneOf":[{"additionalProperties":false,"properties":{"kind":{"const":"arcgis-query","type":"string"},"orderBy":{"pattern":"^[A-Za-z_][A-Za-z0-9_]*$","type":"string"}},"required":["kind","orderBy"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"socrata-resource","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"},"select":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"minItems":1,"type":"array"}},"required":["kind","pageSize"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"ckan-datastore","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["kind","pageSize"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"openfema","type":"string"},"pageSize":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["kind","pageSize"],"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"},"keep":{"additionalProperties":false,"properties":{"column":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"values":{"items":{"minLength":1,"type":"string"},"minItems":1,"type":"array"}},"required":["column","values"],"type":"object"},"mirrored":{"const":true,"type":"boolean"},"multiplicityColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"sourceColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"targetColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"where":{"items":{"additionalProperties":false,"properties":{"column":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"equals":{"minLength":1,"type":"string"}},"required":["column","equals"],"type":"object"},"minItems":1,"type":"array"}},"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":{"delimiter":{"enum":["comma","tab","double-colon"],"type":"string"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"user-item-ratings","type":"string"},"itemType":{"enum":["movie","product"],"type":"string"},"maxRating":{"exclusiveMinimum":0,"type":"number"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","itemType","maxRating"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"konect","type":"string"},"timestamped":{"type":"boolean"},"weighted":{"type":"boolean"}},"required":["format","encoding","weighted","timestamped"],"type":"object"},{"additionalProperties":false,"properties":{"delimiter":{"enum":["tab"],"type":"string"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"user-item-counts","type":"string"},"itemType":{"enum":["artist"],"type":"string"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","itemType"],"type":"object"},{"additionalProperties":false,"properties":{"delimiter":{"enum":["tab","space"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"kg-triples","type":"string"},"header":{"enum":["none","names","count"],"type":"string"},"order":{"enum":["head-relation-tail","head-tail-relation"],"type":"string"},"quoted":{"type":"boolean"}},"required":["format","encoding","delimiter","order","header","quoted"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"hgb","type":"string"},"linkTypes":{"items":{"additionalProperties":false,"properties":{"name":{"minLength":1,"type":"string"},"source":{"minLength":1,"type":"string"},"target":{"minLength":1,"type":"string"}},"required":["name","source","target"],"type":"object"},"minItems":1,"type":"array"},"nodeTypes":{"items":{"minLength":1,"type":"string"},"minItems":1,"type":"array"}},"required":["format","encoding","nodeTypes","linkTypes"],"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"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"ucinet-dl","type":"string"},"matrix":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["format","encoding","matrix"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"gd-contest","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"witvliet-synapses","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"ogb","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"customer-points","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"solomon","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"top","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"toptw","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"tsplib","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"verolog-2019","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"vrp-rep","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"hhcrsp","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"mankowska","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"verolog-2017","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"tdc","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"delimiter":{"enum":["comma","tab","semicolon"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"csv-table","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"nullValues":{"items":{"minLength":1,"type":"string"},"type":"array"},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","idColumn","numericColumns"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"minItems":1,"type":"array"},"dateColumns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"geojson","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"}},"required":["format","encoding","idColumn","numericColumns","dateColumns","columns"],"type":"object"}]},"source":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"status":{"const":"fetchable","type":"string"},"stream":{"const":true,"type":"boolean"}},"required":["status","source","archive","parser"],"type":"object"},{"additionalProperties":false,"properties":{"files":{"items":{"additionalProperties":false,"properties":{"archive":{"anyOf":[{"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":"bzip2","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"inner":{"anyOf":[{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["xlsx","xls","ods"],"type":"string"},"sheet":{"minLength":1,"type":"string"}},"required":["kind","sheet"],"type":"object"}]},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"},{"additionalProperties":false,"properties":{"inner":{"additionalProperties":false,"properties":{"kind":{"const":"xlsx","type":"string"},"sheets":{"minLength":1,"type":"string"}},"required":["kind"],"type":"object"},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"},"members":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","members"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"},"parts":{"items":{"additionalProperties":false,"properties":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]},"name":{"pattern":"^[a-z][a-z0-9]*$","type":"string"}},"required":["name","member"],"type":"object"},"minItems":1,"type":"array"}},"required":["kind","parts"],"type":"object"},{"additionalProperties":false,"properties":{"files":{"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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]},"inner":{"additionalProperties":false,"properties":{"kind":{"const":"gzip","type":"string"}},"required":["kind"],"type":"object"},"kind":{"enum":["zip","tar","tar.gz","tar.bz2"],"type":"string"}},"required":["kind","files"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"enum":["xlsx","xls","ods"],"type":"string"},"sheet":{"minLength":1,"type":"string"}},"required":["kind","sheet"],"type":"object"},{"additionalProperties":false,"properties":{"kind":{"const":"shapefile","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"},{"additionalProperties":false,"properties":{"pattern":{"minLength":1,"type":"string"}},"required":["pattern"],"type":"object"}]}},"required":["kind","member"],"type":"object"}]},"path":{"type":"string"},"source":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["path","source","archive"],"type":"object"},"minItems":1,"type":"array"},"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"},"keep":{"additionalProperties":false,"properties":{"column":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"values":{"items":{"minLength":1,"type":"string"},"minItems":1,"type":"array"}},"required":["column","values"],"type":"object"},"mirrored":{"const":true,"type":"boolean"},"multiplicityColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"sourceColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"targetColumn":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"where":{"items":{"additionalProperties":false,"properties":{"column":{"maximum":9007199254740991,"minimum":0,"type":"integer"},"equals":{"minLength":1,"type":"string"}},"required":["column","equals"],"type":"object"},"minItems":1,"type":"array"}},"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":{"delimiter":{"enum":["comma","tab","double-colon"],"type":"string"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"user-item-ratings","type":"string"},"itemType":{"enum":["movie","product"],"type":"string"},"maxRating":{"exclusiveMinimum":0,"type":"number"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","itemType","maxRating"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"konect","type":"string"},"timestamped":{"type":"boolean"},"weighted":{"type":"boolean"}},"required":["format","encoding","weighted","timestamped"],"type":"object"},{"additionalProperties":false,"properties":{"delimiter":{"enum":["tab"],"type":"string"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"user-item-counts","type":"string"},"itemType":{"enum":["artist"],"type":"string"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","itemType"],"type":"object"},{"additionalProperties":false,"properties":{"delimiter":{"enum":["tab","space"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"kg-triples","type":"string"},"header":{"enum":["none","names","count"],"type":"string"},"order":{"enum":["head-relation-tail","head-tail-relation"],"type":"string"},"quoted":{"type":"boolean"}},"required":["format","encoding","delimiter","order","header","quoted"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"hgb","type":"string"},"linkTypes":{"items":{"additionalProperties":false,"properties":{"name":{"minLength":1,"type":"string"},"source":{"minLength":1,"type":"string"},"target":{"minLength":1,"type":"string"}},"required":["name","source","target"],"type":"object"},"minItems":1,"type":"array"},"nodeTypes":{"items":{"minLength":1,"type":"string"},"minItems":1,"type":"array"}},"required":["format","encoding","nodeTypes","linkTypes"],"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"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"ucinet-dl","type":"string"},"matrix":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"required":["format","encoding","matrix"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"gd-contest","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"witvliet-synapses","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"ogb","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"customer-points","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"solomon","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"top","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"toptw","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"tsplib","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"verolog-2019","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"vrp-rep","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"const":"utf-8","type":"string"},"format":{"const":"hhcrsp","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"mankowska","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"verolog-2017","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"tdc","type":"string"}},"required":["format","encoding"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"delimiter":{"enum":["comma","tab","semicolon"],"type":"string"},"encoding":{"enum":["utf-8","latin1"],"type":"string"},"format":{"const":"csv-table","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"nullValues":{"items":{"minLength":1,"type":"string"},"type":"array"},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"},"skipLines":{"maximum":9007199254740991,"minimum":0,"type":"integer"}},"required":["format","encoding","delimiter","skipLines","idColumn","numericColumns"],"type":"object"},{"additionalProperties":false,"properties":{"columns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"minItems":1,"type":"array"},"dateColumns":{"items":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"type":"array"},"encoding":{"const":"utf-8","type":"string"},"format":{"const":"geojson","type":"string"},"idColumn":{"anyOf":[{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},{"type":"null"}]},"numericColumns":{"items":{"additionalProperties":false,"properties":{"column":{"pattern":"^[A-Za-z](?:[A-Za-z0-9_]*[A-Za-z0-9])?$","type":"string"},"factor":{"exclusiveMinimum":0,"type":"number"}},"required":["column","factor"],"type":"object"},"type":"array"}},"required":["format","encoding","idColumn","numericColumns","dateColumns","columns"],"type":"object"}]},"status":{"const":"fetchable","type":"string"}},"required":["status","files","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"},"subjects":{"items":{"pattern":"^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$","type":"string"},"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.46.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"},"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.45.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.46.0/schemas/manifest.schema.json","$ref":"#/$defs/Manifest","$schema":"https://json-schema.org/draft/2020-12/schema"}