ochre-sdk 1.0.21 → 1.0.22
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.
|
@@ -36,11 +36,45 @@ function normalizeWebsiteResources(resources) {
|
|
|
36
36
|
return normalized;
|
|
37
37
|
}
|
|
38
38
|
const SEGMENT_UNIQUE_SLUG_PREFIX_REGEX = /^\$[^-]*-/;
|
|
39
|
+
function cleanWebsitePageSlug(slug) {
|
|
40
|
+
return slug?.replace(SEGMENT_UNIQUE_SLUG_PREFIX_REGEX, "") ?? null;
|
|
41
|
+
}
|
|
39
42
|
function prefixSlug(slug, slugPrefix) {
|
|
40
43
|
if (slugPrefix == null || slugPrefix === "") return slug;
|
|
41
44
|
if (slug === "") return slugPrefix;
|
|
42
45
|
return `${slugPrefix}/${slug}`;
|
|
43
46
|
}
|
|
47
|
+
function collectWebsitePageSlugs(resources, options, slugPrefix, pageSlugsByUuid = /* @__PURE__ */ new Map(), segmentSlugPrefix = slugPrefix) {
|
|
48
|
+
for (const resource of resources ?? []) {
|
|
49
|
+
if ("segments" in resource) {
|
|
50
|
+
for (const tree of resource.segments.tree) {
|
|
51
|
+
const segmentSlug = tree.identification.abbreviation == null ? null : parseStringContent(tree.identification.abbreviation, options);
|
|
52
|
+
if (segmentSlug == null) throw new Error(`Slug not found for segment website (website uuid “${tree.uuid}”)`, { cause: tree });
|
|
53
|
+
collectWebsitePageSlugs(tree.items?.resource, options, prefixSlug(segmentSlug, segmentSlugPrefix), pageSlugsByUuid);
|
|
54
|
+
}
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (!("identification" in resource)) {
|
|
58
|
+
collectWebsitePageSlugs(resource.resource, options, slugPrefix, pageSlugsByUuid, segmentSlugPrefix);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (websitePresentationReader(resource.properties != null ? parseSimplifiedProperties(resource.properties, options) : []).value("presentation") === "page") {
|
|
62
|
+
const slug = cleanWebsitePageSlug(resource.slug);
|
|
63
|
+
if (slug == null) throw new Error(`Slug not found for page (${formatXMLWebsiteResourceMetadata(resource)})`, { cause: resource });
|
|
64
|
+
const pageSlug = prefixSlug(slug, slugPrefix);
|
|
65
|
+
pageSlugsByUuid.set(resource.uuid, pageSlug);
|
|
66
|
+
collectWebsitePageSlugs(resource.resource, options, slugPrefix == null ? void 0 : pageSlug, pageSlugsByUuid, pageSlug);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
collectWebsitePageSlugs(resource.resource, options, slugPrefix, pageSlugsByUuid, segmentSlugPrefix);
|
|
70
|
+
}
|
|
71
|
+
return pageSlugsByUuid;
|
|
72
|
+
}
|
|
73
|
+
function parseWebsiteLinkTarget(value, context) {
|
|
74
|
+
if (value == null) return null;
|
|
75
|
+
if (value.href != null) return transformPermanentIdentificationUrlToItemLink(value.href);
|
|
76
|
+
return (value.uuid == null ? void 0 : context.pageSlugsByUuid?.get(value.uuid)) ?? value.slug;
|
|
77
|
+
}
|
|
44
78
|
function formatXMLWebsiteResourceMetadata(resource) {
|
|
45
79
|
const metadata = [`label “${parseStringContent(resource.identification.label)}”`, `uuid “${resource.uuid}”`];
|
|
46
80
|
if (resource.slug != null) metadata.push(`slug “${resource.slug}”`);
|
|
@@ -205,7 +239,7 @@ function parseStylesheets(styles) {
|
|
|
205
239
|
* @param elementResource - Raw element resource data in OCHRE format
|
|
206
240
|
* @returns Parsed WebElementComponent object
|
|
207
241
|
*/
|
|
208
|
-
function parseWebElementProperties(componentProperty, elementResource, options) {
|
|
242
|
+
function parseWebElementProperties(componentProperty, elementResource, options, context) {
|
|
209
243
|
const unparsedComponentName = componentProperty.values[0].content;
|
|
210
244
|
const componentNameResult = v.safeParse(componentSchema, unparsedComponentName);
|
|
211
245
|
const componentName = componentNameResult.success ? componentNameResult.output : void 0;
|
|
@@ -229,7 +263,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
229
263
|
}
|
|
230
264
|
case "advanced-search": {
|
|
231
265
|
const boundElementPropertyUuid = componentReader.uuid("bound-element");
|
|
232
|
-
const href = componentReader.
|
|
266
|
+
const href = parseWebsiteLinkTarget(componentReader.valueNode("link-to"), context);
|
|
233
267
|
if (boundElementPropertyUuid == null && href == null) throw new Error(formatComponentError("Bound element or href not found", componentName, elementResource), { cause: componentProperty });
|
|
234
268
|
properties = {
|
|
235
269
|
component: "advanced-search",
|
|
@@ -297,9 +331,9 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
297
331
|
case "button": {
|
|
298
332
|
const variant = componentReader.valueOr("variant", "default");
|
|
299
333
|
let isExternal = false;
|
|
300
|
-
let href = componentReader.
|
|
334
|
+
let href = parseWebsiteLinkTarget(componentReader.valueNode("navigate-to"), context);
|
|
301
335
|
if (href === null) {
|
|
302
|
-
href = componentReader.
|
|
336
|
+
href = parseWebsiteLinkTarget(componentReader.valueNode("link-to"), context);
|
|
303
337
|
if (href === null) throw new Error(formatComponentError("Properties “navigate-to” or “link-to” not found", componentName, elementResource), { cause: componentProperty });
|
|
304
338
|
else isExternal = true;
|
|
305
339
|
}
|
|
@@ -594,7 +628,7 @@ function parseWebElementProperties(componentProperty, elementResource, options)
|
|
|
594
628
|
case "search-bar": {
|
|
595
629
|
const queryVariant = componentReader.valueOr("query-variant", "submit");
|
|
596
630
|
const boundElementUuid = componentReader.uuid("bound-element");
|
|
597
|
-
const href = componentReader.
|
|
631
|
+
const href = parseWebsiteLinkTarget(componentReader.valueNode("link-to"), context);
|
|
598
632
|
if (!boundElementUuid && !href) throw new Error(formatComponentError("Bound element or href not found", componentName, elementResource), { cause: componentProperty });
|
|
599
633
|
properties = {
|
|
600
634
|
component: "search-bar",
|
|
@@ -705,10 +739,10 @@ function parseWebTitle(properties, identification, overrides) {
|
|
|
705
739
|
* @param elementResource - Raw element resource data in OCHRE format
|
|
706
740
|
* @returns Parsed WebElement object
|
|
707
741
|
*/
|
|
708
|
-
function parseWebElement(elementResource, options) {
|
|
742
|
+
function parseWebElement(elementResource, options, context) {
|
|
709
743
|
const identification = parseIdentification(elementResource.identification, options);
|
|
710
744
|
const elementProperties = elementResource.properties?.property ? parseSimplifiedProperties(elementResource.properties, options) : [];
|
|
711
|
-
const properties = parseWebElementProperties(websitePresentationReader(websitePresentationReader(elementProperties).requiredProperty("presentation", `Presentation property not found for element (${formatXMLWebsiteResourceMetadata(elementResource)})`).properties).requiredProperty("component", `Component property not found for element (${formatXMLWebsiteResourceMetadata(elementResource)})`), elementResource, options);
|
|
745
|
+
const properties = parseWebElementProperties(websitePresentationReader(websitePresentationReader(elementProperties).requiredProperty("presentation", `Presentation property not found for element (${formatXMLWebsiteResourceMetadata(elementResource)})`).properties).requiredProperty("component", `Component property not found for element (${formatXMLWebsiteResourceMetadata(elementResource)})`), elementResource, options, context);
|
|
712
746
|
const cssStyles = parseResponsiveCssStyles(elementProperties);
|
|
713
747
|
const title = parseWebTitle(elementProperties, identification, {
|
|
714
748
|
isNameDisplayed: properties.component === "annotated-image" || properties.component === "annotated-document" || properties.component === "collection",
|
|
@@ -733,7 +767,7 @@ function parseWebpage(webpageResource, options, context, slugPrefix) {
|
|
|
733
767
|
const webpageReader = websitePresentationReader(webpageProperties);
|
|
734
768
|
if (webpageReader.value("presentation") !== "page") return null;
|
|
735
769
|
const identification = parseIdentification(webpageResource.identification, options);
|
|
736
|
-
const slug = webpageResource.slug
|
|
770
|
+
const slug = cleanWebsitePageSlug(webpageResource.slug);
|
|
737
771
|
if (slug == null) throw new Error(`Slug not found for page (${formatXMLWebsiteResourceMetadata(webpageResource)})`, { cause: webpageResource });
|
|
738
772
|
const returnWebpage = {
|
|
739
773
|
uuid: webpageResource.uuid,
|
|
@@ -767,12 +801,12 @@ function parseWebpage(webpageResource, options, context, slugPrefix) {
|
|
|
767
801
|
if (resourceType === null) continue;
|
|
768
802
|
switch (resourceType) {
|
|
769
803
|
case "element": {
|
|
770
|
-
const element = parseWebElement(resource, options);
|
|
804
|
+
const element = parseWebElement(resource, options, context);
|
|
771
805
|
items.push(element);
|
|
772
806
|
break;
|
|
773
807
|
}
|
|
774
808
|
case "block": {
|
|
775
|
-
const block = parseWebBlock(resource, options);
|
|
809
|
+
const block = parseWebBlock(resource, options, context);
|
|
776
810
|
if (block) items.push(block);
|
|
777
811
|
break;
|
|
778
812
|
}
|
|
@@ -836,7 +870,7 @@ function parseWebsiteSegments(resources, context, options, slugPrefix) {
|
|
|
836
870
|
* @param resources - Array of raw sidebar resources in OCHRE format
|
|
837
871
|
* @returns Parsed Sidebar object
|
|
838
872
|
*/
|
|
839
|
-
function parseSidebar(resources, options) {
|
|
873
|
+
function parseSidebar(resources, options, context) {
|
|
840
874
|
let returnSidebar = null;
|
|
841
875
|
const items = [];
|
|
842
876
|
let title = null;
|
|
@@ -867,12 +901,12 @@ function parseSidebar(resources, options) {
|
|
|
867
901
|
if (resourceType === null) continue;
|
|
868
902
|
switch (resourceType) {
|
|
869
903
|
case "element": {
|
|
870
|
-
const element = parseWebElement(resource, options);
|
|
904
|
+
const element = parseWebElement(resource, options, context);
|
|
871
905
|
items.push(element);
|
|
872
906
|
break;
|
|
873
907
|
}
|
|
874
908
|
case "block": {
|
|
875
|
-
const block = parseWebBlock(resource, options);
|
|
909
|
+
const block = parseWebBlock(resource, options, context);
|
|
876
910
|
if (block) items.push(block);
|
|
877
911
|
break;
|
|
878
912
|
}
|
|
@@ -889,20 +923,20 @@ function parseSidebar(resources, options) {
|
|
|
889
923
|
};
|
|
890
924
|
return returnSidebar;
|
|
891
925
|
}
|
|
892
|
-
function parseWebAccordionItem(elementResource, childResources, options) {
|
|
893
|
-
const trigger = parseWebElement(elementResource, options);
|
|
926
|
+
function parseWebAccordionItem(elementResource, childResources, options, context) {
|
|
927
|
+
const trigger = parseWebElement(elementResource, options, context);
|
|
894
928
|
const items = [];
|
|
895
929
|
for (const resource of childResources) {
|
|
896
930
|
const resourceType = websitePresentationReader(resource.properties ? parseSimplifiedProperties(resource.properties, options) : []).value("presentation");
|
|
897
931
|
if (resourceType === null) continue;
|
|
898
932
|
switch (resourceType) {
|
|
899
933
|
case "element": {
|
|
900
|
-
const element = parseWebElement(resource, options);
|
|
934
|
+
const element = parseWebElement(resource, options, context);
|
|
901
935
|
items.push(element);
|
|
902
936
|
break;
|
|
903
937
|
}
|
|
904
938
|
case "block": {
|
|
905
|
-
const block = parseWebBlock(resource, options);
|
|
939
|
+
const block = parseWebBlock(resource, options, context);
|
|
906
940
|
if (block) items.push(block);
|
|
907
941
|
break;
|
|
908
942
|
}
|
|
@@ -921,7 +955,7 @@ function parseWebAccordionItem(elementResource, childResources, options) {
|
|
|
921
955
|
* @param blockResource - Raw block resource data in OCHRE format
|
|
922
956
|
* @returns Parsed WebBlock object
|
|
923
957
|
*/
|
|
924
|
-
function parseWebBlock(blockResource, options) {
|
|
958
|
+
function parseWebBlock(blockResource, options, context) {
|
|
925
959
|
const blockProperties = blockResource.properties ? parseSimplifiedProperties(blockResource.properties, options) : [];
|
|
926
960
|
const returnBlock = {
|
|
927
961
|
uuid: blockResource.uuid,
|
|
@@ -1006,16 +1040,16 @@ function parseWebBlock(blockResource, options) {
|
|
|
1006
1040
|
const childResources = resource.resource ? normalizeWebsiteResources(resource.resource) : [];
|
|
1007
1041
|
const componentType = resourceReader.nestedByValue("presentation", "element").value("component");
|
|
1008
1042
|
if (supportsAccordionItems && componentType === "text" && childResources.length > 0) {
|
|
1009
|
-
const item = parseWebAccordionItem(resource, childResources, options);
|
|
1043
|
+
const item = parseWebAccordionItem(resource, childResources, options, context);
|
|
1010
1044
|
blockItems.push(item);
|
|
1011
1045
|
break;
|
|
1012
1046
|
}
|
|
1013
|
-
const element = parseWebElement(resource, options);
|
|
1047
|
+
const element = parseWebElement(resource, options, context);
|
|
1014
1048
|
blockItems.push(element);
|
|
1015
1049
|
break;
|
|
1016
1050
|
}
|
|
1017
1051
|
case "block": {
|
|
1018
|
-
const block = parseWebBlock(resource, options);
|
|
1052
|
+
const block = parseWebBlock(resource, options, context);
|
|
1019
1053
|
if (block) blockItems.push(block);
|
|
1020
1054
|
break;
|
|
1021
1055
|
}
|
|
@@ -1200,7 +1234,12 @@ function parseWebsiteTree(websiteTree, context, type, options, slugPrefix) {
|
|
|
1200
1234
|
if (!websiteTree.properties) throw new Error(`Website properties not found (website uuid “${websiteTree.uuid}”)`, { cause: websiteTree });
|
|
1201
1235
|
if (type === "website" && websiteTree.items?.resource == null) throw new Error(`Website pages not found (website uuid “${websiteTree.uuid}”)`, { cause: websiteTree });
|
|
1202
1236
|
const resources = normalizeWebsiteResources(websiteTree.items?.resource);
|
|
1203
|
-
const
|
|
1237
|
+
const pageSlugsByUuid = context.pageSlugsByUuid ?? collectWebsitePageSlugs(websiteTree.items?.resource, options, slugPrefix);
|
|
1238
|
+
const treeContext = {
|
|
1239
|
+
...context,
|
|
1240
|
+
pageSlugsByUuid
|
|
1241
|
+
};
|
|
1242
|
+
const sidebar = parseSidebar(resources, options, treeContext);
|
|
1204
1243
|
const properties = parseWebsiteProperties(websiteTree.properties.property, websiteTree, sidebar, options);
|
|
1205
1244
|
return {
|
|
1206
1245
|
uuid: websiteTree.uuid,
|
|
@@ -1211,7 +1250,7 @@ function parseWebsiteTree(websiteTree, context, type, options, slugPrefix) {
|
|
|
1211
1250
|
identification: parseIdentification(websiteTree.identification, options),
|
|
1212
1251
|
creators: websiteTree.creators ? parsePersonList(websiteTree.creators.creator, options) : [],
|
|
1213
1252
|
license: parseLicense(websiteTree.availability),
|
|
1214
|
-
items: parseWebpages(resources, options,
|
|
1253
|
+
items: parseWebpages(resources, options, treeContext, slugPrefix),
|
|
1215
1254
|
properties
|
|
1216
1255
|
};
|
|
1217
1256
|
}
|
|
@@ -17,7 +17,6 @@ declare class WebsitePresentationReader<T extends LanguageCodes> {
|
|
|
17
17
|
stringValue(label: string): string | null;
|
|
18
18
|
numberValue(label: string): number | null;
|
|
19
19
|
uuid(label: string): string | null;
|
|
20
|
-
linkTarget(label: string, transformHref: (href: string) => string): string | null;
|
|
21
20
|
multilingualValue(label: string, options: ParserOptions<T>): MultilingualString<T> | null;
|
|
22
21
|
nested(label: string): WebsitePresentationReader<T>;
|
|
23
22
|
nestedByValue(label: string, value: WebsitePropertyContent<T>): WebsitePresentationReader<T>;
|
|
@@ -44,11 +44,6 @@ var WebsitePresentationReader = class WebsitePresentationReader {
|
|
|
44
44
|
uuid(label) {
|
|
45
45
|
return this.valueNode(label)?.uuid ?? null;
|
|
46
46
|
}
|
|
47
|
-
linkTarget(label, transformHref) {
|
|
48
|
-
const value = this.valueNode(label);
|
|
49
|
-
if (value?.href != null) return transformHref(value.href);
|
|
50
|
-
return value?.slug ?? null;
|
|
51
|
-
}
|
|
52
47
|
multilingualValue(label, options) {
|
|
53
48
|
const value = this.valueNode(label);
|
|
54
49
|
if (value == null) return null;
|