{"version":3,"file":"fetchUtils-BaY5iWXw.cjs","names":["symbol: symbol","Emitter","Logger","request: Request","source: RequestControllerSource","DeferredPromise","#handled","symbol"],"sources":["../../src/Interceptor.ts","../../src/InterceptorError.ts","../../src/RequestController.ts","../../src/createRequestId.ts","../../src/utils/canParseUrl.ts","../../src/utils/getValueBySymbol.ts","../../src/utils/fetchUtils.ts"],"sourcesContent":["import { Logger } from '@open-draft/logger'\nimport { Emitter, Listener } from 'strict-event-emitter'\n\nexport type InterceptorEventMap = Record<string, any>\nexport type InterceptorSubscription = () => void\n\n/**\n * Request header name to detect when a single request\n * is being handled by nested interceptors (XHR -> ClientRequest).\n * Obscure by design to prevent collisions with user-defined headers.\n * Ideally, come up with the Interceptor-level mechanism for this.\n * @see https://github.com/mswjs/interceptors/issues/378\n */\nexport const INTERNAL_REQUEST_ID_HEADER_NAME =\n  'x-interceptors-internal-request-id'\n\nexport function getGlobalSymbol<V>(symbol: Symbol): V | undefined {\n  return (\n    // @ts-ignore https://github.com/Microsoft/TypeScript/issues/24587\n    globalThis[symbol] || undefined\n  )\n}\n\nfunction setGlobalSymbol(symbol: Symbol, value: any): void {\n  // @ts-ignore\n  globalThis[symbol] = value\n}\n\nexport function deleteGlobalSymbol(symbol: Symbol): void {\n  // @ts-ignore\n  delete globalThis[symbol]\n}\n\nexport enum InterceptorReadyState {\n  INACTIVE = 'INACTIVE',\n  APPLYING = 'APPLYING',\n  APPLIED = 'APPLIED',\n  DISPOSING = 'DISPOSING',\n  DISPOSED = 'DISPOSED',\n}\n\nexport type ExtractEventNames<Events extends Record<string, any>> =\n  Events extends Record<infer EventName, any> ? EventName : never\n\nexport class Interceptor<Events extends InterceptorEventMap> {\n  protected emitter: Emitter<Events>\n  protected subscriptions: Array<InterceptorSubscription>\n  protected logger: Logger\n\n  public readyState: InterceptorReadyState\n\n  constructor(private readonly symbol: symbol) {\n    this.readyState = InterceptorReadyState.INACTIVE\n\n    this.emitter = new Emitter()\n    this.subscriptions = []\n    this.logger = new Logger(symbol.description!)\n\n    // Do not limit the maximum number of listeners\n    // so not to limit the maximum amount of parallel events emitted.\n    this.emitter.setMaxListeners(0)\n\n    this.logger.info('constructing the interceptor...')\n  }\n\n  /**\n   * Determine if this interceptor can be applied\n   * in the current environment.\n   */\n  protected checkEnvironment(): boolean {\n    return true\n  }\n\n  /**\n   * Apply this interceptor to the current process.\n   * Returns an already running interceptor instance if it's present.\n   */\n  public apply(): void {\n    const logger = this.logger.extend('apply')\n    logger.info('applying the interceptor...')\n\n    if (this.readyState === InterceptorReadyState.APPLIED) {\n      logger.info('intercepted already applied!')\n      return\n    }\n\n    const shouldApply = this.checkEnvironment()\n\n    if (!shouldApply) {\n      logger.info('the interceptor cannot be applied in this environment!')\n      return\n    }\n\n    this.readyState = InterceptorReadyState.APPLYING\n\n    // Whenever applying a new interceptor, check if it hasn't been applied already.\n    // This enables to apply the same interceptor multiple times, for example from a different\n    // interceptor, only proxying events but keeping the stubs in a single place.\n    const runningInstance = this.getInstance()\n\n    if (runningInstance) {\n      logger.info('found a running instance, reusing...')\n\n      // Proxy any listeners you set on this instance to the running instance.\n      this.on = (event, listener) => {\n        logger.info('proxying the \"%s\" listener', event)\n\n        // Add listeners to the running instance so they appear\n        // at the top of the event listeners list and are executed first.\n        runningInstance.emitter.addListener(event, listener)\n\n        // Ensure that once this interceptor instance is disposed,\n        // it removes all listeners it has appended to the running interceptor instance.\n        this.subscriptions.push(() => {\n          runningInstance.emitter.removeListener(event, listener)\n          logger.info('removed proxied \"%s\" listener!', event)\n        })\n\n        return this\n      }\n\n      this.readyState = InterceptorReadyState.APPLIED\n\n      return\n    }\n\n    logger.info('no running instance found, setting up a new instance...')\n\n    // Setup the interceptor.\n    this.setup()\n\n    // Store the newly applied interceptor instance globally.\n    this.setInstance()\n\n    this.readyState = InterceptorReadyState.APPLIED\n  }\n\n  /**\n   * Setup the module augments and stubs necessary for this interceptor.\n   * This method is not run if there's a running interceptor instance\n   * to prevent instantiating an interceptor multiple times.\n   */\n  protected setup(): void {}\n\n  /**\n   * Listen to the interceptor's public events.\n   */\n  public on<EventName extends ExtractEventNames<Events>>(\n    event: EventName,\n    listener: Listener<Events[EventName]>\n  ): this {\n    const logger = this.logger.extend('on')\n\n    if (\n      this.readyState === InterceptorReadyState.DISPOSING ||\n      this.readyState === InterceptorReadyState.DISPOSED\n    ) {\n      logger.info('cannot listen to events, already disposed!')\n      return this\n    }\n\n    logger.info('adding \"%s\" event listener:', event, listener)\n\n    this.emitter.on(event, listener)\n    return this\n  }\n\n  public once<EventName extends ExtractEventNames<Events>>(\n    event: EventName,\n    listener: Listener<Events[EventName]>\n  ): this {\n    this.emitter.once(event, listener)\n    return this\n  }\n\n  public off<EventName extends ExtractEventNames<Events>>(\n    event: EventName,\n    listener: Listener<Events[EventName]>\n  ): this {\n    this.emitter.off(event, listener)\n    return this\n  }\n\n  public removeAllListeners<EventName extends ExtractEventNames<Events>>(\n    event?: EventName\n  ): this {\n    this.emitter.removeAllListeners(event)\n    return this\n  }\n\n  /**\n   * Disposes of any side-effects this interceptor has introduced.\n   */\n  public dispose(): void {\n    const logger = this.logger.extend('dispose')\n\n    if (this.readyState === InterceptorReadyState.DISPOSED) {\n      logger.info('cannot dispose, already disposed!')\n      return\n    }\n\n    logger.info('disposing the interceptor...')\n    this.readyState = InterceptorReadyState.DISPOSING\n\n    if (!this.getInstance()) {\n      logger.info('no interceptors running, skipping dispose...')\n      return\n    }\n\n    // Delete the global symbol as soon as possible,\n    // indicating that the interceptor is no longer running.\n    this.clearInstance()\n\n    logger.info('global symbol deleted:', getGlobalSymbol(this.symbol))\n\n    if (this.subscriptions.length > 0) {\n      logger.info('disposing of %d subscriptions...', this.subscriptions.length)\n\n      for (const dispose of this.subscriptions) {\n        dispose()\n      }\n\n      this.subscriptions = []\n\n      logger.info('disposed of all subscriptions!', this.subscriptions.length)\n    }\n\n    this.emitter.removeAllListeners()\n    logger.info('destroyed the listener!')\n\n    this.readyState = InterceptorReadyState.DISPOSED\n  }\n\n  private getInstance(): this | undefined {\n    const instance = getGlobalSymbol<this>(this.symbol)\n    this.logger.info('retrieved global instance:', instance?.constructor?.name)\n    return instance\n  }\n\n  private setInstance(): void {\n    setGlobalSymbol(this.symbol, this)\n    this.logger.info('set global instance!', this.symbol.description)\n  }\n\n  private clearInstance(): void {\n    deleteGlobalSymbol(this.symbol)\n    this.logger.info('cleared global instance!', this.symbol.description)\n  }\n}\n","export class InterceptorError extends Error {\n  constructor(message?: string) {\n    super(message)\n    this.name = 'InterceptorError'\n    Object.setPrototypeOf(this, InterceptorError.prototype)\n  }\n}\n","import { DeferredPromise } from '@open-draft/deferred-promise'\nimport { invariant } from 'outvariant'\nimport { InterceptorError } from './InterceptorError'\n\nexport interface RequestControllerSource {\n  passthrough(): void\n  respondWith(response: Response): void\n  errorWith(reason?: unknown): void\n}\n\nexport class RequestController {\n  static PENDING = 0 as const\n  static PASSTHROUGH = 1 as const\n  static RESPONSE = 2 as const\n  static ERROR = 3 as const\n\n  public readyState: number\n\n  /**\n   * A Promise that resolves when this controller handles a request.\n   * See `controller.readyState` for more information on the handling result.\n   */\n  public handled: Promise<void>\n\n  constructor(\n    protected readonly request: Request,\n    protected readonly source: RequestControllerSource\n  ) {\n    this.readyState = RequestController.PENDING\n    this.handled = new DeferredPromise<void>()\n  }\n\n  get #handled() {\n    return this.handled as DeferredPromise<void>\n  }\n\n  /**\n   * Perform this request as-is.\n   */\n  public async passthrough(): Promise<void> {\n    invariant.as(\n      InterceptorError,\n      this.readyState === RequestController.PENDING,\n      'Failed to passthrough the \"%s %s\" request: the request has already been handled',\n      this.request.method,\n      this.request.url\n    )\n\n    this.readyState = RequestController.PASSTHROUGH\n    await this.source.passthrough()\n    this.#handled.resolve()\n  }\n\n  /**\n   * Respond to this request with the given `Response` instance.\n   *\n   * @example\n   * controller.respondWith(new Response())\n   * controller.respondWith(Response.json({ id }))\n   * controller.respondWith(Response.error())\n   */\n  public respondWith(response: Response): void {\n    invariant.as(\n      InterceptorError,\n      this.readyState === RequestController.PENDING,\n      'Failed to respond to the \"%s %s\" request with \"%d %s\": the request has already been handled (%d)',\n      this.request.method,\n      this.request.url,\n      response.status,\n      response.statusText || 'OK',\n      this.readyState\n    )\n\n    this.readyState = RequestController.RESPONSE\n    this.#handled.resolve()\n\n    /**\n     * @note Although `source.respondWith()` is potentially asynchronous,\n     * do NOT await it for backward-compatibility. Awaiting it will short-circuit\n     * the request listener invocation as soon as a listener responds to a request.\n     * Ideally, that's what we want, but that's not what we promise the user.\n     */\n    this.source.respondWith(response)\n  }\n\n  /**\n   * Error this request with the given reason.\n   *\n   * @example\n   * controller.errorWith()\n   * controller.errorWith(new Error('Oops!'))\n   * controller.errorWith({ message: 'Oops!'})\n   */\n  public errorWith(reason?: unknown): void {\n    invariant.as(\n      InterceptorError,\n      this.readyState === RequestController.PENDING,\n      'Failed to error the \"%s %s\" request with \"%s\": the request has already been handled (%d)',\n      this.request.method,\n      this.request.url,\n      reason?.toString(),\n      this.readyState\n    )\n\n    this.readyState = RequestController.ERROR\n    this.source.errorWith(reason)\n    this.#handled.resolve()\n  }\n}\n","/**\n * Generate a random ID string to represent a request.\n * @example\n * createRequestId()\n * // \"f774b6c9c600f\"\n */\nexport function createRequestId(): string {\n  return Math.random().toString(16).slice(2)\n}\n","/**\n * Returns a boolean indicating whether the given URL string\n * can be parsed into a `URL` instance.\n * A substitute for `URL.canParse()` for Node.js 18.\n */\nexport function canParseUrl(url: string): boolean {\n  try {\n    new URL(url)\n    return true\n  } catch (_error) {\n    return false\n  }\n}\n","/**\n * Returns the value behind the symbol with the given name.\n */\nexport function getValueBySymbol<T>(\n  symbolName: string,\n  source: object\n): T | undefined {\n  const ownSymbols = Object.getOwnPropertySymbols(source)\n\n  const symbol = ownSymbols.find((symbol) => {\n    return symbol.description === symbolName\n  })\n\n  if (symbol) {\n    return Reflect.get(source, symbol)\n  }\n\n  return\n}\n","import { canParseUrl } from './canParseUrl'\nimport { getValueBySymbol } from './getValueBySymbol'\n\nexport interface FetchResponseInit extends ResponseInit {\n  url?: string\n}\n\ninterface UndiciFetchInternalState {\n  aborted: boolean\n  rangeRequested: boolean\n  timingAllowPassed: boolean\n  requestIncludesCredentials: boolean\n  type: ResponseType\n  status: number\n  statusText: string\n  timingInfo: unknown\n  cacheState: unknown\n  headersList: Record<symbol, Map<string, unknown>>\n  urlList: Array<URL>\n  body?: {\n    stream: ReadableStream\n    source: unknown\n    length: number\n  }\n}\n\nexport class FetchResponse extends Response {\n  /**\n   * Response status codes for responses that cannot have body.\n   * @see https://fetch.spec.whatwg.org/#statuses\n   */\n  static readonly STATUS_CODES_WITHOUT_BODY = [101, 103, 204, 205, 304]\n\n  static readonly STATUS_CODES_WITH_REDIRECT = [301, 302, 303, 307, 308]\n\n  static isConfigurableStatusCode(status: number): boolean {\n    return status >= 200 && status <= 599\n  }\n\n  static isRedirectResponse(status: number): boolean {\n    return FetchResponse.STATUS_CODES_WITH_REDIRECT.includes(status)\n  }\n\n  /**\n   * Returns a boolean indicating whether the given response status\n   * code represents a response that can have a body.\n   */\n  static isResponseWithBody(status: number): boolean {\n    return !FetchResponse.STATUS_CODES_WITHOUT_BODY.includes(status)\n  }\n\n  static setUrl(url: string | undefined, response: Response): void {\n    if (!url || url === 'about:' || !canParseUrl(url)) {\n      return\n    }\n\n    const state = getValueBySymbol<UndiciFetchInternalState>('state', response)\n\n    if (state) {\n      // In Undici, push the URL to the internal list of URLs.\n      // This will respect the `response.url` getter logic correctly.\n      state.urlList.push(new URL(url))\n    } else {\n      // In other libraries, redefine the `url` property directly.\n      Object.defineProperty(response, 'url', {\n        value: url,\n        enumerable: true,\n        configurable: true,\n        writable: false,\n      })\n    }\n  }\n\n  /**\n   * Parses the given raw HTTP headers into a Fetch API `Headers` instance.\n   */\n  static parseRawHeaders(rawHeaders: Array<string>): Headers {\n    const headers = new Headers()\n    for (let line = 0; line < rawHeaders.length; line += 2) {\n      headers.append(rawHeaders[line], rawHeaders[line + 1])\n    }\n    return headers\n  }\n\n  constructor(body?: BodyInit | null, init: FetchResponseInit = {}) {\n    const status = init.status ?? 200\n    const safeStatus = FetchResponse.isConfigurableStatusCode(status)\n      ? status\n      : 200\n    const finalBody = FetchResponse.isResponseWithBody(status) ? body : null\n\n    super(finalBody, {\n      status: safeStatus,\n      statusText: init.statusText,\n      headers: init.headers,\n    })\n\n    if (status !== safeStatus) {\n      /**\n       * @note Undici keeps an internal \"Symbol(state)\" that holds\n       * the actual value of response status. Update that in Node.js.\n       */\n      const state = getValueBySymbol<UndiciFetchInternalState>('state', this)\n\n      if (state) {\n        state.status = status\n      } else {\n        Object.defineProperty(this, 'status', {\n          value: status,\n          enumerable: true,\n          configurable: true,\n          writable: false,\n        })\n      }\n    }\n\n    FetchResponse.setUrl(init.url, this)\n  }\n}\n"],"mappings":"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"}