51 lines
2.0 KiB
TypeScript
51 lines
2.0 KiB
TypeScript
import type { AisTargetSearchResponse } from "../model/types";
|
|
|
|
export type SearchAisTargetsParams = {
|
|
minutes: number;
|
|
bbox?: string;
|
|
centerLon?: number;
|
|
centerLat?: number;
|
|
radiusMeters?: number;
|
|
};
|
|
|
|
export async function searchAisTargets(params: SearchAisTargetsParams, signal?: AbortSignal) {
|
|
// Same convention as the "dark" project:
|
|
// - dev: default to Vite proxy base `/snp-api`
|
|
// - prod/other: can be overridden via `VITE_API_URL` (e.g. `http://host:8041/snp-api`)
|
|
const base = (import.meta.env.VITE_API_URL || "/snp-api").replace(/\/$/, "");
|
|
const u = new URL(`${base}/api/ais-target/search`, window.location.origin);
|
|
u.searchParams.set("minutes", String(params.minutes));
|
|
if (params.bbox) u.searchParams.set("bbox", params.bbox);
|
|
if (typeof params.centerLon === "number" && Number.isFinite(params.centerLon)) {
|
|
u.searchParams.set("centerLon", String(params.centerLon));
|
|
}
|
|
if (typeof params.centerLat === "number" && Number.isFinite(params.centerLat)) {
|
|
u.searchParams.set("centerLat", String(params.centerLat));
|
|
}
|
|
if (typeof params.radiusMeters === "number" && Number.isFinite(params.radiusMeters)) {
|
|
u.searchParams.set("radiusMeters", String(params.radiusMeters));
|
|
}
|
|
|
|
const res = await fetch(u, { signal, headers: { accept: "application/json" } });
|
|
const txt = await res.text();
|
|
let json: unknown = null;
|
|
try {
|
|
json = JSON.parse(txt);
|
|
} catch {
|
|
// ignore
|
|
}
|
|
if (!res.ok) {
|
|
const msg =
|
|
json && typeof json === "object" && typeof (json as { message?: unknown }).message === "string"
|
|
? (json as { message: string }).message
|
|
: txt.slice(0, 200) || res.statusText;
|
|
throw new Error(`AIS target API failed: ${res.status} ${msg}`);
|
|
}
|
|
|
|
if (!json || typeof json !== "object") throw new Error("AIS target API returned invalid payload");
|
|
const parsed = json as AisTargetSearchResponse;
|
|
if (!parsed.success) throw new Error(parsed.message || "AIS target API returned success=false");
|
|
|
|
return parsed;
|
|
}
|