UNPKG

@remcostoeten/fync

Version:

A unified TypeScript library for easy access to popular APIs (GitHub, Spotify, GitLab, etc.)

116 lines 4.21 kB
import { HttpErrorHandler, initializeErrorHandling } from "../../core/errors/exports"; export function createHttpClient(config) { // Initialize error handling system initializeErrorHandling(); // Create error handler with Spotify-specific retry config const errorHandler = new HttpErrorHandler({ maxAttempts: 3, baseDelay: 1000, maxDelay: 30000, backoffMultiplier: 2, retryableStatuses: [408, 429, 500, 502, 503, 504], }); const cache = new Map(); function getCacheKey(url, options = {}) { return `${url}:${JSON.stringify(options)}`; } function isExpired(timestamp, ttl) { return Date.now() - timestamp > ttl; } function getFromCache(key) { const cached = cache.get(key); if (!cached) return null; if (isExpired(cached.timestamp, cached.ttl)) { cache.delete(key); return null; } return cached.data; } function setCache(key, data, ttl) { cache.set(key, { data, timestamp: Date.now(), ttl, }); } async function makeRequest(url, method, data, options = {}) { const shouldCache = options.cache !== false && config.cache !== false; const cacheTTL = options.cacheTTL || config.cacheTTL || 300000; // Check cache for GET requests if (shouldCache && method === "GET") { const cacheKey = getCacheKey(url, options); const cached = getFromCache(cacheKey); if (cached) return cached; } // Use error handler to execute the request with retry logic const result = await errorHandler.execute(async () => { const fetchOptions = { method, headers: { ...(config.accessToken && { "Authorization": `Bearer ${config.accessToken}` }), "Content-Type": "application/json", ...options.headers, }, }; if (data && (method === "POST" || method === "PUT" || method === "DELETE")) { fetchOptions.body = JSON.stringify(data); } const response = await fetch(url, fetchOptions); if (!response.ok) { // Create a structured error message that our transformers can understand let errorMessage = `HTTP ${response.status}: ${response.statusText}`; try { const errorData = (await response.json()); if (errorData.error) { if (typeof errorData.error === "string") { errorMessage = errorData.error; } else { errorMessage = errorData.error.message || errorMessage; } } } catch { // Use the HTTP status error message } throw new Error(errorMessage); } if (response.status === 204) { return undefined; } return (await response.json()); }, { service: "spotify", endpoint: url, method, userAgent: config.userAgent || `@remcostoeten/fync/3.3.0`, }); // Cache successful GET requests if (shouldCache && method === "GET") { const cacheKey = getCacheKey(url, options); setCache(cacheKey, result, cacheTTL); } return result; } function get(url, options) { return makeRequest(url, "GET", undefined, options); } function post(url, data, options) { return makeRequest(url, "POST", data, options); } function put(url, data, options) { return makeRequest(url, "PUT", data, options); } function deleteRequest(url, data, options) { return makeRequest(url, "DELETE", data, options); } return { get, post, put, delete: deleteRequest, }; } //# sourceMappingURL=http-with-errors.js.map