From e1a5c4269683c0762ef416b034552fbc42699ce1 Mon Sep 17 00:00:00 2001 From: Julian Benegas Date: Tue, 19 Nov 2024 18:36:21 -0300 Subject: [PATCH 1/6] add basehub support --- data/domains.json | 3 +- demo/src/examples.json | 4 ++ src/parse.ts | 2 + src/transform.ts | 2 + src/transformers/basehub.test.ts | 117 +++++++++++++++++++++++++++++++ src/transformers/basehub.ts | 50 +++++++++++++ src/types.ts | 3 +- 7 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 src/transformers/basehub.test.ts create mode 100644 src/transformers/basehub.ts diff --git a/data/domains.json b/data/domains.json index 2ae07b9..79bcd29 100644 --- a/data/domains.json +++ b/data/domains.json @@ -11,5 +11,6 @@ "assets.caisy.io": "bunny", "images.contentstack.io": "contentstack", "ucarecdn.com": "uploadcare", - "imagedelivery.net": "cloudflare_images" + "imagedelivery.net": "cloudflare_images", + "assets.basehub.com": "basehub" } diff --git a/demo/src/examples.json b/demo/src/examples.json index fc865e6..f4e752c 100644 --- a/demo/src/examples.json +++ b/demo/src/examples.json @@ -87,5 +87,9 @@ "hygraph": [ "Hygraph", "https://us-west-2.graphassets.com/cm2apl1zp07l506n66dmd9xo8/cm2tr64fx7gvu07n85chjmuno" + ], + "basehub": [ + "BaseHub", + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg" ] } diff --git a/src/parse.ts b/src/parse.ts index 4e8892c..132e14d 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -25,6 +25,7 @@ import { parse as imagekit } from "./transformers/imagekit.ts"; import { parse as uploadcare } from "./transformers/uploadcare.ts"; import { parse as supabase } from "./transformers/supabase.ts"; import { parse as hygraph } from "./transformers/hygraph.ts"; +import { parse as basehub } from "./transformers/basehub.ts"; import { ImageCdn, ParsedUrl, SupportedImageCdn, UrlParser } from "./types.ts"; export const parsers = { @@ -54,6 +55,7 @@ export const parsers = { uploadcare, supabase, hygraph, + basehub, }; export const cdnIsSupportedForParse = ( diff --git a/src/transform.ts b/src/transform.ts index bc3d387..e74f49c 100644 --- a/src/transform.ts +++ b/src/transform.ts @@ -25,6 +25,7 @@ import { transform as imagekit } from "./transformers/imagekit.ts"; import { transform as uploadcare } from "./transformers/uploadcare.ts"; import { transform as supabase } from "./transformers/supabase.ts"; import { transform as hygraph } from "./transformers/hygraph.ts"; +import { transform as basehub } from "./transformers/basehub.ts"; import { ImageCdn, UrlTransformer } from "./types.ts"; import { getCanonicalCdnForUrl } from "./canonical.ts"; @@ -55,6 +56,7 @@ export const getTransformer = (cdn: ImageCdn) => ({ uploadcare, supabase, hygraph, + basehub, }[cdn]); /** diff --git a/src/transformers/basehub.test.ts b/src/transformers/basehub.test.ts new file mode 100644 index 0000000..ac10063 --- /dev/null +++ b/src/transformers/basehub.test.ts @@ -0,0 +1,117 @@ +import { assertEquals } from "jsr:@std/assert"; + +import { transform } from "./basehub.ts"; + +const img = + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg"; + +Deno.test("basehub", async (t) => { + await t.step("should format a URL", () => { + const result = transform({ + url: img, + width: 200, + height: 100, + }); + assertEquals( + result?.toString(), + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=200&h=100", + ); + }); + await t.step("should not set height if not provided", () => { + const result = transform({ url: img, width: 200 }); + assertEquals( + result?.toString(), + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=200", + ); + }); + await t.step("should delete height if not set", () => { + const url = new URL(img); + url.searchParams.set("h", "100"); + const result = transform({ url, width: 200 }); + assertEquals( + result?.toString(), + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=200", + ); + }); + + await t.step("should round non-integer params", () => { + const result = transform({ + url: img, + width: 200.6, + height: 100.2, + format: "webp", + }); + assertEquals( + result?.toString(), + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=201&h=100&format=webp", + ); + }); + + await t.step("should not set fit=fill if another value exists", () => { + const url = new URL(img); + url.searchParams.set("fit", "crop"); + const result = transform({ url, width: 200 }); + assertEquals( + result?.toString(), + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?fit=crop&w=200", + ); + }); + + await t.step("should bracket width if > 4000", () => { + const result = transform({ + url: img, + width: 5000, + }); + assertEquals( + result?.toString(), + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=4000", + ); + }); + + await t.step("should adjust height proportionally if width > 4000", () => { + const result = transform({ + url: img, + width: 5000, + height: 2000, + }); + assertEquals( + result?.toString(), + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=4000&h=1600", + ); + }); + + await t.step("should bracket height if > 4000", () => { + const result = transform({ + url: img, + height: 5000, + }); + assertEquals( + result?.toString(), + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?h=4000", + ); + }); + + await t.step("should adjust width proportionally if height > 4000", () => { + const result = transform({ + url: img, + width: 2000, + height: 5000, + }); + assertEquals( + result?.toString(), + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=1600&h=4000", + ); + }); + + await t.step("it should adjust width and height if both are > 4000", () => { + const result = transform({ + url: img, + width: 6000, + height: 4500, + }); + assertEquals( + result?.toString(), + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=4000&h=3000", + ); + }); +}); diff --git a/src/transformers/basehub.ts b/src/transformers/basehub.ts new file mode 100644 index 0000000..96cb78f --- /dev/null +++ b/src/transformers/basehub.ts @@ -0,0 +1,50 @@ +import { UrlParser, UrlTransformer } from "../types.ts"; +import { + getNumericParam, + setParamIfDefined, + setParamIfUndefined, + toUrl, +} from "../utils.ts"; + +export const parse: UrlParser<{ fit?: string }> = (url) => { + const parsedUrl = toUrl(url); + + const fit = parsedUrl.searchParams.get("fit") || undefined; + const width = getNumericParam(parsedUrl, "w"); + const height = getNumericParam(parsedUrl, "h"); + const quality = getNumericParam(parsedUrl, "q"); + const format = parsedUrl.searchParams.get("format") || undefined; + parsedUrl.search = ""; + return { + width, + height, + format, + base: parsedUrl.toString(), + params: { fit, quality }, + cdn: "contentful", + }; +}; + +export const transform: UrlTransformer = ( + { url: originalUrl, width, height, format }, +) => { + const url = toUrl(originalUrl); + if (width && width > 4000) { + if (height) { + height = Math.round(height * 4000 / width); + } + width = 4000; + } + + if (height && height > 4000) { + if (width) { + width = Math.round(width * 4000 / height); + } + height = 4000; + } + + setParamIfDefined(url, "w", width, true, true); + setParamIfDefined(url, "h", height, true, true); + setParamIfDefined(url, "format", format); + return url; +}; diff --git a/src/types.ts b/src/types.ts index 8fc70bc..cd8fd15 100644 --- a/src/types.ts +++ b/src/types.ts @@ -101,6 +101,7 @@ export type ImageCdn = | "imagekit" | "uploadcare" | "supabase" - | "hygraph"; + | "hygraph" + | "basehub"; export type SupportedImageCdn = ImageCdn; From 03e2b8ab5e37520005d25728fc977635e0738f28 Mon Sep 17 00:00:00 2001 From: Julian Benegas Date: Tue, 19 Nov 2024 18:45:10 -0300 Subject: [PATCH 2/6] fix --- src/transformers/basehub.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/basehub.ts b/src/transformers/basehub.ts index 96cb78f..1347bd6 100644 --- a/src/transformers/basehub.ts +++ b/src/transformers/basehub.ts @@ -21,7 +21,7 @@ export const parse: UrlParser<{ fit?: string }> = (url) => { format, base: parsedUrl.toString(), params: { fit, quality }, - cdn: "contentful", + cdn: "basehub", }; }; From 29e722cd9787b43520433d2e879b3280a58c38d7 Mon Sep 17 00:00:00 2001 From: Julian Benegas Date: Tue, 19 Nov 2024 18:56:09 -0300 Subject: [PATCH 3/6] add fit query param --- src/transformers/basehub.test.ts | 69 +------------------------------- src/transformers/basehub.ts | 20 +++------ 2 files changed, 7 insertions(+), 82 deletions(-) diff --git a/src/transformers/basehub.test.ts b/src/transformers/basehub.test.ts index ac10063..1ef0aa5 100644 --- a/src/transformers/basehub.test.ts +++ b/src/transformers/basehub.test.ts @@ -24,6 +24,7 @@ Deno.test("basehub", async (t) => { "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=200", ); }); + await t.step("should delete height if not set", () => { const url = new URL(img); url.searchParams.set("h", "100"); @@ -46,72 +47,4 @@ Deno.test("basehub", async (t) => { "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=201&h=100&format=webp", ); }); - - await t.step("should not set fit=fill if another value exists", () => { - const url = new URL(img); - url.searchParams.set("fit", "crop"); - const result = transform({ url, width: 200 }); - assertEquals( - result?.toString(), - "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?fit=crop&w=200", - ); - }); - - await t.step("should bracket width if > 4000", () => { - const result = transform({ - url: img, - width: 5000, - }); - assertEquals( - result?.toString(), - "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=4000", - ); - }); - - await t.step("should adjust height proportionally if width > 4000", () => { - const result = transform({ - url: img, - width: 5000, - height: 2000, - }); - assertEquals( - result?.toString(), - "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=4000&h=1600", - ); - }); - - await t.step("should bracket height if > 4000", () => { - const result = transform({ - url: img, - height: 5000, - }); - assertEquals( - result?.toString(), - "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?h=4000", - ); - }); - - await t.step("should adjust width proportionally if height > 4000", () => { - const result = transform({ - url: img, - width: 2000, - height: 5000, - }); - assertEquals( - result?.toString(), - "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=1600&h=4000", - ); - }); - - await t.step("it should adjust width and height if both are > 4000", () => { - const result = transform({ - url: img, - width: 6000, - height: 4500, - }); - assertEquals( - result?.toString(), - "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=4000&h=3000", - ); - }); }); diff --git a/src/transformers/basehub.ts b/src/transformers/basehub.ts index 1347bd6..41422b3 100644 --- a/src/transformers/basehub.ts +++ b/src/transformers/basehub.ts @@ -9,7 +9,7 @@ import { export const parse: UrlParser<{ fit?: string }> = (url) => { const parsedUrl = toUrl(url); - const fit = parsedUrl.searchParams.get("fit") || undefined; + const fit = parsedUrl.searchParams.get("fit") || 'cover'; const width = getNumericParam(parsedUrl, "w"); const height = getNumericParam(parsedUrl, "h"); const quality = getNumericParam(parsedUrl, "q"); @@ -29,22 +29,14 @@ export const transform: UrlTransformer = ( { url: originalUrl, width, height, format }, ) => { const url = toUrl(originalUrl); - if (width && width > 4000) { - if (height) { - height = Math.round(height * 4000 / width); - } - width = 4000; - } - - if (height && height > 4000) { - if (width) { - width = Math.round(width * 4000 / height); - } - height = 4000; - } setParamIfDefined(url, "w", width, true, true); setParamIfDefined(url, "h", height, true, true); setParamIfDefined(url, "format", format); + + if (width && height) { + setParamIfUndefined(url, "fit", "cover"); + } + return url; }; From 78f6319f6e2d2481b602f7b90b73d2112460c0d7 Mon Sep 17 00:00:00 2001 From: Julian Benegas Date: Wed, 20 Nov 2024 13:33:20 -0300 Subject: [PATCH 4/6] add basehub to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 64b33eb..dd0ca49 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ is not auto-detected. - Storyblok - Vercel / Next.js - WordPress.com and Jetpack Site Accelerator +- BaseHub ## Delegated URLs From e1a5e1f2e42b0b4f5f93cf759f98c7e5330fba4d Mon Sep 17 00:00:00 2001 From: Julian Benegas Date: Mon, 25 Nov 2024 20:07:57 -0300 Subject: [PATCH 5/6] update tests --- src/transformers/basehub.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformers/basehub.test.ts b/src/transformers/basehub.test.ts index 1ef0aa5..408ad43 100644 --- a/src/transformers/basehub.test.ts +++ b/src/transformers/basehub.test.ts @@ -14,7 +14,7 @@ Deno.test("basehub", async (t) => { }); assertEquals( result?.toString(), - "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=200&h=100", + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=200&h=100&fit=cover", ); }); await t.step("should not set height if not provided", () => { @@ -44,7 +44,7 @@ Deno.test("basehub", async (t) => { }); assertEquals( result?.toString(), - "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=201&h=100&format=webp", + "https://assets.basehub.com/fa068a12/qZeFxPJWNB7UQdwUzjX3e/features-streamlined-team-communication-real-time-messaging-(light-mode)3x.jpg?w=201&h=100&format=webp&fit=cover", ); }); }); From eb12cd5fb3637954568c7fcb11bd606e350e52a9 Mon Sep 17 00:00:00 2001 From: Julian Benegas Date: Sun, 8 Dec 2024 20:30:19 -0300 Subject: [PATCH 6/6] fix jpeg thing --- src/transformers/basehub.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformers/basehub.ts b/src/transformers/basehub.ts index 41422b3..54c8666 100644 --- a/src/transformers/basehub.ts +++ b/src/transformers/basehub.ts @@ -9,7 +9,7 @@ import { export const parse: UrlParser<{ fit?: string }> = (url) => { const parsedUrl = toUrl(url); - const fit = parsedUrl.searchParams.get("fit") || 'cover'; + const fit = parsedUrl.searchParams.get("fit") || "cover"; const width = getNumericParam(parsedUrl, "w"); const height = getNumericParam(parsedUrl, "h"); const quality = getNumericParam(parsedUrl, "q"); @@ -32,7 +32,7 @@ export const transform: UrlTransformer = ( setParamIfDefined(url, "w", width, true, true); setParamIfDefined(url, "h", height, true, true); - setParamIfDefined(url, "format", format); + setParamIfDefined(url, "format", format === "jpg" ? "jpeg" : format); if (width && height) { setParamIfUndefined(url, "fit", "cover");