114 lines
3.9 KiB
TypeScript
114 lines
3.9 KiB
TypeScript
import { readJson } from "@/server/http/readJson";
|
|
import {
|
|
createSnippet,
|
|
deleteSnippet,
|
|
getSnippetById,
|
|
listSnippets,
|
|
normalizeDeadlineAtInput,
|
|
updateSnippet,
|
|
} from "@/server/snippets";
|
|
|
|
export const snippetRoutes = {
|
|
"/api/snippets": {
|
|
async GET(req: Request) {
|
|
const url = new URL(req.url);
|
|
const q = url.searchParams.get("q");
|
|
const sort = url.searchParams.get("sort");
|
|
return Response.json(listSnippets(q, sort));
|
|
},
|
|
async POST(req: Request) {
|
|
const body = await readJson(req);
|
|
if (!body || typeof body !== "object") {
|
|
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
}
|
|
const o = body as Record<string, unknown>;
|
|
const tags = Array.isArray(o.tags) ? o.tags.filter((t): t is string => typeof t === "string") : [];
|
|
let deadline_at: string | null | undefined;
|
|
if ("deadline_at" in o) {
|
|
try {
|
|
deadline_at = normalizeDeadlineAtInput(o.deadline_at);
|
|
} catch (e) {
|
|
const msg = e instanceof Error ? e.message : "deadline_at ungültig";
|
|
return Response.json({ error: msg }, { status: 400 });
|
|
}
|
|
}
|
|
const snippet = createSnippet({
|
|
title:
|
|
o.title === null ? null : typeof o.title === "string" ? o.title : undefined,
|
|
body: typeof o.body === "string" ? o.body : "",
|
|
tags,
|
|
deadline_at,
|
|
});
|
|
return Response.json(snippet, { status: 201 });
|
|
},
|
|
},
|
|
|
|
"/api/snippets/:id": {
|
|
async GET(req: Request) {
|
|
const id = Number((req as Request & { params: { id: string } }).params.id);
|
|
if (!Number.isFinite(id)) {
|
|
return Response.json({ error: "Invalid id" }, { status: 400 });
|
|
}
|
|
const snippet = getSnippetById(id);
|
|
if (!snippet) {
|
|
return Response.json({ error: "Not found" }, { status: 404 });
|
|
}
|
|
return Response.json(snippet);
|
|
},
|
|
async PATCH(req: Request) {
|
|
const id = Number((req as Request & { params: { id: string } }).params.id);
|
|
if (!Number.isFinite(id)) {
|
|
return Response.json({ error: "Invalid id" }, { status: 400 });
|
|
}
|
|
const body = await readJson(req);
|
|
if (!body || typeof body !== "object") {
|
|
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
}
|
|
const o = body as Record<string, unknown>;
|
|
const patch: {
|
|
title?: string | null;
|
|
body?: string;
|
|
tags?: string[];
|
|
sort_order?: number;
|
|
deadline_at?: string | null;
|
|
} = {};
|
|
if ("title" in o) {
|
|
patch.title = o.title === null ? null : String(o.title);
|
|
}
|
|
if ("body" in o && typeof o.body === "string") {
|
|
patch.body = o.body;
|
|
}
|
|
if ("tags" in o && Array.isArray(o.tags)) {
|
|
patch.tags = o.tags.filter((t): t is string => typeof t === "string");
|
|
}
|
|
if ("sort_order" in o && typeof o.sort_order === "number" && Number.isFinite(o.sort_order)) {
|
|
patch.sort_order = o.sort_order;
|
|
}
|
|
if ("deadline_at" in o) {
|
|
try {
|
|
patch.deadline_at = normalizeDeadlineAtInput(o.deadline_at);
|
|
} catch (e) {
|
|
const msg = e instanceof Error ? e.message : "deadline_at ungültig";
|
|
return Response.json({ error: msg }, { status: 400 });
|
|
}
|
|
}
|
|
const snippet = updateSnippet(id, patch);
|
|
if (!snippet) {
|
|
return Response.json({ error: "Not found" }, { status: 404 });
|
|
}
|
|
return Response.json(snippet);
|
|
},
|
|
async DELETE(req: Request) {
|
|
const id = Number((req as Request & { params: { id: string } }).params.id);
|
|
if (!Number.isFinite(id)) {
|
|
return Response.json({ error: "Invalid id" }, { status: 400 });
|
|
}
|
|
const ok = deleteSnippet(id);
|
|
if (!ok) {
|
|
return Response.json({ error: "Not found" }, { status: 404 });
|
|
}
|
|
return new Response(null, { status: 204 });
|
|
},
|
|
},
|
|
};
|