UNPKG

@allmaps/iiif-parser

Version:

Allmaps IIIF parser

168 lines (167 loc) 5.93 kB
// Presentation API 3.0 - Manifest // https://iiif.io/api/presentation/3.0/#52-manifest import { z } from 'zod'; import { ImageServiceSchema } from './image-service.js'; import { NavDateSchema, NavPlaceSchema } from '../schemas/shared.js'; import { ensureArray } from '../lib/convert.js'; export const SingleValue3Schema = z .union([z.string(), z.number(), z.boolean()]) .transform((val) => String(val)); export const LanguageValue3Schema = z.record(z.string(), SingleValue3Schema.array()); export const Summary3Schema = LanguageValue3Schema; export const HomepageItem3Schema = z.object({ id: z.string().url(), type: z.string().optional(), label: LanguageValue3Schema, format: z.string().optional(), language: z.union([z.string(), z.array(z.string())]).optional() }); export const Rendering3ItemSchema = z.object({ id: z.string().url(), type: z.string().optional(), label: LanguageValue3Schema, format: z.string().optional() }); export const Rendering3Schema = z .union([Rendering3ItemSchema.array(), Rendering3ItemSchema]) .transform(ensureArray); export const Homepage3Schema = z .union([HomepageItem3Schema.array(), HomepageItem3Schema]) .transform(ensureArray); export const ThumbnailItem3Schema = z.object({ id: z.string().url(), type: z.string().optional(), format: z.string().optional(), width: z.number().int().optional(), height: z.number().int().optional() }); export const Thumbnail3Schema = z .union([ThumbnailItem3Schema.array(), ThumbnailItem3Schema]) .transform(ensureArray); export const SeeAlsoItem3Schema = z.object({ id: z.string().url(), type: z.string().optional(), format: z.string().optional(), profile: z.string().optional() }); export const SeeAlso3Schema = z .union([SeeAlsoItem3Schema.array(), SeeAlsoItem3Schema]) .transform(ensureArray); export const NonPaintingAnnotations3 = z .object({ id: z.string().url(), type: z.literal('AnnotationPage'), items: z.object({}).passthrough().array().optional() }) .array(); const ValidMetadataItem3Schema = z.object({ label: LanguageValue3Schema, value: LanguageValue3Schema }); export const MetadataItem3Schema = z .union([ ValidMetadataItem3Schema, // Catchall for incorrect values z.any() ]) .transform((val) => { const { success, data } = ValidMetadataItem3Schema.safeParse(val); if (success) { return data; } }); export const Metadata3Schema = MetadataItem3Schema.array(); export const RequiredStatement3Schema = MetadataItem3Schema; export const AnnotationBody3Schema = z.object({ type: z.literal('Image'), width: z.number().int().optional(), height: z.number().int().optional(), service: ImageServiceSchema.array() }); const Choice3Schema = z.object({ type: z.literal('Choice'), items: AnnotationBody3Schema.array() }); const Annotation3Schema = z.object({ type: z.literal('Annotation'), body: z.union([ AnnotationBody3Schema, AnnotationBody3Schema.array().length(1), Choice3Schema ]) }); const AnnotationPage3Schema = z.object({ type: z.literal('AnnotationPage'), items: Annotation3Schema.array().length(1) }); export const Canvas3Schema = z.object({ id: z.string().url(), type: z.literal('Canvas'), width: z.number().int(), height: z.number().int(), items: AnnotationPage3Schema.array().length(1), label: LanguageValue3Schema.optional(), description: LanguageValue3Schema.optional(), metadata: Metadata3Schema.optional(), navDate: NavDateSchema.optional(), navPlace: NavPlaceSchema.optional(), homepage: Homepage3Schema.optional(), thumbnail: Thumbnail3Schema.optional(), rendering: Rendering3Schema.optional(), seeAlso: SeeAlso3Schema.optional(), summary: Summary3Schema.optional(), requiredStatement: RequiredStatement3Schema.optional(), annotations: NonPaintingAnnotations3.optional() }); export const Manifest3Schema = z.object({ id: z.string().url(), type: z.literal('Manifest'), items: Canvas3Schema.array().nonempty(), label: LanguageValue3Schema.optional(), description: LanguageValue3Schema.optional(), metadata: Metadata3Schema.optional(), navDate: NavDateSchema.optional(), navPlace: NavPlaceSchema.optional(), homepage: Homepage3Schema.optional(), thumbnail: Thumbnail3Schema.optional(), rendering: Rendering3Schema.optional(), seeAlso: SeeAlso3Schema.optional(), summary: Summary3Schema.optional(), requiredStatement: RequiredStatement3Schema.optional(), annotations: NonPaintingAnnotations3.optional() }); // @ts-expect-error - Lazy type is not correctly inferred export const EmbeddedManifest3Schema = z.lazy(() => z.object({ id: z.string().url(), type: z.literal('Manifest'), label: LanguageValue3Schema.optional() })); // @ts-expect-error - Lazy type is not correctly inferred export const Collection3Schema = z.lazy(() => z.object({ id: z.string().url(), type: z.literal('Collection'), items: z .union([ EmbeddedManifest3Schema, Collection3Schema, EmbeddedCollection3Schema ]) .array(), label: LanguageValue3Schema.optional(), description: LanguageValue3Schema.optional(), metadata: Metadata3Schema.optional(), navDate: NavDateSchema.optional(), navPlace: NavPlaceSchema.optional(), homepage: Homepage3Schema.optional(), thumbnail: Thumbnail3Schema.optional(), rendering: Rendering3Schema.optional(), seeAlso: SeeAlso3Schema.optional(), summary: Summary3Schema.optional(), requiredStatement: RequiredStatement3Schema.optional(), annotations: NonPaintingAnnotations3.optional() })); export const EmbeddedCollection3Schema = z.object({ id: z.string().url(), type: z.literal('Collection'), label: LanguageValue3Schema.optional() });