ochre-sdk 1.0.51 → 1.0.53

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.
@@ -233,6 +233,60 @@ function parseStylesheets(styles) {
233
233
  return parsedStyles;
234
234
  }
235
235
  /**
236
+ * Default values for a collection's display properties, shared between the
237
+ * "collection" component and the "query" component's collection overrides.
238
+ */
239
+ const COLLECTION_PROPERTY_DEFAULTS = {
240
+ variant: "slide",
241
+ paginationVariant: "default",
242
+ loadingVariant: "skeleton",
243
+ imageLayout: "start",
244
+ isImagePlaceholderDisplayed: true,
245
+ minimumColumnCount: null,
246
+ maximumColumnCount: null,
247
+ expectedItemCount: null,
248
+ isSortDisplayed: false,
249
+ isUsingQueryParams: false,
250
+ isInteractive: true
251
+ };
252
+ /**
253
+ * Reads the collection display properties explicitly set on a reader, omitting
254
+ * any that are unset. The "collection" component merges these over
255
+ * {@link COLLECTION_PROPERTY_DEFAULTS}, while the "query" component uses them as
256
+ * partial overrides for its embedded collection.
257
+ */
258
+ function parseCollectionPropertyOverrides(reader) {
259
+ const overrides = {};
260
+ function read(key, label) {
261
+ const value = reader.value(label);
262
+ if (value != null) overrides[key] = value;
263
+ }
264
+ read("variant", "variant");
265
+ read("paginationVariant", "pagination-variant");
266
+ read("loadingVariant", "loading-variant");
267
+ read("imageLayout", "image-layout");
268
+ read("isImagePlaceholderDisplayed", "image-placeholder-displayed");
269
+ read("minimumColumnCount", "minimum-column-count");
270
+ read("maximumColumnCount", "maximum-column-count");
271
+ read("expectedItemCount", "item-count");
272
+ read("isSortDisplayed", "sort-displayed");
273
+ read("isUsingQueryParams", "is-using-query-params");
274
+ read("isInteractive", "is-interactive");
275
+ return overrides;
276
+ }
277
+ /**
278
+ * Parses the "use-property" values defining which item properties a collection
279
+ * displays, returning `null` when none are set.
280
+ */
281
+ function parseCollectionDisplayedProperties(reader) {
282
+ const property = reader.property("use-property");
283
+ if (property == null) return null;
284
+ return property.values.filter((value) => value.uuid !== null).map((value) => ({
285
+ uuid: value.uuid,
286
+ label: value.label
287
+ }));
288
+ }
289
+ /**
236
290
  * Parses raw web element properties into a standardized WebElementComponent structure
237
291
  *
238
292
  * @param componentProperty - Raw component property data in OCHRE format
@@ -352,6 +406,14 @@ function parseWebElementProperties(componentProperty, elementResource, options,
352
406
  description: imageLink.description,
353
407
  quality: "high"
354
408
  };
409
+ const childResources = elementResource.resource ? normalizeWebsiteResources(elementResource.resource) : [];
410
+ const elements = [];
411
+ for (const childResource of childResources) {
412
+ const childReader = websitePresentationReader(childResource.properties ? parseSimplifiedProperties(childResource.properties, options) : []);
413
+ if (childReader.value("presentation") !== "element") continue;
414
+ if (childReader.nestedByValue("presentation", "element").value("component") === "button") continue;
415
+ elements.push(parseWebElement(childResource, options, context));
416
+ }
355
417
  properties = {
356
418
  component: "button",
357
419
  variant,
@@ -361,46 +423,27 @@ function parseWebElementProperties(componentProperty, elementResource, options,
361
423
  label: elementResource.document && "content" in elementResource.document ? parseXMLContent(elementResource.document, options) : null,
362
424
  startIcon,
363
425
  endIcon,
364
- image
426
+ image,
427
+ elements
365
428
  };
366
429
  break;
367
430
  }
368
431
  case "collection": {
369
432
  const setLinks = getWebsiteLinks(websiteLinks, "set");
370
433
  if (setLinks.length === 0) throw new Error(formatComponentError("Set links not found", componentName, elementResource), { cause: componentProperty });
371
- const displayedProperties = componentReader.property("use-property");
372
- const variant = componentReader.valueOr("variant", "slide");
373
- const paginationVariant = componentReader.valueOr("pagination-variant", "default");
374
- const loadingVariant = componentReader.valueOr("loading-variant", "skeleton");
375
- const expectedItemCount = componentReader.valueOr("item-count", null);
376
- const isUsingQueryParams = componentReader.valueOr("is-using-query-params", false);
377
434
  const isFilterResultsBarDisplayed = componentReader.valueOr("filter-results-bar-displayed", false);
378
435
  const isFilterInputDisplayed = componentReader.valueOr("filter-input-displayed", false);
379
436
  const isFilterLimitedToInputFilter = componentReader.valueOr("filter-limit-to-input-filter", false);
380
437
  const isFilterLimitedToLeafPropertyValues = componentReader.valueOr("filter-limit-to-leaf-property-values", false);
381
- const isSortDisplayed = componentReader.valueOr("sort-displayed", false);
382
438
  const isFilterSidebarDisplayed = componentReader.valueOr("filter-sidebar-displayed", false);
383
439
  const filterSidebarSort = componentReader.valueOr("filter-sidebar-sort", "default");
384
- const imageLayout = componentReader.valueOr("image-layout", "start");
385
- const isImagePlaceholderDisplayed = componentReader.valueOr("image-placeholder-displayed", true);
386
- const isInteractive = componentReader.valueOr("is-interactive", true);
387
440
  const componentOptions = parseWebsiteOptions(elementResource.options, options);
388
441
  properties = {
389
442
  component: "collection",
390
443
  linkUuids: setLinks.map((link) => link.uuid),
391
- displayedProperties: displayedProperties?.values.filter(({ uuid }) => uuid !== null).map((value) => ({
392
- uuid: value.uuid,
393
- label: value.label
394
- })) ?? null,
395
- variant,
396
- paginationVariant,
397
- loadingVariant,
398
- imageLayout,
399
- isImagePlaceholderDisplayed,
400
- expectedItemCount,
401
- isSortDisplayed,
402
- isUsingQueryParams,
403
- isInteractive,
444
+ displayedProperties: parseCollectionDisplayedProperties(componentReader),
445
+ ...COLLECTION_PROPERTY_DEFAULTS,
446
+ ...parseCollectionPropertyOverrides(componentReader),
404
447
  filter: {
405
448
  isSidebarDisplayed: isFilterSidebarDisplayed,
406
449
  isResultsBarDisplayed: isFilterResultsBarDisplayed,
@@ -601,31 +644,9 @@ function parseWebElementProperties(componentProperty, elementResource, options,
601
644
  }
602
645
  if (items.length === 0) throw new Error(formatComponentError("No queries found", componentName, elementResource), { cause: componentProperty });
603
646
  const componentOptions = parseWebsiteOptions(elementResource.options, options);
604
- const collectionProperties = {};
605
- const displayedProperties = componentReader.property("use-property");
606
- if (displayedProperties != null) collectionProperties.displayedProperties = displayedProperties.values.filter((value) => value.uuid !== null).map((value) => ({
607
- uuid: value.uuid,
608
- label: value.label
609
- }));
610
- const overrideReader = componentReader.nestedByValue("sub-component-override", "collection");
611
- const variant = overrideReader.value("variant");
612
- if (variant != null) collectionProperties.variant = variant;
613
- const paginationVariant = overrideReader.value("pagination-variant");
614
- if (paginationVariant != null) collectionProperties.paginationVariant = paginationVariant;
615
- const loadingVariant = overrideReader.value("loading-variant");
616
- if (loadingVariant != null) collectionProperties.loadingVariant = loadingVariant;
617
- const imageLayout = overrideReader.value("image-layout");
618
- if (imageLayout != null) collectionProperties.imageLayout = imageLayout;
619
- const isImagePlaceholderDisplayed = overrideReader.value("image-placeholder-displayed");
620
- if (isImagePlaceholderDisplayed != null) collectionProperties.isImagePlaceholderDisplayed = isImagePlaceholderDisplayed;
621
- const expectedItemCount = overrideReader.value("item-count");
622
- if (expectedItemCount != null) collectionProperties.expectedItemCount = expectedItemCount;
623
- const isSortDisplayed = overrideReader.value("sort-displayed");
624
- if (isSortDisplayed != null) collectionProperties.isSortDisplayed = isSortDisplayed;
625
- const isUsingQueryParams = overrideReader.value("is-using-query-params");
626
- if (isUsingQueryParams != null) collectionProperties.isUsingQueryParams = isUsingQueryParams;
627
- const isInteractive = overrideReader.value("is-interactive");
628
- if (isInteractive != null) collectionProperties.isInteractive = isInteractive;
647
+ const collectionProperties = parseCollectionPropertyOverrides(componentReader.nestedByValue("sub-component-override", "collection"));
648
+ const displayedProperties = parseCollectionDisplayedProperties(componentReader);
649
+ if (displayedProperties != null) collectionProperties.displayedProperties = displayedProperties;
629
650
  properties = {
630
651
  component: "query",
631
652
  linkUuids: setLinks.map((link) => link.uuid),
@@ -290,6 +290,7 @@ type WebElementComponent<T extends LanguageCodes = LanguageCodes> = {
290
290
  startIcon: string | null;
291
291
  endIcon: string | null;
292
292
  image: WebImage<T> | null;
293
+ elements: Array<WebElement<T>>;
293
294
  } | {
294
295
  component: "collection";
295
296
  linkUuids: Array<string>;
@@ -302,6 +303,8 @@ type WebElementComponent<T extends LanguageCodes = LanguageCodes> = {
302
303
  loadingVariant: "spinner" | "skeleton" | "animation" | "none";
303
304
  imageLayout: "top" | "bottom" | "start" | "end" | null;
304
305
  isImagePlaceholderDisplayed: boolean;
306
+ minimumColumnCount: number | null;
307
+ maximumColumnCount: number | null;
305
308
  expectedItemCount: number | null;
306
309
  isSortDisplayed: boolean;
307
310
  isUsingQueryParams: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.0.51",
3
+ "version": "1.0.53",
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",
@@ -47,7 +47,7 @@
47
47
  "dependencies": {
48
48
  "date-fns": "^4.4.0",
49
49
  "fast-equals": "^6.0.0",
50
- "fast-xml-parser": "^5.8.0",
50
+ "fast-xml-parser": "^5.9.2",
51
51
  "valibot": "^1.4.1"
52
52
  },
53
53
  "devDependencies": {
@@ -55,11 +55,11 @@
55
55
  "@types/node": "^24.13.2",
56
56
  "bumpp": "^11.1.0",
57
57
  "eslint": "^10.5.0",
58
- "knip": "^6.16.1",
59
- "oxfmt": "^0.54.0",
60
- "tsdown": "^0.22.2",
58
+ "knip": "^6.17.1",
59
+ "oxfmt": "^0.55.0",
60
+ "tsdown": "^0.22.3",
61
61
  "typescript": "^6.0.3",
62
- "vitest": "^4.1.8"
62
+ "vitest": "^4.1.9"
63
63
  },
64
64
  "scripts": {
65
65
  "dev": "tsdown src/index.ts --watch",