{"version":3,"file":"fetch-G1DVwDKG.mjs","names":["locationUrl: URL","requestInit: RequestInit","readable","response"],"sources":["../../src/interceptors/fetch/utils/createNetworkError.ts","../../src/interceptors/fetch/utils/followRedirect.ts","../../src/interceptors/fetch/utils/brotli-decompress.ts","../../src/interceptors/fetch/utils/decompression.ts","../../src/interceptors/fetch/index.ts"],"sourcesContent":["export function createNetworkError(cause?: unknown) {\n  return Object.assign(new TypeError('Failed to fetch'), {\n    cause,\n  })\n}\n","import { createNetworkError } from './createNetworkError'\n\nconst REQUEST_BODY_HEADERS = [\n  'content-encoding',\n  'content-language',\n  'content-location',\n  'content-type',\n  'content-length',\n]\n\nconst kRedirectCount = Symbol('kRedirectCount')\n\n/**\n * @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1210\n */\nexport async function followFetchRedirect(\n  request: Request,\n  response: Response\n): Promise<Response> {\n  if (response.status !== 303 && request.body != null) {\n    return Promise.reject(createNetworkError())\n  }\n\n  const requestUrl = new URL(request.url)\n\n  let locationUrl: URL\n  try {\n    // If the location is a relative URL, use the request URL as the base URL.\n    locationUrl = new URL(response.headers.get('location')!, request.url) \n  } catch (error) {\n    return Promise.reject(createNetworkError(error))\n  }\n\n  if (\n    !(locationUrl.protocol === 'http:' || locationUrl.protocol === 'https:')\n  ) {\n    return Promise.reject(\n      createNetworkError('URL scheme must be a HTTP(S) scheme')\n    )\n  }\n\n  if (Reflect.get(request, kRedirectCount) > 20) {\n    return Promise.reject(createNetworkError('redirect count exceeded'))\n  }\n\n  Object.defineProperty(request, kRedirectCount, {\n    value: (Reflect.get(request, kRedirectCount) || 0) + 1,\n  })\n\n  if (\n    request.mode === 'cors' &&\n    (locationUrl.username || locationUrl.password) &&\n    !sameOrigin(requestUrl, locationUrl)\n  ) {\n    return Promise.reject(\n      createNetworkError('cross origin not allowed for request mode \"cors\"')\n    )\n  }\n\n  const requestInit: RequestInit = {}\n\n  if (\n    ([301, 302].includes(response.status) && request.method === 'POST') ||\n    (response.status === 303 && !['HEAD', 'GET'].includes(request.method))\n  ) {\n    requestInit.method = 'GET'\n    requestInit.body = null\n\n    REQUEST_BODY_HEADERS.forEach((headerName) => {\n      request.headers.delete(headerName)\n    })\n  }\n\n  if (!sameOrigin(requestUrl, locationUrl)) {\n    request.headers.delete('authorization')\n    request.headers.delete('proxy-authorization')\n    request.headers.delete('cookie')\n    request.headers.delete('host')\n  }\n\n  /**\n   * @note Undici \"safely\" extracts the request body.\n   * I suspect we cannot dispatch this request again\n   * since its body has been read and the stream is locked.\n   */\n\n  requestInit.headers = request.headers\n  const finalResponse = await fetch(new Request(locationUrl, requestInit))\n  Object.defineProperty(finalResponse, 'redirected', {\n    value: true,\n    configurable: true,\n  })\n\n  return finalResponse\n}\n\n/**\n * @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/util.js#L761\n */\nfunction sameOrigin(left: URL, right: URL): boolean {\n  if (left.origin === right.origin && left.origin === 'null') {\n    return true\n  }\n\n  if (\n    left.protocol === right.protocol &&\n    left.hostname === right.hostname &&\n    left.port === right.port\n  ) {\n    return true\n  }\n\n  return false\n}\n","import zlib from 'node:zlib'\n\nexport class BrotliDecompressionStream extends TransformStream {\n  constructor() {\n    const decompress = zlib.createBrotliDecompress({\n      flush: zlib.constants.BROTLI_OPERATION_FLUSH,\n      finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH,\n    })\n\n    super({\n      async transform(chunk, controller) {\n        const buffer = Buffer.from(chunk)\n\n        const decompressed = await new Promise<Buffer>((resolve, reject) => {\n          decompress.write(buffer, (error) => {\n            if (error) reject(error)\n          })\n\n          decompress.flush()\n          decompress.once('data', (data) => resolve(data))\n          decompress.once('error', (error) => reject(error))\n          decompress.once('end', () => controller.terminate())\n        }).catch((error) => {\n          controller.error(error)\n        })\n\n        controller.enqueue(decompressed)\n      },\n    })\n  }\n}\n","// Import from an internal alias that resolves to different modules\n// depending on the environment. This way, we can keep the fetch interceptor\n// intact while using different strategies for Brotli decompression.\nimport { BrotliDecompressionStream } from 'internal:brotli-decompress'\n\nclass PipelineStream extends TransformStream {\n  constructor(\n    transformStreams: Array<TransformStream>,\n    ...strategies: Array<QueuingStrategy>\n  ) {\n    super({}, ...strategies)\n\n    const readable = [super.readable as any, ...transformStreams].reduce(\n      (readable, transform) => readable.pipeThrough(transform)\n    )\n\n    Object.defineProperty(this, 'readable', {\n      get() {\n        return readable\n      },\n    })\n  }\n}\n\nexport function parseContentEncoding(contentEncoding: string): Array<string> {\n  return contentEncoding\n    .toLowerCase()\n    .split(',')\n    .map((coding) => coding.trim())\n}\n\nfunction createDecompressionStream(\n  contentEncoding: string\n): TransformStream | null {\n  if (contentEncoding === '') {\n    return null\n  }\n\n  const codings = parseContentEncoding(contentEncoding)\n\n  if (codings.length === 0) {\n    return null\n  }\n\n  const transformers = codings.reduceRight<Array<TransformStream>>(\n    (transformers, coding) => {\n      if (coding === 'gzip' || coding === 'x-gzip') {\n        return transformers.concat(new DecompressionStream('gzip'))\n      } else if (coding === 'deflate') {\n        return transformers.concat(new DecompressionStream('deflate'))\n      } else if (coding === 'br') {\n        return transformers.concat(new BrotliDecompressionStream())\n      } else {\n        transformers.length = 0\n      }\n\n      return transformers\n    },\n    []\n  )\n\n  return new PipelineStream(transformers)\n}\n\nexport function decompressResponse(\n  response: Response\n): ReadableStream<any> | null {\n  if (response.body === null) {\n    return null\n  }\n\n  const decompressionStream = createDecompressionStream(\n    response.headers.get('content-encoding') || ''\n  )\n\n  if (!decompressionStream) {\n    return null\n  }\n\n  // Use `pipeTo` and return the decompression stream's readable\n  // instead of `pipeThrough` because that will lock the original\n  // response stream, making it unusable as the input to Response.\n  response.body.pipeTo(decompressionStream.writable)\n  return decompressionStream.readable\n}\n","import { invariant } from 'outvariant'\nimport { until } from '@open-draft/until'\nimport { DeferredPromise } from '@open-draft/deferred-promise'\nimport { HttpRequestEventMap, IS_PATCHED_MODULE } from '../../glossary'\nimport { Interceptor } from '../../Interceptor'\nimport { RequestController } from '../../RequestController'\nimport { emitAsync } from '../../utils/emitAsync'\nimport { handleRequest } from '../../utils/handleRequest'\nimport { canParseUrl } from '../../utils/canParseUrl'\nimport { createRequestId } from '../../createRequestId'\nimport { createNetworkError } from './utils/createNetworkError'\nimport { followFetchRedirect } from './utils/followRedirect'\nimport { decompressResponse } from './utils/decompression'\nimport { hasConfigurableGlobal } from '../../utils/hasConfigurableGlobal'\nimport { FetchResponse } from '../../utils/fetchUtils'\nimport { setRawRequest } from '../../getRawRequest'\nimport { isResponseError } from '../../utils/responseUtils'\n\nexport class FetchInterceptor extends Interceptor<HttpRequestEventMap> {\n  static symbol = Symbol('fetch')\n\n  constructor() {\n    super(FetchInterceptor.symbol)\n  }\n\n  protected checkEnvironment() {\n    return hasConfigurableGlobal('fetch')\n  }\n\n  protected async setup() {\n    const pureFetch = globalThis.fetch\n\n    invariant(\n      !(pureFetch as any)[IS_PATCHED_MODULE],\n      'Failed to patch the \"fetch\" module: already patched.'\n    )\n\n    globalThis.fetch = async (input, init) => {\n      const requestId = createRequestId()\n\n      /**\n       * @note Resolve potentially relative request URL\n       * against the present `location`. This is mainly\n       * for native `fetch` in JSDOM.\n       * @see https://github.com/mswjs/msw/issues/1625\n       */\n      const resolvedInput =\n        typeof input === 'string' &&\n        typeof location !== 'undefined' &&\n        !canParseUrl(input)\n          ? new URL(input, location.href)\n          : input\n\n      const request = new Request(resolvedInput, init)\n\n      /**\n       * @note Set the raw request only if a Request instance was provided to fetch.\n       */\n      if (input instanceof Request) {\n        setRawRequest(request, input)\n      }\n\n      const responsePromise = new DeferredPromise<Response>()\n\n      const controller = new RequestController(request, {\n        passthrough: async () => {\n          this.logger.info('request has not been handled, passthrough...')\n\n          /**\n           * @note Clone the request instance right before performing it.\n           * This preserves any modifications made to the intercepted request\n           * in the \"request\" listener. This also allows the user to read the\n           * request body in the \"response\" listener (otherwise \"unusable\").\n           */\n          const requestCloneForResponseEvent = request.clone()\n\n          // Perform the intercepted request as-is.\n          const { error: responseError, data: originalResponse } = await until(\n            () => pureFetch(request)\n          )\n\n          if (responseError) {\n            return responsePromise.reject(responseError)\n          }\n\n          this.logger.info('original fetch performed', originalResponse)\n\n          if (this.emitter.listenerCount('response') > 0) {\n            this.logger.info('emitting the \"response\" event...')\n\n            const responseClone = originalResponse.clone()\n            await emitAsync(this.emitter, 'response', {\n              response: responseClone,\n              isMockedResponse: false,\n              request: requestCloneForResponseEvent,\n              requestId,\n            })\n          }\n\n          // Resolve the response promise with the original response\n          // since the `fetch()` return this internal promise.\n          responsePromise.resolve(originalResponse)\n        },\n        respondWith: async (rawResponse) => {\n          // Handle mocked `Response.error()` (i.e. request errors).\n          if (isResponseError(rawResponse)) {\n            this.logger.info('request has errored!', { response: rawResponse })\n            responsePromise.reject(createNetworkError(rawResponse))\n            return\n          }\n\n          this.logger.info('received mocked response!', {\n            rawResponse,\n          })\n\n          // Decompress the mocked response body, if applicable.\n          const decompressedStream = decompressResponse(rawResponse)\n          const response =\n            decompressedStream === null\n              ? rawResponse\n              : new FetchResponse(decompressedStream, rawResponse)\n\n          FetchResponse.setUrl(request.url, response)\n\n          /**\n           * Undici's handling of following redirect responses.\n           * Treat the \"manual\" redirect mode as a regular mocked response.\n           * This way, the client can manually follow the redirect it receives.\n           * @see https://github.com/nodejs/undici/blob/a6dac3149c505b58d2e6d068b97f4dc993da55f0/lib/web/fetch/index.js#L1173\n           */\n          if (FetchResponse.isRedirectResponse(response.status)) {\n            // Reject the request promise if its `redirect` is set to `error`\n            // and it receives a mocked redirect response.\n            if (request.redirect === 'error') {\n              responsePromise.reject(createNetworkError('unexpected redirect'))\n              return\n            }\n\n            if (request.redirect === 'follow') {\n              followFetchRedirect(request, response).then(\n                (response) => {\n                  responsePromise.resolve(response)\n                },\n                (reason) => {\n                  responsePromise.reject(reason)\n                }\n              )\n              return\n            }\n          }\n\n          if (this.emitter.listenerCount('response') > 0) {\n            this.logger.info('emitting the \"response\" event...')\n\n            // Await the response listeners to finish before resolving\n            // the response promise. This ensures all your logic finishes\n            // before the interceptor resolves the pending response.\n            await emitAsync(this.emitter, 'response', {\n              // Clone the mocked response for the \"response\" event listener.\n              // This way, the listener can read the response and not lock its body\n              // for the actual fetch consumer.\n              response: response.clone(),\n              isMockedResponse: true,\n              request,\n              requestId,\n            })\n          }\n\n          responsePromise.resolve(response)\n        },\n        errorWith: (reason) => {\n          this.logger.info('request has been aborted!', { reason })\n          responsePromise.reject(reason)\n        },\n      })\n\n      this.logger.info('[%s] %s', request.method, request.url)\n      this.logger.info('awaiting for the mocked response...')\n\n      this.logger.info(\n        'emitting the \"request\" event for %s listener(s)...',\n        this.emitter.listenerCount('request')\n      )\n\n      await handleRequest({\n        request,\n        requestId,\n        emitter: this.emitter,\n        controller,\n      })\n\n      return responsePromise\n    }\n\n    Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {\n      enumerable: true,\n      configurable: true,\n      value: true,\n    })\n\n    this.subscriptions.push(() => {\n      Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {\n        value: undefined,\n      })\n\n      globalThis.fetch = pureFetch\n\n      this.logger.info(\n        'restored native \"globalThis.fetch\"!',\n        globalThis.fetch.name\n      )\n    })\n  }\n}\n"],"mappings":"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"}