@digitalculture/ochre-sdk 0.13.9 → 0.14.0

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/dist/index.d.mts CHANGED
@@ -14,11 +14,11 @@ type Data<T extends DataCategory = DataCategory, U extends DataCategory = (T ext
14
14
  /**
15
15
  * Represents the category of the data
16
16
  */
17
- type DataCategory = "tree" | "set" | "resource" | "spatialUnit" | "concept" | "period" | "bibliography" | "person" | "propertyValue";
17
+ type DataCategory = "resource" | "spatialUnit" | "concept" | "period" | "bibliography" | "person" | "propertyValue" | "text" | "tree" | "set";
18
18
  /**
19
19
  * Represents the item of the data, with proper type narrowing based on category
20
20
  */
21
- type Item<T extends DataCategory = DataCategory, U extends DataCategory = (T extends "tree" ? Exclude<DataCategory, "tree"> : T extends "set" ? DataCategory : never)> = T extends "resource" ? Resource : T extends "spatialUnit" ? SpatialUnit : T extends "concept" ? Concept : T extends "period" ? Period : T extends "bibliography" ? Bibliography : T extends "person" ? Person : T extends "propertyValue" ? PropertyValue : T extends "tree" ? Tree<Exclude<U, "tree">> : T extends "set" ? Set<U> : Resource | SpatialUnit | Concept | Period | Bibliography | Person | PropertyValue | Tree<Exclude<U, "tree">> | Set<U>;
21
+ type Item<T extends DataCategory = DataCategory, U extends DataCategory = (T extends "tree" ? Exclude<DataCategory, "tree"> : T extends "set" ? DataCategory : never)> = T extends "resource" ? Resource : T extends "spatialUnit" ? SpatialUnit : T extends "concept" ? Concept : T extends "period" ? Period : T extends "bibliography" ? Bibliography : T extends "person" ? Person : T extends "propertyValue" ? PropertyValue : T extends "text" ? Text : T extends "tree" ? Tree<Exclude<U, "tree">> : T extends "set" ? Set<U> : Resource | SpatialUnit | Concept | Period | Bibliography | Person | PropertyValue | Tree<Exclude<U, "tree">> | Set<U>;
22
22
  /**
23
23
  * Basic identification information used across multiple types
24
24
  */
@@ -394,10 +394,7 @@ type Bibliography = {
394
394
  startIssue: string;
395
395
  startVolume: string;
396
396
  } | null;
397
- source: {
398
- resource: Pick<Resource, "uuid" | "publicationDateTime" | "type" | "identification"> | null;
399
- documentUrl: string | null;
400
- };
397
+ sourceResources: Array<Pick<Resource, "uuid" | "category" | "publicationDateTime" | "type" | "identification" | "href">>;
401
398
  periods: Array<Period>;
402
399
  authors: Array<Person>;
403
400
  properties: Array<Property>;
@@ -460,6 +457,45 @@ type Property<T extends PropertyValueContentType = PropertyValueContentType> = {
460
457
  comment: string | null;
461
458
  properties: Array<Property>;
462
459
  };
460
+ /**
461
+ * Represents a resource item with associated metadata, content and relationships
462
+ */
463
+ type Text = {
464
+ uuid: string;
465
+ category: "text";
466
+ metadata: Metadata | null;
467
+ publicationDateTime: Date | null;
468
+ type: string | null;
469
+ language: string | null;
470
+ number: number;
471
+ context: Context | null;
472
+ license: License | null;
473
+ copyright: string | null;
474
+ watermark: string | null;
475
+ identification: Identification;
476
+ creators: Array<Person>;
477
+ editors: Array<Person>;
478
+ notes: Array<Note>;
479
+ description: string;
480
+ periods: Array<Period>;
481
+ links: Array<Link>;
482
+ reverseLinks: Array<Link>;
483
+ properties: Array<Property>;
484
+ bibliographies: Array<Bibliography>;
485
+ sections: Array<Section>;
486
+ };
487
+ /**
488
+ * Represents a section of a text
489
+ */
490
+ type Section = {
491
+ uuid: string;
492
+ variant: "translation" | "phonemic";
493
+ type: string;
494
+ identification: Identification;
495
+ project: {
496
+ identification: Identification;
497
+ };
498
+ };
463
499
  /**
464
500
  * Represents a tree structure containing resources, spatial units and concepts
465
501
  */
@@ -475,7 +511,7 @@ type Tree<U extends Exclude<DataCategory, "tree"> = Exclude<DataCategory, "tree"
475
511
  identification: Identification;
476
512
  creators: Array<Person>;
477
513
  properties: Array<Property>;
478
- items: [Exclude<DataCategory, "tree">] extends [U] ? Array<Item> : U extends "resource" ? Array<Resource> : U extends "spatialUnit" ? Array<SpatialUnit> : U extends "concept" ? Array<Concept> : U extends "period" ? Array<Period> : U extends "bibliography" ? Array<Bibliography> : U extends "person" ? Array<Person> : U extends "propertyValue" ? Array<PropertyValue> : U extends "set" ? Array<Set<DataCategory>> : Array<Item>;
514
+ items: [Exclude<DataCategory, "tree">] extends [U] ? Array<Item> : U extends "resource" ? Array<Resource> : U extends "spatialUnit" ? Array<SpatialUnit> : U extends "concept" ? Array<Concept> : U extends "period" ? Array<Period> : U extends "bibliography" ? Array<Bibliography> : U extends "person" ? Array<Person> : U extends "propertyValue" ? Array<PropertyValue> : U extends "text" ? Array<Text> : U extends "set" ? Array<Set<DataCategory>> : Array<Item>;
479
515
  };
480
516
  /**
481
517
  * Represents a gallery with its identification, project identification, resources and max length
@@ -654,7 +690,6 @@ type WebElementComponent = {
654
690
  fileSize: number | null;
655
691
  isInteractive: boolean;
656
692
  isControlsDisplayed: boolean;
657
- isLightingDisplayed: boolean;
658
693
  } | {
659
694
  component: "advanced-search";
660
695
  boundElementUuid: string | null;
@@ -1238,4 +1273,4 @@ declare function filterProperties(property: Property, filter: {
1238
1273
  value: string | number | boolean | Date;
1239
1274
  }, options?: PropertyOptions): boolean;
1240
1275
  //#endregion
1241
- export { Bibliography, Concept, Context, ContextItem, ContextNode, Coordinate, Data, DataCategory, Event, Gallery, Identification, Image, ImageMap, ImageMapArea, Interpretation, Item, LevelContext, LevelContextItem, License, Link, Metadata, Note, Observation, Period, Person, Property, PropertyContexts, PropertyQueryItem, PropertyValue, PropertyValueContent, PropertyValueContentType, Resource, Set, SpatialUnit, Style, Tree, UuidMetadata, WebBlock, WebBlockLayout, WebElement, WebElementComponent, WebImage, WebTitle, Webpage, Website, fetchByUuidMetadata, fetchGallery, fetchItem, fetchPropertyQuery, fetchWebsite, filterProperties, getPropertyByLabel, getPropertyByUuid, getPropertyValueByLabel, getPropertyValueByUuid, getPropertyValuesByLabel, getPropertyValuesByUuid, getUniqueProperties, getUniquePropertyLabels };
1276
+ export { Bibliography, Concept, Context, ContextItem, ContextNode, Coordinate, Data, DataCategory, Event, Gallery, Identification, Image, ImageMap, ImageMapArea, Interpretation, Item, LevelContext, LevelContextItem, License, Link, Metadata, Note, Observation, Period, Person, Property, PropertyContexts, PropertyQueryItem, PropertyValue, PropertyValueContent, PropertyValueContentType, Resource, Section, Set, SpatialUnit, Style, Text, Tree, UuidMetadata, WebBlock, WebBlockLayout, WebElement, WebElementComponent, WebImage, WebTitle, Webpage, Website, fetchByUuidMetadata, fetchGallery, fetchItem, fetchPropertyQuery, fetchWebsite, filterProperties, getPropertyByLabel, getPropertyByUuid, getPropertyValueByLabel, getPropertyValueByUuid, getPropertyValuesByLabel, getPropertyValuesByUuid, getUniqueProperties, getUniquePropertyLabels };
package/dist/index.mjs CHANGED
@@ -2,10 +2,37 @@ import * as z from "zod";
2
2
 
3
3
  //#region src/schemas.ts
4
4
  /**
5
+ * Validates a pseudo-UUID string
6
+ * @param value - The string to validate
7
+ * @returns True if the string is a valid pseudo-UUID, false otherwise
8
+ * @internal
9
+ */
10
+ function isPseudoUuid(value) {
11
+ return /^[\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12}$/i.test(value);
12
+ }
13
+ /**
5
14
  * Schema for validating UUIDs
6
15
  * @internal
7
16
  */
8
- const uuidSchema = z.uuid({ error: "Invalid UUID provided" });
17
+ const uuidSchema = z.string().refine(isPseudoUuid, { error: "Invalid UUID" });
18
+ /**
19
+ * Schema for validating filters
20
+ * @internal
21
+ */
22
+ const filterSchema = z.string().optional();
23
+ /**
24
+ * Schema for validating data options
25
+ * @internal
26
+ */
27
+ const dataOptionsSchema = z.object({
28
+ filter: z.string().optional().default(""),
29
+ start: z.number().positive({ error: "Start must be positive" }).optional().default(1),
30
+ limit: z.number().positive({ error: "Limit must be positive" }).optional().default(40)
31
+ }).optional().default({
32
+ filter: "",
33
+ start: 1,
34
+ limit: 40
35
+ });
9
36
  /**
10
37
  * Schema for validating website properties
11
38
  * @internal
@@ -72,8 +99,9 @@ const categorySchema = z.enum([
72
99
  "bibliography",
73
100
  "person",
74
101
  "propertyValue",
75
- "set",
76
- "tree"
102
+ "text",
103
+ "tree",
104
+ "set"
77
105
  ]);
78
106
  /**
79
107
  * Schema for validating property value content types
@@ -95,7 +123,7 @@ const propertyValueContentTypeSchema = z.enum([
95
123
  * @internal
96
124
  */
97
125
  const gallerySchema = z.object({
98
- uuid: z.uuid({ error: "Invalid UUID" }),
126
+ uuid: z.string().refine(isPseudoUuid, { error: "Invalid UUID" }),
99
127
  filter: z.string().optional(),
100
128
  page: z.number().positive({ error: "Page must be positive" }),
101
129
  perPage: z.number().positive({ error: "Per page must be positive" })
@@ -1305,13 +1333,18 @@ function parsePeriods(periods) {
1305
1333
  * @returns Parsed Bibliography object
1306
1334
  */
1307
1335
  function parseBibliography(bibliography, metadata) {
1308
- let resource = null;
1309
- if (bibliography.source?.resource) resource = {
1310
- uuid: bibliography.source.resource.uuid,
1311
- publicationDateTime: bibliography.source.resource.publicationDateTime ? new Date(bibliography.source.resource.publicationDateTime) : null,
1312
- type: bibliography.source.resource.type,
1313
- identification: parseIdentification(bibliography.source.resource.identification)
1314
- };
1336
+ const sourceResources = [];
1337
+ if (bibliography.source?.resource) {
1338
+ const resourcesToParse = Array.isArray(bibliography.source.resource) ? bibliography.source.resource : [bibliography.source.resource];
1339
+ for (const resource of resourcesToParse) sourceResources.push({
1340
+ uuid: resource.uuid,
1341
+ category: "resource",
1342
+ publicationDateTime: new Date(resource.publicationDateTime),
1343
+ type: resource.type,
1344
+ identification: parseIdentification(resource.identification),
1345
+ href: resource.href ?? null
1346
+ });
1347
+ }
1315
1348
  let shortCitation = null;
1316
1349
  let longCitation = null;
1317
1350
  if (bibliography.citationFormatSpan) try {
@@ -1349,10 +1382,7 @@ function parseBibliography(bibliography, metadata) {
1349
1382
  startIssue: parseFakeString(bibliography.entryInfo.startIssue),
1350
1383
  startVolume: parseFakeString(bibliography.entryInfo.startVolume)
1351
1384
  } : null,
1352
- source: {
1353
- resource,
1354
- documentUrl: bibliography.sourceDocument ? `https://ochre.lib.uchicago.edu/ochre?uuid=${bibliography.sourceDocument.uuid}&load` : null
1355
- },
1385
+ sourceResources,
1356
1386
  periods: bibliography.periods ? parsePeriods(Array.isArray(bibliography.periods.period) ? bibliography.periods.period : [bibliography.periods.period]) : [],
1357
1387
  authors: bibliography.authors ? parsePersons(Array.isArray(bibliography.authors.person) ? bibliography.authors.person : [bibliography.authors.person]) : [],
1358
1388
  properties: bibliography.properties ? parseProperties(Array.isArray(bibliography.properties.property) ? bibliography.properties.property : [bibliography.properties.property]) : []
@@ -1404,6 +1434,82 @@ function parsePropertyValues(propertyValues) {
1404
1434
  return returnPropertyValues;
1405
1435
  }
1406
1436
  /**
1437
+ * Parses raw text data into a standardized Text object
1438
+ *
1439
+ * @param text - Raw text data in OCHRE format
1440
+ * @returns Parsed Text object
1441
+ */
1442
+ function parseText(text, metadata) {
1443
+ return {
1444
+ uuid: text.uuid,
1445
+ category: "text",
1446
+ metadata: metadata ?? null,
1447
+ publicationDateTime: text.publicationDateTime ? new Date(text.publicationDateTime) : null,
1448
+ type: text.type ?? null,
1449
+ language: text.language ?? null,
1450
+ number: text.n ?? 0,
1451
+ context: text.context ? parseContext(text.context) : null,
1452
+ license: "availability" in text && text.availability ? parseLicense(text.availability) : null,
1453
+ copyright: "copyright" in text && text.copyright != null ? parseStringContent(text.copyright) : null,
1454
+ watermark: "watermark" in text && text.watermark != null ? parseStringContent(text.watermark) : null,
1455
+ identification: parseIdentification(text.identification),
1456
+ creators: text.creators ? parsePersons(Array.isArray(text.creators.creator) ? text.creators.creator : [text.creators.creator]) : [],
1457
+ editors: text.editions ? parsePersons(Array.isArray(text.editions.editor) ? text.editions.editor : [text.editions.editor]) : [],
1458
+ notes: text.notes ? parseNotes(Array.isArray(text.notes.note) ? text.notes.note : [text.notes.note]) : [],
1459
+ description: text.description ? parseStringContent(text.description) : "",
1460
+ periods: text.periods ? parsePeriods(Array.isArray(text.periods.period) ? text.periods.period : [text.periods.period]) : [],
1461
+ links: text.links ? parseLinks(Array.isArray(text.links) ? text.links : [text.links]) : [],
1462
+ reverseLinks: text.reverseLinks ? parseLinks(Array.isArray(text.reverseLinks) ? text.reverseLinks : [text.reverseLinks]) : [],
1463
+ properties: text.properties ? parseProperties(Array.isArray(text.properties.property) ? text.properties.property : [text.properties.property]) : [],
1464
+ bibliographies: text.bibliographies ? parseBibliographies(Array.isArray(text.bibliographies.bibliography) ? text.bibliographies.bibliography : [text.bibliographies.bibliography]) : [],
1465
+ sections: text.sections ? parseSections(text.sections) : []
1466
+ };
1467
+ }
1468
+ /**
1469
+ * Parses an array of raw texts into standardized Text objects
1470
+ *
1471
+ * @param texts - Array of raw texts in OCHRE format
1472
+ * @returns Array of parsed Text objects
1473
+ */
1474
+ function parseTexts(texts) {
1475
+ const returnTexts = [];
1476
+ for (const text of texts) returnTexts.push(parseText(text));
1477
+ return returnTexts;
1478
+ }
1479
+ /**
1480
+ * Parses a raw section data into a standardized Section object
1481
+ *
1482
+ * @param section - Raw section data in OCHRE format
1483
+ * @returns Parsed Section object
1484
+ */
1485
+ function parseSection(section, variant) {
1486
+ return {
1487
+ uuid: section.uuid,
1488
+ variant,
1489
+ type: section.type,
1490
+ identification: parseIdentification(section.identification),
1491
+ project: { identification: parseIdentification(section.project.identification) }
1492
+ };
1493
+ }
1494
+ /**
1495
+ * Parses raw sections data into a standardized Section object
1496
+ *
1497
+ * @param sections - Raw sections data in OCHRE format
1498
+ * @param sections.translation - Translation sections
1499
+ * @param sections.phonemic - Phonemic sections
1500
+ * @param sections.translation.section - Translation sections
1501
+ * @param sections.phonemic.section - Phonemic sections
1502
+ * @returns Parsed Section object
1503
+ */
1504
+ function parseSections(sections) {
1505
+ const returnSections = [];
1506
+ const translationSections = sections.translation ? Array.isArray(sections.translation.section) ? sections.translation.section : [sections.translation.section] : [];
1507
+ const phonemicSections = sections.phonemic ? Array.isArray(sections.phonemic.section) ? sections.phonemic.section : [sections.phonemic.section] : [];
1508
+ for (const section of translationSections) returnSections.push(parseSection(section, "translation"));
1509
+ for (const section of phonemicSections) returnSections.push(parseSection(section, "phonemic"));
1510
+ return returnSections;
1511
+ }
1512
+ /**
1407
1513
  * Parses a raw tree structure into a standardized Tree object
1408
1514
  *
1409
1515
  * @param tree - Raw tree data in OCHRE format
@@ -1446,6 +1552,10 @@ function parseTree(tree, itemCategory, metadata) {
1446
1552
  if (!("propertyValue" in tree.items)) throw new Error("Invalid OCHRE data: Tree has no property values");
1447
1553
  items = parsePropertyValues(Array.isArray(tree.items.propertyValue) ? tree.items.propertyValue : [tree.items.propertyValue]);
1448
1554
  break;
1555
+ case "text":
1556
+ if (!("text" in tree.items)) throw new Error("Invalid OCHRE data: Tree has no texts");
1557
+ items = parseTexts(Array.isArray(tree.items.text) ? tree.items.text : [tree.items.text]);
1558
+ break;
1449
1559
  case "set": {
1450
1560
  if (!("set" in tree.items)) throw new Error("Invalid OCHRE data: Tree has no sets");
1451
1561
  const setItems = [];
@@ -1509,6 +1619,10 @@ function parseSet(set, itemCategory, metadata) {
1509
1619
  if (!("propertyValue" in set.items)) throw new Error("Invalid OCHRE data: Set has no property values");
1510
1620
  items = parsePropertyValues(Array.isArray(set.items.propertyValue) ? set.items.propertyValue : [set.items.propertyValue]);
1511
1621
  break;
1622
+ case "text":
1623
+ if (!("text" in set.items)) throw new Error("Invalid OCHRE data: Set has no texts");
1624
+ items = parseTexts(Array.isArray(set.items.text) ? set.items.text : [set.items.text]);
1625
+ break;
1512
1626
  default: throw new Error("Invalid OCHRE data: Set has no items or is malformed");
1513
1627
  }
1514
1628
  return {
@@ -1716,14 +1830,10 @@ function parseWebElementProperties(componentProperty, elementResource) {
1716
1830
  let isControlsDisplayed = true;
1717
1831
  const isControlsDisplayedProperty = getPropertyValueByLabel(componentProperty.properties, "controls-displayed");
1718
1832
  if (isControlsDisplayedProperty !== null) isControlsDisplayed = isControlsDisplayedProperty === true;
1719
- let isLightingDisplayed = true;
1720
- const isLightingDisplayedProperty = getPropertyValueByLabel(componentProperty.properties, "lighting-displayed");
1721
- if (isLightingDisplayedProperty !== null) isLightingDisplayed = isLightingDisplayedProperty === true;
1722
1833
  properties.resourceId = resourceLink.uuid;
1723
1834
  properties.fileSize = resourceLink.fileSize;
1724
1835
  properties.isInteractive = isInteractive;
1725
1836
  properties.isControlsDisplayed = isControlsDisplayed;
1726
- properties.isLightingDisplayed = isLightingDisplayed;
1727
1837
  break;
1728
1838
  }
1729
1839
  case "advanced-search": {
@@ -2984,6 +3094,10 @@ async function fetchItem(uuid, category, itemCategory, options) {
2984
3094
  if (!("propertyValue" in data.ochre)) throw new Error("Invalid OCHRE data: API response missing 'propertyValue' key");
2985
3095
  item = parsePropertyValue(data.ochre.propertyValue, metadata);
2986
3096
  break;
3097
+ case "text":
3098
+ if (!("text" in data.ochre)) throw new Error("Invalid OCHRE data: API response missing 'text' key");
3099
+ item = parseText(data.ochre.text, metadata);
3100
+ break;
2987
3101
  case "set":
2988
3102
  if (!("set" in data.ochre)) throw new Error("Invalid OCHRE data: API response missing 'set' key");
2989
3103
  item = parseSet(data.ochre.set, itemCategory, metadata);
@@ -3199,7 +3313,6 @@ const KNOWN_ABBREVIATIONS = {
3199
3313
  ssmc: "8ff977dd-d440-40f5-ad93-8ad7e2d39e74",
3200
3314
  "sosc-core-at-smart": "db26c953-9b2a-4691-a909-5e8726b531d7"
3201
3315
  };
3202
- const V2_ABBREVIATIONS = /* @__PURE__ */ new Set();
3203
3316
  /**
3204
3317
  * Fetches and parses a website configuration from the OCHRE API
3205
3318
  *
@@ -3233,7 +3346,7 @@ async function fetchWebsite(abbreviation, options) {
3233
3346
  try {
3234
3347
  const cleanAbbreviation = abbreviation.trim().toLocaleLowerCase("en-US");
3235
3348
  const customFetch = options?.customFetch;
3236
- const isVersion2 = V2_ABBREVIATIONS.has(cleanAbbreviation) ? true : options?.isVersion2 ?? false;
3349
+ const isVersion2 = cleanAbbreviation.endsWith("-v2") ? true : options?.isVersion2 ?? false;
3237
3350
  let metadata = null;
3238
3351
  let tree = null;
3239
3352
  if (isVersion2) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitalculture/ochre-sdk",
3
- "version": "0.13.9",
3
+ "version": "0.14.0",
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",