File size: 8,698 Bytes
d4b85c0
1
{"version":3,"sources":["../../src/native/index.ts","../../src/node/SetupServerCommonApi.ts"],"sourcesContent":["import { FetchInterceptor } from '@mswjs/interceptors/fetch'\nimport { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest'\nimport type { RequestHandler } from '~/core/handlers/RequestHandler'\nimport { SetupServerCommonApi } from '../node/SetupServerCommonApi'\n\n/**\n * Sets up a requests interception in React Native with the given request handlers.\n * @param {RequestHandler[]} handlers List of request handlers.\n *\n * @see {@link https://mswjs.io/docs/api/setup-server `setupServer()` API reference}\n */\nexport function setupServer(\n  ...handlers: Array<RequestHandler>\n): SetupServerCommonApi {\n  // Provision request interception via patching the `XMLHttpRequest` class only\n  // in React Native. There is no `http`/`https` modules in that environment.\n  return new SetupServerCommonApi(\n    [FetchInterceptor, XMLHttpRequestInterceptor],\n    handlers,\n  )\n}\n","/**\n * @note This API is extended by both \"msw/node\" and \"msw/native\"\n * so be minding about the things you import!\n */\nimport type { RequiredDeep } from 'type-fest'\nimport { invariant } from 'outvariant'\nimport {\n  BatchInterceptor,\n  InterceptorReadyState,\n  type HttpRequestEventMap,\n  type Interceptor,\n} from '@mswjs/interceptors'\nimport type { LifeCycleEventsMap, SharedOptions } from '~/core/sharedOptions'\nimport { SetupApi } from '~/core/SetupApi'\nimport { handleRequest } from '~/core/utils/handleRequest'\nimport type { RequestHandler } from '~/core/handlers/RequestHandler'\nimport type { WebSocketHandler } from '~/core/handlers/WebSocketHandler'\nimport { mergeRight } from '~/core/utils/internal/mergeRight'\nimport { InternalError, devUtils } from '~/core/utils/internal/devUtils'\nimport type { SetupServerCommon } from './glossary'\nimport { handleWebSocketEvent } from '~/core/ws/handleWebSocketEvent'\nimport { webSocketInterceptor } from '~/core/ws/webSocketInterceptor'\nimport { isHandlerKind } from '~/core/utils/internal/isHandlerKind'\n\nexport const DEFAULT_LISTEN_OPTIONS: RequiredDeep<SharedOptions> = {\n  onUnhandledRequest: 'warn',\n}\n\nexport class SetupServerCommonApi\n  extends SetupApi<LifeCycleEventsMap>\n  implements SetupServerCommon\n{\n  protected readonly interceptor: BatchInterceptor<\n    Array<Interceptor<HttpRequestEventMap>>,\n    HttpRequestEventMap\n  >\n  private resolvedOptions: RequiredDeep<SharedOptions>\n\n  constructor(\n    interceptors: Array<{ new (): Interceptor<HttpRequestEventMap> }>,\n    handlers: Array<RequestHandler | WebSocketHandler>,\n  ) {\n    super(...handlers)\n\n    this.interceptor = new BatchInterceptor({\n      name: 'setup-server',\n      interceptors: interceptors.map((Interceptor) => new Interceptor()),\n    })\n\n    this.resolvedOptions = {} as RequiredDeep<SharedOptions>\n  }\n\n  /**\n   * Subscribe to all requests that are using the interceptor object\n   */\n  private init(): void {\n    this.interceptor.on(\n      'request',\n      async ({ request, requestId, controller }) => {\n        const response = await handleRequest(\n          request,\n          requestId,\n          this.handlersController\n            .currentHandlers()\n            .filter(isHandlerKind('RequestHandler')),\n          this.resolvedOptions,\n          this.emitter,\n          {\n            onPassthroughResponse(request) {\n              const acceptHeader = request.headers.get('accept')\n\n              /**\n               * @note Remove the internal bypass request header.\n               * In the browser, this is done by the worker script.\n               * In Node.js, it has to be done here.\n               */\n              if (acceptHeader) {\n                const nextAcceptHeader = acceptHeader.replace(\n                  /(,\\s+)?msw\\/passthrough/,\n                  '',\n                )\n\n                if (nextAcceptHeader) {\n                  request.headers.set('accept', nextAcceptHeader)\n                } else {\n                  request.headers.delete('accept')\n                }\n              }\n            },\n          },\n        )\n\n        if (response) {\n          controller.respondWith(response)\n        }\n\n        return\n      },\n    )\n\n    this.interceptor.on('unhandledException', ({ error }) => {\n      if (error instanceof InternalError) {\n        throw error\n      }\n    })\n\n    this.interceptor.on(\n      'response',\n      ({ response, isMockedResponse, request, requestId }) => {\n        this.emitter.emit(\n          isMockedResponse ? 'response:mocked' : 'response:bypass',\n          {\n            response,\n            request,\n            requestId,\n          },\n        )\n      },\n    )\n\n    // Preconfigure the WebSocket interception but don't enable it just yet.\n    // It will be enabled when the server starts.\n    handleWebSocketEvent({\n      getUnhandledRequestStrategy: () => {\n        return this.resolvedOptions.onUnhandledRequest\n      },\n      getHandlers: () => {\n        return this.handlersController.currentHandlers()\n      },\n      onMockedConnection: () => {},\n      onPassthroughConnection: () => {},\n    })\n  }\n\n  public listen(options: Partial<SharedOptions> = {}): void {\n    this.resolvedOptions = mergeRight(\n      DEFAULT_LISTEN_OPTIONS,\n      options,\n    ) as RequiredDeep<SharedOptions>\n\n    // Apply the interceptor when starting the server.\n    // Attach the event listeners to the interceptor here\n    // so they get re-attached whenever `.listen()` is called.\n    this.interceptor.apply()\n    this.init()\n    this.subscriptions.push(() => this.interceptor.dispose())\n\n    // Apply the WebSocket interception.\n    webSocketInterceptor.apply()\n    this.subscriptions.push(() => webSocketInterceptor.dispose())\n\n    // Assert that the interceptor has been applied successfully.\n    // Also guards us from forgetting to call \"interceptor.apply()\"\n    // as a part of the \"listen\" method.\n    invariant(\n      [InterceptorReadyState.APPLYING, InterceptorReadyState.APPLIED].includes(\n        this.interceptor.readyState,\n      ),\n      devUtils.formatMessage(\n        'Failed to start \"setupServer\": the interceptor failed to apply. This is likely an issue with the library and you should report it at \"%s\".',\n      ),\n      'https://github.com/mswjs/msw/issues/new/choose',\n    )\n  }\n\n  public close(): void {\n    this.dispose()\n  }\n}\n"],"mappings":"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","names":["request"]}