mini-fetchy
Version:
Custom fetch client for reusable HTTP calls
47 lines (39 loc) • 1.25 kB
text/typescript
// fetchClient.ts
type FetchOptions = {
baseUrl?: string;
headers?: Record<string, string>;
timeout?: number;
};
export const createFetchClient = (config: FetchOptions) => {
return async (url: string, options: RequestInit = {}) => {
const controller = new AbortController();
const id = config.timeout
? setTimeout(() => controller.abort(), config.timeout)
: null;
// Safely combine baseUrl with url path
const fullUrl = config.baseUrl
? config.baseUrl.replace(/\/+$/, '') + '/' + url.replace(/^\/+/, '')
: url;
try {
const response = await fetch(fullUrl, {
...options,
headers: {
...config.headers,
...(options.headers || {}),
},
signal: controller.signal,
});
const contentType = response.headers.get('Content-Type') || '';
if (!response.ok) {
const errorText = await response.text();
throw new Error(`HTTP ${response.status}: ${errorText}`);
}
if (contentType.includes('application/json')) {
return await response.json();
}
return await response.text();
} finally {
if (id) clearTimeout(id);
}
};
};