import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig, } from 'axios'; import { API_CONFIG } from '@/lib/config'; import { ApiError, NetworkError } from '@/lib/errors'; import { HTTP_STATUS, STORAGE_KEYS } from '@/utils/constants'; // Create axios instance export const apiClient = axios.create({ baseURL: API_CONFIG.BASE_URL, headers: { 'Content-Type': 'application/json', }, timeout: API_CONFIG.TIMEOUT, }); // Request interceptor apiClient.interceptors.request.use( (config: InternalAxiosRequestConfig) => { // Add auth token if available const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, (error: unknown) => Promise.reject(error instanceof Error ? error : new Error(String(error))) ); // Response interceptor apiClient.interceptors.response.use( (response: AxiosResponse) => response, (error: AxiosError) => { const statusCode = error.response?.status; const responseData = error.response?.data as Record; const message = typeof responseData?.message === 'string' ? responseData.message : error.message; const code = typeof responseData?.code === 'string' ? responseData.code : undefined; // Handle specific error types if (!error.response) { // Network error throw new NetworkError('Network connection failed', 0); } if (statusCode && statusCode >= HTTP_STATUS.BAD_REQUEST) { throw new ApiError( message, statusCode, code, responseData?.details as Record | undefined ); } return Promise.reject(error); } );