import type { APIRoute } from "astro"; // Valid action types const VALID_ACTIONS = ["copy", "download", "cart"] as const; type Action = (typeof VALID_ACTIONS)[number]; // Column mapping for actions const ACTION_COLUMNS: Record = { copy: "copies", download: "downloads", cart: "carts", }; export const POST: APIRoute = async ({ request, locals }) => { try { // Get D1 binding from Cloudflare runtime const db = (locals as any).runtime?.env?.DB; if (!db) { // Fallback: accept request but don't persist (dev mode without D1) return new Response(JSON.stringify({ ok: true, persisted: false }), { status: 200, headers: { "Content-Type": "application/json" }, }); } // Parse request body const body = await request.json(); const { template, action } = body as { template?: string; action?: string }; // Validate inputs if (!template || typeof template !== "string") { return new Response(JSON.stringify({ error: "Missing template name" }), { status: 400, headers: { "Content-Type": "application/json" }, }); } if (!action || !VALID_ACTIONS.includes(action as Action)) { return new Response(JSON.stringify({ error: "Invalid action" }), { status: 400, headers: { "Content-Type": "application/json" }, }); } const column = ACTION_COLUMNS[action as Action]; // Upsert: increment counter or insert new row await db .prepare( `INSERT INTO usage_counts (template_name, ${column}) VALUES (?, 1) ON CONFLICT(template_name) DO UPDATE SET ${column} = ${column} + 1`, ) .bind(template) .run(); return new Response(JSON.stringify({ ok: true, persisted: true }), { status: 200, headers: { "Content-Type": "application/json" }, }); } catch (error) { // Silently accept in dev mode (no D1 database) const errorMessage = String(error); if (!errorMessage.includes("no such table")) { console.error("Track error:", error); } // Return success without persistence return new Response(JSON.stringify({ ok: true, persisted: false }), { status: 200, headers: { "Content-Type": "application/json" }, }); } }; // Disable prerendering for this API route export const prerender = false;