UNPKG

get-it

Version:

Generic HTTP request library for node, browsers and workers

105 lines (86 loc) 2.78 kB
import type {Middleware} from 'get-it' /** @public */ export const promise = ( options: {onlyBody?: boolean; implementation?: PromiseConstructor} = {}, ) => { const PromiseImplementation = options.implementation || Promise if (!PromiseImplementation) { throw new Error('`Promise` is not available in global scope, and no implementation was passed') } return { onReturn: (channels, context) => new PromiseImplementation((resolve, reject) => { const cancel = context.options.cancelToken if (cancel) { cancel.promise.then((reason: any) => { channels.abort.publish(reason) reject(reason) }) } channels.error.subscribe(reject) channels.response.subscribe((response) => { resolve(options.onlyBody ? (response as any).body : response) }) // Wait until next tick in case cancel has been performed setTimeout(() => { try { channels.request.publish(context) } catch (err) { reject(err) } }, 0) }), } satisfies Middleware } /** * The cancel token API is based on the [cancelable promises proposal](https://github.com/tc39/proposal-cancelable-promises), which is currently at Stage 1. * * Code shamelessly stolen/borrowed from MIT-licensed [axios](https://github.com/mzabriskie/axios). Thanks to [Nick Uraltsev](https://github.com/nickuraltsev), [Matt Zabriskie](https://github.com/mzabriskie) and the other contributors of that project! */ /** @public */ export class Cancel { __CANCEL__ = true message: string | undefined constructor(message: string | undefined) { this.message = message } toString() { return `Cancel${this.message ? `: ${this.message}` : ''}` } } /** @public */ export class CancelToken { promise: Promise<any> reason?: Cancel constructor(executor: (cb: (message?: string) => void) => void) { if (typeof executor !== 'function') { throw new TypeError('executor must be a function.') } let resolvePromise: any = null this.promise = new Promise((resolve) => { resolvePromise = resolve }) executor((message?: string) => { if (this.reason) { // Cancellation has already been requested return } this.reason = new Cancel(message) resolvePromise(this.reason) }) } static source = () => { let cancel: (message?: string) => void const token = new CancelToken((can) => { cancel = can }) return { token: token, cancel: cancel!, } } } const isCancel = (value: any): value is Cancel => !!(value && value?.__CANCEL__) promise.Cancel = Cancel promise.CancelToken = CancelToken promise.isCancel = isCancel