Figuring this shit out
1import { serve } from "@hono/node-server";
2import { Hono } from "hono";
3import { readFileSync } from "node:fs";
4import { resolve, dirname } from "node:path";
5import { fileURLToPath } from "node:url";
6import { getAllEntries, createEntry, deleteEntry } from "./db.js";
7
8// In ESM (ES Modules), __dirname doesn't exist like it does in CommonJS.
9// This is a common pattern you'll see everywhere — it reconstructs __dirname
10// from import.meta.url. Think of it like std::env::current_dir() in Rust.
11const __dirname = dirname(fileURLToPath(import.meta.url));
12
13const app = new Hono();
14
15// ===
16// User facing routes
17// ===
18
19app.get("/", (c) => {
20 const html = readFileSync(resolve(__dirname, "public/index.html"), "utf-8");
21 return c.html(html);
22});
23
24// ===
25// API routes
26// ===
27
28app.get("/api/health", (c) => {
29 return c.json({ status: "ok", timestamp: new Date().toISOString() });
30});
31
32/** GET /api/entries - return all guest book entries */
33app.get("/api/entries", (c) => {
34 const entries = getAllEntries();
35 return c.json(entries);
36});
37
38app.post("/api/entries", async (c) => {
39 const body = await c.req.json();
40
41 // basic validation, replace later
42 if (!body.message || typeof body.message !== "string") {
43 return c.json({ error: "Message is required" }, 400);
44 }
45
46 if (!body.user_did || !body.user_handle) {
47 return c.json({ error: "User info is required" }, 400);
48 }
49
50 const message = body.message.trim().slice(0, 500);
51 if (message.length === 0) {
52 return c.json({ error: "Message cannot be empty" }, 400);
53 }
54
55 const entry = createEntry({
56 user_did: body.user_did,
57 user_handle: body.user_handle,
58 message,
59 });
60
61
62 return c.json(entry, 201);
63
64});
65
66app.delete("/api/entries/:id", async (c) => {
67 const id = Number(c.req.param("id"));
68 const body = await c.req.json();
69
70 // Right now I am trusting whatever DID the user provides, this will change after auth is added
71
72 if (!body.user_did) {
73 return c.json({ error: "User info is required" }, 400);
74 }
75
76 const deleted = deleteEntry(id, body.user_did);
77
78 if (!deleted) {
79 return c.json({ error: "Entry not found" }, 404);
80 }
81
82 return c.body(null, 204);
83
84});
85
86// ===
87// Start the server
88// ===
89
90const port = 3000;
91console.log(`Guestbook server running at http://localhost:${port}`);
92serve({ fetch: app.fetch, port });