import { HttpError } from "@/lib/errors"; import { readJson, route } from "@/lib/http"; import { deleteImageDir, renameImageDir } from "@/lib/images"; import { findPost, mutatePosts, readPosts } from "@/lib/store"; import { validatePost } from "@/lib/validate"; export const dynamic = "force-dynamic"; type Ctx = { params: Promise<{ slug: string }> }; export const GET = route(async (_req, { params }) => { const { slug } = await params; const { posts, revision } = await readPosts(); return Response.json({ post: findPost(posts, slug), revision }); }); /** Body: { post: PostInput, revision? }. A changed slug also moves the * post's image folder and rewrites references to it. */ export const PUT = route(async (req, { params }) => { const { slug } = await params; const body = await readJson<{ post?: unknown; revision?: string }>(req); const { post: input, errors } = validatePost(body.post); if (!input) throw new HttpError(400, "invalid post", errors); const { result, revision } = await mutatePosts(body.revision, async (posts) => { const existing = findPost(posts, slug); const updated = { ...input, id: existing.id }; if (input.slug !== slug) { if (posts.some((p) => p.slug === input.slug)) { throw new HttpError(409, `a post with slug "${input.slug}" already exists`); } await renameImageDir(updated, slug, input.slug); } // images is optional: an editor that cleared the gallery drops the key. if (!input.images) delete (updated as { images?: unknown }).images; posts[posts.indexOf(existing)] = updated; return updated; }); return Response.json({ post: result, revision }); }); /** Query: ?revision=…&images=1 (also delete the post's image folder). */ export const DELETE = route(async (req, { params }) => { const { slug } = await params; const url = new URL(req.url); const { revision } = await mutatePosts(url.searchParams.get("revision") ?? undefined, (posts) => { posts.splice(posts.indexOf(findPost(posts, slug)), 1); }); if (url.searchParams.get("images") === "1") await deleteImageDir(slug); return Response.json({ deleted: slug, revision }); });