| const defaultHeaders = { |
| 'Content-Type': 'application/json' |
| }; |
|
|
| async function request(url, options = {}) { |
| const { method = 'GET', body, headers = {}, signal, responseType, returnResponse = false } = options; |
| const init = { |
| method, |
| headers: body instanceof FormData ? headers : { ...defaultHeaders, ...headers }, |
| body: body instanceof FormData ? body : body ? JSON.stringify(body) : undefined, |
| signal, |
| credentials: 'same-origin' |
| }; |
|
|
| const response = await fetch(url, init); |
| const contentType = response.headers.get('content-type') || ''; |
| const expectedType = responseType || (contentType.includes('application/json') ? 'json' : 'text'); |
| let payload; |
|
|
| if (expectedType === 'blob') { |
| payload = await response.blob(); |
| } else if (expectedType === 'json') { |
| payload = await response.json(); |
| } else { |
| payload = await response.text(); |
| } |
|
|
| if (!response.ok) { |
| const message = payload?.message || response.statusText; |
| throw new Error(message); |
| } |
|
|
| if (returnResponse) { |
| return { data: payload, headers: response.headers, status: response.status }; |
| } |
|
|
| return payload; |
| } |
|
|
| const withQuery = (url, params) => { |
| if (!params) return url; |
| const search = new URLSearchParams(params); |
| return `${url}?${search.toString()}`; |
| }; |
|
|
| export const apiClient = { |
| request, |
| get: (url, params, options = {}) => request(withQuery(url, params), { ...options, method: 'GET' }), |
| post: (url, body, options = {}) => request(url, { ...options, method: 'POST', body }), |
| put: (url, body, options = {}) => request(url, { ...options, method: 'PUT', body }), |
| del: (url, options = {}) => request(url, { ...options, method: 'DELETE' }) |
| }; |
|
|
| export default apiClient; |
|
|