generated from pricelees/issue-pr-template
<!-- 제목 양식 --> <!-- [이슈번호] 작업 요약 (예시: [#10] Gitea 템플릿 생성) --> ## 📝 관련 이슈 및 PR **PR과 관련된 이슈 번호** - #44 ## ✨ 작업 내용 <!-- 어떤 작업을 했는지 알려주세요! --> - 매장 기능 도입 및 기존 기능에 적용 - 관리자 타입(본사, 매장, 전체) 분리 및 API별 적용 ## 🧪 테스트 <!-- 어떤 테스트를 생각했고 진행했는지 알려주세요! --> - 신규 기능 및 매장 기능 도입으로 수정된 기존 API 모두 통합 테스트 완료 ## 📚 참고 자료 및 기타 <!-- 참고한 자료, 또는 논의할 사항이 있다면 알려주세요! --> - 아직 미결제 예약 스케쥴링 작업 등 추가적인 작업이 필요하긴 하지만, 이 작업들은 배포 후 추가로 진행할 예정 - 다음 작업은 배포 + 초기 데이터 삽입 Reviewed-on: #45 Co-authored-by: pricelees <priceelees@gmail.com> Co-committed-by: pricelees <priceelees@gmail.com>
123 lines
3.8 KiB
TypeScript
123 lines
3.8 KiB
TypeScript
import axios, {type AxiosError, type AxiosRequestConfig, type Method} from 'axios';
|
|
import JSONbig from 'json-bigint';
|
|
import { PrincipalType } from './auth/authTypes';
|
|
|
|
// 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<T>(
|
|
method: Method,
|
|
endpoint: string,
|
|
data: object = {},
|
|
type: PrincipalType,
|
|
): Promise<T> {
|
|
const config: AxiosRequestConfig = {
|
|
method,
|
|
url: endpoint,
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
};
|
|
|
|
const accessTokenKey = type === PrincipalType.ADMIN ? 'adminAccessToken' : 'accessToken';
|
|
const accessToken = localStorage.getItem(accessTokenKey);
|
|
|
|
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<T>(endpoint: string): Promise<T> {
|
|
return request<T>('GET', endpoint, {}, PrincipalType.USER);
|
|
}
|
|
|
|
async function adminGet<T>(endpoint: string): Promise<T> {
|
|
return request<T>('GET', endpoint, {}, PrincipalType.ADMIN);
|
|
}
|
|
|
|
async function post<T>(endpoint: string, data: object = {}): Promise<T> {
|
|
return request<T>('POST', endpoint, data, PrincipalType.USER);
|
|
}
|
|
|
|
async function adminPost<T>(endpoint: string, data: object = {}): Promise<T> {
|
|
return request<T>('POST', endpoint, data, PrincipalType.ADMIN);
|
|
}
|
|
|
|
async function put<T>(endpoint: string, data: object = {}): Promise<T> {
|
|
return request<T>('PUT', endpoint, data, PrincipalType.USER);
|
|
}
|
|
|
|
async function adminPut<T>(endpoint: string, data: object = {}): Promise<T> {
|
|
return request<T>('PUT', endpoint, data, PrincipalType.ADMIN);
|
|
}
|
|
|
|
async function patch<T>(endpoint: string, data: object = {}): Promise<T> {
|
|
return request<T>('PATCH', endpoint, data, PrincipalType.USER);
|
|
}
|
|
|
|
async function adminPatch<T>(endpoint: string, data: object = {}): Promise<T> {
|
|
return request<T>('PATCH', endpoint, data, PrincipalType.ADMIN);
|
|
}
|
|
|
|
async function del<T>(endpoint: string): Promise<T> {
|
|
return request<T>('DELETE', endpoint, {}, PrincipalType.USER);
|
|
}
|
|
|
|
async function adminDel<T>(endpoint: string): Promise<T> {
|
|
return request<T>('DELETE', endpoint, {}, PrincipalType.ADMIN);
|
|
}
|
|
|
|
export default {
|
|
get, adminGet,
|
|
post, adminPost,
|
|
put, adminPut,
|
|
patch, adminPatch,
|
|
del, adminDel,
|
|
};
|