wayfarer-weather/lib/weather/respond.ts
Cayden Schwechten 6250d23297 init
2026-10-31 21:20:16 -05:00

35 lines
1.5 KiB
TypeScript

import { NextResponse, type NextRequest } from "next/server";
import { ProviderError } from "./http";
/** Turns any thrown error into a JSON `{ error }` response with a sensible status. */
export function errorResponse(error: unknown): NextResponse {
if (error instanceof ProviderError) {
return NextResponse.json({ error: error.message }, { status: error.status });
}
console.error(error);
return NextResponse.json({ error: "Something went wrong reaching the weather service" }, { status: 500 });
}
export function badRequest(message: string): NextResponse {
return NextResponse.json({ error: message }, { status: 400 });
}
/** Rejects cross-site browser requests so external pages can't hotlink your API/tile quotas. */
export function forbidCrossSite(request: NextRequest): NextResponse | null {
if (request.headers.get("sec-fetch-site") === "cross-site") {
return NextResponse.json({ error: "Cross-site requests are not permitted" }, { status: 403 });
}
return null;
}
/** Parses a lat/lon pair from query params, or returns null if either is missing or invalid. */
export function parseCoords(params: URLSearchParams): { lat: number; lon: number } | null {
const rawLat = params.get("lat")?.trim() ?? "";
const rawLon = params.get("lon")?.trim() ?? "";
if (!rawLat || !rawLon) return null;
const lat = Number(rawLat);
const lon = Number(rawLon);
const valid = Number.isFinite(lat) && Number.isFinite(lon) && Math.abs(lat) <= 90 && Math.abs(lon) <= 180;
return valid ? { lat, lon } : null;
}