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
@@ -6,14 +6,34 @@ export type FetchFunction = (input: string | URL | globalThis.Request, init?: Re
6
6
  export type FetchBaseOptions<TLanguages extends ReadonlyArray<string> | undefined = undefined> = {
7
7
  languages?: TLanguages;
8
8
  fetch?: FetchFunction;
9
+ signal?: AbortSignal;
10
+ timeoutMilliseconds?: number;
9
11
  };
10
12
  export type FetchRuntimeOptions = FetchBaseOptions<ReadonlyArray<string>>;
11
13
  export type FetchLanguages<TLanguages extends ReadonlyArray<string> | undefined> = TLanguages extends readonly [] ? ReadonlyArray<string> : TLanguages extends ReadonlyArray<string> ? TLanguages : ReadonlyArray<string>;
12
14
  export type ParserOptions<T extends ReadonlyArray<string>> = {
13
15
  languages: T;
16
+ /**
17
+ * The language the dataset declares as its default
18
+ *
19
+ * Threaded into every {@link MultilingualString} so a read with no language
20
+ * resolves to the dataset's default rather than whichever language happens to
21
+ * come first in the payload.
22
+ */
23
+ defaultLanguage?: T[number];
14
24
  };
15
25
  export declare function getParserOptions<T extends ReadonlyArray<string>>(options: ParserOptions<T>): ParserOptions<T>;
16
- export declare function cleanObject<T extends Record<string, unknown>>(object: T): Partial<T>;
26
+ /**
27
+ * Drop the keys whose value is undefined
28
+ *
29
+ * Constrained to `object` rather than `Record<string, unknown>`, which an
30
+ * interface never satisfies for want of an index signature. `Object.entries`
31
+ * cannot be typed precisely, so the one cast that costs is here rather than at
32
+ * the call site.
33
+ * @param object - The object to clean
34
+ * @returns A copy carrying only the defined keys
35
+ */
36
+ export declare function cleanObject<T extends object>(object: T): Partial<T>;
17
37
  export declare function parseLicense(availability: {
18
38
  license: XMLString & {
19
39
  target?: string;
@@ -4,11 +4,25 @@ import { parseXMLContent, parseXMLString } from "./string.mjs";
4
4
  //#region src/parsers/helpers.ts
5
5
  const FALLBACK_PARSER_OPTIONS = { languages: DEFAULT_LANGUAGES };
6
6
  function getParserOptions(options) {
7
- return { languages: options.languages };
7
+ return {
8
+ languages: options.languages,
9
+ defaultLanguage: options.defaultLanguage
10
+ };
8
11
  }
12
+ /**
13
+ * Drop the keys whose value is undefined
14
+ *
15
+ * Constrained to `object` rather than `Record<string, unknown>`, which an
16
+ * interface never satisfies for want of an index signature. `Object.entries`
17
+ * cannot be typed precisely, so the one cast that costs is here rather than at
18
+ * the call site.
19
+ * @param object - The object to clean
20
+ * @returns A copy carrying only the defined keys
21
+ */
9
22
  function cleanObject(object) {
23
+ const entries = Object.entries(object);
10
24
  const cleaned = {};
11
- for (const [key, value] of Object.entries(object)) if (value !== void 0) cleaned[key] = value;
25
+ for (const [key, value] of entries) if (value !== void 0) cleaned[key] = value;
12
26
  return cleaned;
13
27
  }
14
28
  function parseLicense(availability) {
@@ -29,16 +43,19 @@ function isXMLContent(value) {
29
43
  function multilingualFromText(text, options) {
30
44
  const content = {};
31
45
  for (const language of options.languages) content[language] = text;
32
- return MultilingualString.fromObject(content, options.languages);
46
+ return MultilingualString.fromObject(content, options.languages, { defaultLanguage: options.defaultLanguage });
33
47
  }
34
48
  function parseContentLike(value, options) {
35
49
  if (value == null) return null;
36
50
  if (typeof value === "string") return multilingualFromText(value, options);
37
51
  if (!isXMLContent(value)) return multilingualFromText(parseXMLString(value), options);
38
- return parseXMLContent(value, { languages: options.languages });
52
+ return parseXMLContent(value, {
53
+ languages: options.languages,
54
+ defaultLanguage: options.defaultLanguage
55
+ });
39
56
  }
40
57
  function parseRequiredContentLike(value, options) {
41
- return parseContentLike(value, options) ?? MultilingualString.empty(options.languages);
58
+ return parseContentLike(value, options) ?? MultilingualString.empty(options.languages, { defaultLanguage: options.defaultLanguage });
42
59
  }
43
60
  function parseContentLikeText(value, options) {
44
61
  return parseContentLike(value, options)?.getText().trim() ?? "";
@@ -46,7 +63,10 @@ function parseContentLikeText(value, options) {
46
63
  function parseStringContent(value, options = FALLBACK_PARSER_OPTIONS) {
47
64
  if (value == null) return "";
48
65
  if (typeof value === "string") return value;
49
- if (isXMLContent(value)) return parseXMLContent(value, { languages: options.languages }).getText();
66
+ if (isXMLContent(value)) return parseXMLContent(value, {
67
+ languages: options.languages,
68
+ defaultLanguage: options.defaultLanguage
69
+ }).getText();
50
70
  return parseXMLString(value).text;
51
71
  }
52
72
  //#endregion
@@ -21,14 +21,6 @@ export declare function parseBibliographyList<T extends ReadonlyArray<string>>(r
21
21
  bibliography: Array<XMLBibliography>;
22
22
  } | undefined, options: ParserOptions<T>): Array<Bibliography<T, "embedded">>;
23
23
  export declare function parsePersonList<T extends ReadonlyArray<string>>(rawPersons: Array<XMLPerson> | undefined, options: ParserOptions<T>): Array<Person<T, "embedded">>;
24
- export declare function parseMetadataLanguages(rawOchre: {
25
- metadata: XMLMetadata;
26
- languages?: string;
27
- }): Array<string>;
28
- export declare function resolveLanguages<T extends ReadonlyArray<string>>(requestedLanguages: T | undefined, metadataLanguages: Array<string>): T;
29
- export declare function resolveDefaultLanguage<T extends ReadonlyArray<string>>(rawOchre: {
30
- metadata: XMLMetadata;
31
- }, languages: T): T[number];
32
24
  export declare function parseMetadata<T extends ReadonlyArray<string>>(rawOchre: {
33
25
  uuidBelongsTo: string;
34
26
  metadata: XMLMetadata;
@@ -1,8 +1,12 @@
1
- import { DEFAULT_LANGUAGES } from "../constants.mjs";
2
- import { MultilingualString } from "./multilingual.mjs";
1
+ import { CONTEXT_CATEGORY_ALIASES, ITEM_CATEGORY_BY_ALIAS, ITEM_CATEGORY_FACTS, SET_ITEM_CATEGORIES, isHeadingItemCategory, normalizeItemCategory } from "../categories.mjs";
2
+ import { readEntries, readProperty } from "../reflection.mjs";
3
3
  import { getXMLSourceIndex } from "../xml/metadata.mjs";
4
+ import { MultilingualString } from "./multilingual.mjs";
5
+ import { readPropertyValueText } from "./property-token.mjs";
4
6
  import { parseXMLString, transformPermanentIdentificationUrl } from "./string.mjs";
5
7
  import { getParserOptions, multilingualFromText, parseContentLike, parseContentLikeText, parseLicense, parseRequiredContentLike, parseStringLike } from "./helpers.mjs";
8
+ import { parseMetadataLanguages, resolveDefaultLanguage, resolveLanguages } from "./languages.mjs";
9
+ import * as v from "valibot";
6
10
  //#region src/parsers/index.ts
7
11
  function isXMLContextGroup(context) {
8
12
  return "context" in context;
@@ -10,68 +14,82 @@ function isXMLContextGroup(context) {
10
14
  function isXMLContextItem(context) {
11
15
  return "project" in context;
12
16
  }
13
- const SET_ITEM_CATEGORIES = ["tree", ...[
14
- "bibliography",
15
- "concept",
16
- "spatialUnit",
17
- "period",
18
- "person",
19
- "propertyVariable",
20
- "propertyValue",
21
- "resource",
22
- "text",
23
- "set"
24
- ]];
25
- const HEADING_ITEM_CATEGORIES = [
26
- "person",
27
- "propertyVariable",
28
- "propertyValue",
29
- "resource",
30
- "text",
31
- "set"
32
- ];
33
- const CONTEXT_CATEGORY_MAPPINGS = [
34
- {
35
- raw: "bibliography",
36
- parsed: "bibliography"
17
+ const ITEM_CATEGORIES = {
18
+ tree: {
19
+ parseEmbedded: (item, options) => parseTree(item, {
20
+ ...options,
21
+ containedItemCategory: normalizeTreeItemCategory(options.containedItemCategory)
22
+ }),
23
+ parseSetItem: (item, options) => parseSetTree(item, options),
24
+ parseLink: (item, options) => parseTreeItemLink(item, options)
25
+ },
26
+ bibliography: {
27
+ parseEmbedded: (item, options) => parseBibliography(item, options),
28
+ parseSetItem: (item, options) => parseSetBibliography(item, options),
29
+ parseLink: (item, options) => parseBibliographyItemLink(item, options)
30
+ },
31
+ concept: {
32
+ parseEmbedded: (item, options) => parseConcept(item, options),
33
+ parseSetItem: (item, options) => parseSetConcept(item, options),
34
+ parseLink: (item, options) => parseConceptItemLink(item, options)
35
+ },
36
+ spatialUnit: {
37
+ parseEmbedded: (item, options) => parseSpatialUnit(item, options),
38
+ parseSetItem: (item, options) => parseSetSpatialUnit(item, options),
39
+ parseLink: (item, options) => parseSpatialUnitItemLink(item, options)
37
40
  },
38
- {
39
- raw: "concept",
40
- parsed: "concept"
41
+ period: {
42
+ parseEmbedded: (item, options) => parsePeriod(item, options),
43
+ parseSetItem: (item, options) => parseSetPeriod(item, options),
44
+ parseLink: (item, options) => parsePeriodItemLink(item, options)
41
45
  },
42
- {
43
- raw: "spatialUnit",
44
- parsed: "spatialUnit"
46
+ person: {
47
+ parseEmbedded: (item, options) => parsePerson(item, options),
48
+ parseSetItem: (item, options) => {
49
+ const person = item;
50
+ return withSetItemProperties(parsePerson(person, options), person.properties, options);
51
+ },
52
+ parseLink: (item, options) => parsePersonItemLink(item, options)
45
53
  },
46
- {
47
- raw: "period",
48
- parsed: "period"
54
+ propertyVariable: {
55
+ parseEmbedded: (item, options) => parsePropertyVariable(item, options),
56
+ parseSetItem: (item, options) => parsePropertyVariable(item, options),
57
+ parseLink: (item, options) => parsePropertyVariableItemLink(item, options)
49
58
  },
50
- {
51
- raw: "propertyVariable",
52
- parsed: "propertyVariable"
59
+ propertyValue: {
60
+ parseEmbedded: (item, options) => parsePropertyValue(item, options),
61
+ parseSetItem: (item, options) => {
62
+ const propertyValue = item;
63
+ return withSetItemProperties(parsePropertyValue(propertyValue, options), propertyValue.properties, options);
64
+ },
65
+ parseLink: (item, options) => parsePropertyValueItemLink(item, options)
53
66
  },
54
- {
55
- raw: "variable",
56
- parsed: "propertyVariable"
67
+ resource: {
68
+ parseEmbedded: (item, options) => parseResource(item, options),
69
+ parseSetItem: (item, options) => parseSetResource(item, options),
70
+ parseLink: (item, options) => parseResourceItemLink(item, options)
57
71
  },
58
- {
59
- raw: "propertyValue",
60
- parsed: "propertyValue"
72
+ text: {
73
+ parseEmbedded: (item, options) => parseText(item, options),
74
+ parseSetItem: (item, options) => parseText(item, options),
75
+ parseLink: (item, options) => parseTextItemLink(item, options)
61
76
  },
62
- {
63
- raw: "value",
64
- parsed: "propertyValue"
77
+ set: {
78
+ parseEmbedded: (item, options) => parseSet(item, options),
79
+ parseSetItem: (item, options) => parseSetSet(item, options),
80
+ parseLink: (item, options) => parseSetItemLink(item, options)
65
81
  },
66
- {
67
- raw: "resource",
68
- parsed: "resource"
82
+ dictionaryUnit: {
83
+ parseEmbedded: null,
84
+ parseSetItem: null,
85
+ parseLink: (item, options) => parseDictionaryUnitItemLink(item, options)
69
86
  },
70
- {
71
- raw: "text",
72
- parsed: "text"
87
+ heading: {
88
+ parseEmbedded: null,
89
+ parseSetItem: null,
90
+ parseLink: null
73
91
  }
74
- ];
92
+ };
75
93
  const PROPERTY_DATA_TYPES = [
76
94
  "string",
77
95
  "coordinate",
@@ -128,12 +146,12 @@ function parseContextNode(rawContextItem) {
128
146
  };
129
147
  const headings = rawContextItem.heading ?? [];
130
148
  for (const heading of headings) node.heading.push(parseContextItem(heading));
131
- for (const { raw, parsed } of CONTEXT_CATEGORY_MAPPINGS) {
132
- const contextValues = rawContextItem[raw] ?? [];
149
+ for (const { alias, category } of CONTEXT_CATEGORY_ALIASES) {
150
+ const contextValues = rawContextItem[alias] ?? [];
133
151
  for (const contextValue of contextValues) {
134
- const parsedItems = node[parsed] ?? [];
152
+ const parsedItems = node[category] ?? [];
135
153
  parsedItems.push(parseContextItem(contextValue));
136
- node[parsed] = parsedItems;
154
+ node[category] = parsedItems;
137
155
  }
138
156
  }
139
157
  return node;
@@ -176,7 +194,7 @@ function parseEvent(rawEvent, options) {
176
194
  location: parseEventReference(rawEvent.location, options),
177
195
  other: rawEvent.other == null ? null : {
178
196
  uuid: rawEvent.other.uuid ?? null,
179
- category: normalizeCategory(rawEvent.other.category),
197
+ category: normalizeItemCategory(rawEvent.other.category),
180
198
  label: parseRequiredContentLike(rawEvent.other, options)
181
199
  }
182
200
  };
@@ -202,44 +220,26 @@ function parseBaseItem(category, rawItem, options) {
202
220
  events
203
221
  };
204
222
  }
205
- function normalizeCategory(category) {
206
- if (category == null) return null;
207
- if (category === "variable") return "propertyVariable";
208
- if (category === "value") return "propertyValue";
209
- for (const knownCategory of SET_ITEM_CATEGORIES) if (category === knownCategory) return knownCategory;
210
- return null;
211
- }
212
- function isHeadingItemCategory(category) {
213
- return HEADING_ITEM_CATEGORIES.includes(category);
214
- }
215
223
  function pushCategory(categories, category) {
216
224
  if (!categories.includes(category)) categories.push(category);
217
225
  }
218
226
  function getHierarchyEntryCategory(key) {
219
- switch (key) {
220
- case "heading":
221
- case "tree":
222
- case "bibliography":
223
- case "concept":
224
- case "spatialUnit":
225
- case "period":
226
- case "person":
227
- case "resource":
228
- case "text":
229
- case "set":
230
- case "dictionaryUnit": return key;
231
- case "propertyVariable":
232
- case "variable": return "propertyVariable";
233
- case "propertyValue":
234
- case "value": return "propertyValue";
235
- default: return null;
236
- }
237
- }
238
- function isRecord(value) {
239
- return typeof value === "object" && value != null;
240
- }
227
+ return ITEM_CATEGORY_BY_ALIAS.get(key) ?? null;
228
+ }
229
+ /**
230
+ * A group element wrapping child resources rather than being one itself
231
+ *
232
+ * A schema rather than a hand-written predicate: `v.is` narrows to exactly what
233
+ * it checked, and a wrapper is distinguished from a resource by carrying no
234
+ * `uuid`, which the `undefined` entry states rather than leaving to a
235
+ * `!("uuid" in value)` test whose false branch means nothing in particular.
236
+ */
237
+ const resourceWrapperSchema = v.looseObject({
238
+ uuid: v.undefined(),
239
+ resource: v.array(v.unknown())
240
+ });
241
241
  function isResourceWrapper(value) {
242
- return isRecord(value) && !("uuid" in value) && Array.isArray(value.resource);
242
+ return v.is(resourceWrapperSchema, value);
243
243
  }
244
244
  function sourceOrderSort(left, right) {
245
245
  const leftIndex = getXMLSourceIndex(left.item);
@@ -249,9 +249,8 @@ function sourceOrderSort(left, right) {
249
249
  }
250
250
  function collectHierarchyEntries(hierarchy, categories) {
251
251
  const entries = [];
252
- if (hierarchy == null) return entries;
253
252
  let fallbackIndex = 0;
254
- for (const [key, values] of Object.entries(hierarchy)) {
253
+ for (const [key, values] of readEntries(hierarchy)) {
255
254
  const category = getHierarchyEntryCategory(key);
256
255
  if (category == null || !(categories == null || categories.includes(category))) continue;
257
256
  if (!Array.isArray(values)) continue;
@@ -458,8 +457,7 @@ function parsePropertyDataType(dataType) {
458
457
  function parsePropertyValueContent(value, options) {
459
458
  const dataType = parsePropertyDataType(value.dataType);
460
459
  const rawLabel = value.content != null ? parseRequiredContentLike(value, options) : value.payload != null && value.payload !== "" ? multilingualFromText(value.payload, options) : null;
461
- const displayText = rawLabel?.getText() ?? value.payload ?? value.slug ?? "";
462
- const contentText = value.rawValue ?? value.payload ?? displayText;
460
+ const contentText = readPropertyValueText(value, () => rawLabel?.getText() ?? null);
463
461
  const common = {
464
462
  hierarchy: {
465
463
  isLeaf: value.inherited == null || !value.inherited,
@@ -563,24 +561,8 @@ function withoutItems(item) {
563
561
  return itemWithoutItems;
564
562
  }
565
563
  function parseEmbeddedItemEntry(entry, options) {
566
- switch (entry.category) {
567
- case "tree": return parseTree(entry.item, {
568
- ...options,
569
- containedItemCategory: normalizeTreeItemCategory(options.containedItemCategory)
570
- });
571
- case "bibliography": return parseBibliography(entry.item, options);
572
- case "concept": return parseConcept(entry.item, options);
573
- case "spatialUnit": return parseSpatialUnit(entry.item, options);
574
- case "period": return parsePeriod(entry.item, options);
575
- case "person": return parsePerson(entry.item, options);
576
- case "propertyVariable": return parsePropertyVariable(entry.item, options);
577
- case "propertyValue": return parsePropertyValue(entry.item, options);
578
- case "resource": return parseResource(entry.item, options);
579
- case "text": return parseText(entry.item, options);
580
- case "set": return parseSet(entry.item, options);
581
- case "dictionaryUnit":
582
- case "heading": return null;
583
- }
564
+ const parse = ITEM_CATEGORIES[entry.category].parseEmbedded;
565
+ return parse == null ? null : parse(entry.item, options);
584
566
  }
585
567
  function parseItemHierarchy(hierarchy, options, categories) {
586
568
  const items = [];
@@ -594,52 +576,19 @@ function parseItemHierarchy(hierarchy, options, categories) {
594
576
  function parseSetItemHierarchy(hierarchy, options, categories) {
595
577
  const items = [];
596
578
  if (hierarchy == null) return items;
597
- for (const entry of collectHierarchyEntries(hierarchy, categories)) switch (entry.category) {
598
- case "tree":
599
- items.push(parseSetTree(entry.item, options));
600
- break;
601
- case "bibliography":
602
- items.push(parseSetBibliography(entry.item, options));
603
- break;
604
- case "concept":
605
- items.push(parseSetConcept(entry.item, options));
606
- break;
607
- case "spatialUnit":
608
- items.push(parseSetSpatialUnit(entry.item, options));
609
- break;
610
- case "period":
611
- items.push(parseSetPeriod(entry.item, options));
612
- break;
613
- case "person": {
614
- const person = entry.item;
615
- items.push(withSetItemProperties(parsePerson(person, options), person.properties, options));
616
- break;
617
- }
618
- case "propertyVariable":
619
- items.push(parsePropertyVariable(entry.item, options));
620
- break;
621
- case "propertyValue": {
622
- const propertyValue = entry.item;
623
- items.push(withSetItemProperties(parsePropertyValue(propertyValue, options), propertyValue.properties, options));
624
- break;
625
- }
626
- case "resource":
627
- items.push(parseSetResource(entry.item, options));
628
- break;
629
- case "text":
630
- items.push(parseText(entry.item, options));
631
- break;
632
- case "set": items.push(parseSetSet(entry.item, options));
579
+ for (const entry of collectHierarchyEntries(hierarchy, categories)) {
580
+ const parse = ITEM_CATEGORIES[entry.category].parseSetItem;
581
+ if (parse != null) items.push(parse(entry.item, options));
633
582
  }
634
583
  return items;
635
584
  }
636
585
  function normalizeTreeLinkItemsCategory(type) {
637
- const category = normalizeCategory(type);
586
+ const category = normalizeItemCategory(type);
638
587
  if (category === "tree" || category == null) return null;
639
588
  return category;
640
589
  }
641
590
  function normalizeSetLinkItemsCategory(type) {
642
- const category = normalizeCategory(type);
591
+ const category = normalizeItemCategory(type);
643
592
  return category == null ? null : [category];
644
593
  }
645
594
  function parseBaseItemLink(category, rawItem, options) {
@@ -794,41 +743,9 @@ function parseLinks(rawLinks, options) {
794
743
  const links = [];
795
744
  if (rawLinks == null) return links;
796
745
  const hierarchy = rawLinks;
797
- for (const entry of collectHierarchyEntries(hierarchy)) switch (entry.category) {
798
- case "tree":
799
- links.push(parseTreeItemLink(entry.item, options));
800
- break;
801
- case "bibliography":
802
- links.push(parseBibliographyItemLink(entry.item, options));
803
- break;
804
- case "concept":
805
- links.push(parseConceptItemLink(entry.item, options));
806
- break;
807
- case "spatialUnit":
808
- links.push(parseSpatialUnitItemLink(entry.item, options));
809
- break;
810
- case "period":
811
- links.push(parsePeriodItemLink(entry.item, options));
812
- break;
813
- case "person":
814
- links.push(parsePersonItemLink(entry.item, options));
815
- break;
816
- case "propertyVariable":
817
- links.push(parsePropertyVariableItemLink(entry.item, options));
818
- break;
819
- case "propertyValue":
820
- links.push(parsePropertyValueItemLink(entry.item, options));
821
- break;
822
- case "resource":
823
- links.push(parseResourceItemLink(entry.item, options));
824
- break;
825
- case "text":
826
- links.push(parseTextItemLink(entry.item, options));
827
- break;
828
- case "set":
829
- links.push(parseSetItemLink(entry.item, options));
830
- break;
831
- case "dictionaryUnit": links.push(parseDictionaryUnitItemLink(entry.item, options));
746
+ for (const entry of collectHierarchyEntries(hierarchy)) {
747
+ const parse = ITEM_CATEGORIES[entry.category].parseLink;
748
+ if (parse != null) links.push(parse(entry.item, options));
832
749
  }
833
750
  return links;
834
751
  }
@@ -1149,37 +1066,6 @@ function parseText(rawText, options) {
1149
1066
  editions
1150
1067
  };
1151
1068
  }
1152
- function parseMetadataLanguages(rawOchre) {
1153
- const languages = [];
1154
- const metadataLanguages = rawOchre.metadata.language ?? [];
1155
- for (const language of metadataLanguages) {
1156
- const parsedLanguage = parseStringLike(language);
1157
- if (parsedLanguage != null) languages.push(parsedLanguage);
1158
- }
1159
- if (languages.length > 0) return languages;
1160
- if (rawOchre.languages != null) {
1161
- for (const language of rawOchre.languages.split(";")) if (language !== "") languages.push(language);
1162
- }
1163
- return languages.length > 0 ? languages : [...DEFAULT_LANGUAGES];
1164
- }
1165
- function resolveLanguages(requestedLanguages, metadataLanguages) {
1166
- if (requestedLanguages == null || requestedLanguages.length === 0) return metadataLanguages;
1167
- const unsupportedLanguages = [];
1168
- for (const requestedLanguage of requestedLanguages) if (!metadataLanguages.some((metadataLanguage) => metadataLanguage.toLocaleLowerCase("en-US") === requestedLanguage.toLocaleLowerCase("en-US"))) unsupportedLanguages.push(requestedLanguage);
1169
- if (unsupportedLanguages.length > 0) throw new Error(`The following language(s) are not supported by the dataset: ${unsupportedLanguages.toSorted((a, b) => a.localeCompare(b, "en-US")).join(", ")}. Available languages: ${metadataLanguages.toSorted((a, b) => a.localeCompare(b, "en-US")).join(", ")}`, { cause: unsupportedLanguages });
1170
- return requestedLanguages;
1171
- }
1172
- function resolveDefaultLanguage(rawOchre, languages) {
1173
- const metadataLanguages = rawOchre.metadata.language ?? [];
1174
- for (const language of metadataLanguages) {
1175
- const parsedLanguage = parseStringLike(language);
1176
- if (parsedLanguage != null && language.default === "true" && languages.includes(parsedLanguage)) return parsedLanguage;
1177
- }
1178
- for (const language of languages) if (language === DEFAULT_LANGUAGES[0]) return language;
1179
- const firstLanguage = languages[0];
1180
- if (firstLanguage == null) throw new Error("Default language not found", { cause: languages });
1181
- return firstLanguage;
1182
- }
1183
1069
  function parseMetadataPublisher(rawPublisher) {
1184
1070
  const publisher = Array.isArray(rawPublisher) ? rawPublisher[0] : rawPublisher;
1185
1071
  return parseStringLike(publisher) ?? "";
@@ -1211,7 +1097,7 @@ function parseMetadata(rawOchre, options, defaultLanguage) {
1211
1097
  },
1212
1098
  item: rawMetadata.item == null ? null : {
1213
1099
  identification: parseIdentification(rawMetadata.item.identification, metadataOptions),
1214
- category: normalizeCategory(rawMetadata.item.category) ?? rawMetadata.item.category,
1100
+ category: normalizeItemCategory(rawMetadata.item.category) ?? rawMetadata.item.category,
1215
1101
  type: rawMetadata.item.type,
1216
1102
  maxLength: rawMetadata.item.maxLength ?? null
1217
1103
  },
@@ -1231,45 +1117,17 @@ function getSingleTopLevelRawItem(items, category) {
1231
1117
  return items[0];
1232
1118
  }
1233
1119
  function parseTopLevelItem(rawOchre, category, options) {
1234
- const rawItems = rawOchre;
1235
- let parsedItem;
1236
- switch (category) {
1237
- case "tree":
1238
- parsedItem = parseTree(getSingleTopLevelRawItem(rawItems.tree, "tree"), {
1239
- ...options,
1240
- containedItemCategory: normalizeTreeItemCategory(options.containedItemCategory)
1241
- });
1242
- break;
1243
- case "bibliography":
1244
- parsedItem = parseBibliography(getSingleTopLevelRawItem(rawItems.bibliography, "bibliography"), options);
1245
- break;
1246
- case "concept":
1247
- parsedItem = parseConcept(getSingleTopLevelRawItem(rawItems.concept, "concept"), options);
1248
- break;
1249
- case "spatialUnit":
1250
- parsedItem = parseSpatialUnit(getSingleTopLevelRawItem(rawItems.spatialUnit, "spatial unit"), options);
1251
- break;
1252
- case "period":
1253
- parsedItem = parsePeriod(getSingleTopLevelRawItem(rawItems.period, "period"), options);
1254
- break;
1255
- case "person":
1256
- parsedItem = parsePerson(getSingleTopLevelRawItem(rawItems.person, "person"), options);
1257
- break;
1258
- case "propertyVariable":
1259
- parsedItem = parsePropertyVariable(getSingleTopLevelRawItem(rawItems.propertyVariable ?? rawItems.variable, "property variable"), options);
1120
+ const entry = ITEM_CATEGORIES[category];
1121
+ const facts = ITEM_CATEGORY_FACTS[category];
1122
+ let rawCategoryItems;
1123
+ for (const alias of facts.aliases) {
1124
+ const aliasItems = readProperty(rawOchre, alias);
1125
+ if (Array.isArray(aliasItems)) {
1126
+ rawCategoryItems = aliasItems;
1260
1127
  break;
1261
- case "propertyValue":
1262
- parsedItem = parsePropertyValue(getSingleTopLevelRawItem(rawItems.propertyValue ?? rawItems.value, "property value"), options);
1263
- break;
1264
- case "resource":
1265
- parsedItem = parseResource(getSingleTopLevelRawItem(rawItems.resource, "resource"), options);
1266
- break;
1267
- case "text":
1268
- parsedItem = parseText(getSingleTopLevelRawItem(rawItems.text, "text"), options);
1269
- break;
1270
- case "set": parsedItem = parseSet(getSingleTopLevelRawItem(rawItems.set, "set"), options);
1128
+ }
1271
1129
  }
1272
- return parsedItem;
1130
+ return entry.parseEmbedded(getSingleTopLevelRawItem(rawCategoryItems, facts.label), options);
1273
1131
  }
1274
1132
  function parseLinkedItems(rawItems, options) {
1275
1133
  const parserOptions = {
@@ -1300,11 +1158,13 @@ function parseItem(rawData, options) {
1300
1158
  const rawOchre = rawData.result.ochre;
1301
1159
  const metadataLanguages = parseMetadataLanguages(rawOchre);
1302
1160
  const languagesToUse = resolveLanguages(options.languages, metadataLanguages);
1161
+ const defaultLanguage = resolveDefaultLanguage(rawOchre, languagesToUse);
1303
1162
  const parserOptions = {
1304
1163
  languages: languagesToUse,
1164
+ defaultLanguage,
1305
1165
  containedItemCategory: options.containedItemCategory
1306
1166
  };
1307
- const inferredCategory = normalizeCategory(rawOchre.metadata.item?.category) ?? inferTopLevelCategory(rawOchre);
1167
+ const inferredCategory = normalizeItemCategory(rawOchre.metadata.item?.category) ?? inferTopLevelCategory(rawOchre);
1308
1168
  let category = inferredCategory;
1309
1169
  if (options.category != null) {
1310
1170
  if (typeof options.category === "string") category = options.category;
@@ -1313,7 +1173,6 @@ function parseItem(rawData, options) {
1313
1173
  categories: options.category
1314
1174
  } });
1315
1175
  }
1316
- const defaultLanguage = resolveDefaultLanguage(rawOchre, languagesToUse);
1317
1176
  const belongsTo = {
1318
1177
  uuid: rawOchre.uuidBelongsTo,
1319
1178
  abbreviation: rawOchre.belongsTo
@@ -1342,4 +1201,4 @@ function parseItem(rawData, options) {
1342
1201
  };
1343
1202
  }
1344
1203
  //#endregion
1345
- export { getParserOptions, parseBibliographyList, parseGallery, parseIdentification, parseItem, parseLinkedItems, parseLinks, parseMetadata, parseMetadataLanguages, parseNotes, parsePersonList, parseProperties, parseSetItems, parseSimplifiedProperties, parseStringLike, resolveDefaultLanguage, resolveLanguages };
1204
+ export { getParserOptions, parseBibliographyList, parseGallery, parseIdentification, parseItem, parseLinkedItems, parseLinks, parseMetadata, parseNotes, parsePersonList, parseProperties, parseSetItems, parseSimplifiedProperties, parseStringLike };