UNPKG

@remcostoeten/fync

Version:

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

94 lines 3.6 kB
import { memoize } from "../http/memoize"; export function createChainableClient(config, httpClient, serviceConfig, pathSegments = []) { function buildPath() { return "/" + pathSegments.join("/"); } async function executeRequest(method, data, options) { const path = buildPath(); const mergedOptions = { ...serviceConfig.defaultOptions, ...options }; const { params, cache = config.cache !== false } = mergedOptions; async function requestFn() { if (mergedOptions.paginate || mergedOptions.allPages) { return handlePagination(path, params, mergedOptions); } return (await httpClient.get(path, params)).data; } if (cache) { const cacheKey = `${serviceConfig.cacheKeyPrefix}:${path}:${JSON.stringify(params || {})}`; function getCacheKey() { return cacheKey; } const memoizedFn = memoize(requestFn, getCacheKey, { ttl: mergedOptions.cacheTTL ?? config.cacheTTL ?? 300000, }); return memoizedFn(); } return requestFn(); } async function handlePagination(path, params, options) { if (!serviceConfig.supportsPagination || !httpClient.getPaginated) { throw new Error("Pagination not supported for this service"); } const response = await httpClient.getPaginated(path, params); if (options?.allPages && response.nextUrl) { const allData = [...response.data]; let nextUrl = response.nextUrl; while (nextUrl) { const nextResponse = await httpClient.getPaginated(nextUrl); allData.push(...nextResponse.data); nextUrl = nextResponse.nextUrl; } return allData; } return response.data; } async function* streamPages(options) { if (!serviceConfig.supportsPagination || !httpClient.getPaginated) { throw new Error("Streaming not supported for this service"); } const path = buildPath(); const { params } = options || {}; let response = await httpClient.getPaginated(path, params); yield* response.data; while (response.nextUrl) { response = await httpClient.getPaginated(response.nextUrl); yield* response.data; } } function createMethodHandler(method) { function getHandler(options) { return executeRequest(method, undefined, options); } return getHandler; } return new Proxy({}, { get(target, prop) { if (prop === "get") { return createMethodHandler("GET"); } if (prop === "paginate") { function paginateHandler(options) { return executeRequest("GET", undefined, { ...options, paginate: true, }); } return paginateHandler; } if (prop === "stream") { function streamHandler(options) { return streamPages(options); } return streamHandler; } if (prop === "path") { return buildPath; } return createChainableClient(config, httpClient, serviceConfig, [ ...pathSegments, String(prop), ]); }, }); } //# sourceMappingURL=factory.js.map