examples/storefront Public
// The storefront's HTTP API. createApp takes the environment and the few things tests replace// (the clock and id generation) and returns a fetch handler.import { getProduct, listProducts, parseProductInput, upsertProduct } from "./catalog.ts";import type { Env } from "./env.ts";import { errorResponse, HttpError, json, readJson, requireAdmin } from "./http.ts";import { Router } from "./router.ts";export type Deps = { now: () => number; newId: () => string;};export const defaultDeps: Deps = { now: Date.now, newId: () => crypto.randomUUID() };export function createApp(env: Env, deps: Deps = defaultDeps) { const r = new Router(); r.on("GET", "/products", async () => json({ products: await listProducts(env.DB) })); r.on("GET", "/products/:id", async (_req, p) => { const product = await getProduct(env.DB, p.id!); if (!product || !product.active) throw new HttpError(404, "not_found", "No such product."); return json({ product }); }); r.on("PUT", "/admin/products/:id", async (req, p) => { requireAdmin(req, env.ADMIN_TOKEN); const input = parseProductInput(p.id!, await readJson(req)); return json({ product: await upsertProduct(env.DB, input, deps.now()) }); }); return { async fetch(req: Request): Promise<Response> { const url = new URL(req.url); try { const hit = r.match(req.method, url.pathname); if (hit === null) throw new HttpError(404, "not_found", "No such route."); if (hit === "method_not_allowed") throw new HttpError(405, "method_not_allowed", `${req.method} is not allowed here.`); return await hit.handler(req, hit.params); } catch (e) { if (e instanceof HttpError) return errorResponse(e); if (e instanceof URIError) return errorResponse(new HttpError(400, "bad_path", "The path is not valid.")); console.error(JSON.stringify({ msg: "unhandled error", path: url.pathname, error: String(e) })); return errorResponse(new HttpError(500, "internal", "Something went wrong.")); } }, };}