45 lines
1.4 KiB
TypeScript
45 lines
1.4 KiB
TypeScript
/**
|
|
* orval이 생성하는 API 클라이언트의 HTTP 어댑터.
|
|
*
|
|
* - `kyInstance`: 공통 타임아웃·리트라이·훅(인증 토큰 주입, 401 처리 등 추후 추가) 설정
|
|
* - `customFetcher`: orval `httpClient: 'fetch'` 모드의 custom mutator.
|
|
* 생성된 코드가 `customFetcher(url, init)`로 호출하면 ky로 요청을 보내고,
|
|
* 생성 타입이 기대하는 `{ status, data, headers }` 형태로 응답을 정규화함.
|
|
*/
|
|
import ky, { type KyInstance } from 'ky'
|
|
|
|
export const kyInstance: KyInstance = ky.create({
|
|
timeout: 10_000,
|
|
retry: 1,
|
|
// orval generated 타입이 4xx/5xx 응답도 data로 받아오므로 throw 비활성
|
|
throwHttpErrors: false,
|
|
hooks: {
|
|
beforeRequest: [
|
|
// TODO: 인증 토큰 주입
|
|
// request => {
|
|
// const token = localStorage.getItem('token')
|
|
// if (token) request.headers.set('Authorization', `Bearer ${token}`)
|
|
// },
|
|
],
|
|
afterResponse: [
|
|
// TODO: 401 처리, 토큰 갱신 등
|
|
],
|
|
},
|
|
})
|
|
|
|
export const customFetcher = async <T>(
|
|
url: string,
|
|
init?: RequestInit,
|
|
): Promise<T> => {
|
|
const response = await kyInstance(url, init as Parameters<KyInstance>[1])
|
|
let data: unknown = null
|
|
try {
|
|
data = await response.json()
|
|
} catch {
|
|
// 빈 응답이거나 JSON 파싱 실패
|
|
}
|
|
return { status: response.status, data, headers: response.headers } as T
|
|
}
|
|
|
|
export default customFetcher
|