@digitalculture/ochre-sdk 0.5.19 → 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 +464 -667
- package/dist/index.d.cts +58 -357
- package/dist/index.d.ts +58 -357
- package/dist/index.js +463 -657
- 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;
|
|
@@ -288,251 +474,43 @@ function parseStringDocumentItem(item, footnotes) {
|
|
|
288
474
|
returnString = parseWhitespace(parseEmail(returnString), item.whitespace);
|
|
289
475
|
}
|
|
290
476
|
}
|
|
291
|
-
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
|
-
);
|
|
477
|
+
return returnString.replaceAll(/^(\d+)\./gm, String.raw`$1\.`);
|
|
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
|
|
536
514
|
function parseIdentification(identification) {
|
|
537
515
|
try {
|
|
538
516
|
const returnIdentification = {
|
|
@@ -1117,54 +1095,83 @@ function parseTree(tree) {
|
|
|
1117
1095
|
return returnTree;
|
|
1118
1096
|
}
|
|
1119
1097
|
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
|
-
|
|
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
|
+
}
|
|
1164
1170
|
}
|
|
1165
1171
|
return {
|
|
1166
1172
|
uuid: set.uuid,
|
|
1167
1173
|
category: "set",
|
|
1174
|
+
itemCategory,
|
|
1168
1175
|
publicationDateTime: set.publicationDateTime ? new Date(set.publicationDateTime) : null,
|
|
1169
1176
|
date: set.date != null ? new Date(set.date) : null,
|
|
1170
1177
|
license: parseLicense(set.availability),
|
|
@@ -1176,18 +1183,10 @@ function parseSet(set) {
|
|
|
1176
1183
|
) : [],
|
|
1177
1184
|
type: set.type,
|
|
1178
1185
|
number: set.n,
|
|
1179
|
-
items
|
|
1180
|
-
resources,
|
|
1181
|
-
spatialUnits,
|
|
1182
|
-
concepts,
|
|
1183
|
-
periods,
|
|
1184
|
-
bibliographies,
|
|
1185
|
-
persons,
|
|
1186
|
-
propertyValues
|
|
1187
|
-
}
|
|
1186
|
+
items
|
|
1188
1187
|
};
|
|
1189
1188
|
}
|
|
1190
|
-
function parseResource(resource
|
|
1189
|
+
function parseResource(resource) {
|
|
1191
1190
|
const returnResource = {
|
|
1192
1191
|
uuid: resource.uuid,
|
|
1193
1192
|
category: "resource",
|
|
@@ -1230,34 +1229,20 @@ function parseResource(resource, isNested = false) {
|
|
|
1230
1229
|
Array.isArray(resource.citedBibliography.reference) ? resource.citedBibliography.reference : [resource.citedBibliography.reference]
|
|
1231
1230
|
) : [],
|
|
1232
1231
|
resources: resource.resource ? parseResources(
|
|
1233
|
-
Array.isArray(resource.resource) ? resource.resource : [resource.resource]
|
|
1234
|
-
true
|
|
1232
|
+
Array.isArray(resource.resource) ? resource.resource : [resource.resource]
|
|
1235
1233
|
) : []
|
|
1236
1234
|
};
|
|
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
1235
|
return returnResource;
|
|
1251
1236
|
}
|
|
1252
|
-
function parseResources(resources
|
|
1237
|
+
function parseResources(resources) {
|
|
1253
1238
|
const returnResources = [];
|
|
1254
1239
|
const resourcesToParse = Array.isArray(resources) ? resources : [resources];
|
|
1255
1240
|
for (const resource of resourcesToParse) {
|
|
1256
|
-
returnResources.push(parseResource(resource
|
|
1241
|
+
returnResources.push(parseResource(resource));
|
|
1257
1242
|
}
|
|
1258
1243
|
return returnResources;
|
|
1259
1244
|
}
|
|
1260
|
-
function parseSpatialUnit(spatialUnit
|
|
1245
|
+
function parseSpatialUnit(spatialUnit) {
|
|
1261
1246
|
const returnSpatialUnit = {
|
|
1262
1247
|
uuid: spatialUnit.uuid,
|
|
1263
1248
|
category: "spatialUnit",
|
|
@@ -1277,34 +1262,22 @@ function parseSpatialUnit(spatialUnit, isNested = false) {
|
|
|
1277
1262
|
) : spatialUnit.observation ? [parseObservation(spatialUnit.observation)] : [],
|
|
1278
1263
|
events: "events" in spatialUnit && spatialUnit.events ? parseEvents(
|
|
1279
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]
|
|
1280
1268
|
) : []
|
|
1281
1269
|
};
|
|
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
1270
|
return returnSpatialUnit;
|
|
1296
1271
|
}
|
|
1297
|
-
function parseSpatialUnits(spatialUnits
|
|
1272
|
+
function parseSpatialUnits(spatialUnits) {
|
|
1298
1273
|
const returnSpatialUnits = [];
|
|
1299
1274
|
const spatialUnitsToParse = Array.isArray(spatialUnits) ? spatialUnits : [spatialUnits];
|
|
1300
1275
|
for (const spatialUnit of spatialUnitsToParse) {
|
|
1301
|
-
returnSpatialUnits.push(
|
|
1302
|
-
parseSpatialUnit(spatialUnit, isNested)
|
|
1303
|
-
);
|
|
1276
|
+
returnSpatialUnits.push(parseSpatialUnit(spatialUnit));
|
|
1304
1277
|
}
|
|
1305
1278
|
return returnSpatialUnits;
|
|
1306
1279
|
}
|
|
1307
|
-
function parseConcept(concept
|
|
1280
|
+
function parseConcept(concept) {
|
|
1308
1281
|
const returnConcept = {
|
|
1309
1282
|
uuid: concept.uuid,
|
|
1310
1283
|
category: "concept",
|
|
@@ -1317,17 +1290,6 @@ function parseConcept(concept, isNested = false) {
|
|
|
1317
1290
|
Array.isArray(concept.interpretations.interpretation) ? concept.interpretations.interpretation : [concept.interpretations.interpretation]
|
|
1318
1291
|
)
|
|
1319
1292
|
};
|
|
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
1293
|
return returnConcept;
|
|
1332
1294
|
}
|
|
1333
1295
|
var parseWebpageResources = async (webpageResources, type) => {
|
|
@@ -1370,11 +1332,11 @@ var parseWebpageResources = async (webpageResources, type) => {
|
|
|
1370
1332
|
}
|
|
1371
1333
|
return returnElements;
|
|
1372
1334
|
};
|
|
1373
|
-
function parseConcepts(concepts
|
|
1335
|
+
function parseConcepts(concepts) {
|
|
1374
1336
|
const returnConcepts = [];
|
|
1375
1337
|
const conceptsToParse = Array.isArray(concepts) ? concepts : [concepts];
|
|
1376
1338
|
for (const concept of conceptsToParse) {
|
|
1377
|
-
returnConcepts.push(parseConcept(concept
|
|
1339
|
+
returnConcepts.push(parseConcept(concept));
|
|
1378
1340
|
}
|
|
1379
1341
|
return returnConcepts;
|
|
1380
1342
|
}
|
|
@@ -1395,11 +1357,11 @@ async function parseWebElementProperties(componentProperty, elementResource) {
|
|
|
1395
1357
|
if (document === null) {
|
|
1396
1358
|
const documentLink = links.find((link) => link.type === "internalDocument");
|
|
1397
1359
|
if (documentLink) {
|
|
1398
|
-
const
|
|
1399
|
-
if (
|
|
1360
|
+
const { item, error } = await fetchItem(documentLink.uuid, "resource");
|
|
1361
|
+
if (error !== null) {
|
|
1400
1362
|
throw new Error("Failed to fetch OCHRE data");
|
|
1401
1363
|
}
|
|
1402
|
-
document =
|
|
1364
|
+
document = item.document;
|
|
1403
1365
|
}
|
|
1404
1366
|
}
|
|
1405
1367
|
switch (componentName) {
|
|
@@ -2440,300 +2402,144 @@ async function parseWebsite(websiteTree, projectName, website) {
|
|
|
2440
2402
|
};
|
|
2441
2403
|
}
|
|
2442
2404
|
|
|
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) {
|
|
2405
|
+
// src/utils/fetchers/uuid.ts
|
|
2406
|
+
async function fetchByUuid(uuid) {
|
|
2510
2407
|
try {
|
|
2511
|
-
const
|
|
2512
|
-
if (!parsed.success) {
|
|
2513
|
-
throw new Error(parsed.error.message);
|
|
2514
|
-
}
|
|
2408
|
+
const parsedUuid = uuidSchema.parse(uuid);
|
|
2515
2409
|
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`
|
|
2410
|
+
`https://ochre.lib.uchicago.edu/ochre?uuid=${parsedUuid}&format=json&lang="*"`
|
|
2526
2411
|
);
|
|
2527
2412
|
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");
|
|
2413
|
+
throw new Error("Failed to fetch OCHRE data");
|
|
2533
2414
|
}
|
|
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);
|
|
2415
|
+
const dataRaw = await response.json();
|
|
2416
|
+
if (!("ochre" in dataRaw)) {
|
|
2417
|
+
throw new Error("Invalid OCHRE data: API response missing 'ochre' key");
|
|
2559
2418
|
}
|
|
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 };
|
|
2419
|
+
return [null, dataRaw];
|
|
2575
2420
|
} catch (error) {
|
|
2576
|
-
|
|
2577
|
-
return null;
|
|
2421
|
+
return [error instanceof Error ? error.message : "Unknown error", null];
|
|
2578
2422
|
}
|
|
2579
2423
|
}
|
|
2580
2424
|
|
|
2581
|
-
// src/utils/fetchers/
|
|
2582
|
-
async function
|
|
2425
|
+
// src/utils/fetchers/item.ts
|
|
2426
|
+
async function fetchItem(uuid, category) {
|
|
2583
2427
|
try {
|
|
2584
|
-
const [error,
|
|
2428
|
+
const [error, data] = await fetchByUuid(uuid);
|
|
2585
2429
|
if (error !== null) {
|
|
2586
2430
|
throw new Error(error);
|
|
2587
2431
|
}
|
|
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
|
-
|
|
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
|
+
}
|
|
2617
2517
|
}
|
|
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
|
|
2518
|
+
const metadata = parseMetadata(data.ochre.metadata);
|
|
2519
|
+
const belongsTo = {
|
|
2520
|
+
uuid: data.ochre.uuidBelongsTo,
|
|
2521
|
+
abbreviation: parseFakeString(data.ochre.belongsTo)
|
|
2631
2522
|
};
|
|
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
|
|
2523
|
+
return {
|
|
2524
|
+
error: null,
|
|
2525
|
+
metadata,
|
|
2526
|
+
belongsTo,
|
|
2527
|
+
item,
|
|
2528
|
+
category
|
|
2661
2529
|
};
|
|
2662
|
-
return { metadata: data.metadata, spatialUnit: data.item };
|
|
2663
2530
|
} 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
|
|
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
|
|
2692
2537
|
};
|
|
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
2538
|
}
|
|
2724
2539
|
}
|
|
2725
2540
|
export {
|
|
2726
|
-
fetchBibliography,
|
|
2727
2541
|
fetchByUuid,
|
|
2728
|
-
|
|
2729
|
-
fetchGallery,
|
|
2730
|
-
fetchPeriod,
|
|
2731
|
-
fetchPropertyValue,
|
|
2732
|
-
fetchResource,
|
|
2733
|
-
fetchSet,
|
|
2734
|
-
fetchSpatialUnit,
|
|
2735
|
-
fetchTree,
|
|
2736
|
-
fetchWebsite,
|
|
2542
|
+
fetchItem,
|
|
2737
2543
|
filterProperties,
|
|
2738
2544
|
getAllPropertyLabels,
|
|
2739
2545
|
getPropertyByLabel,
|