import { NextRequest } from "next/server"; import { z } from "zod"; import { searchEntries, getEntryFacets } from "@/server/repo"; import { parseIdList } from "@/utils/params"; const querySchema = z.object({ q: z.string().optional(), page: z.coerce.number().int().positive().optional(), pageSize: z.coerce.number().int().positive().max(100).optional(), genreId: z.coerce.number().int().positive().optional(), languageId: z .string() .trim() .length(2, "languageId must be a 2-char code") .optional(), machinetypeId: z.string().optional(), year: z.coerce.number().int().optional(), sort: z.enum(["title", "id_desc"]).optional(), scope: z.enum(["title", "title_aliases", "title_aliases_origins"]).optional(), facets: z.coerce.boolean().optional(), }); export async function GET(req: NextRequest) { const { searchParams } = new URL(req.url); const parsed = querySchema.safeParse({ q: searchParams.get("q") ?? undefined, page: searchParams.get("page") ?? undefined, pageSize: searchParams.get("pageSize") ?? undefined, genreId: searchParams.get("genreId") ?? undefined, languageId: searchParams.get("languageId") ?? undefined, machinetypeId: searchParams.get("machinetypeId") ?? undefined, year: searchParams.get("year") ?? undefined, sort: searchParams.get("sort") ?? undefined, scope: searchParams.get("scope") ?? undefined, facets: searchParams.get("facets") ?? undefined, }); if (!parsed.success) { return new Response( JSON.stringify({ error: parsed.error.flatten() }), { status: 400, headers: { "content-type": "application/json" } } ); } const machinetypeId = parseIdList(parsed.data.machinetypeId); const searchParamsParsed = { ...parsed.data, machinetypeId }; const data = await searchEntries(searchParamsParsed); const body = parsed.data.facets ? { ...data, facets: await getEntryFacets(searchParamsParsed) } : data; return new Response(JSON.stringify(body), { headers: { "content-type": "application/json" }, }); } // Ensure Node.js runtime (required for mysql2) export const runtime = "nodejs";