ochre-sdk 1.0.13 → 1.0.15

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 (51) hide show
  1. package/dist/constants.d.mts +17 -0
  2. package/dist/constants.mjs +85 -0
  3. package/dist/fetchers/gallery.d.mts +38 -0
  4. package/dist/fetchers/gallery.mjs +91 -0
  5. package/dist/fetchers/item-links.d.mts +32 -0
  6. package/dist/fetchers/item-links.mjs +120 -0
  7. package/dist/fetchers/item.d.mts +74 -0
  8. package/dist/fetchers/item.mjs +146 -0
  9. package/dist/fetchers/set/items.d.mts +48 -0
  10. package/dist/fetchers/set/items.mjs +268 -0
  11. package/dist/fetchers/set/property-values.d.mts +46 -0
  12. package/dist/fetchers/set/property-values.mjs +514 -0
  13. package/dist/fetchers/website.d.mts +25 -0
  14. package/dist/fetchers/website.mjs +38 -0
  15. package/dist/getters.d.mts +193 -0
  16. package/dist/getters.mjs +341 -0
  17. package/dist/helpers.d.mts +18 -0
  18. package/dist/helpers.mjs +33 -0
  19. package/dist/index.d.mts +12 -1971
  20. package/dist/index.mjs +9 -7236
  21. package/dist/parsers/helpers.d.mts +27 -0
  22. package/dist/parsers/helpers.mjs +53 -0
  23. package/dist/parsers/index.d.mts +65 -0
  24. package/dist/parsers/index.mjs +1338 -0
  25. package/dist/parsers/mdx.d.mts +4 -0
  26. package/dist/parsers/mdx.mjs +9 -0
  27. package/dist/parsers/multilingual.d.mts +189 -0
  28. package/dist/parsers/multilingual.mjs +410 -0
  29. package/dist/parsers/string.d.mts +29 -0
  30. package/dist/parsers/string.mjs +445 -0
  31. package/dist/parsers/website/index.d.mts +20 -0
  32. package/dist/parsers/website/index.mjs +1245 -0
  33. package/dist/parsers/website/reader.d.mts +29 -0
  34. package/dist/parsers/website/reader.mjs +75 -0
  35. package/dist/query.d.mts +13 -0
  36. package/dist/query.mjs +827 -0
  37. package/dist/schemas.d.mts +79 -0
  38. package/dist/schemas.mjs +223 -0
  39. package/dist/types/index.d.mts +840 -0
  40. package/dist/types/index.mjs +1 -0
  41. package/dist/types/website.d.mts +501 -0
  42. package/dist/types/website.mjs +1 -0
  43. package/dist/utils.d.mts +34 -0
  44. package/dist/utils.mjs +172 -0
  45. package/dist/xml/metadata.d.mts +5 -0
  46. package/dist/xml/metadata.mjs +30 -0
  47. package/dist/xml/schemas.d.mts +13 -0
  48. package/dist/xml/schemas.mjs +849 -0
  49. package/dist/xml/types.d.mts +901 -0
  50. package/dist/xml/types.mjs +1 -0
  51. package/package.json +19 -17
@@ -0,0 +1,445 @@
1
+ import { TEXT_ANNOTATION_UUID } from "../constants.mjs";
2
+ import { serializeMDXText } from "./mdx.mjs";
3
+ import { MultilingualString } from "./multilingual.mjs";
4
+ import { renderOptionsSchema } from "../schemas.mjs";
5
+ import { getXMLSourceIndex } from "../xml/metadata.mjs";
6
+ import * as v from "valibot";
7
+ //#region src/parsers/string.ts
8
+ const TEXT_ANNOTATION_TOKEN = "text-annotation";
9
+ const TEXT_STYLING_TOKEN = "text-styling";
10
+ const HOVER_CARD_TOKEN = "hover-card";
11
+ const ITEM_PAGE_TOKEN = "item-page";
12
+ const ENTRY_PAGE_TOKEN = "entry-page";
13
+ const VARIANT_TOKEN = "variant";
14
+ const HEADING_LEVEL_TOKEN = "heading-level";
15
+ const MDX_QUOTED_ATTRIBUTE_ESCAPE_REGEX = /[\n\r"]/;
16
+ const MDX_RENDER_ELEMENTS = {
17
+ bold: "strong",
18
+ italic: "em",
19
+ underline: "u"
20
+ };
21
+ function isXMLRichTextLink(value) {
22
+ return typeof value === "object" && value != null;
23
+ }
24
+ function getLinkStringProperty(link, property) {
25
+ switch (property) {
26
+ case "uuid": return "uuid" in link && typeof link.uuid === "string" ? link.uuid : null;
27
+ case "href": return "href" in link && typeof link.href === "string" ? link.href : null;
28
+ case "height": return "height" in link && link.height != null ? link.height.toString() : null;
29
+ case "width": return "width" in link && link.width != null ? link.width.toString() : null;
30
+ }
31
+ }
32
+ function transformPermanentIdentificationUrl(url) {
33
+ return url.replace("https://pi.lib.uchicago.edu/1001/org/ochre/", "https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?uuid=");
34
+ }
35
+ /**
36
+ * Applies text rendering options (bold, italic, underline) to a string
37
+ *
38
+ * @param contentString - The string content to render
39
+ * @param renderString - Space-separated string of render options
40
+ * @param rendering - Which text rendering to produce
41
+ * @returns String with rich-text formatting applied
42
+ * @internal
43
+ */
44
+ function parseRenderOptions(contentString, renderString, rendering) {
45
+ const { success, output } = v.safeParse(renderOptionsSchema, renderString);
46
+ if (!success) return contentString;
47
+ if (rendering !== "rich") return contentString.replaceAll("'", "'");
48
+ return applyRichRenderOptions(contentString, output).replaceAll("'", "'");
49
+ }
50
+ function applyRichRenderOptions(contentString, options) {
51
+ const withoutLeadingWhitespace = contentString.trimStart();
52
+ const leadingWhitespace = contentString.slice(0, contentString.length - withoutLeadingWhitespace.length);
53
+ const renderableContent = withoutLeadingWhitespace.trimEnd();
54
+ const trailingWhitespace = withoutLeadingWhitespace.slice(renderableContent.length);
55
+ if (renderableContent === "") return contentString;
56
+ return `${leadingWhitespace}${applyMDXRenderElements(renderableContent, options)}${trailingWhitespace}`;
57
+ }
58
+ function applyMDXRenderElements(contentString, options) {
59
+ let result = contentString;
60
+ for (const option of options) {
61
+ const element = MDX_RENDER_ELEMENTS[option];
62
+ result = `<${element}>${result}</${element}>`;
63
+ }
64
+ return result;
65
+ }
66
+ /**
67
+ * Parses XML string into a formatted string with rendering options
68
+ *
69
+ * @param string - XML string to parse
70
+ * @param options - Options for parsing
71
+ * @param options.rendering - Which text rendering to produce
72
+ * @returns Formatted string with rendering options
73
+ *
74
+ * @internal
75
+ */
76
+ function parseXMLStringVariant(string, options) {
77
+ let returnString = parseXMLStringPayload(string, options);
78
+ if (string.rend != null) returnString = parseRenderOptions(returnString, string.rend, options.rendering);
79
+ return returnString;
80
+ }
81
+ function parseXMLStringPayload(string, options) {
82
+ const payload = string.payload ?? "";
83
+ return options.rendering === "rich" ? serializeMDXText(payload) : payload;
84
+ }
85
+ function parseXMLString(string) {
86
+ return {
87
+ text: parseXMLStringVariant(string, { rendering: "plain" }),
88
+ richText: parseXMLStringVariant(string, { rendering: "rich" })
89
+ };
90
+ }
91
+ /**
92
+ * Creates an MDX component based on the variant
93
+ *
94
+ * @param variant - The variant of the component
95
+ * @param properties - The properties of the component
96
+ * @param properties.uuid - The UUID of the component
97
+ * @param properties.href - The href of the component
98
+ * @param properties.height - The height of the component
99
+ * @param properties.width - The width of the component
100
+ * @param properties.content - The content of the component
101
+ * @param properties.text - The text of the component
102
+ * @returns The MDX component as a string
103
+ *
104
+ * @internal
105
+ */
106
+ function createMDXComponent(variant, properties) {
107
+ const { uuid, href, height, width, content, text } = properties;
108
+ const tooltipContent = getDistinctTooltipContent(content, text);
109
+ let returnString = "";
110
+ switch (variant) {
111
+ case "inlineImage":
112
+ returnString = `<InlineImage${createMDXStringAttribute("uuid", uuid ?? "null")}${createMDXStringAttribute("content", content)} height={${height ?? "null"}} width={${width ?? "null"}} />`;
113
+ break;
114
+ case "internalLink":
115
+ returnString = `<InternalLink${createMDXStringAttribute("uuid", uuid ?? "null")}${createMDXStringAttribute("content", tooltipContent)}>${text}</InternalLink>`;
116
+ break;
117
+ case "externalLink":
118
+ returnString = `<ExternalLink${createMDXStringAttribute("href", href == null ? "#" : transformPermanentIdentificationUrl(href))}${createMDXStringAttribute("content", tooltipContent)}>${text}</ExternalLink>`;
119
+ break;
120
+ case "documentLink":
121
+ returnString = `<ExternalLink${createMDXStringAttribute("href", `https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?uuid=${uuid}&load`)}${createMDXStringAttribute("content", tooltipContent)}>${text}</ExternalLink>`;
122
+ break;
123
+ case "tooltipSpan":
124
+ returnString = `<TooltipSpan${createMDXStringAttribute("content", content)}>${text}</TooltipSpan>`;
125
+ break;
126
+ }
127
+ return returnString;
128
+ }
129
+ function getDistinctTooltipContent(content, textContent) {
130
+ return content === textContent ? void 0 : content;
131
+ }
132
+ function createMDXStringAttribute(name, value) {
133
+ if (value == null || value === "") return "";
134
+ return ` ${name}=${MDX_QUOTED_ATTRIBUTE_ESCAPE_REGEX.test(value) ? `{${JSON.stringify(value)}}` : `"${value}"`}`;
135
+ }
136
+ function getPropertyValueUuid(property) {
137
+ const value = property?.value?.[0];
138
+ return value?.uuid == null || value.uuid === "" ? null : value.uuid;
139
+ }
140
+ function getFirstPropertyMetadata(item) {
141
+ const itemProperty = item.properties?.property[0];
142
+ if (itemProperty == null) return null;
143
+ return {
144
+ labelUuid: itemProperty.label.uuid,
145
+ valueUuid: getPropertyValueUuid(itemProperty)
146
+ };
147
+ }
148
+ function parseContentLikeForLanguage(value, options) {
149
+ if (value == null) return "";
150
+ if (!("content" in value)) return parseXMLString(value).text;
151
+ const contentItem = value.content.find((item) => item.lang === options.language) ?? value.content[0];
152
+ if (contentItem == null) return "";
153
+ const languages = [contentItem.lang];
154
+ return parseXMLContent({ content: [contentItem] }, { languages }).getText(contentItem.lang);
155
+ }
156
+ function parsePropertyValueText(property, options) {
157
+ const value = property?.value?.[0];
158
+ if (value == null) return "";
159
+ if (value.rawValue != null) return value.rawValue;
160
+ if (value.payload != null) return value.payload;
161
+ if (value.slug != null) return value.slug;
162
+ if (value.content != null) return parseContentLikeForLanguage(value, options);
163
+ return "";
164
+ }
165
+ function normalizePropertyToken(value) {
166
+ return value.trim().toLowerCase().replaceAll(/[\s_]+/g, "-");
167
+ }
168
+ function propertyLabelMatches(property, uuid, tokens, options) {
169
+ if (uuid !== "" && property.label.uuid === uuid) return true;
170
+ const label = normalizePropertyToken(parseContentLikeForLanguage(property.label, options));
171
+ return tokens.includes(label);
172
+ }
173
+ function propertyValueMatches(property, uuid, tokens, options) {
174
+ if (uuid !== "" && getPropertyValueUuid(property) === uuid) return true;
175
+ const value = normalizePropertyToken(parsePropertyValueText(property, options));
176
+ return tokens.includes(value);
177
+ }
178
+ function extractAnnotationMetadata(item, options) {
179
+ const result = {
180
+ linkVariant: null,
181
+ textStyling: null
182
+ };
183
+ const itemProperty = item.properties?.property[0];
184
+ if (itemProperty == null) return result;
185
+ if (!propertyLabelMatches(itemProperty, "f1c131b6-1498-48a4-95bf-a9edae9fd518", ["presentation"], options) || !propertyValueMatches(itemProperty, "b9ca2732-78f4-416e-b77f-dae7647e68a9", [TEXT_ANNOTATION_TOKEN], options)) return result;
186
+ for (const textAnnotationProperty of itemProperty.property ?? []) {
187
+ if (propertyValueMatches(textAnnotationProperty, "c7f6a08a-f07b-49b6-bcb1-af485da3c58f", [HOVER_CARD_TOKEN], options)) {
188
+ result.linkVariant = "hover-card";
189
+ continue;
190
+ }
191
+ if (propertyValueMatches(textAnnotationProperty, "bf4476ab-6bc8-40d0-a001-1446213c72ce", [ITEM_PAGE_TOKEN], options)) {
192
+ result.linkVariant = "item-page";
193
+ continue;
194
+ }
195
+ if (propertyValueMatches(textAnnotationProperty, "9d52db95-a9cf-45f7-a0bf-fc9ba9f0aae0", [ENTRY_PAGE_TOKEN], options)) {
196
+ result.linkVariant = "entry-page";
197
+ continue;
198
+ }
199
+ if (propertyValueMatches(textAnnotationProperty, "3e6f86ab-df81-45ae-8257-e2867357df56", [TEXT_STYLING_TOKEN], options)) {
200
+ let variant = "block";
201
+ let size = "md";
202
+ let headingLevel = null;
203
+ const cssStyles = [];
204
+ const textStylingProperties = textAnnotationProperty.property ?? [];
205
+ for (const textStylingProperty of textStylingProperties) {
206
+ if (propertyLabelMatches(textStylingProperty, "e1647bef-d801-4100-bdde-d081c422f763", [VARIANT_TOKEN], options)) {
207
+ variant = parsePropertyValueText(textStylingProperty, options);
208
+ for (const nestedProperty of textStylingProperty.property ?? []) if (propertyLabelMatches(nestedProperty, "", ["size"], options)) size = parsePropertyValueText(nestedProperty, options);
209
+ continue;
210
+ }
211
+ if (propertyLabelMatches(textStylingProperty, "d4266f0b-3f8d-4b32-8c15-4b229c8bb11e", [HEADING_LEVEL_TOKEN], options)) {
212
+ headingLevel = parsePropertyValueText(textStylingProperty, options);
213
+ continue;
214
+ }
215
+ cssStyles.push({
216
+ label: parseContentLikeForLanguage(textStylingProperty.label, options),
217
+ value: parsePropertyValueText(textStylingProperty, options)
218
+ });
219
+ }
220
+ result.textStyling = {
221
+ variant,
222
+ size,
223
+ headingLevel,
224
+ cssStyles
225
+ };
226
+ continue;
227
+ }
228
+ }
229
+ return result;
230
+ }
231
+ function hasRichTextEnvelope(item) {
232
+ return item.properties?.property[0] != null || getXMLRichTextLinks(item).length > 0;
233
+ }
234
+ function parseXMLStringItem(item, contentItem, options) {
235
+ if (!(item.payload != null || item.string != null) && getXMLRichTextLinks(item).length === 0) return "";
236
+ if (hasRichTextEnvelope(item)) {
237
+ let linkString = item.payload != null ? parseXMLStringPayload(item, { rendering: options.rendering }) : parseNestedStringItems(item.string ?? [], contentItem, { ...options });
238
+ if (item.rend != null) linkString = parseRenderOptions(linkString, item.rend, options.rendering);
239
+ if (options.rendering === "plain") return linkString;
240
+ return renderRichTextItem(item, linkString, contentItem, options);
241
+ }
242
+ if (item.payload != null) return parseXMLStringVariant(item, { rendering: options.rendering });
243
+ let result = parseNestedStringItems(item.string ?? [], contentItem, options);
244
+ if (item.rend != null) result = parseRenderOptions(result, item.rend, options.rendering);
245
+ return result;
246
+ }
247
+ function parseNestedStringItems(items, contentItem, options) {
248
+ let result = "";
249
+ for (const item of items) result += parseXMLStringItem(item, contentItem, options);
250
+ return result;
251
+ }
252
+ function isTextAnnotationMarkerLink(link) {
253
+ return getLinkStringProperty(link, "uuid") === TEXT_ANNOTATION_UUID;
254
+ }
255
+ function wrapWithTextStyling(content, textStyling) {
256
+ if (textStyling == null) return content;
257
+ return `<Annotation type="text-styling"${createMDXStringAttribute("variant", textStyling.variant)}${createMDXStringAttribute("size", textStyling.size)}${createMDXStringAttribute("headingLevel", textStyling.headingLevel ?? void 0)}${textStyling.cssStyles.length > 0 ? ` cssStyles={{default: ${JSON.stringify(textStyling.cssStyles)}, tablet: [], mobile: []}}` : ""}>${content}</Annotation>`;
258
+ }
259
+ function createInternalLinkComponent(properties) {
260
+ const innerContent = wrapWithTextStyling(properties.text, properties.annotationMetadata.textStyling);
261
+ switch (properties.annotationMetadata.linkVariant) {
262
+ case "hover-card": return `<Annotation type="hover-card"${createMDXStringAttribute("uuid", properties.uuid ?? "null")}>${innerContent}</Annotation>`;
263
+ case "item-page": return `<InternalLink type="item"${createMDXStringAttribute("uuid", properties.uuid ?? "null")}>${innerContent}</InternalLink>`;
264
+ case "entry-page": return `<InternalLink type="entry"${createMDXStringAttribute("uuid", properties.uuid ?? "null")}>${innerContent}</InternalLink>`;
265
+ default: return `<InternalLink${createMDXStringAttribute("uuid", properties.uuid ?? "null")}${properties.propertyMetadata != null ? `${createMDXStringAttribute("properties", properties.propertyMetadata.labelUuid)}${createMDXStringAttribute("value", properties.propertyMetadata.valueUuid ?? void 0)}` : ""}${createMDXStringAttribute("content", getDistinctTooltipContent(properties.content, properties.text))}>${innerContent}</InternalLink>`;
266
+ }
267
+ }
268
+ function getXMLRichTextLinks(item) {
269
+ const links = [];
270
+ let fallbackIndex = 0;
271
+ for (const rawLinks of Object.values(item.links ?? {})) {
272
+ if (!Array.isArray(rawLinks)) continue;
273
+ for (const rawLink of rawLinks) if (isXMLRichTextLink(rawLink) && !isTextAnnotationMarkerLink(rawLink)) {
274
+ links.push({
275
+ link: rawLink,
276
+ fallbackIndex
277
+ });
278
+ fallbackIndex += 1;
279
+ }
280
+ }
281
+ links.sort((left, right) => {
282
+ const leftIndex = getXMLSourceIndex(left.link);
283
+ const rightIndex = getXMLSourceIndex(right.link);
284
+ if (leftIndex != null && rightIndex != null && leftIndex !== rightIndex) return leftIndex - rightIndex;
285
+ return left.fallbackIndex - right.fallbackIndex;
286
+ });
287
+ const sortedLinks = [];
288
+ for (const { link } of links) sortedLinks.push(link);
289
+ return sortedLinks;
290
+ }
291
+ function renderRichTextItem(item, linkString, contentItem, options) {
292
+ const { languages, rendering } = options;
293
+ const annotationMetadata = extractAnnotationMetadata(item, { language: contentItem.lang });
294
+ const links = getXMLRichTextLinks(item);
295
+ if (links.length === 0) return wrapWithTextStyling(linkString, annotationMetadata.textStyling);
296
+ let result = "";
297
+ for (const link of links) {
298
+ const linkContent = link.identification != null ? "content" in link.identification.label ? parseXMLContent(link.identification.label, { languages }) : MultilingualString.create(contentItem.lang, parseXMLString(link.identification.label), languages) : MultilingualString.create(contentItem.lang, "", languages);
299
+ const contentText = (rendering === "rich" ? linkContent.getExactRichText(contentItem.lang) : linkContent.getExactText(contentItem.lang)) ?? "";
300
+ if ("type" in link && link.type != null) switch (link.type) {
301
+ case "IIIF":
302
+ case "image":
303
+ if ("rend" in link && link.rend === "inline") {
304
+ const component = createMDXComponent("inlineImage", {
305
+ uuid: getLinkStringProperty(link, "uuid"),
306
+ href: getLinkStringProperty(link, "href") ?? void 0,
307
+ height: getLinkStringProperty(link, "height") ?? void 0,
308
+ width: getLinkStringProperty(link, "width") ?? void 0,
309
+ content: contentText,
310
+ text: linkString
311
+ });
312
+ result += component;
313
+ } else if (link.publicationDateTime != null) {
314
+ const component = createInternalLinkComponent({
315
+ uuid: getLinkStringProperty(link, "uuid"),
316
+ text: linkString,
317
+ content: contentText,
318
+ annotationMetadata
319
+ });
320
+ result += component;
321
+ } else {
322
+ const component = createMDXComponent("tooltipSpan", {
323
+ uuid: getLinkStringProperty(link, "uuid"),
324
+ text: linkString,
325
+ content: contentText
326
+ });
327
+ result += component;
328
+ }
329
+ break;
330
+ case "internalDocument": {
331
+ const component = createInternalLinkComponent({
332
+ uuid: getLinkStringProperty(link, "uuid"),
333
+ text: linkString,
334
+ content: contentText,
335
+ annotationMetadata,
336
+ propertyMetadata: getFirstPropertyMetadata(item)
337
+ });
338
+ result += component;
339
+ break;
340
+ }
341
+ case "externalDocument": {
342
+ const component = link.publicationDateTime != null ? createMDXComponent("documentLink", {
343
+ uuid: getLinkStringProperty(link, "uuid"),
344
+ text: linkString,
345
+ content: contentText
346
+ }) : createMDXComponent("tooltipSpan", {
347
+ uuid: getLinkStringProperty(link, "uuid"),
348
+ text: linkString,
349
+ content: contentText
350
+ });
351
+ result += component;
352
+ break;
353
+ }
354
+ case "webpage": {
355
+ const component = createMDXComponent("externalLink", {
356
+ uuid: getLinkStringProperty(link, "uuid"),
357
+ href: getLinkStringProperty(link, "href") ?? "#",
358
+ text: linkString,
359
+ content: contentText
360
+ });
361
+ result += component;
362
+ break;
363
+ }
364
+ }
365
+ else if (link.publicationDateTime != null) {
366
+ const component = createInternalLinkComponent({
367
+ uuid: getLinkStringProperty(link, "uuid"),
368
+ text: linkString,
369
+ content: contentText,
370
+ annotationMetadata
371
+ });
372
+ result += component;
373
+ } else {
374
+ const component = createMDXComponent("tooltipSpan", {
375
+ uuid: getLinkStringProperty(link, "uuid"),
376
+ text: linkString,
377
+ content: contentText
378
+ });
379
+ result += component;
380
+ }
381
+ }
382
+ return result;
383
+ }
384
+ /**
385
+ * Parses rich text content into a formatted string with links and annotations
386
+ *
387
+ * @param item - XML-based rich text item to parse
388
+ * @param options - Options for parsing
389
+ * @param options.languages - Languages of the content
390
+ * @returns Plain and rich formatted strings
391
+ *
392
+ * @internal
393
+ */
394
+ function parseXMLContent(item, options) {
395
+ const { languages } = options;
396
+ const aliases = extractAliases(item) ?? [];
397
+ const content = {};
398
+ for (const contentItem of item.content) {
399
+ if (contentItem.lang === "zxx" || !languages.includes(contentItem.lang)) continue;
400
+ const language = contentItem.lang;
401
+ const entries = content[language] ?? [];
402
+ entries.push(parseXMLContentItem(contentItem, { languages }));
403
+ content[language] = entries;
404
+ }
405
+ if (Object.keys(content).length > 0) return MultilingualString.fromEntries(content, languages, { aliases });
406
+ for (const contentItem of item.content) {
407
+ if (contentItem.lang === "zxx") continue;
408
+ const fallbackText = parseXMLContentItem(contentItem, { languages: [contentItem.lang] });
409
+ const fallbackContent = {};
410
+ for (const language of languages) fallbackContent[language] = [fallbackText];
411
+ return MultilingualString.fromEntries(fallbackContent, languages, { aliases });
412
+ }
413
+ return MultilingualString.empty(languages, { aliases });
414
+ }
415
+ function parseXMLContentItem(contentItem, options) {
416
+ return {
417
+ text: parseNestedStringItems(contentItem.string, contentItem, {
418
+ ...options,
419
+ rendering: "plain"
420
+ }),
421
+ richText: parseNestedStringItems(contentItem.string, contentItem, {
422
+ ...options,
423
+ rendering: "rich"
424
+ })
425
+ };
426
+ }
427
+ /**
428
+ * Extracts alias strings from XMLContent where lang="zxx"
429
+ * @param content - The XMLContent to extract aliases from
430
+ * @returns Array of alias strings, or null if none found
431
+ *
432
+ * @internal
433
+ */
434
+ function extractAliases(content) {
435
+ if (content == null) return null;
436
+ const aliases = [];
437
+ for (const contentItem of content.content) {
438
+ if (contentItem.lang !== "zxx") continue;
439
+ const alias = parseXMLContentItem(contentItem, { languages: ["zxx"] }).text;
440
+ if (alias !== "") aliases.push(alias);
441
+ }
442
+ return aliases.length > 0 ? aliases : null;
443
+ }
444
+ //#endregion
445
+ export { extractAliases, parseXMLContent, parseXMLString, transformPermanentIdentificationUrl };
@@ -0,0 +1,20 @@
1
+ import { Webpage, Website } from "../../types/website.mjs";
2
+ import { XMLWebsiteData, XMLWebsiteResource } from "../../xml/types.mjs";
3
+ import { ParserOptions } from "../helpers.mjs";
4
+
5
+ //#region src/parsers/website/index.d.ts
6
+ /**
7
+ * Parses raw bounds data into a standardized bounds structure
8
+ *
9
+ * @param bounds - Raw bounds data in OCHRE format
10
+ * @returns Parsed bounds object
11
+ */
12
+ declare function parseBounds(bounds: string): [[number, number], [number, number]];
13
+ declare function parseWebpageView<T extends ReadonlyArray<string>>(view: {
14
+ resource?: Array<XMLWebsiteResource>;
15
+ } | undefined, options: ParserOptions<T>, context: Pick<Website<T>, "belongsTo" | "metadata">): Webpage<T> | null;
16
+ declare function parseWebsite<const T extends ReadonlyArray<string> = ReadonlyArray<string>>(data: XMLWebsiteData, options?: {
17
+ languages?: T;
18
+ }): Website<T>;
19
+ //#endregion
20
+ export { parseBounds, parseWebpageView, parseWebsite };