Files
TJWaterFrontend_Refine/src/lib/api.ts
T

68 lines
1.8 KiB
TypeScript

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<string, string>
: 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);
},
);