Files
simple-admin/src/shared/config/api/httpClient.ts
2025-11-12 13:53:30 +05:00

117 lines
3.1 KiB
TypeScript

import i18n from "@/shared/config/i18n";
import {
getAuthToken,
getRefAuthToken,
removeAuthToken,
removeRefAuthToken,
setAuthToken,
} from "@/shared/lib/authCookies";
import axios, { AxiosError } from "axios";
import { BASE_URL } from "./URLs";
let isRefreshing = false;
let failedQueue: {
resolve: (token: string) => void;
reject: (error: any) => void;
}[] = [];
const processQueue = (error: any, token: string | null = null) => {
failedQueue.forEach((prom) => {
if (error) prom.reject(error);
else if (token) prom.resolve(token);
});
failedQueue = [];
};
const httpClient = axios.create({
baseURL: BASE_URL,
timeout: 10000,
});
httpClient.interceptors.request.use(
async (config) => {
const method: string = (config.method || "").toLowerCase();
if (method === "get") {
// GET so'rovlarda hozirgi i18n tilini yuboramiz
config.headers["Accept-Language"] = i18n.language;
} else if (["put", "post", "delete"].includes(method)) {
// PUT, POST, DELETE da faqat "uz"
config.headers["Accept-Language"] = "uz";
}
const accessToken = getAuthToken();
if (accessToken) {
config.headers["Authorization"] = `Bearer ${accessToken}`;
}
return config;
},
(error) => Promise.reject(error),
);
httpClient.interceptors.response.use(
(response) => response,
async (error: AxiosError) => {
const originalRequest = error.config as any;
if (error.response?.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
return new Promise((resolve, reject) => {
failedQueue.push({ resolve, reject });
})
.then((token) => {
originalRequest.headers["Authorization"] = `Bearer ${token}`;
return httpClient(originalRequest);
})
.catch((err) => Promise.reject(err));
}
originalRequest._retry = true;
isRefreshing = true;
const refreshToken = getRefAuthToken();
if (!refreshToken) {
removeAuthToken();
removeRefAuthToken();
window.location.href = "/login";
return Promise.reject(error);
}
try {
const response = await axios.post(`${BASE_URL}auth/token/refresh/`, {
refresh: refreshToken,
});
const newAccessToken = response.data.access;
setAuthToken(newAccessToken);
httpClient.defaults.headers["Authorization"] =
`Bearer ${newAccessToken}`;
processQueue(null, newAccessToken);
originalRequest.headers["Authorization"] = `Bearer ${newAccessToken}`;
return httpClient(originalRequest);
} catch (refreshError: any) {
processQueue(refreshError, null);
removeAuthToken();
removeRefAuthToken();
const status = refreshError.response?.status;
if ([401].includes(status)) {
window.location.href = "/login";
}
return Promise.reject(refreshError);
} finally {
isRefreshing = false;
}
}
console.error("API error:", error);
return Promise.reject(error);
},
);
export default httpClient;