import type { AxiosInstance, AxiosResponse } from 'axios'; import { type Fetcher, type Method, createApiClient } from '../generated/api-client/api-client'; import { TanstackQueryApiClient } from '../generated/api-client/tanstack-client'; const API_BASE_URL: string | undefined = import.meta.env.VITE_API_BASE_URL; const get_fetch: (axios: AxiosInstance) => Fetcher['fetch'] = (axios) => async ({ method, url: incomingUrl, parameters: params }) => { // Use a plain object for Axios headers const headers: Record = {}; // Replace path parameters (supports both {param} and :param formats) const actualUrl = replacePathParams(incomingUrl.toString(), (params?.path ?? {}) as Record); const url = new URL(actualUrl); // Handle query parameters if (params?.query) { const searchParams = new URLSearchParams(); Object.entries(params.query).forEach(([key, value]) => { if (value != null) { // Skip null/undefined values if (Array.isArray(value)) { value.forEach((val) => val != null && searchParams.append(key, String(val))); } else { searchParams.append(key, String(value)); } } }); url.search = searchParams.toString(); } // Handle request body for mutation methods (use Axios `data`) const data = (['post', 'put', 'patch', 'delete'] satisfies Method[] as string[]).includes(method.toLowerCase()) ? params?.body : undefined; if (data != null) { headers['Content-Type'] = 'application/json'; } // Add custom headers if (params?.header) { Object.entries(params.header).forEach(([key, value]) => { if (value != null) { headers[key] = String(value); } }); } const response = await axios(url.toString(), { method: method.toUpperCase(), ...(data !== undefined && { data }), headers: headers, }); return axiosResponseToFetchResponse(response); }; function axiosResponseToFetchResponse(response: AxiosResponse): Response { const headers = new Headers(); Object.entries(response.headers).forEach(([key, value]) => { if (Array.isArray(value)) { value.forEach((val) => headers.append(key, val)); } else { headers.append(key, value); } }); return new Response(response.data, { status: response.status, statusText: response.statusText, headers: headers, }); } /** * Replace path parameters in URL * Supports both OpenAPI format {param} and Express format :param */ function replacePathParams(url: string, params: Record): string { return url.replace(/{(\w+)}/g, (_, key: string) => params[key] || `{${key}}`).replace(/:([a-zA-Z0-9_]+)/g, (_, key: string) => params[key] || `:${key}`); } export function createApi(axios: AxiosInstance) { return createApiClient( { fetch: get_fetch(axios), }, API_BASE_URL ?? window.location.origin ); } export function createTanstackApi(axios: AxiosInstance) { return new TanstackQueryApiClient(createApi(axios)); }