diff --git a/.changeset/pink-tigers-smash.md b/.changeset/pink-tigers-smash.md new file mode 100644 index 00000000..58eb9d69 --- /dev/null +++ b/.changeset/pink-tigers-smash.md @@ -0,0 +1,5 @@ +--- +"@imgproxy/imgproxy-js-core": minor +--- + +Add `smart_subsample` to `webp_options` diff --git a/src/options/webpOptions.ts b/src/options/webpOptions.ts index 04790a95..9b4f113d 100644 --- a/src/options/webpOptions.ts +++ b/src/options/webpOptions.ts @@ -1,5 +1,5 @@ import type { WebpOptions, WebpOptionsPartial } from "../types/webpOptions"; -import { guardIsUndef, guardIsValidVal } from "../utils"; +import { guardIsNotBool, guardIsUndef, guardIsValidVal } from "../utils"; const correctOptions = { lossy: true, @@ -14,11 +14,24 @@ const test = (options: WebpOptionsPartial): boolean => Boolean(getOpt(options)); const build = (options: WebpOptionsPartial): string => { const webpOptions = getOpt(options); + let compression: string, smart_subsample: boolean | undefined; guardIsUndef(webpOptions, "webp_options"); - guardIsValidVal(correctOptions, webpOptions, "webp_options"); - return `webpo:${webpOptions}`; + if (typeof webpOptions === "string") { + compression = webpOptions; + } else { + compression = webpOptions.compression; + + if (webpOptions.smart_subsample !== undefined) { + smart_subsample = webpOptions.smart_subsample; + guardIsNotBool(smart_subsample, "webp_options.smart_subsample"); + } + } + + guardIsValidVal(correctOptions, compression, "webp_options"); + + return `webpo:${compression}${smart_subsample !== undefined ? `:${smart_subsample}` : ""}`; }; export { test, build }; diff --git a/src/types/webpOptions.ts b/src/types/webpOptions.ts index fa7cebca..b49c759b 100644 --- a/src/types/webpOptions.ts +++ b/src/types/webpOptions.ts @@ -1,8 +1,4 @@ /** - * *WEBP options*. **PRO feature** - * - * Allows redefining WebP saving options. - * * Available values: * - `"lossy"` - (default) lossy compression. The lossy compression is based on VP8 key frame encoding. * VP8 is a video compression format created by On2 Technologies as a successor to the VP6 and VP7 formats. @@ -15,11 +11,27 @@ * For the entropy coding we use a variant of LZ77-Huffman coding, which uses 2D encoding of distance values * and compact sparse values. * + */ +type WebPCompressionOptions = "lossy" | "near_lossless" | "lossless"; + +/** + * *WEBP options*. **PRO feature** + * + * Allows redefining WebP saving options. + * * @default "lossy" * * @see {@link https://docs.imgproxy.net/generating_the_url?id=webp-options | WEBP options imgproxy docs} */ -type WebpOptions = "lossy" | "near_lossless" | "lossless"; +type WebpOptions = + | WebPCompressionOptions + | { + compression: WebPCompressionOptions; + /** + * when `true`, enables smart subsampling. Smart subsampling increases the resulting file size and compression time but improves quality. Default: `false` + */ + smart_subsample?: boolean; + }; /** * *WEBP options option*. **PRO feature** diff --git a/tests/optionsBasic/webpOptions.test.ts b/tests/optionsBasic/webpOptions.test.ts index 71bae84a..6bd0df45 100644 --- a/tests/optionsBasic/webpOptions.test.ts +++ b/tests/optionsBasic/webpOptions.test.ts @@ -42,5 +42,21 @@ describe("webpOptions", () => { it("should return webpo:near_lossless if webpo option is near_lossless", () => { expect(build({ webpo: "near_lossless" })).toEqual("webpo:near_lossless"); }); + + it("should support `smart_subsample` option", () => { + expect(build({ webp_options: { compression: "lossy" } })).toEqual( + "webpo:lossy" + ); + + expect( + build({ webp_options: { compression: "lossy", smart_subsample: true } }) + ).toEqual("webpo:lossy:true"); + + expect( + build({ + webp_options: { compression: "lossy", smart_subsample: false }, + }) + ).toEqual("webpo:lossy:false"); + }); }); });