@digitalculture/ochre-sdk 0.1.21 → 0.1.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
@@ -1,15 +1,45 @@
1
1
  # OCHRE SDK
2
2
 
3
- A JavaScript/TypeScript SDK for working with OCHRE (Online Cultural and Historical Research Environment) data.
3
+ This is the OCHRE JavaScript/TypeScript SDK for interacting with OCHRE (Online Cultural and Historical Research Environment) data.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- pnpm add @uchicago/ochre
8
+ pnpm add @digital-culture/ochre-sdk
9
+ ```
10
+
9
11
  or
10
- npm install @uchicago/ochre
12
+
13
+ ```bash
14
+ npm install @digital-culture/ochre-sdk
15
+ ```
16
+
11
17
  or
12
- bun install @uchicago/ochre
18
+
19
+ ```bash
20
+ bun add @digital-culture/ochre-sdk
21
+ ```
22
+
23
+ ## Start development server
24
+
25
+ From the root directory of the project, run the following command:
26
+
27
+ ```bash
28
+ pnpm run dev:ochre-sdk
29
+ ```
30
+
31
+ ## Build production server
32
+
33
+ From the root directory of the project, run the following command:
34
+
35
+ ```bash
36
+ pnpm run ci
37
+ ```
38
+
39
+ ## Release new version to NPM
40
+
41
+ ```bash
42
+ pnpm run release
13
43
  ```
14
44
 
15
45
  ## Features
package/dist/index.cjs CHANGED
@@ -22,6 +22,7 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  fetchByUuid: () => fetchByUuid,
24
24
  fetchConcept: () => fetchConcept,
25
+ fetchGallery: () => fetchGallery,
25
26
  fetchResource: () => fetchResource,
26
27
  fetchSet: () => fetchSet,
27
28
  fetchSpatialUnit: () => fetchSpatialUnit,
@@ -593,7 +594,8 @@ var componentSchema = import_zod3.z.enum(
593
594
  "network-graph",
594
595
  "table",
595
596
  "text",
596
- "text-image"
597
+ "text-image",
598
+ "timeline"
597
599
  ],
598
600
  { message: "Invalid component" }
599
601
  );
@@ -1026,6 +1028,7 @@ function parseTree(tree) {
1026
1028
  let spatialUnits = [];
1027
1029
  let concepts = [];
1028
1030
  let periods = [];
1031
+ let bibliographies = [];
1029
1032
  if (typeof tree.items !== "string" && "resource" in tree.items) {
1030
1033
  resources = parseResources(
1031
1034
  Array.isArray(tree.items.resource) ? tree.items.resource : [tree.items.resource]
@@ -1046,6 +1049,11 @@ function parseTree(tree) {
1046
1049
  Array.isArray(tree.items.period) ? tree.items.period : [tree.items.period]
1047
1050
  );
1048
1051
  }
1052
+ if (typeof tree.items !== "string" && "bibliography" in tree.items) {
1053
+ bibliographies = parseBibliographies(
1054
+ Array.isArray(tree.items.bibliography) ? tree.items.bibliography : [tree.items.bibliography]
1055
+ );
1056
+ }
1049
1057
  const returnTree = {
1050
1058
  uuid: tree.uuid,
1051
1059
  category: "tree",
@@ -1060,7 +1068,8 @@ function parseTree(tree) {
1060
1068
  resources,
1061
1069
  spatialUnits,
1062
1070
  concepts,
1063
- periods
1071
+ periods,
1072
+ bibliographies
1064
1073
  },
1065
1074
  properties: tree.properties ? parseProperties(
1066
1075
  Array.isArray(tree.properties.property) ? tree.properties.property : [tree.properties.property]
@@ -1073,6 +1082,7 @@ function parseSet(set) {
1073
1082
  let spatialUnits = [];
1074
1083
  let concepts = [];
1075
1084
  let periods = [];
1085
+ let bibliographies = [];
1076
1086
  if (typeof set.items !== "string" && "resource" in set.items) {
1077
1087
  resources = parseResources(
1078
1088
  Array.isArray(set.items.resource) ? set.items.resource : [set.items.resource],
@@ -1096,6 +1106,11 @@ function parseSet(set) {
1096
1106
  Array.isArray(set.items.period) ? set.items.period : [set.items.period]
1097
1107
  );
1098
1108
  }
1109
+ if (typeof set.items !== "string" && "bibliography" in set.items) {
1110
+ bibliographies = parseBibliographies(
1111
+ Array.isArray(set.items.bibliography) ? set.items.bibliography : [set.items.bibliography]
1112
+ );
1113
+ }
1099
1114
  return {
1100
1115
  uuid: set.uuid,
1101
1116
  category: "set",
@@ -1114,7 +1129,8 @@ function parseSet(set) {
1114
1129
  resources,
1115
1130
  spatialUnits,
1116
1131
  concepts,
1117
- periods
1132
+ periods,
1133
+ bibliographies
1118
1134
  }
1119
1135
  };
1120
1136
  }
@@ -1578,6 +1594,16 @@ async function parseWebElementProperties(componentProperty, elementResource) {
1578
1594
  properties.imageOpacity = null;
1579
1595
  break;
1580
1596
  }
1597
+ case "timeline": {
1598
+ const timelineLink = links.find((link) => link.category === "tree");
1599
+ if (!timelineLink) {
1600
+ throw new Error(
1601
+ `Timeline link not found for the following component: \u201C${componentName}\u201D`
1602
+ );
1603
+ }
1604
+ properties.timelineId = timelineLink.uuid;
1605
+ break;
1606
+ }
1581
1607
  default: {
1582
1608
  console.warn(
1583
1609
  `Invalid or non-implemented component name \u201C${componentName}\u201D for the following element: \u201C${parseStringContent(
@@ -1876,6 +1902,56 @@ async function fetchConcept(uuid) {
1876
1902
  }
1877
1903
  }
1878
1904
 
1905
+ // src/utils/fetchers/gallery.ts
1906
+ var import_zod4 = require("zod");
1907
+ var gallerySchema = import_zod4.z.object({
1908
+ uuid: import_zod4.z.string().uuid({ message: "Invalid UUID" }),
1909
+ filter: import_zod4.z.string().optional(),
1910
+ page: import_zod4.z.number().positive({ message: "Page must be positive" }),
1911
+ perPage: import_zod4.z.number().positive({ message: "Per page must be positive" })
1912
+ }).strict();
1913
+ async function fetchGallery(uuid, filter, page, perPage) {
1914
+ try {
1915
+ const parsed = gallerySchema.safeParse({ uuid, filter, page, perPage });
1916
+ if (!parsed.success) {
1917
+ throw new Error(parsed.error.message);
1918
+ }
1919
+ const response = await fetch(
1920
+ `https://ochre.lib.uchicago.edu/ochre?xquery=${encodeURIComponent(`
1921
+ for $q in input()/ochre[@uuid='${uuid}']
1922
+ let $filtered := $q/tree/items/resource[contains(lower-case(identification/label), lower-case('${filter}'))]
1923
+ let $maxLength := count($filtered)
1924
+ return <gallery maxLength='{$maxLength}'>
1925
+ {$q/metadata/project}
1926
+ {$q/metadata/item}
1927
+ {$filtered[position() >= ${((page - 1) * perPage + 1).toString()} and position() < ${(page * perPage + 1).toString()}]}
1928
+ </gallery>
1929
+ `)}&format=json`
1930
+ );
1931
+ if (!response.ok) {
1932
+ throw new Error("Error fetching gallery items, please try again later.");
1933
+ }
1934
+ const data = await response.json();
1935
+ if (!("gallery" in data.result)) {
1936
+ throw new Error("Failed to fetch gallery");
1937
+ }
1938
+ const galleryIdentification = parseIdentification(data.result.gallery.item);
1939
+ const galleryProjectIdentification = parseIdentification(
1940
+ data.result.gallery.project.identification
1941
+ );
1942
+ const gallery = {
1943
+ identification: galleryIdentification,
1944
+ projectIdentification: galleryProjectIdentification,
1945
+ resources: Array.isArray(data.result.gallery.resource) ? parseResources(data.result.gallery.resource) : [parseResource(data.result.gallery.resource)],
1946
+ maxLength: data.result.gallery.maxLength
1947
+ };
1948
+ return gallery;
1949
+ } catch (error) {
1950
+ console.error(error);
1951
+ return null;
1952
+ }
1953
+ }
1954
+
1879
1955
  // src/utils/fetchers/set.ts
1880
1956
  async function fetchSet(uuid) {
1881
1957
  try {
@@ -1994,6 +2070,7 @@ async function fetchWebsite(abbreviation) {
1994
2070
  0 && (module.exports = {
1995
2071
  fetchByUuid,
1996
2072
  fetchConcept,
2073
+ fetchGallery,
1997
2074
  fetchResource,
1998
2075
  fetchSet,
1999
2076
  fetchSpatialUnit,
package/dist/index.d.cts CHANGED
@@ -287,6 +287,7 @@ type Set = {
287
287
  spatialUnits: Array<NestedSpatialUnit>;
288
288
  concepts: Array<NestedConcept>;
289
289
  periods: Array<Period>;
290
+ bibliographies: Array<Bibliography>;
290
291
  };
291
292
  };
292
293
  /**
@@ -372,9 +373,19 @@ type Tree = {
372
373
  spatialUnits: Array<SpatialUnit>;
373
374
  concepts: Array<Concept>;
374
375
  periods: Array<Period>;
376
+ bibliographies: Array<Bibliography>;
375
377
  };
376
378
  properties: Array<Property>;
377
379
  };
380
+ /**
381
+ * Represents a gallery with its identification, project identification, resources and max length
382
+ */
383
+ type Gallery = {
384
+ identification: Identification;
385
+ projectIdentification: Identification;
386
+ resources: Array<Resource>;
387
+ maxLength: number;
388
+ };
378
389
  /**
379
390
  * Represents a website with its properties and elements
380
391
  */
@@ -498,6 +509,9 @@ type WebElementComponent = {
498
509
  image: WebImage;
499
510
  imageOpacity: number | null;
500
511
  content: string;
512
+ } | {
513
+ component: "timeline";
514
+ timelineId: string;
501
515
  };
502
516
  /**
503
517
  * Represents an image used in web elements
@@ -545,6 +559,34 @@ declare function fetchConcept(uuid: string): Promise<{
545
559
  concept: Concept;
546
560
  } | null>;
547
561
 
562
+ /**
563
+ * Fetches and parses a gallery from the OCHRE API
564
+ *
565
+ * @param uuid - The UUID of the gallery
566
+ * @param filter - The filter to apply to the gallery
567
+ * @param page - The page number to fetch
568
+ * @param perPage - The number of items per page
569
+ * @returns The parsed gallery or null if the fetch/parse fails
570
+ *
571
+ * @example
572
+ * ```ts
573
+ * const gallery = await fetchGallery("9c4da06b-f15e-40af-a747-0933eaf3587e", "1978", 1, 12);
574
+ * if (gallery === null) {
575
+ * console.error("Failed to fetch gallery");
576
+ * return;
577
+ * }
578
+ * console.log(`Fetched gallery: ${gallery.identification.label}`);
579
+ * console.log(`Contains ${gallery.resources.length.toLocaleString()} resources`);
580
+ * ```
581
+ *
582
+ * @remarks
583
+ * The returned gallery includes:
584
+ * - Gallery metadata and identification
585
+ * - Project identification
586
+ * - Resources (gallery items)
587
+ */
588
+ declare function fetchGallery(uuid: string, filter: string, page: number, perPage: number): Promise<Gallery | null>;
589
+
548
590
  /**
549
591
  * Raw string value that can be a string, number, or boolean
550
592
  */
@@ -681,7 +723,8 @@ type OchreTree = {
681
723
  }
682
724
  | { spatialUnit: OchreSpatialUnit | Array<OchreSpatialUnit> }
683
725
  | { concept: OchreConcept | Array<OchreConcept> }
684
- | { period: OchrePeriod | Array<OchrePeriod> };
726
+ | { period: OchrePeriod | Array<OchrePeriod> }
727
+ | { bibliography: OchreBibliography | Array<OchreBibliography> };
685
728
  properties?: { property: OchreProperty | Array<OchreProperty> };
686
729
  };
687
730
 
@@ -704,7 +747,8 @@ type OchreSet = {
704
747
  | { resource: OchreResource | Array<OchreResource> }
705
748
  | { spatialUnit: OchreSpatialUnit | Array<OchreSpatialUnit> }
706
749
  | { concept: OchreConcept | Array<OchreConcept> }
707
- | { period: OchrePeriod | Array<OchrePeriod> };
750
+ | { period: OchrePeriod | Array<OchrePeriod> }
751
+ | { bibliography: OchreBibliography | Array<OchreBibliography> };
708
752
  };
709
753
 
710
754
  /**
@@ -1651,4 +1695,4 @@ declare function trimEndLineBreaks(string: string): string;
1651
1695
  */
1652
1696
  declare function parseStringContent(content: OchreStringContent, language?: string): string;
1653
1697
 
1654
- export { type Bibliography, type Concept, type Context, type ContextItem, type ContextNode, type Coordinates, type Data, type Document, type Event, type Footnote, type Identification, type Image, type ImageMap, type ImageMapArea, type Interpretation, type License, type Link, type Metadata, type NestedConcept, type NestedResource, type NestedSpatialUnit, type Note, type Observation, type Period, type Person, type Property, type PropertyValue, type PropertyValueType, type Resource, type Set, type SpatialUnit, type Style, type Tree, type WebElement, type WebElementComponent, type WebImage, type Webpage, type WebpageProperties, type Website, type WebsiteProperties, fetchByUuid, fetchConcept, fetchResource, fetchSet, fetchSpatialUnit, fetchTree, fetchWebsite, filterProperties, getAllPropertyLabels, getPropertyByLabel, getPropertyValueByLabel, getPropertyValuesByLabel, parseBibliographies, parseBibliography, parseConcept, parseConcepts, parseContext, parseCoordinates, parseDocument, parseEmailAndUrl, parseEvents, parseFakeString, parseIdentification, parseImage, parseImageMap, parseInterpretations, parseLanguages, parseLicense, parseLink, parseLinks, parseMetadata, parseNotes, parseObservation, parseObservations, parsePeriod, parsePeriods, parsePersons, parseProperties, parseResource, parseResources, parseSet, parseSpatialUnit, parseSpatialUnits, parseStringContent, parseStringDocumentItem, parseStringItem, parseTree, parseWebsite, trimEndLineBreaks };
1698
+ export { type Bibliography, type Concept, type Context, type ContextItem, type ContextNode, type Coordinates, type Data, type Document, type Event, type Footnote, type Gallery, type Identification, type Image, type ImageMap, type ImageMapArea, type Interpretation, type License, type Link, type Metadata, type NestedConcept, type NestedResource, type NestedSpatialUnit, type Note, type Observation, type Period, type Person, type Property, type PropertyValue, type PropertyValueType, type Resource, type Set, type SpatialUnit, type Style, type Tree, type WebElement, type WebElementComponent, type WebImage, type Webpage, type WebpageProperties, type Website, type WebsiteProperties, fetchByUuid, fetchConcept, fetchGallery, fetchResource, fetchSet, fetchSpatialUnit, fetchTree, fetchWebsite, filterProperties, getAllPropertyLabels, getPropertyByLabel, getPropertyValueByLabel, getPropertyValuesByLabel, parseBibliographies, parseBibliography, parseConcept, parseConcepts, parseContext, parseCoordinates, parseDocument, parseEmailAndUrl, parseEvents, parseFakeString, parseIdentification, parseImage, parseImageMap, parseInterpretations, parseLanguages, parseLicense, parseLink, parseLinks, parseMetadata, parseNotes, parseObservation, parseObservations, parsePeriod, parsePeriods, parsePersons, parseProperties, parseResource, parseResources, parseSet, parseSpatialUnit, parseSpatialUnits, parseStringContent, parseStringDocumentItem, parseStringItem, parseTree, parseWebsite, trimEndLineBreaks };
package/dist/index.d.ts CHANGED
@@ -287,6 +287,7 @@ type Set = {
287
287
  spatialUnits: Array<NestedSpatialUnit>;
288
288
  concepts: Array<NestedConcept>;
289
289
  periods: Array<Period>;
290
+ bibliographies: Array<Bibliography>;
290
291
  };
291
292
  };
292
293
  /**
@@ -372,9 +373,19 @@ type Tree = {
372
373
  spatialUnits: Array<SpatialUnit>;
373
374
  concepts: Array<Concept>;
374
375
  periods: Array<Period>;
376
+ bibliographies: Array<Bibliography>;
375
377
  };
376
378
  properties: Array<Property>;
377
379
  };
380
+ /**
381
+ * Represents a gallery with its identification, project identification, resources and max length
382
+ */
383
+ type Gallery = {
384
+ identification: Identification;
385
+ projectIdentification: Identification;
386
+ resources: Array<Resource>;
387
+ maxLength: number;
388
+ };
378
389
  /**
379
390
  * Represents a website with its properties and elements
380
391
  */
@@ -498,6 +509,9 @@ type WebElementComponent = {
498
509
  image: WebImage;
499
510
  imageOpacity: number | null;
500
511
  content: string;
512
+ } | {
513
+ component: "timeline";
514
+ timelineId: string;
501
515
  };
502
516
  /**
503
517
  * Represents an image used in web elements
@@ -545,6 +559,34 @@ declare function fetchConcept(uuid: string): Promise<{
545
559
  concept: Concept;
546
560
  } | null>;
547
561
 
562
+ /**
563
+ * Fetches and parses a gallery from the OCHRE API
564
+ *
565
+ * @param uuid - The UUID of the gallery
566
+ * @param filter - The filter to apply to the gallery
567
+ * @param page - The page number to fetch
568
+ * @param perPage - The number of items per page
569
+ * @returns The parsed gallery or null if the fetch/parse fails
570
+ *
571
+ * @example
572
+ * ```ts
573
+ * const gallery = await fetchGallery("9c4da06b-f15e-40af-a747-0933eaf3587e", "1978", 1, 12);
574
+ * if (gallery === null) {
575
+ * console.error("Failed to fetch gallery");
576
+ * return;
577
+ * }
578
+ * console.log(`Fetched gallery: ${gallery.identification.label}`);
579
+ * console.log(`Contains ${gallery.resources.length.toLocaleString()} resources`);
580
+ * ```
581
+ *
582
+ * @remarks
583
+ * The returned gallery includes:
584
+ * - Gallery metadata and identification
585
+ * - Project identification
586
+ * - Resources (gallery items)
587
+ */
588
+ declare function fetchGallery(uuid: string, filter: string, page: number, perPage: number): Promise<Gallery | null>;
589
+
548
590
  /**
549
591
  * Raw string value that can be a string, number, or boolean
550
592
  */
@@ -681,7 +723,8 @@ type OchreTree = {
681
723
  }
682
724
  | { spatialUnit: OchreSpatialUnit | Array<OchreSpatialUnit> }
683
725
  | { concept: OchreConcept | Array<OchreConcept> }
684
- | { period: OchrePeriod | Array<OchrePeriod> };
726
+ | { period: OchrePeriod | Array<OchrePeriod> }
727
+ | { bibliography: OchreBibliography | Array<OchreBibliography> };
685
728
  properties?: { property: OchreProperty | Array<OchreProperty> };
686
729
  };
687
730
 
@@ -704,7 +747,8 @@ type OchreSet = {
704
747
  | { resource: OchreResource | Array<OchreResource> }
705
748
  | { spatialUnit: OchreSpatialUnit | Array<OchreSpatialUnit> }
706
749
  | { concept: OchreConcept | Array<OchreConcept> }
707
- | { period: OchrePeriod | Array<OchrePeriod> };
750
+ | { period: OchrePeriod | Array<OchrePeriod> }
751
+ | { bibliography: OchreBibliography | Array<OchreBibliography> };
708
752
  };
709
753
 
710
754
  /**
@@ -1651,4 +1695,4 @@ declare function trimEndLineBreaks(string: string): string;
1651
1695
  */
1652
1696
  declare function parseStringContent(content: OchreStringContent, language?: string): string;
1653
1697
 
1654
- export { type Bibliography, type Concept, type Context, type ContextItem, type ContextNode, type Coordinates, type Data, type Document, type Event, type Footnote, type Identification, type Image, type ImageMap, type ImageMapArea, type Interpretation, type License, type Link, type Metadata, type NestedConcept, type NestedResource, type NestedSpatialUnit, type Note, type Observation, type Period, type Person, type Property, type PropertyValue, type PropertyValueType, type Resource, type Set, type SpatialUnit, type Style, type Tree, type WebElement, type WebElementComponent, type WebImage, type Webpage, type WebpageProperties, type Website, type WebsiteProperties, fetchByUuid, fetchConcept, fetchResource, fetchSet, fetchSpatialUnit, fetchTree, fetchWebsite, filterProperties, getAllPropertyLabels, getPropertyByLabel, getPropertyValueByLabel, getPropertyValuesByLabel, parseBibliographies, parseBibliography, parseConcept, parseConcepts, parseContext, parseCoordinates, parseDocument, parseEmailAndUrl, parseEvents, parseFakeString, parseIdentification, parseImage, parseImageMap, parseInterpretations, parseLanguages, parseLicense, parseLink, parseLinks, parseMetadata, parseNotes, parseObservation, parseObservations, parsePeriod, parsePeriods, parsePersons, parseProperties, parseResource, parseResources, parseSet, parseSpatialUnit, parseSpatialUnits, parseStringContent, parseStringDocumentItem, parseStringItem, parseTree, parseWebsite, trimEndLineBreaks };
1698
+ export { type Bibliography, type Concept, type Context, type ContextItem, type ContextNode, type Coordinates, type Data, type Document, type Event, type Footnote, type Gallery, type Identification, type Image, type ImageMap, type ImageMapArea, type Interpretation, type License, type Link, type Metadata, type NestedConcept, type NestedResource, type NestedSpatialUnit, type Note, type Observation, type Period, type Person, type Property, type PropertyValue, type PropertyValueType, type Resource, type Set, type SpatialUnit, type Style, type Tree, type WebElement, type WebElementComponent, type WebImage, type Webpage, type WebpageProperties, type Website, type WebsiteProperties, fetchByUuid, fetchConcept, fetchGallery, fetchResource, fetchSet, fetchSpatialUnit, fetchTree, fetchWebsite, filterProperties, getAllPropertyLabels, getPropertyByLabel, getPropertyValueByLabel, getPropertyValuesByLabel, parseBibliographies, parseBibliography, parseConcept, parseConcepts, parseContext, parseCoordinates, parseDocument, parseEmailAndUrl, parseEvents, parseFakeString, parseIdentification, parseImage, parseImageMap, parseInterpretations, parseLanguages, parseLicense, parseLink, parseLinks, parseMetadata, parseNotes, parseObservation, parseObservations, parsePeriod, parsePeriods, parsePersons, parseProperties, parseResource, parseResources, parseSet, parseSpatialUnit, parseSpatialUnits, parseStringContent, parseStringDocumentItem, parseStringItem, parseTree, parseWebsite, trimEndLineBreaks };
package/dist/index.js CHANGED
@@ -519,7 +519,8 @@ var componentSchema = z3.enum(
519
519
  "network-graph",
520
520
  "table",
521
521
  "text",
522
- "text-image"
522
+ "text-image",
523
+ "timeline"
523
524
  ],
524
525
  { message: "Invalid component" }
525
526
  );
@@ -952,6 +953,7 @@ function parseTree(tree) {
952
953
  let spatialUnits = [];
953
954
  let concepts = [];
954
955
  let periods = [];
956
+ let bibliographies = [];
955
957
  if (typeof tree.items !== "string" && "resource" in tree.items) {
956
958
  resources = parseResources(
957
959
  Array.isArray(tree.items.resource) ? tree.items.resource : [tree.items.resource]
@@ -972,6 +974,11 @@ function parseTree(tree) {
972
974
  Array.isArray(tree.items.period) ? tree.items.period : [tree.items.period]
973
975
  );
974
976
  }
977
+ if (typeof tree.items !== "string" && "bibliography" in tree.items) {
978
+ bibliographies = parseBibliographies(
979
+ Array.isArray(tree.items.bibliography) ? tree.items.bibliography : [tree.items.bibliography]
980
+ );
981
+ }
975
982
  const returnTree = {
976
983
  uuid: tree.uuid,
977
984
  category: "tree",
@@ -986,7 +993,8 @@ function parseTree(tree) {
986
993
  resources,
987
994
  spatialUnits,
988
995
  concepts,
989
- periods
996
+ periods,
997
+ bibliographies
990
998
  },
991
999
  properties: tree.properties ? parseProperties(
992
1000
  Array.isArray(tree.properties.property) ? tree.properties.property : [tree.properties.property]
@@ -999,6 +1007,7 @@ function parseSet(set) {
999
1007
  let spatialUnits = [];
1000
1008
  let concepts = [];
1001
1009
  let periods = [];
1010
+ let bibliographies = [];
1002
1011
  if (typeof set.items !== "string" && "resource" in set.items) {
1003
1012
  resources = parseResources(
1004
1013
  Array.isArray(set.items.resource) ? set.items.resource : [set.items.resource],
@@ -1022,6 +1031,11 @@ function parseSet(set) {
1022
1031
  Array.isArray(set.items.period) ? set.items.period : [set.items.period]
1023
1032
  );
1024
1033
  }
1034
+ if (typeof set.items !== "string" && "bibliography" in set.items) {
1035
+ bibliographies = parseBibliographies(
1036
+ Array.isArray(set.items.bibliography) ? set.items.bibliography : [set.items.bibliography]
1037
+ );
1038
+ }
1025
1039
  return {
1026
1040
  uuid: set.uuid,
1027
1041
  category: "set",
@@ -1040,7 +1054,8 @@ function parseSet(set) {
1040
1054
  resources,
1041
1055
  spatialUnits,
1042
1056
  concepts,
1043
- periods
1057
+ periods,
1058
+ bibliographies
1044
1059
  }
1045
1060
  };
1046
1061
  }
@@ -1504,6 +1519,16 @@ async function parseWebElementProperties(componentProperty, elementResource) {
1504
1519
  properties.imageOpacity = null;
1505
1520
  break;
1506
1521
  }
1522
+ case "timeline": {
1523
+ const timelineLink = links.find((link) => link.category === "tree");
1524
+ if (!timelineLink) {
1525
+ throw new Error(
1526
+ `Timeline link not found for the following component: \u201C${componentName}\u201D`
1527
+ );
1528
+ }
1529
+ properties.timelineId = timelineLink.uuid;
1530
+ break;
1531
+ }
1507
1532
  default: {
1508
1533
  console.warn(
1509
1534
  `Invalid or non-implemented component name \u201C${componentName}\u201D for the following element: \u201C${parseStringContent(
@@ -1802,6 +1827,56 @@ async function fetchConcept(uuid) {
1802
1827
  }
1803
1828
  }
1804
1829
 
1830
+ // src/utils/fetchers/gallery.ts
1831
+ import { z as z4 } from "zod";
1832
+ var gallerySchema = z4.object({
1833
+ uuid: z4.string().uuid({ message: "Invalid UUID" }),
1834
+ filter: z4.string().optional(),
1835
+ page: z4.number().positive({ message: "Page must be positive" }),
1836
+ perPage: z4.number().positive({ message: "Per page must be positive" })
1837
+ }).strict();
1838
+ async function fetchGallery(uuid, filter, page, perPage) {
1839
+ try {
1840
+ const parsed = gallerySchema.safeParse({ uuid, filter, page, perPage });
1841
+ if (!parsed.success) {
1842
+ throw new Error(parsed.error.message);
1843
+ }
1844
+ const response = await fetch(
1845
+ `https://ochre.lib.uchicago.edu/ochre?xquery=${encodeURIComponent(`
1846
+ for $q in input()/ochre[@uuid='${uuid}']
1847
+ let $filtered := $q/tree/items/resource[contains(lower-case(identification/label), lower-case('${filter}'))]
1848
+ let $maxLength := count($filtered)
1849
+ return <gallery maxLength='{$maxLength}'>
1850
+ {$q/metadata/project}
1851
+ {$q/metadata/item}
1852
+ {$filtered[position() >= ${((page - 1) * perPage + 1).toString()} and position() < ${(page * perPage + 1).toString()}]}
1853
+ </gallery>
1854
+ `)}&format=json`
1855
+ );
1856
+ if (!response.ok) {
1857
+ throw new Error("Error fetching gallery items, please try again later.");
1858
+ }
1859
+ const data = await response.json();
1860
+ if (!("gallery" in data.result)) {
1861
+ throw new Error("Failed to fetch gallery");
1862
+ }
1863
+ const galleryIdentification = parseIdentification(data.result.gallery.item);
1864
+ const galleryProjectIdentification = parseIdentification(
1865
+ data.result.gallery.project.identification
1866
+ );
1867
+ const gallery = {
1868
+ identification: galleryIdentification,
1869
+ projectIdentification: galleryProjectIdentification,
1870
+ resources: Array.isArray(data.result.gallery.resource) ? parseResources(data.result.gallery.resource) : [parseResource(data.result.gallery.resource)],
1871
+ maxLength: data.result.gallery.maxLength
1872
+ };
1873
+ return gallery;
1874
+ } catch (error) {
1875
+ console.error(error);
1876
+ return null;
1877
+ }
1878
+ }
1879
+
1805
1880
  // src/utils/fetchers/set.ts
1806
1881
  async function fetchSet(uuid) {
1807
1882
  try {
@@ -1919,6 +1994,7 @@ async function fetchWebsite(abbreviation) {
1919
1994
  export {
1920
1995
  fetchByUuid,
1921
1996
  fetchConcept,
1997
+ fetchGallery,
1922
1998
  fetchResource,
1923
1999
  fetchSet,
1924
2000
  fetchSpatialUnit,
package/package.json CHANGED
@@ -1,10 +1,18 @@
1
1
  {
2
2
  "name": "@digitalculture/ochre-sdk",
3
- "version": "0.1.21",
3
+ "version": "0.1.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",
7
7
  "author": "Firat Ciftci <firatciftci@uchicago.edu> (https://digitalculture.uchicago.edu)",
8
+ "homepage": "https://github.com/forumfordigitalculture/ochre-sdk",
9
+ "bugs": {
10
+ "url": "https://github.com/forumfordigitalculture/ochre-sdk/issues"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/forumfordigitalculture/ochre-sdk.git"
15
+ },
8
16
  "keywords": [
9
17
  "ochre",
10
18
  "uchicago",
@@ -39,6 +47,7 @@
39
47
  "@antfu/eslint-config": "^4.1.0",
40
48
  "@arethetypeswrong/cli": "^0.17.3",
41
49
  "@changesets/cli": "^2.27.12",
50
+ "@total-typescript/ts-reset": "^0.6.1",
42
51
  "@types/node": "^22.10.10",
43
52
  "eslint-plugin-unused-imports": "^4.1.4",
44
53
  "prettier": "^3.4.2",
@@ -48,7 +57,7 @@
48
57
  },
49
58
  "scripts": {
50
59
  "dev": "tsup src/index.ts --watch",
51
- "build": "tsup",
60
+ "build:ochre-sdk": "tsup",
52
61
  "lint": "eslint .",
53
62
  "lint:fix": "eslint . --fix",
54
63
  "format": "prettier --check .",
@@ -56,7 +65,7 @@
56
65
  "check-types": "tsc --noEmit",
57
66
  "check-exports": "attw --pack .",
58
67
  "test": "vitest run",
59
- "ci": "pnpm run build && pnpm run lint && pnpm run format && pnpm run check-types && pnpm run check-exports && pnpm run test",
68
+ "ci": "pnpm run build:ochre-sdk && pnpm run lint && pnpm run format && pnpm run check-types && pnpm run check-exports && pnpm run test",
60
69
  "changeset": "changeset add",
61
70
  "release": "changeset version && changeset publish"
62
71
  }