get-it
Version:
Generic HTTP request library for node, browsers and workers
1 lines • 26.3 kB
Source Map (JSON)
{"version":3,"file":"index.browser.cjs","sources":["../src/util/middlewareReducer.ts","../src/createRequester.ts","../src/util/pubsub.ts","../node_modules/parse-headers/parse-headers.js","../src/request/browser/fetchXhr.ts","../src/request/browser-request.ts","../src/index.browser.ts"],"sourcesContent":["import type {ApplyMiddleware, MiddlewareReducer} from 'get-it'\n\nexport const middlewareReducer = (middleware: MiddlewareReducer) =>\n function applyMiddleware(hook, defaultValue, ...args) {\n const bailEarly = hook === 'onError'\n\n let value = defaultValue\n for (let i = 0; i < middleware[hook].length; i++) {\n const handler = middleware[hook][i]\n // @ts-expect-error -- find a better way to deal with argument tuples\n value = handler(value, ...args)\n\n if (bailEarly && !value) {\n break\n }\n }\n\n return value\n } as ApplyMiddleware\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {processOptions} from './middleware/defaultOptionsProcessor'\nimport {validateOptions} from './middleware/defaultOptionsValidator'\nimport type {\n HttpContext,\n HttpRequest,\n HttpRequestOngoing,\n Middleware,\n MiddlewareChannels,\n MiddlewareHooks,\n MiddlewareReducer,\n MiddlewareResponse,\n Middlewares,\n Requester,\n RequestOptions,\n} from './types'\nimport {middlewareReducer} from './util/middlewareReducer'\nimport {createPubSub} from './util/pubsub'\n\nconst channelNames = [\n 'request',\n 'response',\n 'progress',\n 'error',\n 'abort',\n] satisfies (keyof MiddlewareChannels)[]\nconst middlehooks = [\n 'processOptions',\n 'validateOptions',\n 'interceptRequest',\n 'finalizeOptions',\n 'onRequest',\n 'onResponse',\n 'onError',\n 'onReturn',\n 'onHeaders',\n] satisfies (keyof MiddlewareHooks)[]\n\n/** @public */\nexport function createRequester(initMiddleware: Middlewares, httpRequest: HttpRequest): Requester {\n const loadedMiddleware: Middlewares = []\n const middleware: MiddlewareReducer = middlehooks.reduce(\n (ware, name) => {\n ware[name] = ware[name] || []\n return ware\n },\n {\n processOptions: [processOptions],\n validateOptions: [validateOptions],\n } as any,\n )\n\n function request(opts: RequestOptions | string) {\n const onResponse = (reqErr: Error | null, res: MiddlewareResponse, ctx: HttpContext) => {\n let error = reqErr\n let response: MiddlewareResponse | null = res\n\n // We're processing non-errors first, in case a middleware converts the\n // response into an error (for instance, status >= 400 == HttpError)\n if (!error) {\n try {\n response = applyMiddleware('onResponse', res, ctx)\n } catch (err: any) {\n response = null\n error = err\n }\n }\n\n // Apply error middleware - if middleware return the same (or a different) error,\n // publish as an error event. If we *don't* return an error, assume it has been handled\n error = error && applyMiddleware('onError', error, ctx)\n\n // Figure out if we should publish on error/response channels\n if (error) {\n channels.error.publish(error)\n } else if (response) {\n channels.response.publish(response)\n }\n }\n\n const channels: MiddlewareChannels = channelNames.reduce((target, name) => {\n target[name] = createPubSub() as MiddlewareChannels[typeof name]\n return target\n }, {} as any)\n\n // Prepare a middleware reducer that can be reused throughout the lifecycle\n const applyMiddleware = middlewareReducer(middleware)\n\n // Parse the passed options\n const options = applyMiddleware('processOptions', opts as RequestOptions)\n\n // Validate the options\n applyMiddleware('validateOptions', options)\n\n // Build a context object we can pass to child handlers\n const context = {options, channels, applyMiddleware}\n\n // We need to hold a reference to the current, ongoing request,\n // in order to allow cancellation. In the case of the retry middleware,\n // a new request might be triggered\n let ongoingRequest: HttpRequestOngoing | undefined\n const unsubscribe = channels.request.subscribe((ctx) => {\n // Let request adapters (node/browser) perform the actual request\n ongoingRequest = httpRequest(ctx, (err, res) => onResponse(err, res!, ctx))\n })\n\n // If we abort the request, prevent further requests from happening,\n // and be sure to cancel any ongoing request (obviously)\n channels.abort.subscribe(() => {\n unsubscribe()\n if (ongoingRequest) {\n ongoingRequest.abort()\n }\n })\n\n // See if any middleware wants to modify the return value - for instance\n // the promise or observable middlewares\n const returnValue = applyMiddleware('onReturn', channels, context)\n\n // If return value has been modified by a middleware, we expect the middleware\n // to publish on the 'request' channel. If it hasn't been modified, we want to\n // trigger it right away\n if (returnValue === channels) {\n channels.request.publish(context)\n }\n\n return returnValue\n }\n\n request.use = function use(newMiddleware: Middleware) {\n if (!newMiddleware) {\n throw new Error('Tried to add middleware that resolved to falsey value')\n }\n\n if (typeof newMiddleware === 'function') {\n throw new Error(\n 'Tried to add middleware that was a function. It probably expects you to pass options to it.',\n )\n }\n\n if (newMiddleware.onReturn && middleware.onReturn.length > 0) {\n throw new Error(\n 'Tried to add new middleware with `onReturn` handler, but another handler has already been registered for this event',\n )\n }\n\n middlehooks.forEach((key) => {\n if (newMiddleware[key]) {\n middleware[key].push(newMiddleware[key] as any)\n }\n })\n\n loadedMiddleware.push(newMiddleware)\n return request\n }\n\n request.clone = () => createRequester(loadedMiddleware, httpRequest)\n\n initMiddleware.forEach(request.use)\n\n return request\n}\n","// Code borrowed from https://github.com/bjoerge/nano-pubsub\n\nimport type {PubSub, Subscriber} from 'get-it'\n\nexport function createPubSub<Message = void>(): PubSub<Message> {\n const subscribers: {[id: string]: Subscriber<Message>} = Object.create(null)\n let nextId = 0\n function subscribe(subscriber: Subscriber<Message>) {\n const id = nextId++\n subscribers[id] = subscriber\n return function unsubscribe() {\n delete subscribers[id]\n }\n }\n\n function publish(event: Message) {\n for (const id in subscribers) {\n subscribers[id](event)\n }\n }\n\n return {\n publish,\n subscribe,\n }\n}\n","var trim = function(string) {\n return string.replace(/^\\s+|\\s+$/g, '');\n}\n , isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n }\n\nmodule.exports = function (headers) {\n if (!headers)\n return {}\n\n var result = {}\n\n var headersArr = trim(headers).split('\\n')\n\n for (var i = 0; i < headersArr.length; i++) {\n var row = headersArr[i]\n var index = row.indexOf(':')\n , key = trim(row.slice(0, index)).toLowerCase()\n , value = trim(row.slice(index + 1))\n\n if (typeof(result[key]) === 'undefined') {\n result[key] = value\n } else if (isArray(result[key])) {\n result[key].push(value)\n } else {\n result[key] = [ result[key], value ]\n }\n }\n\n return result\n}\n","/**\n * Mimicks the XMLHttpRequest API with only the parts needed for get-it's XHR adapter\n */\nexport class FetchXhr\n implements Pick<XMLHttpRequest, 'open' | 'abort' | 'getAllResponseHeaders' | 'setRequestHeader'>\n{\n /**\n * Public interface, interop with real XMLHttpRequest\n */\n onabort: (() => void) | undefined\n onerror: ((error?: any) => void) | undefined\n onreadystatechange: (() => void) | undefined\n ontimeout: XMLHttpRequest['ontimeout'] | undefined\n /**\n * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState\n */\n readyState: 0 | 1 | 2 | 3 | 4 = 0\n response: XMLHttpRequest['response']\n responseText: XMLHttpRequest['responseText'] = ''\n responseType: XMLHttpRequest['responseType'] = ''\n status: XMLHttpRequest['status'] | undefined\n statusText: XMLHttpRequest['statusText'] | undefined\n withCredentials: XMLHttpRequest['withCredentials'] | undefined\n\n /**\n * Private implementation details\n */\n #method!: string\n #url!: string\n #resHeaders!: string\n #headers: Record<string, string> = {}\n #controller?: AbortController\n #init: RequestInit = {}\n #useAbortSignal?: boolean\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- _async is only declared for typings compatibility\n open(method: string, url: string, _async?: boolean) {\n this.#method = method\n this.#url = url\n this.#resHeaders = ''\n this.readyState = 1 // Open\n this.onreadystatechange?.()\n this.#controller = undefined\n }\n abort() {\n if (this.#controller) {\n this.#controller.abort()\n }\n }\n getAllResponseHeaders() {\n return this.#resHeaders\n }\n setRequestHeader(name: string, value: string) {\n this.#headers[name] = value\n }\n // Allow setting extra fetch init options, needed for runtimes such as Vercel Edge to set `cache` and other options in React Server Components\n setInit(init: RequestInit, useAbortSignal = true) {\n this.#init = init\n this.#useAbortSignal = useAbortSignal\n }\n send(body: BodyInit) {\n const textBody = this.responseType !== 'arraybuffer'\n const options: RequestInit = {\n ...this.#init,\n method: this.#method,\n headers: this.#headers,\n body,\n }\n if (typeof AbortController === 'function' && this.#useAbortSignal) {\n this.#controller = new AbortController()\n // The instanceof check ensures environments like Edge Runtime, Node 18 with built-in fetch\n // and more don't throw if `signal` doesn't implement`EventTarget`\n // Native browser AbortSignal implements EventTarget, so we can use it\n if (typeof EventTarget !== 'undefined' && this.#controller.signal instanceof EventTarget) {\n options.signal = this.#controller.signal\n }\n }\n\n // Some environments (like CloudFlare workers) don't support credentials in\n // RequestInitDict, and there doesn't seem to be any easy way to check for it,\n // so for now let's just make do with a document check :/\n if (typeof document !== 'undefined') {\n options.credentials = this.withCredentials ? 'include' : 'omit'\n }\n\n fetch(this.#url, options)\n .then((res): Promise<string | ArrayBuffer> => {\n res.headers.forEach((value: any, key: any) => {\n this.#resHeaders += `${key}: ${value}\\r\\n`\n })\n this.status = res.status\n this.statusText = res.statusText\n this.readyState = 3 // Loading\n this.onreadystatechange?.()\n return textBody ? res.text() : res.arrayBuffer()\n })\n .then((resBody) => {\n if (typeof resBody === 'string') {\n this.responseText = resBody\n } else {\n this.response = resBody\n }\n this.readyState = 4 // Done\n this.onreadystatechange?.()\n })\n .catch((err: Error) => {\n if (err.name === 'AbortError') {\n this.onabort?.()\n return\n }\n\n this.onerror?.(err)\n })\n }\n}\n","import type {HttpRequest, MiddlewareResponse, RequestOptions} from 'get-it'\nimport parseHeaders from 'parse-headers'\n\nimport {FetchXhr} from './browser/fetchXhr'\n\n/**\n * Use fetch if it's available, non-browser environments such as Deno, Edge Runtime and more provide fetch as a global but doesn't provide xhr\n * @public\n */\nexport const adapter = (\n typeof XMLHttpRequest === 'function' ? ('xhr' as const) : ('fetch' as const)\n) satisfies import('../types').RequestAdapter\n\n// Fallback to fetch-based XHR polyfill for non-browser environments like Workers\nconst XmlHttpRequest = adapter === 'xhr' ? XMLHttpRequest : FetchXhr\n\nexport const httpRequester: HttpRequest = (context, callback) => {\n const opts = context.options\n const options = context.applyMiddleware('finalizeOptions', opts) as RequestOptions\n const timers: any = {}\n\n // Allow middleware to inject a response, for instance in the case of caching or mocking\n const injectedResponse = context.applyMiddleware('interceptRequest', undefined, {\n adapter,\n context,\n })\n\n // If middleware injected a response, treat it as we normally would and return it\n // Do note that the injected response has to be reduced to a cross-environment friendly response\n if (injectedResponse) {\n const cbTimer = setTimeout(callback, 0, null, injectedResponse)\n const cancel = () => clearTimeout(cbTimer)\n return {abort: cancel}\n }\n\n // We'll want to null out the request on success/failure\n let xhr = new XmlHttpRequest()\n\n if (xhr instanceof FetchXhr && typeof options.fetch === 'object') {\n xhr.setInit(options.fetch, options.useAbortSignal ?? true)\n }\n\n const headers = options.headers\n const delays = options.timeout\n\n // Request state\n let aborted = false\n let loaded = false\n let timedOut = false\n\n // Apply event handlers\n xhr.onerror = (event: ProgressEvent) => {\n // If fetch is used then rethrow the original error\n if (xhr instanceof FetchXhr) {\n onError(\n event instanceof Error\n ? event\n : new Error(`Request error while attempting to reach is ${options.url}`, {cause: event}),\n )\n } else {\n onError(\n new Error(\n `Request error while attempting to reach is ${options.url}${\n event.lengthComputable ? `(${event.loaded} of ${event.total} bytes transferred)` : ''\n }`,\n ),\n )\n }\n }\n xhr.ontimeout = (event: ProgressEvent) => {\n onError(\n new Error(\n `Request timeout while attempting to reach ${options.url}${\n event.lengthComputable ? `(${event.loaded} of ${event.total} bytes transferred)` : ''\n }`,\n ),\n )\n }\n xhr.onabort = () => {\n stopTimers(true)\n aborted = true\n }\n\n xhr.onreadystatechange = function () {\n // Prevent request from timing out\n resetTimers()\n\n if (aborted || !xhr || xhr.readyState !== 4) {\n return\n }\n\n // Will be handled by onError\n if (xhr.status === 0) {\n return\n }\n\n onLoad()\n }\n\n // @todo two last options to open() is username/password\n xhr.open(\n options.method!,\n options.url,\n true, // Always async\n )\n\n // Some options need to be applied after open\n xhr.withCredentials = !!options.withCredentials\n\n // Set headers\n if (headers && xhr.setRequestHeader) {\n for (const key in headers) {\n // eslint-disable-next-line no-prototype-builtins\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key])\n }\n }\n }\n\n if (options.rawBody) {\n xhr.responseType = 'arraybuffer'\n }\n\n // Let middleware know we're about to do a request\n context.applyMiddleware('onRequest', {options, adapter, request: xhr, context})\n\n xhr.send(options.body || null)\n\n // Figure out which timeouts to use (if any)\n if (delays) {\n timers.connect = setTimeout(() => timeoutRequest('ETIMEDOUT'), delays.connect)\n }\n\n return {abort}\n\n function abort() {\n aborted = true\n\n if (xhr) {\n xhr.abort()\n }\n }\n\n function timeoutRequest(code: any) {\n timedOut = true\n xhr.abort()\n const error: any = new Error(\n code === 'ESOCKETTIMEDOUT'\n ? `Socket timed out on request to ${options.url}`\n : `Connection timed out on request to ${options.url}`,\n )\n error.code = code\n context.channels.error.publish(error)\n }\n\n function resetTimers() {\n if (!delays) {\n return\n }\n\n stopTimers()\n timers.socket = setTimeout(() => timeoutRequest('ESOCKETTIMEDOUT'), delays.socket)\n }\n\n function stopTimers(force?: boolean) {\n // Only clear the connect timeout if we've got a connection\n if (force || aborted || (xhr && xhr.readyState >= 2 && timers.connect)) {\n clearTimeout(timers.connect)\n }\n\n if (timers.socket) {\n clearTimeout(timers.socket)\n }\n }\n\n function onError(error: Error) {\n if (loaded) {\n return\n }\n\n // Clean up\n stopTimers(true)\n loaded = true\n ;(xhr as any) = null\n\n // Annoyingly, details are extremely scarce and hidden from us.\n // We only really know that it is a network error\n const err = (error ||\n new Error(`Network error while attempting to reach ${options.url}`)) as Error & {\n isNetworkError: boolean\n request?: typeof options\n }\n err.isNetworkError = true\n err.request = options\n callback(err)\n }\n\n function reduceResponse(): MiddlewareResponse {\n return {\n body:\n xhr.response ||\n (xhr.responseType === '' || xhr.responseType === 'text' ? xhr.responseText : ''),\n url: options.url,\n method: options.method!,\n headers: parseHeaders(xhr.getAllResponseHeaders()),\n statusCode: xhr.status!,\n statusMessage: xhr.statusText!,\n }\n }\n\n function onLoad() {\n if (aborted || loaded || timedOut) {\n return\n }\n\n if (xhr.status === 0) {\n onError(new Error('Unknown XHR error'))\n return\n }\n\n // Prevent being called twice\n stopTimers()\n loaded = true\n callback(null, reduceResponse())\n }\n}\n","import {createRequester} from './createRequester'\nimport {httpRequester} from './request/browser-request'\nimport type {ExportEnv, HttpRequest, Middlewares, Requester} from './types'\n\nexport type * from './types'\n\n/** @public */\nexport const getIt = (\n initMiddleware: Middlewares = [],\n httpRequest: HttpRequest = httpRequester,\n): Requester => createRequester(initMiddleware, httpRequest)\n\n/** @public */\nexport const environment = 'browser' satisfies ExportEnv\n\n/** @public */\nexport {adapter} from './request/browser-request'\n"],"names":["Object","defineProperty","exports","value","_commonjsHelpers","require","channelNames","middlehooks","createRequester","initMiddleware","httpRequest","loadedMiddleware","middleware","reduce","ware","name","processOptions","validateOptions","v","request","opts","channels","target","subscribers","create","nextId","publish","event","id","subscribe","subscriber","createPubSub","applyMiddleware","hook","defaultValue","args","bailEarly","i","length","handler","middlewareReducer","options","context","ongoingRequest","unsubscribe","ctx","err","res","reqErr","error","response","onResponse","abort","returnValue","use","newMiddleware","Error","onReturn","forEach","key","push","clone","trim","string","replace","parseHeaders","headers","result","headersArr","split","row","index","indexOf","slice","toLowerCase","arg","prototype","toString","call","g","parseHeadersExports","FetchXhr","onabort","onerror","onreadystatechange","ontimeout","readyState","responseText","responseType","status","statusText","withCredentials","method","url","resHeaders","controller","init","useAbortSignal","open","_async","this","getAllResponseHeaders","setRequestHeader","setInit","send","body","textBody","AbortController","EventTarget","signal","document","credentials","fetch","then","text","arrayBuffer","resBody","catch","adapter","XMLHttpRequest","XmlHttpRequest","httpRequester","callback","timers","injectedResponse","cbTimer","setTimeout","clearTimeout","xhr","delays","timeout","aborted","loaded","timedOut","onError","cause","lengthComputable","total","stopTimers","socket","timeoutRequest","statusCode","statusMessage","onLoad","hasOwnProperty","rawBody","connect","code","force","isNetworkError","environment","getIt"],"mappings":"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","x_google_ignoreList":[3]}