import { unlink } from "node:fs/promises"; import { join } from "node:path"; import { zValidator } from "@hono/zod-validator"; import { Hono } from "hono"; import { createItemSchema, updateItemSchema } from "../../shared/schemas.ts"; import { parseId } from "../lib/params.ts"; import { createItem, deleteItem, duplicateItem, getAllItems, getItemById, updateItem, } from "../services/item.service.ts"; type Env = { Variables: { db?: any } }; const app = new Hono(); app.get("/", (c) => { const db = c.get("db"); const items = getAllItems(db); return c.json(items); }); app.get("/:id", (c) => { const db = c.get("db"); const id = parseId(c.req.param("id")); if (!id) return c.json({ error: "Invalid item ID" }, 400); const item = getItemById(db, id); if (!item) return c.json({ error: "Item not found" }, 404); return c.json(item); }); app.post("/", zValidator("json", createItemSchema), (c) => { const db = c.get("db"); const data = c.req.valid("json"); const item = createItem(db, data); return c.json(item, 201); }); app.put( "/:id", zValidator("json", updateItemSchema.omit({ id: true })), (c) => { const db = c.get("db"); const id = parseId(c.req.param("id")); if (!id) return c.json({ error: "Invalid item ID" }, 400); const data = c.req.valid("json"); const item = updateItem(db, id, data); if (!item) return c.json({ error: "Item not found" }, 404); return c.json(item); }, ); app.post("/:id/duplicate", (c) => { const db = c.get("db"); const id = parseId(c.req.param("id")); if (!id) return c.json({ error: "Invalid item ID" }, 400); const newItem = duplicateItem(db, id); if (!newItem) return c.json({ error: "Item not found" }, 404); return c.json(newItem, 201); }); app.delete("/:id", async (c) => { const db = c.get("db"); const id = parseId(c.req.param("id")); if (!id) return c.json({ error: "Invalid item ID" }, 400); const deleted = deleteItem(db, id); if (!deleted) return c.json({ error: "Item not found" }, 404); // Clean up image file if exists if (deleted.imageFilename) { try { await unlink(join("uploads", deleted.imageFilename)); } catch { // File missing is not an error worth failing the delete over } } return c.json({ success: true }); }); export { app as itemRoutes };