UNPKG

rest-envelop

Version:

Wrapper for working with REST API using well-known axios and native fetch modules, with pluggable caching, retry with backoff, and TypeScript typings

79 lines (71 loc) 2.86 kB
const { RequestTimeoutError } = require('./errors'); /** * NodeFetch class provides a simplified interface for making HTTP requests * using the native `fetch` global available in Node.js 18+. * It supports request timeouts via `AbortController`. */ class NodeFetch { constructor(options = {}) { this.baseURL = options.baseURL || ''; this.defaultOptions = options; } /** * Makes an HTTP request with a timeout mechanism. * If a timeout is specified, the request will be aborted if it exceeds the given time limit. * * @param {string} url - The full URL for the HTTP request. * @param {object} options - Configuration options for the request. * @param {number} [options.timeout] - Timeout in milliseconds for the request. * @param {AbortSignal} [options.signal] - AbortSignal for manual request cancellation. * @returns {Promise<object>} A Promise resolving to the response object. * @throws {RequestTimeoutError} If the request times out. * @private */ async #fetchWithTimeout(url, options) { const controller = new AbortController(); const timeout = options.timeout || this.defaultOptions.timeout || 0; const timeoutId = timeout > 0 ? setTimeout(() => controller.abort(), timeout) : null; const externalSignal = options.signal; if (externalSignal) { externalSignal.addEventListener('abort', () => controller.abort(), { once: true }); } try { return await fetch(url, { ...options, signal: controller.signal }); } catch (error) { if (error.name === 'AbortError') throw new RequestTimeoutError(url, timeout); throw error; } finally { if (timeoutId) clearTimeout(timeoutId); } } /** * Makes an HTTP request with the given URL and options. * Merges instance-level default options with request-specific options. * * @param {string} url - The full URL for the HTTP request. * @param {object} [options={}] - Configuration options for the request. * @returns {Promise<object>} A Promise resolving to the response object. * @throws {Error} If the request fails or times out. */ async request(url, options = {}) { return this.#fetchWithTimeout(url, { ...this.defaultOptions, ...options, }); } /** * Creates a new NodeFetch instance with the given configuration. * Useful for creating multiple instances with different base URLs or default settings. * * @param {object} [config={}] - Configuration options for the new instance. * @param {string} [config.baseURL] - The base URL to prepend to all requests. * @param {object} [config.defaultOptions] - Default options to use for all requests. * @returns {NodeFetch} A new instance of the NodeFetch class. */ static create(config = {}) { return new NodeFetch(config); } } module.exports = NodeFetch;