CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 4s
CI (SIAX Cloud) / sonar (pull_request) Skipped
CI (SIAX Cloud) / security (push) Successful in 15s
masterplan-lock / check (pull_request) Successful in 7s
Security Scan (SIAX Cloud) / security (push) Successful in 18s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 17s
CI (SIAX Cloud) / security (pull_request) Successful in 20s
CI (SIAX Cloud) / integration (pull_request) Successful in 35s
CI (SIAX Cloud) / quality (pull_request) Successful in 39s
CI (SIAX Cloud) / quality (push) Successful in 48s
31 lines
1.9 KiB
TypeScript
31 lines
1.9 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { engineFetch, hasEngine } from "@/lib/engine";
|
|
|
|
// A missing record is distinct from an unavailable or malformed source.
|
|
export async function GET(req: NextRequest) {
|
|
const plate = (req.nextUrl.searchParams.get("plate") ?? "").toUpperCase().replace(/[-\s]/g, "").replace(/[^A-Z0-9]/g, "");
|
|
if (!plate) return NextResponse.json({ error: { code: "bad_request", message: "plate krävs" } }, { status: 400 });
|
|
const unavailable = () => NextResponse.json({ error: { code: "source_unavailable", message: "Fordonskällan är inte tillgänglig" } }, { status: 503 });
|
|
try {
|
|
if (hasEngine()) {
|
|
const eng = await engineFetch(`/vehicles/${plate}`);
|
|
if (!eng?.ok) return unavailable();
|
|
const data: unknown = await eng.json();
|
|
if (!data || typeof data !== "object" || Array.isArray(data) || (data as { source_status?: unknown }).source_status !== "ok") return unavailable();
|
|
return NextResponse.json(data);
|
|
}
|
|
const r = await fetch(`https://opendata.rdw.nl/resource/m9d7-ebf2.json?kenteken=${encodeURIComponent(plate)}`, {
|
|
headers: { "User-Agent": "0pt/0.1 (+https://0pt.app; SIAX)" }, cache: "no-store",
|
|
});
|
|
if (!r.ok) return unavailable();
|
|
const data: unknown = await r.json();
|
|
if (!Array.isArray(data) || data.some((item) => !item || typeof item !== "object" || Array.isArray(item))) return unavailable();
|
|
if (!data.length) return NextResponse.json({ vehicle: null });
|
|
const d = data[0] as Record<string, string>;
|
|
if (d.datum_eerste_toelating != null && typeof d.datum_eerste_toelating !== "string") return unavailable();
|
|
return NextResponse.json({ source: "rdw", vehicle: { reg_plate: plate, market: "NL", make: d.merk ?? null,
|
|
model: d.handelsbenaming ?? null, year: (d.datum_eerste_toelating ?? "").slice(0, 4) || null },
|
|
provenance: { level: 3, source: "rdw" } });
|
|
} catch { return unavailable(); }
|
|
}
|