@digitalculture/ochre-sdk 0.5.19 → 0.6.1
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.cjs +469 -666
- package/dist/index.d.cts +58 -357
- package/dist/index.d.ts +58 -357
- package/dist/index.js +468 -656
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,52 +1,244 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import { z as z3 } from "zod";
|
|
3
|
-
|
|
4
|
-
// src/utils/fetchers/generic.ts
|
|
1
|
+
// src/schemas.ts
|
|
5
2
|
import { z } from "zod";
|
|
6
3
|
var uuidSchema = z.string().uuid({ message: "Invalid UUID provided" });
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
4
|
+
var websiteSchema = z.object({
|
|
5
|
+
type: z.enum(
|
|
6
|
+
[
|
|
7
|
+
"traditional",
|
|
8
|
+
"digital-collection",
|
|
9
|
+
"plum",
|
|
10
|
+
"cedar",
|
|
11
|
+
"elm",
|
|
12
|
+
"maple",
|
|
13
|
+
"oak",
|
|
14
|
+
"palm"
|
|
15
|
+
],
|
|
16
|
+
{ message: "Invalid website type" }
|
|
17
|
+
),
|
|
18
|
+
status: z.enum(
|
|
19
|
+
["development", "preview", "production"],
|
|
20
|
+
{ message: "Invalid website status" }
|
|
21
|
+
),
|
|
22
|
+
privacy: z.enum(
|
|
23
|
+
["public", "password", "private"],
|
|
24
|
+
{ message: "Invalid website privacy" }
|
|
25
|
+
)
|
|
26
|
+
});
|
|
27
|
+
var componentSchema = z.enum(
|
|
28
|
+
[
|
|
29
|
+
"annotated-document",
|
|
30
|
+
"annotated-image",
|
|
31
|
+
"bibliography",
|
|
32
|
+
"blog",
|
|
33
|
+
"button",
|
|
34
|
+
"collection",
|
|
35
|
+
"empty-space",
|
|
36
|
+
"filter-categories",
|
|
37
|
+
"iframe",
|
|
38
|
+
"iiif-viewer",
|
|
39
|
+
"image",
|
|
40
|
+
"image-gallery",
|
|
41
|
+
"n-columns",
|
|
42
|
+
"n-rows",
|
|
43
|
+
"network-graph",
|
|
44
|
+
"search-bar",
|
|
45
|
+
"table",
|
|
46
|
+
"text",
|
|
47
|
+
"timeline",
|
|
48
|
+
"video"
|
|
49
|
+
],
|
|
50
|
+
{ message: "Invalid component" }
|
|
51
|
+
);
|
|
52
|
+
var categorySchema = z.enum([
|
|
53
|
+
"resource",
|
|
54
|
+
"spatialUnit",
|
|
55
|
+
"concept",
|
|
56
|
+
"period",
|
|
57
|
+
"bibliography",
|
|
58
|
+
"person",
|
|
59
|
+
"propertyValue",
|
|
60
|
+
"set",
|
|
61
|
+
"tree"
|
|
62
|
+
]);
|
|
63
|
+
var gallerySchema = z.object({
|
|
64
|
+
uuid: z.string().uuid({ message: "Invalid UUID" }),
|
|
65
|
+
filter: z.string().optional(),
|
|
66
|
+
page: z.number().positive({ message: "Page must be positive" }),
|
|
67
|
+
perPage: z.number().positive({ message: "Per page must be positive" })
|
|
68
|
+
}).strict();
|
|
69
|
+
var renderOptionsSchema = z.string().transform((str) => str.split(" ")).pipe(
|
|
70
|
+
z.array(
|
|
71
|
+
z.enum([
|
|
34
72
|
"bold",
|
|
35
73
|
"italic",
|
|
36
74
|
"underline"
|
|
37
75
|
])
|
|
38
76
|
)
|
|
39
77
|
);
|
|
40
|
-
var whitespaceSchema =
|
|
41
|
-
|
|
42
|
-
|
|
78
|
+
var whitespaceSchema = z.string().transform((str) => str.split(" ")).pipe(
|
|
79
|
+
z.array(
|
|
80
|
+
z.enum([
|
|
43
81
|
"newline",
|
|
44
82
|
"trailing",
|
|
45
83
|
"leading"
|
|
46
84
|
])
|
|
47
85
|
)
|
|
48
86
|
);
|
|
49
|
-
var emailSchema =
|
|
87
|
+
var emailSchema = z.string().email({ message: "Invalid email" });
|
|
88
|
+
|
|
89
|
+
// src/utils/helpers.ts
|
|
90
|
+
function getItemCategory(keys) {
|
|
91
|
+
const categoryFound = keys.find(
|
|
92
|
+
(key) => categorySchema.safeParse(key).success
|
|
93
|
+
);
|
|
94
|
+
if (!categoryFound) {
|
|
95
|
+
const unknownKey = keys.find(
|
|
96
|
+
(key) => ![
|
|
97
|
+
"uuid",
|
|
98
|
+
"uuidBelongsTo",
|
|
99
|
+
"belongsTo",
|
|
100
|
+
"publicationDateTime",
|
|
101
|
+
"metadata",
|
|
102
|
+
"languages"
|
|
103
|
+
].includes(key)
|
|
104
|
+
);
|
|
105
|
+
throw new Error(`Invalid OCHRE data; found unexpected "${unknownKey}" key`);
|
|
106
|
+
}
|
|
107
|
+
const categoryKey = categorySchema.parse(categoryFound);
|
|
108
|
+
return categoryKey;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/utils/getters.ts
|
|
112
|
+
var DEFAULT_OPTIONS = {
|
|
113
|
+
searchNestedProperties: false
|
|
114
|
+
};
|
|
115
|
+
function getPropertyByLabel(properties, label, options = DEFAULT_OPTIONS) {
|
|
116
|
+
const { searchNestedProperties } = options;
|
|
117
|
+
const property = properties.find((property2) => property2.label === label);
|
|
118
|
+
if (property) {
|
|
119
|
+
return property;
|
|
120
|
+
}
|
|
121
|
+
if (searchNestedProperties) {
|
|
122
|
+
for (const property2 of properties) {
|
|
123
|
+
if (property2.properties.length > 0) {
|
|
124
|
+
const nestedResult = getPropertyByLabel(property2.properties, label, {
|
|
125
|
+
searchNestedProperties
|
|
126
|
+
});
|
|
127
|
+
if (nestedResult) {
|
|
128
|
+
return nestedResult;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
function getPropertyValuesByLabel(properties, label, options = DEFAULT_OPTIONS) {
|
|
136
|
+
const { searchNestedProperties } = options;
|
|
137
|
+
const property = properties.find((property2) => property2.label === label);
|
|
138
|
+
if (property) {
|
|
139
|
+
return property.values.map((value) => value.content);
|
|
140
|
+
}
|
|
141
|
+
if (searchNestedProperties) {
|
|
142
|
+
for (const property2 of properties) {
|
|
143
|
+
if (property2.properties.length > 0) {
|
|
144
|
+
const nestedResult = getPropertyValuesByLabel(
|
|
145
|
+
property2.properties,
|
|
146
|
+
label,
|
|
147
|
+
{ searchNestedProperties }
|
|
148
|
+
);
|
|
149
|
+
if (nestedResult) {
|
|
150
|
+
return nestedResult;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
function getPropertyValueByLabel(properties, label, options = DEFAULT_OPTIONS) {
|
|
158
|
+
const { searchNestedProperties } = options;
|
|
159
|
+
const values = getPropertyValuesByLabel(properties, label, {
|
|
160
|
+
searchNestedProperties
|
|
161
|
+
});
|
|
162
|
+
if (values !== null && values.length > 0) {
|
|
163
|
+
return values[0];
|
|
164
|
+
}
|
|
165
|
+
if (searchNestedProperties) {
|
|
166
|
+
for (const property of properties) {
|
|
167
|
+
if (property.properties.length > 0) {
|
|
168
|
+
const nestedResult = getPropertyValueByLabel(
|
|
169
|
+
property.properties,
|
|
170
|
+
label,
|
|
171
|
+
{ searchNestedProperties }
|
|
172
|
+
);
|
|
173
|
+
if (nestedResult !== null) {
|
|
174
|
+
return nestedResult;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
function getAllPropertyLabels(properties, options = DEFAULT_OPTIONS) {
|
|
182
|
+
const { searchNestedProperties } = options;
|
|
183
|
+
const labels = /* @__PURE__ */ new Set();
|
|
184
|
+
for (const property of properties) {
|
|
185
|
+
labels.add(property.label);
|
|
186
|
+
if (property.properties.length > 0 && searchNestedProperties) {
|
|
187
|
+
const nestedLabels = getAllPropertyLabels(property.properties, {
|
|
188
|
+
searchNestedProperties: true
|
|
189
|
+
});
|
|
190
|
+
for (const label of nestedLabels) {
|
|
191
|
+
labels.add(label);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return [...labels];
|
|
196
|
+
}
|
|
197
|
+
function filterProperties(property, filter, options = DEFAULT_OPTIONS) {
|
|
198
|
+
const { searchNestedProperties } = options;
|
|
199
|
+
const isAllFields = filter.label.toLocaleLowerCase("en-US") === "all fields";
|
|
200
|
+
if (isAllFields || property.label.toLocaleLowerCase("en-US") === filter.label.toLocaleLowerCase("en-US")) {
|
|
201
|
+
let isFound = property.values.some((value) => {
|
|
202
|
+
if (value.content === null) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
if (typeof value.content === "string") {
|
|
206
|
+
if (typeof filter.value !== "string") {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
return value.content.toLocaleLowerCase("en-US").includes(filter.value.toLocaleLowerCase("en-US"));
|
|
210
|
+
}
|
|
211
|
+
if (typeof value.content === "number") {
|
|
212
|
+
if (typeof filter.value !== "number") {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
return value.content === filter.value;
|
|
216
|
+
}
|
|
217
|
+
if (typeof value.content === "boolean") {
|
|
218
|
+
if (typeof filter.value !== "boolean") {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
return value.booleanValue === filter.value;
|
|
222
|
+
}
|
|
223
|
+
if (value.content instanceof Date) {
|
|
224
|
+
if (!(filter.value instanceof Date)) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
return value.content.getTime() === filter.value.getTime();
|
|
228
|
+
}
|
|
229
|
+
return false;
|
|
230
|
+
});
|
|
231
|
+
if (!isFound && searchNestedProperties) {
|
|
232
|
+
isFound = property.properties.some(
|
|
233
|
+
(property2) => filterProperties(property2, filter, { searchNestedProperties: true })
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
return isFound;
|
|
237
|
+
}
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/utils/string.ts
|
|
50
242
|
function getStringItemByLanguage(content, language) {
|
|
51
243
|
const stringItemToFind = content.find((item) => item.lang === language);
|
|
52
244
|
return stringItemToFind ?? null;
|
|
@@ -289,250 +481,42 @@ function parseStringDocumentItem(item, footnotes) {
|
|
|
289
481
|
}
|
|
290
482
|
}
|
|
291
483
|
return returnString.replaceAll(/^(\d+)\./gm, String.raw`$1\.`);
|
|
292
|
-
}
|
|
293
|
-
function parseStringContent(content, language = "eng") {
|
|
294
|
-
switch (typeof content.content) {
|
|
295
|
-
case "string":
|
|
296
|
-
case "number":
|
|
297
|
-
case "boolean": {
|
|
298
|
-
return parseFakeString(content.content);
|
|
299
|
-
}
|
|
300
|
-
case "object": {
|
|
301
|
-
if (Array.isArray(content.content)) {
|
|
302
|
-
const stringItem = getStringItemByLanguage(content.content, language);
|
|
303
|
-
if (stringItem) {
|
|
304
|
-
return parseStringItem(stringItem);
|
|
305
|
-
} else {
|
|
306
|
-
const returnStringItem = content.content[0];
|
|
307
|
-
if (!returnStringItem) {
|
|
308
|
-
throw new Error(
|
|
309
|
-
`No string item found for language \u201C${language}\u201D in the following content:
|
|
310
|
-
${JSON.stringify(
|
|
311
|
-
content.content
|
|
312
|
-
)}.`
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
|
-
return parseStringItem(returnStringItem);
|
|
316
|
-
}
|
|
317
|
-
} else {
|
|
318
|
-
return parseStringItem(content.content);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
default: {
|
|
322
|
-
return String(content.content).replaceAll(/^(\d+)\./gm, String.raw`$1\.`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// src/utils/
|
|
328
|
-
async function fetchResource(uuid) {
|
|
329
|
-
try {
|
|
330
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
331
|
-
if (error !== null) {
|
|
332
|
-
throw new Error(error);
|
|
333
|
-
}
|
|
334
|
-
if (!("resource" in dataRaw.ochre)) {
|
|
335
|
-
throw new Error(
|
|
336
|
-
"Invalid OCHRE data: API response missing 'resource' key"
|
|
337
|
-
);
|
|
338
|
-
}
|
|
339
|
-
const resourceItem = parseResource(dataRaw.ochre.resource);
|
|
340
|
-
const data = {
|
|
341
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
342
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
343
|
-
belongsTo: {
|
|
344
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
345
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
346
|
-
},
|
|
347
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
348
|
-
item: resourceItem
|
|
349
|
-
};
|
|
350
|
-
return { metadata: data.metadata, resource: data.item };
|
|
351
|
-
} catch (error) {
|
|
352
|
-
console.error(error);
|
|
353
|
-
return null;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// src/utils/getters.ts
|
|
358
|
-
var DEFAULT_OPTIONS = {
|
|
359
|
-
searchNestedProperties: false
|
|
360
|
-
};
|
|
361
|
-
function getPropertyByLabel(properties, label, options = DEFAULT_OPTIONS) {
|
|
362
|
-
const { searchNestedProperties } = options;
|
|
363
|
-
const property = properties.find((property2) => property2.label === label);
|
|
364
|
-
if (property) {
|
|
365
|
-
return property;
|
|
366
|
-
}
|
|
367
|
-
if (searchNestedProperties) {
|
|
368
|
-
for (const property2 of properties) {
|
|
369
|
-
if (property2.properties.length > 0) {
|
|
370
|
-
const nestedResult = getPropertyByLabel(property2.properties, label, {
|
|
371
|
-
searchNestedProperties
|
|
372
|
-
});
|
|
373
|
-
if (nestedResult) {
|
|
374
|
-
return nestedResult;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
return null;
|
|
380
|
-
}
|
|
381
|
-
function getPropertyValuesByLabel(properties, label, options = DEFAULT_OPTIONS) {
|
|
382
|
-
const { searchNestedProperties } = options;
|
|
383
|
-
const property = properties.find((property2) => property2.label === label);
|
|
384
|
-
if (property) {
|
|
385
|
-
return property.values.map((value) => value.content);
|
|
386
|
-
}
|
|
387
|
-
if (searchNestedProperties) {
|
|
388
|
-
for (const property2 of properties) {
|
|
389
|
-
if (property2.properties.length > 0) {
|
|
390
|
-
const nestedResult = getPropertyValuesByLabel(
|
|
391
|
-
property2.properties,
|
|
392
|
-
label,
|
|
393
|
-
{ searchNestedProperties }
|
|
394
|
-
);
|
|
395
|
-
if (nestedResult) {
|
|
396
|
-
return nestedResult;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
return null;
|
|
402
|
-
}
|
|
403
|
-
function getPropertyValueByLabel(properties, label, options = DEFAULT_OPTIONS) {
|
|
404
|
-
const { searchNestedProperties } = options;
|
|
405
|
-
const values = getPropertyValuesByLabel(properties, label, {
|
|
406
|
-
searchNestedProperties
|
|
407
|
-
});
|
|
408
|
-
if (values !== null && values.length > 0) {
|
|
409
|
-
return values[0];
|
|
410
|
-
}
|
|
411
|
-
if (searchNestedProperties) {
|
|
412
|
-
for (const property of properties) {
|
|
413
|
-
if (property.properties.length > 0) {
|
|
414
|
-
const nestedResult = getPropertyValueByLabel(
|
|
415
|
-
property.properties,
|
|
416
|
-
label,
|
|
417
|
-
{ searchNestedProperties }
|
|
418
|
-
);
|
|
419
|
-
if (nestedResult !== null) {
|
|
420
|
-
return nestedResult;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
return null;
|
|
426
|
-
}
|
|
427
|
-
function getAllPropertyLabels(properties, options = DEFAULT_OPTIONS) {
|
|
428
|
-
const { searchNestedProperties } = options;
|
|
429
|
-
const labels = /* @__PURE__ */ new Set();
|
|
430
|
-
for (const property of properties) {
|
|
431
|
-
labels.add(property.label);
|
|
432
|
-
if (property.properties.length > 0 && searchNestedProperties) {
|
|
433
|
-
const nestedLabels = getAllPropertyLabels(property.properties, {
|
|
434
|
-
searchNestedProperties: true
|
|
435
|
-
});
|
|
436
|
-
for (const label of nestedLabels) {
|
|
437
|
-
labels.add(label);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
return [...labels];
|
|
442
|
-
}
|
|
443
|
-
function filterProperties(property, filter, options = DEFAULT_OPTIONS) {
|
|
444
|
-
const { searchNestedProperties } = options;
|
|
445
|
-
const isAllFields = filter.label.toLocaleLowerCase("en-US") === "all fields";
|
|
446
|
-
if (isAllFields || property.label.toLocaleLowerCase("en-US") === filter.label.toLocaleLowerCase("en-US")) {
|
|
447
|
-
let isFound = property.values.some((value) => {
|
|
448
|
-
if (value.content === null) {
|
|
449
|
-
return false;
|
|
450
|
-
}
|
|
451
|
-
if (typeof value.content === "string") {
|
|
452
|
-
if (typeof filter.value !== "string") {
|
|
453
|
-
return false;
|
|
454
|
-
}
|
|
455
|
-
return value.content.toLocaleLowerCase("en-US").includes(filter.value.toLocaleLowerCase("en-US"));
|
|
456
|
-
}
|
|
457
|
-
if (typeof value.content === "number") {
|
|
458
|
-
if (typeof filter.value !== "number") {
|
|
459
|
-
return false;
|
|
460
|
-
}
|
|
461
|
-
return value.content === filter.value;
|
|
462
|
-
}
|
|
463
|
-
if (typeof value.content === "boolean") {
|
|
464
|
-
if (typeof filter.value !== "boolean") {
|
|
465
|
-
return false;
|
|
466
|
-
}
|
|
467
|
-
return value.booleanValue === filter.value;
|
|
468
|
-
}
|
|
469
|
-
if (value.content instanceof Date) {
|
|
470
|
-
if (!(filter.value instanceof Date)) {
|
|
471
|
-
return false;
|
|
472
|
-
}
|
|
473
|
-
return value.content.getTime() === filter.value.getTime();
|
|
474
|
-
}
|
|
475
|
-
return false;
|
|
476
|
-
});
|
|
477
|
-
if (!isFound && searchNestedProperties) {
|
|
478
|
-
isFound = property.properties.some(
|
|
479
|
-
(property2) => filterProperties(property2, filter, { searchNestedProperties: true })
|
|
480
|
-
);
|
|
481
|
-
}
|
|
482
|
-
return isFound;
|
|
483
|
-
}
|
|
484
|
-
return false;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// src/utils/parse.ts
|
|
488
|
-
var websiteSchema = z3.object({
|
|
489
|
-
type: z3.enum(
|
|
490
|
-
[
|
|
491
|
-
"traditional",
|
|
492
|
-
"digital-collection",
|
|
493
|
-
"plum",
|
|
494
|
-
"cedar",
|
|
495
|
-
"elm",
|
|
496
|
-
"maple",
|
|
497
|
-
"oak",
|
|
498
|
-
"palm"
|
|
499
|
-
],
|
|
500
|
-
{ message: "Invalid website type" }
|
|
501
|
-
),
|
|
502
|
-
status: z3.enum(
|
|
503
|
-
["development", "preview", "production"],
|
|
504
|
-
{ message: "Invalid website status" }
|
|
505
|
-
),
|
|
506
|
-
privacy: z3.enum(
|
|
507
|
-
["public", "password", "private"],
|
|
508
|
-
{ message: "Invalid website privacy" }
|
|
509
|
-
)
|
|
510
|
-
});
|
|
511
|
-
var componentSchema = z3.enum(
|
|
512
|
-
[
|
|
513
|
-
"annotated-document",
|
|
514
|
-
"annotated-image",
|
|
515
|
-
"bibliography",
|
|
516
|
-
"blog",
|
|
517
|
-
"button",
|
|
518
|
-
"collection",
|
|
519
|
-
"empty-space",
|
|
520
|
-
"filter-categories",
|
|
521
|
-
"iframe",
|
|
522
|
-
"iiif-viewer",
|
|
523
|
-
"image",
|
|
524
|
-
"image-gallery",
|
|
525
|
-
"n-columns",
|
|
526
|
-
"n-rows",
|
|
527
|
-
"network-graph",
|
|
528
|
-
"search-bar",
|
|
529
|
-
"table",
|
|
530
|
-
"text",
|
|
531
|
-
"timeline",
|
|
532
|
-
"video"
|
|
533
|
-
],
|
|
534
|
-
{ message: "Invalid component" }
|
|
535
|
-
);
|
|
484
|
+
}
|
|
485
|
+
function parseStringContent(content, language = "eng") {
|
|
486
|
+
switch (typeof content.content) {
|
|
487
|
+
case "string":
|
|
488
|
+
case "number":
|
|
489
|
+
case "boolean": {
|
|
490
|
+
return parseFakeString(content.content);
|
|
491
|
+
}
|
|
492
|
+
case "object": {
|
|
493
|
+
if (Array.isArray(content.content)) {
|
|
494
|
+
const stringItem = getStringItemByLanguage(content.content, language);
|
|
495
|
+
if (stringItem) {
|
|
496
|
+
return parseStringItem(stringItem);
|
|
497
|
+
} else {
|
|
498
|
+
const returnStringItem = content.content[0];
|
|
499
|
+
if (!returnStringItem) {
|
|
500
|
+
throw new Error(
|
|
501
|
+
`No string item found for language \u201C${language}\u201D in the following content:
|
|
502
|
+
${JSON.stringify(
|
|
503
|
+
content.content
|
|
504
|
+
)}.`
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
return parseStringItem(returnStringItem);
|
|
508
|
+
}
|
|
509
|
+
} else {
|
|
510
|
+
return parseStringItem(content.content);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
default: {
|
|
514
|
+
return String(content.content).replaceAll(/^(\d+)\./gm, String.raw`$1\.`);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// src/utils/parse.ts
|
|
536
520
|
function parseIdentification(identification) {
|
|
537
521
|
try {
|
|
538
522
|
const returnIdentification = {
|
|
@@ -1117,54 +1101,83 @@ function parseTree(tree) {
|
|
|
1117
1101
|
return returnTree;
|
|
1118
1102
|
}
|
|
1119
1103
|
function parseSet(set) {
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
let
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1104
|
+
if (typeof set.items === "string") {
|
|
1105
|
+
throw new TypeError("Invalid OCHRE data: Set has no items");
|
|
1106
|
+
}
|
|
1107
|
+
const itemCategory = getItemCategory(Object.keys(set.items));
|
|
1108
|
+
let items = [];
|
|
1109
|
+
switch (itemCategory) {
|
|
1110
|
+
case "resource": {
|
|
1111
|
+
if (!("resource" in set.items)) {
|
|
1112
|
+
throw new Error("Invalid OCHRE data: Set has no resources");
|
|
1113
|
+
}
|
|
1114
|
+
items = parseResources(
|
|
1115
|
+
Array.isArray(set.items.resource) ? set.items.resource : [set.items.resource]
|
|
1116
|
+
);
|
|
1117
|
+
break;
|
|
1118
|
+
}
|
|
1119
|
+
case "spatialUnit": {
|
|
1120
|
+
if (!("spatialUnit" in set.items)) {
|
|
1121
|
+
throw new Error("Invalid OCHRE data: Set has no spatial units");
|
|
1122
|
+
}
|
|
1123
|
+
items = parseSpatialUnits(
|
|
1124
|
+
Array.isArray(set.items.spatialUnit) ? set.items.spatialUnit : [set.items.spatialUnit]
|
|
1125
|
+
);
|
|
1126
|
+
break;
|
|
1127
|
+
}
|
|
1128
|
+
case "concept": {
|
|
1129
|
+
if (!("concept" in set.items)) {
|
|
1130
|
+
throw new Error("Invalid OCHRE data: Set has no concepts");
|
|
1131
|
+
}
|
|
1132
|
+
items = parseConcepts(
|
|
1133
|
+
Array.isArray(set.items.concept) ? set.items.concept : [set.items.concept]
|
|
1134
|
+
);
|
|
1135
|
+
break;
|
|
1136
|
+
}
|
|
1137
|
+
case "period": {
|
|
1138
|
+
if (!("period" in set.items)) {
|
|
1139
|
+
throw new Error("Invalid OCHRE data: Set has no periods");
|
|
1140
|
+
}
|
|
1141
|
+
items = parsePeriods(
|
|
1142
|
+
Array.isArray(set.items.period) ? set.items.period : [set.items.period]
|
|
1143
|
+
);
|
|
1144
|
+
break;
|
|
1145
|
+
}
|
|
1146
|
+
case "bibliography": {
|
|
1147
|
+
if (!("bibliography" in set.items)) {
|
|
1148
|
+
throw new Error("Invalid OCHRE data: Set has no bibliographies");
|
|
1149
|
+
}
|
|
1150
|
+
items = parseBibliographies(
|
|
1151
|
+
Array.isArray(set.items.bibliography) ? set.items.bibliography : [set.items.bibliography]
|
|
1152
|
+
);
|
|
1153
|
+
break;
|
|
1154
|
+
}
|
|
1155
|
+
case "person": {
|
|
1156
|
+
if (!("person" in set.items)) {
|
|
1157
|
+
throw new Error("Invalid OCHRE data: Set has no persons");
|
|
1158
|
+
}
|
|
1159
|
+
items = parsePersons(
|
|
1160
|
+
Array.isArray(set.items.person) ? set.items.person : [set.items.person]
|
|
1161
|
+
);
|
|
1162
|
+
break;
|
|
1163
|
+
}
|
|
1164
|
+
case "propertyValue": {
|
|
1165
|
+
if (!("propertyValue" in set.items)) {
|
|
1166
|
+
throw new Error("Invalid OCHRE data: Set has no property values");
|
|
1167
|
+
}
|
|
1168
|
+
items = parsePropertyValues(
|
|
1169
|
+
Array.isArray(set.items.propertyValue) ? set.items.propertyValue : [set.items.propertyValue]
|
|
1170
|
+
);
|
|
1171
|
+
break;
|
|
1172
|
+
}
|
|
1173
|
+
default: {
|
|
1174
|
+
throw new Error("Invalid OCHRE data: Set has no items or is malformed");
|
|
1175
|
+
}
|
|
1164
1176
|
}
|
|
1165
1177
|
return {
|
|
1166
1178
|
uuid: set.uuid,
|
|
1167
1179
|
category: "set",
|
|
1180
|
+
itemCategory,
|
|
1168
1181
|
publicationDateTime: set.publicationDateTime ? new Date(set.publicationDateTime) : null,
|
|
1169
1182
|
date: set.date != null ? new Date(set.date) : null,
|
|
1170
1183
|
license: parseLicense(set.availability),
|
|
@@ -1176,18 +1189,10 @@ function parseSet(set) {
|
|
|
1176
1189
|
) : [],
|
|
1177
1190
|
type: set.type,
|
|
1178
1191
|
number: set.n,
|
|
1179
|
-
items
|
|
1180
|
-
resources,
|
|
1181
|
-
spatialUnits,
|
|
1182
|
-
concepts,
|
|
1183
|
-
periods,
|
|
1184
|
-
bibliographies,
|
|
1185
|
-
persons,
|
|
1186
|
-
propertyValues
|
|
1187
|
-
}
|
|
1192
|
+
items
|
|
1188
1193
|
};
|
|
1189
1194
|
}
|
|
1190
|
-
function parseResource(resource
|
|
1195
|
+
function parseResource(resource) {
|
|
1191
1196
|
const returnResource = {
|
|
1192
1197
|
uuid: resource.uuid,
|
|
1193
1198
|
category: "resource",
|
|
@@ -1230,34 +1235,20 @@ function parseResource(resource, isNested = false) {
|
|
|
1230
1235
|
Array.isArray(resource.citedBibliography.reference) ? resource.citedBibliography.reference : [resource.citedBibliography.reference]
|
|
1231
1236
|
) : [],
|
|
1232
1237
|
resources: resource.resource ? parseResources(
|
|
1233
|
-
Array.isArray(resource.resource) ? resource.resource : [resource.resource]
|
|
1234
|
-
true
|
|
1238
|
+
Array.isArray(resource.resource) ? resource.resource : [resource.resource]
|
|
1235
1239
|
) : []
|
|
1236
1240
|
};
|
|
1237
|
-
if (isNested) {
|
|
1238
|
-
const returnNestedResource = {
|
|
1239
|
-
...returnResource,
|
|
1240
|
-
publicationDateTime: null,
|
|
1241
|
-
context: null,
|
|
1242
|
-
license: null,
|
|
1243
|
-
copyright: null
|
|
1244
|
-
};
|
|
1245
|
-
delete returnNestedResource.publicationDateTime;
|
|
1246
|
-
delete returnNestedResource.license;
|
|
1247
|
-
delete returnNestedResource.copyright;
|
|
1248
|
-
return returnNestedResource;
|
|
1249
|
-
}
|
|
1250
1241
|
return returnResource;
|
|
1251
1242
|
}
|
|
1252
|
-
function parseResources(resources
|
|
1243
|
+
function parseResources(resources) {
|
|
1253
1244
|
const returnResources = [];
|
|
1254
1245
|
const resourcesToParse = Array.isArray(resources) ? resources : [resources];
|
|
1255
1246
|
for (const resource of resourcesToParse) {
|
|
1256
|
-
returnResources.push(parseResource(resource
|
|
1247
|
+
returnResources.push(parseResource(resource));
|
|
1257
1248
|
}
|
|
1258
1249
|
return returnResources;
|
|
1259
1250
|
}
|
|
1260
|
-
function parseSpatialUnit(spatialUnit
|
|
1251
|
+
function parseSpatialUnit(spatialUnit) {
|
|
1261
1252
|
const returnSpatialUnit = {
|
|
1262
1253
|
uuid: spatialUnit.uuid,
|
|
1263
1254
|
category: "spatialUnit",
|
|
@@ -1277,34 +1268,22 @@ function parseSpatialUnit(spatialUnit, isNested = false) {
|
|
|
1277
1268
|
) : spatialUnit.observation ? [parseObservation(spatialUnit.observation)] : [],
|
|
1278
1269
|
events: "events" in spatialUnit && spatialUnit.events ? parseEvents(
|
|
1279
1270
|
Array.isArray(spatialUnit.events.event) ? spatialUnit.events.event : [spatialUnit.events.event]
|
|
1271
|
+
) : [],
|
|
1272
|
+
properties: "properties" in spatialUnit && spatialUnit.properties ? parseProperties(
|
|
1273
|
+
Array.isArray(spatialUnit.properties.property) ? spatialUnit.properties.property : [spatialUnit.properties.property]
|
|
1280
1274
|
) : []
|
|
1281
1275
|
};
|
|
1282
|
-
if (isNested) {
|
|
1283
|
-
const returnNestedSpatialUnit = {
|
|
1284
|
-
...returnSpatialUnit,
|
|
1285
|
-
publicationDateTime: null,
|
|
1286
|
-
license: null,
|
|
1287
|
-
properties: "properties" in spatialUnit && spatialUnit.properties ? parseProperties(
|
|
1288
|
-
Array.isArray(spatialUnit.properties.property) ? spatialUnit.properties.property : [spatialUnit.properties.property]
|
|
1289
|
-
) : []
|
|
1290
|
-
};
|
|
1291
|
-
delete returnNestedSpatialUnit.publicationDateTime;
|
|
1292
|
-
delete returnNestedSpatialUnit.license;
|
|
1293
|
-
return returnNestedSpatialUnit;
|
|
1294
|
-
}
|
|
1295
1276
|
return returnSpatialUnit;
|
|
1296
1277
|
}
|
|
1297
|
-
function parseSpatialUnits(spatialUnits
|
|
1278
|
+
function parseSpatialUnits(spatialUnits) {
|
|
1298
1279
|
const returnSpatialUnits = [];
|
|
1299
1280
|
const spatialUnitsToParse = Array.isArray(spatialUnits) ? spatialUnits : [spatialUnits];
|
|
1300
1281
|
for (const spatialUnit of spatialUnitsToParse) {
|
|
1301
|
-
returnSpatialUnits.push(
|
|
1302
|
-
parseSpatialUnit(spatialUnit, isNested)
|
|
1303
|
-
);
|
|
1282
|
+
returnSpatialUnits.push(parseSpatialUnit(spatialUnit));
|
|
1304
1283
|
}
|
|
1305
1284
|
return returnSpatialUnits;
|
|
1306
1285
|
}
|
|
1307
|
-
function parseConcept(concept
|
|
1286
|
+
function parseConcept(concept) {
|
|
1308
1287
|
const returnConcept = {
|
|
1309
1288
|
uuid: concept.uuid,
|
|
1310
1289
|
category: "concept",
|
|
@@ -1317,17 +1296,6 @@ function parseConcept(concept, isNested = false) {
|
|
|
1317
1296
|
Array.isArray(concept.interpretations.interpretation) ? concept.interpretations.interpretation : [concept.interpretations.interpretation]
|
|
1318
1297
|
)
|
|
1319
1298
|
};
|
|
1320
|
-
if (isNested) {
|
|
1321
|
-
const returnNestedConcept = {
|
|
1322
|
-
...returnConcept,
|
|
1323
|
-
publicationDateTime: null,
|
|
1324
|
-
context: null,
|
|
1325
|
-
license: null
|
|
1326
|
-
};
|
|
1327
|
-
delete returnNestedConcept.publicationDateTime;
|
|
1328
|
-
delete returnNestedConcept.license;
|
|
1329
|
-
return returnNestedConcept;
|
|
1330
|
-
}
|
|
1331
1299
|
return returnConcept;
|
|
1332
1300
|
}
|
|
1333
1301
|
var parseWebpageResources = async (webpageResources, type) => {
|
|
@@ -1370,11 +1338,11 @@ var parseWebpageResources = async (webpageResources, type) => {
|
|
|
1370
1338
|
}
|
|
1371
1339
|
return returnElements;
|
|
1372
1340
|
};
|
|
1373
|
-
function parseConcepts(concepts
|
|
1341
|
+
function parseConcepts(concepts) {
|
|
1374
1342
|
const returnConcepts = [];
|
|
1375
1343
|
const conceptsToParse = Array.isArray(concepts) ? concepts : [concepts];
|
|
1376
1344
|
for (const concept of conceptsToParse) {
|
|
1377
|
-
returnConcepts.push(parseConcept(concept
|
|
1345
|
+
returnConcepts.push(parseConcept(concept));
|
|
1378
1346
|
}
|
|
1379
1347
|
return returnConcepts;
|
|
1380
1348
|
}
|
|
@@ -1395,11 +1363,11 @@ async function parseWebElementProperties(componentProperty, elementResource) {
|
|
|
1395
1363
|
if (document === null) {
|
|
1396
1364
|
const documentLink = links.find((link) => link.type === "internalDocument");
|
|
1397
1365
|
if (documentLink) {
|
|
1398
|
-
const
|
|
1399
|
-
if (
|
|
1366
|
+
const { item, error } = await fetchItem(documentLink.uuid, "resource");
|
|
1367
|
+
if (error !== null) {
|
|
1400
1368
|
throw new Error("Failed to fetch OCHRE data");
|
|
1401
1369
|
}
|
|
1402
|
-
document =
|
|
1370
|
+
document = item.document;
|
|
1403
1371
|
}
|
|
1404
1372
|
}
|
|
1405
1373
|
switch (componentName) {
|
|
@@ -2440,300 +2408,144 @@ async function parseWebsite(websiteTree, projectName, website) {
|
|
|
2440
2408
|
};
|
|
2441
2409
|
}
|
|
2442
2410
|
|
|
2443
|
-
// src/utils/fetchers/
|
|
2444
|
-
async function
|
|
2445
|
-
try {
|
|
2446
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
2447
|
-
if (error !== null) {
|
|
2448
|
-
throw new Error(error);
|
|
2449
|
-
}
|
|
2450
|
-
if (!("bibliography" in dataRaw.ochre)) {
|
|
2451
|
-
throw new Error(
|
|
2452
|
-
"Invalid OCHRE data: API response missing 'bibliography' key"
|
|
2453
|
-
);
|
|
2454
|
-
}
|
|
2455
|
-
const bibliographyItem = parseBibliography(dataRaw.ochre.bibliography);
|
|
2456
|
-
const data = {
|
|
2457
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2458
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2459
|
-
belongsTo: {
|
|
2460
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2461
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2462
|
-
},
|
|
2463
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2464
|
-
item: bibliographyItem
|
|
2465
|
-
};
|
|
2466
|
-
return { metadata: data.metadata, bibliography: data.item };
|
|
2467
|
-
} catch (error) {
|
|
2468
|
-
console.error(error);
|
|
2469
|
-
return null;
|
|
2470
|
-
}
|
|
2471
|
-
}
|
|
2472
|
-
|
|
2473
|
-
// src/utils/fetchers/concept.ts
|
|
2474
|
-
async function fetchConcept(uuid) {
|
|
2475
|
-
try {
|
|
2476
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
2477
|
-
if (error !== null) {
|
|
2478
|
-
throw new Error(error);
|
|
2479
|
-
}
|
|
2480
|
-
if (!("concept" in dataRaw.ochre)) {
|
|
2481
|
-
throw new Error("Invalid OCHRE data: API response missing 'concept' key");
|
|
2482
|
-
}
|
|
2483
|
-
const conceptItem = parseConcept(dataRaw.ochre.concept);
|
|
2484
|
-
const data = {
|
|
2485
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2486
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2487
|
-
belongsTo: {
|
|
2488
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2489
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2490
|
-
},
|
|
2491
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2492
|
-
item: conceptItem
|
|
2493
|
-
};
|
|
2494
|
-
return { metadata: data.metadata, concept: data.item };
|
|
2495
|
-
} catch (error) {
|
|
2496
|
-
console.error(error);
|
|
2497
|
-
return null;
|
|
2498
|
-
}
|
|
2499
|
-
}
|
|
2500
|
-
|
|
2501
|
-
// src/utils/fetchers/gallery.ts
|
|
2502
|
-
import { z as z4 } from "zod";
|
|
2503
|
-
var gallerySchema = z4.object({
|
|
2504
|
-
uuid: z4.string().uuid({ message: "Invalid UUID" }),
|
|
2505
|
-
filter: z4.string().optional(),
|
|
2506
|
-
page: z4.number().positive({ message: "Page must be positive" }),
|
|
2507
|
-
perPage: z4.number().positive({ message: "Per page must be positive" })
|
|
2508
|
-
}).strict();
|
|
2509
|
-
async function fetchGallery(uuid, filter, page, perPage) {
|
|
2411
|
+
// src/utils/fetchers/uuid.ts
|
|
2412
|
+
async function fetchByUuid(uuid) {
|
|
2510
2413
|
try {
|
|
2511
|
-
const
|
|
2512
|
-
if (!parsed.success) {
|
|
2513
|
-
throw new Error(parsed.error.message);
|
|
2514
|
-
}
|
|
2414
|
+
const parsedUuid = uuidSchema.parse(uuid);
|
|
2515
2415
|
const response = await fetch(
|
|
2516
|
-
`https://ochre.lib.uchicago.edu/ochre?
|
|
2517
|
-
for $q in input()/ochre[@uuid='${uuid}']
|
|
2518
|
-
let $filtered := $q/tree/items/resource[contains(lower-case(identification/label), lower-case('${filter}'))]
|
|
2519
|
-
let $maxLength := count($filtered)
|
|
2520
|
-
return <gallery maxLength='{$maxLength}'>
|
|
2521
|
-
{$q/metadata/project}
|
|
2522
|
-
{$q/metadata/item}
|
|
2523
|
-
{$filtered[position() >= ${((page - 1) * perPage + 1).toString()} and position() < ${(page * perPage + 1).toString()}]}
|
|
2524
|
-
</gallery>
|
|
2525
|
-
`)}&format=json`
|
|
2416
|
+
`https://ochre.lib.uchicago.edu/ochre?uuid=${parsedUuid}&format=json&lang="*"`
|
|
2526
2417
|
);
|
|
2527
2418
|
if (!response.ok) {
|
|
2528
|
-
throw new Error("
|
|
2529
|
-
}
|
|
2530
|
-
const data = await response.json();
|
|
2531
|
-
if (!("gallery" in data.result)) {
|
|
2532
|
-
throw new Error("Failed to fetch gallery");
|
|
2419
|
+
throw new Error("Failed to fetch OCHRE data");
|
|
2533
2420
|
}
|
|
2534
|
-
const
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
const galleryProjectIdentification = parseIdentification(
|
|
2538
|
-
data.result.gallery.project.identification
|
|
2539
|
-
);
|
|
2540
|
-
const gallery = {
|
|
2541
|
-
identification: galleryIdentification,
|
|
2542
|
-
projectIdentification: galleryProjectIdentification,
|
|
2543
|
-
resources: data.result.gallery.resource ? Array.isArray(data.result.gallery.resource) ? parseResources(data.result.gallery.resource) : [parseResource(data.result.gallery.resource)] : [],
|
|
2544
|
-
maxLength: data.result.gallery.maxLength
|
|
2545
|
-
};
|
|
2546
|
-
return gallery;
|
|
2547
|
-
} catch (error) {
|
|
2548
|
-
console.error(error);
|
|
2549
|
-
return null;
|
|
2550
|
-
}
|
|
2551
|
-
}
|
|
2552
|
-
|
|
2553
|
-
// src/utils/fetchers/period.ts
|
|
2554
|
-
async function fetchPeriod(uuid) {
|
|
2555
|
-
try {
|
|
2556
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
2557
|
-
if (error !== null) {
|
|
2558
|
-
throw new Error(error);
|
|
2421
|
+
const dataRaw = await response.json();
|
|
2422
|
+
if (!("ochre" in dataRaw)) {
|
|
2423
|
+
throw new Error("Invalid OCHRE data: API response missing 'ochre' key");
|
|
2559
2424
|
}
|
|
2560
|
-
|
|
2561
|
-
throw new Error("Invalid OCHRE data: API response missing 'period' key");
|
|
2562
|
-
}
|
|
2563
|
-
const periodItem = parsePeriod(dataRaw.ochre.period);
|
|
2564
|
-
const data = {
|
|
2565
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2566
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2567
|
-
belongsTo: {
|
|
2568
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2569
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2570
|
-
},
|
|
2571
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2572
|
-
item: periodItem
|
|
2573
|
-
};
|
|
2574
|
-
return { metadata: data.metadata, period: data.item };
|
|
2425
|
+
return [null, dataRaw];
|
|
2575
2426
|
} catch (error) {
|
|
2576
|
-
|
|
2577
|
-
return null;
|
|
2427
|
+
return [error instanceof Error ? error.message : "Unknown error", null];
|
|
2578
2428
|
}
|
|
2579
2429
|
}
|
|
2580
2430
|
|
|
2581
|
-
// src/utils/fetchers/
|
|
2582
|
-
async function
|
|
2431
|
+
// src/utils/fetchers/item.ts
|
|
2432
|
+
async function fetchItem(uuid, category) {
|
|
2583
2433
|
try {
|
|
2584
|
-
const [error,
|
|
2434
|
+
const [error, data] = await fetchByUuid(uuid);
|
|
2585
2435
|
if (error !== null) {
|
|
2586
2436
|
throw new Error(error);
|
|
2587
2437
|
}
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2438
|
+
const categoryKey = getItemCategory(Object.keys(data.ochre));
|
|
2439
|
+
let item;
|
|
2440
|
+
switch (categoryKey) {
|
|
2441
|
+
case "resource": {
|
|
2442
|
+
if (!("resource" in data.ochre)) {
|
|
2443
|
+
throw new Error(
|
|
2444
|
+
"Invalid OCHRE data: API response missing 'resource' key"
|
|
2445
|
+
);
|
|
2446
|
+
}
|
|
2447
|
+
item = parseResource(data.ochre.resource);
|
|
2448
|
+
break;
|
|
2449
|
+
}
|
|
2450
|
+
case "spatialUnit": {
|
|
2451
|
+
if (!("spatialUnit" in data.ochre)) {
|
|
2452
|
+
throw new Error(
|
|
2453
|
+
"Invalid OCHRE data: API response missing 'spatialUnit' key"
|
|
2454
|
+
);
|
|
2455
|
+
}
|
|
2456
|
+
item = parseSpatialUnit(data.ochre.spatialUnit);
|
|
2457
|
+
break;
|
|
2458
|
+
}
|
|
2459
|
+
case "concept": {
|
|
2460
|
+
if (!("concept" in data.ochre)) {
|
|
2461
|
+
throw new Error(
|
|
2462
|
+
"Invalid OCHRE data: API response missing 'concept' key"
|
|
2463
|
+
);
|
|
2464
|
+
}
|
|
2465
|
+
item = parseConcept(data.ochre.concept);
|
|
2466
|
+
break;
|
|
2467
|
+
}
|
|
2468
|
+
case "period": {
|
|
2469
|
+
if (!("period" in data.ochre)) {
|
|
2470
|
+
throw new Error(
|
|
2471
|
+
"Invalid OCHRE data: API response missing 'period' key"
|
|
2472
|
+
);
|
|
2473
|
+
}
|
|
2474
|
+
item = parsePeriod(data.ochre.period);
|
|
2475
|
+
break;
|
|
2476
|
+
}
|
|
2477
|
+
case "bibliography": {
|
|
2478
|
+
if (!("bibliography" in data.ochre)) {
|
|
2479
|
+
throw new Error(
|
|
2480
|
+
"Invalid OCHRE data: API response missing 'bibliography' key"
|
|
2481
|
+
);
|
|
2482
|
+
}
|
|
2483
|
+
item = parseBibliography(data.ochre.bibliography);
|
|
2484
|
+
break;
|
|
2485
|
+
}
|
|
2486
|
+
case "person": {
|
|
2487
|
+
if (!("person" in data.ochre)) {
|
|
2488
|
+
throw new Error(
|
|
2489
|
+
"Invalid OCHRE data: API response missing 'person' key"
|
|
2490
|
+
);
|
|
2491
|
+
}
|
|
2492
|
+
item = parsePerson(data.ochre.person);
|
|
2493
|
+
break;
|
|
2494
|
+
}
|
|
2495
|
+
case "propertyValue": {
|
|
2496
|
+
if (!("propertyValue" in data.ochre)) {
|
|
2497
|
+
throw new Error(
|
|
2498
|
+
"Invalid OCHRE data: API response missing 'propertyValue' key"
|
|
2499
|
+
);
|
|
2500
|
+
}
|
|
2501
|
+
item = parsePropertyValue(data.ochre.propertyValue);
|
|
2502
|
+
break;
|
|
2503
|
+
}
|
|
2504
|
+
case "set": {
|
|
2505
|
+
if (!("set" in data.ochre)) {
|
|
2506
|
+
throw new Error("Invalid OCHRE data: API response missing 'set' key");
|
|
2507
|
+
}
|
|
2508
|
+
item = parseSet(data.ochre.set);
|
|
2509
|
+
break;
|
|
2510
|
+
}
|
|
2511
|
+
case "tree": {
|
|
2512
|
+
if (!("tree" in data.ochre)) {
|
|
2513
|
+
throw new Error(
|
|
2514
|
+
"Invalid OCHRE data: API response missing 'tree' key"
|
|
2515
|
+
);
|
|
2516
|
+
}
|
|
2517
|
+
item = parseTree(data.ochre.tree);
|
|
2518
|
+
break;
|
|
2519
|
+
}
|
|
2520
|
+
default: {
|
|
2521
|
+
throw new Error("Invalid category");
|
|
2522
|
+
}
|
|
2617
2523
|
}
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
const data = {
|
|
2623
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2624
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2625
|
-
belongsTo: {
|
|
2626
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2627
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2628
|
-
},
|
|
2629
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2630
|
-
item: setItem
|
|
2524
|
+
const metadata = parseMetadata(data.ochre.metadata);
|
|
2525
|
+
const belongsTo = {
|
|
2526
|
+
uuid: data.ochre.uuidBelongsTo,
|
|
2527
|
+
abbreviation: parseFakeString(data.ochre.belongsTo)
|
|
2631
2528
|
};
|
|
2632
|
-
return {
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
// src/utils/fetchers/spatial-unit.ts
|
|
2640
|
-
async function fetchSpatialUnit(uuid) {
|
|
2641
|
-
try {
|
|
2642
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
2643
|
-
if (error !== null) {
|
|
2644
|
-
throw new Error(error);
|
|
2645
|
-
}
|
|
2646
|
-
if (!("spatialUnit" in dataRaw.ochre)) {
|
|
2647
|
-
throw new Error(
|
|
2648
|
-
"Invalid OCHRE data: API response missing 'spatialUnit' key"
|
|
2649
|
-
);
|
|
2650
|
-
}
|
|
2651
|
-
const spatialUnitItem = parseSpatialUnit(dataRaw.ochre.spatialUnit);
|
|
2652
|
-
const data = {
|
|
2653
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2654
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2655
|
-
belongsTo: {
|
|
2656
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2657
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2658
|
-
},
|
|
2659
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2660
|
-
item: spatialUnitItem
|
|
2529
|
+
return {
|
|
2530
|
+
error: null,
|
|
2531
|
+
metadata,
|
|
2532
|
+
belongsTo,
|
|
2533
|
+
item,
|
|
2534
|
+
category
|
|
2661
2535
|
};
|
|
2662
|
-
return { metadata: data.metadata, spatialUnit: data.item };
|
|
2663
2536
|
} catch (error) {
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
async function fetchTree(uuid) {
|
|
2671
|
-
try {
|
|
2672
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
2673
|
-
if (error !== null) {
|
|
2674
|
-
throw new Error(error);
|
|
2675
|
-
}
|
|
2676
|
-
if (!("tree" in dataRaw.ochre)) {
|
|
2677
|
-
throw new Error("Invalid OCHRE data: API response missing 'tree' key");
|
|
2678
|
-
}
|
|
2679
|
-
const tree = parseTree(dataRaw.ochre.tree);
|
|
2680
|
-
if (!tree) {
|
|
2681
|
-
throw new Error("Invalid OCHRE data: Could not parse tree");
|
|
2682
|
-
}
|
|
2683
|
-
const data = {
|
|
2684
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2685
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2686
|
-
belongsTo: {
|
|
2687
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2688
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2689
|
-
},
|
|
2690
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2691
|
-
item: tree
|
|
2537
|
+
return {
|
|
2538
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
2539
|
+
metadata: void 0,
|
|
2540
|
+
belongsTo: void 0,
|
|
2541
|
+
item: void 0,
|
|
2542
|
+
category: void 0
|
|
2692
2543
|
};
|
|
2693
|
-
return { metadata: data.metadata, tree: data.item };
|
|
2694
|
-
} catch (error) {
|
|
2695
|
-
console.error(error);
|
|
2696
|
-
return null;
|
|
2697
|
-
}
|
|
2698
|
-
}
|
|
2699
|
-
|
|
2700
|
-
// src/utils/fetchers/website.ts
|
|
2701
|
-
async function fetchWebsite(abbreviation) {
|
|
2702
|
-
try {
|
|
2703
|
-
const response = await fetch(
|
|
2704
|
-
`https://ochre.lib.uchicago.edu/ochre?xquery=for $q in input()/ochre[tree[@type='lesson'][identification/abbreviation='${abbreviation.toLocaleLowerCase("en-US")}']] return $q&format=json`
|
|
2705
|
-
);
|
|
2706
|
-
if (!response.ok) {
|
|
2707
|
-
throw new Error("Failed to fetch website");
|
|
2708
|
-
}
|
|
2709
|
-
const data = await response.json();
|
|
2710
|
-
if (!("ochre" in data.result) || !("tree" in data.result.ochre)) {
|
|
2711
|
-
throw new Error("Failed to fetch website");
|
|
2712
|
-
}
|
|
2713
|
-
const projectIdentification = data.result.ochre.metadata.project?.identification ? parseIdentification(data.result.ochre.metadata.project.identification) : null;
|
|
2714
|
-
const website = await parseWebsite(
|
|
2715
|
-
data.result.ochre.tree,
|
|
2716
|
-
projectIdentification?.label ?? "",
|
|
2717
|
-
data.result.ochre.metadata.project?.identification.website ?? null
|
|
2718
|
-
);
|
|
2719
|
-
return website;
|
|
2720
|
-
} catch (error) {
|
|
2721
|
-
console.error(error);
|
|
2722
|
-
return null;
|
|
2723
2544
|
}
|
|
2724
2545
|
}
|
|
2725
2546
|
export {
|
|
2726
|
-
fetchBibliography,
|
|
2727
2547
|
fetchByUuid,
|
|
2728
|
-
|
|
2729
|
-
fetchGallery,
|
|
2730
|
-
fetchPeriod,
|
|
2731
|
-
fetchPropertyValue,
|
|
2732
|
-
fetchResource,
|
|
2733
|
-
fetchSet,
|
|
2734
|
-
fetchSpatialUnit,
|
|
2735
|
-
fetchTree,
|
|
2736
|
-
fetchWebsite,
|
|
2548
|
+
fetchItem,
|
|
2737
2549
|
filterProperties,
|
|
2738
2550
|
getAllPropertyLabels,
|
|
2739
2551
|
getPropertyByLabel,
|