1import * as Cloudflare from "alchemy/Cloudflare";
2import { makeDatabase } from "./prisma/generated/client.ts";
3import { schemas } from "./prisma/generated/schemas.ts";
4import * as Schema from "effect/Schema";
5import * as Effect from "effect/Effect";
6import * as HttpServerRequest from "effect/http/HttpServerRequest";
7import * as HttpServerResponse from "effect/http/HttpServerResponse";
8import { Hyperdrive } from "./Db.ts";
9
10export default class Api extends Cloudflare.Worker<Api>()(
11 "Api",
12 {
13 main: import.meta.url,
14 },
15 Effect.gen(function* () {
16 const conn = yield* Cloudflare.Hyperdrive.Connect(Hyperdrive);
17 const db = yield* makeDatabase(conn.connectionString);
18
19 return {
20 fetch: Effect.gen(function* () {
21 const request = yield* HttpServerRequest.HttpServerRequest;
22 switch (request.method) {
23 case "GET": {
24 if (request.url === "/") {
25 const users = yield* db.orm.public.User.all();
26 return yield* HttpServerResponse.json({ users });
27 }
28 const id = request.url.split("/").pop() ?? "";
29 const user = yield* db.orm.public.User.where({ id })
30 .include("posts")
31 .first();
32 return yield* HttpServerResponse.json({ user });
33 }
34 case "POST": {
35 const values = yield* Effect.sync(() => ({
36 name: crypto.randomUUID(),
37 email: crypto.randomUUID(),
38 }));
39 const row = yield* db.orm.public.User.create(values);
40 const user = yield* Schema.decodeUnknownEffect(schemas.public.User)(
41 row,
42 );
43 return yield* HttpServerResponse.json({ user });
44 }
45 case "DELETE": {
46 const id = request.url.split("/").pop() ?? "";
47 const user = yield* db.orm.public.User.where({ id }).delete();
48 return yield* HttpServerResponse.json({ user });
49 }
50 default: {
51 return yield* HttpServerResponse.json(
52 { error: "Method not allowed" },
53 { status: 405 },
54 );
55 }
56 }
57 }).pipe(
58 Effect.catch((cause) =>
59 HttpServerResponse.json(
60 { ok: false, error: cause._tag },
61 { status: 500 },
62 ),
63 ),
64 ),
65 };
66 }).pipe(Effect.provide(Cloudflare.Hyperdrive.ConnectBinding)),
67) {}