1import * as GCP from "alchemy/GCP";
2import * as Effect from "effect/Effect";
3import { HttpServerRequest } from "effect/http/HttpServerRequest";
4import * as HttpServerResponse from "effect/http/HttpServerResponse";
5
6const QUOTES = [
7 "Simplicity is prerequisite for reliability. — Edsger W. Dijkstra",
8 "Make it work, make it right, make it fast. — Kent Beck",
9 "Programs must be written for people to read. — Harold Abelson",
10];
11
12/**
13 * A private backend. Without `invokerIamDisabled`, Cloud Run's front end
14 * rejects every request that does not carry a Google-signed ID token
15 * from a principal holding `roles/run.invoker` on this service — the
16 * container never sees them.
17 *
18 * - `GET /quote` — a quote, picked by the optional `?n=` index.
19 */
20export default class Quotes extends GCP.Function<Quotes>()(
21 "Quotes",
22 {
23 main: import.meta.url,
24 },
25 Effect.gen(function* () {
26 return {
27 fetch: Effect.gen(function* () {
28 const request = yield* HttpServerRequest;
29 const url = new URL(request.originalUrl, "http://localhost");
30
31 if (request.method === "GET" && url.pathname === "/quote") {
32 const n = Number(url.searchParams.get("n") ?? "0");
33 const index = Number.isInteger(n) && n >= 0 ? n % QUOTES.length : 0;
34 return yield* HttpServerResponse.json({
35 index,
36 quote: QUOTES[index],
37 servedBy: "quotes",
38 });
39 }
40
41 return yield* HttpServerResponse.json(
42 { error: "not found" },
43 { status: 404 },
44 );
45 }),
46 };
47 }),
48) {}