UNPKG

tskew

Version:

TypeScript interface to Kew Gardens botanical data services

78 lines 3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Api = void 0; class Api { constructor(baseUrl, config = {}) { this.baseUrl = baseUrl; this.config = { timeout: 30000, retries: 3, retryDelay: 1000, ...config, }; } buildUrl(endpoint, params = {}) { // Ensure baseUrl ends with / and endpoint starts with / const baseUrlNormalized = this.baseUrl.endsWith("/") ? this.baseUrl : this.baseUrl + "/"; const endpointNormalized = endpoint.startsWith("/") ? endpoint.slice(1) : endpoint; const url = new URL(endpointNormalized, baseUrlNormalized); Object.entries(params).forEach(([key, value]) => { if (value !== undefined && value !== null) { url.searchParams.append(key, String(value)); } }); return url.toString(); } async makeRequest(url, retryCount = 0) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), this.config.timeout); try { const response = await fetch(url, { method: "GET", headers: { "User-Agent": "python-requests/2.31.0", Accept: "*/*", "Accept-Encoding": "gzip, deflate", Connection: "keep-alive", }, signal: controller.signal, }); clearTimeout(timeoutId); // Check if response is ok if (!response.ok) { // Match pykew behavior: retry on status code 249 (rate limit) if (response.status === 249 && retryCount < this.config.retries) { // Wait 5 seconds like pykew does await new Promise((resolve) => setTimeout(resolve, 5000)); return this.makeRequest(url, retryCount + 1); } const errorText = await response.text(); throw new Error(`HTTP ${response.status}: ${response.statusText}. ${errorText}`); } const data = await response.json(); return data; } catch (error) { clearTimeout(timeoutId); if (error.name === "AbortError") { throw new Error(`Request timeout after ${this.config.timeout}ms`); } // For other errors, retry if configured if (retryCount < this.config.retries) { await new Promise((resolve) => setTimeout(resolve, this.config.retryDelay)); return this.makeRequest(url, retryCount + 1); } throw error; } } async get(endpoint, params = {}) { const url = this.buildUrl(endpoint, params); return this.makeRequest(url); } } exports.Api = Api; //# sourceMappingURL=api.js.map