UNPKG

@droppii-org/chat-sdk

Version:

Droppii React Chat SDK

66 lines (65 loc) 2.79 kB
import axios from "axios"; import useAuthStore from "../store/auth"; const TIMEOUT = 90000; export const apiInstance = axios.create({ headers: { Accept: "application/json", "Content-Type": "application/json", }, timeout: TIMEOUT, }); // Module-level refresh promise cache to prevent concurrent refresh calls let sdkRefreshPromise = null; apiInstance.interceptors.request.use((config) => { return Object.assign(Object.assign({}, config), { baseURL: useAuthStore.getState().apiAddress, headers: Object.assign(Object.assign({}, config.headers), { Authorization: `Bearer ${useAuthStore.getState().accessToken}`, token: useAuthStore.getState().chatToken }) }); }, (error) => { // Handle errors globally return Promise.reject(error); }); // Response interceptor for 401 handling - delegates to consumer app apiInstance.interceptors.response.use((response) => response, async (error) => { var _a; const originalRequest = error.config; // Prevent infinite loops with _retry flag if (originalRequest._retry) { return Promise.reject(error); } // Handle 401 responses if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 401) { const { onTokenRefresh, onAuthError } = useAuthStore.getState(); // No callback provided, reject immediately if (!onTokenRefresh) { const authError = new Error("Token expired, no refresh callback provided"); onAuthError === null || onAuthError === void 0 ? void 0 : onAuthError(authError); return Promise.reject(error); } originalRequest._retry = true; try { // Cache refresh promise to ensure single refresh call for concurrent requests if (!sdkRefreshPromise) { sdkRefreshPromise = onTokenRefresh() .then((newToken) => { // Update SDK's access token useAuthStore.getState().setAccessToken(newToken); return newToken; }) .catch((err) => { // Notify consumer app of auth error onAuthError === null || onAuthError === void 0 ? void 0 : onAuthError(err); throw err; }) .finally(() => { sdkRefreshPromise = null; }); } const newToken = await sdkRefreshPromise; // Retry original request with new token originalRequest.headers.Authorization = `Bearer ${newToken}`; return apiInstance(originalRequest); } catch (refreshError) { return Promise.reject(error); } } return Promise.reject(error); });