UNPKG

create-kalp-boilerplate

Version:

A Kalp CLI tool to generate a React boilerplate

102 lines (87 loc) 3.01 kB
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'; import { API_CONFIG } from './config'; // Define types for tokens and responses interface TokenResponse { access_token: string; refresh_token: string; } interface APIResponse<T = any> { success: boolean; result: T; } // Utility functions to manage tokens const getAccessToken = (): string | null => localStorage.getItem('access_token'); const getRefreshToken = (): string | null => localStorage.getItem('refresh_token'); // Token refresh logic let isRefreshing = false; // Function to create Axios instances const createAxiosInstance = (baseURL: string, defaultHeaders: Record<string, string> = {}): AxiosInstance => { return axios.create({ baseURL, timeout: API_CONFIG.TIMEOUT, headers: defaultHeaders, }); }; // Primary axios instance export const axiosInstance: AxiosInstance = createAxiosInstance(API_CONFIG.BASE_URL); // Request interceptor axiosInstance.interceptors.request.use( (config: AxiosRequestConfig): AxiosRequestConfig => { const token = getAccessToken(); if (token) { config.headers = { ...config.headers, Authorization: `Bearer ${token}`, }; } return config; }, (error: AxiosError): Promise<AxiosError> => Promise.reject(error) ); // Response interceptor axiosInstance.interceptors.response.use( (response: AxiosResponse): AxiosResponse => response, async (error: AxiosError): Promise<AxiosResponse | void> => { const originalRequest = error.config; if (error.response?.status === 403) { try { await axios.get(`${API_CONFIG.BASE_URL}/users/logout`, { headers: { Authorization: `Bearer ${getAccessToken()}`, 'Content-Type': 'application/json', }, }); } catch (logoutError) { console.error('Logout failed:', logoutError); } return Promise.reject(error); } if (error.response?.status === 401 && !originalRequest._retry) { originalRequest._retry = true; if (!isRefreshing) { isRefreshing = true; try { const response = await axios.get<APIResponse<TokenResponse>>(`${API_CONFIG.BASE_URL}/users/refresh-token`, { headers: { refresh_token: getRefreshToken() || '', 'Content-Type': 'application/json', }, }); const { access_token, refresh_token } = response.data.result; localStorage.setItem('access_token', access_token); localStorage.setItem('refresh_token', refresh_token); isRefreshing = false; originalRequest.headers = { ...originalRequest.headers, Authorization: `Bearer ${access_token}`, }; return axiosInstance(originalRequest); } catch (refreshError) { isRefreshing = false; return Promise.reject(refreshError); } } } return Promise.reject(error); } );