{"version":3,"file":"index.cjs","sources":["../src/util/middlewareReducer.ts","../src/createRequester.ts","../src/util/pubsub.ts","../src/index.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","import {createRequester} from './createRequester'\nimport {httpRequester} from './request/node-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 = 'node' satisfies ExportEnv\n\n/** @public */\nexport {adapter} from './request/node-request'\n"],"names":["Object","defineProperty","exports","value","nodeRequest","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","adapter","a","environment","getIt","httpRequester"],"mappings":"aAEOA,OAAAC,eAAAC,QAAA,aAAA,CAAAC,OAAA,IAAA,IAAAC,EAAAC,QAAA,kCCiBP,MAAMC,EAAe,CACnB,UACA,WACA,WACA,QACA,SAEIC,EAAc,CAClB,iBACA,kBACA,mBACA,kBACA,YACA,aACA,UACA,WACA,aAIc,SAAAC,EAAgBC,EAA6BC,GAC3D,MAAMC,EAAgC,GAChCC,EAAgCL,EAAYM,QAChD,CAACC,EAAMC,KACLD,EAAKC,GAAQD,EAAKC,IAAS,GACpBD,IAET,CACEE,eAAgB,CAACA,EAAAA,GACjBC,gBAAiB,CAACA,EAAeC,KAIrC,SAASC,EAAQC,GACf,MA2BMC,EAA+Bf,EAAaO,QAAO,CAACS,EAAQP,KAChEO,EAAOP,GC7EN,WACC,MAAAQ,iBAA0DvB,OAAAwB,OAAO,MACvE,IAAIC,EAAS,EAeN,MAAA,CACLC,QAPF,SAAiBC,GACf,IAAA,MAAWC,KAAML,EACHA,EAAAK,GAAID,EAAK,EAMvBE,UAhBF,SAAmBC,GACjB,MAAMF,EAAKH,IACC,OAAAF,EAAAK,GAAME,EACX,kBACEP,EAAYK,EACrB,CAAA,EAaJ,CDwDqBG,GACRT,IACN,CAAS,GAGNU,EDpFuB,CAACpB,GAChC,SAAyBqB,EAAMC,KAAiBC,GAC9C,MAAMC,EAAqB,YAATH,EAElB,IAAI9B,EAAQ+B,EACZ,IAAA,IAASG,EAAI,EAAGA,EAAIzB,EAAWqB,GAAMK,SAGnCnC,GAAQoC,EAFQ3B,EAAWqB,GAAMI,IAEjBlC,KAAUgC,IAEtBC,GAAcjC,GALyBkC,KAUtC,OAAAlC,CACT,ECoE0BqC,CAAkB5B,GAGpC6B,EAAUT,EAAgB,iBAAkBZ,GAGlDY,EAAgB,kBAAmBS,GAGnC,MAAMC,EAAU,CAACD,UAASpB,WAAUW,mBAKhC,IAAAW,EACJ,MAAMC,EAAcvB,EAASF,QAAQU,WAAWgB,IAE7BF,EAAAjC,EAAYmC,GAAK,CAACC,EAAKC,IAlDvB,EAACC,EAAsBD,EAAyBF,KAC7D,IAAAI,EAAQD,EACRE,EAAsCH,EAI1C,IAAKE,EACC,IACSC,EAAAlB,EAAgB,aAAce,EAAKF,SACvCC,GACPI,EAAW,KACXD,EAAQH,CAAA,CAMZG,EAAQA,GAASjB,EAAgB,UAAWiB,EAAOJ,GAG/CI,EACF5B,EAAS4B,MAAMvB,QAAQuB,GACdC,GACT7B,EAAS6B,SAASxB,QAAQwB,EAAQ,EA2BYC,CAAWL,EAAKC,EAAMF,IAAI,IAKnExB,EAAA+B,MAAMvB,WAAU,SAEnBc,GACFA,EAAeS,OAAM,IAMzB,MAAMC,EAAcrB,EAAgB,WAAYX,EAAUqB,GAK1D,OAAIW,IAAgBhC,GAClBA,EAASF,QAAQO,QAAQgB,GAGpBW,CAAA,CAGD,OAAAlC,EAAAmC,IAAM,SAAaC,GACzB,IAAKA,EACG,MAAA,IAAIC,MAAM,yDAGlB,GAA6B,mBAAlBD,EACT,MAAM,IAAIC,MACR,+FAIJ,GAAID,EAAcE,UAAY7C,EAAW6C,SAASnB,OAAS,EACzD,MAAM,IAAIkB,MACR,uHAIQ,OAAAjD,EAAAmD,SAASC,IACDJ,EAAAI,IAChB/C,EAAW+C,GAAKC,KAAKL,EAAcI,GAAW,IAIlDhD,EAAiBiD,KAAKL,GACfpC,CAGT,EAAAA,EAAQ0C,MAAQ,IAAMrD,EAAgBG,EAAkBD,GAExDD,EAAeiD,QAAQvC,EAAQmC,KAExBnC,CACT,CEpJ2BjB,QAAA4D,QAAA1D,EAAA2D,EAAA7D,QAAA8D,YAAA,OAAA9D,QAAA+D,MANN,CACnBxD,EAA8B,GAC9BC,EAA2BwD,MACb1D,EAAgBC,EAAgBC"}