diff --git a/__tests__/__snapshots__/thumbnail-helper.test.ts.snap b/__tests__/__snapshots__/thumbnail-helper.test.ts.snap new file mode 100644 index 0000000..84743aa --- /dev/null +++ b/__tests__/__snapshots__/thumbnail-helper.test.ts.snap @@ -0,0 +1,189 @@ +// Vitest Snapshot v1 + +exports[`Thumbnail helper > Thumbnail - Canvas with no thumbnail property - ImageService 1`] = ` +[ + { + "best": { + "height": 512, + "id": "https://iiif.io/api/image/2.1/example/reference/918ecd18c2592080851777620de9bcb5-fountain/full/512,/0/default.jpg", + "type": "fixed", + "unsafe": false, + "width": 512, + }, + "fallback": [], + "log": [], + }, + { + "best": { + "height": 512, + "id": "https://iiif.io/api/image/2.1/example/reference/918ecd18c2592080851777620de9bcb5-gottingen/full/512,/0/default.jpg", + "type": "fixed", + "unsafe": false, + "width": 512, + }, + "fallback": [], + "log": [], + }, +] +`; + +exports[`Thumbnail helper > Thumbnail - Canvas with no thumbnail property - level0 image 1`] = ` +[ + { + "best": { + "height": 189, + "id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/tractor/full/252,189/0/default.jpg", + "type": "fixed", + "unsafe": false, + "width": 252, + }, + "fallback": [], + "log": [], + }, + { + "best": { + "height": 189, + "id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/van/full/252,189/0/default.jpg", + "type": "fixed", + "unsafe": false, + "width": 252, + }, + "fallback": [], + "log": [], + }, +] +`; + +exports[`Thumbnail helper > Thumbnail - Canvas with no thumbnail property - simple image 1`] = ` +[ + { + "best": { + "height": 4032, + "id": "https://fixtures.iiif.io/images/Glen/photos/fountain.jpg", + "type": "fixed", + "unsafe": true, + "width": 3024, + }, + "fallback": [], + "log": [], + }, + { + "best": undefined, + "fallback": [], + "log": [], + }, +] +`; + +exports[`Thumbnail helper > Thumbnail - Canvases with thumbnail property which is an image URL 1`] = ` +[ + { + "best": { + "height": 512, + "id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso/full/512,/0/default.jpg", + "type": "fixed", + "unsafe": false, + "width": 512, + }, + "fallback": [ + { + "height": 7230, + "id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso/full/full/0/default.jpg", + "type": "fixed", + "unsafe": true, + "width": 5428, + }, + ], + "log": [], + }, + { + "best": { + "height": 512, + "id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso/full/512,/0/default.jpg", + "type": "fixed", + "unsafe": false, + "width": 512, + }, + "fallback": [ + { + "height": 7230, + "id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso/full/full/0/default.jpg", + "type": "fixed", + "unsafe": true, + "width": 5428, + }, + ], + "log": [], + }, +] +`; + +exports[`Thumbnail helper > Thumbnail - Canvases with thumbnail property which is an image URL with dimensions 1`] = ` +[ + { + "best": { + "height": 512, + "id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso/full/512,/0/default.jpg", + "type": "fixed", + "unsafe": false, + "width": 512, + }, + "fallback": [ + { + "height": 7230, + "id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso/full/full/0/default.jpg", + "type": "fixed", + "unsafe": true, + "width": 5428, + }, + ], + "log": [], + }, + { + "best": { + "height": 512, + "id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso/full/512,/0/default.jpg", + "type": "fixed", + "unsafe": false, + "width": 512, + }, + "fallback": [ + { + "height": 7230, + "id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso/full/full/0/default.jpg", + "type": "fixed", + "unsafe": true, + "width": 5428, + }, + ], + "log": [], + }, +] +`; + +exports[`Thumbnail helper > Thumbnail - Canvases with thumbnail property with level0 image service (Most optimised option) 1`] = ` +[ + { + "best": { + "height": 452, + "id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/titlepage1_verso/full/340,452/0/default.jpg", + "type": "fixed", + "unsafe": false, + "width": 340, + }, + "fallback": [], + "log": [], + }, + { + "best": { + "height": 452, + "id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/titlepage2_verso/full/340,452/0/default.jpg", + "type": "fixed", + "unsafe": false, + "width": 340, + }, + "fallback": [], + "log": [], + }, +] +`; diff --git a/__tests__/thumbnail-helper.test.ts b/__tests__/thumbnail-helper.test.ts new file mode 100644 index 0000000..f8706e5 --- /dev/null +++ b/__tests__/thumbnail-helper.test.ts @@ -0,0 +1,29 @@ +import { thumbnailFixtures } from '../fixtures'; +import { expect, test } from 'vitest'; +import { Vault } from '@iiif/vault'; +import { createThumbnailHelper } from '../src/thumbnail'; +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { ManifestNormalized } from '@iiif/presentation-3'; + +describe('Thumbnail helper', function () { + test.each(thumbnailFixtures as { label: string; description: string }[])(`Thumbnail - $label`, async (fixture) => { + const vault = new Vault(); + const helper = createThumbnailHelper(vault); + const manifestJson: any = JSON.parse( + (await readFile(path.join(process.cwd(), 'fixtures/thumbnails', `${fixture.label}.json`))).toString() + ); + const manifest = await vault.load(manifestJson.id || manifestJson['@id']); + + if (!manifest) { + expect.fail(`Invalid manifest`); + } + + const thumbnails = []; + for (const canvas of manifest.items) { + thumbnails.push(helper.getBestThumbnailAtSize(canvas, { width: 256, height: 256 })); + } + + expect(await Promise.all(thumbnails)).toMatchSnapshot(); + }); +}); diff --git a/fixtures.mjs b/fixtures.mjs new file mode 100644 index 0000000..9ab373f --- /dev/null +++ b/fixtures.mjs @@ -0,0 +1,35 @@ +// Add thumbnail fixtures here. + +// @type any +export const thumbnailFixtures = [ + { + label: 'Canvas with no thumbnail property - ImageService', + url: 'https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/image_service2/manifest.json', + description: 'This is a manifest where there is no thumbnail property but the thumbnail can be generated from the image service.', + }, + { + label: 'Canvas with no thumbnail property - level0 image', + url: 'https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/manifest.json', + description: 'This is a manifest where there is no thumbnail property but the thumbnail can be generated from the level 0 image service.', + }, + { + label: 'Canvas with no thumbnail property - simple image', + url: 'https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/simple_image/manifest.json', + description: 'This is a manifest where there is no thumbnail property. There is a single image painted onto the canvas' + }, + { + label: 'Canvases with thumbnail property which is an image URL', + url: 'https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_url/manifest.json', + description: 'Each canvas has a thumbnail property which is a URL to an image', + }, + { + label: 'Canvases with thumbnail property which is an image URL with dimensions', + url: 'https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_dimensions/manifest.json', + description: 'Each canvas has a thumbnail property which is a URL to an image. The thumbnail property includes a type but no image service' + }, + { + label: 'Canvases with thumbnail property with level0 image service (Most optimised option)', + url: 'https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/manifest.json', + description: 'This is an efficient way of advertising various sizes for a thumbnail and allows a producer to cache copies of thumbnails to make them fast to retrieve.', + }, +]; diff --git a/fixtures/thumbnails/Canvas with no thumbnail property - ImageService.json b/fixtures/thumbnails/Canvas with no thumbnail property - ImageService.json new file mode 100644 index 0000000..27886e6 --- /dev/null +++ b/fixtures/thumbnails/Canvas with no thumbnail property - ImageService.json @@ -0,0 +1,66 @@ +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/image_service2/manifest.json", + "@type": "sc:Manifest", + "label": "No thumb property", + "sequences": [ + { + "@type": "sc:Sequence", + "label": "Default to page order", + "canvases": [ + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/image_service2/canvas/1", + "@type": "sc:Canvas", + "label": "Image 1", + "height": 4032, + "width": 3024, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://iiif.io/api/image/2.1/example/reference/918ecd18c2592080851777620de9bcb5-fountain/full/full/0/default.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 4032, + "width": 3024, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.io/api/image/2.1/example/reference/918ecd18c2592080851777620de9bcb5-fountain", + "profile": "http://iiif.io/api/image/2/level2.json" + } + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/image_service2/canvas/1" + } + ] + }, + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/image_service2/canvas/2", + "@type": "sc:Canvas", + "label": "Image 2", + "height": 4032, + "width": 3024, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://iiif.io/api/image/2.1/example/reference/918ecd18c2592080851777620de9bcb5-gottingen/full/full/0/default.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 4032, + "width": 3024, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.io/api/image/2.1/example/reference/918ecd18c2592080851777620de9bcb5-gottingen", + "profile": "http://iiif.io/api/image/2/level2.json" + } + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/image_service2/canvas/2" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/fixtures/thumbnails/Canvas with no thumbnail property - level0 image.json b/fixtures/thumbnails/Canvas with no thumbnail property - level0 image.json new file mode 100644 index 0000000..355cfc3 --- /dev/null +++ b/fixtures/thumbnails/Canvas with no thumbnail property - level0 image.json @@ -0,0 +1,66 @@ +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/manifest.json", + "@type": "sc:Manifest", + "label": "No thumb property - level 0", + "sequences": [ + { + "@type": "sc:Sequence", + "label": "Default to page order", + "canvases": [ + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/canvas/1", + "@type": "sc:Canvas", + "label": "Image 1", + "height": 3023, + "width": 4031, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/tractor/full/full/0/default.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 3023, + "width": 4031, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/tractor", + "profile": "http://iiif.io/api/image/2/level0.json" + } + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/canvas/1" + } + ] + }, + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/canvas/2", + "@type": "sc:Canvas", + "label": "Image 2", + "height": 3024, + "width": 4032, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/van/full/full/0/default.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 3024, + "width": 4032, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/van", + "profile": "http://iiif.io/api/image/2/level0.json" + } + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/level0/canvas/2" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/fixtures/thumbnails/Canvas with no thumbnail property - simple image.json b/fixtures/thumbnails/Canvas with no thumbnail property - simple image.json new file mode 100644 index 0000000..d8688fd --- /dev/null +++ b/fixtures/thumbnails/Canvas with no thumbnail property - simple image.json @@ -0,0 +1,56 @@ +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/simple_image/manifest.json", + "@type": "sc:Manifest", + "label": "No thumb property - level 0", + "sequences": [ + { + "@type": "sc:Sequence", + "label": "Default to page order", + "canvases": [ + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/simple_image/canvas/1", + "@type": "sc:Canvas", + "label": "Fountain", + "height": 4032, + "width": 3024, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://fixtures.iiif.io/images/Glen/photos/fountain.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 4032, + "width": 3024 + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/simple_image/canvas/1" + } + ] + }, + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/simple_image/canvas/2", + "@type": "Square", + "label": "Image 2", + "height": 3024, + "width": 4032, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://fixtures.iiif.io/images/Glen/photos/gottingen.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 3024, + "width": 4032 + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/no_thum_prop/v2/simple_image/canvas/2" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/fixtures/thumbnails/Canvases with thumbnail property which is an image URL with dimensions.json b/fixtures/thumbnails/Canvases with thumbnail property which is an image URL with dimensions.json new file mode 100644 index 0000000..06cda30 --- /dev/null +++ b/fixtures/thumbnails/Canvases with thumbnail property which is an image URL with dimensions.json @@ -0,0 +1,78 @@ +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_dimensions/manifest.json", + "@type": "sc:Manifest", + "label": "Canvases with thumbnail property which is an image URL with dimensions", + "sequences": [ + { + "@type": "sc:Sequence", + "label": "Default to page order", + "canvases": [ + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_dimensions/canvas/1", + "@type": "sc:Canvas", + "label": "Page 1", + "thumbnail": { + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso/full/512,/0/default.jpg", + "@type": "dctypes:Image", + "height": 682, + "width": 512 + }, + "height": 7230, + "width": 5428, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso/full/full/0/default.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 7230, + "width": 5428, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso", + "profile": "http://iiif.io/api/image/2/level2.json" + } + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_dimensions/canvas/1" + } + ] + }, + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_dimensions/canvas/2", + "@type": "sc:Canvas", + "label": "Page 2", + "thumbnail": { + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso/full/512,/0/default.jpg", + "@type": "dctypes:Image", + "height": 682, + "width": 512 + }, + "height": 7230, + "width": 5428, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso/full/full/0/default.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 7230, + "width": 5428, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso", + "profile": "http://iiif.io/api/image/2/level2.json" + } + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_dimensions/canvas/2" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/fixtures/thumbnails/Canvases with thumbnail property which is an image URL.json b/fixtures/thumbnails/Canvases with thumbnail property which is an image URL.json new file mode 100644 index 0000000..c23e45a --- /dev/null +++ b/fixtures/thumbnails/Canvases with thumbnail property which is an image URL.json @@ -0,0 +1,68 @@ +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_url/manifest.json", + "@type": "sc:Manifest", + "label": "Canvases with thumbnail property which is a image URL", + "sequences": [ + { + "@type": "sc:Sequence", + "label": "Default to page order", + "canvases": [ + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_url/canvas/1", + "@type": "sc:Canvas", + "label": "Page 1", + "thumbnail": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso/full/512,/0/default.jpg", + "height": 7230, + "width": 5428, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso/full/full/0/default.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 7230, + "width": 5428, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso", + "profile": "http://iiif.io/api/image/2/level2.json" + } + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_url/canvas/1" + } + ] + }, + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_url/canvas/2", + "@type": "sc:Canvas", + "label": "Page 2", + "thumbnail": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso/full/512,/0/default.jpg", + "height": 7230, + "width": 5428, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso/full/full/0/default.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 7230, + "width": 5428, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso", + "profile": "http://iiif.io/api/image/2/level2.json" + } + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_url/canvas/2" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/fixtures/thumbnails/Canvases with thumbnail property with level0 image service (Most optimised option).json b/fixtures/thumbnails/Canvases with thumbnail property with level0 image service (Most optimised option).json new file mode 100644 index 0000000..802f9eb --- /dev/null +++ b/fixtures/thumbnails/Canvases with thumbnail property with level0 image service (Most optimised option).json @@ -0,0 +1,145 @@ +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/manifest.json", + "@type": "sc:Manifest", + "label": "Canvases with thumbnail property which is a level0 image service", + "sequences": [ + { + "@type": "sc:Sequence", + "label": "Default to page order", + "canvases": [ + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/canvas/1", + "@type": "sc:Canvas", + "label": "Page 1", + "thumbnail": { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/titlepage1_verso/full/170,/0/default.jpg", + "@type": "dctypes:Image", + "height": 226, + "width": 170, + "service": { + "protocol": "http://iiif.io/api/image", + "sizes": [ + { + "width": 170, + "height": 226 + }, + { + "width": 340, + "height": 452 + }, + { + "width": 679, + "height": 904 + }, + { + "width": 1357, + "height": 1808 + }, + { + "width": 2714, + "height": 3615 + }, + { + "width": 5428, + "height": 7230 + } + ], + "profile": "http://iiif.io/api/image/2/level0.json", + "width": 5428, + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/titlepage1_verso", + "@context": "http://iiif.io/api/image/2/context.json", + "height": 7230 + } + }, + "height": 7230, + "width": 5428, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso/full/full/0/default.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 7230, + "width": 5428, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-4_titlepage1_verso", + "profile": "http://iiif.io/api/image/2/level2.json" + } + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/canvas/1" + } + ] + }, + { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/canvas/2", + "@type": "sc:Canvas", + "label": "Page 2", + "thumbnail": { + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/titlepage2_verso/full/170,/0/default.jpg", + "height": 226, + "width": 170, + "service": { + "protocol": "http://iiif.io/api/image", + "sizes": [ + { + "width": 170, + "height": 226 + }, + { + "width": 340, + "height": 452 + }, + { + "width": 679, + "height": 904 + }, + { + "width": 1357, + "height": 1808 + }, + { + "width": 2714, + "height": 3615 + }, + { + "width": 5428, + "height": 7230 + } + ], + "profile": "http://iiif.io/api/image/2/level0.json", + "width": 5428, + "@id": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/titlepage2_verso", + "@context": "http://iiif.io/api/image/2/context.json", + "height": 7230 + } + }, + "height": 7230, + "width": 5428, + "images": [ + { + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso/full/full/0/default.jpg", + "@type": "dcTypes:Image", + "format": "image/jpeg", + "height": 7230, + "width": 5428, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.io/api/image/2.1/example/reference/15f769d62ca9a3a2deca390efed75d73-6_titlepage2_verso", + "profile": "http://iiif.io/api/image/2/level2.json" + } + }, + "on": "https://iiif-commons.github.io/fixtures/examples/thumbnail/thum_prop/v2/canvas_thum_level0/canvas/2" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json index aea3ba4..d346481 100644 --- a/package.json +++ b/package.json @@ -137,6 +137,7 @@ "eslint-plugin-prettier": "^4.0.0", "happy-dom": "^6.0.3", "jsdom": "^20.0.0", + "node-fetch": "3.3.0", "prettier": "^2.5.1", "react": "17.0.2", "react-i18next": "^11.18.0", diff --git a/src/thumbnail.ts b/src/thumbnail.ts index 185cb95..796a1df 100644 --- a/src/thumbnail.ts +++ b/src/thumbnail.ts @@ -62,7 +62,7 @@ export function createThumbnailHelper(vault: Vault, dependencies: { imageService | CanvasNormalized | AnnotationNormalized | AnnotationPageNormalized - | ContentResource = vault.get(input as any) as any; + | ContentResource = vault.get(input as any, { skipSelfReturn: false }) as any; if (typeof fullInput === 'string') { return { best: getFixedSizeFromImage(fullInput as any), fallback: [], log: [] }; diff --git a/tsconfig.json b/tsconfig.json index f0616a3..1828da9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,7 @@ "moduleResolution": "node", "strict": true, "sourceMap": true, + "allowJs": true, "resolveJsonModule": true, "outDir": "./.build/types", "declaration": true, diff --git a/update-fixtures.mjs b/update-fixtures.mjs new file mode 100644 index 0000000..113049f --- /dev/null +++ b/update-fixtures.mjs @@ -0,0 +1,24 @@ +import { thumbnailFixtures } from "./fixtures.mjs"; +import fetch from 'node-fetch'; +import { mkdir, writeFile } from 'node:fs/promises'; +import * as path from 'node:path'; + +async function main() { + await mkdir(path.join('./fixtures', 'thumbnails'), { recursive: true }); + const promises = []; + + for (const fixture of thumbnailFixtures) { + + promises.push((async () => { + const text = await (await fetch(fixture.url)).text(); + await writeFile(path.join('./fixtures', 'thumbnails', `${fixture.label}.json`), text); + })()) + // + } + + await Promise.all(promises); +} + +main().then(() => { + console.log('Done!'); +}); diff --git a/yarn.lock b/yarn.lock index 29c4da5..82d9ad9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2106,6 +2106,15 @@ node-domexception@^1.0.0: resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== +node-fetch@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.0.tgz#37e71db4ecc257057af828d523a7243d651d91e4" + integrity sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + node-fetch@^2.x.x: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"