1import * as DAX from "@/AWS/DAX";
2import * as Lambda from "@/AWS/Lambda";
3import * as Effect from "effect/Effect";
4import * as Layer from "effect/Layer";
5import { HttpServerRequest } from "effect/http/HttpServerRequest";
6import * as HttpServerResponse from "effect/http/HttpServerResponse";
7import path from "pathe";
8
9const main = path.resolve(import.meta.dirname, "handler.ts");
10
11// Well-formed-but-nonexistent cluster name — the /clusters route drives the
12// DescribeClusters binding against it so the fixture exercises the IAM grant
13// and the typed error decode at zero cost (no cluster is ever created).
14const NONEXISTENT_CLUSTER_NAME = "alchemy-nonexistent-dax-probe";
15
16export class DAXTestFunction extends Lambda.Function<Lambda.Function>()(
17 "DAXTestFunction",
18) {}
19
20export default DAXTestFunction.make(
21 {
22 main,
23 functionUrl: true,
24 },
25 Effect.gen(function* () {
26 const describeClusters = yield* DAX.DescribeClusters();
27 const describeEvents = yield* DAX.DescribeEvents();
28
29 const bound = {
30 describeClusters,
31 describeEvents,
32 };
33
34 return {
35 fetch: Effect.gen(function* () {
36 const request = yield* HttpServerRequest;
37 const url = new URL(request.originalUrl);
38 const pathname = url.pathname;
39
40 if (request.method === "GET" && pathname === "/bindings") {
41 return yield* HttpServerResponse.json({
42 bound: Object.keys(bound),
43 });
44 }
45
46 if (request.method === "GET" && pathname === "/clusters") {
47 // A nonexistent cluster name must surface the service's typed
48 // not-found tag — an IAM gap would surface AccessDeniedException
49 // and fail the route with an opaque 500 instead.
50 const tag = yield* describeClusters({
51 ClusterNames: [NONEXISTENT_CLUSTER_NAME],
52 }).pipe(
53 Effect.map(() => "Found"),
54 Effect.catchTag("ClusterNotFoundFault", (e) =>
55 Effect.succeed(e._tag),
56 ),
57 );
58 return yield* HttpServerResponse.json({ tag });
59 }
60
61 if (request.method === "GET" && pathname === "/events") {
62 // Listing the account's recent DAX events succeeds (possibly
63 // empty) — proves the grant and the response schema decode.
64 const result = yield* describeEvents();
65 return yield* HttpServerResponse.json({
66 count: (result.Events ?? []).length,
67 });
68 }
69
70 return yield* HttpServerResponse.json(
71 { error: "Not found", method: request.method, pathname },
72 { status: 404 },
73 );
74 }).pipe(Effect.orDie),
75 };
76 }).pipe(
77 Effect.provide(
78 Layer.mergeAll(DAX.DescribeClustersHttp, DAX.DescribeEventsHttp),
79 ),
80 ),
81);