ochre-sdk 1.0.20 → 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.
package/README.md CHANGED
@@ -46,10 +46,12 @@ present and `error` is `null`; on failure, the parsed value is `null` and
46
46
  ## Core API
47
47
 
48
48
  - `fetchItem(uuid, options)` fetches and parses a single OCHRE item. Passing
49
- `category` narrows the returned TypeScript type, and `containedItemCategory`
50
- controls how nested Tree or Set contents are parsed. For large Trees or Sets,
51
- pass `shouldOmitEmbeddedItems: true` to fetch the top-level item without its
52
- embedded `<items>` payload.
49
+ `category` as a single category narrows the returned TypeScript type to that
50
+ category; passing an array narrows it to any category in that list and lets the
51
+ parser resolve the actual category from the payload. `containedItemCategory`
52
+ controls how nested Tree or Set contents are parsed. For large recursive item
53
+ categories, pass `shouldOmitEmbeddedItems: true` to fetch the top-level item
54
+ without its embedded item hierarchy.
53
55
  - `fetchItemLinks(uuid, options)` fetches items linked from a source item and
54
56
  parses them as embedded OCHRE items.
55
57
  - `fetchGallery(params, options)` fetches paginated resource galleries with an
@@ -1,4 +1,4 @@
1
- import { ContainedItemCategory, ContainedItemCategoryFromOption, ContainedItemCategoryOption, Item, ItemCategory, ItemContainerCategory, ItemWithoutEmbeddedItems } from "../types/index.mjs";
1
+ import { ContainedItemCategoryFromOption, ContainedItemCategoryOption, Item, ItemCategory, ItemCategoryFromOption, ItemCategoryOption, ItemCategoryWithEmbeddedItems, ItemContainerCategory, ItemWithoutEmbeddedItems } from "../types/index.mjs";
2
2
  import { FetchBaseOptions, FetchLanguages } from "../parsers/helpers.mjs";
3
3
 
4
4
  //#region src/fetchers/item.d.ts
@@ -31,9 +31,11 @@ declare function withLanguages<const TLanguages extends ReadonlyArray<string>>(l
31
31
  *
32
32
  * @param uuid - The UUID of the OCHRE item to fetch
33
33
  * @param options - Required options object
34
- * @param options.category - The category of the OCHRE item to fetch
34
+ * @param options.category - The category of the OCHRE item to fetch. Pass a
35
+ * single category when it is known, or an array when the item may be any
36
+ * category in that list.
35
37
  * @param options.containedItemCategory - The category of items inside the OCHRE item to fetch. Only valid for Trees and Sets. Tree accepts one category; Set accepts one category or an array.
36
- * @param options.shouldOmitEmbeddedItems - Whether to omit the embedded `<items>` node when fetching a Tree or Set.
38
+ * @param options.shouldOmitEmbeddedItems - Whether to omit the embedded item hierarchy when fetching a recursive item category.
37
39
  * @param options.languages - Language codes to parse. Inline arrays preserve literal types automatically.
38
40
  * @param options.fetch - Custom fetch function to use instead of the default fetch
39
41
  * @returns An object containing the parsed item
@@ -47,21 +49,16 @@ declare function fetchItem<const TContainedItemCategory extends ContainedItemCat
47
49
  category?: undefined;
48
50
  containedItemCategory?: TContainedItemCategory;
49
51
  shouldOmitEmbeddedItems?: true;
50
- }): FetchItemResult<ItemWithoutEmbeddedItems<ItemContainerCategory, ContainedItemCategoryFromOption<ItemContainerCategory, TContainedItemCategory>, FetchLanguages<TLanguages>>>;
51
- declare function fetchItem<const TCategory extends ItemContainerCategory, const TContainedItemCategory extends ContainedItemCategoryOption<TCategory> | undefined = undefined, const TLanguages extends ReadonlyArray<string> | undefined = undefined>(uuid: string, options: FetchBaseOptions<TLanguages> & {
52
+ }): FetchItemResult<ItemWithoutEmbeddedItems<ItemCategoryWithEmbeddedItems, ContainedItemCategoryFromOption<ItemContainerCategory, TContainedItemCategory>, FetchLanguages<TLanguages>>>;
53
+ declare function fetchItem<const TCategory extends ItemCategoryOption, const TContainedItemCategory extends ContainedItemCategoryOption<ItemCategoryFromOption<TCategory>> | undefined = undefined, const TLanguages extends ReadonlyArray<string> | undefined = undefined>(uuid: string, options: FetchBaseOptions<TLanguages> & {
52
54
  category: TCategory;
53
55
  containedItemCategory?: TContainedItemCategory;
54
56
  shouldOmitEmbeddedItems?: false;
55
- }): FetchItemResult<Item<TCategory, ContainedItemCategoryFromOption<TCategory, TContainedItemCategory>, FetchLanguages<TLanguages>>>;
56
- declare function fetchItem<const TCategory extends ItemContainerCategory, const TContainedItemCategory extends ContainedItemCategoryOption<TCategory> | undefined = undefined, const TLanguages extends ReadonlyArray<string> | undefined = undefined>(uuid: string, options: FetchBaseOptions<TLanguages> & {
57
+ }): FetchItemResult<Item<ItemCategoryFromOption<TCategory>, ContainedItemCategoryFromOption<ItemCategoryFromOption<TCategory>, TContainedItemCategory>, FetchLanguages<TLanguages>>>;
58
+ declare function fetchItem<const TCategory extends ItemCategoryOption, const TContainedItemCategory extends ContainedItemCategoryOption<Extract<ItemCategoryFromOption<TCategory>, ItemCategoryWithEmbeddedItems>> | undefined = undefined, const TLanguages extends ReadonlyArray<string> | undefined = undefined>(uuid: string, options: FetchBaseOptions<TLanguages> & {
57
59
  category: TCategory;
58
60
  containedItemCategory?: TContainedItemCategory;
59
- shouldOmitEmbeddedItems: true;
60
- }): FetchItemResult<ItemWithoutEmbeddedItems<TCategory, ContainedItemCategoryFromOption<TCategory, TContainedItemCategory>, FetchLanguages<TLanguages>>>;
61
- declare function fetchItem<const TCategory extends ItemCategory, const TLanguages extends ReadonlyArray<string> | undefined = undefined>(uuid: string, options: FetchBaseOptions<TLanguages> & {
62
- category: TCategory;
63
- containedItemCategory?: never;
64
- shouldOmitEmbeddedItems?: false;
65
- }): FetchItemResult<Item<TCategory, ContainedItemCategory<TCategory>, FetchLanguages<TLanguages>>>;
61
+ shouldOmitEmbeddedItems: ItemCategoryFromOption<TCategory> extends ItemCategoryWithEmbeddedItems ? true : never;
62
+ }): FetchItemResult<ItemWithoutEmbeddedItems<Extract<ItemCategoryFromOption<TCategory>, ItemCategoryWithEmbeddedItems>, ContainedItemCategoryFromOption<Extract<ItemCategoryFromOption<TCategory>, ItemCategoryWithEmbeddedItems>, TContainedItemCategory>, FetchLanguages<TLanguages>>>;
66
63
  //#endregion
67
64
  export { defineLanguages, fetchItem, withLanguages };
@@ -11,63 +11,62 @@ import { XMLParser } from "fast-xml-parser";
11
11
  function isItemContainerCategory(category) {
12
12
  return category === "tree" || category === "set";
13
13
  }
14
- function isItemContainer(item) {
15
- return isItemContainerCategory(item.category);
14
+ function isItemCategoryWithEmbeddedItems(category) {
15
+ return category === "tree" || category === "bibliography" || category === "concept" || category === "spatialUnit" || category === "period" || category === "resource" || category === "set";
16
+ }
17
+ function isItemWithEmbeddedItems(item) {
18
+ return isItemCategoryWithEmbeddedItems(item.category);
16
19
  }
17
20
  function assertItemCategoryAllowed(category, containedItemCategory) {
18
- if (category == null || containedItemCategory == null || isItemContainerCategory(category)) return;
19
- throw new Error(`containedItemCategory can only be used when category is "tree" or "set"; received category "${category}"`);
21
+ if (category == null || containedItemCategory == null) return;
22
+ const categories = typeof category === "string" ? [category] : category;
23
+ for (const possibleCategory of categories) if (isItemContainerCategory(possibleCategory)) return;
24
+ throw new Error(`containedItemCategory can only be used when category is "tree" or "set"; received category "${categories.join(", ")}"`);
20
25
  }
21
26
  function assertShouldOmitEmbeddedItemsAllowed(category, shouldOmitEmbeddedItems) {
22
- if (!shouldOmitEmbeddedItems || category == null || isItemContainerCategory(category)) return;
23
- throw new Error(`shouldOmitEmbeddedItems can only be used when category is "tree" or "set"; received category "${category}"`);
24
- }
25
- function normalizeFetchedCategory(category) {
26
- switch (category) {
27
- case "tree":
28
- case "bibliography":
29
- case "concept":
30
- case "spatialUnit":
31
- case "period":
32
- case "person":
33
- case "propertyVariable":
34
- case "propertyValue":
35
- case "resource":
36
- case "text":
37
- case "set": return category;
38
- case "variable": return "propertyVariable";
39
- case "value": return "propertyValue";
40
- default: return null;
41
- }
42
- }
43
- function inferFetchItemCategory(rawOchre) {
44
- const metadataCategory = normalizeFetchedCategory(rawOchre.metadata.item?.category);
45
- if (metadataCategory != null) return metadataCategory;
46
- if ("tree" in rawOchre) return "tree";
47
- if ("bibliography" in rawOchre) return "bibliography";
48
- if ("concept" in rawOchre) return "concept";
49
- if ("spatialUnit" in rawOchre) return "spatialUnit";
50
- if ("period" in rawOchre) return "period";
51
- if ("person" in rawOchre) return "person";
52
- if ("propertyVariable" in rawOchre || "variable" in rawOchre) return "propertyVariable";
53
- if ("propertyValue" in rawOchre || "value" in rawOchre) return "propertyValue";
54
- if ("resource" in rawOchre) return "resource";
55
- if ("text" in rawOchre) return "text";
56
- if ("set" in rawOchre) return "set";
57
- throw new Error("Could not infer OCHRE item category", { cause: rawOchre });
27
+ if (!shouldOmitEmbeddedItems || category == null) return;
28
+ const categories = typeof category === "string" ? [category] : category;
29
+ for (const possibleCategory of categories) if (!isItemCategoryWithEmbeddedItems(possibleCategory)) throw new Error(`shouldOmitEmbeddedItems can only be used when the item category contains embedded items; received category "${possibleCategory}"`);
58
30
  }
59
- function buildOmitEmbeddedItemsXQuery(uuid) {
31
+ function buildOmitEmbeddedItemsXQuery(uuid, category) {
32
+ const collectionCategories = [];
33
+ const categories = category == null ? [
34
+ "tree",
35
+ "bibliography",
36
+ "concept",
37
+ "spatialUnit",
38
+ "period",
39
+ "resource",
40
+ "set"
41
+ ] : typeof category === "string" ? [category] : category;
42
+ for (const possibleCategory of categories) if (!collectionCategories.includes(possibleCategory)) collectionCategories.push(possibleCategory);
43
+ const collectionQueries = [];
44
+ for (const collectionCategory of collectionCategories) collectionQueries.push(`cts:search(fn:collection("ochre/${collectionCategory}")/ochre, $uuid-query)`);
60
45
  return `xquery version "1.0-ml";
61
46
 
62
- let $ochre := doc()/ochre[@uuid=${stringLiteral(uuid)}][1]
47
+ let $uuid := ${stringLiteral(uuid)}
48
+ let $uuid-query := cts:element-attribute-value-query(xs:QName("ochre"), xs:QName("uuid"), $uuid, "exact")
49
+ let $ochre := (
50
+ ${collectionQueries.join(",\n ")}
51
+ )[1]
52
+ let $item := (
53
+ $ochre/tree,
54
+ $ochre/bibliography,
55
+ $ochre/concept,
56
+ $ochre/spatialUnit,
57
+ $ochre/period,
58
+ $ochre/resource,
59
+ $ochre/set
60
+ )[1]
61
+ let $embedded-child-name := if (local-name($item) = ("tree", "set")) then "items" else local-name($item)
63
62
  return
64
- if (empty($ochre)) then ()
63
+ if (empty($ochre) or empty($item)) then ()
65
64
  else element ochre {
66
65
  $ochre/@*,
67
66
  for $node in $ochre/node()
68
67
  return
69
- if (local-name($node) = ("tree", "set"))
70
- then element { node-name($node) } { $node/@*, $node/node()[not(self::items)] }
68
+ if ($node is $item)
69
+ then element { node-name($item) } { $item/@*, $item/node()[not(self::*[local-name() = $embedded-child-name])] }
71
70
  else $node
72
71
  }`;
73
72
  }
@@ -108,11 +107,19 @@ async function fetchItem(uuid, options) {
108
107
  assertItemCategoryAllowed(options?.category, options?.containedItemCategory);
109
108
  const shouldOmitEmbeddedItems = options?.shouldOmitEmbeddedItems === true;
110
109
  assertShouldOmitEmbeddedItemsAllowed(options?.category, shouldOmitEmbeddedItems);
110
+ let omitEmbeddedItemsCategory;
111
+ if (options?.category != null) if (typeof options.category === "string") {
112
+ if (isItemCategoryWithEmbeddedItems(options.category)) omitEmbeddedItemsCategory = options.category;
113
+ } else {
114
+ const categories = [];
115
+ for (const possibleCategory of options.category) if (isItemCategoryWithEmbeddedItems(possibleCategory)) categories.push(possibleCategory);
116
+ omitEmbeddedItemsCategory = categories;
117
+ }
111
118
  const languages = options?.languages == null ? [] : parseLanguages(options.languages);
112
119
  const fetcher = options?.fetch ?? fetch;
113
120
  const response = shouldOmitEmbeddedItems ? await fetcher("https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?xquery&xsl=none&lang=\"*\"", {
114
121
  method: "POST",
115
- body: buildOmitEmbeddedItemsXQuery(parsedUuid),
122
+ body: buildOmitEmbeddedItemsXQuery(parsedUuid, omitEmbeddedItemsCategory),
116
123
  headers: { "Content-Type": "application/xquery" }
117
124
  }) : await fetcher(`https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?uuid=${parsedUuid}&xsl=none&lang="*"`);
118
125
  if (!response.ok) throw new Error("Failed to fetch OCHRE data", { cause: response.statusText });
@@ -121,17 +128,16 @@ async function fetchItem(uuid, options) {
121
128
  const { success, issues, output } = v.safeParse(XMLData, data);
122
129
  if (!success) throw createSchemaValidationError("Failed to parse OCHRE data", issues);
123
130
  restoreXMLMetadata(output, data);
124
- const category = options?.category ?? inferFetchItemCategory(output.result.ochre);
125
- assertItemCategoryAllowed(category, options?.containedItemCategory);
126
- assertShouldOmitEmbeddedItemsAllowed(category, shouldOmitEmbeddedItems);
127
131
  const parsedItem = parseItem(output, {
128
- category,
132
+ category: options?.category,
129
133
  containedItemCategory: options?.containedItemCategory,
130
134
  languages,
131
135
  parseResourceView: (view, context) => parseWebpageView(view, { languages: context.metadata.languages }, context)
132
136
  });
137
+ assertItemCategoryAllowed(parsedItem.category, options?.containedItemCategory);
138
+ assertShouldOmitEmbeddedItemsAllowed(parsedItem.category, shouldOmitEmbeddedItems);
133
139
  return {
134
- item: shouldOmitEmbeddedItems && isItemContainer(parsedItem) ? omitEmbeddedItems(parsedItem) : parsedItem,
140
+ item: shouldOmitEmbeddedItems && isItemWithEmbeddedItems(parsedItem) ? omitEmbeddedItems(parsedItem) : parsedItem,
135
141
  error: null,
136
142
  detailedError: null
137
143
  };
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { MultilingualOptions, MultilingualString, MultilingualStringEntries, MultilingualStringEntry, MultilingualStringInput, MultilingualStringJSON, MultilingualStringObject, MultilingualStringText } from "./parsers/multilingual.mjs";
2
2
  import { AccordionWebBlock, ContextTree, ContextTreeFilterLevel, ContextTreeLevel, ContextTreeLevelItem, Scope, Style, StylesheetCategory, StylesheetItem, WebAccordionItem, WebBlock, WebBlockByLayout, WebBlockItem, WebBlockLayout, WebElement, WebElementComponent, WebElementComponentName, WebElementComponentOf, WebElementOf, WebImage, WebTitle, Webpage, Website, WebsiteMetadata, WebsitePropertyQuery, WebsitePropertyQueryNode, WebsiteSegment, WebsiteType } from "./types/website.mjs";
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, ItemContainerCategory, ItemLink, ItemLinkCategory, ItemLinks, ItemPayloadKind, ItemProperty, ItemWithoutEmbeddedItems, LanguageCodes, License, Metadata, Note, Observation, Period, PeriodItemLink, Person, PersonItemLink, Property, PropertyLike, PropertyValue, PropertyValueContent, PropertyValueDataType, PropertyValueItemLink, PropertyValueQueryItem, PropertyVariable, PropertyVariableItemLink, Query, QueryGroup, QueryLeaf, QueryablePropertyValueDataType, RecursiveItemCategory, Resource, ResourceItemLink, Section, Set, SetAttributeValueQueryItem, SetBibliography, SetConcept, SetItem, SetItemCategory, SetItemLink, SetItemProperty, SetItemSimplifiedProperty, SetItemsSort, SetItemsSortDirection, SetPeriod, SetResource, SetSpatialUnit, SetTree, SimplifiedProperty, SpatialUnit, SpatialUnitItemLink, Text, TextItemLink, TopLevelItem, Tree, TreeItemCategory, TreeItemLink } from "./types/index.mjs";
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, Period, PeriodItemLink, Person, PersonItemLink, Property, PropertyLike, PropertyValue, PropertyValueContent, PropertyValueDataType, PropertyValueItemLink, PropertyValueQueryItem, PropertyVariable, PropertyVariableItemLink, Query, QueryGroup, QueryLeaf, QueryablePropertyValueDataType, RecursiveItemCategory, Resource, ResourceItemLink, Section, Set, SetAttributeValueQueryItem, SetBibliography, SetConcept, SetItem, SetItemCategory, SetItemLink, SetItemProperty, SetItemSimplifiedProperty, SetItemsSort, SetItemsSortDirection, SetPeriod, SetResource, SetSpatialUnit, SetTree, SimplifiedProperty, SpatialUnit, SpatialUnitItemLink, Text, TextItemLink, TopLevelItem, Tree, TreeItemCategory, TreeItemLink } from "./types/index.mjs";
4
4
  import { fetchGallery } from "./fetchers/gallery.mjs";
5
5
  import { fetchItemLinks } from "./fetchers/item-links.mjs";
6
6
  import { defineLanguages, fetchItem, withLanguages } from "./fetchers/item.mjs";
@@ -10,4 +10,4 @@ import { fetchWebsiteMetadata } from "./fetchers/website-metadata.mjs";
10
10
  import { fetchWebsite } from "./fetchers/website.mjs";
11
11
  import { PropertyOptions, filterProperties, getLeafPropertyValues, getPropertyByVariableLabel, getPropertyByVariableLabelAndValue, getPropertyByVariableLabelAndValueContent, getPropertyByVariableLabelAndValueContents, getPropertyByVariableLabelAndValues, getPropertyByVariableUuid, getPropertyValueByVariableLabel, getPropertyValueByVariableUuid, getPropertyValueContentByVariableLabel, getPropertyValueContentByVariableUuid, getPropertyValueContentsByVariableUuid, getPropertyValuesByVariableLabel, getPropertyValuesByVariableUuid, getUniqueProperties, getUniquePropertyVariableLabels } from "./getters.mjs";
12
12
  import { DEFAULT_PAGE_SIZE, flattenItemProperties } from "./helpers.mjs";
13
- 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 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 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 Period, type PeriodItemLink, type Person, type PersonItemLink, type Property, type PropertyLike, PropertyOptions, type PropertyValue, type PropertyValueContent, type PropertyValueDataType, type PropertyValueItemLink, type PropertyValueQueryItem, type PropertyVariable, type PropertyVariableItemLink, type Query, type QueryGroup, type QueryLeaf, type QueryablePropertyValueDataType, type RecursiveItemCategory, type Resource, type ResourceItemLink, type Scope, type Section, type Set, type SetAttributeValueQueryItem, type SetBibliography, type SetConcept, type SetItem, type SetItemCategory, type SetItemLink, type SetItemProperty, type SetItemSimplifiedProperty, type SetItemsSort, type SetItemsSortDirection, type SetPeriod, type SetResource, type SetSpatialUnit, 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 WebImage, type WebTitle, type Webpage, type Website, type WebsiteMetadata, type WebsitePropertyQuery, type WebsitePropertyQueryNode, type WebsiteSegment, type WebsiteType, defineLanguages, fetchGallery, fetchItem, fetchItemLinks, fetchSetItems, fetchSetPropertyValues, fetchWebsite, fetchWebsiteMetadata, filterProperties, flattenItemProperties, getLeafPropertyValues, getPropertyByVariableLabel, getPropertyByVariableLabelAndValue, getPropertyByVariableLabelAndValueContent, getPropertyByVariableLabelAndValueContents, getPropertyByVariableLabelAndValues, getPropertyByVariableUuid, getPropertyValueByVariableLabel, getPropertyValueByVariableUuid, getPropertyValueContentByVariableLabel, getPropertyValueContentByVariableUuid, getPropertyValueContentsByVariableUuid, getPropertyValuesByVariableLabel, getPropertyValuesByVariableUuid, getUniqueProperties, getUniquePropertyVariableLabels, withLanguages };
13
+ 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 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 Period, type PeriodItemLink, type Person, type PersonItemLink, type Property, type PropertyLike, PropertyOptions, type PropertyValue, type PropertyValueContent, type PropertyValueDataType, type PropertyValueItemLink, type PropertyValueQueryItem, type PropertyVariable, type PropertyVariableItemLink, type Query, type QueryGroup, type QueryLeaf, type QueryablePropertyValueDataType, type RecursiveItemCategory, type Resource, type ResourceItemLink, type Scope, type Section, type Set, type SetAttributeValueQueryItem, type SetBibliography, type SetConcept, type SetItem, type SetItemCategory, type SetItemLink, type SetItemProperty, type SetItemSimplifiedProperty, type SetItemsSort, type SetItemsSortDirection, type SetPeriod, type SetResource, type SetSpatialUnit, 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 WebImage, type WebTitle, type Webpage, type Website, type WebsiteMetadata, type WebsitePropertyQuery, type WebsitePropertyQueryNode, type WebsiteSegment, type WebsiteType, defineLanguages, fetchGallery, fetchItem, fetchItemLinks, fetchSetItems, fetchSetPropertyValues, fetchWebsite, fetchWebsiteMetadata, filterProperties, flattenItemProperties, getLeafPropertyValues, getPropertyByVariableLabel, getPropertyByVariableLabelAndValue, getPropertyByVariableLabelAndValueContent, getPropertyByVariableLabelAndValueContents, getPropertyByVariableLabelAndValues, getPropertyByVariableUuid, getPropertyValueByVariableLabel, getPropertyValueByVariableUuid, getPropertyValueContentByVariableLabel, getPropertyValueContentByVariableUuid, getPropertyValueContentsByVariableUuid, getPropertyValuesByVariableLabel, getPropertyValuesByVariableUuid, getUniqueProperties, getUniquePropertyVariableLabels, withLanguages };
@@ -1,5 +1,5 @@
1
1
  import { Webpage } from "../types/website.mjs";
2
- import { Bibliography, ContainedItemCategoryFromOption, ContainedItemCategoryOption, Gallery, Identification, Item, ItemCategory, ItemLinks, Metadata, Note, Person, Property, Resource, SetItem, SetItemCategory, SimplifiedProperty } from "../types/index.mjs";
2
+ import { Bibliography, ContainedItemCategoryFromOption, ContainedItemCategoryOption, Gallery, Identification, Item, ItemCategory, ItemCategoryFromOption, ItemCategoryOption, ItemContainerCategory, ItemLinks, Metadata, Note, Person, Property, Resource, SetItem, SetItemCategory, SimplifiedProperty } from "../types/index.mjs";
3
3
  import { XMLBibliography, XMLData, XMLDataItem, XMLGalleryData, XMLIdentification, XMLItemLinks, XMLLink, XMLMetadata, XMLNote, XMLPerson, XMLProperty, XMLResource, XMLSetItems, XMLSimplifiedProperty } from "../xml/types.mjs";
4
4
  import { ParserOptions, getParserOptions, parseStringLike } from "./helpers.mjs";
5
5
 
@@ -49,14 +49,14 @@ declare function parseItem<const TContainedItemCategory extends ContainedItemCat
49
49
  languages: T;
50
50
  parseResourceView?: ResourceViewParser<T>;
51
51
  }): Item<ItemCategory, ContainedItemCategoryFromOption<ItemCategory, TContainedItemCategory>, T>;
52
- declare function parseItem<const TCategory extends ItemCategory, const TContainedItemCategory extends ContainedItemCategoryOption<TCategory> | undefined = undefined, T extends ReadonlyArray<string> = ReadonlyArray<string>>(rawData: XMLData, options: {
52
+ declare function parseItem<const TCategory extends ItemCategoryOption, const TContainedItemCategory extends ContainedItemCategoryOption<Extract<ItemCategoryFromOption<TCategory>, ItemContainerCategory>> | undefined = undefined, T extends ReadonlyArray<string> = ReadonlyArray<string>>(rawData: XMLData, options: {
53
53
  category: TCategory;
54
54
  containedItemCategory?: TContainedItemCategory;
55
55
  languages: T;
56
56
  parseResourceView?: ResourceViewParser<T>;
57
- }): Item<TCategory, ContainedItemCategoryFromOption<TCategory, TContainedItemCategory>, T>;
57
+ }): Item<ItemCategoryFromOption<TCategory>, ContainedItemCategoryFromOption<ItemCategoryFromOption<TCategory>, TContainedItemCategory>, T>;
58
58
  declare function parseItem(rawData: XMLData, options: {
59
- category?: ItemCategory;
59
+ category?: ItemCategoryOption;
60
60
  containedItemCategory?: ContainedItemCategoryOption<ItemCategory>;
61
61
  languages: ReadonlyArray<string>;
62
62
  parseResourceView?: ResourceViewParser<ReadonlyArray<string>>;
@@ -1305,7 +1305,15 @@ function parseItem(rawData, options) {
1305
1305
  languages: languagesToUse,
1306
1306
  containedItemCategory: options.containedItemCategory
1307
1307
  };
1308
- const category = options.category ?? normalizeCategory(rawOchre.metadata.item?.category) ?? inferTopLevelCategory(rawOchre);
1308
+ const inferredCategory = normalizeCategory(rawOchre.metadata.item?.category) ?? inferTopLevelCategory(rawOchre);
1309
+ let category = inferredCategory;
1310
+ if (options.category != null) {
1311
+ if (typeof options.category === "string") category = options.category;
1312
+ else if (!options.category.includes(inferredCategory)) throw new Error(`OCHRE item category "${inferredCategory}" is not one of the expected categories: ${options.category.join(", ")}`, { cause: {
1313
+ category: inferredCategory,
1314
+ categories: options.category
1315
+ } });
1316
+ }
1309
1317
  const defaultLanguage = resolveDefaultLanguage(rawOchre, languagesToUse);
1310
1318
  const belongsTo = {
1311
1319
  uuid: rawOchre.uuidBelongsTo,
@@ -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.linkTarget("link-to", transformPermanentIdentificationUrlToItemLink);
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.linkTarget("navigate-to", transformPermanentIdentificationUrlToItemLink);
334
+ let href = parseWebsiteLinkTarget(componentReader.valueNode("navigate-to"), context);
301
335
  if (href === null) {
302
- href = componentReader.linkTarget("link-to", transformPermanentIdentificationUrlToItemLink);
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.linkTarget("link-to", transformPermanentIdentificationUrlToItemLink);
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?.replace(SEGMENT_UNIQUE_SLUG_PREFIX_REGEX, "") ?? null;
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 sidebar = parseSidebar(resources, options);
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, context, slugPrefix),
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;
@@ -18,6 +18,10 @@ type ItemCategory = "tree" | "bibliography" | "concept" | "spatialUnit" | "perio
18
18
  * OCHRE item categories that can contain other items in API payloads.
19
19
  */
20
20
  type ItemContainerCategory = Extract<ItemCategory, "tree" | "set">;
21
+ /**
22
+ * OCHRE item categories that expose recursive embedded item payloads.
23
+ */
24
+ type ItemCategoryWithEmbeddedItems = Extract<ItemCategory, "tree" | "bibliography" | "concept" | "spatialUnit" | "period" | "resource" | "set">;
21
25
  /**
22
26
  * The category of items in a Tree
23
27
  */
@@ -26,6 +30,8 @@ type TreeItemCategory = Exclude<ItemCategory, "tree">;
26
30
  * The category of items in a Set
27
31
  */
28
32
  type SetItemCategory = ItemCategory;
33
+ type ItemCategoryOption<U extends ItemCategory = ItemCategory> = U | ReadonlyArray<U>;
34
+ type ItemCategoryFromOption<U extends ItemCategoryOption | undefined = undefined> = U extends ReadonlyArray<infer V> ? Extract<V, ItemCategory> : U extends ItemCategory ? U : ItemCategory;
29
35
  type ContainedItemCategory<U extends ItemCategory = ItemCategory> = U extends "tree" ? TreeItemCategory : U extends "set" ? SetItemCategory : never;
30
36
  type ContainedItemCategoryOption<U extends ItemCategory = ItemCategory> = U extends "tree" ? TreeItemCategory : U extends "set" ? SetItemCategory | ReadonlyArray<SetItemCategory> : never;
31
37
  type ContainedItemCategoryFromOption<U extends ItemCategory = ItemCategory, V extends ContainedItemCategoryOption<U> | undefined = undefined> = V extends ReadonlyArray<infer W> ? Extract<W, ContainedItemCategory<U>> : V extends ContainedItemCategory<U> ? V : ContainedItemCategory<U>;
@@ -448,9 +454,9 @@ type ItemLink<U extends ItemLinkCategory = ItemLinkCategory, T extends LanguageC
448
454
  */
449
455
  type Item<U extends ItemCategory = ItemCategory, V extends ContainedItemCategory<U> = ContainedItemCategory<U>, T extends LanguageCodes = LanguageCodes, W extends ItemPayloadKind = "topLevel"> = U extends ItemCategory ? U extends "tree" ? Tree<Extract<V, TreeItemCategory>, T, W> : U extends "set" ? Set<Extract<V, SetItemCategory>, T, W> : U extends "bibliography" ? Bibliography<T, W> : U extends "concept" ? Concept<T, W> : U extends "spatialUnit" ? SpatialUnit<T, W> : U extends "period" ? Period<T, W> : U extends "person" ? Person<T, W> : U extends "propertyVariable" ? PropertyVariable<T, W> : U extends "propertyValue" ? PropertyValue<T, W> : U extends "resource" ? Resource<T, W> : U extends "text" ? Text<T, W> : never : never;
450
456
  /**
451
- * A Tree or Set fetched without its embedded item hierarchy.
457
+ * An item fetched without its embedded item hierarchy.
452
458
  */
453
- type ItemWithoutEmbeddedItems<U extends ItemContainerCategory = ItemContainerCategory, V extends ContainedItemCategory<U> = ContainedItemCategory<U>, T extends LanguageCodes = LanguageCodes, W extends ItemPayloadKind = "topLevel"> = U extends ItemContainerCategory ? U extends "tree" ? Prettify<Omit<Tree<Extract<V, TreeItemCategory>, T, W>, "items">> : U extends "set" ? Prettify<Omit<Set<Extract<V, SetItemCategory>, T, W>, "items">> : never : never;
459
+ type ItemWithoutEmbeddedItems<U extends ItemCategoryWithEmbeddedItems = ItemCategoryWithEmbeddedItems, V extends ContainedItemCategory<U> = ContainedItemCategory<U>, T extends LanguageCodes = LanguageCodes, W extends ItemPayloadKind = "topLevel"> = U extends ItemCategoryWithEmbeddedItems ? U extends "tree" ? Prettify<Omit<Tree<Extract<V, TreeItemCategory>, T, W>, "items">> : U extends "set" ? Prettify<Omit<Set<Extract<V, SetItemCategory>, T, W>, "items">> : U extends "bibliography" ? Prettify<Omit<Bibliography<T, W>, "items">> : U extends "concept" ? Prettify<Omit<Concept<T, W>, "items">> : U extends "spatialUnit" ? Prettify<Omit<SpatialUnit<T, W>, "items">> : U extends "period" ? Prettify<Omit<Period<T, W>, "items">> : U extends "resource" ? Prettify<Omit<Resource<T, W>, "items">> : never : never;
454
460
  type TopLevelItem<U extends ItemCategory = ItemCategory, V extends ContainedItemCategory<U> = ContainedItemCategory<U>, T extends LanguageCodes = LanguageCodes> = Item<U, V, T, "topLevel">;
455
461
  type EmbeddedItem<U extends ItemCategory = ItemCategory, V extends ContainedItemCategory<U> = ContainedItemCategory<U>, T extends LanguageCodes = LanguageCodes> = Item<U, V, T, "embedded">;
456
462
  type AnyItem<U extends ItemCategory = ItemCategory, V extends ContainedItemCategory<U> = ContainedItemCategory<U>, T extends LanguageCodes = LanguageCodes> = Item<U, V, T, ItemPayloadKind>;
@@ -837,4 +843,4 @@ type QueryGroup = {
837
843
  */
838
844
  type Query = QueryLeaf | QueryGroup;
839
845
  //#endregion
840
- export { 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, ItemContainerCategory, ItemLink, ItemLinkCategory, ItemLinks, ItemPayloadKind, ItemProperty, ItemWithoutEmbeddedItems, LanguageCodes, License, Metadata, Note, Observation, Period, PeriodItemLink, Person, PersonItemLink, Property, PropertyLike, PropertyValue, PropertyValueContent, PropertyValueDataType, PropertyValueItemLink, PropertyValueQueryItem, PropertyVariable, PropertyVariableItemLink, Query, QueryGroup, QueryLeaf, QueryablePropertyValueDataType, RecursiveItemCategory, Resource, ResourceItemLink, Section, Set, SetAttributeValueQueryItem, SetBibliography, SetConcept, SetItem, SetItemCategory, SetItemLink, SetItemProperty, SetItemSimplifiedProperty, SetItemsSort, SetItemsSortDirection, SetPeriod, SetResource, SetSpatialUnit, SetTree, SimplifiedProperty, SpatialUnit, SpatialUnitItemLink, Text, TextItemLink, TopLevelItem, Tree, TreeItemCategory, TreeItemLink };
846
+ export { 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, Period, PeriodItemLink, Person, PersonItemLink, Property, PropertyLike, PropertyValue, PropertyValueContent, PropertyValueDataType, PropertyValueItemLink, PropertyValueQueryItem, PropertyVariable, PropertyVariableItemLink, Query, QueryGroup, QueryLeaf, QueryablePropertyValueDataType, RecursiveItemCategory, Resource, ResourceItemLink, Section, Set, SetAttributeValueQueryItem, SetBibliography, SetConcept, SetItem, SetItemCategory, SetItemLink, SetItemProperty, SetItemSimplifiedProperty, SetItemsSort, SetItemsSortDirection, SetPeriod, SetResource, SetSpatialUnit, SetTree, SimplifiedProperty, SpatialUnit, SpatialUnitItemLink, Text, TextItemLink, TopLevelItem, Tree, TreeItemCategory, TreeItemLink };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
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",