@digitalculture/ochre-sdk 0.5.18 → 0.6.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.cjs +465 -689
- package/dist/index.d.cts +59 -362
- package/dist/index.d.ts +59 -362
- package/dist/index.js +464 -679
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,52 +1,238 @@
|
|
|
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 renderOptionsSchema = z.string().transform((str) => str.split(" ")).pipe(
|
|
64
|
+
z.array(
|
|
65
|
+
z.enum([
|
|
34
66
|
"bold",
|
|
35
67
|
"italic",
|
|
36
68
|
"underline"
|
|
37
69
|
])
|
|
38
70
|
)
|
|
39
71
|
);
|
|
40
|
-
var whitespaceSchema =
|
|
41
|
-
|
|
42
|
-
|
|
72
|
+
var whitespaceSchema = z.string().transform((str) => str.split(" ")).pipe(
|
|
73
|
+
z.array(
|
|
74
|
+
z.enum([
|
|
43
75
|
"newline",
|
|
44
76
|
"trailing",
|
|
45
77
|
"leading"
|
|
46
78
|
])
|
|
47
79
|
)
|
|
48
80
|
);
|
|
49
|
-
var emailSchema =
|
|
81
|
+
var emailSchema = z.string().email({ message: "Invalid email" });
|
|
82
|
+
|
|
83
|
+
// src/utils/helpers.ts
|
|
84
|
+
function getItemCategory(keys) {
|
|
85
|
+
const categoryFound = keys.find(
|
|
86
|
+
(key) => categorySchema.safeParse(key).success
|
|
87
|
+
);
|
|
88
|
+
if (!categoryFound) {
|
|
89
|
+
const unknownKey = keys.find(
|
|
90
|
+
(key) => ![
|
|
91
|
+
"uuid",
|
|
92
|
+
"uuidBelongsTo",
|
|
93
|
+
"belongsTo",
|
|
94
|
+
"publicationDateTime",
|
|
95
|
+
"metadata",
|
|
96
|
+
"languages"
|
|
97
|
+
].includes(key)
|
|
98
|
+
);
|
|
99
|
+
throw new Error(`Invalid OCHRE data; found unexpected "${unknownKey}" key`);
|
|
100
|
+
}
|
|
101
|
+
const categoryKey = categorySchema.parse(categoryFound);
|
|
102
|
+
return categoryKey;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/utils/getters.ts
|
|
106
|
+
var DEFAULT_OPTIONS = {
|
|
107
|
+
searchNestedProperties: false
|
|
108
|
+
};
|
|
109
|
+
function getPropertyByLabel(properties, label, options = DEFAULT_OPTIONS) {
|
|
110
|
+
const { searchNestedProperties } = options;
|
|
111
|
+
const property = properties.find((property2) => property2.label === label);
|
|
112
|
+
if (property) {
|
|
113
|
+
return property;
|
|
114
|
+
}
|
|
115
|
+
if (searchNestedProperties) {
|
|
116
|
+
for (const property2 of properties) {
|
|
117
|
+
if (property2.properties.length > 0) {
|
|
118
|
+
const nestedResult = getPropertyByLabel(property2.properties, label, {
|
|
119
|
+
searchNestedProperties
|
|
120
|
+
});
|
|
121
|
+
if (nestedResult) {
|
|
122
|
+
return nestedResult;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
function getPropertyValuesByLabel(properties, label, options = DEFAULT_OPTIONS) {
|
|
130
|
+
const { searchNestedProperties } = options;
|
|
131
|
+
const property = properties.find((property2) => property2.label === label);
|
|
132
|
+
if (property) {
|
|
133
|
+
return property.values.map((value) => value.content);
|
|
134
|
+
}
|
|
135
|
+
if (searchNestedProperties) {
|
|
136
|
+
for (const property2 of properties) {
|
|
137
|
+
if (property2.properties.length > 0) {
|
|
138
|
+
const nestedResult = getPropertyValuesByLabel(
|
|
139
|
+
property2.properties,
|
|
140
|
+
label,
|
|
141
|
+
{ searchNestedProperties }
|
|
142
|
+
);
|
|
143
|
+
if (nestedResult) {
|
|
144
|
+
return nestedResult;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
function getPropertyValueByLabel(properties, label, options = DEFAULT_OPTIONS) {
|
|
152
|
+
const { searchNestedProperties } = options;
|
|
153
|
+
const values = getPropertyValuesByLabel(properties, label, {
|
|
154
|
+
searchNestedProperties
|
|
155
|
+
});
|
|
156
|
+
if (values !== null && values.length > 0) {
|
|
157
|
+
return values[0];
|
|
158
|
+
}
|
|
159
|
+
if (searchNestedProperties) {
|
|
160
|
+
for (const property of properties) {
|
|
161
|
+
if (property.properties.length > 0) {
|
|
162
|
+
const nestedResult = getPropertyValueByLabel(
|
|
163
|
+
property.properties,
|
|
164
|
+
label,
|
|
165
|
+
{ searchNestedProperties }
|
|
166
|
+
);
|
|
167
|
+
if (nestedResult !== null) {
|
|
168
|
+
return nestedResult;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
function getAllPropertyLabels(properties, options = DEFAULT_OPTIONS) {
|
|
176
|
+
const { searchNestedProperties } = options;
|
|
177
|
+
const labels = /* @__PURE__ */ new Set();
|
|
178
|
+
for (const property of properties) {
|
|
179
|
+
labels.add(property.label);
|
|
180
|
+
if (property.properties.length > 0 && searchNestedProperties) {
|
|
181
|
+
const nestedLabels = getAllPropertyLabels(property.properties, {
|
|
182
|
+
searchNestedProperties: true
|
|
183
|
+
});
|
|
184
|
+
for (const label of nestedLabels) {
|
|
185
|
+
labels.add(label);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return [...labels];
|
|
190
|
+
}
|
|
191
|
+
function filterProperties(property, filter, options = DEFAULT_OPTIONS) {
|
|
192
|
+
const { searchNestedProperties } = options;
|
|
193
|
+
const isAllFields = filter.label.toLocaleLowerCase("en-US") === "all fields";
|
|
194
|
+
if (isAllFields || property.label.toLocaleLowerCase("en-US") === filter.label.toLocaleLowerCase("en-US")) {
|
|
195
|
+
let isFound = property.values.some((value) => {
|
|
196
|
+
if (value.content === null) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
if (typeof value.content === "string") {
|
|
200
|
+
if (typeof filter.value !== "string") {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
return value.content.toLocaleLowerCase("en-US").includes(filter.value.toLocaleLowerCase("en-US"));
|
|
204
|
+
}
|
|
205
|
+
if (typeof value.content === "number") {
|
|
206
|
+
if (typeof filter.value !== "number") {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
return value.content === filter.value;
|
|
210
|
+
}
|
|
211
|
+
if (typeof value.content === "boolean") {
|
|
212
|
+
if (typeof filter.value !== "boolean") {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
return value.booleanValue === filter.value;
|
|
216
|
+
}
|
|
217
|
+
if (value.content instanceof Date) {
|
|
218
|
+
if (!(filter.value instanceof Date)) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
return value.content.getTime() === filter.value.getTime();
|
|
222
|
+
}
|
|
223
|
+
return false;
|
|
224
|
+
});
|
|
225
|
+
if (!isFound && searchNestedProperties) {
|
|
226
|
+
isFound = property.properties.some(
|
|
227
|
+
(property2) => filterProperties(property2, filter, { searchNestedProperties: true })
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
return isFound;
|
|
231
|
+
}
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// src/utils/string.ts
|
|
50
236
|
function getStringItemByLanguage(content, language) {
|
|
51
237
|
const stringItemToFind = content.find((item) => item.lang === language);
|
|
52
238
|
return stringItemToFind ?? null;
|
|
@@ -289,267 +475,42 @@ function parseStringDocumentItem(item, footnotes) {
|
|
|
289
475
|
}
|
|
290
476
|
}
|
|
291
477
|
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 resourceTypeSchema = z3.enum(
|
|
512
|
-
[
|
|
513
|
-
"audio",
|
|
514
|
-
"document",
|
|
515
|
-
"drawing",
|
|
516
|
-
"FITS",
|
|
517
|
-
"geospatial",
|
|
518
|
-
"IIIF",
|
|
519
|
-
"image",
|
|
520
|
-
"model",
|
|
521
|
-
"PTM",
|
|
522
|
-
"TEI",
|
|
523
|
-
"video",
|
|
524
|
-
"webpage"
|
|
525
|
-
],
|
|
526
|
-
{ message: "Invalid resource type" }
|
|
527
|
-
);
|
|
528
|
-
var componentSchema = z3.enum(
|
|
529
|
-
[
|
|
530
|
-
"annotated-document",
|
|
531
|
-
"annotated-image",
|
|
532
|
-
"bibliography",
|
|
533
|
-
"blog",
|
|
534
|
-
"button",
|
|
535
|
-
"collection",
|
|
536
|
-
"empty-space",
|
|
537
|
-
"filter-categories",
|
|
538
|
-
"iframe",
|
|
539
|
-
"iiif-viewer",
|
|
540
|
-
"image",
|
|
541
|
-
"image-gallery",
|
|
542
|
-
"n-columns",
|
|
543
|
-
"n-rows",
|
|
544
|
-
"network-graph",
|
|
545
|
-
"search-bar",
|
|
546
|
-
"table",
|
|
547
|
-
"text",
|
|
548
|
-
"timeline",
|
|
549
|
-
"video"
|
|
550
|
-
],
|
|
551
|
-
{ message: "Invalid component" }
|
|
552
|
-
);
|
|
478
|
+
}
|
|
479
|
+
function parseStringContent(content, language = "eng") {
|
|
480
|
+
switch (typeof content.content) {
|
|
481
|
+
case "string":
|
|
482
|
+
case "number":
|
|
483
|
+
case "boolean": {
|
|
484
|
+
return parseFakeString(content.content);
|
|
485
|
+
}
|
|
486
|
+
case "object": {
|
|
487
|
+
if (Array.isArray(content.content)) {
|
|
488
|
+
const stringItem = getStringItemByLanguage(content.content, language);
|
|
489
|
+
if (stringItem) {
|
|
490
|
+
return parseStringItem(stringItem);
|
|
491
|
+
} else {
|
|
492
|
+
const returnStringItem = content.content[0];
|
|
493
|
+
if (!returnStringItem) {
|
|
494
|
+
throw new Error(
|
|
495
|
+
`No string item found for language \u201C${language}\u201D in the following content:
|
|
496
|
+
${JSON.stringify(
|
|
497
|
+
content.content
|
|
498
|
+
)}.`
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
return parseStringItem(returnStringItem);
|
|
502
|
+
}
|
|
503
|
+
} else {
|
|
504
|
+
return parseStringItem(content.content);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
default: {
|
|
508
|
+
return String(content.content).replaceAll(/^(\d+)\./gm, String.raw`$1\.`);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// src/utils/parse.ts
|
|
553
514
|
function parseIdentification(identification) {
|
|
554
515
|
try {
|
|
555
516
|
const returnIdentification = {
|
|
@@ -959,13 +920,10 @@ function parsePeriods(periods) {
|
|
|
959
920
|
function parseBibliography(bibliography) {
|
|
960
921
|
let resource = null;
|
|
961
922
|
if (bibliography.source?.resource) {
|
|
962
|
-
const resourceType = resourceTypeSchema.parse(
|
|
963
|
-
bibliography.source.resource.type
|
|
964
|
-
);
|
|
965
923
|
resource = {
|
|
966
924
|
uuid: bibliography.source.resource.uuid,
|
|
967
925
|
publicationDateTime: bibliography.source.resource.publicationDateTime ? new Date(bibliography.source.resource.publicationDateTime) : null,
|
|
968
|
-
type:
|
|
926
|
+
type: bibliography.source.resource.type,
|
|
969
927
|
identification: parseIdentification(
|
|
970
928
|
bibliography.source.resource.identification
|
|
971
929
|
)
|
|
@@ -1137,54 +1095,83 @@ function parseTree(tree) {
|
|
|
1137
1095
|
return returnTree;
|
|
1138
1096
|
}
|
|
1139
1097
|
function parseSet(set) {
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
let
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1098
|
+
if (typeof set.items === "string") {
|
|
1099
|
+
throw new TypeError("Invalid OCHRE data: Set has no items");
|
|
1100
|
+
}
|
|
1101
|
+
const itemCategory = getItemCategory(Object.keys(set.items));
|
|
1102
|
+
let items = [];
|
|
1103
|
+
switch (itemCategory) {
|
|
1104
|
+
case "resource": {
|
|
1105
|
+
if (!("resource" in set.items)) {
|
|
1106
|
+
throw new Error("Invalid OCHRE data: Set has no resources");
|
|
1107
|
+
}
|
|
1108
|
+
items = parseResources(
|
|
1109
|
+
Array.isArray(set.items.resource) ? set.items.resource : [set.items.resource]
|
|
1110
|
+
);
|
|
1111
|
+
break;
|
|
1112
|
+
}
|
|
1113
|
+
case "spatialUnit": {
|
|
1114
|
+
if (!("spatialUnit" in set.items)) {
|
|
1115
|
+
throw new Error("Invalid OCHRE data: Set has no spatial units");
|
|
1116
|
+
}
|
|
1117
|
+
items = parseSpatialUnits(
|
|
1118
|
+
Array.isArray(set.items.spatialUnit) ? set.items.spatialUnit : [set.items.spatialUnit]
|
|
1119
|
+
);
|
|
1120
|
+
break;
|
|
1121
|
+
}
|
|
1122
|
+
case "concept": {
|
|
1123
|
+
if (!("concept" in set.items)) {
|
|
1124
|
+
throw new Error("Invalid OCHRE data: Set has no concepts");
|
|
1125
|
+
}
|
|
1126
|
+
items = parseConcepts(
|
|
1127
|
+
Array.isArray(set.items.concept) ? set.items.concept : [set.items.concept]
|
|
1128
|
+
);
|
|
1129
|
+
break;
|
|
1130
|
+
}
|
|
1131
|
+
case "period": {
|
|
1132
|
+
if (!("period" in set.items)) {
|
|
1133
|
+
throw new Error("Invalid OCHRE data: Set has no periods");
|
|
1134
|
+
}
|
|
1135
|
+
items = parsePeriods(
|
|
1136
|
+
Array.isArray(set.items.period) ? set.items.period : [set.items.period]
|
|
1137
|
+
);
|
|
1138
|
+
break;
|
|
1139
|
+
}
|
|
1140
|
+
case "bibliography": {
|
|
1141
|
+
if (!("bibliography" in set.items)) {
|
|
1142
|
+
throw new Error("Invalid OCHRE data: Set has no bibliographies");
|
|
1143
|
+
}
|
|
1144
|
+
items = parseBibliographies(
|
|
1145
|
+
Array.isArray(set.items.bibliography) ? set.items.bibliography : [set.items.bibliography]
|
|
1146
|
+
);
|
|
1147
|
+
break;
|
|
1148
|
+
}
|
|
1149
|
+
case "person": {
|
|
1150
|
+
if (!("person" in set.items)) {
|
|
1151
|
+
throw new Error("Invalid OCHRE data: Set has no persons");
|
|
1152
|
+
}
|
|
1153
|
+
items = parsePersons(
|
|
1154
|
+
Array.isArray(set.items.person) ? set.items.person : [set.items.person]
|
|
1155
|
+
);
|
|
1156
|
+
break;
|
|
1157
|
+
}
|
|
1158
|
+
case "propertyValue": {
|
|
1159
|
+
if (!("propertyValue" in set.items)) {
|
|
1160
|
+
throw new Error("Invalid OCHRE data: Set has no property values");
|
|
1161
|
+
}
|
|
1162
|
+
items = parsePropertyValues(
|
|
1163
|
+
Array.isArray(set.items.propertyValue) ? set.items.propertyValue : [set.items.propertyValue]
|
|
1164
|
+
);
|
|
1165
|
+
break;
|
|
1166
|
+
}
|
|
1167
|
+
default: {
|
|
1168
|
+
throw new Error("Invalid OCHRE data: Set has no items or is malformed");
|
|
1169
|
+
}
|
|
1184
1170
|
}
|
|
1185
1171
|
return {
|
|
1186
1172
|
uuid: set.uuid,
|
|
1187
1173
|
category: "set",
|
|
1174
|
+
itemCategory,
|
|
1188
1175
|
publicationDateTime: set.publicationDateTime ? new Date(set.publicationDateTime) : null,
|
|
1189
1176
|
date: set.date != null ? new Date(set.date) : null,
|
|
1190
1177
|
license: parseLicense(set.availability),
|
|
@@ -1196,24 +1183,15 @@ function parseSet(set) {
|
|
|
1196
1183
|
) : [],
|
|
1197
1184
|
type: set.type,
|
|
1198
1185
|
number: set.n,
|
|
1199
|
-
items
|
|
1200
|
-
resources,
|
|
1201
|
-
spatialUnits,
|
|
1202
|
-
concepts,
|
|
1203
|
-
periods,
|
|
1204
|
-
bibliographies,
|
|
1205
|
-
persons,
|
|
1206
|
-
propertyValues
|
|
1207
|
-
}
|
|
1186
|
+
items
|
|
1208
1187
|
};
|
|
1209
1188
|
}
|
|
1210
|
-
function parseResource(resource
|
|
1211
|
-
const resourceType = resourceTypeSchema.parse(resource.type);
|
|
1189
|
+
function parseResource(resource) {
|
|
1212
1190
|
const returnResource = {
|
|
1213
1191
|
uuid: resource.uuid,
|
|
1214
1192
|
category: "resource",
|
|
1215
1193
|
publicationDateTime: resource.publicationDateTime ? new Date(resource.publicationDateTime) : null,
|
|
1216
|
-
type:
|
|
1194
|
+
type: resource.type,
|
|
1217
1195
|
number: resource.n,
|
|
1218
1196
|
format: resource.format ?? null,
|
|
1219
1197
|
context: "context" in resource && resource.context ? parseContext(resource.context) : null,
|
|
@@ -1251,34 +1229,20 @@ function parseResource(resource, isNested = false) {
|
|
|
1251
1229
|
Array.isArray(resource.citedBibliography.reference) ? resource.citedBibliography.reference : [resource.citedBibliography.reference]
|
|
1252
1230
|
) : [],
|
|
1253
1231
|
resources: resource.resource ? parseResources(
|
|
1254
|
-
Array.isArray(resource.resource) ? resource.resource : [resource.resource]
|
|
1255
|
-
true
|
|
1232
|
+
Array.isArray(resource.resource) ? resource.resource : [resource.resource]
|
|
1256
1233
|
) : []
|
|
1257
1234
|
};
|
|
1258
|
-
if (isNested) {
|
|
1259
|
-
const returnNestedResource = {
|
|
1260
|
-
...returnResource,
|
|
1261
|
-
publicationDateTime: null,
|
|
1262
|
-
context: null,
|
|
1263
|
-
license: null,
|
|
1264
|
-
copyright: null
|
|
1265
|
-
};
|
|
1266
|
-
delete returnNestedResource.publicationDateTime;
|
|
1267
|
-
delete returnNestedResource.license;
|
|
1268
|
-
delete returnNestedResource.copyright;
|
|
1269
|
-
return returnNestedResource;
|
|
1270
|
-
}
|
|
1271
1235
|
return returnResource;
|
|
1272
1236
|
}
|
|
1273
|
-
function parseResources(resources
|
|
1237
|
+
function parseResources(resources) {
|
|
1274
1238
|
const returnResources = [];
|
|
1275
1239
|
const resourcesToParse = Array.isArray(resources) ? resources : [resources];
|
|
1276
1240
|
for (const resource of resourcesToParse) {
|
|
1277
|
-
returnResources.push(parseResource(resource
|
|
1241
|
+
returnResources.push(parseResource(resource));
|
|
1278
1242
|
}
|
|
1279
1243
|
return returnResources;
|
|
1280
1244
|
}
|
|
1281
|
-
function parseSpatialUnit(spatialUnit
|
|
1245
|
+
function parseSpatialUnit(spatialUnit) {
|
|
1282
1246
|
const returnSpatialUnit = {
|
|
1283
1247
|
uuid: spatialUnit.uuid,
|
|
1284
1248
|
category: "spatialUnit",
|
|
@@ -1298,34 +1262,22 @@ function parseSpatialUnit(spatialUnit, isNested = false) {
|
|
|
1298
1262
|
) : spatialUnit.observation ? [parseObservation(spatialUnit.observation)] : [],
|
|
1299
1263
|
events: "events" in spatialUnit && spatialUnit.events ? parseEvents(
|
|
1300
1264
|
Array.isArray(spatialUnit.events.event) ? spatialUnit.events.event : [spatialUnit.events.event]
|
|
1265
|
+
) : [],
|
|
1266
|
+
properties: "properties" in spatialUnit && spatialUnit.properties ? parseProperties(
|
|
1267
|
+
Array.isArray(spatialUnit.properties.property) ? spatialUnit.properties.property : [spatialUnit.properties.property]
|
|
1301
1268
|
) : []
|
|
1302
1269
|
};
|
|
1303
|
-
if (isNested) {
|
|
1304
|
-
const returnNestedSpatialUnit = {
|
|
1305
|
-
...returnSpatialUnit,
|
|
1306
|
-
publicationDateTime: null,
|
|
1307
|
-
license: null,
|
|
1308
|
-
properties: "properties" in spatialUnit && spatialUnit.properties ? parseProperties(
|
|
1309
|
-
Array.isArray(spatialUnit.properties.property) ? spatialUnit.properties.property : [spatialUnit.properties.property]
|
|
1310
|
-
) : []
|
|
1311
|
-
};
|
|
1312
|
-
delete returnNestedSpatialUnit.publicationDateTime;
|
|
1313
|
-
delete returnNestedSpatialUnit.license;
|
|
1314
|
-
return returnNestedSpatialUnit;
|
|
1315
|
-
}
|
|
1316
1270
|
return returnSpatialUnit;
|
|
1317
1271
|
}
|
|
1318
|
-
function parseSpatialUnits(spatialUnits
|
|
1272
|
+
function parseSpatialUnits(spatialUnits) {
|
|
1319
1273
|
const returnSpatialUnits = [];
|
|
1320
1274
|
const spatialUnitsToParse = Array.isArray(spatialUnits) ? spatialUnits : [spatialUnits];
|
|
1321
1275
|
for (const spatialUnit of spatialUnitsToParse) {
|
|
1322
|
-
returnSpatialUnits.push(
|
|
1323
|
-
parseSpatialUnit(spatialUnit, isNested)
|
|
1324
|
-
);
|
|
1276
|
+
returnSpatialUnits.push(parseSpatialUnit(spatialUnit));
|
|
1325
1277
|
}
|
|
1326
1278
|
return returnSpatialUnits;
|
|
1327
1279
|
}
|
|
1328
|
-
function parseConcept(concept
|
|
1280
|
+
function parseConcept(concept) {
|
|
1329
1281
|
const returnConcept = {
|
|
1330
1282
|
uuid: concept.uuid,
|
|
1331
1283
|
category: "concept",
|
|
@@ -1338,17 +1290,6 @@ function parseConcept(concept, isNested = false) {
|
|
|
1338
1290
|
Array.isArray(concept.interpretations.interpretation) ? concept.interpretations.interpretation : [concept.interpretations.interpretation]
|
|
1339
1291
|
)
|
|
1340
1292
|
};
|
|
1341
|
-
if (isNested) {
|
|
1342
|
-
const returnNestedConcept = {
|
|
1343
|
-
...returnConcept,
|
|
1344
|
-
publicationDateTime: null,
|
|
1345
|
-
context: null,
|
|
1346
|
-
license: null
|
|
1347
|
-
};
|
|
1348
|
-
delete returnNestedConcept.publicationDateTime;
|
|
1349
|
-
delete returnNestedConcept.license;
|
|
1350
|
-
return returnNestedConcept;
|
|
1351
|
-
}
|
|
1352
1293
|
return returnConcept;
|
|
1353
1294
|
}
|
|
1354
1295
|
var parseWebpageResources = async (webpageResources, type) => {
|
|
@@ -1391,11 +1332,11 @@ var parseWebpageResources = async (webpageResources, type) => {
|
|
|
1391
1332
|
}
|
|
1392
1333
|
return returnElements;
|
|
1393
1334
|
};
|
|
1394
|
-
function parseConcepts(concepts
|
|
1335
|
+
function parseConcepts(concepts) {
|
|
1395
1336
|
const returnConcepts = [];
|
|
1396
1337
|
const conceptsToParse = Array.isArray(concepts) ? concepts : [concepts];
|
|
1397
1338
|
for (const concept of conceptsToParse) {
|
|
1398
|
-
returnConcepts.push(parseConcept(concept
|
|
1339
|
+
returnConcepts.push(parseConcept(concept));
|
|
1399
1340
|
}
|
|
1400
1341
|
return returnConcepts;
|
|
1401
1342
|
}
|
|
@@ -1416,11 +1357,11 @@ async function parseWebElementProperties(componentProperty, elementResource) {
|
|
|
1416
1357
|
if (document === null) {
|
|
1417
1358
|
const documentLink = links.find((link) => link.type === "internalDocument");
|
|
1418
1359
|
if (documentLink) {
|
|
1419
|
-
const
|
|
1420
|
-
if (
|
|
1360
|
+
const { item, error } = await fetchItem(documentLink.uuid, "resource");
|
|
1361
|
+
if (error !== null) {
|
|
1421
1362
|
throw new Error("Failed to fetch OCHRE data");
|
|
1422
1363
|
}
|
|
1423
|
-
document =
|
|
1364
|
+
document = item.document;
|
|
1424
1365
|
}
|
|
1425
1366
|
}
|
|
1426
1367
|
switch (componentName) {
|
|
@@ -2461,300 +2402,144 @@ async function parseWebsite(websiteTree, projectName, website) {
|
|
|
2461
2402
|
};
|
|
2462
2403
|
}
|
|
2463
2404
|
|
|
2464
|
-
// src/utils/fetchers/
|
|
2465
|
-
async function
|
|
2466
|
-
try {
|
|
2467
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
2468
|
-
if (error !== null) {
|
|
2469
|
-
throw new Error(error);
|
|
2470
|
-
}
|
|
2471
|
-
if (!("bibliography" in dataRaw.ochre)) {
|
|
2472
|
-
throw new Error(
|
|
2473
|
-
"Invalid OCHRE data: API response missing 'bibliography' key"
|
|
2474
|
-
);
|
|
2475
|
-
}
|
|
2476
|
-
const bibliographyItem = parseBibliography(dataRaw.ochre.bibliography);
|
|
2477
|
-
const data = {
|
|
2478
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2479
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2480
|
-
belongsTo: {
|
|
2481
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2482
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2483
|
-
},
|
|
2484
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2485
|
-
item: bibliographyItem
|
|
2486
|
-
};
|
|
2487
|
-
return { metadata: data.metadata, bibliography: data.item };
|
|
2488
|
-
} catch (error) {
|
|
2489
|
-
console.error(error);
|
|
2490
|
-
return null;
|
|
2491
|
-
}
|
|
2492
|
-
}
|
|
2493
|
-
|
|
2494
|
-
// src/utils/fetchers/concept.ts
|
|
2495
|
-
async function fetchConcept(uuid) {
|
|
2496
|
-
try {
|
|
2497
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
2498
|
-
if (error !== null) {
|
|
2499
|
-
throw new Error(error);
|
|
2500
|
-
}
|
|
2501
|
-
if (!("concept" in dataRaw.ochre)) {
|
|
2502
|
-
throw new Error("Invalid OCHRE data: API response missing 'concept' key");
|
|
2503
|
-
}
|
|
2504
|
-
const conceptItem = parseConcept(dataRaw.ochre.concept);
|
|
2505
|
-
const data = {
|
|
2506
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2507
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2508
|
-
belongsTo: {
|
|
2509
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2510
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2511
|
-
},
|
|
2512
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2513
|
-
item: conceptItem
|
|
2514
|
-
};
|
|
2515
|
-
return { metadata: data.metadata, concept: data.item };
|
|
2516
|
-
} catch (error) {
|
|
2517
|
-
console.error(error);
|
|
2518
|
-
return null;
|
|
2519
|
-
}
|
|
2520
|
-
}
|
|
2521
|
-
|
|
2522
|
-
// src/utils/fetchers/gallery.ts
|
|
2523
|
-
import { z as z4 } from "zod";
|
|
2524
|
-
var gallerySchema = z4.object({
|
|
2525
|
-
uuid: z4.string().uuid({ message: "Invalid UUID" }),
|
|
2526
|
-
filter: z4.string().optional(),
|
|
2527
|
-
page: z4.number().positive({ message: "Page must be positive" }),
|
|
2528
|
-
perPage: z4.number().positive({ message: "Per page must be positive" })
|
|
2529
|
-
}).strict();
|
|
2530
|
-
async function fetchGallery(uuid, filter, page, perPage) {
|
|
2405
|
+
// src/utils/fetchers/uuid.ts
|
|
2406
|
+
async function fetchByUuid(uuid) {
|
|
2531
2407
|
try {
|
|
2532
|
-
const
|
|
2533
|
-
if (!parsed.success) {
|
|
2534
|
-
throw new Error(parsed.error.message);
|
|
2535
|
-
}
|
|
2408
|
+
const parsedUuid = uuidSchema.parse(uuid);
|
|
2536
2409
|
const response = await fetch(
|
|
2537
|
-
`https://ochre.lib.uchicago.edu/ochre?
|
|
2538
|
-
for $q in input()/ochre[@uuid='${uuid}']
|
|
2539
|
-
let $filtered := $q/tree/items/resource[contains(lower-case(identification/label), lower-case('${filter}'))]
|
|
2540
|
-
let $maxLength := count($filtered)
|
|
2541
|
-
return <gallery maxLength='{$maxLength}'>
|
|
2542
|
-
{$q/metadata/project}
|
|
2543
|
-
{$q/metadata/item}
|
|
2544
|
-
{$filtered[position() >= ${((page - 1) * perPage + 1).toString()} and position() < ${(page * perPage + 1).toString()}]}
|
|
2545
|
-
</gallery>
|
|
2546
|
-
`)}&format=json`
|
|
2410
|
+
`https://ochre.lib.uchicago.edu/ochre?uuid=${parsedUuid}&format=json&lang="*"`
|
|
2547
2411
|
);
|
|
2548
2412
|
if (!response.ok) {
|
|
2549
|
-
throw new Error("
|
|
2550
|
-
}
|
|
2551
|
-
const data = await response.json();
|
|
2552
|
-
if (!("gallery" in data.result)) {
|
|
2553
|
-
throw new Error("Failed to fetch gallery");
|
|
2413
|
+
throw new Error("Failed to fetch OCHRE data");
|
|
2554
2414
|
}
|
|
2555
|
-
const
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
const galleryProjectIdentification = parseIdentification(
|
|
2559
|
-
data.result.gallery.project.identification
|
|
2560
|
-
);
|
|
2561
|
-
const gallery = {
|
|
2562
|
-
identification: galleryIdentification,
|
|
2563
|
-
projectIdentification: galleryProjectIdentification,
|
|
2564
|
-
resources: data.result.gallery.resource ? Array.isArray(data.result.gallery.resource) ? parseResources(data.result.gallery.resource) : [parseResource(data.result.gallery.resource)] : [],
|
|
2565
|
-
maxLength: data.result.gallery.maxLength
|
|
2566
|
-
};
|
|
2567
|
-
return gallery;
|
|
2568
|
-
} catch (error) {
|
|
2569
|
-
console.error(error);
|
|
2570
|
-
return null;
|
|
2571
|
-
}
|
|
2572
|
-
}
|
|
2573
|
-
|
|
2574
|
-
// src/utils/fetchers/period.ts
|
|
2575
|
-
async function fetchPeriod(uuid) {
|
|
2576
|
-
try {
|
|
2577
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
2578
|
-
if (error !== null) {
|
|
2579
|
-
throw new Error(error);
|
|
2415
|
+
const dataRaw = await response.json();
|
|
2416
|
+
if (!("ochre" in dataRaw)) {
|
|
2417
|
+
throw new Error("Invalid OCHRE data: API response missing 'ochre' key");
|
|
2580
2418
|
}
|
|
2581
|
-
|
|
2582
|
-
throw new Error("Invalid OCHRE data: API response missing 'period' key");
|
|
2583
|
-
}
|
|
2584
|
-
const periodItem = parsePeriod(dataRaw.ochre.period);
|
|
2585
|
-
const data = {
|
|
2586
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2587
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2588
|
-
belongsTo: {
|
|
2589
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2590
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2591
|
-
},
|
|
2592
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2593
|
-
item: periodItem
|
|
2594
|
-
};
|
|
2595
|
-
return { metadata: data.metadata, period: data.item };
|
|
2419
|
+
return [null, dataRaw];
|
|
2596
2420
|
} catch (error) {
|
|
2597
|
-
|
|
2598
|
-
return null;
|
|
2421
|
+
return [error instanceof Error ? error.message : "Unknown error", null];
|
|
2599
2422
|
}
|
|
2600
2423
|
}
|
|
2601
2424
|
|
|
2602
|
-
// src/utils/fetchers/
|
|
2603
|
-
async function
|
|
2425
|
+
// src/utils/fetchers/item.ts
|
|
2426
|
+
async function fetchItem(uuid, category) {
|
|
2604
2427
|
try {
|
|
2605
|
-
const [error,
|
|
2428
|
+
const [error, data] = await fetchByUuid(uuid);
|
|
2606
2429
|
if (error !== null) {
|
|
2607
2430
|
throw new Error(error);
|
|
2608
2431
|
}
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2432
|
+
const categoryKey = getItemCategory(Object.keys(data.ochre));
|
|
2433
|
+
let item;
|
|
2434
|
+
switch (categoryKey) {
|
|
2435
|
+
case "resource": {
|
|
2436
|
+
if (!("resource" in data.ochre)) {
|
|
2437
|
+
throw new Error(
|
|
2438
|
+
"Invalid OCHRE data: API response missing 'resource' key"
|
|
2439
|
+
);
|
|
2440
|
+
}
|
|
2441
|
+
item = parseResource(data.ochre.resource);
|
|
2442
|
+
break;
|
|
2443
|
+
}
|
|
2444
|
+
case "spatialUnit": {
|
|
2445
|
+
if (!("spatialUnit" in data.ochre)) {
|
|
2446
|
+
throw new Error(
|
|
2447
|
+
"Invalid OCHRE data: API response missing 'spatialUnit' key"
|
|
2448
|
+
);
|
|
2449
|
+
}
|
|
2450
|
+
item = parseSpatialUnit(data.ochre.spatialUnit);
|
|
2451
|
+
break;
|
|
2452
|
+
}
|
|
2453
|
+
case "concept": {
|
|
2454
|
+
if (!("concept" in data.ochre)) {
|
|
2455
|
+
throw new Error(
|
|
2456
|
+
"Invalid OCHRE data: API response missing 'concept' key"
|
|
2457
|
+
);
|
|
2458
|
+
}
|
|
2459
|
+
item = parseConcept(data.ochre.concept);
|
|
2460
|
+
break;
|
|
2461
|
+
}
|
|
2462
|
+
case "period": {
|
|
2463
|
+
if (!("period" in data.ochre)) {
|
|
2464
|
+
throw new Error(
|
|
2465
|
+
"Invalid OCHRE data: API response missing 'period' key"
|
|
2466
|
+
);
|
|
2467
|
+
}
|
|
2468
|
+
item = parsePeriod(data.ochre.period);
|
|
2469
|
+
break;
|
|
2470
|
+
}
|
|
2471
|
+
case "bibliography": {
|
|
2472
|
+
if (!("bibliography" in data.ochre)) {
|
|
2473
|
+
throw new Error(
|
|
2474
|
+
"Invalid OCHRE data: API response missing 'bibliography' key"
|
|
2475
|
+
);
|
|
2476
|
+
}
|
|
2477
|
+
item = parseBibliography(data.ochre.bibliography);
|
|
2478
|
+
break;
|
|
2479
|
+
}
|
|
2480
|
+
case "person": {
|
|
2481
|
+
if (!("person" in data.ochre)) {
|
|
2482
|
+
throw new Error(
|
|
2483
|
+
"Invalid OCHRE data: API response missing 'person' key"
|
|
2484
|
+
);
|
|
2485
|
+
}
|
|
2486
|
+
item = parsePerson(data.ochre.person);
|
|
2487
|
+
break;
|
|
2488
|
+
}
|
|
2489
|
+
case "propertyValue": {
|
|
2490
|
+
if (!("propertyValue" in data.ochre)) {
|
|
2491
|
+
throw new Error(
|
|
2492
|
+
"Invalid OCHRE data: API response missing 'propertyValue' key"
|
|
2493
|
+
);
|
|
2494
|
+
}
|
|
2495
|
+
item = parsePropertyValue(data.ochre.propertyValue);
|
|
2496
|
+
break;
|
|
2497
|
+
}
|
|
2498
|
+
case "set": {
|
|
2499
|
+
if (!("set" in data.ochre)) {
|
|
2500
|
+
throw new Error("Invalid OCHRE data: API response missing 'set' key");
|
|
2501
|
+
}
|
|
2502
|
+
item = parseSet(data.ochre.set);
|
|
2503
|
+
break;
|
|
2504
|
+
}
|
|
2505
|
+
case "tree": {
|
|
2506
|
+
if (!("tree" in data.ochre)) {
|
|
2507
|
+
throw new Error(
|
|
2508
|
+
"Invalid OCHRE data: API response missing 'tree' key"
|
|
2509
|
+
);
|
|
2510
|
+
}
|
|
2511
|
+
item = parseTree(data.ochre.tree);
|
|
2512
|
+
break;
|
|
2513
|
+
}
|
|
2514
|
+
default: {
|
|
2515
|
+
throw new Error("Invalid category");
|
|
2516
|
+
}
|
|
2638
2517
|
}
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
const data = {
|
|
2644
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2645
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2646
|
-
belongsTo: {
|
|
2647
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2648
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2649
|
-
},
|
|
2650
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2651
|
-
item: setItem
|
|
2518
|
+
const metadata = parseMetadata(data.ochre.metadata);
|
|
2519
|
+
const belongsTo = {
|
|
2520
|
+
uuid: data.ochre.uuidBelongsTo,
|
|
2521
|
+
abbreviation: parseFakeString(data.ochre.belongsTo)
|
|
2652
2522
|
};
|
|
2653
|
-
return {
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
// src/utils/fetchers/spatial-unit.ts
|
|
2661
|
-
async function fetchSpatialUnit(uuid) {
|
|
2662
|
-
try {
|
|
2663
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
2664
|
-
if (error !== null) {
|
|
2665
|
-
throw new Error(error);
|
|
2666
|
-
}
|
|
2667
|
-
if (!("spatialUnit" in dataRaw.ochre)) {
|
|
2668
|
-
throw new Error(
|
|
2669
|
-
"Invalid OCHRE data: API response missing 'spatialUnit' key"
|
|
2670
|
-
);
|
|
2671
|
-
}
|
|
2672
|
-
const spatialUnitItem = parseSpatialUnit(dataRaw.ochre.spatialUnit);
|
|
2673
|
-
const data = {
|
|
2674
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2675
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2676
|
-
belongsTo: {
|
|
2677
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2678
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2679
|
-
},
|
|
2680
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2681
|
-
item: spatialUnitItem
|
|
2523
|
+
return {
|
|
2524
|
+
error: null,
|
|
2525
|
+
metadata,
|
|
2526
|
+
belongsTo,
|
|
2527
|
+
item,
|
|
2528
|
+
category
|
|
2682
2529
|
};
|
|
2683
|
-
return { metadata: data.metadata, spatialUnit: data.item };
|
|
2684
2530
|
} catch (error) {
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
async function fetchTree(uuid) {
|
|
2692
|
-
try {
|
|
2693
|
-
const [error, dataRaw] = await fetchByUuid(uuid);
|
|
2694
|
-
if (error !== null) {
|
|
2695
|
-
throw new Error(error);
|
|
2696
|
-
}
|
|
2697
|
-
if (!("tree" in dataRaw.ochre)) {
|
|
2698
|
-
throw new Error("Invalid OCHRE data: API response missing 'tree' key");
|
|
2699
|
-
}
|
|
2700
|
-
const tree = parseTree(dataRaw.ochre.tree);
|
|
2701
|
-
if (!tree) {
|
|
2702
|
-
throw new Error("Invalid OCHRE data: Could not parse tree");
|
|
2703
|
-
}
|
|
2704
|
-
const data = {
|
|
2705
|
-
uuid: parseFakeString(dataRaw.ochre.uuid),
|
|
2706
|
-
publicationDateTime: new Date(dataRaw.ochre.publicationDateTime),
|
|
2707
|
-
belongsTo: {
|
|
2708
|
-
uuid: dataRaw.ochre.uuidBelongsTo,
|
|
2709
|
-
abbreviation: parseFakeString(dataRaw.ochre.belongsTo)
|
|
2710
|
-
},
|
|
2711
|
-
metadata: parseMetadata(dataRaw.ochre.metadata),
|
|
2712
|
-
item: tree
|
|
2531
|
+
return {
|
|
2532
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
2533
|
+
metadata: void 0,
|
|
2534
|
+
belongsTo: void 0,
|
|
2535
|
+
item: void 0,
|
|
2536
|
+
category: void 0
|
|
2713
2537
|
};
|
|
2714
|
-
return { metadata: data.metadata, tree: data.item };
|
|
2715
|
-
} catch (error) {
|
|
2716
|
-
console.error(error);
|
|
2717
|
-
return null;
|
|
2718
|
-
}
|
|
2719
|
-
}
|
|
2720
|
-
|
|
2721
|
-
// src/utils/fetchers/website.ts
|
|
2722
|
-
async function fetchWebsite(abbreviation) {
|
|
2723
|
-
try {
|
|
2724
|
-
const response = await fetch(
|
|
2725
|
-
`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`
|
|
2726
|
-
);
|
|
2727
|
-
if (!response.ok) {
|
|
2728
|
-
throw new Error("Failed to fetch website");
|
|
2729
|
-
}
|
|
2730
|
-
const data = await response.json();
|
|
2731
|
-
if (!("ochre" in data.result) || !("tree" in data.result.ochre)) {
|
|
2732
|
-
throw new Error("Failed to fetch website");
|
|
2733
|
-
}
|
|
2734
|
-
const projectIdentification = data.result.ochre.metadata.project?.identification ? parseIdentification(data.result.ochre.metadata.project.identification) : null;
|
|
2735
|
-
const website = await parseWebsite(
|
|
2736
|
-
data.result.ochre.tree,
|
|
2737
|
-
projectIdentification?.label ?? "",
|
|
2738
|
-
data.result.ochre.metadata.project?.identification.website ?? null
|
|
2739
|
-
);
|
|
2740
|
-
return website;
|
|
2741
|
-
} catch (error) {
|
|
2742
|
-
console.error(error);
|
|
2743
|
-
return null;
|
|
2744
2538
|
}
|
|
2745
2539
|
}
|
|
2746
2540
|
export {
|
|
2747
|
-
fetchBibliography,
|
|
2748
2541
|
fetchByUuid,
|
|
2749
|
-
|
|
2750
|
-
fetchGallery,
|
|
2751
|
-
fetchPeriod,
|
|
2752
|
-
fetchPropertyValue,
|
|
2753
|
-
fetchResource,
|
|
2754
|
-
fetchSet,
|
|
2755
|
-
fetchSpatialUnit,
|
|
2756
|
-
fetchTree,
|
|
2757
|
-
fetchWebsite,
|
|
2542
|
+
fetchItem,
|
|
2758
2543
|
filterProperties,
|
|
2759
2544
|
getAllPropertyLabels,
|
|
2760
2545
|
getPropertyByLabel,
|