import { AuthApi } from "./AuthApi"; interface APIResponse { data: any; status: number; } export class ApiError extends Error { constructor(message: string, public code: number, public data: any) { super(message); } } export class APIClient { /** * Get backend URL */ static backendURL(): string { const URL = import.meta.env.VITE_APP_BACKEND ?? ""; if (URL.length === 0) throw new Error("Backend URL undefined!"); return URL; } /** * Check out whether the backend is accessed through * HTTPS or not */ static IsBackendSecure(): boolean { return this.backendURL().startsWith("https"); } /** * Perform a request on the backend */ static async exec(args: { uri: string; method: "GET" | "POST" | "DELETE" | "PATCH" | "PUT"; allowFail?: boolean; jsonData?: any; formData?: FormData; }): Promise { let body = undefined; let headers: any = { "X-auth-token": AuthApi.SignedIn ? AuthApi.AuthToken : "none", }; // JSON request if (args.jsonData) { headers["Content-Type"] = "application/json"; body = JSON.stringify(args.jsonData); } // Form data request else if (args.formData) { body = args.formData; } const res = await fetch(this.backendURL() + args.uri, { method: args.method, body: body, headers: headers, }); // Process response let data; if (res.headers.get("content-type") === "application/json") data = await res.json(); else data = await res.blob(); // Handle expired tokens if (res.status === 412) { AuthApi.RemoveAuthToken(); window.location.href = "/"; } if (!args.allowFail && !res.ok) throw new ApiError("Request failed!", res.status, data); return { data: data, status: res.status, }; } }