1// Async (non-Effect) Worker that drives an Images binding the way real users
2// do — `info(...)` and `input(...).transform(...).output(...)` over the
3// request body. Used by Images.local.test.ts both against the local
4// Sharp-backed simulator and (piped through `Alchemy.remote()`) against the real
5// Images service via the remote-bindings proxy.
6import type * as cf from "@cloudflare/workers-types";
7
8interface Env {
9 IMAGES: cf.ImagesBinding;
10}
11
12export default {
13 async fetch(request: Request, env: Env): Promise<Response> {
14 const url = new URL(request.url);
15 try {
16 if (url.pathname === "/info") {
17 const info = await env.IMAGES.info(
18 request.body as unknown as cf.ReadableStream<Uint8Array>,
19 );
20 return Response.json(info);
21 }
22 if (url.pathname === "/transform") {
23 let transformer = env.IMAGES.input(
24 request.body as unknown as cf.ReadableStream<Uint8Array>,
25 );
26 const width = url.searchParams.get("width");
27 if (width !== null) {
28 transformer = transformer.transform({ width: Number(width) });
29 }
30 const format = (url.searchParams.get("format") ??
31 "image/png") as Parameters<typeof transformer.output>[0]["format"];
32 try {
33 const result = await transformer.output({ format });
34 return result.response() as unknown as Response;
35 } catch (e) {
36 const error = e as { code?: number; message?: string };
37 return Response.json({
38 error: true,
39 code: error.code,
40 message: error.message,
41 });
42 }
43 }
44 return new Response("not found", { status: 404 });
45 } catch (e) {
46 const error = e as { stack?: string };
47 return new Response(`fixture error: ${error?.stack ?? String(e)}`, {
48 status: 500,
49 });
50 }
51 },
52};