ochre-sdk 1.0.0 → 1.0.2
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/dist/index.mjs +286 -138
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -54,6 +54,7 @@ const XML_ARRAY_TAGS = [
|
|
|
54
54
|
];
|
|
55
55
|
const XML_PARSER_OPTIONS = {
|
|
56
56
|
alwaysCreateTextNode: true,
|
|
57
|
+
captureMetaData: true,
|
|
57
58
|
ignoreAttributes: false,
|
|
58
59
|
removeNSPrefix: true,
|
|
59
60
|
ignorePiTags: true,
|
|
@@ -814,6 +815,34 @@ const setItemsParamsSchema = v.object({
|
|
|
814
815
|
pageSize: v.optional(positiveNumber("Page size must be positive"), 48)
|
|
815
816
|
});
|
|
816
817
|
//#endregion
|
|
818
|
+
//#region src/xml/metadata.ts
|
|
819
|
+
const XML_METADATA_SYMBOL = XMLParser.getMetaDataSymbol();
|
|
820
|
+
function isRecord$4(value) {
|
|
821
|
+
return typeof value === "object" && value != null;
|
|
822
|
+
}
|
|
823
|
+
function getXMLMetadata(value) {
|
|
824
|
+
if (!isRecord$4(value)) return null;
|
|
825
|
+
return value[XML_METADATA_SYMBOL] ?? null;
|
|
826
|
+
}
|
|
827
|
+
function getXMLSourceIndex(value) {
|
|
828
|
+
const startIndex = getXMLMetadata(value)?.startIndex;
|
|
829
|
+
return typeof startIndex === "number" ? startIndex : null;
|
|
830
|
+
}
|
|
831
|
+
function restoreXMLMetadata(output, input) {
|
|
832
|
+
if (!isRecord$4(output) || !isRecord$4(input)) return;
|
|
833
|
+
const metadata = getXMLMetadata(input);
|
|
834
|
+
if (metadata != null) Object.defineProperty(output, XML_METADATA_SYMBOL, {
|
|
835
|
+
value: metadata,
|
|
836
|
+
enumerable: false,
|
|
837
|
+
configurable: true
|
|
838
|
+
});
|
|
839
|
+
if (Array.isArray(output) && Array.isArray(input)) {
|
|
840
|
+
for (const [index, outputValue] of output.entries()) restoreXMLMetadata(outputValue, input[index]);
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
for (const [key, outputValue] of Object.entries(output)) restoreXMLMetadata(outputValue, input[key]);
|
|
844
|
+
}
|
|
845
|
+
//#endregion
|
|
817
846
|
//#region src/parsers/string.ts
|
|
818
847
|
const TEXT_ANNOTATION_TOKEN = "text-annotation";
|
|
819
848
|
const TEXT_STYLING_TOKEN = "text-styling";
|
|
@@ -979,19 +1008,20 @@ function parseXMLString(string, options) {
|
|
|
979
1008
|
*/
|
|
980
1009
|
function createMDXComponent(variant, properties) {
|
|
981
1010
|
const { uuid, href, height, width, content, text } = properties;
|
|
1011
|
+
const tooltipContent = getDistinctTooltipContent(content, text);
|
|
982
1012
|
let returnString = "";
|
|
983
1013
|
switch (variant) {
|
|
984
1014
|
case "inlineImage":
|
|
985
1015
|
returnString = `<InlineImage uuid="${uuid}"${createMDXStringAttribute("content", content)} height={${height ?? "null"}} width={${width ?? "null"}} />`;
|
|
986
1016
|
break;
|
|
987
1017
|
case "internalLink":
|
|
988
|
-
returnString = `<InternalLink uuid="${uuid}"${createMDXStringAttribute("content",
|
|
1018
|
+
returnString = `<InternalLink uuid="${uuid}"${createMDXStringAttribute("content", tooltipContent)}>${text}</InternalLink>`;
|
|
989
1019
|
break;
|
|
990
1020
|
case "externalLink":
|
|
991
|
-
returnString = `<ExternalLink href="${href == null ? "#" : transformPermanentIdentificationUrl(href)}"${createMDXStringAttribute("content",
|
|
1021
|
+
returnString = `<ExternalLink href="${href == null ? "#" : transformPermanentIdentificationUrl(href)}"${createMDXStringAttribute("content", tooltipContent)}>${text}</ExternalLink>`;
|
|
992
1022
|
break;
|
|
993
1023
|
case "documentLink":
|
|
994
|
-
returnString = String.raw`<ExternalLink href="https:\/\/ochre.lib.uchicago.edu/ochre/v2/ochre.php?uuid=${uuid}&load"${createMDXStringAttribute("content",
|
|
1024
|
+
returnString = String.raw`<ExternalLink href="https:\/\/ochre.lib.uchicago.edu/ochre/v2/ochre.php?uuid=${uuid}&load"${createMDXStringAttribute("content", tooltipContent)}>${text}</ExternalLink>`;
|
|
995
1025
|
break;
|
|
996
1026
|
case "tooltipSpan":
|
|
997
1027
|
returnString = `<TooltipSpan${createMDXStringAttribute("content", content)}>${text}</TooltipSpan>`;
|
|
@@ -999,6 +1029,9 @@ function createMDXComponent(variant, properties) {
|
|
|
999
1029
|
}
|
|
1000
1030
|
return returnString;
|
|
1001
1031
|
}
|
|
1032
|
+
function getDistinctTooltipContent(content, textContent) {
|
|
1033
|
+
return content === textContent ? void 0 : content;
|
|
1034
|
+
}
|
|
1002
1035
|
function createMDXStringAttribute(name, value) {
|
|
1003
1036
|
if (value == null || value === "") return "";
|
|
1004
1037
|
return ` ${name}=${MDX_QUOTED_ATTRIBUTE_ESCAPE_REGEX.test(value) ? `{${JSON.stringify(value)}}` : `"${value}"`}`;
|
|
@@ -1144,16 +1177,31 @@ function createInternalLinkComponent(properties) {
|
|
|
1144
1177
|
case "hover-card": return `<Annotation type="hover-card" uuid="${properties.uuid}">${innerContent}</Annotation>`;
|
|
1145
1178
|
case "item-page": return `<InternalLink type="item" uuid="${properties.uuid}">${innerContent}</InternalLink>`;
|
|
1146
1179
|
case "entry-page": return `<InternalLink type="entry" uuid="${properties.uuid}">${innerContent}</InternalLink>`;
|
|
1147
|
-
default: return `<InternalLink uuid="${properties.uuid}"${properties.propertyMetadata != null ? ` properties="${properties.propertyMetadata.labelUuid}"${properties.propertyMetadata.valueUuid != null ? ` value="${properties.propertyMetadata.valueUuid}"` : ""}` : ""}${createMDXStringAttribute("content", properties.content)}>${innerContent}</InternalLink>`;
|
|
1180
|
+
default: return `<InternalLink uuid="${properties.uuid}"${properties.propertyMetadata != null ? ` properties="${properties.propertyMetadata.labelUuid}"${properties.propertyMetadata.valueUuid != null ? ` value="${properties.propertyMetadata.valueUuid}"` : ""}` : ""}${createMDXStringAttribute("content", getDistinctTooltipContent(properties.content, properties.text))}>${innerContent}</InternalLink>`;
|
|
1148
1181
|
}
|
|
1149
1182
|
}
|
|
1150
1183
|
function getXMLRichTextLinks(item) {
|
|
1151
1184
|
const links = [];
|
|
1185
|
+
let fallbackIndex = 0;
|
|
1152
1186
|
for (const rawLinks of Object.values(item.links ?? {})) {
|
|
1153
1187
|
if (!Array.isArray(rawLinks)) continue;
|
|
1154
|
-
for (const rawLink of rawLinks) if (isXMLRichTextLink(rawLink) && !isTextAnnotationMarkerLink(rawLink))
|
|
1188
|
+
for (const rawLink of rawLinks) if (isXMLRichTextLink(rawLink) && !isTextAnnotationMarkerLink(rawLink)) {
|
|
1189
|
+
links.push({
|
|
1190
|
+
link: rawLink,
|
|
1191
|
+
fallbackIndex
|
|
1192
|
+
});
|
|
1193
|
+
fallbackIndex += 1;
|
|
1194
|
+
}
|
|
1155
1195
|
}
|
|
1156
|
-
|
|
1196
|
+
links.sort((left, right) => {
|
|
1197
|
+
const leftIndex = getXMLSourceIndex(left.link);
|
|
1198
|
+
const rightIndex = getXMLSourceIndex(right.link);
|
|
1199
|
+
if (leftIndex != null && rightIndex != null && leftIndex !== rightIndex) return leftIndex - rightIndex;
|
|
1200
|
+
return left.fallbackIndex - right.fallbackIndex;
|
|
1201
|
+
});
|
|
1202
|
+
const sortedLinks = [];
|
|
1203
|
+
for (const { link } of links) sortedLinks.push(link);
|
|
1204
|
+
return sortedLinks;
|
|
1157
1205
|
}
|
|
1158
1206
|
function renderRichTextItem(item, linkString, contentItem, options) {
|
|
1159
1207
|
const { languages, rendering } = options;
|
|
@@ -1556,29 +1604,83 @@ function normalizeCategory(category) {
|
|
|
1556
1604
|
function isHeadingItemCategory(category) {
|
|
1557
1605
|
return HEADING_ITEM_CATEGORIES.includes(category);
|
|
1558
1606
|
}
|
|
1559
|
-
function pushCategoryIfPresent(categories, category, items) {
|
|
1560
|
-
if ((items?.length ?? 0) === 0) return;
|
|
1561
|
-
pushCategory(categories, category);
|
|
1562
|
-
}
|
|
1563
1607
|
function pushCategory(categories, category) {
|
|
1564
1608
|
if (!categories.includes(category)) categories.push(category);
|
|
1565
1609
|
}
|
|
1610
|
+
function getHierarchyEntryCategory(key) {
|
|
1611
|
+
switch (key) {
|
|
1612
|
+
case "heading":
|
|
1613
|
+
case "tree":
|
|
1614
|
+
case "bibliography":
|
|
1615
|
+
case "concept":
|
|
1616
|
+
case "spatialUnit":
|
|
1617
|
+
case "period":
|
|
1618
|
+
case "person":
|
|
1619
|
+
case "resource":
|
|
1620
|
+
case "text":
|
|
1621
|
+
case "set":
|
|
1622
|
+
case "dictionaryUnit": return key;
|
|
1623
|
+
case "propertyVariable":
|
|
1624
|
+
case "variable": return "propertyVariable";
|
|
1625
|
+
case "propertyValue":
|
|
1626
|
+
case "value": return "propertyValue";
|
|
1627
|
+
default: return null;
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
function isRecord$3(value) {
|
|
1631
|
+
return typeof value === "object" && value != null;
|
|
1632
|
+
}
|
|
1633
|
+
function isResourceWrapper(value) {
|
|
1634
|
+
return isRecord$3(value) && !("uuid" in value) && Array.isArray(value.resource);
|
|
1635
|
+
}
|
|
1636
|
+
function sourceOrderSort(left, right) {
|
|
1637
|
+
const leftIndex = getXMLSourceIndex(left.item);
|
|
1638
|
+
const rightIndex = getXMLSourceIndex(right.item);
|
|
1639
|
+
if (leftIndex != null && rightIndex != null && leftIndex !== rightIndex) return leftIndex - rightIndex;
|
|
1640
|
+
return left.fallbackIndex - right.fallbackIndex;
|
|
1641
|
+
}
|
|
1642
|
+
function collectHierarchyEntries(hierarchy, categories) {
|
|
1643
|
+
const entries = [];
|
|
1644
|
+
if (hierarchy == null) return entries;
|
|
1645
|
+
let fallbackIndex = 0;
|
|
1646
|
+
for (const key of Object.keys(hierarchy)) {
|
|
1647
|
+
const category = getHierarchyEntryCategory(key);
|
|
1648
|
+
if (category == null || !(categories == null || categories.includes(category))) continue;
|
|
1649
|
+
const values = hierarchy[key];
|
|
1650
|
+
if (!Array.isArray(values)) continue;
|
|
1651
|
+
for (const value of values) {
|
|
1652
|
+
if (category === "resource" && isResourceWrapper(value)) {
|
|
1653
|
+
for (const resource of value.resource) {
|
|
1654
|
+
entries.push({
|
|
1655
|
+
category,
|
|
1656
|
+
item: resource,
|
|
1657
|
+
fallbackIndex
|
|
1658
|
+
});
|
|
1659
|
+
fallbackIndex += 1;
|
|
1660
|
+
}
|
|
1661
|
+
continue;
|
|
1662
|
+
}
|
|
1663
|
+
entries.push({
|
|
1664
|
+
category,
|
|
1665
|
+
item: value,
|
|
1666
|
+
fallbackIndex
|
|
1667
|
+
});
|
|
1668
|
+
fallbackIndex += 1;
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
entries.sort(sourceOrderSort);
|
|
1672
|
+
return entries;
|
|
1673
|
+
}
|
|
1566
1674
|
function inferItemCategories(hierarchy) {
|
|
1567
1675
|
const categories = [];
|
|
1568
1676
|
if (hierarchy == null) return categories;
|
|
1569
|
-
for (const
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
pushCategoryIfPresent(categories, category, hierarchy.propertyVariable);
|
|
1573
|
-
pushCategoryIfPresent(categories, category, hierarchy.variable);
|
|
1574
|
-
continue;
|
|
1575
|
-
}
|
|
1576
|
-
if (category === "propertyValue") {
|
|
1577
|
-
pushCategoryIfPresent(categories, category, hierarchy.propertyValue);
|
|
1578
|
-
pushCategoryIfPresent(categories, category, hierarchy.value);
|
|
1677
|
+
for (const entry of collectHierarchyEntries(hierarchy)) {
|
|
1678
|
+
if (entry.category === "heading") {
|
|
1679
|
+
for (const category of inferItemCategories(entry.item)) pushCategory(categories, category);
|
|
1579
1680
|
continue;
|
|
1580
1681
|
}
|
|
1581
|
-
|
|
1682
|
+
if (entry.category === "dictionaryUnit") continue;
|
|
1683
|
+
pushCategory(categories, entry.category);
|
|
1582
1684
|
}
|
|
1583
1685
|
return categories;
|
|
1584
1686
|
}
|
|
@@ -1864,62 +1966,79 @@ function withoutItems(item) {
|
|
|
1864
1966
|
const { items: _items, ...itemWithoutItems } = item;
|
|
1865
1967
|
return itemWithoutItems;
|
|
1866
1968
|
}
|
|
1969
|
+
function parseEmbeddedItemEntry(entry, options) {
|
|
1970
|
+
switch (entry.category) {
|
|
1971
|
+
case "tree": return parseTree(entry.item, {
|
|
1972
|
+
...options,
|
|
1973
|
+
containedItemCategory: normalizeTreeItemCategory(options.containedItemCategory)
|
|
1974
|
+
});
|
|
1975
|
+
case "bibliography": return parseBibliography(entry.item, options);
|
|
1976
|
+
case "concept": return parseConcept(entry.item, options);
|
|
1977
|
+
case "spatialUnit": return parseSpatialUnit(entry.item, options);
|
|
1978
|
+
case "period": return parsePeriod(entry.item, options);
|
|
1979
|
+
case "person": return parsePerson(entry.item, options);
|
|
1980
|
+
case "propertyVariable": return parsePropertyVariable(entry.item, options);
|
|
1981
|
+
case "propertyValue": return parsePropertyValue(entry.item, options);
|
|
1982
|
+
case "resource": return parseResource(entry.item, options);
|
|
1983
|
+
case "text": return parseText(entry.item, options);
|
|
1984
|
+
case "set": return parseSet(entry.item, options);
|
|
1985
|
+
case "dictionaryUnit":
|
|
1986
|
+
case "heading": return null;
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1867
1989
|
function parseItemHierarchy(hierarchy, options, categories) {
|
|
1868
1990
|
const items = [];
|
|
1869
1991
|
if (hierarchy == null) return items;
|
|
1870
|
-
const
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
if (shouldParse("concept")) for (const concept of hierarchy.concept ?? []) items.push(parseConcept(concept, options));
|
|
1874
|
-
if (shouldParse("spatialUnit")) for (const spatialUnit of hierarchy.spatialUnit ?? []) items.push(parseSpatialUnit(spatialUnit, options));
|
|
1875
|
-
if (shouldParse("period")) for (const period of hierarchy.period ?? []) items.push(parsePeriod(period, options));
|
|
1876
|
-
if (shouldParse("person")) for (const person of hierarchy.person ?? []) items.push(parsePerson(person, options));
|
|
1877
|
-
if (shouldParse("propertyVariable")) {
|
|
1878
|
-
for (const propertyVariable of hierarchy.propertyVariable ?? []) items.push(parsePropertyVariable(propertyVariable, options));
|
|
1879
|
-
for (const propertyVariable of hierarchy.variable ?? []) items.push(parsePropertyVariable(propertyVariable, options));
|
|
1880
|
-
}
|
|
1881
|
-
if (shouldParse("propertyValue")) {
|
|
1882
|
-
for (const propertyValue of hierarchy.propertyValue ?? []) items.push(parsePropertyValue(propertyValue, options));
|
|
1883
|
-
for (const propertyValue of hierarchy.value ?? []) items.push(parsePropertyValue(propertyValue, options));
|
|
1884
|
-
}
|
|
1885
|
-
if (shouldParse("resource")) for (const resource of hierarchy.resource ?? []) {
|
|
1886
|
-
if (!("uuid" in resource)) {
|
|
1887
|
-
for (const embeddedResource of resource.resource) items.push(parseResource(embeddedResource, options));
|
|
1888
|
-
continue;
|
|
1889
|
-
}
|
|
1890
|
-
items.push(parseResource(resource, options));
|
|
1992
|
+
for (const entry of collectHierarchyEntries(hierarchy, categories)) {
|
|
1993
|
+
const item = parseEmbeddedItemEntry(entry, options);
|
|
1994
|
+
if (item != null) items.push(item);
|
|
1891
1995
|
}
|
|
1892
|
-
if (shouldParse("text")) for (const text of hierarchy.text ?? []) items.push(parseText(text, options));
|
|
1893
|
-
if (shouldParse("set")) for (const set of hierarchy.set ?? []) items.push(parseSet(set, options));
|
|
1894
1996
|
return items;
|
|
1895
1997
|
}
|
|
1896
1998
|
function parseSetItemHierarchy(hierarchy, options, categories) {
|
|
1897
1999
|
const items = [];
|
|
1898
2000
|
if (hierarchy == null) return items;
|
|
1899
|
-
const
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
2001
|
+
for (const entry of collectHierarchyEntries(hierarchy, categories)) switch (entry.category) {
|
|
2002
|
+
case "tree":
|
|
2003
|
+
items.push(parseSetTree(entry.item, options));
|
|
2004
|
+
break;
|
|
2005
|
+
case "bibliography":
|
|
2006
|
+
items.push(parseSetBibliography(entry.item, options));
|
|
2007
|
+
break;
|
|
2008
|
+
case "concept":
|
|
2009
|
+
items.push(parseSetConcept(entry.item, options));
|
|
2010
|
+
break;
|
|
2011
|
+
case "spatialUnit":
|
|
2012
|
+
items.push(parseSetSpatialUnit(entry.item, options));
|
|
2013
|
+
break;
|
|
2014
|
+
case "period":
|
|
2015
|
+
items.push(parseSetPeriod(entry.item, options));
|
|
2016
|
+
break;
|
|
2017
|
+
case "person": {
|
|
2018
|
+
const person = entry.item;
|
|
2019
|
+
items.push(withSetItemProperties(parsePerson(person, options), person.properties, options));
|
|
2020
|
+
break;
|
|
2021
|
+
}
|
|
2022
|
+
case "propertyVariable":
|
|
2023
|
+
items.push(parsePropertyVariable(entry.item, options));
|
|
2024
|
+
break;
|
|
2025
|
+
case "propertyValue": {
|
|
2026
|
+
const propertyValue = entry.item;
|
|
2027
|
+
items.push(withSetItemProperties(parsePropertyValue(propertyValue, options), propertyValue.properties, options));
|
|
2028
|
+
break;
|
|
1918
2029
|
}
|
|
1919
|
-
|
|
2030
|
+
case "resource":
|
|
2031
|
+
items.push(parseSetResource(entry.item, options));
|
|
2032
|
+
break;
|
|
2033
|
+
case "text":
|
|
2034
|
+
items.push(parseText(entry.item, options));
|
|
2035
|
+
break;
|
|
2036
|
+
case "set":
|
|
2037
|
+
items.push(parseSetSet(entry.item, options));
|
|
2038
|
+
break;
|
|
2039
|
+
case "dictionaryUnit":
|
|
2040
|
+
case "heading": break;
|
|
1920
2041
|
}
|
|
1921
|
-
if (shouldParse("text")) for (const text of hierarchy.text ?? []) items.push(parseText(text, options));
|
|
1922
|
-
if (shouldParse("set")) for (const set of hierarchy.set ?? []) items.push(parseSetSet(set, options));
|
|
1923
2042
|
return items;
|
|
1924
2043
|
}
|
|
1925
2044
|
function normalizeTreeLinkItemsCategory(type) {
|
|
@@ -2088,26 +2207,45 @@ function parseLinks(rawLinks, options) {
|
|
|
2088
2207
|
const links = [];
|
|
2089
2208
|
if (rawLinks == null) return links;
|
|
2090
2209
|
const hierarchy = rawLinks;
|
|
2091
|
-
for (const
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2210
|
+
for (const entry of collectHierarchyEntries(hierarchy)) switch (entry.category) {
|
|
2211
|
+
case "tree":
|
|
2212
|
+
links.push(parseTreeItemLink(entry.item, options));
|
|
2213
|
+
break;
|
|
2214
|
+
case "bibliography":
|
|
2215
|
+
links.push(parseBibliographyItemLink(entry.item, options));
|
|
2216
|
+
break;
|
|
2217
|
+
case "concept":
|
|
2218
|
+
links.push(parseConceptItemLink(entry.item, options));
|
|
2219
|
+
break;
|
|
2220
|
+
case "spatialUnit":
|
|
2221
|
+
links.push(parseSpatialUnitItemLink(entry.item, options));
|
|
2222
|
+
break;
|
|
2223
|
+
case "period":
|
|
2224
|
+
links.push(parsePeriodItemLink(entry.item, options));
|
|
2225
|
+
break;
|
|
2226
|
+
case "person":
|
|
2227
|
+
links.push(parsePersonItemLink(entry.item, options));
|
|
2228
|
+
break;
|
|
2229
|
+
case "propertyVariable":
|
|
2230
|
+
links.push(parsePropertyVariableItemLink(entry.item, options));
|
|
2231
|
+
break;
|
|
2232
|
+
case "propertyValue":
|
|
2233
|
+
links.push(parsePropertyValueItemLink(entry.item, options));
|
|
2234
|
+
break;
|
|
2235
|
+
case "resource":
|
|
2236
|
+
links.push(parseResourceItemLink(entry.item, options));
|
|
2237
|
+
break;
|
|
2238
|
+
case "text":
|
|
2239
|
+
links.push(parseTextItemLink(entry.item, options));
|
|
2240
|
+
break;
|
|
2241
|
+
case "set":
|
|
2242
|
+
links.push(parseSetItemLink(entry.item, options));
|
|
2243
|
+
break;
|
|
2244
|
+
case "dictionaryUnit":
|
|
2245
|
+
links.push(parseDictionaryUnitItemLink(entry.item, options));
|
|
2246
|
+
break;
|
|
2247
|
+
case "heading": break;
|
|
2107
2248
|
}
|
|
2108
|
-
for (const text of hierarchy.text ?? []) links.push(parseTextItemLink(text, options));
|
|
2109
|
-
for (const set of hierarchy.set ?? []) links.push(parseSetItemLink(set, options));
|
|
2110
|
-
for (const dictionaryUnit of hierarchy.dictionaryUnit ?? []) links.push(parseDictionaryUnitItemLink(dictionaryUnit, options));
|
|
2111
2249
|
return links;
|
|
2112
2250
|
}
|
|
2113
2251
|
function parseReverseLinks(rawLinks, options) {
|
|
@@ -2183,8 +2321,19 @@ function parseTree(rawTree, options) {
|
|
|
2183
2321
|
const childOptions = getParserOptions(options);
|
|
2184
2322
|
const containedItemCategory = resolveTreeItemCategory(rawTree, normalizeTreeItemCategory(options.containedItemCategory));
|
|
2185
2323
|
const items = [];
|
|
2186
|
-
if (containedItemCategory != null
|
|
2187
|
-
|
|
2324
|
+
if (containedItemCategory != null) {
|
|
2325
|
+
const itemCategories = [containedItemCategory];
|
|
2326
|
+
if (isHeadingItemCategory(containedItemCategory)) itemCategories.push("heading");
|
|
2327
|
+
for (const entry of collectHierarchyEntries(rawTree.items, itemCategories)) {
|
|
2328
|
+
if (entry.category === "heading") {
|
|
2329
|
+
if (!isHeadingItemCategory(containedItemCategory)) continue;
|
|
2330
|
+
items.push(parseHeading(entry.item, containedItemCategory, childOptions));
|
|
2331
|
+
continue;
|
|
2332
|
+
}
|
|
2333
|
+
const item = parseEmbeddedItemEntry(entry, childOptions);
|
|
2334
|
+
if (item != null) items.push(item);
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2188
2337
|
return {
|
|
2189
2338
|
...parseBaseItem("tree", rawTree, childOptions),
|
|
2190
2339
|
type: rawTree.type ?? null,
|
|
@@ -2516,22 +2665,10 @@ function parseLinkedItems(rawItems, options) {
|
|
|
2516
2665
|
containedItemCategory: options.containedItemCategory
|
|
2517
2666
|
};
|
|
2518
2667
|
const items = [];
|
|
2519
|
-
for (const
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
}
|
|
2523
|
-
for (const bibliography of rawItems?.bibliography ?? []) items.push(parseBibliography(bibliography, parserOptions));
|
|
2524
|
-
for (const concept of rawItems?.concept ?? []) items.push(parseConcept(concept, parserOptions));
|
|
2525
|
-
for (const spatialUnit of rawItems?.spatialUnit ?? []) items.push(parseSpatialUnit(spatialUnit, parserOptions));
|
|
2526
|
-
for (const period of rawItems?.period ?? []) items.push(parsePeriod(period, parserOptions));
|
|
2527
|
-
for (const person of rawItems?.person ?? []) items.push(parsePerson(person, parserOptions));
|
|
2528
|
-
for (const propertyVariable of rawItems?.propertyVariable ?? []) items.push(parsePropertyVariable(propertyVariable, parserOptions));
|
|
2529
|
-
for (const propertyVariable of rawItems?.variable ?? []) items.push(parsePropertyVariable(propertyVariable, parserOptions));
|
|
2530
|
-
for (const propertyValue of rawItems?.propertyValue ?? []) items.push(parsePropertyValue(propertyValue, parserOptions));
|
|
2531
|
-
for (const propertyValue of rawItems?.value ?? []) items.push(parsePropertyValue(propertyValue, parserOptions));
|
|
2532
|
-
for (const resource of rawItems?.resource ?? []) items.push(parseResource(resource, parserOptions));
|
|
2533
|
-
for (const text of rawItems?.text ?? []) items.push(parseText(text, parserOptions));
|
|
2534
|
-
for (const set of rawItems?.set ?? []) items.push(parseSet(set, parserOptions));
|
|
2668
|
+
for (const entry of collectHierarchyEntries(rawItems)) {
|
|
2669
|
+
const item = parseEmbeddedItemEntry(entry, parserOptions);
|
|
2670
|
+
if (item != null) items.push(item);
|
|
2671
|
+
}
|
|
2535
2672
|
return items;
|
|
2536
2673
|
}
|
|
2537
2674
|
function parseSetItems(rawItems, options) {
|
|
@@ -3481,6 +3618,7 @@ async function fetchGallery(params, options) {
|
|
|
3481
3618
|
logIssues(issues);
|
|
3482
3619
|
throw new Error("Failed to parse gallery XML");
|
|
3483
3620
|
}
|
|
3621
|
+
restoreXMLMetadata(output, data);
|
|
3484
3622
|
return {
|
|
3485
3623
|
gallery: parseGallery(output, { languages: resolveGalleryLanguages(output, requestedLanguages) }),
|
|
3486
3624
|
error: null
|
|
@@ -3532,39 +3670,46 @@ function resolveItemLinksLanguages(data, requestedLanguages) {
|
|
|
3532
3670
|
function buildXQuery$2(uuid) {
|
|
3533
3671
|
return `<ochre>{${`let $item-uuid := "${uuid}"
|
|
3534
3672
|
|
|
3535
|
-
let $
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3673
|
+
let $source-items := (
|
|
3674
|
+
fn:collection("ochre/resource")/ochre[@uuid = $item-uuid]/resource,
|
|
3675
|
+
fn:collection("ochre/bibliography")/ochre[@uuid = $item-uuid]/bibliography,
|
|
3676
|
+
fn:collection("ochre/period")/ochre[@uuid = $item-uuid]/period,
|
|
3677
|
+
fn:collection("ochre/person")/ochre[@uuid = $item-uuid]/person,
|
|
3678
|
+
fn:collection("ochre/propertyVariable")/ochre[@uuid = $item-uuid]/propertyVariable,
|
|
3679
|
+
fn:collection("ochre/propertyValue")/ochre[@uuid = $item-uuid]/propertyValue,
|
|
3680
|
+
fn:collection("ochre/text")/ochre[@uuid = $item-uuid]/text,
|
|
3681
|
+
fn:collection("ochre/tree")/ochre[@uuid = $item-uuid]/tree,
|
|
3682
|
+
fn:collection("ochre/set")/ochre[@uuid = $item-uuid]/set,
|
|
3683
|
+
fn:collection("ochre/spatialUnit")/ochre[@uuid = $item-uuid]/spatialUnit,
|
|
3684
|
+
fn:collection("ochre/concept")/ochre[@uuid = $item-uuid]/concept
|
|
3685
|
+
)
|
|
3548
3686
|
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3687
|
+
let $link-nodes := (
|
|
3688
|
+
$source-items/links/*,
|
|
3689
|
+
$source-items/observations/observation/links/*,
|
|
3690
|
+
$source-items/interpretations/interpretation/links/*
|
|
3691
|
+
)
|
|
3553
3692
|
|
|
3554
3693
|
return
|
|
3555
|
-
<items>{
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3694
|
+
<items>{
|
|
3695
|
+
for $link at $position in $link-nodes
|
|
3696
|
+
let $uuid := $link/@uuid/string()
|
|
3697
|
+
let $category := name($link)
|
|
3698
|
+
where $uuid ne "" and not($uuid = $link-nodes[position() lt $position]/@uuid/string())
|
|
3699
|
+
return
|
|
3700
|
+
if ($category = "resource") then fn:collection("ochre/resource")/ochre/resource[@uuid = $uuid]
|
|
3701
|
+
else if ($category = "bibliography") then fn:collection("ochre/bibliography")/ochre/bibliography[@uuid = $uuid]
|
|
3702
|
+
else if ($category = "period") then fn:collection("ochre/period")/ochre/period[@uuid = $uuid]
|
|
3703
|
+
else if ($category = "person") then fn:collection("ochre/person")/ochre/person[@uuid = $uuid]
|
|
3704
|
+
else if ($category = "propertyVariable" or $category = "variable") then fn:collection("ochre/propertyVariable")/ochre/propertyVariable[@uuid = $uuid]
|
|
3705
|
+
else if ($category = "propertyValue" or $category = "value") then fn:collection("ochre/propertyValue")/ochre/propertyValue[@uuid = $uuid]
|
|
3706
|
+
else if ($category = "text") then fn:collection("ochre/text")/ochre/text[@uuid = $uuid]
|
|
3707
|
+
else if ($category = "tree") then fn:collection("ochre/tree")/ochre/tree[@uuid = $uuid]
|
|
3708
|
+
else if ($category = "set") then fn:collection("ochre/set")/ochre/set[@uuid = $uuid]
|
|
3709
|
+
else if ($category = "spatialUnit") then fn:collection("ochre/spatialUnit")/ochre/spatialUnit[@uuid = $uuid]
|
|
3710
|
+
else if ($category = "concept") then fn:collection("ochre/concept")/ochre/concept[@uuid = $uuid]
|
|
3711
|
+
else ()
|
|
3712
|
+
}</items>`}}</ochre>`;
|
|
3568
3713
|
}
|
|
3569
3714
|
async function fetchItemLinks(uuid, options) {
|
|
3570
3715
|
try {
|
|
@@ -3583,6 +3728,7 @@ async function fetchItemLinks(uuid, options) {
|
|
|
3583
3728
|
logIssues(issues);
|
|
3584
3729
|
throw new Error("Failed to parse OCHRE item links");
|
|
3585
3730
|
}
|
|
3731
|
+
restoreXMLMetadata(output, data);
|
|
3586
3732
|
const languages = resolveItemLinksLanguages(output, requestedLanguages);
|
|
3587
3733
|
return {
|
|
3588
3734
|
items: parseLinkedItems(output.result.ochre.items, {
|
|
@@ -3683,6 +3829,7 @@ async function fetchItem(uuid, options) {
|
|
|
3683
3829
|
logIssues(issues);
|
|
3684
3830
|
throw new Error("Failed to parse OCHRE data");
|
|
3685
3831
|
}
|
|
3832
|
+
restoreXMLMetadata(output, data);
|
|
3686
3833
|
const category = options?.category ?? inferFetchItemCategory(output.result.ochre);
|
|
3687
3834
|
assertItemCategoryAllowed(category, options?.containedItemCategory);
|
|
3688
3835
|
return {
|
|
@@ -4756,6 +4903,7 @@ async function fetchSetItems(params, containedItemCategories, options) {
|
|
|
4756
4903
|
logIssues(issues);
|
|
4757
4904
|
throw new Error("Failed to parse OCHRE Set items");
|
|
4758
4905
|
}
|
|
4906
|
+
restoreXMLMetadata(output, data);
|
|
4759
4907
|
if (containedItemCategories != null) {
|
|
4760
4908
|
const missingCategories = containedItemCategories.filter((category) => !hasSetItemsCategory(output.result.ochre.items, category));
|
|
4761
4909
|
if (missingCategories.length > 0) throw new Error(`No Set items found for item categories: ${missingCategories.join(", ")}`);
|
|
@@ -6096,15 +6244,14 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
6096
6244
|
break;
|
|
6097
6245
|
}
|
|
6098
6246
|
case "image": {
|
|
6099
|
-
|
|
6100
|
-
if (imageLinks.length === 0) throw new Error(formatComponentError("No links found", componentName, elementResource));
|
|
6247
|
+
if (websiteLinks.length === 0) throw new Error(formatComponentError("No links found", componentName, elementResource));
|
|
6101
6248
|
const imageQuality = componentReader.valueOr("image-quality", "high");
|
|
6102
6249
|
const images = [];
|
|
6103
|
-
for (const link of
|
|
6250
|
+
for (const link of websiteLinks) images.push({
|
|
6104
6251
|
uuid: link.uuid,
|
|
6105
6252
|
label: link.identification.label,
|
|
6106
|
-
width: link.image?.width ?? 0,
|
|
6107
|
-
height: link.image?.height ?? 0,
|
|
6253
|
+
width: "image" in link ? link.image?.width ?? 0 : 0,
|
|
6254
|
+
height: "image" in link ? link.image?.height ?? 0 : 0,
|
|
6108
6255
|
description: link.description,
|
|
6109
6256
|
quality: imageQuality
|
|
6110
6257
|
});
|
|
@@ -7033,6 +7180,7 @@ async function fetchWebsite(abbreviation, options) {
|
|
|
7033
7180
|
logIssues(issues);
|
|
7034
7181
|
throw new Error("Failed to parse website XML");
|
|
7035
7182
|
}
|
|
7183
|
+
restoreXMLMetadata(output, data);
|
|
7036
7184
|
return {
|
|
7037
7185
|
website: parseWebsite(output, { languages: options?.languages }),
|
|
7038
7186
|
error: null
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ochre-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Node.js library for working with OCHRE (Online Cultural and Historical Research Environment) data",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"date-fns": "^4.1.0",
|
|
47
47
|
"fast-equals": "^6.0.0",
|
|
48
|
-
"fast-xml-parser": "^5.
|
|
48
|
+
"fast-xml-parser": "^5.8.0",
|
|
49
49
|
"valibot": "^1.4.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|