PRMSChallenge / web /script.js
Vineela Gampa
Fixing build yet another time
0d0f773 unverified
// 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());
})();