diff --git a/code/websites/pokedex.online/src/utilities/api-client.js b/code/websites/pokedex.online/src/utilities/api-client.js index e218370..22ab971 100644 --- a/code/websites/pokedex.online/src/utilities/api-client.js +++ b/code/websites/pokedex.online/src/utilities/api-client.js @@ -1,13 +1,13 @@ /** * API Client Utility - * + * * Centralized fetch wrapper with: * - Automatic error handling * - Retry logic with exponential backoff * - Request/response interceptors * - Request deduplication * - Timeout support - * + * * @example * const client = createApiClient({ baseURL: '/api' }); * const data = await client.get('/users'); @@ -66,10 +66,7 @@ export function createApiClient(config = {}) { * Make the actual HTTP request with retries */ async function makeRequest(url, options) { - const { - retries = maxRetries, - ...fetchOptions - } = options; + const { retries = maxRetries, ...fetchOptions } = options; // Merge headers const headers = { @@ -88,9 +85,14 @@ export function createApiClient(config = {}) { while (attempt <= retries) { try { // Call request interceptor - let requestOptions = { ...fetchOptions, headers, signal: controller.signal }; + let requestOptions = { + ...fetchOptions, + headers, + signal: controller.signal + }; if (onRequest) { - requestOptions = await onRequest(url, requestOptions) || requestOptions; + requestOptions = + (await onRequest(url, requestOptions)) || requestOptions; } const response = await fetch(url, requestOptions); @@ -99,15 +101,17 @@ export function createApiClient(config = {}) { // Call response interceptor let processedResponse = response; if (onResponse) { - processedResponse = await onResponse(response.clone()) || response; + processedResponse = (await onResponse(response.clone())) || response; } // Handle HTTP errors if (!processedResponse.ok) { - const error = new Error(`HTTP ${processedResponse.status}: ${processedResponse.statusText}`); + const error = new Error( + `HTTP ${processedResponse.status}: ${processedResponse.statusText}` + ); error.status = processedResponse.status; error.response = processedResponse; - + // Try to parse error body try { const contentType = processedResponse.headers.get('content-type'); @@ -129,7 +133,6 @@ export function createApiClient(config = {}) { return await processedResponse.json(); } return await processedResponse.text(); - } catch (error) { clearTimeout(timeoutId); lastError = error; @@ -150,7 +153,9 @@ export function createApiClient(config = {}) { // If more retries remaining, wait before retrying if (attempt <= retries) { - await new Promise(resolve => setTimeout(resolve, retryDelay * attempt)); + await new Promise(resolve => + setTimeout(resolve, retryDelay * attempt) + ); } } } @@ -167,22 +172,26 @@ export function createApiClient(config = {}) { return { request, get: (url, options = {}) => request(url, { ...options, method: 'GET' }), - post: (url, data, options = {}) => request(url, { - ...options, - method: 'POST', - body: JSON.stringify(data) - }), - put: (url, data, options = {}) => request(url, { - ...options, - method: 'PUT', - body: JSON.stringify(data) - }), - patch: (url, data, options = {}) => request(url, { - ...options, - method: 'PATCH', - body: JSON.stringify(data) - }), - delete: (url, options = {}) => request(url, { ...options, method: 'DELETE' }) + post: (url, data, options = {}) => + request(url, { + ...options, + method: 'POST', + body: JSON.stringify(data) + }), + put: (url, data, options = {}) => + request(url, { + ...options, + method: 'PUT', + body: JSON.stringify(data) + }), + patch: (url, data, options = {}) => + request(url, { + ...options, + method: 'PATCH', + body: JSON.stringify(data) + }), + delete: (url, options = {}) => + request(url, { ...options, method: 'DELETE' }) }; }