Skip to content
File

Blob: worker/index.ts

typescript58 lines
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 */
8import { handleImageOptimization, DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES } from "vinext/server/image-optimization";
9import type { ImageConfig } from "vinext/server/image-optimization";
10import handler from "vinext/server/app-router-entry";
11 
12interface 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 
23interface 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 
34export 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};