import { withUser, json, ApiError } from "@/lib/api"; import { LIMITS } from "@/lib/rate-limit"; import { listFiles, saveFile, deleteFile, LIBRARY_MAX_BYTES } from "@/lib/library/service"; export const dynamic = "force-dynamic"; /** GET /api/library/files?projectId=&q=&kind= → { files } (metadata only). */ export const GET = withUser(async ({ req, user }) => { const p = new URL(req.url).searchParams; const files = await listFiles(user.id, { projectId: p.get("projectId") ?? undefined, q: p.get("q") ?? undefined, kind: p.get("kind") ?? undefined, limit: p.get("limit") ? Number(p.get("limit")) : undefined, }); return json({ files }); }); /** POST /api/library/files — multipart: file, projectId?, description? → 201 { file } */ export const POST = withUser( async ({ req, user }) => { const len = Number(req.headers.get("content-length") ?? 0); if (len > LIBRARY_MAX_BYTES + 8192) throw new ApiError(413, "File too large (max 10 MB)", "PAYLOAD_TOO_LARGE"); const form = await req.formData().catch(() => null); const file = form?.get("file"); if (!(file instanceof File)) throw new ApiError(400, "Missing file", "BAD_REQUEST"); const projectId = form?.get("projectId"); const description = form?.get("description"); const saved = await saveFile(user.id, { file, projectId: typeof projectId === "string" && projectId && projectId !== "none" ? projectId.slice(0, 64) : null, description: typeof description === "string" ? description : null, }); return json({ file: saved }, { status: 201 }); }, { limit: { ...LIMITS.upload, key: "library-upload" } }, ); /** DELETE /api/library/files?id= */ export const DELETE = withUser(async ({ req, user }) => { const id = new URL(req.url).searchParams.get("id"); if (!id) throw new ApiError(400, "Missing id"); await deleteFile(user.id, id); return json({ ok: true }); });