ochre-sdk 1.3.3 → 1.3.4

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.
@@ -48,8 +48,8 @@ function normalizePropertyValueDataType(dataType) {
48
48
  function sortPropertyValues(values) {
49
49
  return values.toSorted((a, b) => {
50
50
  if (a.count !== b.count) return b.count - a.count;
51
- const label = a.label?.getText() ?? null;
52
- const otherLabel = b.label?.getText() ?? null;
51
+ const label = a.label?.getText(a.label.getDefaultLanguage()) ?? null;
52
+ const otherLabel = b.label?.getText(b.label.getDefaultLanguage()) ?? null;
53
53
  if (label !== otherLabel) return label?.localeCompare(otherLabel ?? "") ?? 0;
54
54
  return a.content?.toString().localeCompare(b.content?.toString() ?? "") ?? 0;
55
55
  });
@@ -26,7 +26,7 @@ function parseWebsiteMetadata(data, options) {
26
26
  const websiteTree = rawOchre.tree[0];
27
27
  if (websiteTree == null) throw new Error("Website tree not found", { cause: data });
28
28
  const identification = parseIdentification(websiteTree.identification, options);
29
- const websiteName = identification.label.getText().trim();
29
+ const websiteName = identification.label.getText(identification.label.getDefaultLanguage()).trim();
30
30
  const metadataDescription = (parseStringLike(rawOchre.metadata.description) ?? "").trim();
31
31
  const properties = parseSimplifiedProperties(websiteTree.properties, options);
32
32
  const reader = websitePresentationReader(properties);
package/dist/getters.mjs CHANGED
@@ -27,7 +27,7 @@ function withDefaultOptions(options) {
27
27
  };
28
28
  }
29
29
  function getPropertyVariableLabel(property) {
30
- return typeof property.variable.label === "string" ? property.variable.label : property.variable.label.getText();
30
+ return typeof property.variable.label === "string" ? property.variable.label : property.variable.label.getText(property.variable.label.getDefaultLanguage());
31
31
  }
32
32
  function hasPropertyValue(property, value) {
33
33
  for (const candidateValue of property.values) if (deepEqual(candidateValue, value)) return true;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { MultilingualOptions, MultilingualString, MultilingualStringEntries, MultilingualStringEntry, MultilingualStringInput, MultilingualStringJSON, MultilingualStringObject, MultilingualStringText } from "./parsers/multilingual.mjs";
2
- import { AccordionWebBlock, ContextTree, ContextTreeFilterLevel, ContextTreeFilterVariant, ContextTreeLevel, ContextTreeLevelItem, ProtectedWebsite, ResponsiveStyles, Scope, Style, StylesheetCategory, StylesheetItem, WebAccordionItem, WebBlock, WebBlockByLayout, WebBlockItem, WebBlockLayout, WebElement, WebElementComponent, WebElementComponentName, WebElementComponentOf, WebElementOf, WebIiifViewer, WebImage, WebLoadingVariant, WebOptions, WebSectionDisplay, WebSectionVariant, WebSidebar, WebTitle, Webpage, Website, WebsiteMetadata, WebsitePrivacy, WebsitePropertyQuery, WebsitePropertyQueryNode, WebsiteSegment, WebsiteType } from "./types/website.mjs";
2
+ import { AccordionWebBlock, ContextTree, ContextTreeFilterLevel, ContextTreeFilterVariant, ContextTreeLevel, ContextTreeLevelItem, ProtectedWebsite, ResponsiveStyles, Scope, Style, StylesheetCategory, StylesheetItem, WebAccordionItem, WebBlock, WebBlockByLayout, WebBlockItem, WebBlockLayout, WebElement, WebElementComponent, WebElementComponentName, WebElementComponentOf, WebElementOf, WebIiifViewer, WebImage, WebLoadingVariant, WebOptions, WebRelationVariant, WebSectionDisplay, WebSectionVariant, WebSidebar, WebTitle, Webpage, Website, WebsiteMetadata, WebsitePrivacy, WebsitePropertyQuery, WebsitePropertyQueryNode, WebsiteSegment, WebsiteType } from "./types/website.mjs";
3
3
  import { AnyBibliography, AnyConcept, AnyItem, AnyPeriod, AnyPerson, AnyPropertyValue, AnyPropertyVariable, AnyResource, AnySet, AnySpatialUnit, AnyText, AnyTree, BaseItem, BaseItemLink, BelongsTo, Bibliography, BibliographyEntryInfo, BibliographyItemLink, BibliographySourceDocument, Concept, ConceptItemLink, ContainedItemCategory, ContainedItemCategoryFromOption, ContainedItemCategoryOption, Context, ContextItem, ContextItemCategory, ContextNode, Coordinates, CoordinatesSource, DictionaryUnitItemLink, EmbeddedBibliography, EmbeddedConcept, EmbeddedItem, EmbeddedPeriod, EmbeddedPerson, EmbeddedPropertyValue, EmbeddedPropertyVariable, EmbeddedResource, EmbeddedSet, EmbeddedSpatialUnit, EmbeddedText, EmbeddedTree, Event, Gallery, Heading, HeadingItemCategory, Identification, Image, ImageMap, ImageMapArea, Interpretation, Item, ItemCategory, ItemCategoryFromOption, ItemCategoryOption, ItemCategoryWithEmbeddedItems, ItemContainerCategory, ItemLink, ItemLinkCategory, ItemLinks, ItemPayloadKind, ItemProperty, ItemWithoutEmbeddedItems, LanguageCodes, License, Metadata, Note, Observation, OcrString, Period, PeriodItemLink, Person, PersonItemLink, Property, PropertyLike, PropertyRelation, PropertyValue, PropertyValueContent, PropertyValueDataType, PropertyValueItemLink, PropertyValueQueryItem, PropertyVariable, PropertyVariableItemLink, Query, QueryGroup, QueryLeaf, QueryablePropertyValueDataType, RecursiveItemCategory, Resource, ResourceItemLink, Section, Set, SetAttributeValueQueryItem, SetBibliography, SetConcept, SetItem, SetItemCategory, SetItemLink, SetItemLocation, SetItemProperty, SetItemSimplifiedProperty, SetItemsSort, SetItemsSortDirection, SetPeriod, SetResource, SetSpatialUnit, SetStyle, SetStyleProperty, SetTree, SimplifiedProperty, SpatialUnit, SpatialUnitItemLink, Text, TextItemLink, TopLevelItem, Tree, TreeItemCategory, TreeItemLink } from "./types/index.mjs";
4
4
  import { DEFAULT_PAGE_SIZE } from "./constants.mjs";
5
5
  import { fetchGallery } from "./fetchers/gallery.mjs";
@@ -16,4 +16,4 @@ import { fetchWebsite } from "./fetchers/website.mjs";
16
16
  import { PropertyOptions, PropertySelector, getLeafPropertyValues, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel } from "./getters.mjs";
17
17
  import { flattenItemProperties } from "./helpers.mjs";
18
18
  import { defineLanguages } from "./parsers/languages.mjs";
19
- export { type AccordionWebBlock, type AnyBibliography, type AnyConcept, type AnyItem, type AnyPeriod, type AnyPerson, type AnyPropertyValue, type AnyPropertyVariable, type AnyResource, type AnySet, type AnySpatialUnit, type AnyText, type AnyTree, type BaseItem, type BaseItemLink, type BelongsTo, type Bibliography, type BibliographyEntryInfo, type BibliographyItemLink, type BibliographySourceDocument, type Concept, type ConceptItemLink, type ContainedItemCategory, type ContainedItemCategoryFromOption, type ContainedItemCategoryOption, type Context, type ContextItem, type ContextItemCategory, type ContextNode, type ContextTree, type ContextTreeFilterLevel, type ContextTreeFilterVariant, type ContextTreeLevel, type ContextTreeLevelItem, type Coordinates, type CoordinatesSource, DEFAULT_PAGE_SIZE, type DictionaryUnitItemLink, type EmbeddedBibliography, type EmbeddedConcept, type EmbeddedItem, type EmbeddedPeriod, type EmbeddedPerson, type EmbeddedPropertyValue, type EmbeddedPropertyVariable, type EmbeddedResource, type EmbeddedSet, type EmbeddedSpatialUnit, type EmbeddedText, type EmbeddedTree, type Event, type Gallery, type Heading, type HeadingItemCategory, type Identification, type Image, type ImageMap, type ImageMapArea, type Interpretation, type Item, type ItemCategory, type ItemCategoryFromOption, type ItemCategoryOption, type ItemCategoryWithEmbeddedItems, type ItemContainerCategory, type ItemLink, type ItemLinkCategory, type ItemLinks, type ItemPayloadKind, type ItemProperty, type ItemWithoutEmbeddedItems, type LanguageCodes, type License, type Metadata, type MultilingualOptions, MultilingualString, type MultilingualStringEntries, type MultilingualStringEntry, type MultilingualStringInput, type MultilingualStringJSON, type MultilingualStringObject, type MultilingualStringText, type Note, type Observation, type OcrString, type Period, type PeriodItemLink, type Person, type PersonItemLink, type Property, type PropertyLike, type PropertyOptions, type PropertyRelation, type PropertySelector, type PropertyValue, type PropertyValueContent, type PropertyValueDataType, type PropertyValueItemLink, type PropertyValueQueryItem, type PropertyVariable, type PropertyVariableItemLink, type ProtectedWebsite, type Query, type QueryGroup, type QueryLeaf, type QueryablePropertyValueDataType, type RecursiveItemCategory, type Resource, type ResourceItemLink, type ResponsiveStyles, type Scope, type Section, type Set, type SetAttributeValueQueryItem, type SetBibliography, type SetConcept, type SetItem, type SetItemCategory, type SetItemLink, type SetItemLocation, type SetItemProperty, type SetItemSimplifiedProperty, type SetItemsSort, type SetItemsSortDirection, type SetPeriod, type SetResource, type SetSpatialUnit, type SetStyle, type SetStyleProperty, type SetTree, type SimplifiedProperty, type SpatialUnit, type SpatialUnitItemLink, type Style, type StylesheetCategory, type StylesheetItem, type Text, type TextItemLink, type TopLevelItem, type Tree, type TreeItemCategory, type TreeItemLink, type WebAccordionItem, type WebBlock, type WebBlockByLayout, type WebBlockItem, type WebBlockLayout, type WebElement, type WebElementComponent, type WebElementComponentName, type WebElementComponentOf, type WebElementOf, type WebIiifViewer, type WebImage, type WebLoadingVariant, type WebOptions, type WebSectionDisplay, type WebSectionVariant, type WebSidebar, type WebTitle, type Webpage, type Website, type WebsiteMetadata, type WebsitePrivacy, type WebsitePropertyQuery, type WebsitePropertyQueryNode, type WebsiteSegment, type WebsiteType, defineLanguages, fetchGallery, fetchItem, fetchItemChildren, fetchItemLinks, fetchItemOcrData, fetchSetItemLocations, fetchSetItems, fetchSetPropertyValues, fetchTreeItems, fetchWebsite, fetchWebsiteMetadata, flattenItemProperties, getLeafPropertyValues, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
19
+ export { type AccordionWebBlock, type AnyBibliography, type AnyConcept, type AnyItem, type AnyPeriod, type AnyPerson, type AnyPropertyValue, type AnyPropertyVariable, type AnyResource, type AnySet, type AnySpatialUnit, type AnyText, type AnyTree, type BaseItem, type BaseItemLink, type BelongsTo, type Bibliography, type BibliographyEntryInfo, type BibliographyItemLink, type BibliographySourceDocument, type Concept, type ConceptItemLink, type ContainedItemCategory, type ContainedItemCategoryFromOption, type ContainedItemCategoryOption, type Context, type ContextItem, type ContextItemCategory, type ContextNode, type ContextTree, type ContextTreeFilterLevel, type ContextTreeFilterVariant, type ContextTreeLevel, type ContextTreeLevelItem, type Coordinates, type CoordinatesSource, DEFAULT_PAGE_SIZE, type DictionaryUnitItemLink, type EmbeddedBibliography, type EmbeddedConcept, type EmbeddedItem, type EmbeddedPeriod, type EmbeddedPerson, type EmbeddedPropertyValue, type EmbeddedPropertyVariable, type EmbeddedResource, type EmbeddedSet, type EmbeddedSpatialUnit, type EmbeddedText, type EmbeddedTree, type Event, type Gallery, type Heading, type HeadingItemCategory, type Identification, type Image, type ImageMap, type ImageMapArea, type Interpretation, type Item, type ItemCategory, type ItemCategoryFromOption, type ItemCategoryOption, type ItemCategoryWithEmbeddedItems, type ItemContainerCategory, type ItemLink, type ItemLinkCategory, type ItemLinks, type ItemPayloadKind, type ItemProperty, type ItemWithoutEmbeddedItems, type LanguageCodes, type License, type Metadata, type MultilingualOptions, MultilingualString, type MultilingualStringEntries, type MultilingualStringEntry, type MultilingualStringInput, type MultilingualStringJSON, type MultilingualStringObject, type MultilingualStringText, type Note, type Observation, type OcrString, type Period, type PeriodItemLink, type Person, type PersonItemLink, type Property, type PropertyLike, type PropertyOptions, type PropertyRelation, type PropertySelector, type PropertyValue, type PropertyValueContent, type PropertyValueDataType, type PropertyValueItemLink, type PropertyValueQueryItem, type PropertyVariable, type PropertyVariableItemLink, type ProtectedWebsite, type Query, type QueryGroup, type QueryLeaf, type QueryablePropertyValueDataType, type RecursiveItemCategory, type Resource, type ResourceItemLink, type ResponsiveStyles, type Scope, type Section, type Set, type SetAttributeValueQueryItem, type SetBibliography, type SetConcept, type SetItem, type SetItemCategory, type SetItemLink, type SetItemLocation, type SetItemProperty, type SetItemSimplifiedProperty, type SetItemsSort, type SetItemsSortDirection, type SetPeriod, type SetResource, type SetSpatialUnit, type SetStyle, type SetStyleProperty, type SetTree, type SimplifiedProperty, type SpatialUnit, type SpatialUnitItemLink, type Style, type StylesheetCategory, type StylesheetItem, type Text, type TextItemLink, type TopLevelItem, type Tree, type TreeItemCategory, type TreeItemLink, type WebAccordionItem, type WebBlock, type WebBlockByLayout, type WebBlockItem, type WebBlockLayout, type WebElement, type WebElementComponent, type WebElementComponentName, type WebElementComponentOf, type WebElementOf, type WebIiifViewer, type WebImage, type WebLoadingVariant, type WebOptions, type WebRelationVariant, type WebSectionDisplay, type WebSectionVariant, type WebSidebar, type WebTitle, type Webpage, type Website, type WebsiteMetadata, type WebsitePrivacy, type WebsitePropertyQuery, type WebsitePropertyQueryNode, type WebsiteSegment, type WebsiteType, defineLanguages, fetchGallery, fetchItem, fetchItemChildren, fetchItemLinks, fetchItemOcrData, fetchSetItemLocations, fetchSetItems, fetchSetPropertyValues, fetchTreeItems, fetchWebsite, fetchWebsiteMetadata, flattenItemProperties, getLeafPropertyValues, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
@@ -58,15 +58,19 @@ function parseRequiredContentLike(value, options) {
58
58
  return parseContentLike(value, options) ?? MultilingualString.empty(options.languages, { defaultLanguage: options.defaultLanguage });
59
59
  }
60
60
  function parseContentLikeText(value, options) {
61
- return parseContentLike(value, options)?.getText().trim() ?? "";
61
+ const content = parseContentLike(value, options);
62
+ return content?.getText(content.getDefaultLanguage()).trim() ?? "";
62
63
  }
63
64
  function parseStringContent(value, options = FALLBACK_PARSER_OPTIONS) {
64
65
  if (value == null) return "";
65
66
  if (typeof value === "string") return value;
66
- if (isXMLContent(value)) return parseXMLContent(value, {
67
- languages: options.languages,
68
- defaultLanguage: options.defaultLanguage
69
- }).getText();
67
+ if (isXMLContent(value)) {
68
+ const content = parseXMLContent(value, {
69
+ languages: options.languages,
70
+ defaultLanguage: options.defaultLanguage
71
+ });
72
+ return content.getText(content.getDefaultLanguage());
73
+ }
70
74
  return parseXMLString(value).text;
71
75
  }
72
76
  //#endregion
@@ -457,7 +457,7 @@ function parsePropertyDataType(dataType) {
457
457
  function parsePropertyValueContent(value, options) {
458
458
  const dataType = parsePropertyDataType(value.dataType);
459
459
  const rawLabel = value.content != null ? parseRequiredContentLike(value, options) : value.payload != null && value.payload !== "" ? multilingualFromText(value.payload, options) : null;
460
- const contentText = readPropertyValueText(value, () => rawLabel?.getText() ?? null);
460
+ const contentText = readPropertyValueText(value, () => rawLabel?.getText(rawLabel.getDefaultLanguage()) ?? null);
461
461
  const common = {
462
462
  hierarchy: {
463
463
  isLeaf: value.inherited == null || !value.inherited,
@@ -109,11 +109,11 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
109
109
  /**
110
110
  * Get text in a specific language, falling back when it has none
111
111
  */
112
- getText(language?: T[number]): string;
112
+ getText(language: T[number]): string;
113
113
  /**
114
114
  * Get rich text in a specific language, falling back when it has none
115
115
  */
116
- getRichText(language?: T[number]): string;
116
+ getRichText(language: T[number]): string;
117
117
  /**
118
118
  * Get text in a specific language, with no fallback
119
119
  */
@@ -133,16 +133,16 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
133
133
  * can carry several entries for one language, and this returns all of them
134
134
  * rather than only the primary. Each entry carries both `text` and
135
135
  * `richText`, so a caller rendering a rich field reads them from here.
136
- * @param language - The language to read, or undefined for the default
136
+ * @param language - The language to read
137
137
  * @returns The entries, or an empty array when no language has any
138
138
  */
139
- getEntries(language?: T[number]): Array<MultilingualStringEntry>;
139
+ getEntries(language: T[number]): Array<MultilingualStringEntry>;
140
140
  /**
141
141
  * Get the text of every entry for a language, falling back when it has none
142
- * @param language - The language to read, or undefined for the default
142
+ * @param language - The language to read
143
143
  * @returns The texts, or an empty array when no language has any
144
144
  */
145
- getTexts(language?: T[number]): Array<string>;
145
+ getTexts(language: T[number]): Array<string>;
146
146
  /**
147
147
  * Get the text of every entry for a language, with no fallback
148
148
  * @param language - The language to read
@@ -259,10 +259,6 @@ export declare class MultilingualString<T extends ReadonlyArray<string> = Readon
259
259
  * @returns A new multilingual string
260
260
  */
261
261
  filterEntries(shouldKeep: (entry: MultilingualStringEntry, language: T[number]) => boolean): MultilingualString<T>;
262
- /**
263
- * Get the string representation, using the default language
264
- */
265
- toString(): string;
266
262
  /**
267
263
  * Get the JSON representation
268
264
  *
@@ -228,7 +228,7 @@ var MultilingualString = class MultilingualString {
228
228
  * can carry several entries for one language, and this returns all of them
229
229
  * rather than only the primary. Each entry carries both `text` and
230
230
  * `richText`, so a caller rendering a rich field reads them from here.
231
- * @param language - The language to read, or undefined for the default
231
+ * @param language - The language to read
232
232
  * @returns The entries, or an empty array when no language has any
233
233
  */
234
234
  getEntries(language) {
@@ -236,7 +236,7 @@ var MultilingualString = class MultilingualString {
236
236
  }
237
237
  /**
238
238
  * Get the text of every entry for a language, falling back when it has none
239
- * @param language - The language to read, or undefined for the default
239
+ * @param language - The language to read
240
240
  * @returns The texts, or an empty array when no language has any
241
241
  */
242
242
  getTexts(language) {
@@ -423,12 +423,6 @@ var MultilingualString = class MultilingualString {
423
423
  }, newAvailableLanguages);
424
424
  }
425
425
  /**
426
- * Get the string representation, using the default language
427
- */
428
- toString() {
429
- return this.getText();
430
- }
431
- /**
432
426
  * Get the JSON representation
433
427
  *
434
428
  * Carries `defaultLanguage`, because it is not derivable from the content:
@@ -85,6 +85,23 @@ function parseCollectionDisplayedProperties(reader) {
85
85
  label: value.label
86
86
  }]);
87
87
  }
88
+ /**
89
+ * Parses the "customize-special" "relations" properties, each pairing the
90
+ * property variables it links with "use-property" with a display "variant".
91
+ */
92
+ function parseCollectionRelations(reader) {
93
+ const relations = [];
94
+ const relationReaders = reader.nestedAllByValue("customize-special", "relations");
95
+ for (const relationReader of relationReaders) {
96
+ const variant = relationReader.value("variant");
97
+ const properties = parseCollectionDisplayedProperties(relationReader) ?? [];
98
+ for (const property of properties) relations.push({
99
+ ...property,
100
+ variant
101
+ });
102
+ }
103
+ return relations;
104
+ }
88
105
  const THREE_D_VIEWER_COMPONENT_DEFAULTS = {
89
106
  isInteractive: true,
90
107
  isControlsDisplayed: true
@@ -261,6 +278,7 @@ function parseCollectionComponent(parameters) {
261
278
  component: "collection",
262
279
  linkUuids: setLinks.map((link) => link.uuid),
263
280
  displayedProperties: parseCollectionDisplayedProperties(componentReader),
281
+ relations: parseCollectionRelations(componentReader),
264
282
  ...COLLECTION_PROPERTY_DEFAULTS,
265
283
  ...propertyOverrides,
266
284
  image: {
@@ -472,9 +490,12 @@ function parseQueryComponent(parameters) {
472
490
  }
473
491
  if (items.length === 0) throw new Error(formatComponentError("No queries found", "query", elementResource), { cause: componentProperty });
474
492
  const componentOptions = parseWebsiteOptions(elementResource.options, options);
475
- const collectionProperties = parseCollectionPropertyOverrides(componentReader.nestedByValue("sub-component-override", "collection"));
493
+ const overrideReader = componentReader.nestedByValue("sub-component-override", "collection");
494
+ const collectionProperties = parseCollectionPropertyOverrides(overrideReader);
476
495
  const displayedProperties = parseCollectionDisplayedProperties(componentReader);
477
496
  if (displayedProperties != null) collectionProperties.displayedProperties = displayedProperties;
497
+ const relations = parseCollectionRelations(overrideReader);
498
+ if (relations.length > 0) collectionProperties.relations = relations;
478
499
  return {
479
500
  component: "query",
480
501
  linkUuids: setLinks.map((link) => link.uuid),
@@ -104,7 +104,7 @@ function parseWebsiteOptions(rawOptions, options) {
104
104
  };
105
105
  const notes = parseNotes(rawOptions?.notes, options);
106
106
  for (const note of notes) {
107
- if (note.title?.getText() !== "Title label") continue;
107
+ if (note.title?.getText(note.title.getDefaultLanguage()) !== "Title label") continue;
108
108
  parsedOptions.labels.title = note.content;
109
109
  break;
110
110
  }
@@ -76,6 +76,7 @@ function parseWebsiteProperties(properties, websiteTree, sidebar, options, paren
76
76
  isPersistentIdentifierDisplayed: parent?.itemPage.isPersistentIdentifierDisplayed ?? true,
77
77
  iiifViewer: parent?.itemPage.iiifViewer ?? "universal-viewer"
78
78
  },
79
+ relations: { variant: parent?.relations.variant ?? "list" },
79
80
  options: {
80
81
  contextTree: parent?.options.contextTree ?? null,
81
82
  scopes: parent?.options.scopes ?? null,
@@ -117,7 +118,7 @@ function parseWebsiteProperties(properties, websiteTree, sidebar, options, paren
117
118
  websiteReader.readAllUuids(returnProperties.navbar, { searchBarBoundElementUuid: "bound-element-navbar-search-bar" });
118
119
  websiteReader.readAll(returnProperties.footer, { isDisplayed: "footer-displayed" });
119
120
  websiteReader.readAllUuids(returnProperties.footer, { logoUuid: "footer-logo" });
120
- const itemPageReader = websiteReader.nestedByValue("page-type", "item-page");
121
+ const itemPageReader = websiteReader.nestedByValue("customize-special", "item-page");
121
122
  if (itemPageReader.size > 0) {
122
123
  for (const [key, slug] of [
123
124
  ["description", "description"],
@@ -142,6 +143,7 @@ function parseWebsiteProperties(properties, websiteTree, sidebar, options, paren
142
143
  iiifViewer: "item-page-iiif-viewer"
143
144
  });
144
145
  }
146
+ websiteReader.nestedByValue("customize-special", "relations").readAll(returnProperties.relations, { variant: "variant" });
145
147
  if (websiteTree.options != null) {
146
148
  const parsedOptions = parseWebsiteOptions(websiteTree.options, options);
147
149
  returnProperties.options.scopes = (parsedOptions.scopes != null && parsedOptions.scopes.length > 0 ? parsedOptions : returnProperties.options).scopes;
@@ -70,6 +70,7 @@ export declare class WebsitePresentationReader<T extends LanguageCodes> {
70
70
  readAllUuids<O extends object>(target: O, labels: Partial<Record<UuidKeys<O>, string>>): void;
71
71
  nested(label: string): WebsitePresentationReader<T>;
72
72
  nestedByValue(label: string, value: WebsitePropertyContent<T>): WebsitePresentationReader<T>;
73
+ nestedAllByValue(label: string, value: WebsitePropertyContent<T>): Array<WebsitePresentationReader<T>>;
73
74
  get size(): number;
74
75
  }
75
76
  export declare function websitePresentationReader<T extends LanguageCodes>(properties: ReadonlyArray<SimplifiedProperty<T>>): WebsitePresentationReader<T>;
@@ -103,6 +103,14 @@ var WebsitePresentationReader = class WebsitePresentationReader {
103
103
  nestedByValue(label, value) {
104
104
  return new WebsitePresentationReader(this.propertyByValue(label, value)?.properties ?? []);
105
105
  }
106
+ nestedAllByValue(label, value) {
107
+ const readers = [];
108
+ for (const property of this.sourceProperties) if (getProperty([property], {
109
+ label,
110
+ valueContent: value
111
+ }) != null) readers.push(new WebsitePresentationReader(property.properties));
112
+ return readers;
113
+ }
106
114
  get size() {
107
115
  return this.sourceProperties.length;
108
116
  }
@@ -87,6 +87,10 @@ export type WebLoadingVariant = "spinner" | "skeleton" | "animation" | "none";
87
87
  * How an item page groups a repeated section
88
88
  */
89
89
  export type WebSectionVariant = "discrete" | "tabs-horizontal" | "tabs-vertical" | "tabular";
90
+ /**
91
+ * How a website displays an item's related items
92
+ */
93
+ export type WebRelationVariant = "list" | "dropdown-list" | "grid" | "gallery" | "inline";
90
94
  /**
91
95
  * The IIIF viewer a website renders images with
92
96
  */
@@ -206,6 +210,9 @@ export type Website<T extends LanguageCodes = LanguageCodes> = {
206
210
  isPersistentIdentifierDisplayed: boolean;
207
211
  iiifViewer: WebIiifViewer;
208
212
  };
213
+ relations: {
214
+ variant: WebRelationVariant;
215
+ };
209
216
  options: Prettify<WebOptions<T> & {
210
217
  stylesheets: {
211
218
  properties: Array<StylesheetItem>;
@@ -336,6 +343,11 @@ export type WebElementComponent<T extends LanguageCodes = LanguageCodes> = {
336
343
  uuid: string;
337
344
  label: MultilingualString<T> | null;
338
345
  }> | null;
346
+ relations: Array<{
347
+ uuid: string;
348
+ label: MultilingualString<T> | null;
349
+ variant: WebRelationVariant | null;
350
+ }>;
339
351
  variant: "slide" | "table" | "card" | "tile" | "showcase";
340
352
  paginationVariant: "default" | "numeric";
341
353
  loadingVariant: WebLoadingVariant;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
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,20 +45,20 @@
45
45
  "dist"
46
46
  ],
47
47
  "dependencies": {
48
- "fast-equals": "^6.0.4",
48
+ "fast-equals": "^6.1.0",
49
49
  "fast-xml-parser": "^5.11.2",
50
50
  "valibot": "^1.5.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@antfu/eslint-config": "^9.5.1",
54
- "@types/node": "^24.19.0",
54
+ "@types/node": "^24.19.1",
55
55
  "bumpp": "^12.3.0",
56
- "eslint": "^10.11.0",
56
+ "eslint": "^10.12.0",
57
57
  "eslint-plugin-erasable-syntax-only": "^0.7.2",
58
58
  "eslint-plugin-slop": "^0.1.3",
59
59
  "eslint-plugin-sonarjs": "^4.2.2",
60
60
  "knip": "^6.39.0",
61
- "oxfmt": "^0.71.0",
61
+ "oxfmt": "^0.72.0",
62
62
  "tsdown": "^0.23.0",
63
63
  "typescript": "^6.0.3",
64
64
  "vitest": "^5.0.3"