ochre-sdk 1.0.78 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +31 -3
  2. package/dist/_virtual/_rolldown/runtime.mjs +13 -0
  3. package/dist/categories.d.mts +249 -0
  4. package/dist/categories.mjs +259 -0
  5. package/dist/constants.d.mts +14 -0
  6. package/dist/constants.mjs +18 -1
  7. package/dist/errors.d.mts +23 -0
  8. package/dist/{utilities.mjs → errors.mjs} +33 -84
  9. package/dist/fetchers/gallery.mjs +15 -51
  10. package/dist/fetchers/item-children.mjs +20 -66
  11. package/dist/fetchers/item-links.mjs +26 -79
  12. package/dist/fetchers/item-ocr-data.d.mts +2 -2
  13. package/dist/fetchers/item-ocr-data.mjs +11 -15
  14. package/dist/fetchers/item.d.mts +0 -15
  15. package/dist/fetchers/item.mjs +20 -72
  16. package/dist/fetchers/request.d.mts +70 -0
  17. package/dist/fetchers/request.mjs +100 -0
  18. package/dist/fetchers/set/items.mjs +27 -73
  19. package/dist/fetchers/set/property-values.d.mts +2 -3
  20. package/dist/fetchers/set/property-values.mjs +96 -130
  21. package/dist/fetchers/website-metadata.mjs +35 -57
  22. package/dist/fetchers/website.d.mts +2 -3
  23. package/dist/fetchers/website.mjs +22 -31
  24. package/dist/getters.d.mts +78 -148
  25. package/dist/getters.mjs +127 -208
  26. package/dist/helpers.d.mts +0 -4
  27. package/dist/helpers.mjs +19 -6
  28. package/dist/index.d.mts +8 -6
  29. package/dist/index.mjs +6 -4
  30. package/dist/ocr.d.mts +37 -0
  31. package/dist/ocr.mjs +52 -0
  32. package/dist/parsers/helpers.d.mts +21 -1
  33. package/dist/parsers/helpers.mjs +26 -6
  34. package/dist/parsers/index.d.mts +0 -8
  35. package/dist/parsers/index.mjs +118 -259
  36. package/dist/parsers/languages.d.mts +72 -0
  37. package/dist/parsers/languages.mjs +132 -0
  38. package/dist/parsers/multilingual.d.mts +49 -74
  39. package/dist/parsers/multilingual.mjs +88 -189
  40. package/dist/parsers/property-token.d.mts +34 -0
  41. package/dist/parsers/property-token.mjs +29 -0
  42. package/dist/parsers/string.d.mts +19 -0
  43. package/dist/parsers/string.mjs +45 -25
  44. package/dist/parsers/website/bounds.d.mts +10 -0
  45. package/dist/parsers/website/bounds.mjs +28 -0
  46. package/dist/parsers/website/components.d.mts +91 -0
  47. package/dist/parsers/website/components.mjs +681 -0
  48. package/dist/parsers/website/index.d.mts +0 -7
  49. package/dist/parsers/website/index.mjs +92 -1153
  50. package/dist/parsers/website/links.d.mts +36 -0
  51. package/dist/parsers/website/links.mjs +58 -0
  52. package/dist/parsers/website/messages.d.mts +24 -0
  53. package/dist/parsers/website/messages.mjs +31 -0
  54. package/dist/parsers/website/options.d.mts +6 -0
  55. package/dist/parsers/website/options.mjs +114 -0
  56. package/dist/parsers/website/properties.d.mts +12 -0
  57. package/dist/parsers/website/properties.mjs +158 -0
  58. package/dist/parsers/website/reader.d.mts +54 -4
  59. package/dist/parsers/website/reader.mjs +65 -20
  60. package/dist/parsers/website/slug.d.mts +64 -0
  61. package/dist/parsers/website/slug.mjs +82 -0
  62. package/dist/parsers/website/styles.d.mts +28 -0
  63. package/dist/parsers/website/styles.mjs +103 -0
  64. package/dist/parsers/website/walk.d.mts +68 -0
  65. package/dist/parsers/website/walk.mjs +116 -0
  66. package/dist/query.d.mts +66 -18
  67. package/dist/query.mjs +202 -48
  68. package/dist/reflection.d.mts +64 -0
  69. package/dist/reflection.mjs +79 -0
  70. package/dist/schemas.d.mts +7 -0
  71. package/dist/schemas.mjs +12 -3
  72. package/dist/types/index.d.mts +1 -31
  73. package/dist/types/utilities.d.mts +9 -0
  74. package/dist/types/utilities.mjs +1 -0
  75. package/dist/types/website.d.mts +49 -58
  76. package/dist/xml/metadata.d.mts +16 -0
  77. package/dist/xml/metadata.mjs +32 -11
  78. package/dist/xml/schemas.d.mts +5970 -3
  79. package/dist/xml/schemas.mjs +43 -45
  80. package/dist/xml/types.d.mts +13 -30
  81. package/dist/xquery.d.mts +46 -0
  82. package/dist/xquery.mjs +66 -0
  83. package/package.json +3 -3
  84. package/dist/utilities.d.mts +0 -54
@@ -1,4 +1,5 @@
1
- import { isPseudoUuid } from "../utilities.mjs";
1
+ import { readArrayProperty } from "../reflection.mjs";
2
+ import { isPseudoUuid } from "../schemas.mjs";
2
3
  import { parseDateTime } from "./dates.mjs";
3
4
  import * as v from "valibot";
4
5
  //#region src/xml/schemas.ts
@@ -47,13 +48,20 @@ const XMLRichTextEnvelope = {
47
48
  properties: v.optional(v.object({ property: v.array(v.lazy(() => XMLProperty), "XMLRichTextEnvelope: properties is array of XMLProperty") })),
48
49
  annotation: v.optional(v.string("XMLRichTextEnvelope: annotation is string and optional"))
49
50
  };
50
- const XMLString = v.lazy(() => v.object({
51
+ /**
52
+ * The entries every string-like OCHRE element carries
53
+ *
54
+ * Spread rather than re-listed by the shapes that embed a string envelope, so
55
+ * a shape cannot declare the envelope in its type and forget to validate it.
56
+ */
57
+ const XMLStringEntries = {
51
58
  payload: v.optional(v.string("XMLString: payload is string and optional")),
52
59
  rend: v.optional(v.string("XMLString: rend is string and optional")),
53
60
  whitespace: v.optional(v.string("XMLString: whitespace is string and optional")),
54
61
  ...XMLRichTextEnvelope,
55
- string: v.optional(v.array(XMLString, "XMLString: string is array of XMLString"))
56
- }, "XMLString: Shape error"));
62
+ string: v.optional(v.array(v.lazy(() => XMLString), "XMLString: string is array of XMLString"))
63
+ };
64
+ const XMLString = v.object(XMLStringEntries, "XMLString: Shape error");
57
65
  const XMLContent = v.object({ content: v.array(v.object({
58
66
  string: v.array(XMLString),
59
67
  title: v.optional(v.string("XMLContent: title is string and optional")),
@@ -110,6 +118,7 @@ const XMLMetadata = v.object({
110
118
  }, "XMLMetadata: item is object with identification, category, type, and maxLength"))
111
119
  });
112
120
  const XMLLicense = v.object({
121
+ ...XMLStringEntries,
113
122
  payload: v.string("XMLLicense: payload is string and required"),
114
123
  target: v.optional(v.pipe(v.string("XMLLicense: target is string and optional"), v.url("XMLLicense: target is not a valid URL")))
115
124
  }, "XMLLicense: Shape error");
@@ -225,10 +234,8 @@ const XMLImageMap = v.object({
225
234
  height: XMLNumber
226
235
  }, "XMLImageMap: Shape error");
227
236
  const XMLNote = v.object({
237
+ ...XMLStringEntries,
228
238
  content: v.optional(XMLContent.entries.content),
229
- payload: v.optional(v.string("XMLNote: payload is string and optional")),
230
- rend: v.optional(v.string("XMLNote: rend is string and optional")),
231
- whitespace: v.optional(v.string("XMLNote: whitespace is string and optional")),
232
239
  noteNo: XMLOptionalNumber,
233
240
  title: v.optional(v.string("XMLNote: title is string and optional")),
234
241
  date: v.optional(customDateTime("XMLNote: date is not a valid datetime")),
@@ -263,34 +270,15 @@ const XMLProperty = v.lazy(() => v.object({
263
270
  comment: v.optional(XMLContent),
264
271
  property: v.optional(v.array(XMLProperty, "XMLProperty: property is array of XMLProperty"))
265
272
  }, "XMLProperty: Shape error"));
266
- const XMLSimplifiedProperty = v.lazy(() => v.object({
267
- label: v.intersect([v.union([XMLContent, XMLString]), v.object({
268
- uuid: v.union([v.literal(""), v.pipe(v.string("XMLSimplifiedProperty: uuid is string and required"), v.check(isPseudoUuid, "XMLSimplifiedProperty: uuid is not a valid pseudo-UUID"))], "XMLSimplifiedProperty: uuid is string and required"),
269
- publicationDateTime: v.optional(customDateTime("XMLSimplifiedProperty: publicationDateTime is not a valid datetime")),
270
- relation: v.optional(XMLPropertyRelation)
271
- }, "XMLSimplifiedProperty: label is object with uuid")]),
272
- value: v.optional(v.array(v.object({
273
- ...v.partial(XMLContent).entries,
274
- i: XMLOptionalNumber,
275
- inherited: v.optional(XMLBoolean),
276
- uuid: v.optional(v.union([v.literal(""), v.pipe(v.string("XMLSimplifiedProperty: uuid is string and optional"), v.check(isPseudoUuid, "XMLSimplifiedProperty: uuid is not a valid pseudo-UUID"))])),
277
- publicationDateTime: v.optional(customDateTime("XMLSimplifiedProperty: publicationDateTime is not a valid datetime")),
278
- dataType: v.optional(v.string("XMLSimplifiedProperty: dataType is string and optional")),
279
- category: v.optional(v.string("XMLSimplifiedProperty: category is string and optional")),
280
- type: v.optional(v.string("XMLSimplifiedProperty: type is string and optional")),
281
- slug: v.optional(v.string("XMLSimplifiedProperty: slug is string and optional")),
282
- unit: v.optional(v.string("XMLSimplifiedProperty: unit is string and optional")),
283
- height: XMLOptionalNumber,
284
- width: XMLOptionalNumber,
285
- fileSize: XMLOptionalNumber,
286
- rawValue: v.optional(v.string("XMLSimplifiedProperty: rawValue is string and optional")),
287
- isUncertain: v.optional(v.literal("true", "XMLSimplifiedProperty: isUncertain is true")),
288
- href: v.optional(v.string("XMLSimplifiedProperty: href is string and optional")),
289
- payload: v.optional(v.string("XMLSimplifiedProperty: payload is string"))
290
- }), "XMLSimplifiedProperty: value is array of objects with payload")),
291
- comment: v.optional(XMLContent),
292
- property: v.optional(v.array(XMLSimplifiedProperty, "XMLSimplifiedProperty: property is array of XMLSimplifiedProperty"))
293
- }, "XMLSimplifiedProperty: Shape error"));
273
+ /**
274
+ * The raw shape of a simplified property
275
+ *
276
+ * Identical to {@link XMLProperty}: OCHRE serves one shape, and the
277
+ * "simplified" distinction is a parsing choice, not a wire-format one. The
278
+ * parser decides whether a label becomes a multilingual string or a plain
279
+ * string; nothing about the XML differs.
280
+ */
281
+ const XMLSimplifiedProperty = XMLProperty;
294
282
  const XMLBaseItem = v.object({
295
283
  uuid: v.pipe(v.string("XMLBaseItem: uuid is string and required"), v.check(isPseudoUuid, "XMLBaseItem: uuid is not a valid pseudo-UUID")),
296
284
  publicationDateTime: v.optional(customDateTime("XMLBaseItem: publicationDateTime is not a valid datetime")),
@@ -418,6 +406,7 @@ const XMLHeading = v.intersect([v.object({
418
406
  ])]);
419
407
  const XMLTree = v.object({
420
408
  ...XMLBaseItem.entries,
409
+ type: v.optional(v.string("XMLTree: type is string and optional")),
421
410
  date: v.optional(v.union([customDateTime("XMLTree: date is not a valid datetime"), XMLString])),
422
411
  links: v.optional(v.lazy(() => XMLLink)),
423
412
  reverseLinks: v.optional(v.union([
@@ -532,6 +521,7 @@ const XMLInterpretation = v.object({
532
521
  }, "XMLInterpretation: Shape error");
533
522
  const XMLConcept = v.object({
534
523
  ...XMLBaseItem.entries,
524
+ status: v.optional(v.literal("live", "XMLConcept: status is live")),
535
525
  image: v.optional(XMLImage),
536
526
  interpretations: v.optional(v.object({ interpretation: v.array(XMLInterpretation) })),
537
527
  interpretation: v.optional(v.array(XMLInterpretation)),
@@ -825,6 +815,11 @@ const XMLWebsiteTree = v.lazy(() => v.object({
825
815
  type: v.optional(v.string("XMLWebsiteTree: type is string and optional")),
826
816
  date: v.optional(v.union([customDateTime("XMLWebsiteTree: date is not a valid datetime"), XMLString])),
827
817
  links: v.optional(v.lazy(() => XMLLink)),
818
+ reverseLinks: v.optional(v.union([
819
+ v.lazy(() => XMLLink),
820
+ v.lazy(() => XMLDataItem),
821
+ v.array(v.union([v.lazy(() => XMLLink), v.lazy(() => XMLDataItem)]))
822
+ ])),
828
823
  notes: v.optional(v.object({ note: v.array(XMLNote) })),
829
824
  bibliographies: v.optional(v.object({ bibliography: v.array(v.lazy(() => XMLBibliography)) })),
830
825
  options: v.optional(XMLWebsiteOptions),
@@ -847,20 +842,23 @@ const XMLDataItem = v.union([
847
842
  v.object({ text: v.array(XMLText) }, "XMLDataItem: text is array of XMLText"),
848
843
  v.object({ set: v.array(XMLSet) }, "XMLDataItem: set is array of XMLSet")
849
844
  ], "XMLDataItem: Shape error");
850
- function hasNestedRecursiveChildren(items, getChildren) {
851
- for (const item of items) {
852
- const children = getChildren(item) ?? [];
853
- for (const child of children) if ((getChildren(child)?.length ?? 0) > 0) return true;
854
- }
845
+ /**
846
+ * Whether any child of these items has children of its own
847
+ *
848
+ * Driven by the child element's name rather than an accessor, so the check does
849
+ * not have to name a declared element type and cannot drift from one.
850
+ */
851
+ function hasNestedRecursiveChildren(items, childKey) {
852
+ for (const item of items) for (const child of readArrayProperty(item, childKey)) if (readArrayProperty(child, childKey).length > 0) return true;
855
853
  return false;
856
854
  }
857
855
  const XMLTopLevelDataItem = v.pipe(XMLDataItem, v.check((dataItem) => {
858
856
  if ("tree" in dataItem) return true;
859
- if ("bibliography" in dataItem && hasNestedRecursiveChildren(dataItem.bibliography, (item) => item.bibliography)) return false;
860
- if ("concept" in dataItem && hasNestedRecursiveChildren(dataItem.concept, (item) => item.concept)) return false;
861
- if ("spatialUnit" in dataItem && hasNestedRecursiveChildren(dataItem.spatialUnit, (item) => item.spatialUnit)) return false;
862
- if ("period" in dataItem && hasNestedRecursiveChildren(dataItem.period, (item) => item.period)) return false;
863
- if ("resource" in dataItem && hasNestedRecursiveChildren(dataItem.resource, (item) => item.resource)) return false;
857
+ if ("bibliography" in dataItem && hasNestedRecursiveChildren(dataItem.bibliography, "bibliography")) return false;
858
+ if ("concept" in dataItem && hasNestedRecursiveChildren(dataItem.concept, "concept")) return false;
859
+ if ("spatialUnit" in dataItem && hasNestedRecursiveChildren(dataItem.spatialUnit, "spatialUnit")) return false;
860
+ if ("period" in dataItem && hasNestedRecursiveChildren(dataItem.period, "period")) return false;
861
+ if ("resource" in dataItem && hasNestedRecursiveChildren(dataItem.resource, "resource")) return false;
864
862
  return true;
865
863
  }, "XMLDataItem: standalone recursive item children cannot contain nested recursive children"));
866
864
  const XMLItemLinks = v.object({
@@ -1,6 +1,7 @@
1
- //#region src/xml/types.d.ts
1
+ declare namespace types_d_exports {
2
+ export { XMLBaseItem, XMLBibliography, XMLConcept, XMLContent, XMLContext, XMLContextGroup, XMLContextItem, XMLContextValue, XMLCoordinate, XMLCoordinates, XMLCoordinatesSource, XMLData, XMLDataItem, XMLDictionaryUnit, XMLEmptyContext, XMLEvent, XMLGallery, XMLGalleryData, XMLHeading, XMLIdentification, XMLImage, XMLImageMap, XMLImageMapArea, XMLInterpretation, XMLItemCategory, XMLItemLinks, XMLItemLinksData, XMLLicense, XMLLink, XMLLinkedBaseItem, XMLLinkedBibliography, XMLLinkedConcept, XMLLinkedPeriod, XMLLinkedPerson, XMLLinkedPropertyValue, XMLLinkedPropertyVariable, XMLLinkedResource, XMLLinkedSet, XMLLinkedSpatialUnit, XMLLinkedText, XMLLinkedTree, XMLMetadata, XMLNote, XMLObservation, XMLPeriod, XMLPerson, XMLProperty, XMLPropertyRelation, XMLPropertyValue, XMLPropertyVariable, XMLRecursiveItemCategory, XMLResource, XMLRichTextEnvelope, XMLSection, XMLSet, XMLSetItems, XMLSetItemsData, XMLSimplifiedProperty, XMLSpatialUnit, XMLString, XMLText, XMLTree, XMLWebsiteContext, XMLWebsiteContextItem, XMLWebsiteContextLevel, XMLWebsiteData, XMLWebsiteFilterContext, XMLWebsiteFilterContextItem, XMLWebsiteOptions, XMLWebsiteProperties, XMLWebsiteResource, XMLWebsiteResourceGroup, XMLWebsiteResourceItem, XMLWebsiteScope, XMLWebsiteSegment, XMLWebsiteStyle, XMLWebsiteTree };
3
+ }
2
4
  export type XMLItemCategory = "tree" | "bibliography" | "spatialUnit" | "concept" | "period" | "person" | "propertyVariable" | "variable" | "propertyValue" | "value" | "text" | "resource" | "set";
3
- export type XMLHeadingItemCategory = Exclude<XMLItemCategory, "tree" | "bibliography" | "spatialUnit" | "concept" | "period">;
4
5
  export type XMLRecursiveItemCategory = Exclude<XMLItemCategory, "tree" | "person" | "propertyVariable" | "propertyValue" | "set">;
5
6
  /**
6
7
  * Rich text envelope shared by `<string>` and `<content>` nodes, carrying the
@@ -183,6 +184,7 @@ export type XMLImageMap = {
183
184
  export type XMLNote = Partial<XMLContent> & XMLString & {
184
185
  noteNo?: number;
185
186
  title?: string;
187
+ date?: Date;
186
188
  authors?: {
187
189
  author: Array<XMLPerson>;
188
190
  };
@@ -215,33 +217,13 @@ export type XMLProperty = {
215
217
  comment?: XMLContent;
216
218
  property?: Array<XMLProperty>;
217
219
  };
218
- export type XMLSimplifiedProperty = {
219
- label: (XMLContent | XMLString) & {
220
- uuid: string;
221
- publicationDateTime?: Date;
222
- relation?: XMLPropertyRelation;
223
- };
224
- value?: Array<Partial<XMLContent> & {
225
- i?: number;
226
- inherited?: boolean;
227
- uuid?: string;
228
- publicationDateTime?: Date;
229
- dataType?: string;
230
- category?: string;
231
- type?: string;
232
- slug?: string;
233
- unit?: string;
234
- height?: number;
235
- width?: number;
236
- fileSize?: number;
237
- href?: string;
238
- rawValue?: string;
239
- isUncertain?: "true";
240
- payload?: string;
241
- }>;
242
- comment?: XMLContent;
243
- property?: Array<XMLSimplifiedProperty>;
244
- };
220
+ /**
221
+ * The raw shape of a simplified property
222
+ *
223
+ * Identical to {@link XMLProperty}: the "simplified" distinction is a parsing
224
+ * choice, not a wire-format one.
225
+ */
226
+ export type XMLSimplifiedProperty = XMLProperty;
245
227
  export type XMLBaseItem = {
246
228
  uuid: string;
247
229
  publicationDateTime?: Date;
@@ -919,4 +901,5 @@ export type XMLWebsiteData = {
919
901
  };
920
902
  };
921
903
  };
922
- //#endregion
904
+ //#endregion
905
+ export { types_d_exports };
@@ -0,0 +1,46 @@
1
+ //#region src/xquery.d.ts
2
+ /**
3
+ * Build a string literal for an XQuery string
4
+ * @param value - The string value to escape
5
+ * @returns The escaped string literal
6
+ * @internal
7
+ */
8
+ export declare function stringLiteral(value: string): string;
9
+ /**
10
+ * What a query body can ask the surrounding document for
11
+ *
12
+ * Handed to the body rather than imported by it, so a body cannot reference a
13
+ * prolog declaration the document did not emit.
14
+ */
15
+ export type OchreQueryContext = {
16
+ /**
17
+ * Wrap a node expression so supplemental nodes are omitted from it
18
+ * @param expression - The XQuery expression returning the nodes to filter
19
+ * @returns The wrapped XQuery expression
20
+ */
21
+ omitSupplemental: (expression: string) => string;
22
+ /**
23
+ * An XQuery predicate keeping only nodes that are neither supplemental
24
+ * themselves nor nested inside a supplemental node. Use it when aggregating
25
+ * over nodes instead of returning them.
26
+ */
27
+ notSupplemental: string;
28
+ };
29
+ /**
30
+ * Compile a complete XQuery document for the OCHRE API
31
+ *
32
+ * Owns the version declaration, the prolog ordering, and the
33
+ * supplemental-stripping helper. The body receives what it is allowed to call,
34
+ * so the helper cannot be invoked without having been declared, and every
35
+ * fetcher stops restating the same preamble.
36
+ * @param parameters - The document parameters
37
+ * @param parameters.declarations - Prolog declarations, emitted in order before the supplemental helper
38
+ * @param parameters.body - Builds the query body
39
+ * @returns A complete XQuery document
40
+ * @internal
41
+ */
42
+ export declare function compileOchreQuery(parameters: {
43
+ declarations?: ReadonlyArray<string>;
44
+ body: (context: OchreQueryContext) => string;
45
+ }): string;
46
+ //#endregion
@@ -0,0 +1,66 @@
1
+ //#region src/xquery.ts
2
+ /**
3
+ * Build a string literal for an XQuery string
4
+ * @param value - The string value to escape
5
+ * @returns The escaped string literal
6
+ * @internal
7
+ */
8
+ function stringLiteral(value) {
9
+ return `"${value.replaceAll("\"", "\"\"")}"`;
10
+ }
11
+ /**
12
+ * XQuery prolog declaring `local:omit-supplemental`, which drops every element
13
+ * carrying `supplemental="true"` from a node sequence, at any depth.
14
+ *
15
+ * Subtrees without a supplemental descendant are returned by reference, so
16
+ * nodes are only copied along the path leading to an omitted element. The
17
+ * lookahead walks the attribute axis (`//@supplemental`) rather than testing
18
+ * every element, which measures around three times faster on large documents.
19
+ *
20
+ * Private on purpose: it is only correct when it precedes a body that calls it,
21
+ * and {@link compileOchreQuery} is the only thing that can guarantee that.
22
+ */
23
+ const SUPPLEMENTAL_XQUERY_PROLOG = `declare function local:omit-supplemental($nodes as node()*) as node()* {
24
+ for $node in $nodes
25
+ return
26
+ if ($node instance of element())
27
+ then
28
+ if ($node/@supplemental = "true")
29
+ then ()
30
+ else if (empty($node//@supplemental[. = "true"]))
31
+ then $node
32
+ else element { node-name($node) } {
33
+ $node/@*,
34
+ local:omit-supplemental($node/node())
35
+ }
36
+ else $node
37
+ };`;
38
+ const NOT_SUPPLEMENTAL_PREDICATE = "[not(ancestor-or-self::*[@supplemental = \"true\"])]";
39
+ /**
40
+ * Compile a complete XQuery document for the OCHRE API
41
+ *
42
+ * Owns the version declaration, the prolog ordering, and the
43
+ * supplemental-stripping helper. The body receives what it is allowed to call,
44
+ * so the helper cannot be invoked without having been declared, and every
45
+ * fetcher stops restating the same preamble.
46
+ * @param parameters - The document parameters
47
+ * @param parameters.declarations - Prolog declarations, emitted in order before the supplemental helper
48
+ * @param parameters.body - Builds the query body
49
+ * @returns A complete XQuery document
50
+ * @internal
51
+ */
52
+ function compileOchreQuery(parameters) {
53
+ const { declarations = [], body } = parameters;
54
+ return `${[
55
+ "xquery version \"1.0-ml\";",
56
+ ...declarations,
57
+ SUPPLEMENTAL_XQUERY_PROLOG
58
+ ].join("\n\n")}
59
+
60
+ ${body({
61
+ omitSupplemental: (expression) => `local:omit-supplemental(${expression})`,
62
+ notSupplemental: NOT_SUPPLEMENTAL_PREDICATE
63
+ })}`;
64
+ }
65
+ //#endregion
66
+ export { compileOchreQuery, stringLiteral };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.0.78",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Node.js library for working with OCHRE (Online Cultural and Historical Research Environment) data",
@@ -66,8 +66,8 @@
66
66
  "scripts": {
67
67
  "dev": "tsdown src/index.ts --watch",
68
68
  "build": "tsdown",
69
- "lint": "knip; eslint --concurrency auto .",
70
- "lint:fix": "knip --fix; eslint --concurrency auto --fix .",
69
+ "lint": "knip && eslint --concurrency auto .",
70
+ "lint:fix": "knip --fix && eslint --concurrency auto --fix .",
71
71
  "format": "oxfmt --check",
72
72
  "format:fix": "oxfmt",
73
73
  "check-types": "tsc --noEmit",
@@ -1,54 +0,0 @@
1
- import { LanguageCodes, Property, SetItemProperty } from "./types/index.mjs";
2
- import * as v from "valibot";
3
- //#region src/utilities.d.ts
4
- type SchemaValidationIssue = v.BaseIssue<unknown>;
5
- export declare function getErrorOutput(error: unknown, fallbackMessage: string): {
6
- error: string;
7
- detailedError: string;
8
- };
9
- export declare function createSchemaValidationError(message: string, issues: ReadonlyArray<SchemaValidationIssue>): Error;
10
- /**
11
- * Validates a pseudo-UUID string
12
- * @param value - The string to validate
13
- * @returns True if the string is a valid pseudo-UUID, false otherwise
14
- * @internal
15
- */
16
- export declare function isPseudoUuid(value: string): boolean;
17
- /**
18
- * Build a string literal for an XQuery string
19
- * @param value - The string value to escape
20
- * @returns The escaped string literal
21
- */
22
- export declare function stringLiteral(value: string): string;
23
- /**
24
- * XQuery prolog declaring `local:omit-supplemental`, which drops every element
25
- * carrying `supplemental="true"` from a node sequence, at any depth.
26
- *
27
- * Subtrees without a supplemental descendant are returned by reference, so
28
- * nodes are only copied along the path leading to an omitted element. The
29
- * lookahead walks the attribute axis (`//@supplemental`) rather than testing
30
- * every element, which measures around three times faster on large documents.
31
- *
32
- * Must be declared before any query body that calls {@link omitSupplemental}.
33
- */
34
- export declare const SUPPLEMENTAL_XQUERY_PROLOG = "declare function local:omit-supplemental($nodes as node()*) as node()* {\n for $node in $nodes\n return\n if ($node instance of element())\n then\n if ($node/@supplemental = \"true\")\n then ()\n else if (empty($node//@supplemental[. = \"true\"]))\n then $node\n else element { node-name($node) } {\n $node/@*,\n local:omit-supplemental($node/node())\n }\n else $node\n};";
35
- /**
36
- * Wrap an XQuery node expression so supplemental nodes are omitted from it
37
- * @param expression - The XQuery expression returning the nodes to filter
38
- * @returns The wrapped XQuery expression
39
- */
40
- export declare function omitSupplemental(expression: string): string;
41
- /**
42
- * XQuery predicate keeping only nodes that are neither supplemental themselves
43
- * nor nested inside a supplemental node. Use it when aggregating over nodes
44
- * instead of returning them.
45
- */
46
- export declare const NOT_SUPPLEMENTAL_PREDICATE = "[not(ancestor-or-self::*[@supplemental = \"true\"])]";
47
- /**
48
- * Flatten a properties array
49
- * @param properties - The properties to flatten
50
- * @returns The flattened properties
51
- * @internal
52
- */
53
- export declare function flattenProperties<T extends LanguageCodes = LanguageCodes>(properties: ReadonlyArray<Property<T> | SetItemProperty<T>>): Array<SetItemProperty<T>>;
54
- //#endregion