// script.js (function () { const isLocal = /^(localhost|127\.0\.0\.1)$/.test(location.hostname); // Current page querystring utilities const qs = new URLSearchParams(location.search); // Optional API base override: ?api=http://localhost:9000 const override = qs.get("api"); const saved = localStorage.getItem("API_BASE"); const baseRaw = override || saved || // Local dev -> FastAPI on 8000; Prod -> same origin (isLocal ? "http://localhost:8000" : location.origin); if (override) localStorage.setItem("API_BASE", override); let API_BASE = baseRaw.replace(/\/$/, ""); // trim trailing slash function buildUrl(path, params) { // allow absolute URLs const full = /^https?:\/\//i.test(path) ? path : API_BASE + (path.startsWith("/") ? path : "/" + path); const url = new URL(full); console.log("Calling api :",url); if (params && typeof params === "object") { for (const [k, v] of Object.entries(params)) { if (v === undefined || v === null) continue; if (Array.isArray(v)) { v.forEach((val) => url.searchParams.append(k, String(val))); } else { url.searchParams.set(k, String(v)); } } } return url.toString(); } async function http(method, path, { params, data, headers, ...rest } = {}) { const url = buildUrl(path, params); const init = { method, headers: { Accept: "application/json", ...(headers || {}) }, ...rest, }; if (data instanceof FormData) { init.body = data; // let browser set multipart boundary } else if (data !== undefined) { init.body = JSON.stringify(data); init.headers["Content-Type"] = "application/json"; } const res = await fetch(url, init); if (!res.ok) { const text = await res.text(); throw new Error(`${method} ${url} failed (${res.status}) - ${text}`); } const ct = res.headers.get("content-type") || ""; return ct.includes("application/json") ? res.json() : res.text(); } // ---- Expose globals (usable from any page) ---- window.API_BASE = API_BASE; window.setApiBase = (url) => { if (!url) return; const norm = url.replace(/\/$/, ""); localStorage.setItem("API_BASE", norm); API_BASE = norm; window.API_BASE = norm; }; // Build URL: api(path, params?) window.api = (path, params) => buildUrl(path, params); // Simple HTTP helpers window.apiGet = (path, params, options) => http("GET", path, { params, ...(options || {}) }); window.apiPost = (path, data, options) => http("POST", path, { data, ...(options || {}) }); window.apiPut = (path, data, options) => http("PUT", path, { data, ...(options || {}) }); window.apiDelete = (path, params, options) => http("DELETE", path, { params, ...(options || {}) }); window.apiUpload = (path, formData, params, options) => http("POST", path, { params, data: formData, ...(options || {}) }); // Query helpers for the *current page* (read-only) window.qs = qs; // URLSearchParams instance window.getQueryParam = (name, defVal = null) => qs.has(name) ? qs.get(name) : defVal; window.getAllQueryParams = () => Object.fromEntries(qs.entries()); })();