import type { ApiSettings } from "../types"; const STORAGE_KEY = "multimailer.apiSettings"; export function loadApiSettings(): ApiSettings { const storedBaseUrl = localStorage.getItem(`${STORAGE_KEY}.baseUrl`); return { // Empty base URL means "same origin". In Vite dev, /api is proxied to FastAPI. apiBaseUrl: storedBaseUrl !== null ? storedBaseUrl : import.meta.env.VITE_API_BASE_URL ?? "", apiKey: localStorage.getItem(`${STORAGE_KEY}.apiKey`) || "", accessToken: localStorage.getItem(`${STORAGE_KEY}.accessToken`) || "" }; } export function saveApiSettings(settings: ApiSettings): void { localStorage.setItem(`${STORAGE_KEY}.baseUrl`, settings.apiBaseUrl); localStorage.setItem(`${STORAGE_KEY}.apiKey`, settings.apiKey); localStorage.setItem(`${STORAGE_KEY}.accessToken`, settings.accessToken); } export function clearAccessToken(): void { localStorage.removeItem(`${STORAGE_KEY}.accessToken`); } export async function apiFetch(settings: ApiSettings, path: string, init?: RequestInit): Promise { const baseUrl = settings.apiBaseUrl.trim().replace(/\/$/, ""); const url = baseUrl ? `${baseUrl}${path}` : path; const headers = new Headers(init?.headers || {}); if (!(init?.body instanceof FormData) && !headers.has("Content-Type")) { headers.set("Content-Type", "application/json"); } if (settings.accessToken) { headers.set("Authorization", `Bearer ${settings.accessToken}`); } else if (settings.apiKey) { headers.set("X-API-Key", settings.apiKey); } const response = await fetch(url, { ...init, headers }); if (!response.ok) { const text = await response.text(); throw new Error(`${response.status} ${response.statusText}: ${text}`); } if (response.status === 204) { return undefined as T; } const contentType = response.headers.get("content-type") || ""; if (!contentType.includes("application/json")) { return (await response.text()) as T; } return (await response.json()) as T; }