Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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",
);
});
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",
);
});
});
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);

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;