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

96 lines (81 loc) 3.33 kB
const NodeFetch = require('./NodeFetch'); const Base = require('./Base'); const { RestEnvelopError } = require('./errors'); const { FETCH_CONTENT_TYPES } = require('../constants'); class Fetch extends Base { #instance = null; #options = null; constructor({ optional = {}, ...args }) { super({ optional, ...args }); this.options = args; this.createInstance(); } set options(value) { if (value) this.#options = value; } get options() { return this.#options; } /** * Creates a NodeFetch instance with the provided options. * This instance will be used for making HTTP requests. */ createInstance() { this.#instance = NodeFetch.create(this.options); } /** * Returns a NodeFetch instance for making HTTP requests. * Throws an error if the instance has not been created. * * @param {string} url - The URL for the request. * @param {object} options - Configuration options for the request. * @returns {Promise} A Promise resolving with the HTTP response. * @throws {Error} If the NodeFetch instance has not been initialized. */ instance(url, options) { if (!this.#instance) throw new RestEnvelopError('No fetch instance available'); return this.#instance.request(url, options); } /** * Makes an HTTP request with optional caching, timeout, and headers. * Handles URL construction and processes the response based on its content type. * * @param {string} url - The endpoint or full URL for the HTTP request. * @param {object} [options={}] - The configuration options for the request. * @param {object} [options.params] - Query parameters to append to the URL. * @param {object} [options.headers] - Custom headers for the request. * @param {number} [options.timeout] - Timeout for the request in milliseconds. * @param {object} [options.cache] - Caching options, including TTL and cache key. * @param {object} [options.retry] - Retry logic, including attempts and expected statuses. * @returns {Promise<object>} A Promise resolving with the HTTP response, including: * - `data`: The response body parsed according to its content type. * - `status`: The HTTP status code. * - `headers`: The response headers object. * @throws {Error} If the request fails after all retry attempts or an unexpected error occurs. */ async request(url, options = {}) { const requestUrl = Base.absoluteUrl(url) ? `${url}?${new URLSearchParams(options.params || {})}` : `${this.options.baseURL || ''}${url}?${new URLSearchParams(options.params || {})}`; return this.handleCache(requestUrl, options, async () => { const response = await this.instance(requestUrl, { timeout: options.timeout || this.timeout, ...options, headers: { ...options.headers, ...this.options.headers, }, }); const contentType = response.headers.get('Content-Type'); const [parseMethod] = Object.entries(FETCH_CONTENT_TYPES) .find(([, regex]) => regex.test(contentType)) || []; const responseData = parseMethod ? await response[parseMethod]() : undefined; return { data: responseData, status: response.status, headers: response.headers, }; }); } } module.exports = Fetch;