ochre-sdk 1.0.5 → 1.0.6
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 +1 -1
- package/dist/index.mjs +106 -88
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ const result = await fetchItem("<item-uuid>", {
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
if (result.error != null) {
|
|
36
|
-
throw new Error(result.error);
|
|
36
|
+
throw new Error("Failed to fetch item", { cause: result.error });
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
console.log(result.item.identification.label.getText("eng"));
|
package/dist/index.mjs
CHANGED
|
@@ -1409,6 +1409,12 @@ function parseStringContent(value, options = FALLBACK_PARSER_OPTIONS) {
|
|
|
1409
1409
|
}
|
|
1410
1410
|
//#endregion
|
|
1411
1411
|
//#region src/parsers/index.ts
|
|
1412
|
+
function isXMLContextGroup(context) {
|
|
1413
|
+
return "context" in context;
|
|
1414
|
+
}
|
|
1415
|
+
function isXMLContextItem(context) {
|
|
1416
|
+
return "project" in context;
|
|
1417
|
+
}
|
|
1412
1418
|
const SET_ITEM_CATEGORIES = ["tree", ...[
|
|
1413
1419
|
"bibliography",
|
|
1414
1420
|
"concept",
|
|
@@ -1521,27 +1527,33 @@ function emptyContextItem() {
|
|
|
1521
1527
|
}
|
|
1522
1528
|
function parseContext(rawContext) {
|
|
1523
1529
|
const nodes = [];
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1530
|
+
let displayPath = "";
|
|
1531
|
+
for (const rawContextOuterItem of rawContext) {
|
|
1532
|
+
if (!isXMLContextGroup(rawContextOuterItem)) continue;
|
|
1533
|
+
displayPath = displayPath || rawContextOuterItem.displayPath;
|
|
1534
|
+
for (const rawContextItem of rawContextOuterItem.context) {
|
|
1535
|
+
if (!isXMLContextItem(rawContextItem)) continue;
|
|
1536
|
+
const node = {
|
|
1537
|
+
tree: rawContextItem.tree[0] == null ? emptyContextItem() : parseContextItem$1(rawContextItem.tree[0]),
|
|
1538
|
+
project: parseContextItem$1(rawContextItem.project),
|
|
1539
|
+
heading: []
|
|
1540
|
+
};
|
|
1541
|
+
const rawContextValues = rawContextItem;
|
|
1542
|
+
for (const heading of rawContextValues.heading ?? []) node.heading.push(parseContextItem$1(heading));
|
|
1543
|
+
for (const { raw, parsed } of CONTEXT_CATEGORY_MAPPINGS) {
|
|
1544
|
+
const contextValues = rawContextValues[raw] ?? [];
|
|
1545
|
+
for (const contextValue of contextValues) {
|
|
1546
|
+
const parsedItems = node[parsed] ?? [];
|
|
1547
|
+
parsedItems.push(parseContextItem$1(contextValue));
|
|
1548
|
+
node[parsed] = parsedItems;
|
|
1549
|
+
}
|
|
1538
1550
|
}
|
|
1551
|
+
nodes.push(node);
|
|
1539
1552
|
}
|
|
1540
|
-
nodes.push(node);
|
|
1541
1553
|
}
|
|
1542
1554
|
return {
|
|
1543
1555
|
nodes,
|
|
1544
|
-
displayPath
|
|
1556
|
+
displayPath
|
|
1545
1557
|
};
|
|
1546
1558
|
}
|
|
1547
1559
|
function parseEventReference(rawReference, options) {
|
|
@@ -1692,16 +1704,19 @@ function normalizeSetItemCategories(containedItemCategory) {
|
|
|
1692
1704
|
return uniqueCategories;
|
|
1693
1705
|
}
|
|
1694
1706
|
function normalizeTreeItemCategory(containedItemCategory) {
|
|
1695
|
-
if (containedItemCategory != null && typeof containedItemCategory !== "string") throw new Error("Tree containedItemCategory must be a single category");
|
|
1696
|
-
if (containedItemCategory === "tree") throw new Error("Tree containedItemCategory cannot be \"tree\"");
|
|
1707
|
+
if (containedItemCategory != null && typeof containedItemCategory !== "string") throw new Error("Tree containedItemCategory must be a single category", { cause: containedItemCategory });
|
|
1708
|
+
if (containedItemCategory === "tree") throw new Error("Tree containedItemCategory cannot be \"tree\"", { cause: containedItemCategory });
|
|
1697
1709
|
return containedItemCategory;
|
|
1698
1710
|
}
|
|
1699
1711
|
function resolveTreeItemCategory(rawTree, containedItemCategory) {
|
|
1700
1712
|
const inferredCategories = inferItemCategories(rawTree.items);
|
|
1701
|
-
if (inferredCategories.length > 1) throw new Error(`Expected Tree items to contain one category, received ${inferredCategories.join(", ")}
|
|
1713
|
+
if (inferredCategories.length > 1) throw new Error(`Expected Tree items to contain one category, received ${inferredCategories.join(", ")}`, { cause: inferredCategories });
|
|
1702
1714
|
const inferredCategory = inferredCategories[0] ?? null;
|
|
1703
|
-
if (inferredCategory === "tree") throw new Error("Tree items cannot contain category \"tree\"");
|
|
1704
|
-
if (containedItemCategory != null && inferredCategory != null && containedItemCategory !== inferredCategory) throw new Error(`Tree containedItemCategory "${containedItemCategory}" does not match XML items category "${inferredCategory}"
|
|
1715
|
+
if (inferredCategory === "tree") throw new Error("Tree items cannot contain category \"tree\"", { cause: inferredCategory });
|
|
1716
|
+
if (containedItemCategory != null && inferredCategory != null && containedItemCategory !== inferredCategory) throw new Error(`Tree containedItemCategory "${containedItemCategory}" does not match XML items category "${inferredCategory}"`, { cause: {
|
|
1717
|
+
containedItemCategory,
|
|
1718
|
+
inferredCategory
|
|
1719
|
+
} });
|
|
1705
1720
|
return containedItemCategory ?? inferredCategory;
|
|
1706
1721
|
}
|
|
1707
1722
|
function parseImage(rawImage, options) {
|
|
@@ -1849,12 +1864,13 @@ function parseNotes(rawNotes, options) {
|
|
|
1849
1864
|
}
|
|
1850
1865
|
function parsePropertyDataType(dataType) {
|
|
1851
1866
|
if (dataType == null || dataType === "") return "string";
|
|
1852
|
-
|
|
1853
|
-
|
|
1867
|
+
const normalizedDataType = dataType.startsWith("xs:") ? dataType.slice(3) : dataType;
|
|
1868
|
+
for (const propertyDataType of PROPERTY_DATA_TYPES) if (normalizedDataType === propertyDataType) return propertyDataType;
|
|
1869
|
+
throw new Error(`Invalid property value data type: ${dataType}`, { cause: dataType });
|
|
1854
1870
|
}
|
|
1855
1871
|
function parsePropertyValueContent(value, options) {
|
|
1856
1872
|
const dataType = parsePropertyDataType(value.dataType);
|
|
1857
|
-
const rawLabel = value.content
|
|
1873
|
+
const rawLabel = value.content != null ? parseRequiredContentLike(value, options) : value.payload != null && value.payload !== "" ? multilingualFromText(value.payload, options) : null;
|
|
1858
1874
|
const displayText = rawLabel?.getText() ?? value.payload ?? value.slug ?? "";
|
|
1859
1875
|
const contentText = value.rawValue ?? value.payload ?? displayText;
|
|
1860
1876
|
const common = {
|
|
@@ -2580,7 +2596,7 @@ function resolveLanguages(requestedLanguages, metadataLanguages) {
|
|
|
2580
2596
|
if (requestedLanguages.length === 0) return metadataLanguages;
|
|
2581
2597
|
const unsupportedLanguages = [];
|
|
2582
2598
|
for (const requestedLanguage of requestedLanguages) if (!metadataLanguages.some((metadataLanguage) => metadataLanguage.toLocaleLowerCase("en-US") === requestedLanguage.toLocaleLowerCase("en-US"))) unsupportedLanguages.push(requestedLanguage);
|
|
2583
|
-
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(", ")}
|
|
2599
|
+
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 });
|
|
2584
2600
|
return requestedLanguages;
|
|
2585
2601
|
}
|
|
2586
2602
|
function resolveDefaultLanguage(rawOchre, languages) {
|
|
@@ -2590,7 +2606,7 @@ function resolveDefaultLanguage(rawOchre, languages) {
|
|
|
2590
2606
|
}
|
|
2591
2607
|
for (const language of languages) if (language === DEFAULT_LANGUAGES[0]) return language;
|
|
2592
2608
|
const firstLanguage = languages[0];
|
|
2593
|
-
if (firstLanguage == null) throw new Error("Default language not found");
|
|
2609
|
+
if (firstLanguage == null) throw new Error("Default language not found", { cause: languages });
|
|
2594
2610
|
return firstLanguage;
|
|
2595
2611
|
}
|
|
2596
2612
|
function parseMetadataPublisher(rawPublisher) {
|
|
@@ -2635,11 +2651,11 @@ function inferTopLevelCategory(rawOchre) {
|
|
|
2635
2651
|
for (const category of SET_ITEM_CATEGORIES) if (category in rawOchre) return category;
|
|
2636
2652
|
if ("variable" in rawOchre) return "propertyVariable";
|
|
2637
2653
|
if ("value" in rawOchre) return "propertyValue";
|
|
2638
|
-
throw new Error("Could not infer OCHRE item category");
|
|
2654
|
+
throw new Error("Could not infer OCHRE item category", { cause: rawOchre });
|
|
2639
2655
|
}
|
|
2640
2656
|
function getSingleTopLevelRawItem(items, category) {
|
|
2641
|
-
if (items == null || items.length === 0) throw new Error(`${category} not found
|
|
2642
|
-
if (items.length > 1) throw new Error(`Expected one ${category}, received ${items.length}
|
|
2657
|
+
if (items == null || items.length === 0) throw new Error(`${category} not found`, { cause: items });
|
|
2658
|
+
if (items.length > 1) throw new Error(`Expected one ${category}, received ${items.length}`, { cause: items });
|
|
2643
2659
|
return items[0];
|
|
2644
2660
|
}
|
|
2645
2661
|
function parseTopLevelItem(rawOchre, category, options) {
|
|
@@ -2826,10 +2842,12 @@ const XMLContextItem = v.objectWithRest({
|
|
|
2826
2842
|
tree: v.array(XMLContextValue),
|
|
2827
2843
|
displayPath: v.string("XMLContextItem: displayPath is string and required")
|
|
2828
2844
|
}, v.array(XMLContextValue), "XMLContextItem: Shape error");
|
|
2829
|
-
const
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2845
|
+
const XMLEmptyContext = v.object({ payload: v.string("XMLEmptyContext: payload is string and required") }, "XMLEmptyContext: Shape error");
|
|
2846
|
+
const XMLContextGroup = v.object({
|
|
2847
|
+
context: v.array(v.union([XMLContextItem, XMLEmptyContext]), "XMLContextGroup: context is array of XMLContextItem or XMLEmptyContext"),
|
|
2848
|
+
displayPath: v.string("XMLContextGroup: displayPath is string and required")
|
|
2849
|
+
}, "XMLContextGroup: Shape error");
|
|
2850
|
+
const XMLContext = v.array(v.union([XMLContextGroup, XMLEmptyContext], "XMLContext: item is XMLContextGroup or XMLEmptyContext"));
|
|
2833
2851
|
const XMLEvent = v.object({
|
|
2834
2852
|
dateTime: v.optional(customDateTime("XMLEvent: dateTime is not a valid datetime")),
|
|
2835
2853
|
endDateTime: v.optional(customDateTime("XMLEvent: endDateTime is not a valid datetime")),
|
|
@@ -3612,13 +3630,13 @@ async function fetchGallery(params, options) {
|
|
|
3612
3630
|
}),
|
|
3613
3631
|
headers: { "Content-Type": "application/xquery" }
|
|
3614
3632
|
});
|
|
3615
|
-
if (!response.ok) throw new Error("Error fetching gallery items, please try again later.");
|
|
3633
|
+
if (!response.ok) throw new Error("Error fetching gallery items, please try again later.", { cause: response.statusText });
|
|
3616
3634
|
const dataRaw = await response.text();
|
|
3617
3635
|
const data = new XMLParser(XML_PARSER_OPTIONS).parse(dataRaw);
|
|
3618
3636
|
const { success, issues, output } = v.safeParse(XMLGalleryData, data);
|
|
3619
3637
|
if (!success) {
|
|
3620
3638
|
logIssues(issues);
|
|
3621
|
-
throw new Error("Failed to parse gallery XML");
|
|
3639
|
+
throw new Error("Failed to parse gallery XML", { cause: issues });
|
|
3622
3640
|
}
|
|
3623
3641
|
restoreXMLMetadata(output, data);
|
|
3624
3642
|
return {
|
|
@@ -3722,13 +3740,13 @@ async function fetchItemLinks(uuid, options) {
|
|
|
3722
3740
|
body: buildXQuery$2(parsedUuid),
|
|
3723
3741
|
headers: { "Content-Type": "application/xquery" }
|
|
3724
3742
|
});
|
|
3725
|
-
if (!response.ok) throw new Error("Failed to fetch OCHRE item links");
|
|
3743
|
+
if (!response.ok) throw new Error("Failed to fetch OCHRE item links", { cause: response.statusText });
|
|
3726
3744
|
const dataRaw = await response.text();
|
|
3727
3745
|
const data = new XMLParser(XML_PARSER_OPTIONS).parse(dataRaw);
|
|
3728
3746
|
const { success, issues, output } = v.safeParse(XMLItemLinksData, data);
|
|
3729
3747
|
if (!success) {
|
|
3730
3748
|
logIssues(issues);
|
|
3731
|
-
throw new Error("Failed to parse OCHRE item links");
|
|
3749
|
+
throw new Error("Failed to parse OCHRE item links", { cause: issues });
|
|
3732
3750
|
}
|
|
3733
3751
|
restoreXMLMetadata(output, data);
|
|
3734
3752
|
const languages = resolveItemLinksLanguages(output, requestedLanguages);
|
|
@@ -3788,7 +3806,7 @@ function inferFetchItemCategory(rawOchre) {
|
|
|
3788
3806
|
if ("resource" in rawOchre) return "resource";
|
|
3789
3807
|
if ("text" in rawOchre) return "text";
|
|
3790
3808
|
if ("set" in rawOchre) return "set";
|
|
3791
|
-
throw new Error("Could not infer OCHRE item category");
|
|
3809
|
+
throw new Error("Could not infer OCHRE item category", { cause: rawOchre });
|
|
3792
3810
|
}
|
|
3793
3811
|
/**
|
|
3794
3812
|
* Validate language codes while preserving literal tuple inference.
|
|
@@ -3823,13 +3841,13 @@ async function fetchItem(uuid, options) {
|
|
|
3823
3841
|
assertItemCategoryAllowed(options?.category, options?.containedItemCategory);
|
|
3824
3842
|
const languages = options?.languages == null ? [] : parseLanguages$1(options.languages);
|
|
3825
3843
|
const response = await (options?.fetch ?? fetch)(`https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?uuid=${parsedUuid}&xsl=none&lang="*"`);
|
|
3826
|
-
if (!response.ok) throw new Error("Failed to fetch OCHRE data");
|
|
3844
|
+
if (!response.ok) throw new Error("Failed to fetch OCHRE data", { cause: response.statusText });
|
|
3827
3845
|
const dataRaw = await response.text();
|
|
3828
3846
|
const data = new XMLParser(XML_PARSER_OPTIONS).parse(dataRaw);
|
|
3829
3847
|
const { success, issues, output } = v.safeParse(XMLData, data);
|
|
3830
3848
|
if (!success) {
|
|
3831
3849
|
logIssues(issues);
|
|
3832
|
-
throw new Error("Failed to parse OCHRE data");
|
|
3850
|
+
throw new Error("Failed to parse OCHRE data", { cause: issues });
|
|
3833
3851
|
}
|
|
3834
3852
|
restoreXMLMetadata(output, data);
|
|
3835
3853
|
const category = options?.category ?? inferFetchItemCategory(output.result.ochre);
|
|
@@ -4514,7 +4532,7 @@ function buildLeafQueryExpression(context, query) {
|
|
|
4514
4532
|
if (query.target === "property" && query.dataType !== "date" && query.dataType !== "dateTime" && !("value" in query) && query.propertyVariable != null) return buildPropertyPresenceQueryExpression({ propertyVariable: query.propertyVariable });
|
|
4515
4533
|
if (query.target === "property" && (query.dataType === "date" || query.dataType === "dateTime") && query.value == null) return buildPropertyDateRangeQueryExpression(query);
|
|
4516
4534
|
const searchValue = getLeafSearchValue(query);
|
|
4517
|
-
if (searchValue == null) throw new Error("Missing searchable value for query leaf");
|
|
4535
|
+
if (searchValue == null) throw new Error("Missing searchable value for query leaf", { cause: query });
|
|
4518
4536
|
const exactHelper = registerLeafHelper({
|
|
4519
4537
|
context,
|
|
4520
4538
|
query,
|
|
@@ -4589,9 +4607,9 @@ function getCompatibleIncludesGroupLeaves(query) {
|
|
|
4589
4607
|
}
|
|
4590
4608
|
function buildIncludesGroupQueryExpression(context, queries) {
|
|
4591
4609
|
const firstQuery = queries[0];
|
|
4592
|
-
if (firstQuery == null) throw new Error("Cannot build an includes group without queries");
|
|
4610
|
+
if (firstQuery == null) throw new Error("Cannot build an includes group without queries", { cause: queries });
|
|
4593
4611
|
const groupValue = getGroupableIncludesValue(firstQuery);
|
|
4594
|
-
if (groupValue == null) throw new Error("Cannot build an includes group without a search value");
|
|
4612
|
+
if (groupValue == null) throw new Error("Cannot build an includes group without a search value", { cause: firstQuery });
|
|
4595
4613
|
const terms = tokenizeIncludesSearchValue({
|
|
4596
4614
|
value: groupValue,
|
|
4597
4615
|
isCaseSensitive: firstQuery.isCaseSensitive
|
|
@@ -4897,18 +4915,18 @@ async function fetchSetItems(params, containedItemCategories, options) {
|
|
|
4897
4915
|
body: xquery,
|
|
4898
4916
|
headers: { "Content-Type": "application/xquery" }
|
|
4899
4917
|
});
|
|
4900
|
-
if (!response.ok) throw new Error(`OCHRE API responded with status: ${response.status}
|
|
4918
|
+
if (!response.ok) throw new Error(`OCHRE API responded with status: ${response.status}`, { cause: response.statusText });
|
|
4901
4919
|
const dataRaw = await response.text();
|
|
4902
4920
|
const data = new XMLParser(XML_PARSER_OPTIONS).parse(dataRaw);
|
|
4903
4921
|
const { success, issues, output } = v.safeParse(XMLSetItemsData, data);
|
|
4904
4922
|
if (!success) {
|
|
4905
4923
|
logIssues(issues);
|
|
4906
|
-
throw new Error("Failed to parse OCHRE Set items");
|
|
4924
|
+
throw new Error("Failed to parse OCHRE Set items", { cause: issues });
|
|
4907
4925
|
}
|
|
4908
4926
|
restoreXMLMetadata(output, data);
|
|
4909
4927
|
if (containedItemCategories != null) {
|
|
4910
4928
|
const missingCategories = containedItemCategories.filter((category) => !hasSetItemsCategory(output.result.ochre.items, category));
|
|
4911
|
-
if (missingCategories.length > 0) throw new Error(`No Set items found for item categories: ${missingCategories.join(", ")}
|
|
4929
|
+
if (missingCategories.length > 0) throw new Error(`No Set items found for item categories: ${missingCategories.join(", ")}`, { cause: missingCategories });
|
|
4912
4930
|
}
|
|
4913
4931
|
const languages = resolveSetItemsLanguages(output, requestedLanguages);
|
|
4914
4932
|
const items = parseSetItems(output.result.ochre.items, {
|
|
@@ -5374,13 +5392,13 @@ async function fetchSetPropertyValues(params, options) {
|
|
|
5374
5392
|
body: xquery,
|
|
5375
5393
|
headers: { "Content-Type": "application/xquery" }
|
|
5376
5394
|
});
|
|
5377
|
-
if (!response.ok) throw new Error(`OCHRE API responded with status: ${response.status}
|
|
5395
|
+
if (!response.ok) throw new Error(`OCHRE API responded with status: ${response.status}`, { cause: response.statusText });
|
|
5378
5396
|
const dataRaw = await response.text();
|
|
5379
5397
|
const data = new XMLParser(XML_PARSER_OPTIONS).parse(dataRaw);
|
|
5380
5398
|
const { success, issues, output } = v.safeParse(responseSchema, data);
|
|
5381
5399
|
if (!success) {
|
|
5382
5400
|
logIssues(issues);
|
|
5383
|
-
throw new Error("Failed to parse OCHRE Set property values");
|
|
5401
|
+
throw new Error("Failed to parse OCHRE Set property values", { cause: issues });
|
|
5384
5402
|
}
|
|
5385
5403
|
const parsedPropertyValues = [];
|
|
5386
5404
|
const parsedAttributeValues = [];
|
|
@@ -5794,7 +5812,7 @@ var WebsitePresentationReader = class WebsitePresentationReader {
|
|
|
5794
5812
|
}
|
|
5795
5813
|
requiredProperty(label, message) {
|
|
5796
5814
|
const property = this.property(label);
|
|
5797
|
-
if (property === null) throw new Error(message);
|
|
5815
|
+
if (property === null) throw new Error(message, { cause: this.sourceProperties });
|
|
5798
5816
|
return property;
|
|
5799
5817
|
}
|
|
5800
5818
|
propertyByValue(label, value) {
|
|
@@ -5942,7 +5960,7 @@ function parseResponsiveCssStyles(properties) {
|
|
|
5942
5960
|
*/
|
|
5943
5961
|
function parseBounds(bounds) {
|
|
5944
5962
|
const [southWest, northEast] = bounds.trim().startsWith("[") ? parseJsonBounds(bounds) : bounds.split(";").map((pair) => pair.split(",").map((coordinate) => Number.parseFloat(coordinate.trim())));
|
|
5945
|
-
if (southWest?.length !== 2 || northEast?.length !== 2 || southWest.some((coordinate) => Number.isNaN(coordinate)) || northEast.some((coordinate) => Number.isNaN(coordinate))) throw new Error(`Invalid bounds: ${bounds}
|
|
5963
|
+
if (southWest?.length !== 2 || northEast?.length !== 2 || southWest.some((coordinate) => Number.isNaN(coordinate)) || northEast.some((coordinate) => Number.isNaN(coordinate))) throw new Error(`Invalid bounds: ${bounds}`, { cause: bounds });
|
|
5946
5964
|
return [[southWest[0], southWest[1]], [northEast[0], northEast[1]]];
|
|
5947
5965
|
}
|
|
5948
5966
|
function parseJsonBounds(bounds) {
|
|
@@ -5950,9 +5968,9 @@ function parseJsonBounds(bounds) {
|
|
|
5950
5968
|
try {
|
|
5951
5969
|
parsed = JSON.parse(bounds);
|
|
5952
5970
|
} catch {
|
|
5953
|
-
throw new Error(`Invalid bounds: ${bounds}
|
|
5971
|
+
throw new Error(`Invalid bounds: ${bounds}`, { cause: bounds });
|
|
5954
5972
|
}
|
|
5955
|
-
if (!isNumberPairArray(parsed)) throw new Error(`Invalid bounds: ${bounds}
|
|
5973
|
+
if (!isNumberPairArray(parsed)) throw new Error(`Invalid bounds: ${bounds}`, { cause: bounds });
|
|
5956
5974
|
return parsed;
|
|
5957
5975
|
}
|
|
5958
5976
|
function isNumberPairArray(value) {
|
|
@@ -6030,7 +6048,7 @@ function parseStylesheets(styles) {
|
|
|
6030
6048
|
mobile: []
|
|
6031
6049
|
};
|
|
6032
6050
|
if (style.category === "propertyValue" || style.valueUuid != null) {
|
|
6033
|
-
if (style.valueUuid == null) throw new Error(`Stylesheet property value "${style.variableUuid}" is missing a value UUID
|
|
6051
|
+
if (style.valueUuid == null) throw new Error(`Stylesheet property value "${style.variableUuid}" is missing a value UUID`, { cause: style });
|
|
6034
6052
|
parsedStyles.push({
|
|
6035
6053
|
uuid: style.valueUuid,
|
|
6036
6054
|
category: "propertyValue",
|
|
@@ -6066,7 +6084,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6066
6084
|
switch (componentName) {
|
|
6067
6085
|
case "3d-viewer": {
|
|
6068
6086
|
const resourceLink = findWebsiteLink(websiteLinks, "resource", (link) => link.fileFormat === "model/obj");
|
|
6069
|
-
if (resourceLink == null) throw new Error(formatComponentError("Resource link not found", componentName, elementResource));
|
|
6087
|
+
if (resourceLink == null) throw new Error(formatComponentError("Resource link not found", componentName, elementResource), { cause: componentProperty });
|
|
6070
6088
|
const isInteractive = componentReader.valueOr("is-interactive", true);
|
|
6071
6089
|
const isControlsDisplayed = componentReader.valueOr("controls-displayed", true);
|
|
6072
6090
|
properties = {
|
|
@@ -6081,7 +6099,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6081
6099
|
case "advanced-search": {
|
|
6082
6100
|
const boundElementPropertyUuid = componentReader.uuid("bound-element");
|
|
6083
6101
|
const href = componentReader.linkTarget("link-to", transformPermanentIdentificationUrlToItemLink);
|
|
6084
|
-
if (boundElementPropertyUuid == null && href == null) throw new Error(formatComponentError("Bound element or href not found", componentName, elementResource));
|
|
6102
|
+
if (boundElementPropertyUuid == null && href == null) throw new Error(formatComponentError("Bound element or href not found", componentName, elementResource), { cause: componentProperty });
|
|
6085
6103
|
properties = {
|
|
6086
6104
|
component: "advanced-search",
|
|
6087
6105
|
boundElementUuid: boundElementPropertyUuid,
|
|
@@ -6091,7 +6109,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6091
6109
|
}
|
|
6092
6110
|
case "annotated-document": {
|
|
6093
6111
|
const documentLink = findWebsiteLink(websiteLinks, "resource", (link) => link.type === "internalDocument");
|
|
6094
|
-
if (documentLink == null) throw new Error(formatComponentError("Document link not found", componentName, elementResource));
|
|
6112
|
+
if (documentLink == null) throw new Error(formatComponentError("Document link not found", componentName, elementResource), { cause: componentProperty });
|
|
6095
6113
|
properties = {
|
|
6096
6114
|
component: "annotated-document",
|
|
6097
6115
|
linkUuid: documentLink.uuid
|
|
@@ -6100,7 +6118,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6100
6118
|
}
|
|
6101
6119
|
case "annotated-image": {
|
|
6102
6120
|
const imageLinks = getWebsiteLinks(websiteLinks, "resource").filter((link) => link.type === "image" || link.type === "IIIF");
|
|
6103
|
-
if (imageLinks.length === 0) throw new Error(formatComponentError("Image link not found", componentName, elementResource));
|
|
6121
|
+
if (imageLinks.length === 0) throw new Error(formatComponentError("Image link not found", componentName, elementResource), { cause: componentProperty });
|
|
6104
6122
|
const isFilterInputDisplayed = componentReader.valueOr("filter-input-displayed", true);
|
|
6105
6123
|
const isOptionsDisplayed = componentReader.valueOr("options-displayed", true);
|
|
6106
6124
|
const isAnnotationHighlightsDisplayed = componentReader.valueOr("annotation-highlights-displayed", true);
|
|
@@ -6117,7 +6135,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6117
6135
|
}
|
|
6118
6136
|
case "audio-player": {
|
|
6119
6137
|
const audioLink = findWebsiteLink(websiteLinks, "resource", (link) => link.type === "audio");
|
|
6120
|
-
if (audioLink == null) throw new Error(formatComponentError("Audio link not found", componentName, elementResource));
|
|
6138
|
+
if (audioLink == null) throw new Error(formatComponentError("Audio link not found", componentName, elementResource), { cause: componentProperty });
|
|
6121
6139
|
const isSpeedControlsDisplayed = componentReader.valueOr("speed-controls-displayed", true);
|
|
6122
6140
|
const isVolumeControlsDisplayed = componentReader.valueOr("volume-controls-displayed", true);
|
|
6123
6141
|
const isSeekBarDisplayed = componentReader.valueOr("seek-bar-displayed", true);
|
|
@@ -6133,7 +6151,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6133
6151
|
case "bibliography": {
|
|
6134
6152
|
const itemLinks = websiteLinks.filter((link) => link.category !== "bibliography");
|
|
6135
6153
|
const bibliographies = parseBibliographyList(elementResource.bibliographies, options);
|
|
6136
|
-
if (itemLinks.length === 0 && bibliographies.length === 0) throw new Error(formatComponentError("No links found", componentName, elementResource));
|
|
6154
|
+
if (itemLinks.length === 0 && bibliographies.length === 0) throw new Error(formatComponentError("No links found", componentName, elementResource), { cause: componentProperty });
|
|
6137
6155
|
const layout = componentReader.valueOr("layout", "long");
|
|
6138
6156
|
const isSourceDocumentDisplayed = componentReader.valueOr("source-document-displayed", true);
|
|
6139
6157
|
properties = {
|
|
@@ -6151,7 +6169,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6151
6169
|
let href = componentReader.linkTarget("navigate-to", transformPermanentIdentificationUrlToItemLink);
|
|
6152
6170
|
if (href === null) {
|
|
6153
6171
|
href = componentReader.linkTarget("link-to", transformPermanentIdentificationUrlToItemLink);
|
|
6154
|
-
if (href === null) throw new Error(formatComponentError("Properties “navigate-to” or “link-to” not found", componentName, elementResource));
|
|
6172
|
+
if (href === null) throw new Error(formatComponentError("Properties “navigate-to” or “link-to” not found", componentName, elementResource), { cause: componentProperty });
|
|
6155
6173
|
else isExternal = true;
|
|
6156
6174
|
}
|
|
6157
6175
|
const startIcon = componentReader.value("start-icon");
|
|
@@ -6180,7 +6198,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6180
6198
|
}
|
|
6181
6199
|
case "collection": {
|
|
6182
6200
|
const setLinks = getWebsiteLinks(websiteLinks, "set");
|
|
6183
|
-
if (setLinks.length === 0) throw new Error(formatComponentError("Set links not found", componentName, elementResource));
|
|
6201
|
+
if (setLinks.length === 0) throw new Error(formatComponentError("Set links not found", componentName, elementResource), { cause: componentProperty });
|
|
6184
6202
|
const displayedProperties = componentReader.property("use-property");
|
|
6185
6203
|
const variant = componentReader.valueOr("variant", "slide");
|
|
6186
6204
|
const paginationVariant = componentReader.valueOr("pagination-variant", "default");
|
|
@@ -6229,7 +6247,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6229
6247
|
break;
|
|
6230
6248
|
case "entries": {
|
|
6231
6249
|
const entriesLink = findWebsiteLinkByCategories(websiteLinks, ["set", "tree"]);
|
|
6232
|
-
if (entriesLink == null) throw new Error(formatComponentError("Entries link not found", componentName, elementResource));
|
|
6250
|
+
if (entriesLink == null) throw new Error(formatComponentError("Entries link not found", componentName, elementResource), { cause: componentProperty });
|
|
6233
6251
|
const variant = componentReader.valueOr("variant", "entry");
|
|
6234
6252
|
const isFilterInputDisplayed = componentReader.valueOr("filter-input-displayed", false);
|
|
6235
6253
|
properties = {
|
|
@@ -6242,7 +6260,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6242
6260
|
}
|
|
6243
6261
|
case "iframe": {
|
|
6244
6262
|
const webpageLink = findWebsiteLink(websiteLinks, "resource", (link) => link.type === "webpage");
|
|
6245
|
-
if (webpageLink?.href == null) throw new Error(formatComponentError("URL not found", componentName, elementResource));
|
|
6263
|
+
if (webpageLink?.href == null) throw new Error(formatComponentError("URL not found", componentName, elementResource), { cause: componentProperty });
|
|
6246
6264
|
properties = {
|
|
6247
6265
|
component: "iframe",
|
|
6248
6266
|
href: transformPermanentIdentificationUrlToItemLink(webpageLink.href),
|
|
@@ -6253,7 +6271,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6253
6271
|
}
|
|
6254
6272
|
case "iiif-viewer": {
|
|
6255
6273
|
const manifestLink = findWebsiteLink(websiteLinks, "resource", (link) => link.type === "IIIF");
|
|
6256
|
-
if (manifestLink == null) throw new Error(formatComponentError("Manifest link not found", componentName, elementResource));
|
|
6274
|
+
if (manifestLink == null) throw new Error(formatComponentError("Manifest link not found", componentName, elementResource), { cause: componentProperty });
|
|
6257
6275
|
const variant = componentReader.valueOr("variant", "universal-viewer");
|
|
6258
6276
|
properties = {
|
|
6259
6277
|
component: "iiif-viewer",
|
|
@@ -6263,7 +6281,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6263
6281
|
break;
|
|
6264
6282
|
}
|
|
6265
6283
|
case "image": {
|
|
6266
|
-
if (websiteLinks.length === 0) throw new Error(formatComponentError("No links found", componentName, elementResource));
|
|
6284
|
+
if (websiteLinks.length === 0) throw new Error(formatComponentError("No links found", componentName, elementResource), { cause: componentProperty });
|
|
6267
6285
|
const imageQuality = componentReader.valueOr("image-quality", "high");
|
|
6268
6286
|
const images = [];
|
|
6269
6287
|
for (const link of websiteLinks) images.push({
|
|
@@ -6333,7 +6351,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6333
6351
|
}
|
|
6334
6352
|
case "image-gallery": {
|
|
6335
6353
|
const galleryLink = findWebsiteLinkByCategories(websiteLinks, ["set", "tree"]);
|
|
6336
|
-
if (galleryLink == null) throw new Error(formatComponentError("Image gallery link not found", componentName, elementResource));
|
|
6354
|
+
if (galleryLink == null) throw new Error(formatComponentError("Image gallery link not found", componentName, elementResource), { cause: componentProperty });
|
|
6337
6355
|
const isFilterInputDisplayed = componentReader.valueOr("filter-input-displayed", true);
|
|
6338
6356
|
properties = {
|
|
6339
6357
|
component: "image-gallery",
|
|
@@ -6344,7 +6362,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6344
6362
|
}
|
|
6345
6363
|
case "map": {
|
|
6346
6364
|
const mapLink = findWebsiteLinkByCategories(websiteLinks, ["set", "tree"]);
|
|
6347
|
-
if (mapLink == null) throw new Error(formatComponentError("Map link not found", componentName, elementResource));
|
|
6365
|
+
if (mapLink == null) throw new Error(formatComponentError("Map link not found", componentName, elementResource), { cause: componentProperty });
|
|
6348
6366
|
const isInteractive = componentReader.valueOr("is-interactive", true);
|
|
6349
6367
|
const isClustered = componentReader.valueOr("is-clustered", false);
|
|
6350
6368
|
const isUsingPins = componentReader.valueOr("is-using-pins", false);
|
|
@@ -6373,9 +6391,9 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6373
6391
|
}
|
|
6374
6392
|
case "query": {
|
|
6375
6393
|
const setLinks = getWebsiteLinks(websiteLinks, "set");
|
|
6376
|
-
if (setLinks.length === 0) throw new Error(formatComponentError("Set links not found", componentName, elementResource));
|
|
6394
|
+
if (setLinks.length === 0) throw new Error(formatComponentError("Set links not found", componentName, elementResource), { cause: componentProperty });
|
|
6377
6395
|
const items = [];
|
|
6378
|
-
if (componentProperty.properties.length === 0) throw new Error(formatComponentError("Query properties not found", componentName, elementResource));
|
|
6396
|
+
if (componentProperty.properties.length === 0) throw new Error(formatComponentError("Query properties not found", componentName, elementResource), { cause: componentProperty });
|
|
6379
6397
|
for (const queryItem of componentProperty.properties) {
|
|
6380
6398
|
const queryReader = websitePresentationReader(queryItem.properties);
|
|
6381
6399
|
const label = queryReader.multilingualValue("query-prompt", options);
|
|
@@ -6385,9 +6403,9 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6385
6403
|
if (queryLanguage == null) throw new Error(formatComponentError("Query language not found", componentName, elementResource));
|
|
6386
6404
|
const queries = [];
|
|
6387
6405
|
for (const propertyVariable of propertyVariables) {
|
|
6388
|
-
if (propertyVariable.uuid === null) throw new Error(formatComponentError("Property variable UUID not found", componentName, elementResource));
|
|
6406
|
+
if (propertyVariable.uuid === null) throw new Error(formatComponentError("Property variable UUID not found", componentName, elementResource), { cause: propertyVariable });
|
|
6389
6407
|
const dataType = propertyVariable.dataType;
|
|
6390
|
-
if (dataType === "coordinate") throw new Error(formatComponentError("Query prompts with data type \"coordinate\" are not supported", componentName, elementResource));
|
|
6408
|
+
if (dataType === "coordinate") throw new Error(formatComponentError("Query prompts with data type \"coordinate\" are not supported", componentName, elementResource), { cause: propertyVariable });
|
|
6391
6409
|
queries.push({
|
|
6392
6410
|
target: "property",
|
|
6393
6411
|
propertyVariable: propertyVariable.uuid,
|
|
@@ -6406,7 +6424,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6406
6424
|
endIcon
|
|
6407
6425
|
});
|
|
6408
6426
|
}
|
|
6409
|
-
if (items.length === 0) throw new Error(formatComponentError("No queries found", componentName, elementResource));
|
|
6427
|
+
if (items.length === 0) throw new Error(formatComponentError("No queries found", componentName, elementResource), { cause: componentProperty });
|
|
6410
6428
|
const componentOptions = parseWebsiteOptions(elementResource.options, options);
|
|
6411
6429
|
const displayedProperties = componentReader.property("use-property");
|
|
6412
6430
|
const variant = componentReader.valueOr("variant", "slide");
|
|
@@ -6433,7 +6451,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6433
6451
|
}
|
|
6434
6452
|
case "table": {
|
|
6435
6453
|
const tableLink = findWebsiteLink(websiteLinks, "set");
|
|
6436
|
-
if (tableLink == null) throw new Error(formatComponentError("Table link not found", componentName, elementResource));
|
|
6454
|
+
if (tableLink == null) throw new Error(formatComponentError("Table link not found", componentName, elementResource), { cause: componentProperty });
|
|
6437
6455
|
properties = {
|
|
6438
6456
|
component: "table",
|
|
6439
6457
|
linkUuid: tableLink.uuid
|
|
@@ -6444,7 +6462,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6444
6462
|
const queryVariant = componentReader.valueOr("query-variant", "submit");
|
|
6445
6463
|
const boundElementUuid = componentReader.uuid("bound-element");
|
|
6446
6464
|
const href = componentReader.linkTarget("link-to", transformPermanentIdentificationUrlToItemLink);
|
|
6447
|
-
if (!boundElementUuid && !href) throw new Error(formatComponentError("Bound element or href not found", componentName, elementResource));
|
|
6465
|
+
if (!boundElementUuid && !href) throw new Error(formatComponentError("Bound element or href not found", componentName, elementResource), { cause: componentProperty });
|
|
6448
6466
|
properties = {
|
|
6449
6467
|
component: "search-bar",
|
|
6450
6468
|
queryVariant,
|
|
@@ -6457,7 +6475,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6457
6475
|
}
|
|
6458
6476
|
case "text": {
|
|
6459
6477
|
const content = elementResource.document && "content" in elementResource.document ? parseXMLContent(elementResource.document, options) : null;
|
|
6460
|
-
if (content == null) throw new Error(formatComponentError("Content not found", componentName, elementResource));
|
|
6478
|
+
if (content == null) throw new Error(formatComponentError("Content not found", componentName, elementResource), { cause: componentProperty });
|
|
6461
6479
|
let variantName = "block";
|
|
6462
6480
|
let variant;
|
|
6463
6481
|
const variantProperty = componentReader.property("variant");
|
|
@@ -6503,7 +6521,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6503
6521
|
}
|
|
6504
6522
|
case "timeline": {
|
|
6505
6523
|
const timelineLink = findWebsiteLink(websiteLinks, "tree");
|
|
6506
|
-
if (timelineLink == null) throw new Error(formatComponentError("Timeline link not found", componentName, elementResource));
|
|
6524
|
+
if (timelineLink == null) throw new Error(formatComponentError("Timeline link not found", componentName, elementResource), { cause: componentProperty });
|
|
6507
6525
|
properties = {
|
|
6508
6526
|
component: "timeline",
|
|
6509
6527
|
linkUuid: timelineLink.uuid
|
|
@@ -6512,7 +6530,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6512
6530
|
}
|
|
6513
6531
|
case "video": {
|
|
6514
6532
|
const videoLink = findWebsiteLink(websiteLinks, "resource", (link) => link.type === "video");
|
|
6515
|
-
if (videoLink == null) throw new Error(formatComponentError("Video link not found", componentName, elementResource));
|
|
6533
|
+
if (videoLink == null) throw new Error(formatComponentError("Video link not found", componentName, elementResource), { cause: componentProperty });
|
|
6516
6534
|
const isChaptersDisplayed = componentReader.valueOr("chapters-displayed", true);
|
|
6517
6535
|
properties = {
|
|
6518
6536
|
component: "video",
|
|
@@ -6525,7 +6543,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6525
6543
|
console.warn(`Invalid or non-implemented component name “${unparsedComponentName.toString()}” for the following element: “${parseStringContent(elementResource.identification.label, options)}”`);
|
|
6526
6544
|
break;
|
|
6527
6545
|
}
|
|
6528
|
-
if (properties === null) throw new Error(formatComponentError("Properties not found", componentName, elementResource));
|
|
6546
|
+
if (properties === null) throw new Error(formatComponentError("Properties not found", componentName, elementResource), { cause: componentProperty });
|
|
6529
6547
|
return properties;
|
|
6530
6548
|
}
|
|
6531
6549
|
function parseWebTitle(properties, identification, overrides) {
|
|
@@ -6586,7 +6604,7 @@ function parseWebpage(webpageResource, options, context, slugPrefix) {
|
|
|
6586
6604
|
if (webpageReader.value("presentation") !== "page") return null;
|
|
6587
6605
|
const identification = parseIdentification(webpageResource.identification, options);
|
|
6588
6606
|
const slug = webpageResource.slug?.replace(SEGMENT_UNIQUE_SLUG_PREFIX_REGEX, "") ?? null;
|
|
6589
|
-
if (slug == null) throw new Error(`Slug not found for page (${formatXMLWebsiteResourceMetadata(webpageResource)})
|
|
6607
|
+
if (slug == null) throw new Error(`Slug not found for page (${formatXMLWebsiteResourceMetadata(webpageResource)})`, { cause: webpageResource });
|
|
6590
6608
|
const returnWebpage = {
|
|
6591
6609
|
uuid: webpageResource.uuid,
|
|
6592
6610
|
type: "page",
|
|
@@ -6673,7 +6691,7 @@ function parseWebsiteSegments(resources, context, options, slugPrefix) {
|
|
|
6673
6691
|
if (!("segments" in resource)) continue;
|
|
6674
6692
|
for (const tree of resource.segments.tree) {
|
|
6675
6693
|
const segmentSlug = tree.identification.abbreviation == null ? null : parseStringContent(tree.identification.abbreviation, options);
|
|
6676
|
-
if (segmentSlug == null) throw new Error(`Slug not found for segment website (website uuid “${tree.uuid}”)
|
|
6694
|
+
if (segmentSlug == null) throw new Error(`Slug not found for segment website (website uuid “${tree.uuid}”)`, { cause: tree });
|
|
6677
6695
|
segments.push(parseWebsiteTree(tree, context, "segment", options, prefixSlug(segmentSlug, slugPrefix)));
|
|
6678
6696
|
}
|
|
6679
6697
|
}
|
|
@@ -6854,9 +6872,9 @@ function parseWebBlock(blockResource, options) {
|
|
|
6854
6872
|
for (const resource of blockResources) {
|
|
6855
6873
|
const resourceReader = websitePresentationReader(resource.properties ? parseSimplifiedProperties(resource.properties, options) : []);
|
|
6856
6874
|
const resourceType = resourceReader.value("presentation");
|
|
6857
|
-
if (resourceType !== "element") throw new Error(`Accordion only accepts elements, but got “${resourceType}” (${formatXMLWebsiteResourceMetadata(resource)})
|
|
6875
|
+
if (resourceType !== "element") throw new Error(`Accordion only accepts elements, but got “${resourceType}” (${formatXMLWebsiteResourceMetadata(resource)})`, { cause: resource });
|
|
6858
6876
|
const componentType = resourceReader.nestedByValue("presentation", "element").value("component");
|
|
6859
|
-
if (componentType !== "text") throw new Error(`Accordion only accepts text components, but got “${componentType}” (${formatXMLWebsiteResourceMetadata(resource)})
|
|
6877
|
+
if (componentType !== "text") throw new Error(`Accordion only accepts text components, but got “${componentType}” (${formatXMLWebsiteResourceMetadata(resource)})`, { cause: resource });
|
|
6860
6878
|
const element = parseWebElementForAccordion(resource, options);
|
|
6861
6879
|
accordionItems.push(element);
|
|
6862
6880
|
}
|
|
@@ -6950,7 +6968,7 @@ function parseWebsiteProperties(properties, websiteTree, sidebar, options) {
|
|
|
6950
6968
|
name: contactContent[0],
|
|
6951
6969
|
email: contactContent[1] ?? null
|
|
6952
6970
|
};
|
|
6953
|
-
else throw new Error(`Contact property must use “name;email”, got “${contactProperty.values[0]?.content}” (website uuid “${websiteTree.uuid}”)
|
|
6971
|
+
else throw new Error(`Contact property must use “name;email”, got “${contactProperty.values[0]?.content}” (website uuid “${websiteTree.uuid}”)`, { cause: websiteTree });
|
|
6954
6972
|
}
|
|
6955
6973
|
returnProperties.loadingVariant = websiteReader.valueOr("loading-variant", "spinner");
|
|
6956
6974
|
returnProperties.theme.isThemeToggleDisplayed = websiteReader.valueOr("supports-theme-toggle", true);
|
|
@@ -7056,8 +7074,8 @@ function parseFilterContexts(filterContextLevels, options) {
|
|
|
7056
7074
|
return filterContextTreeLevels;
|
|
7057
7075
|
}
|
|
7058
7076
|
function parseWebsiteTree(websiteTree, context, type, options, slugPrefix) {
|
|
7059
|
-
if (!websiteTree.properties) throw new Error(`Website properties not found (website uuid “${websiteTree.uuid}”)
|
|
7060
|
-
if (type === "website" && websiteTree.items?.resource == null) throw new Error(`Website pages not found (website uuid “${websiteTree.uuid}”)
|
|
7077
|
+
if (!websiteTree.properties) throw new Error(`Website properties not found (website uuid “${websiteTree.uuid}”)`, { cause: websiteTree });
|
|
7078
|
+
if (type === "website" && websiteTree.items?.resource == null) throw new Error(`Website pages not found (website uuid “${websiteTree.uuid}”)`, { cause: websiteTree });
|
|
7061
7079
|
const resources = normalizeWebsiteResources(websiteTree.items?.resource);
|
|
7062
7080
|
const sidebar = parseSidebar(resources, options);
|
|
7063
7081
|
const properties = parseWebsiteProperties(websiteTree.properties.property, websiteTree, sidebar, options);
|
|
@@ -7081,7 +7099,7 @@ function parseWebsite(data, options) {
|
|
|
7081
7099
|
const parserOptions = { languages };
|
|
7082
7100
|
const defaultLanguage = resolveDefaultLanguage(rawOchre, languages);
|
|
7083
7101
|
const websiteTree = rawOchre.tree[0];
|
|
7084
|
-
if (websiteTree == null) throw new Error("Website tree not found");
|
|
7102
|
+
if (websiteTree == null) throw new Error("Website tree not found", { cause: data });
|
|
7085
7103
|
return parseWebsiteTree(websiteTree, {
|
|
7086
7104
|
belongsTo: {
|
|
7087
7105
|
uuid: rawOchre.uuidBelongsTo,
|
|
@@ -7102,13 +7120,13 @@ async function fetchWebsite(abbreviation, options) {
|
|
|
7102
7120
|
try {
|
|
7103
7121
|
const cleanAbbreviation = abbreviation.trim().toLocaleLowerCase("en-US");
|
|
7104
7122
|
const response = await (options?.fetch ?? fetch)(`https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?xquery=${encodeURIComponent(`collection('ochre/tree')/ochre[tree/identification/abbreviation/content/string='${cleanAbbreviation}']`)}&xsl=none&lang="*"`);
|
|
7105
|
-
if (!response.ok) throw new Error("Failed to fetch website");
|
|
7123
|
+
if (!response.ok) throw new Error("Failed to fetch website", { cause: response.statusText });
|
|
7106
7124
|
const dataRaw = await response.text();
|
|
7107
7125
|
const data = new XMLParser(XML_PARSER_OPTIONS).parse(dataRaw);
|
|
7108
7126
|
const { success, issues, output } = v.safeParse(XMLWebsiteData, data);
|
|
7109
7127
|
if (!success) {
|
|
7110
7128
|
logIssues(issues);
|
|
7111
|
-
throw new Error("Failed to parse website XML");
|
|
7129
|
+
throw new Error("Failed to parse website XML", { cause: issues });
|
|
7112
7130
|
}
|
|
7113
7131
|
restoreXMLMetadata(output, data);
|
|
7114
7132
|
return {
|