onsitesurvey/src/hooks/useAxios.ts

121 lines
3.3 KiB
TypeScript

import axios, { AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import Config from '@/config/config.export'
import { useSpinnerStore } from '@/store/spinnerStore'
export function useAxios() {
const requestHandler = (config: InternalAxiosRequestConfig) => {
useSpinnerStore.getState().setIsShow(true)
return config
}
const responseHandler = (response: AxiosResponse) => {
/* spinner 조작 커스텀이 필요한 경우 api 응답 헤더에 spinner-state: true 추가 */
if (!response.headers['spinner-state']) {
useSpinnerStore.getState().setIsShow(false)
}
response.data = transferResponse(response)
return response
}
const errorHandler = (error: any) => {
useSpinnerStore.getState().setIsShow(false)
return Promise.reject(error)
}
const createAxiosInstance = (url: string | null | undefined) => {
const baseURL = url || Config().baseUrl
return axios.create({
baseURL,
headers: {
Accept: 'application/json',
},
})
}
const axiosInstance = (url: string | null | undefined) => {
const instance = axios.create({
baseURL: url || Config().baseUrl,
headers: {
Accept: 'application/json',
},
})
instance.interceptors.request.use(
// (config) => {
// return config
// },
// (error) => {
// return Promise.reject(error)
// },
(config) => requestHandler(config),
(error) => errorHandler(error),
)
instance.interceptors.response.use(
// (response) => {
// response.data = transferResponse(response)
// return response
// },
// (error) => {
// return Promise.reject(error)
// },
(response) => responseHandler(response),
(error) => errorHandler(error),
)
return instance
}
// response데이터가 array, object에 따라 분기하여 키 변환
const transferResponse = (response: any) => {
if (!response.data) return response.data
// 배열인 경우 각 객체의 키를 변환
if (Array.isArray(response.data)) {
return response.data.map((item: any) => transformObjectKeys(item))
}
// 단일 객체인 경우
return transformObjectKeys(response.data)
}
// camel case object 반환
const transformObjectKeys = (obj: any): any => {
if (Array.isArray(obj)) {
return obj.map(transformObjectKeys)
}
if (obj !== null && typeof obj === 'object') {
return Object.keys(obj).reduce((acc: any, key: string) => {
let transformedKey = key
// Handle uppercase snake_case (e.g., USER_NAME -> userName)
// Handle lowercase snake_case (e.g., user_name -> userName)
if (/^[A-Z_]+$/.test(key) || /^[a-z_]+$/.test(key)) {
transformedKey = snakeToCamel(key)
}
// Handle single uppercase word (e.g., ROLE -> role)
else if (/^[A-Z]+$/.test(key)) {
transformedKey = key.toLowerCase()
}
// Preserve existing camelCase
acc[transformedKey] = transformObjectKeys(obj[key])
return acc
}, {})
}
return obj
}
const snakeToCamel = (str: string): string => {
return str.toLowerCase().replace(/([-_][a-z])/g, (group) => group.toUpperCase().replace('-', '').replace('_', ''))
}
return {
axiosInstance,
transferResponse,
transformObjectKeys,
}
}