|
1 | | -import { Accepts } from 'https://deno.land/x/accepts@2.1.1/mod.ts' |
2 | | -import type { Context } from 'https://edge.netlify.com' |
3 | | -// Available at build time |
4 | | -import imageconfig from './imageconfig.json' assert { type: 'json' } |
5 | | - |
6 | | -const defaultFormat = 'webp' |
7 | | - |
8 | | -interface ImageConfig extends Record<string, unknown> { |
9 | | - formats?: string[] |
10 | | -} |
11 | | - |
12 | | -// Checks if a URL param is numeric |
13 | | -const isNumeric = (value: string | null) => Number(value).toString() === value |
14 | | - |
15 | | -/** |
16 | | - * Implement content negotiation for images |
17 | | - */ |
18 | | - |
19 | | -// deno-lint-ignore require-await |
20 | | -const handler = async (req: Request, context: Context) => { |
21 | | - const { searchParams } = new URL(req.url) |
22 | | - const accept = new Accepts(req.headers) |
23 | | - const { formats = [defaultFormat] } = imageconfig as ImageConfig |
24 | | - if (formats.length === 0) { |
25 | | - formats.push(defaultFormat) |
26 | | - } |
27 | | - let type = accept.types(formats) || defaultFormat |
28 | | - if (Array.isArray(type)) { |
29 | | - type = type[0] |
30 | | - } |
31 | | - |
32 | | - const source = searchParams.get('url') |
33 | | - const width = searchParams.get('w') |
34 | | - const quality = searchParams.get('q') ?? '75' |
| 1 | +import { getHandler } from 'https://ipx-edge-function-layer.netlify.app/mod.ts' |
35 | 2 |
|
36 | | - const errors: Array<string> = [] |
37 | | - |
38 | | - if (!source) { |
39 | | - errors.push('Missing "url" parameter') |
40 | | - } else if (!source.startsWith('http') && !source.startsWith('/')) { |
41 | | - errors.push('The "url" parameter must be a valid URL or path') |
42 | | - } |
43 | | - |
44 | | - if (!width) { |
45 | | - errors.push('Missing "w" parameter') |
46 | | - } else if (!isNumeric(width)) { |
47 | | - errors.push('Invalid "w" parameter') |
48 | | - } |
49 | | - |
50 | | - if (!isNumeric(quality)) { |
51 | | - errors.push('Invalid "q" parameter') |
52 | | - } |
53 | | - |
54 | | - if (!source || errors.length > 0) { |
55 | | - return new Response(`Invalid request: \n${errors.join('\n')}`, { |
56 | | - status: 400, |
57 | | - }) |
58 | | - } |
59 | | - |
60 | | - const modifiers = [`w_${width}`, `q_${quality}`] |
61 | | - |
62 | | - if (type) { |
63 | | - if (type.includes('/')) { |
64 | | - // If this is a mimetype, strip "image/" |
65 | | - type = type.split('/')[1] |
66 | | - } |
67 | | - modifiers.push(`f_${type}`) |
68 | | - } |
69 | | - const target = `/_ipx/${modifiers.join(',')}/${encodeURIComponent(source)}` |
70 | | - return context.rewrite(target) |
71 | | -} |
| 3 | +import imageconfig from './imageconfig.json' assert { type: 'json' } |
72 | 4 |
|
73 | | -export default handler |
| 5 | +export default getHandler({ formats: imageconfig?.formats }) |
0 commit comments