-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathipx.ts
57 lines (47 loc) · 1.4 KB
/
ipx.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import { Accepts } from "https://deno.land/x/[email protected]/mod.ts";
import type { Context } from "netlify:edge";
// Available at build time
import imageconfig from "../functions-internal/_ipx/imageconfig.json" assert {
type: "json",
};
const defaultFormat = "webp"
interface ImageConfig extends Record<string, unknown> {
formats?: string[];
}
/**
* Implement content negotiation for images
*/
// deno-lint-ignore require-await
const handler = async (req: Request, context: Context) => {
const { searchParams } = new URL(req.url);
const accept = new Accepts(req.headers);
const { formats = [defaultFormat] } = imageconfig as ImageConfig;
if (formats.length === 0) {
formats.push(defaultFormat);
}
let type = accept.types(formats) || defaultFormat;
if(Array.isArray(type)) {
type = type[0];
}
const source = searchParams.get("url");
const width = searchParams.get("w");
const quality = searchParams.get("q") ?? 75;
if (!source || !width) {
return new Response("Invalid request", {
status: 400,
});
}
const modifiers = [`w_${width}`, `q_${quality}`];
if (type) {
if(type.includes('/')) {
// If this is a mimetype, strip "image/"
type = type.split('/')[1];
}
modifiers.push(`f_${type}`);
}
const target = `/_ipx/${modifiers.join(",")}/${encodeURIComponent(source)}`;
return context.rewrite(
target,
);
};
export default handler;