import type { Meta, SuggestHit, TreeQuery, TreeResponse, DefinitionPayload } from "./types"; async function json(res: Response): Promise { if (!res.ok) { const text = await res.text(); throw new Error(text || res.statusText); } return res.json() as Promise; } export const api = { meta: () => fetch("/api/meta").then((r) => json(r)), suggest: (q: string) => fetch(`/api/suggest?q=${encodeURIComponent(q)}&limit=18`).then((r) => json<{ hits: SuggestHit[] }>(r)), tree: (body: TreeQuery, signal?: AbortSignal) => fetch("/api/tree", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), signal, }).then((r) => json(r)), node: (term: string, lang: string) => fetch(`/api/node?term=${encodeURIComponent(term)}&lang=${encodeURIComponent(lang)}`).then((r) => json>(r)), define: (term: string, lang: string, iso?: string | null) => { const params = new URLSearchParams({ term, lang }); if (iso) params.set("iso", iso); return fetch(`/api/define?${params}`).then((r) => json(r)); }, exportUrl: (body: TreeQuery) => { return fetch("/api/export?format=csv", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }).then(async (r) => { const blob = await r.blob(); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "reverse-etymology.csv"; a.click(); URL.revokeObjectURL(url); }); }, };