import axios, { AxiosHeaders, type InternalAxiosRequestConfig } from "axios"; import { config } from "@config/config"; import { useAuthStore } from "@/store/authStore"; import { applyAuthContextHeaders, type AuthContextHeaderOptions, } from "@/lib/requestHeaders"; export const API_URL = config.BACKEND_URL; export const api = axios.create({ baseURL: API_URL, }); export const resolveRequestUrl = (request: { baseURL?: string; url?: string; }) => { const requestUrl = request.url ?? ""; if (/^([a-z][a-z\d+\-.]*:)?\/\//i.test(requestUrl)) { return requestUrl; } const baseURL = request.baseURL ?? ""; if (!baseURL || !requestUrl) { return `${baseURL}${requestUrl}`; } return `${baseURL.replace(/\/+$/, "")}/${requestUrl.replace(/^\/+/, "")}`; }; export interface ApiRequestConfig extends InternalAxiosRequestConfig, AuthContextHeaderOptions {} api.interceptors.request.use(async (request: ApiRequestConfig) => { const headers = new Headers( request.headers ? AxiosHeaders.from(request.headers).toJSON() as Record : undefined, ); await applyAuthContextHeaders(resolveRequestUrl(request), headers, request); request.headers = AxiosHeaders.from(Object.fromEntries(headers.entries())); return request; }); api.interceptors.response.use( (response) => { if ( response.data && typeof response.data === "object" && Array.isArray(response.data.items) && typeof response.data.total === "number" ) { response.data = response.data.items; } return response; }, async (error) => { if (error?.response?.status === 401 && typeof window !== "undefined") { useAuthStore.getState().markSessionExpired("unauthorized"); } return Promise.reject(error); }, );