import type { ApiError } from "@/types" const API_BASE = "/admin/api" let _csrfToken: string | null = null export function setCsrfToken(token: string | null) { _csrfToken = token } export function getCsrfToken() { return _csrfToken } class ApiClientError extends Error { status: number data: ApiError constructor(status: number, data: ApiError) { super(data.error || "Request failed") this.status = status this.data = data } } export { ApiClientError } async function request( path: string, options?: RequestInit, ): Promise { const headers: Record = { ...(options?.headers as Record), } if (_csrfToken && options?.method && options.method !== "GET") { headers["X-CSRF-Token"] = _csrfToken } if (options?.body && typeof options.body === "string") { headers["Content-Type"] = "application/json" } const res = await fetch(`${API_BASE}${path}`, { ...options, headers, credentials: "same-origin", }) const data = await res.json() if (!res.ok) { if (res.status === 401) { setCsrfToken(null) } throw new ApiClientError(res.status, data) } return data as T } export const api = { session: () => request("/session"), login: (password: string) => request<{ success: boolean; error?: string }>("/login", { method: "POST", body: JSON.stringify({ password }), }), logout: () => request<{ success: boolean }>("/logout", { method: "POST" }), stats: () => request("/stats"), getToken: () => request("/token"), getTokens: () => request("/tokens"), saveToken: (raw_token: string) => request("/token", { method: "POST", body: JSON.stringify({ raw_token }), }), createTokenAccount: (payload: { name?: string raw_token: string enabled?: boolean max_concurrency?: number min_interval_seconds?: number }) => request("/tokens", { method: "POST", body: JSON.stringify(payload), }), updateTokenAccount: ( id: string, payload: { name?: string raw_token?: string enabled?: boolean max_concurrency?: number min_interval_seconds?: number }, ) => request(`/tokens/${id}`, { method: "PATCH", body: JSON.stringify(payload), }), deleteTokenAccount: (id: string) => request(`/tokens/${id}`, { method: "DELETE", }), refreshToken: () => request("/token/refresh", { method: "POST", }), refreshTokenAccount: (id: string) => request(`/tokens/${id}/refresh`, { method: "POST", }), validateToken: () => request("/token/validate"), validateTokenAccount: (id: string) => request(`/tokens/${id}/validate`), getKeys: () => request("/keys"), createKey: (name?: string) => request("/keys", { method: "POST", body: JSON.stringify({ name }), }), deleteKey: (key: string) => request(`/keys/${key}`, { method: "DELETE", }), getLogs: (filters: Partial) => { const params = new URLSearchParams() for (const [k, v] of Object.entries(filters)) { if (v) params.set(k, v) } const qs = params.toString() return request(`/logs${qs ? `?${qs}` : ""}`) }, getLogDetail: (requestId: string) => request(`/logs/${requestId}`), }