Last active
January 9, 2024 19:04
-
-
Save anymaniax/1efd5ccd7829ab73dc239935739e35da to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type HttpInterceptor = ( | |
options: FetchOptions, | |
) => Promise<FetchOptions> | FetchOptions; | |
type HttpInstance = { | |
baseURL: string; | |
headers: Record<string, string>; | |
}; | |
export const HTTP_INSTANCE: HttpInstance = { | |
baseURL: '', | |
headers: {}, | |
}; | |
export type FetchOptions = { | |
baseURL?: string; | |
headers?: Record<string, string>; | |
url: string; | |
method: | |
| 'get' | |
| 'post' | |
| 'put' | |
| 'delete' | |
| 'patch' | |
| 'GET' | |
| 'POST' | |
| 'PUT' | |
| 'DELETE' | |
| 'PATCH'; | |
params?: any; | |
data?: any; | |
responseType?: string; | |
signal?: AbortSignal; | |
}; | |
export type FetchResponse<T = unknown> = { | |
data: T; | |
headers: { | |
authorization?: string | null; | |
}; | |
}; | |
export type FetchError<T = unknown> = { | |
data: T; | |
status: number; | |
}; | |
export const getResponseBody = <T>(response: Response): Promise<T> => { | |
const contentType = response.headers.get('content-type'); | |
if (contentType && contentType.includes('application/json')) { | |
return response.json(); | |
} | |
if (contentType && contentType.includes('application/pdf')) { | |
return response.blob() as Promise<T>; | |
} | |
return response.text() as Promise<T>; | |
}; | |
export const fetchInstance = async <T>( | |
config: FetchOptions, | |
init?: ResponseInit | |
): Promise<FetchResponse<T>> => { | |
const isFormData = config.headers?.['Content-Type'] === 'multipart/form-data'; | |
const isJson = config.headers?.['Content-Type'] === 'application/json'; | |
const baseUrl = config.baseURL; | |
const headers = { | |
...config.headers, | |
...(isJson ? { 'Content-Type': 'application/json' } : {}), | |
}; | |
// Remove Content-Type header if it's not needed to avoid issues | |
if (!isJson) { | |
delete headers['Content-Type']; | |
} | |
const response = await fetch( | |
`${baseUrl}${config.url}` + | |
(config.params ? `?${new URLSearchParams(config.params)}` : ''), | |
{ | |
method: config.method, | |
...(config.data | |
? { body: !isFormData ? JSON.stringify(config.data) : config.data } | |
: {}), | |
headers, | |
signal: config.signal, | |
}, | |
); | |
const data = await getResponseBody<T>(response); | |
if (!response.ok) { | |
throw { | |
status: response.status, | |
data, | |
}; | |
} | |
return { | |
headers: { | |
authorization: response.headers.get('authorization'), | |
}, | |
data, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment