@allmaps/iiif-parser
Version:
Allmaps IIIF parser
99 lines (98 loc) • 3.05 kB
JavaScript
import { z } from 'zod';
export const LanguageString3Schema = z.record(z.string(), z.string().array());
export const MetadataStringItem3Schema = z.object({
label: LanguageString3Schema.optional(),
value: LanguageString3Schema.optional()
});
// type MetadataString3Type = z.infer<typeof MetadataString3Schema>
export function parseVersion2String(str) {
// TODO: use type guards!
if (typeof str === 'string' ||
typeof str === 'number' ||
typeof str === 'boolean') {
return {
none: [String(str)]
};
}
else if (Array.isArray(str)) {
let strings = {};
str.forEach((item) => {
if (typeof item === 'string' ||
typeof item === 'number' ||
typeof item === 'boolean') {
if (!strings['none']) {
strings['none'] = [];
}
strings['none'].push(String(item));
}
else if (typeof item === 'object') {
// TODO: find test input data for this scenario
strings = { ...strings, ...parseVersion2String(item) };
}
else {
throw new Error('Unable to parse string');
}
});
return strings;
}
else if (str && typeof str === 'object') {
const language = str['@language'] || 'none';
const value = String(str['@value']);
return {
[language]: Array.isArray(value) ? value : [value]
};
}
else {
throw new Error('Unable to parse string');
}
}
export function parseVersion3String(str) {
if (!str) {
return;
}
const parsedStr = {};
for (const language in str) {
parsedStr[language] = str[language].map((item) => String(item));
}
return parsedStr;
}
export function parseVersion2Metadata(metadata) {
if (Array.isArray(metadata)) {
if (metadata.length === 0) {
return undefined;
}
return (metadata
// Only process metadata entries that have both label & value
.filter((entry) => entry)
.filter(({ label, value }) => label && value)
.map(({ label, value }) => ({
label: parseVersion2String(label),
value: parseVersion2String(value)
})));
}
else if (!metadata) {
return undefined;
}
else {
throw new Error('Unable to parse metadata');
}
}
export function filterInvalidMetadata(metadata) {
if (!metadata) {
return undefined;
}
// TODO: I don't know why TypeScript complains about
// a simple filter function. For now, do this:
const filteredMetadata = [];
for (const item of metadata) {
const label = parseVersion3String(item.label);
const value = parseVersion3String(item.value);
if (label && value) {
filteredMetadata.push({
label,
value
});
}
}
return filteredMetadata;
}