import axios, {type AxiosError, type AxiosRequestConfig, type Method} from 'axios'; import JSONbig from 'json-bigint'; // Create a JSONbig instance that stores big integers as strings const JSONbigString = JSONbig({ storeAsString: true }); const apiClient = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL || '/api', timeout: 10000, // transformResponse is used to parse JSON with big integers (Long type from backend) as strings. // This prevents precision loss in JavaScript. transformResponse: [(data) => { // Do not transform if data is not a string or is empty if (!data || typeof data !== 'string') { return data; } try { // Use the configured JSONbig instance to parse the data return JSONbigString.parse(data); } catch (e) { // If parsing fails, it might not be JSON, so return original data // This is the default behavior of axios if parsing fails return data; } }], }); export const isLoginRequiredError = (error: any): boolean => { if (!axios.isAxiosError(error) || !error.response) { return false; } const LOGIN_REQUIRED_ERROR_CODE = ['A001', 'A002', 'A003', 'A006']; const code = error.response?.data?.code; return code && LOGIN_REQUIRED_ERROR_CODE.includes(code); } async function request( method: Method, endpoint: string, data: object = {}, isRequiredAuth: boolean = false ): Promise { const config: AxiosRequestConfig = { method, url: endpoint, headers: { 'Content-Type': 'application/json' }, }; const accessToken = localStorage.getItem('accessToken'); if (accessToken) { if (!config.headers) { config.headers = {}; } config.headers['Authorization'] = `Bearer ${accessToken}`; } if (method.toUpperCase() !== 'GET') { config.data = data; } try { const response = await apiClient.request(config); return response.data.data; } catch (error: unknown) { const axiosError = error as AxiosError<{ code: string, message: string }>; console.error('API 요청 실패:', axiosError); throw axiosError; } } async function get(endpoint: string, isRequiredAuth: boolean = false): Promise { return request('GET', endpoint, {}, isRequiredAuth); } async function post(endpoint: string, data: object = {}, isRequiredAuth: boolean = false): Promise { return request('POST', endpoint, data, isRequiredAuth); } async function put(endpoint: string, data: object = {}, isRequiredAuth: boolean = false): Promise { return request('PUT', endpoint, data, isRequiredAuth); } async function patch(endpoint: string, data: object = {}, isRequiredAuth: boolean = false): Promise { return request('PATCH', endpoint, data, isRequiredAuth); } async function del(endpoint: string, isRequiredAuth: boolean = false): Promise { return request('DELETE', endpoint, {}, isRequiredAuth); } export default { get, post, put, patch, del };