ochre-sdk 1.0.25 → 1.0.27

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.
@@ -35,7 +35,7 @@ declare function withLanguages<const TLanguages extends ReadonlyArray<string>>(l
35
35
  * single category when it is known, or an array when the item may be any
36
36
  * category in that list.
37
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.
38
- * @param options.shouldOmitEmbeddedItems - Whether to omit the embedded item hierarchy when fetching a recursive item category.
38
+ * @param options.shouldOmitEmbeddedItems - Whether to omit the embedded item hierarchy when fetching a recursive item category. Ignored when the fetched item does not expose recursive embedded items.
39
39
  * @param options.languages - Language codes to parse. Inline arrays preserve literal types automatically.
40
40
  * @param options.fetch - Custom fetch function to use instead of the default fetch
41
41
  * @returns An object containing the parsed item
@@ -49,7 +49,7 @@ declare function fetchItem<const TContainedItemCategory extends ContainedItemCat
49
49
  category?: undefined;
50
50
  containedItemCategory?: TContainedItemCategory;
51
51
  shouldOmitEmbeddedItems?: true;
52
- }): FetchItemResult<ItemWithoutEmbeddedItems<ItemCategoryWithEmbeddedItems, ContainedItemCategoryFromOption<ItemContainerCategory, TContainedItemCategory>, FetchLanguages<TLanguages>>>;
52
+ }): FetchItemResult<ItemWithoutEmbeddedItems<ItemCategoryWithEmbeddedItems, ContainedItemCategoryFromOption<ItemContainerCategory, TContainedItemCategory>, FetchLanguages<TLanguages>> | Item<Exclude<ItemCategory, ItemCategoryWithEmbeddedItems>, never, FetchLanguages<TLanguages>>>;
53
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> & {
54
54
  category: TCategory;
55
55
  containedItemCategory?: TContainedItemCategory;
@@ -58,7 +58,7 @@ declare function fetchItem<const TCategory extends ItemCategoryOption, const TCo
58
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> & {
59
59
  category: TCategory;
60
60
  containedItemCategory?: TContainedItemCategory;
61
- shouldOmitEmbeddedItems: ItemCategoryFromOption<TCategory> extends ItemCategoryWithEmbeddedItems ? true : never;
62
- }): FetchItemResult<ItemWithoutEmbeddedItems<Extract<ItemCategoryFromOption<TCategory>, ItemCategoryWithEmbeddedItems>, ContainedItemCategoryFromOption<Extract<ItemCategoryFromOption<TCategory>, ItemCategoryWithEmbeddedItems>, TContainedItemCategory>, FetchLanguages<TLanguages>>>;
61
+ shouldOmitEmbeddedItems: true;
62
+ }): FetchItemResult<ItemWithoutEmbeddedItems<Extract<ItemCategoryFromOption<TCategory>, ItemCategoryWithEmbeddedItems>, ContainedItemCategoryFromOption<Extract<ItemCategoryFromOption<TCategory>, ItemCategoryWithEmbeddedItems>, TContainedItemCategory>, FetchLanguages<TLanguages>> | Item<Exclude<ItemCategoryFromOption<TCategory>, ItemCategoryWithEmbeddedItems>, never, FetchLanguages<TLanguages>>>;
63
63
  //#endregion
64
64
  export { defineLanguages, fetchItem, withLanguages };
@@ -23,11 +23,6 @@ function assertItemCategoryAllowed(category, containedItemCategory) {
23
23
  for (const possibleCategory of categories) if (isItemContainerCategory(possibleCategory)) return;
24
24
  throw new Error(`containedItemCategory can only be used when category is "tree" or "set"; received category "${categories.join(", ")}"`);
25
25
  }
26
- function assertShouldOmitEmbeddedItemsAllowed(category, shouldOmitEmbeddedItems) {
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}"`);
30
- }
31
26
  function buildOmitEmbeddedItemsXQuery(uuid, category) {
32
27
  const collectionCategories = [];
33
28
  const categories = category == null ? [
@@ -106,25 +101,39 @@ async function fetchItem(uuid, options) {
106
101
  const parsedUuid = v.parse(uuidSchema, uuid);
107
102
  assertItemCategoryAllowed(options?.category, options?.containedItemCategory);
108
103
  const shouldOmitEmbeddedItems = options?.shouldOmitEmbeddedItems === true;
109
- assertShouldOmitEmbeddedItemsAllowed(options?.category, shouldOmitEmbeddedItems);
104
+ let shouldFetchOmittedEmbeddedItems = shouldOmitEmbeddedItems;
110
105
  let omitEmbeddedItemsCategory;
111
- if (options?.category != null) if (typeof options.category === "string") {
112
- if (isItemCategoryWithEmbeddedItems(options.category)) omitEmbeddedItemsCategory = options.category;
113
- } else {
106
+ if (options?.category != null) if (typeof options.category === "string") if (isItemCategoryWithEmbeddedItems(options.category)) omitEmbeddedItemsCategory = options.category;
107
+ else shouldFetchOmittedEmbeddedItems = false;
108
+ else {
114
109
  const categories = [];
115
110
  for (const possibleCategory of options.category) if (isItemCategoryWithEmbeddedItems(possibleCategory)) categories.push(possibleCategory);
116
111
  omitEmbeddedItemsCategory = categories;
112
+ shouldFetchOmittedEmbeddedItems = categories.length > 0;
117
113
  }
118
114
  const languages = options?.languages == null ? [] : parseLanguages(options.languages);
119
115
  const fetcher = options?.fetch ?? fetch;
120
- const response = shouldOmitEmbeddedItems ? await fetcher("https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?xquery&xsl=none&lang=\"*\"", {
116
+ const regularItemUrl = `https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?uuid=${parsedUuid}&xsl=none&lang="*"`;
117
+ let response = shouldFetchOmittedEmbeddedItems ? await fetcher("https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?xquery&xsl=none&lang=\"*\"", {
121
118
  method: "POST",
122
119
  body: buildOmitEmbeddedItemsXQuery(parsedUuid, omitEmbeddedItemsCategory),
123
120
  headers: { "Content-Type": "application/xquery" }
124
- }) : await fetcher(`https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?uuid=${parsedUuid}&xsl=none&lang="*"`);
121
+ }) : await fetcher(regularItemUrl);
125
122
  if (!response.ok) throw new Error("Failed to fetch OCHRE data", { cause: response.statusText });
126
123
  const dataRaw = await response.text();
127
- const data = new XMLParser(XML_PARSER_OPTIONS).parse(dataRaw);
124
+ const parser = new XMLParser(XML_PARSER_OPTIONS);
125
+ let data = parser.parse(dataRaw);
126
+ if (shouldFetchOmittedEmbeddedItems && typeof data === "object" && data != null && "result" in data) {
127
+ const result = data.result;
128
+ if (typeof result === "object" && result != null && "ochre" in result) {
129
+ const ochre = result.ochre;
130
+ if (typeof ochre === "object" && ochre != null && (Object.keys(ochre).length === 0 || "payload" in ochre && ochre.payload === "" && Object.keys(ochre).length === 1)) {
131
+ response = await fetcher(regularItemUrl);
132
+ if (!response.ok) throw new Error("Failed to fetch OCHRE data", { cause: response.statusText });
133
+ data = parser.parse(await response.text());
134
+ }
135
+ }
136
+ }
128
137
  const { success, issues, output } = v.safeParse(XMLData, data);
129
138
  if (!success) throw createSchemaValidationError("Failed to parse OCHRE data", issues);
130
139
  restoreXMLMetadata(output, data);
@@ -135,7 +144,6 @@ async function fetchItem(uuid, options) {
135
144
  parseResourceView: (view, context) => parseWebpageView(view, { languages: context.metadata.languages }, context)
136
145
  });
137
146
  assertItemCategoryAllowed(parsedItem.category, options?.containedItemCategory);
138
- assertShouldOmitEmbeddedItemsAllowed(parsedItem.category, shouldOmitEmbeddedItems);
139
147
  return {
140
148
  item: shouldOmitEmbeddedItems && isItemWithEmbeddedItems(parsedItem) ? omitEmbeddedItems(parsedItem) : parsedItem,
141
149
  error: null,
@@ -12,7 +12,7 @@ const ITEM_PAGE_TOKEN = "item-page";
12
12
  const ENTRY_PAGE_TOKEN = "entry-page";
13
13
  const VARIANT_TOKEN = "variant";
14
14
  const HEADING_LEVEL_TOKEN = "heading-level";
15
- const RAW_MDX_BLOCK_DELIMITER = "```***```";
15
+ const RAW_MDX_BLOCK_DELIMITER = "``md``";
16
16
  const RAW_MDX_BLOCK_PLACEHOLDER_PREFIX = "\0raw-mdx-block:";
17
17
  const RAW_MDX_BLOCK_PLACEHOLDER_SUFFIX = "\0";
18
18
  const MDX_QUOTED_ATTRIBUTE_ESCAPE_REGEX = /[\n\r"]/;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
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",
@@ -67,7 +67,7 @@
67
67
  }
68
68
  },
69
69
  "dependencies": {
70
- "date-fns": "^4.3.0",
70
+ "date-fns": "^4.4.0",
71
71
  "fast-equals": "^6.0.0",
72
72
  "fast-xml-parser": "^5.8.0",
73
73
  "valibot": "^1.4.1"
@@ -76,8 +76,8 @@
76
76
  "@antfu/eslint-config": "^9.0.0",
77
77
  "@types/node": "^24.12.4",
78
78
  "bumpp": "^11.1.0",
79
- "eslint": "^10.4.0",
80
- "knip": "^6.14.2",
79
+ "eslint": "^10.4.1",
80
+ "knip": "^6.15.0",
81
81
  "prettier": "^3.8.3",
82
82
  "tsdown": "^0.22.1",
83
83
  "typescript": "^6.0.3",