diff --git a/package-lock.json b/package-lock.json index fc7b7e1..301e82f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -154,7 +154,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -216,7 +215,6 @@ "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -1495,7 +1493,6 @@ "resolved": "https://registry.npmjs.org/@iiif/parser/-/parser-2.2.1.tgz", "integrity": "sha512-pHz4WR+1LXm9VglHmcPKthqOkDRB8YzbDkGJE82wgQyZyh8l0iXQcq9MysSqxK5GuKi8qBaOTTUdiFlb1r2ARA==", "license": "MIT", - "peer": true, "dependencies": { "@iiif/presentation-2": "^1.0.4", "@iiif/presentation-3": "^2.2.2", @@ -1517,7 +1514,6 @@ "resolved": "https://registry.npmjs.org/@iiif/presentation-3/-/presentation-3-2.2.3.tgz", "integrity": "sha512-xCLbUr9euqegsrxGe65M2fWbv6gKpiUhHXCpOn+V+qtawkMbOSNWbYOISo2aLQdYVg4DGYD0g2bMzSCF33uNOQ==", "license": "MIT", - "peer": true, "dependencies": { "@types/geojson": "^7946.0.10" } @@ -4447,7 +4443,6 @@ "integrity": "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -4458,7 +4453,6 @@ "integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==", "devOptional": true, "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^19.0.0" } @@ -4860,7 +4854,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5323,7 +5316,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.2", "caniuse-lite": "^1.0.30001741", @@ -6356,7 +6348,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -6426,7 +6417,6 @@ "integrity": "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -7916,7 +7906,6 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -8798,6 +8787,7 @@ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "license": "MIT", + "peer": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -10977,6 +10967,7 @@ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" } @@ -12339,7 +12330,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -12820,7 +12810,6 @@ "integrity": "sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.44.0", "@typescript-eslint/types": "8.44.0", @@ -13305,7 +13294,6 @@ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -13399,7 +13387,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, diff --git a/src/calculator/v3.ts b/src/calculator/v3.ts index 6e96291..1231fbd 100644 --- a/src/calculator/v3.ts +++ b/src/calculator/v3.ts @@ -31,7 +31,7 @@ export class Calculator extends Base { } super.size(v); const { region, size, upscale } = this._parsedInfo; - if (!upscale) { + if (!upscale && size.fit !== 'inside') { if (size.width > region.width || size.height > region.height) { throw new IIIFError('Requested size requires upscaling', { statusCode: 400 diff --git a/tests/v3/calculator.test.ts b/tests/v3/calculator.test.ts index 0081e6f..56e03ca 100644 --- a/tests/v3/calculator.test.ts +++ b/tests/v3/calculator.test.ts @@ -154,6 +154,40 @@ describe('Calculator', () => { subject.region('pct:50,50,25,25').size('^512,384').rotation('45').quality('default').format('jpg', 600); assert.deepEqual(subject.info(), expected); }); + + it('allows best-fit sizing larger than source without upscaling error', () => { + subject = new Calculator({ width: 1024, height: 768 }); + + // !9000,9000 should not throw even though dimensions exceed source + assert.doesNotThrow(() => { + subject + .region('full') + .size('!9000,9000') + .rotation('0') + .quality('default') + .format('jpg'); + }, IIIFError); + + const result = subject.info(); + assert.equal(result.size.fit, 'inside'); + assert.equal(result.size.width, 9000); + assert.equal(result.size.height, 9000); + assert.equal(result.upscale, false); + }); + + it('throws upscaling error for exact size larger than source', () => { + subject = new Calculator({ width: 1024, height: 768 }); + + // 9000,9000 without ! should throw upscaling error + assert.throws(() => { + subject + .region('full') + .size('9000,9000') + .rotation('0') + .quality('default') + .format('jpg'); + }, IIIFError); + }); }); describe('density', () => {