1import * as Cloudflare from "@/Cloudflare/index.ts";
2import * as Effect from "effect/Effect";
3import * as HttpServerError from "effect/http/HttpServerError";
4import { HttpServerRequest } from "effect/http/HttpServerRequest";
5import * as HttpServerResponse from "effect/http/HttpServerResponse";
6
7export const readyMarker = "http-server-worker-ready";
8
9/**
10 * Values that must never escape the Worker over the wire when a handler
11 * fails. The test asserts none of them appear in the HTTP response.
12 */
13export const sensitiveContext = [
14 "sk_live_alchemy_super_secret",
15 "tenant-customer-42",
16 "/srv/alchemy/private/customer-42.json",
17 "10.42.0.17",
18];
19
20export default class HttpServerWorker extends Cloudflare.Worker<HttpServerWorker>()(
21 "HttpServerWorker",
22 {
23 main: import.meta.url,
24 },
25 Effect.gen(function* () {
26 return {
27 fetch: Effect.gen(function* () {
28 const request = yield* HttpServerRequest;
29 if (request.url.startsWith("/missing")) {
30 // A Respondable error escaping as a defect must keep its intended
31 // response (404), not be flattened into a generic 500.
32 return yield* Effect.die(
33 new HttpServerError.RouteNotFound({ request }),
34 );
35 }
36 if (request.url.startsWith("/boom")) {
37 return yield* Effect.fail(
38 new Error(
39 `Sensitive handler context: ${sensitiveContext.join(" ")}`,
40 ),
41 ).pipe(Effect.orDie);
42 }
43 return HttpServerResponse.text(readyMarker);
44 }),
45 };
46 }),
47) {}