Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ is not auto-detected.
- Storyblok
- Vercel / Next.js
- WordPress.com and Jetpack Site Accelerator
- BaseHub

## Delegated URLs

Expand Down
3 changes: 2 additions & 1 deletion data/domains.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
4 changes: 4 additions & 0 deletions demo/src/examples.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
}
2 changes: 2 additions & 0 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -54,6 +55,7 @@ export const parsers = {
uploadcare,
supabase,
hygraph,
basehub,
};

export const cdnIsSupportedForParse = (
Expand Down
2 changes: 2 additions & 0 deletions src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -55,6 +56,7 @@ export const getTransformer = (cdn: ImageCdn) => ({
uploadcare,
supabase,
hygraph,
basehub,
}[cdn]);

/**
Expand Down
50 changes: 50 additions & 0 deletions src/transformers/basehub.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
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&fit=cover",
);
});
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&fit=cover",
);
});
});
42 changes: 42 additions & 0 deletions src/transformers/basehub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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") || "cover";
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: "basehub",
};
};

export const transform: UrlTransformer = (
{ url: originalUrl, width, height, format },
) => {
const url = toUrl(originalUrl);

setParamIfDefined(url, "w", width, true, true);
setParamIfDefined(url, "h", height, true, true);
setParamIfDefined(url, "format", format === "jpg" ? "jpeg" : format);

if (width && height) {
setParamIfUndefined(url, "fit", "cover");
}

return url;
};
3 changes: 2 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export type ImageCdn =
| "imagekit"
| "uploadcare"
| "supabase"
| "hygraph";
| "hygraph"
| "basehub";

export type SupportedImageCdn = ImageCdn;
Loading