File
Blob: worker/index.ts
| 1 | /** |
| 2 | * Cloudflare Worker entry point — auto-generated by vinext deploy. |
| 3 | * Edit freely or delete to regenerate on next deploy. |
| 4 | * |
| 5 | * For apps without image optimization, you can use vinext/server/app-router-entry |
| 6 | * directly in wrangler.jsonc: "main": "vinext/server/app-router-entry" |
| 7 | */ |
| 8 | import { handleImageOptimization, DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES } from "vinext/server/image-optimization"; |
| 9 | import type { ImageConfig } from "vinext/server/image-optimization"; |
| 10 | import handler from "vinext/server/app-router-entry"; |
| 11 | |
| 12 | interface Env { |
| 13 | ASSETS: Fetcher; |
| 14 | IMAGES: { |
| 15 | input(stream: ReadableStream): { |
| 16 | transform(options: Record<string, unknown>): { |
| 17 | output(options: { format: string; quality: number }): Promise<{ response(): Response }>; |
| 18 | }; |
| 19 | }; |
| 20 | }; |
| 21 | } |
| 22 | |
| 23 | interface ExecutionContext { |
| 24 | waitUntil(promise: Promise<unknown>): void; |
| 25 | passThroughOnException(): void; |
| 26 | } |
| 27 | |
| 28 | // Image security config. SVG sources with .svg extension auto-skip the |
| 29 | // optimization endpoint on the client side (served directly, no proxy). |
| 30 | // To route SVGs through the optimizer (with security headers), set |
| 31 | // dangerouslyAllowSVG: true in next.config.js and uncomment below: |
| 32 | // const imageConfig: ImageConfig = { dangerouslyAllowSVG: true }; |
| 33 | |
| 34 | export default { |
| 35 | async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> { |
| 36 | const url = new URL(request.url); |
| 37 | |
| 38 | // Image optimization via Cloudflare Images binding. |
| 39 | // The parseImageParams validation inside handleImageOptimization |
| 40 | // normalizes backslashes and validates the origin hasn't changed. |
| 41 | if (url.pathname === "/_vinext/image") { |
| 42 | const allowedWidths = [...DEFAULT_DEVICE_SIZES, ...DEFAULT_IMAGE_SIZES]; |
| 43 | return handleImageOptimization(request, { |
| 44 | fetchAsset: (path) => env.ASSETS.fetch(new Request(new URL(path, request.url))), |
| 45 | transformImage: async (body, { width, format, quality }) => { |
| 46 | const result = await env.IMAGES.input(body).transform(width > 0 ? { width } : {}).output({ format, quality }); |
| 47 | return result.response(); |
| 48 | }, |
| 49 | }, allowedWidths); |
| 50 | } |
| 51 | |
| 52 | // Delegate everything else to vinext, forwarding ctx so that |
| 53 | // ctx.waitUntil() is available to background cache writes and |
| 54 | // other deferred work via getRequestExecutionContext(). |
| 55 | return handler.fetch(request, env, ctx); |
| 56 | }, |
| 57 | }; |