Full Code of mswjs/msw for AI

main 002f3e7d86dd cached
584 files
1021.2 KB
272.3k tokens
648 symbols
1 requests
Download .txt
Showing preview only (1,160K chars total). Download the full file or copy to clipboard to get everything.
Repository: mswjs/msw
Branch: main
Commit: 002f3e7d86dd
Files: 584
Total size: 1021.2 KB

Directory structure:
gitextract_krzcz2ns/

├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── 01-issue-browser.yml
│   │   ├── 02-issue-nodejs.yml
│   │   └── 03-feature.yml
│   └── workflows/
│       ├── auto.yml
│       ├── ci.yml
│       ├── compat.yml
│       ├── lock-closed-issues.yml
│       ├── release-preview.yml
│       ├── release.yml
│       ├── smoke-test.yml
│       └── typescript-nightly.yml
├── .gitignore
├── .nvmrc
├── .prettierrc
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── browser/
│   └── package.json
├── cli/
│   ├── index.js
│   ├── init.js
│   ├── invariant.js
│   └── package.json
├── commitlint.config.js
├── config/
│   ├── constants.js
│   ├── copyServiceWorker.ts
│   ├── package.json
│   ├── plugins/
│   │   └── esbuild/
│   │       ├── copyWorkerPlugin.ts
│   │       ├── forceEsmExtensionsPlugin.ts
│   │       ├── graphQLImportPlugin.ts
│   │       └── resolveCoreImportsPlugin.ts
│   ├── polyfills-node.ts
│   ├── replaceCoreImports.js
│   └── scripts/
│       ├── patch-ts.js
│       ├── postinstall.js
│       └── smoke-test.sh
├── decisions/
│   ├── jest-support.md
│   ├── linting-worker-script.md
│   ├── releases.md
│   └── typescript-versioning.md
├── eslint.config.mjs
├── global.d.ts
├── knip.json
├── native/
│   └── package.json
├── node/
│   └── package.json
├── package.json
├── release.config.json
├── src/
│   ├── browser/
│   │   ├── global.browser.d.ts
│   │   ├── index.ts
│   │   ├── setupWorker/
│   │   │   ├── glossary.ts
│   │   │   ├── setupWorker.node.test.ts
│   │   │   ├── setupWorker.ts
│   │   │   ├── start/
│   │   │   │   ├── createFallbackRequestListener.ts
│   │   │   │   ├── createRequestListener.ts
│   │   │   │   ├── createResponseListener.ts
│   │   │   │   ├── createStartHandler.ts
│   │   │   │   └── utils/
│   │   │   │       ├── enableMocking.ts
│   │   │   │       ├── getWorkerByRegistration.ts
│   │   │   │       ├── getWorkerInstance.ts
│   │   │   │       ├── prepareStartHandler.test.ts
│   │   │   │       ├── prepareStartHandler.ts
│   │   │   │       ├── printStartMessage.test.ts
│   │   │   │       ├── printStartMessage.ts
│   │   │   │       └── validateWorkerScope.ts
│   │   │   └── stop/
│   │   │       └── utils/
│   │   │           ├── printStopMessage.test.ts
│   │   │           └── printStopMessage.ts
│   │   ├── tsconfig.browser.build.json
│   │   ├── tsconfig.browser.json
│   │   └── utils/
│   │       ├── checkWorkerIntegrity.ts
│   │       ├── deserializeRequest.ts
│   │       ├── getAbsoluteWorkerUrl.test.ts
│   │       ├── getAbsoluteWorkerUrl.ts
│   │       ├── pruneGetRequestBody.test.ts
│   │       ├── pruneGetRequestBody.ts
│   │       ├── supports.ts
│   │       └── workerChannel.ts
│   ├── core/
│   │   ├── HttpResponse.test.ts
│   │   ├── HttpResponse.ts
│   │   ├── SetupApi.ts
│   │   ├── bypass.test.ts
│   │   ├── bypass.ts
│   │   ├── delay.ts
│   │   ├── getResponse.test.ts
│   │   ├── getResponse.ts
│   │   ├── graphql.test.ts
│   │   ├── graphql.ts
│   │   ├── handlers/
│   │   │   ├── GraphQLHandler.test.ts
│   │   │   ├── GraphQLHandler.ts
│   │   │   ├── HttpHandler.test.ts
│   │   │   ├── HttpHandler.ts
│   │   │   ├── RequestHandler.ts
│   │   │   ├── WebSocketHandler.test.ts
│   │   │   ├── WebSocketHandler.ts
│   │   │   └── common.ts
│   │   ├── http.test.ts
│   │   ├── http.ts
│   │   ├── index.ts
│   │   ├── isCommonAssetRequest.ts
│   │   ├── passthrough.test.ts
│   │   ├── passthrough.ts
│   │   ├── sharedOptions.ts
│   │   ├── sse.ts
│   │   ├── typeUtils.ts
│   │   ├── utils/
│   │   │   ├── HttpResponse/
│   │   │   │   └── decorators.ts
│   │   │   ├── cookieStore.ts
│   │   │   ├── executeHandlers.ts
│   │   │   ├── handleRequest.test.ts
│   │   │   ├── handleRequest.ts
│   │   │   ├── internal/
│   │   │   │   ├── Disposable.ts
│   │   │   │   ├── checkGlobals.ts
│   │   │   │   ├── devUtils.test.ts
│   │   │   │   ├── devUtils.ts
│   │   │   │   ├── getCallFrame.test.ts
│   │   │   │   ├── getCallFrame.ts
│   │   │   │   ├── hasRefCounted.test.ts
│   │   │   │   ├── hasRefCounted.ts
│   │   │   │   ├── isHandlerKind.test.ts
│   │   │   │   ├── isHandlerKind.ts
│   │   │   │   ├── isIterable.test.ts
│   │   │   │   ├── isIterable.ts
│   │   │   │   ├── isObject.test.ts
│   │   │   │   ├── isObject.ts
│   │   │   │   ├── isStringEqual.test.ts
│   │   │   │   ├── isStringEqual.ts
│   │   │   │   ├── jsonParse.test.ts
│   │   │   │   ├── jsonParse.ts
│   │   │   │   ├── mergeRight.test.ts
│   │   │   │   ├── mergeRight.ts
│   │   │   │   ├── parseGraphQLRequest.test.ts
│   │   │   │   ├── parseGraphQLRequest.ts
│   │   │   │   ├── parseMultipartData.test.ts
│   │   │   │   ├── parseMultipartData.ts
│   │   │   │   ├── pipeEvents.test.ts
│   │   │   │   ├── pipeEvents.ts
│   │   │   │   ├── requestHandlerUtils.ts
│   │   │   │   ├── toReadonlyArray.test.ts
│   │   │   │   ├── toReadonlyArray.ts
│   │   │   │   ├── tryCatch.test.ts
│   │   │   │   └── tryCatch.ts
│   │   │   ├── logging/
│   │   │   │   ├── getStatusCodeColor.test.ts
│   │   │   │   ├── getStatusCodeColor.ts
│   │   │   │   ├── getTimestamp.test.ts
│   │   │   │   ├── getTimestamp.ts
│   │   │   │   ├── serializeRequest.test.ts
│   │   │   │   ├── serializeRequest.ts
│   │   │   │   ├── serializeResponse.test.ts
│   │   │   │   └── serializeResponse.ts
│   │   │   ├── matching/
│   │   │   │   ├── matchRequestUrl.test.ts
│   │   │   │   ├── matchRequestUrl.ts
│   │   │   │   ├── normalizePath.node.test.ts
│   │   │   │   ├── normalizePath.test.ts
│   │   │   │   └── normalizePath.ts
│   │   │   ├── request/
│   │   │   │   ├── getAllAcceptedMimeTypes.test.ts
│   │   │   │   ├── getAllAcceptedMimeTypes.ts
│   │   │   │   ├── getRequestCookies.ts
│   │   │   │   ├── onUnhandledRequest.node.test.ts
│   │   │   │   ├── onUnhandledRequest.test.ts
│   │   │   │   ├── onUnhandledRequest.ts
│   │   │   │   ├── storeResponseCookies.ts
│   │   │   │   ├── toPublicUrl.node.test.ts
│   │   │   │   ├── toPublicUrl.test.ts
│   │   │   │   └── toPublicUrl.ts
│   │   │   ├── toResponseInit.ts
│   │   │   └── url/
│   │   │       ├── cleanUrl.test.ts
│   │   │       ├── cleanUrl.ts
│   │   │       ├── getAbsoluteUrl.node.test.ts
│   │   │       ├── getAbsoluteUrl.test.ts
│   │   │       ├── getAbsoluteUrl.ts
│   │   │       ├── isAbsoluteUrl.test.ts
│   │   │       └── isAbsoluteUrl.ts
│   │   ├── ws/
│   │   │   ├── WebSocketClientManager.test.ts
│   │   │   ├── WebSocketClientManager.ts
│   │   │   ├── WebSocketClientStore.ts
│   │   │   ├── WebSocketIndexedDBClientStore.ts
│   │   │   ├── WebSocketMemoryClientStore.ts
│   │   │   ├── handleWebSocketEvent.ts
│   │   │   ├── utils/
│   │   │   │   ├── attachWebSocketLogger.ts
│   │   │   │   ├── getMessageLength.test.ts
│   │   │   │   ├── getMessageLength.ts
│   │   │   │   ├── getPublicData.test.ts
│   │   │   │   ├── getPublicData.ts
│   │   │   │   ├── truncateMessage.test.ts
│   │   │   │   └── truncateMessage.ts
│   │   │   └── webSocketInterceptor.ts
│   │   ├── ws.test.ts
│   │   └── ws.ts
│   ├── iife/
│   │   └── index.ts
│   ├── mockServiceWorker.js
│   ├── native/
│   │   └── index.ts
│   ├── node/
│   │   ├── SetupServerApi.ts
│   │   ├── SetupServerCommonApi.ts
│   │   ├── glossary.ts
│   │   ├── index.ts
│   │   └── setupServer.ts
│   ├── package.json
│   ├── shims/
│   │   ├── cookie.ts
│   │   └── statuses.ts
│   ├── tsconfig.core.build.json
│   ├── tsconfig.node.build.json
│   ├── tsconfig.node.json
│   ├── tsconfig.src.json
│   └── tsconfig.worker.json
├── test/
│   ├── README.md
│   ├── browser/
│   │   ├── graphql-api/
│   │   │   ├── anonymous-operation.mocks.ts
│   │   │   ├── anonymous-operation.test.ts
│   │   │   ├── cookies.mocks.ts
│   │   │   ├── cookies.test.ts
│   │   │   ├── custom-predicate.mocks.ts
│   │   │   ├── custom-predicate.test.ts
│   │   │   ├── document-node.mocks.ts
│   │   │   ├── errors.mocks.ts
│   │   │   ├── errors.test.ts
│   │   │   ├── extensions.mocks.ts
│   │   │   ├── extensions.test.ts
│   │   │   ├── link.mocks.ts
│   │   │   ├── link.test.ts
│   │   │   ├── logging.mocks.ts
│   │   │   ├── logging.test.ts
│   │   │   ├── multipart-data.mocks.ts
│   │   │   ├── multipart-data.test.ts
│   │   │   ├── mutation.mocks.ts
│   │   │   ├── mutation.test.ts
│   │   │   ├── operation-reference.mocks.ts
│   │   │   ├── operation-reference.test.ts
│   │   │   ├── operation.mocks.ts
│   │   │   ├── operation.test.ts
│   │   │   ├── query.mocks.ts
│   │   │   ├── query.test.ts
│   │   │   ├── response-patching.mocks.ts
│   │   │   ├── response-patching.test.ts
│   │   │   ├── variables.mocks.ts
│   │   │   └── variables.test.ts
│   │   ├── msw-api/
│   │   │   ├── context/
│   │   │   │   ├── delay.mocks.ts
│   │   │   │   └── delay.test.ts
│   │   │   ├── distribution/
│   │   │   │   ├── iife.mocks.js
│   │   │   │   └── iife.test.ts
│   │   │   ├── exception-handling.mocks.ts
│   │   │   ├── exception-handling.test.ts
│   │   │   ├── hard-reload.mocks.ts
│   │   │   ├── hard-reload.test.ts
│   │   │   ├── integrity-check-invalid.mocks.ts
│   │   │   ├── integrity-check-valid.mocks.ts
│   │   │   ├── integrity-check.test.ts
│   │   │   ├── regression/
│   │   │   │   ├── 2129-worker-use.mocks.ts
│   │   │   │   ├── 2129-worker-use.test.ts
│   │   │   │   ├── handle-stream.mocks.ts
│   │   │   │   ├── handle-stream.test.ts
│   │   │   │   ├── null-body.mocks.ts
│   │   │   │   └── null-body.test.ts
│   │   │   ├── req/
│   │   │   │   ├── passthrough.mocks.ts
│   │   │   │   └── passthrough.test.ts
│   │   │   ├── res/
│   │   │   │   ├── network-error.mocks.ts
│   │   │   │   └── network-error.test.ts
│   │   │   ├── setup-worker/
│   │   │   │   ├── fallback-mode/
│   │   │   │   │   ├── fallback-mode.mocks.ts
│   │   │   │   │   └── fallback-mode.test.ts
│   │   │   │   ├── input-validation.mocks.ts
│   │   │   │   ├── input-validation.test.ts
│   │   │   │   ├── life-cycle-events/
│   │   │   │   │   ├── on.mocks.ts
│   │   │   │   │   ├── on.test.ts
│   │   │   │   │   ├── removeAllListeners.test.ts
│   │   │   │   │   └── removeListener.test.ts
│   │   │   │   ├── listHandlers.mocks.ts
│   │   │   │   ├── listHandlers.test.ts
│   │   │   │   ├── resetHandlers.test.ts
│   │   │   │   ├── response-logging.test.ts
│   │   │   │   ├── restoreHandlers.test.ts
│   │   │   │   ├── scenarios/
│   │   │   │   │   ├── custom-transformers.mocks.ts
│   │   │   │   │   ├── custom-transformers.test.ts
│   │   │   │   │   ├── errors/
│   │   │   │   │   │   ├── internal-error.mocks.ts
│   │   │   │   │   │   ├── internal-error.test.ts
│   │   │   │   │   │   ├── network-error.mocks.ts
│   │   │   │   │   │   └── network-error.test.ts
│   │   │   │   │   ├── fall-through.mocks.ts
│   │   │   │   │   ├── fall-through.test.ts
│   │   │   │   │   ├── iframe/
│   │   │   │   │   │   ├── app.html
│   │   │   │   │   │   ├── iframe.mocks.ts
│   │   │   │   │   │   ├── iframe.test.ts
│   │   │   │   │   │   ├── multiple-workers/
│   │   │   │   │   │   │   ├── child.mocks.ts
│   │   │   │   │   │   │   ├── iframe-multiple-workers.test.ts
│   │   │   │   │   │   │   └── parent.mocks.ts
│   │   │   │   │   │   ├── page-in-iframe.html
│   │   │   │   │   │   └── page-in-nested-iframe.html
│   │   │   │   │   ├── iframe-isolated-response/
│   │   │   │   │   │   ├── app.html
│   │   │   │   │   │   ├── iframe-isolated-response.mocks.ts
│   │   │   │   │   │   ├── iframe-isolated-response.test.ts
│   │   │   │   │   │   ├── one.html
│   │   │   │   │   │   └── two.html
│   │   │   │   │   ├── scope/
│   │   │   │   │   │   ├── scope-nested-quiet.mocks.ts
│   │   │   │   │   │   ├── scope-nested.mocks.ts
│   │   │   │   │   │   ├── scope-root.mocks.ts
│   │   │   │   │   │   └── scope-validation.test.ts
│   │   │   │   │   ├── shared-worker/
│   │   │   │   │   │   ├── shared-worker.mocks.ts
│   │   │   │   │   │   ├── shared-worker.test.ts
│   │   │   │   │   │   └── worker.js
│   │   │   │   │   ├── text-event-stream.mocks.ts
│   │   │   │   │   └── text-event-stream.test.ts
│   │   │   │   ├── start/
│   │   │   │   │   ├── error.mocks.ts
│   │   │   │   │   ├── error.test.ts
│   │   │   │   │   ├── find-worker.error.mocks.ts
│   │   │   │   │   ├── find-worker.mocks.ts
│   │   │   │   │   ├── find-worker.test.ts
│   │   │   │   │   ├── on-unhandled-request/
│   │   │   │   │   │   ├── bypass.mocks.ts
│   │   │   │   │   │   ├── bypass.test.ts
│   │   │   │   │   │   ├── callback-print.mocks.ts
│   │   │   │   │   │   ├── callback-print.test.ts
│   │   │   │   │   │   ├── callback-throws.mocks.ts
│   │   │   │   │   │   ├── callback.mocks.ts
│   │   │   │   │   │   ├── callback.test.ts
│   │   │   │   │   │   ├── default.mocks.ts
│   │   │   │   │   │   ├── default.test.ts
│   │   │   │   │   │   ├── warn.mocks.ts
│   │   │   │   │   │   └── warn.test.ts
│   │   │   │   │   ├── options-sw-scope.mocks.ts
│   │   │   │   │   ├── options-sw-scope.test.ts
│   │   │   │   │   ├── quiet.mocks.ts
│   │   │   │   │   ├── quiet.test.ts
│   │   │   │   │   ├── start.mocks.ts
│   │   │   │   │   ├── start.test.ts
│   │   │   │   │   ├── warn-on-wait-until-ready.mocks.ts
│   │   │   │   │   ├── warn-on-wait-until-ready.test.ts
│   │   │   │   │   └── worker.delayed.js
│   │   │   │   ├── stop/
│   │   │   │   │   ├── in-flight-request.mocks.ts
│   │   │   │   │   ├── in-flight-request.test.ts
│   │   │   │   │   ├── quiet.mocks.ts
│   │   │   │   │   ├── quiet.test.ts
│   │   │   │   │   ├── removes-all-listeners.mocks.ts
│   │   │   │   │   └── removes-all-listeners.test.ts
│   │   │   │   ├── stop.mocks.ts
│   │   │   │   ├── stop.test.ts
│   │   │   │   ├── use.mocks.ts
│   │   │   │   ├── use.test.ts
│   │   │   │   ├── worker-passthrough-header.mocks.ts
│   │   │   │   └── worker-passthrough-header.test.ts
│   │   │   ├── unregister.mocks.ts
│   │   │   └── unregister.test.ts
│   │   ├── playwright.config.ts
│   │   ├── playwright.extend.ts
│   │   ├── rest-api/
│   │   │   ├── 204-response.test.ts
│   │   │   ├── 206-response.mocks.ts
│   │   │   ├── 206-response.test.ts
│   │   │   ├── basic.mocks.ts
│   │   │   ├── basic.test.ts
│   │   │   ├── body.mocks.ts
│   │   │   ├── body.test.ts
│   │   │   ├── context.mocks.ts
│   │   │   ├── context.test.ts
│   │   │   ├── cors.mocks.ts
│   │   │   ├── cors.test.ts
│   │   │   ├── generator.mocks.ts
│   │   │   ├── generator.test.ts
│   │   │   ├── headers-multiple.mocks.ts
│   │   │   ├── headers-multiple.test.ts
│   │   │   ├── logging.test.ts
│   │   │   ├── params.mocks.ts
│   │   │   ├── params.test.ts
│   │   │   ├── plain-response.mocks.ts
│   │   │   ├── plain-response.test.ts
│   │   │   ├── query-params-warning.mocks.ts
│   │   │   ├── query-params-warning.test.ts
│   │   │   ├── query.mocks.ts
│   │   │   ├── query.test.ts
│   │   │   ├── redirect.mocks.ts
│   │   │   ├── redirect.test.ts
│   │   │   ├── request/
│   │   │   │   ├── body/
│   │   │   │   │   ├── body-arraybuffer-range.mocks.ts
│   │   │   │   │   ├── body-arraybuffer-range.test.ts
│   │   │   │   │   ├── body-arraybuffer.test.ts
│   │   │   │   │   ├── body-form-data.page.html
│   │   │   │   │   ├── body-form-data.test.ts
│   │   │   │   │   ├── body-json.test.ts
│   │   │   │   │   ├── body-text.test.ts
│   │   │   │   │   └── body.mocks.ts
│   │   │   │   ├── matching/
│   │   │   │   │   ├── all.mocks.ts
│   │   │   │   │   ├── all.test.ts
│   │   │   │   │   ├── custom-predicate.mocks.ts
│   │   │   │   │   ├── custom-predicate.test.ts
│   │   │   │   │   ├── method.mocks.ts
│   │   │   │   │   ├── method.test.ts
│   │   │   │   │   ├── path-params-decode.mocks.ts
│   │   │   │   │   ├── path-params-decode.test.ts
│   │   │   │   │   ├── uri.mocks.ts
│   │   │   │   │   └── uri.test.ts
│   │   │   │   ├── request-cookies.mocks.ts
│   │   │   │   └── request-cookies.test.ts
│   │   │   ├── response/
│   │   │   │   ├── body/
│   │   │   │   │   ├── body-binary.mocks.ts
│   │   │   │   │   ├── body-binary.test.ts
│   │   │   │   │   ├── body-blob.mocks.ts
│   │   │   │   │   ├── body-blob.test.ts
│   │   │   │   │   ├── body-formdata.mocks.ts
│   │   │   │   │   ├── body-formdata.test.ts
│   │   │   │   │   ├── body-html.mocks.ts
│   │   │   │   │   ├── body-html.test.ts
│   │   │   │   │   ├── body-json.mocks.ts
│   │   │   │   │   ├── body-json.test.ts
│   │   │   │   │   ├── body-stream.mocks.ts
│   │   │   │   │   ├── body-stream.test.ts
│   │   │   │   │   ├── body-text.mocks.ts
│   │   │   │   │   ├── body-text.test.ts
│   │   │   │   │   ├── body-xml.mocks.ts
│   │   │   │   │   └── body-xml.test.ts
│   │   │   │   ├── response-cookies.mocks.ts
│   │   │   │   ├── response-cookies.test.ts
│   │   │   │   ├── response-error.mocks.ts
│   │   │   │   ├── response-error.test.ts
│   │   │   │   ├── throw-response.mocks.ts
│   │   │   │   └── throw-response.test.ts
│   │   │   ├── response-patching.mocks.ts
│   │   │   ├── response-patching.test.ts
│   │   │   ├── send-beacon.mocks.ts
│   │   │   ├── send-beacon.test.ts
│   │   │   ├── status.mocks.ts
│   │   │   ├── status.test.ts
│   │   │   ├── xhr.mocks.ts
│   │   │   └── xhr.test.ts
│   │   ├── setup/
│   │   │   ├── webpackHttpServer.ts
│   │   │   └── workerConsole.ts
│   │   ├── sse-api/
│   │   │   ├── sse.client.send.extraneous.test.ts
│   │   │   ├── sse.client.send.multiline.test.ts
│   │   │   ├── sse.client.send.test.ts
│   │   │   ├── sse.mocks.ts
│   │   │   ├── sse.quiet.test.ts
│   │   │   ├── sse.retry.test.ts
│   │   │   ├── sse.server.connect.test.ts
│   │   │   ├── sse.use.test.ts
│   │   │   └── sse.with-credentials.test.ts
│   │   ├── third-party/
│   │   │   ├── axios-upload.browser.test.ts
│   │   │   └── axios-upload.runtime.js
│   │   └── ws-api/
│   │       ├── ws.apply.browser.test.ts
│   │       ├── ws.client.send.test.ts
│   │       ├── ws.clients.browser.test.ts
│   │       ├── ws.intercept.client.browser.test.ts
│   │       ├── ws.intercept.server.browser.test.ts
│   │       ├── ws.logging.browser.test.ts
│   │       ├── ws.runtime.js
│   │       ├── ws.server.connect.browser.test.ts
│   │       └── ws.use.browser.test.ts
│   ├── e2e/
│   │   ├── auto-update-worker.node.test.ts
│   │   ├── cli-init.node.test.ts
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   ├── vitest.d.ts
│   │   └── vitest.global.setup.ts
│   ├── global.d.ts
│   ├── modules/
│   │   ├── browser/
│   │   │   ├── esm-browser.test.ts
│   │   │   └── playwright.config.ts
│   │   ├── module-utils.ts
│   │   └── node/
│   │       ├── esm-node.test.ts
│   │       ├── tsconfig.json
│   │       └── vitest.config.ts
│   ├── native/
│   │   ├── node-events.native.test.ts
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   └── vitest.setup.ts
│   ├── node/
│   │   ├── graphql-api/
│   │   │   ├── anonymous-operations.test.ts
│   │   │   ├── batched-queries.apollo.test.ts
│   │   │   ├── batched-queries.batched-execute.test.ts
│   │   │   ├── compatibility.node.test.ts
│   │   │   ├── content-type.test.ts
│   │   │   ├── cookies.test.ts
│   │   │   ├── custom-predicate.node.test.ts
│   │   │   ├── extensions.node.test.ts
│   │   │   ├── response-patching.node.test.ts
│   │   │   ├── typed-document-node.test.ts
│   │   │   └── typed-document-string.test.ts
│   │   ├── msw-api/
│   │   │   ├── context/
│   │   │   │   ├── delay-infinite.fixture.js
│   │   │   │   └── delay.node.test.ts
│   │   │   ├── req/
│   │   │   │   └── passthrough.node.test.ts
│   │   │   ├── res/
│   │   │   │   └── network-error.node.test.ts
│   │   │   └── setup-server/
│   │   │       ├── boundary/
│   │   │       │   ├── boundary.args.test.ts
│   │   │       │   ├── boundary.concurrency.test.ts
│   │   │       │   └── boundary.handlers.test.ts
│   │   │       ├── input-validation.node.test.ts
│   │   │       ├── life-cycle-events/
│   │   │       │   ├── on.node.test.ts
│   │   │       │   ├── removeAllListeners.node.test.ts
│   │   │       │   └── removeListener.node.test.ts
│   │   │       ├── listHandlers.node.test.ts
│   │   │       ├── resetHandlers.node.test.ts
│   │   │       ├── restoreHandlers.node.test.ts
│   │   │       ├── scenarios/
│   │   │       │   ├── cookies-request.node.test.ts
│   │   │       │   ├── custom-interceptors.node.test.ts
│   │   │       │   ├── custom-transformers.node.test.ts
│   │   │       │   ├── fake-timers.node.test.ts
│   │   │       │   ├── fall-through.node.test.ts
│   │   │       │   ├── fetch.node.test.ts
│   │   │       │   ├── generator.node.test.ts
│   │   │       │   ├── graphql.node.test.ts
│   │   │       │   ├── http.node.test.ts
│   │   │       │   ├── https.node.test.ts
│   │   │       │   ├── on-unhandled-request/
│   │   │       │   │   ├── bypass.node.test.ts
│   │   │       │   │   ├── callback-throws.node.test.ts
│   │   │       │   │   ├── callback.node.test.ts
│   │   │       │   │   ├── default.node.test.ts
│   │   │       │   │   ├── error.node.test.ts
│   │   │       │   │   └── warn.node.test.ts
│   │   │       │   ├── relative-url.node.test.ts
│   │   │       │   ├── response-patching.node.test.ts
│   │   │       │   └── xhr.node.test.ts
│   │   │       └── use.node.test.ts
│   │   ├── regressions/
│   │   │   ├── 2129-server-use.test.ts
│   │   │   ├── 2370-listen-after-close.test.ts
│   │   │   ├── many-request-handlers-jsdom.test.ts
│   │   │   ├── many-request-handlers.test.ts
│   │   │   ├── miniflare.node.test.ts
│   │   │   └── mixed-graphql-http-with-query-in-body.node.test.ts
│   │   ├── rest-api/
│   │   │   ├── cookies-inheritance.node.test.ts
│   │   │   ├── https.node.test.ts
│   │   │   ├── request/
│   │   │   │   ├── body/
│   │   │   │   │   ├── body-arraybuffer.node.test.ts
│   │   │   │   │   ├── body-blob.node.test.ts
│   │   │   │   │   ├── body-form-data.node.test.ts
│   │   │   │   │   ├── body-json.node.test.ts
│   │   │   │   │   ├── body-protobuf.node.test.ts
│   │   │   │   │   ├── body-text.node.test.ts
│   │   │   │   │   └── body-used.node.test.ts
│   │   │   │   └── matching/
│   │   │   │       ├── all.node.test.ts
│   │   │   │       ├── custom-predicate.node.test.ts
│   │   │   │       ├── path-params-decode.node.test.ts
│   │   │   │       ├── path-params-optional.node.test.ts
│   │   │   │       └── relative-url.node.test.ts
│   │   │   ├── response/
│   │   │   │   ├── body-binary.node.test.ts
│   │   │   │   ├── body-html.node.test.ts
│   │   │   │   ├── body-json.node.test.ts
│   │   │   │   ├── body-stream.node.test.ts
│   │   │   │   ├── body-text.node.test.ts
│   │   │   │   ├── body-xml.node.test.ts
│   │   │   │   ├── generator.test.ts
│   │   │   │   ├── response-cookies.test.ts
│   │   │   │   ├── response-error.test.ts
│   │   │   │   └── throw-response.node.test.ts
│   │   │   └── response-patching.node.test.ts
│   │   ├── third-party/
│   │   │   ├── axios-error-response.test.ts
│   │   │   ├── axios-timeout.node.test.ts
│   │   │   └── axios-upload.node.test.ts
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   └── ws-api/
│   │       ├── on-unhandled-request/
│   │       │   ├── callback.test.ts
│   │       │   ├── error.test.ts
│   │       │   └── warn.test.ts
│   │       ├── ws.apply.test.ts
│   │       ├── ws.event-patching.test.ts
│   │       ├── ws.intercept.client.test.ts
│   │       ├── ws.intercept.server.test.ts
│   │       ├── ws.server.connect.test.ts
│   │       ├── ws.stop-propagation.test.ts
│   │       ├── ws.unhandled-exception.test.ts
│   │       └── ws.use.test.ts
│   ├── package.json
│   ├── support/
│   │   ├── WebSocketServer.ts
│   │   ├── alias.ts
│   │   ├── environments/
│   │   │   └── vitest-environment-node-websocket.ts
│   │   ├── graphql.ts
│   │   ├── msw-esm/
│   │   │   └── package.json
│   │   ├── utils.ts
│   │   └── waitFor.ts
│   ├── tsconfig.json
│   └── typings/
│       ├── custom-handler.test-d.ts
│       ├── custom-resolver.test-d.ts
│       ├── graphql-custom-predicate.test-d.ts
│       ├── graphql-typed-document-node.test-d.ts
│       ├── graphql-typed-document-string.test-d.ts
│       ├── graphql.test-d.ts
│       ├── http-custom-predicate.test-d.ts
│       ├── http.test-d.ts
│       ├── regressions/
│       │   ├── default-resolver-type.test-d.ts
│       │   ├── request-handler-type.test-d.ts
│       │   └── response-body-type.test-d.ts
│       ├── resolver-generator.test-d.ts
│       ├── server.boundary.test-d.ts
│       ├── setup-server.test-d.ts
│       ├── setup-worker.test-d.ts
│       ├── sse.test-d.ts
│       ├── tsconfig.5.0.json
│       ├── tsconfig.5.1.json
│       ├── tsconfig.5.2.json
│       ├── tsconfig.5.3.json
│       ├── tsconfig.5.4.json
│       ├── tsconfig.5.5.json
│       ├── tsconfig.json
│       ├── vitest.config.ts
│       └── ws.test-d.ts
├── tsconfig.base.json
├── tsconfig.json
├── tsconfig.test.unit.json
├── tsup.config.ts
└── vitest.config.mts

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
github: mswjs
open_collective: mswjs


================================================
FILE: .github/ISSUE_TEMPLATE/01-issue-browser.yml
================================================
name: 'Bug report (Browser)'
description: I experience unexpected behavior using the library in a browser.
labels: ['bug', 'scope:browser', 'needs:triage']
body:
  - type: markdown
    attributes:
      value: Thank you for reporting an issue to Mock Service Worker! Please fill in the template below to help our team tackle it in the most efficient way.

  - type: checkboxes
    attributes:
      label: Prerequisites
      description: Before we begin, let's make sure your issue hasn't been solved already.
      options:
        - label: I confirm my issue is not in the [opened issues](https://github.com/mswjs/msw/issues)
          required: true
        - label: I confirm the [Frequently Asked Questions](https://mswjs.io/docs/faq) didn't contain the answer to my issue
          required: true

  - type: checkboxes
    attributes:
      label: Environment check
      options:
        - label: I'm using the [latest](https://github.com/mswjs/msw/releases/latest) `msw` version
          required: true
        - label: I'm using Node.js version 20 or higher
          required: true

  - type: dropdown
    attributes:
      label: Browsers
      description: Select in which browser(s) you're experiencing the issue.
      multiple: true
      options:
        - 'Chromium (Chrome, Brave, etc.)'
        - 'Firefox'
        - 'Safari'

  - type: input
    attributes:
      label: Reproduction repository
      description: A link to the repository where your issue can be reproduced. You can clone one of [our examples](https://github.com/mswjs/examples) to create a reproduction repository much faster. **Issues without a reproduction repository will be closed**.
      placeholder: i.e. https://github.com/you/msw-issue
    validations:
      required: true

  - type: textarea
    attributes:
      label: Reproduction steps
      description: Include any steps necessary to reproduce the issue in the repository above.
      placeholder: i.e. "npm test"
    validations:
      required: true

  - type: textarea
    attributes:
      label: Current behavior
      description: Share any details on what behavior you're experiencing (error messages, logs, context).
    validations:
      required: true

  - type: textarea
    attributes:
      label: Expected behavior
      description: What do you expect to happen instead?
    validations:
      required: true


================================================
FILE: .github/ISSUE_TEMPLATE/02-issue-nodejs.yml
================================================
name: 'Bug report (Node.js)'
description: I experience unexpected behavior using the library in Node.js (Vitest/React Native/Express/etc.).
labels: ['bug', 'scope:node', 'needs:triage']
body:
  - type: markdown
    attributes:
      value: Thank you for reporting an issue to Mock Service Worker! Please fill in the template below to help our team tackle it in the most efficient way.

  - type: checkboxes
    attributes:
      label: Prerequisites
      description: Before we begin, let's make sure your issue hasn't been solved already.
      options:
        - label: I confirm my issue is not in the [opened issues](https://github.com/mswjs/msw/issues)
          required: true
        - label: I confirm the [Frequently Asked Questions](https://mswjs.io/docs/faq) didn't contain the answer to my issue
          required: true

  - type: checkboxes
    attributes:
      label: Environment check
      description: Next, let's make sure you're using the library in the officially supported environments.
      options:
        - label: I'm using the [latest](https://github.com/mswjs/msw/releases/latest) `msw` version
          required: true
        - label: I'm using Node.js version 20 or higher
          required: true

  - type: input
    attributes:
      label: Node.js version
      description: Specify which Node.js version you're using (`node -v`).
      placeholder: i.e. v20.18.0
    validations:
      required: true

  - type: input
    attributes:
      label: Reproduction repository
      description: A link to the repository where your issue can be reproduced. You can clone one of [our examples](https://github.com/mswjs/examples) to create a reproduction repository much faster. **Issues without a reproduction repository will be closed**.
      placeholder: i.e. https://github.com/you/msw-issue
    validations:
      required: true

  - type: textarea
    attributes:
      label: Reproduction steps
      description: Include any steps necessary to reproduce the issue in the repository above.
      placeholder: i.e. "npm test"
    validations:
      required: true

  - type: textarea
    attributes:
      label: Current behavior
      description: Share any details on what behavior you're experiencing (error messages, logs, context).
    validations:
      required: true

  - type: textarea
    attributes:
      label: Expected behavior
      description: What do you expect to happen instead?
    validations:
      required: true


================================================
FILE: .github/ISSUE_TEMPLATE/03-feature.yml
================================================
name: 'Feature request'
description: Propose a feature or improvement.
labels: [feature]
body:
  - type: markdown
    attributes:
      value: Thank you for deciding to make Mock Service Worker better! Please fill in the form below so our team could understand your feature better.

  - type: dropdown
    attributes:
      label: Scope
      multiple: false
      options:
        - 'Adds a new behavior'
        - 'Improves an existing behavior'
    validations:
      required: true

  - type: checkboxes
    attributes:
      label: Compatibility
      description: Check if your proposal is a breaking change. Leave this field unchecked if not sure.
      options:
        - label: This is a breaking change
          required: false

  - type: textarea
    attributes:
      label: Feature description
      description: "Describe the feature you're suggesting. Be as detailed as possible: include behavior description, pseudo-code snippets, comparison to similar features."
    validations:
      required: true


================================================
FILE: .github/workflows/auto.yml
================================================
name: auto

on: [push]

jobs:
  cancel-previous-workflows:
    runs-on: macos-latest
    timeout-minutes: 3
    steps:
      - uses: styfle/cancel-workflow-action@0.9.1
        with:
          workflow_id: ci.yml
          access_token: ${{ github.token }}


================================================
FILE: .github/workflows/ci.yml
================================================
name: ci

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:

jobs:
  build-20:
    name: build (20)
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install

      - name: Lint
        run: pnpm lint

      - name: Build
        run: pnpm build

      - name: Cache build output
        uses: actions/cache@v4
        with:
          path: ./lib
          key: ${{ runner.os }}-node-20-build-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-build-20

  build-22:
    name: build (22)
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install

      - name: Lint
        run: pnpm lint

      - name: Build
        run: pnpm build

      - name: Cache build output
        uses: actions/cache@v4
        with:
          path: ./lib
          key: ${{ runner.os }}-node-22-build-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-build-22

  test-unit:
    name: test (unit)
    needs: build-20
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Restore build cache
        uses: actions/cache@v4
        with:
          path: ./lib
          key: ${{ runner.os }}-node-20-build-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-node-20-build-

      - name: Install dependencies
        run: pnpm install

      - name: Install Playwright browsers
        run: pnpm exec playwright install chromium --with-deps --only-shell

      - name: Unit tests
        run: pnpm test:unit

  test-node-20:
    name: test (node.js) (20)
    needs: build-20
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Restore build cache
        uses: actions/cache@v4
        with:
          path: ./lib
          key: ${{ runner.os }}-node-20-build-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-node-20-build-

      - name: Install dependencies
        run: pnpm install

      - name: Node.js tests
        run: pnpm test:node

  test-node-22:
    name: test (node.js) (22)
    needs: build-22
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'pnpm'

      - name: Restore build cache
        uses: actions/cache@v4
        with:
          path: ./lib
          key: ${{ runner.os }}-node-22-build-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-node-22-build-

      - name: Install dependencies
        run: pnpm install

      - name: Node.js tests
        run: pnpm test:node

  test-e2e:
    name: test (e2e) (20)
    needs: build-20
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install

      - name: E2E tests
        run: pnpm test:e2e

  test-browser:
    name: test (browser)
    needs: build-20
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Restore build cache
        uses: actions/cache@v4
        with:
          path: ./lib
          key: ${{ runner.os }}-node-20-build-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-node-20-build-

      - name: Install dependencies
        run: pnpm install

      - name: Playwright install
        run: pnpm exec playwright install chromium --with-deps --only-shell

      - name: Browser tests
        run: pnpm test:browser

      - name: Upload test artifacts
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: playwright-report
          path: test/browser/test-results

  test-native:
    name: test (react-native)
    needs: build-20
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Restore build cache
        uses: actions/cache@v4
        with:
          path: ./lib
          key: ${{ runner.os }}-node-20-build-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-node-20-build-

      - name: Install dependencies
        run: pnpm install

      - name: React Native tests
        run: pnpm test:native


================================================
FILE: .github/workflows/compat.yml
================================================
name: compat

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:

jobs:
  # Validate the package.json exports and emitted CJS/ESM bundles.
  exports:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Install dependencies
        run: pnpm install

      - name: Install Playwright browsers
        run: pnpm exec playwright install chromium --with-deps --only-shell

      - name: Build
        run: pnpm build

      - name: Lint package
        run: pnpm publint

      - name: Test modules (Node.js)
        run: pnpm test:modules:node

      - name: Test modules (browser)
        run: pnpm test:modules:browser

  # Checks the library's compatibility with different
  # TypeScript versions to discover type regressions.
  typescript:
    runs-on: macos-latest
    # Skip TypeScript compatibility check on "main".
    # A merged pull request implies passing "typescript" job.
    if: github.ref != 'refs/heads/main'
    strategy:
      fail-fast: false
      matrix:
        # As a general rule, when adding a new version, remove the oldest version
        # Check if the oldest version is EOL or not first.
        ts: ['5.0', '5.1', '5.2', '5.3', '5.4', '5.5', '5.6', '5.7', '5.8']
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Install dependencies
        run: pnpm install

      - name: Build
        run: pnpm build

      - name: Install TypeScript ${{ matrix.ts }}
        run: pnpm add typescript@${{ matrix.ts }}

      - name: Typings tests
        run: |
          pnpm tsc --version
          pnpm test:ts


================================================
FILE: .github/workflows/lock-closed-issues.yml
================================================
name: locked-closed-issues

on:
  schedule:
    - cron: '0 0 * * *'

permissions:
  issues: write

jobs:
  action:
    runs-on: macos-latest
    steps:
      - uses: dessant/lock-threads@v5
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          issue-inactive-days: '14'
          issue-lock-reason: ''
          process-only: 'issues'


================================================
FILE: .github/workflows/release-preview.yml
================================================
name: release-preview

on:
  push:
    branches-ignore:
      - 'main'
    tags:
      - '!**'
  workflow_dispatch:

jobs:
  publish:
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Install dependencies
        run: pnpm install

      - name: Install Playwright browsers
        run: pnpm exec playwright install chromium --with-deps --only-shell

      - name: Lint
        run: pnpm lint

      - name: Build
        run: pnpm build

      - name: Tests
        run: pnpm test

      - name: Publish preview
        run: pnpm dlx pkg-pr-new@0.0 publish --compact --pnpm --comment=update


================================================
FILE: .github/workflows/release.yml
================================================
name: release

on:
  schedule:
    - cron: '0 1 * * *'
  workflow_dispatch:

jobs:
  build:
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.GH_ADMIN_TOKEN }}

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install

      - name: Install Playwright browsers
        run: pnpm exec playwright install chromium --with-deps --only-shell

      - name: Lint
        run: pnpm lint

      - name: Build
        run: pnpm build

      - name: Tests
        run: pnpm test

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-artifacts
          path: ./lib

  release:
    needs: [build]
    runs-on: macos-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.GH_ADMIN_TOKEN }}

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          # Trusted Publishing only works on Node.js v24.
          node-version: 24
          cache: 'pnpm'

      - name: Setup Git
        run: |
          git config --local user.name "Artem Zakharchenko"
          git config --local user.email "kettanaito@gmail.com"

      - name: Install dependencies
        run: pnpm install

      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: build-artifacts
          path: ./lib

      - name: Release
        run: pnpm release
        env:
          GITHUB_TOKEN: ${{ secrets.GH_ADMIN_TOKEN }}


================================================
FILE: .github/workflows/smoke-test.yml
================================================
name: smoke-test

on:
  # Always run smoke tests upon a successful
  # "ci" job completion on "main".
  workflow_run:
    workflows: ['ci']
    branches: [main]
    types: [completed]
  workflow_dispatch:

jobs:
  examples:
    if: ${{ (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || github.event_name == 'workflow_dispatch' }}
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Install dependencies
        run: pnpm install

      - name: Test examples
        run: ./config/scripts/smoke-test.sh


================================================
FILE: .github/workflows/typescript-nightly.yml
================================================
name: typescript-nightly

on:
  schedule:
    # Schedule to run nightly at midnight
    - cron: '0 0 * * *'
  workflow_dispatch:

jobs:
  compare:
    runs-on: macos-latest
    steps:
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Get latest TypeScript version
        id: get-versions
        run: |
          # Fetch the latest published version of TypeScript on npm
          latest_version=$(npm show typescript dist-tags.latest)

          # Get the currently installed version
          rc_version=$(npm show typescript dist-tags.rc)

          latest_major_minor=$(echo "$latest_version" | cut -d '.' -f 1,2)
          rc_major_minor=$(echo "$rc_version" | cut -d '.' -f 1,2)

          echo "latest_version=$latest_major_minor" >> $GITHUB_OUTPUT
          echo "rc_version=$rc_major_minor" >> $GITHUB_OUTPUT

  test:
    runs-on: macos-latest
    # Skip TypeScript compatibility check on "main".
    # A merged pull request implies passing "typescript" job.
    if: ${{ needs.compare.outputs.latest_version != needs.compare.outputs.rc_version }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Install dependencies
        run: pnpm install

      - name: Build
        run: pnpm build

      - name: Install TypeScript RC
        run: pnpm add typescript@rc

      - name: Write tsconfig
        run: |
          cp test/typings/tsconfig.5.2.json test/typings/tsconfig.${needs.compare.outputs.rc_version}.json

      - name: Typings tests
        run: |
          pnpm tsc --version
          pnpm test:ts


================================================
FILE: .gitignore
================================================
__*
.DS_*
node_modules
/lib
tmp
*-error.log
/package-lock.json
/yarn.lock
stats.html
.vscode
.idea
msw-*.tgz
.husky/_
.env
**/test-results
/test/modules/node/node-esm-tests

# Smoke test temporary files.
/package.json.copy
/examples
/test/modules/node/node-esm-tests
*.vitest-temp.json


================================================
FILE: .nvmrc
================================================
v20


================================================
FILE: .prettierrc
================================================
{
  "arrowParens": "always",
  "bracketSpacing": true,
  "semi": false,
  "useTabs": false,
  "trailingComma": "all",
  "singleQuote": true
}

================================================
FILE: CHANGELOG.md
================================================
# Change Log

This project adheres to [Semantic Versioning](https://semver.org/).
Every release, along with the migration instructions, is documented on the Github [Releases](https://github.com/mswjs/msw/releases) page.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

Hey! Thank you for deciding to contribute to Mock Service Worker! This page will help you land your first contribution by giving you a better understanding about the project's structure, dependencies, and development workflow.

## Tools

Getting yourself familiar with the tools below will substantially ease your contribution experience.

- [TypeScript](https://www.typescriptlang.org/)
- [Vitest](https://vitest.dev/)
- [Playwright](https://playwright.dev/)

## Dependencies

Mock Service Worker depends on multiple other libraries.

| Library name                                            | Purpose                                                                  |
| ------------------------------------------------------- | ------------------------------------------------------------------------ |
| [cookies](https://github.com/mswjs/cookies)             | Enables cookies persistence and inference between environments.          |
| [headers-utils](https://github.com/mswjs/headers-utils) | `Headers` polyfill to manage request/response headers.                   |
| [interceptors](https://github.com/mswjs/interceptors)   | Provisions request interception in Node.js (internals of `setupServer`). |

There are cases when an issue originates from one of the said dependencies. Don't hesitate to address it in the respective repository, as they all are governed by the same team.

## Getting started

### Fork the repository

Please use the GitHub UI to [fork this repository](https://github.com/mswjs/msw) (_read more about [Forking a repository](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo)_). Mock Service Worker has forked builds enabled in the CI, so you will see the build status of your fork's branch.

### Install

```bash
$ cd msw
$ pnpm install
$ pnpm start
```

> Please use [PNPM][pnpm-url] version 8.15 while working on this project.
> Guide on how to install a specific PNPM version can be [found here][pnpm-install-guide-url].

## Git workflow

```bash
# Checkout the default branch and ensure it's up-to-date
$ git checkout main
$ git pull --rebase

# Create a feature branch
$ git checkout -b feature/graphql-subscriptions

# Commit the changes
$ git add .
$ git commit
# Follow the interactive prompt to compose a commit message

# Push
$ git push -u origin feature/graphql-subscriptions
```

We are using [Conventional Commits](https://conventionalcommits.org/) naming convention. It helps us automate library releases and ensure clean and standardized commit tree. Please take a moment to read about the said convention before you name your commits.

> **Tip:** running `git commit` will open an interactive prompt in your terminal. Follow the prompt to compose a valid commit message.

Once you have pushed the changes to your remote feature branch, [create a pull request](https://github.com/open-draft/msw/compare) on GitHub. Undergo the process of code review, where the maintainers of the library will help you get the changes from good to great, and enjoy your implementation merged to the default branch.

> Please be respectful when requesting and going through the code review. Everyone on the team is interested in merging quality and well tested code, and we're hopeful that you have the same goal. It may take some time and iterations to get it right, and we will assist you throughout the process.

## Build

Build the library with the following command:

```bash
$ pnpm build
```

## Tests

### Testing levels

There are two levels of tests on the project:

- [Unit tests](#unit-tests), cover small independent functions.
- [Integration tests](#integration-tests), test in-browser usage scenarios.

**Always begin your implementation from tests**. When tackling an issue, a test for it must be missing, or is incomplete. When working on a feature, starting with a test allows you to model the feature's usage before diving into implementation.

### Unit tests

#### Writing a unit test

Unit tests are placed next to the tested code. For example, if you're testing a newly added `multiply` function, create a `multiply.test.ts` file next to where the function is located:

```bash
$ touch src/utils/multiply.test.ts
```

Proceed by writing a unit test that resembles the usage of the function. Make sure to cover all the scenarios

```ts
// src/utils/multiply.test.ts
import { multiply } from './multiply'

test('multiplies two given numbers', () => {
  expect(multiply(2, 3)).toEqual(6)
})
```

> Please [avoid nesting](https://kentcdodds.com/blog/avoid-nesting-when-youre-testing/) while you're testing.

#### Running a single unit test

Once your test is written, run it in isolation.

```bash
$ pnpm test:unit src/utils/multiply.test.ts
```

At this point, the actual implementation is not ready yet, so you can expect your test to fail. **That's perfect**. Add the necessary modules and logic, and gradually see your test cases pass.

#### Running all unit tests

```bash
$ pnpm test:unit
```

### Integration tests

We follow an example-driven testing paradigm, meaning that each integration test represents a _usage example_. Mock Service Worker can be used in different environments (browser, Node.js), making such usage examples different.

> **Make sure that you [build the library](#build) before running the integration tests**. It's a good idea to keep the build running (`pnpm start`) while working on the tests. Keeping both compiler and test runner in watch mode boosts your productivity.

#### Browser integration tests

You can find all the browser integration tests under `./test/browser`. Those tests are run with Playwright and usually consist of two parts:

- `[test-name].mocks.ts`, the usage example of MSW;
- `[test-name].test.ts`, the test suite that loads the usage example, does actions and performs assertions.

It's also a great idea to get familiar with our Playwright configuration and extensions:

- [**Playwright configuration file**](./test/browser/playwright.config.ts)
- [Playwright extensions](./test/browser/playwright.extend.ts)

Let's write an example integration test that asserts the interception of a GET request. First, start with the `*.mocks.ts` file:

```js
// test/browser/example.mocks.ts
import { http, HttpResponse } from 'msw'
import { setupWorker } from 'msw/browser'

const worker = setupWorker(
  http.get('/books', () => {
    return HttpResponse.json([
      {
        id: 'ea42ffcb-e729-4dd5-bfac-7a5b645cb1da',
        title: 'The Lord of the Rings',
        publishedAt: -486867600,
      },
    ])
  }),
)

worker.start()
```

> Notice how there's nothing test-specific in the example? The `example.mocks.ts` file is a copy-paste example of intercepting the `GET /books` request. This allows to share these mocks with the users as a legitimate example, because it is!

Once the `*.mocks.ts` file is written, proceed by creating a test file:

```ts
// test/browser/example.test.ts
import * as path from 'path'
import { test, expect } from './playwright.extend'

test('returns a mocked response', async ({ loadExample, fetch }) => {
  // Compile the given usage example on runtime.
  await loadExample(new URL('./example.mocks.ts', import.meta.url))

  // Perform the "GET /books" request in the browser.
  const res = await fetch('/books')

  // Assert the returned response body.
  expect(await res.json()).toEqual([
    {
      id: 'ea42ffcb-e729-4dd5-bfac-7a5b645cb1da',
      title: 'The Lord of the Rings',
      publishedAt: -486867600,
    },
  ])
})
```

##### Running all browser tests

Make sure Playwright chromium has been installed before running browser tests.

```sh
pnpm test:browser
```

#### Running a single browser test

```sh
pnpm test:browser ./test/browser/example.test.ts
```

#### Node.js integration test

Integration tests showcase a usage example in Node.js and are often placed next to the in-browser tests. Node.js integration tests reside in the `./test/node` directory.

Similar to the browser tests, these are going to contain a usage example and the assertions over it. However, for Node.js tests there is no need to create a separate `*.mocks.ts` file. Instead, keep the usage example in the test file directly.

Let's replicate the same `GET /books` integration test in Node.js.

```ts
// test/node/example.test.ts
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'

const server = setupServer(
  http.get('/books', () => {
    return HttpResponse.json([
      {
        id: 'ea42ffcb-e729-4dd5-bfac-7a5b645cb1da',
        title: 'The Lord of the Rings',
        publishedAt: -486867600,
      },
    ])
  }),
)

beforeAll(() => server.listen())

afterAll(() => server.close())

test('returns a mocked response', async () => {
  const res = await fetch('/books')

  expect(await res.json()).toEqual([
    {
      id: 'ea42ffcb-e729-4dd5-bfac-7a5b645cb1da',
      title: 'The Lord of the Rings',
      publishedAt: -486867600,
    },
  ])
})
```

##### Running all Node.js tests

```sh
pnpm test:node
```

##### Running a single Node.js test

```sh
pnpm test:node ./test/node/example.test.ts
```

## Build

Build the library with the following command:

```bash
$ pnpm build
```

[pnpm-url]: https://pnpm.io/
[page-with-url]: https://github.com/kettanaito/page-with
[pnpm-install-guide-url]: https://pnpm.io/8.x/installation#installing-a-specific-version


================================================
FILE: LICENSE.md
================================================
MIT License

Copyright (c) 2018–present Artem Zakharchenko

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
<br />

<p align="center">
  <img src="media/msw-logo.svg" width="100" alt="The Mock Service Worker logo" />
</p>

<h1 align="center">Mock Service Worker</h1>
<p align="center">Industry standard API mocking for JavaScript.</p>

<p align="center">
   <a href="https://kettanaito.com/discord" target="_blank">Join our Discord server</a>
</p>

<br />
<br />

## Features

- **Seamless**. A dedicated layer of requests interception at your disposal. Keep your application's code and tests unaware of whether something is mocked or not.
- **Deviation-free**. Request the same production resources and test the actual behavior of your app. Augment an existing API, or design it as you go when there is none.
- **Familiar & Powerful**. Use [Express](https://github.com/expressjs/express)-like routing syntax to intercept requests. Use parameters, wildcards, and regular expressions to match requests, and respond with necessary status codes, headers, cookies, delays, or completely custom resolvers.

---

> "_I found MSW and was thrilled that not only could I still see the mocked responses in my DevTools, but that the mocks didn't have to be written in a Service Worker and could instead live alongside the rest of my app. This made it silly easy to adopt. The fact that I can use it for testing as well makes MSW a huge productivity booster._"
>
> — [Kent C. Dodds](https://twitter.com/kentcdodds)

## Documentation

This README will give you a brief overview of the library, but there's no better place to start with Mock Service Worker than its official documentation.

- [Documentation](https://mswjs.io/docs)
- [**Quick start**](https://mswjs.io/docs/quick-start)
- [FAQ](https://mswjs.io/docs/faq)

## Examples

- See the list of [**Usage examples**](https://github.com/mswjs/examples)

## Courses

We've partnered with Egghead to bring you quality paid materials to learn the best practices of API mocking on the web. Please give them a shot! The royalties earned from them help sustain the project's development. Thank you.

- 🚀 [**Mocking REST and GraphQL APIs with Mock Service Worker**](https://egghead.io/courses/mock-rest-and-graphql-apis-with-mock-service-worker-8d471ece?af=8mci9b)
- 🔌 [Mocking (and testing) WebSocket APIs with Mock Service Worker](https://egghead.io/courses/mocking-websocket-apis-with-mock-service-worker-9933b7f5)

## Browser

- [Learn more about using MSW in a browser](https://mswjs.io/docs/integrations/browser)
- [`setupWorker` API](https://mswjs.io/docs/api/setup-worker)

### How does it work?

In-browser usage is what sets Mock Service Worker apart from other tools. Utilizing the [Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API), which can intercept requests for the purpose of caching, Mock Service Worker responds to intercepted requests with your mock definition on the network level. This way your application knows nothing about the mocking.

**Take a look at this quick presentation on how Mock Service Worker functions in a browser:**

[![What is Mock Service Worker?](https://raw.githubusercontent.com/mswjs/msw/main/media/msw-video-thumbnail.jpg)](https://youtu.be/HcQCqboatZk)

### How is it different?

- This library intercepts requests on the network level, which means _after_ they have been performed and "left" your application. As a result, the entirety of your code runs, giving you more confidence when mocking;
- Imagine your application as a box. Every API mocking library out there opens your box and removes the part that does the request, placing a blackbox in its stead. Mock Service Worker leaves your box intact, 1-1 as it is in production. Instead, MSW lives in a separate box next to yours;
- No more stubbing of `fetch`, `axios`, `react-query`, you-name-it;
- You can reuse the same mock definition for the unit, integration, and E2E testing. Did we mention local development and debugging? Yep. All running against the same network description without the need for adapters or bloated configurations.

### Usage example

```js
// 1. Import the library.
import { http, HttpResponse } from 'msw'
import { setupWorker } from 'msw/browser'

// 2. Describe network behavior with request handlers.
const worker = setupWorker(
  http.get('https://github.com/octocat', ({ request, params, cookies }) => {
    return HttpResponse.json(
      {
        message: 'Mocked response',
      },
      {
        status: 202,
        statusText: 'Mocked status',
      },
    )
  }),
)

// 3. Start mocking by starting the Service Worker.
await worker.start()
```

Performing a `GET https://github.com/octocat` request in your application will result into a mocked response that you can inspect in your browser's "Network" tab:

![Chrome DevTools Network screenshot with the request mocked](https://github.com/mswjs/msw/blob/main/media/msw-quick-look-network.png?raw=true)

> **Tip:** Did you know that although Service Worker runs in a separate thread, your request handlers execute entirely on the client? This way you can use the same languages, like TypeScript, third-party libraries, and internal logic to create the mocks you need.

## Node.js

- [Learn more about using MSW in Node.js](https://mswjs.io/docs/integrations/node)
- [`setupServer` API](https://mswjs.io/docs/api/setup-server)

### How does it work?

There's no such thing as Service Workers in Node.js. Instead, MSW implements a [low-level interception algorithm](https://github.com/mswjs/interceptors) that can utilize the very same request handlers you have for the browser. This blends the boundary between environments, allowing you to focus on your network behaviors.

### How is it different?

- Does not stub `fetch`, `axios`, etc. As a result, your tests know _nothing_ about mocking;
- You can reuse the same request handlers for local development and debugging, as well as for testing. Truly a single source of truth for your network behavior across all environments and all tools.

### Usage example

Here's an example of using Mock Service Worker while developing your Express server:

```js
import express from 'express'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'

const app = express()
const server = setupServer()

app.get(
  '/checkout/session',
  server.boundary((req, res) => {
    // Describe the network for this Express route.
    server.use(
      http.get(
        'https://api.stripe.com/v1/checkout/sessions/:id',
        ({ params }) => {
          return HttpResponse.json({
            id: params.id,
            mode: 'payment',
            status: 'open',
          })
        },
      ),
    )

    // Continue with processing the checkout session.
    handleSession(req, res)
  }),
)
```

> This example showcases [`server.boundary()`](https://mswjs.io/docs/api/setup-server/boundary) to scope request interception to a particular closure, which is extremely handy!

## Sponsors

Mock Service Worker is trusted by hundreds of thousands of engineers around the globe. It's used by companies like Google, Microsoft, Spotify, Amazon, Netflix, and countless others. Despite that, it remains a hobby project maintained in a spare time and has no opportunity to financially support even a single full-time contributor.

**You can change that!** Consider [sponsoring the effort](https://github.com/sponsors/mswjs) behind one of the most innovative approaches around API mocking. Raise a topic of open source sponsorships with your boss and colleagues. Let's build sustainable open source together!

### Golden sponsors

> Become our _golden sponsor_ and get featured right here, enjoying other perks like issue prioritization and a personal consulting session with us.
>
> **Learn more on our [GitHub Sponsors profile](https://github.com/sponsors/mswjs)**.

<br />

<table>
  <tr>
    <td>
      <a href="https://www.github.com/" target="_blank">
        <picture>
          <source media="(prefers-color-scheme: dark)" srcset="media/sponsors/github-light.svg" />
          <img src="media/sponsors/github.svg" alt="GitHub" height="64" />
        </picture>
      </a>
    </td>
    <td>
      <a href="https://www.codacy.com/" target="_blank">
        <img src="media/sponsors/codacy.svg" alt="Codacy" height="64" />
      </a>
    </td>
    <td>
      <a href="https://workleap.com/" target="_blank">
        <img src="media/sponsors/workleap.svg" alt="Workleap" height="64" width="174" />
      </a>
    </td>
    <td>
      <a href="https://www.chromatic.com/?ref=mswjs" target="_blank">
        <img src="media/sponsors/chromatic.svg" alt="Chromatic" height="64" />
      </a>
    </td>
  </tr>
  <tr>
    <td align="center">
      <a href="https://stackblitz.com/" target="_blank">
        <img src="media/sponsors/stackblitz.svg" alt="StackBlitz" height="64" />
      </a>
    </td>
  </tr>
</table>

### Silver sponsors

> Become our _silver sponsor_ and get your profile image and link featured right here.
>
> **Learn more on our [GitHub Sponsors profile](https://github.com/sponsors/mswjs)**.

<br />

<table>
  <tr>
    <td>
      <a href="https://www.replay.io/" target="_blank">
        <img src="media/sponsors/replay.svg" alt="Replay" height="64" />
      </a>
    </td>
    <td>
      <a href="https://codemod.com/" target="_blank">
        <img src="media/sponsors/codemod.svg" alt="Codemod" height="64" width="128" />
      </a>
    </td>
    <td>
      <a href="https://github.com/ryanmagoon" target="_blank">
        <img src="https://github.com/ryanmagoon.png" alt="Ryan Magoon" height="64" />
      </a>
    </td>
  </tr>
</table>

### Bronze sponsors

> Become our _bronze sponsor_ and get your profile image and link featured in this section.
>
> **Learn more on our [GitHub Sponsors profile](https://github.com/sponsors/mswjs)**.

<br />

<table>
  <tr>
    <td>
      <a href="https://materialize.com/" target="_blank">
        <img src="media/sponsors/materialize.svg" alt="Materialize" height="64" />
      </a>
    </td>
    <td>
      <a href="https://trigger.dev/" target="_blank">
        <img src="media/sponsors/trigger-dev.png" alt="Trigger.dev" height="64" />
      </a>
    </td>
    <td>
      <a href="https://vital.io/" target="_blank">
        <img src="media/sponsors/vital.svg" alt="Vital" width="64" />
      </a>
    </td>
  </tr>
</table>

## Awards & mentions

We've been extremely humbled to receive awards and mentions from the community for all the innovation and reach Mock Service Worker brings to the JavaScript ecosystem.

<table>
  <tr valign="middle">
    <td width="124">
      <img src="https://raw.githubusercontent.com/mswjs/msw/main/media/tech-radar.png" width="124" alt="Technology Radar">
    </td>
    <td>
      <h4>Solution Worth Pursuing</h4>
      <p><em><a href="https://www.thoughtworks.com/radar/languages-and-frameworks/mock-service-worker">Technology Radar</a> (2020–2021)</em></p>
    </td>
  </tr>
  <tr>
    <td width="124">
      <img src="https://raw.githubusercontent.com/mswjs/msw/main/media/os-awards.png" width="124" alt="Open Source Awards 2020">
    </td>
    <td>
      <h4>The Most Exciting Use of Technology</h4>
      <p><em><a href="https://osawards.com/javascript/2020">Open Source Awards</a> (2020)</em></p>
    </td>
  </tr>
</table>


================================================
FILE: browser/package.json
================================================
{
  "type": "module",
  "main": "../lib/browser/index.js",
  "module": "../lib/browser/index.mjs",
  "types": "../lib/browser/index.d.ts",
  "exports": {
    ".": {
      "module-sync": {
        "types": "./../lib/browser/index.d.mts",
        "default": "./../lib/browser/index.mjs"
      },
      "module": {
        "types": "./../lib/browser/index.d.mts",
        "default": "./../lib/browser/index.mjs"
      },
      "browser": {
        "types": "./../lib/browser/index.d.mts",
        "default": "./../lib/browser/index.mjs"
      },
      "import": {
        "types": "./../lib/browser/index.d.mts",
        "default": "./../lib/browser/index.mjs"
      },
      "default": {
        "types": "./../lib/browser/index.d.ts",
        "default": "./../lib/browser/index.js"
      }
    },
    "./package.json": "./package.json"
  }
}


================================================
FILE: cli/index.js
================================================
#!/usr/bin/env node
import yargs from 'yargs'
import { init } from './init.js'

// eslint-disable-next-line @typescript-eslint/no-unused-expressions
yargs(process.argv.slice(2))
  .usage('$0 <cmd> [args]')
  .command(
    'init',
    'Initializes Mock Service Worker at the specified directory',
    (yargs) => {
      yargs
        .positional('publicDir', {
          type: 'string',
          description: 'Relative path to the public directory',
          demandOption: false,
          normalize: true,
        })
        .option('save', {
          type: 'boolean',
          description: 'Save the worker directory in your package.json',
        })
        .option('cwd', {
          type: 'string',
          description: 'Custom current worker directory',
          normalize: true,
        })
        .example('msw init')
        .example('msw init ./public')
        .example('msw init ./static --save')
    },
    init,
  )
  .demandCommand()
  .help().argv


================================================
FILE: cli/init.js
================================================
import fs from 'node:fs'
import path from 'node:path'
import colors from 'picocolors'
import confirm from '@inquirer/confirm'
import { invariant } from './invariant.js'
import { SERVICE_WORKER_BUILD_PATH } from '../config/constants.js'

export async function init(args) {
  const CWD = args.cwd || process.cwd()
  const publicDir = args._[1] ? normalizePath(args._[1]) : undefined

  const packageJsonPath = path.resolve(CWD, 'package.json')
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
  const savedWorkerDirectories = Array.prototype
    .concat((packageJson.msw && packageJson.msw.workerDirectory) || [])
    .map(normalizePath)

  if (publicDir) {
    // If the public directory was provided, copy the worker script
    // to that directory only. Even if there are paths stored in "msw.workerDirectory",
    // those will not be touched.
    await copyWorkerScript(publicDir, CWD)
    const relativePublicDir = path.relative(CWD, publicDir)
    printSuccessMessage([publicDir])

    if (args.save) {
      // Only save the public path if it's not already saved in "package.json".
      if (!savedWorkerDirectories.includes(relativePublicDir)) {
        saveWorkerDirectory(packageJsonPath, relativePublicDir)
      }
    }
    // Explicitly check if "save" was not provided (was null).
    // You can also provide the "--no-save" option, and then "args.save"
    // will equal to false.
    else if (args.save == null) {
      // eslint-disable-next-line no-console
      console.log(`\
      ${colors.cyan(
        'INFO',
      )} In order to ease the future updates to the worker script,
      we recommend saving the path to the worker directory in your package.json.`)

      // If the "--save" flag was not provided, prompt to save
      // the public path.
      promptWorkerDirectoryUpdate(
        `Do you wish to save "${relativePublicDir}" as the worker directory?`,
        packageJsonPath,
        relativePublicDir,
      )
    }

    return
  }

  // Calling "init" without a public directory but with the "--save" flag is a no-op.
  invariant(
    args.save == null,
    'Failed to copy the worker script: cannot call the "init" command without a public directory but with the "--save" flag. Either drop the "--save" flag to copy the worker script to all paths listed in "msw.workerDirectory", or add an explicit public directory to the command, like "npx msw init ./public".',
  )

  // If the public directory was not provided, check any existing
  // paths in "msw.workerDirectory". When called without the public
  // directory, the "init" command must copy the worker script
  // to all the paths stored in "msw.workerDirectory".
  if (savedWorkerDirectories.length > 0) {
    const copyResults = await Promise.allSettled(
      savedWorkerDirectories.map((destination) => {
        return copyWorkerScript(destination, CWD).catch((error) => {
          // Inject the absolute destination path onto the copy function rejections
          // so it's available in the failed paths array below.
          throw [toAbsolutePath(destination, CWD), error]
        })
      }),
    )
    const successfulPaths = copyResults
      .filter((result) => result.status === 'fulfilled')
      .map((result) => result.value)
    const failedPathsWithErrors = copyResults
      .filter((result) => result.status === 'rejected')
      .map((result) => result.reason)

    // Notify about failed copies, if any.
    if (failedPathsWithErrors.length > 0) {
      printFailureMessage(failedPathsWithErrors)
    }

    // Notify about successful copies, if any.
    if (successfulPaths.length > 0) {
      printSuccessMessage(successfulPaths)
    }
  }
}

/**
 * @param {string} maybeAbsolutePath
 * @param {string} cwd
 * @returns {string}
 */
function toAbsolutePath(maybeAbsolutePath, cwd) {
  return path.isAbsolute(maybeAbsolutePath)
    ? maybeAbsolutePath
    : path.resolve(cwd, maybeAbsolutePath)
}

/**
 * @param {string} destination
 * @param {string} cwd
 * @returns {Promise<string>}
 */
async function copyWorkerScript(destination, cwd) {
  // When running as a part of "postinstall" script, "cwd" equals the library's directory.
  // The "postinstall" script resolves the right absolute public directory path.
  const absolutePublicDir = toAbsolutePath(destination, cwd)

  if (!fs.existsSync(absolutePublicDir)) {
    await fs.promises
      .mkdir(absolutePublicDir, { recursive: true })
      .catch((error) => {
        throw new Error(
          invariant(
            false,
            'Failed to copy the worker script at "%s": directory does not exist and could not be created.\nMake sure to include a relative path to the public directory of your application.\n\nSee the original error below:\n\n%s',
            absolutePublicDir,
            error,
          ),
        )
      })
  }

  // eslint-disable-next-line no-console
  console.log('Copying the worker script at "%s"...', absolutePublicDir)

  const workerFilename = path.basename(SERVICE_WORKER_BUILD_PATH)
  const workerDestinationPath = path.resolve(absolutePublicDir, workerFilename)

  fs.copyFileSync(SERVICE_WORKER_BUILD_PATH, workerDestinationPath)

  return workerDestinationPath
}

/**
 * @param {Array<string>} paths
 */
function printSuccessMessage(paths) {
  // eslint-disable-next-line no-console
  console.log(`
${colors.green('Worker script successfully copied!')}
${paths.map((path) => colors.gray(`  - ${path}\n`))}
Continue by describing the network in your application:


${colors.red(colors.bold('https://mswjs.io/docs/quick-start'))}
`)
}

function printFailureMessage(pathsWithErrors) {
  // eslint-disable-next-line no-console
  console.error(`\
${colors.red('Copying the worker script failed at following paths:')}
${pathsWithErrors
  .map(([path, error]) => colors.gray(`  - ${path}`) + '\n' + `  ${error}`)
  .join('\n\n')}
  `)
}

/**
 * @param {string} packageJsonPath
 * @param {string} publicDir
 */
function saveWorkerDirectory(packageJsonPath, publicDir) {
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))

  // eslint-disable-next-line no-console
  console.log(
    colors.gray('Updating "msw.workerDirectory" at "%s"...'),
    packageJsonPath,
  )

  const prevWorkerDirectory = Array.prototype.concat(
    (packageJson.msw && packageJson.msw.workerDirectory) || [],
  )
  const nextWorkerDirectory = Array.from(
    new Set(prevWorkerDirectory).add(publicDir),
  )

  const nextPackageJson = Object.assign({}, packageJson, {
    msw: {
      workerDirectory: nextWorkerDirectory,
    },
  })

  fs.writeFileSync(
    packageJsonPath,
    JSON.stringify(nextPackageJson, null, 2),
    'utf8',
  )
}

/**
 * @param {string} message
 * @param {string} packageJsonPath
 * @param {string} publicDir
 * @returns {void}
 */
function promptWorkerDirectoryUpdate(message, packageJsonPath, publicDir) {
  return confirm({
    theme: {
      prefix: colors.yellowBright('?'),
    },
    message,
  }).then((answer) => {
    if (answer) {
      saveWorkerDirectory(packageJsonPath, publicDir)
    }
  })
}

/**
 * Normalizes the given path, replacing ambiguous path separators
 * with the platform-specific path separator.
 * @param {string} input Path to normalize.
 * @returns {string}
 */
function normalizePath(input) {
  return input.replace(/[\\|\/]+/g, path.sep)
}


================================================
FILE: cli/invariant.js
================================================
import colors from 'picocolors'

export function invariant(predicate, message, ...args) {
  if (!predicate) {
    // eslint-disable-next-line no-console
    console.error(colors.red(message), ...args)
    process.exit(1)
  }
}


================================================
FILE: cli/package.json
================================================
{
  "type": "module"
}


================================================
FILE: commitlint.config.js
================================================
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'body-max-line-length': [0, 'always', Infinity],
    'footer-max-line-length': [1, 'always'],
  },
}


================================================
FILE: config/constants.js
================================================
import url from 'node:url'
import path from 'node:path'

export const SERVICE_WORKER_SOURCE_PATH = url.fileURLToPath(
  new URL('../src/mockServiceWorker.js', import.meta.url),
)

export const SERVICE_WORKER_BUILD_PATH = url.fileURLToPath(
  new URL(
    path.join('../lib', path.basename(SERVICE_WORKER_SOURCE_PATH)),
    import.meta.url,
  ),
)


================================================
FILE: config/copyServiceWorker.ts
================================================
import fs from 'node:fs'
import path from 'node:path'
import { until } from 'until-async'

/**
 * Copies the given Service Worker source file into the destination.
 * Injects the integrity checksum into the destination file.
 */
export default async function copyServiceWorker(
  sourceFilePath: string,
  destFilePath: string,
  checksum: string,
): Promise<void> {
  // eslint-disable-next-line no-console
  console.log('Compiling Service Worker...')

  const [readFileError, readFileResult] = await until(() =>
    fs.promises.readFile(sourceFilePath, 'utf8'),
  )

  if (readFileError) {
    throw new Error('Failed to read file.\n${readError.message}')
  }

  const destFileDirectory = path.dirname(destFilePath)
  // eslint-disable-next-line no-console
  console.log('Checking if "%s" path exists...', destFileDirectory)

  if (!fs.existsSync(destFileDirectory)) {
    // eslint-disable-next-line no-console
    console.log('Destination directory does not exist, creating...')
    await fs.promises.mkdir(destFileDirectory, { recursive: true })
  }

  const packageJson = JSON.parse(
    fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8'),
  )

  const nextFileContent = readFileResult
    .replace('<INTEGRITY_CHECKSUM>', checksum)
    .replace('<PACKAGE_VERSION>', packageJson.version)

  const [writeFileError] = await until(() =>
    fs.promises.writeFile(destFilePath, nextFileContent),
  )

  if (writeFileError) {
    throw new Error(`Failed to write file.\n${writeFileError.message}`)
  }

  // eslint-disable-next-line no-console
  console.log('Service Worker copied to: %s', destFilePath)
}


================================================
FILE: config/package.json
================================================
{
  "type": "module"
}


================================================
FILE: config/plugins/esbuild/copyWorkerPlugin.ts
================================================
import fs from 'node:fs'
import path from 'node:path'
import crypto from 'crypto'
import minify from 'babel-minify'
import { invariant } from 'outvariant'
import type { Plugin } from 'esbuild'
import copyServiceWorker from '../../copyServiceWorker.js'

const SERVICE_WORKER_ENTRY_PATH = path.resolve(
  process.cwd(),
  './src/mockServiceWorker.js',
)

const SERVICE_WORKER_OUTPUT_PATH = path.resolve(
  process.cwd(),
  './lib/mockServiceWorker.js',
)

function getChecksum(contents: string): string {
  const { code } = minify(contents, {}, { comments: false })

  return crypto.createHash('md5').update(code, 'utf8').digest('hex')
}

export function getWorkerChecksum(): string {
  const workerContents = fs.readFileSync(SERVICE_WORKER_ENTRY_PATH, 'utf8')
  return getChecksum(workerContents)
}

export function copyWorkerPlugin(checksum: string): Plugin {
  return {
    name: 'copyWorkerPlugin',
    async setup(build) {
      invariant(
        SERVICE_WORKER_ENTRY_PATH,
        'Failed to locate the worker script source file',
      )

      if (fs.existsSync(SERVICE_WORKER_OUTPUT_PATH)) {
        console.warn(
          'Skipped copying the worker script to "%s": already exists',
          SERVICE_WORKER_OUTPUT_PATH,
        )
        return
      }

      // Generate the checksum from the worker script's contents.
      // const workerContents = await fs.readFile(workerSourcePath, 'utf8')
      // const checksum = getChecksum(workerContents)

      build.onLoad({ filter: /mockServiceWorker\.js$/ }, async () => {
        return {
          // Prevent the worker script from being transpiled.
          // But, generally, the worker script is not in the entrypoints.
          contents: '',
        }
      })

      build.onEnd(() => {
        // eslint-disable-next-line no-console
        console.log('worker script checksum:', checksum)

        // Copy the worker script on the next tick.
        process.nextTick(async () => {
          await copyServiceWorker(
            SERVICE_WORKER_ENTRY_PATH,
            SERVICE_WORKER_OUTPUT_PATH,
            checksum,
          )
        })
      })
    },
  }
}


================================================
FILE: config/plugins/esbuild/forceEsmExtensionsPlugin.ts
================================================
import { type Plugin } from 'esbuild'

export const ESM_EXTENSION = '.mjs'
export const CJS_EXTENSION = '.js'

export function forceEsmExtensionsPlugin(): Plugin {
  return {
    name: 'forceEsmExtensionsPlugin',
    setup(build) {
      const isEsm = build.initialOptions.format === 'esm'

      build.onEnd(async (result) => {
        if (result.errors.length > 0) {
          return
        }

        for (const outputFile of result.outputFiles || []) {
          // Only target CJS/ESM files.
          // This ignores additional files emitted, like sourcemaps ("*.js.map").
          if (
            !(
              outputFile.path.endsWith(ESM_EXTENSION) ||
              outputFile.path.endsWith('.mjs')
            )
          ) {
            continue
          }

          const fileContents = outputFile.text
          const nextFileContents = modifyRelativeImports(fileContents, isEsm)

          outputFile.contents = Buffer.from(nextFileContents)
        }
      })
    },
  }
}

const CJS_RELATIVE_IMPORT_EXP = /require\(["'](\..+)["']\)(;)?/gm
const ESM_RELATIVE_IMPORT_EXP = /from ["'](\..+)["'](;)?/gm

function modifyRelativeImports(contents: string, isEsm: boolean): string {
  const extension = isEsm ? ESM_EXTENSION : CJS_EXTENSION
  const importExpression = isEsm
    ? ESM_RELATIVE_IMPORT_EXP
    : CJS_RELATIVE_IMPORT_EXP

  return contents.replace(
    importExpression,
    (_, importPath, maybeSemicolon = '') => {
      if (importPath.endsWith('.') || importPath.endsWith('/')) {
        return isEsm
          ? `from '${importPath}/index${extension}'${maybeSemicolon}`
          : `require("${importPath}/index${extension}")${maybeSemicolon}`
      }

      if (importPath.endsWith(extension)) {
        return isEsm
          ? `from '${importPath}'${maybeSemicolon}`
          : `require("${importPath}")${maybeSemicolon}`
      }

      return isEsm
        ? `from '${importPath}${extension}'${maybeSemicolon}`
        : `require("${importPath}${extension}")${maybeSemicolon}`
    },
  )
}


================================================
FILE: config/plugins/esbuild/graphQLImportPlugin.ts
================================================
import fs from 'node:fs'
import type { Plugin } from 'esbuild'

/**
 * A plugin to replace `require('graphql')` statements with `await import('graphql')`
 * only for ESM bundles. This makes the GraphQL module to be imported lazily
 * while maintaining the CommonJS compatibility.
 * @see https://github.com/mswjs/msw/issues/2254
 */
export function graphqlImportPlugin(): Plugin {
  return {
    name: 'graphql-import-plugin',
    setup(build) {
      if (build.initialOptions.format !== 'esm') {
        return
      }

      build.onLoad({ filter: /\.ts$/ }, async (args) => {
        const contents = await fs.promises.readFile(args.path, 'utf-8')
        const match = /require\(['"]graphql['"]\)/g.exec(contents)

        if (match) {
          return {
            loader: 'ts',
            contents:
              contents.slice(0, match.index - 1) +
              `await import('graphql').catch((error) => {console.error('[MSW] Failed to parse a GraphQL query: cannot import the "graphql" module. Please make sure you install it if you wish to intercept GraphQL requests. See the original import error below.'); throw error})` +
              contents.slice(match.index + match[0].length),
          }
        }
      })
    },
  }
}


================================================
FILE: config/plugins/esbuild/resolveCoreImportsPlugin.ts
================================================
import { Plugin } from 'esbuild'
import { replaceCoreImports } from '../../replaceCoreImports.js'
import { ESM_EXTENSION } from './forceEsmExtensionsPlugin.js'

export function resolveCoreImportsPlugin(): Plugin {
  return {
    name: 'resolveCoreImportsPlugin',
    setup(build) {
      build.onEnd(async (result) => {
        if (result.errors.length > 0) {
          return
        }

        for (const outputFile of result.outputFiles || []) {
          const isEsm = outputFile.path.endsWith(ESM_EXTENSION)
          const fileContents = outputFile.text
          const nextFileContents = replaceCoreImports(
            outputFile.path,
            fileContents,
            isEsm,
          )

          outputFile.contents = Buffer.from(nextFileContents)
        }
      })
    },
  }
}


================================================
FILE: config/polyfills-node.ts
================================================
import { setTimeout as nodeSetTimeout } from 'timers'

// Polyfill the global "setTimeout" so MSW could be used
// with "jest.useFakeTimers()". MSW response handling
// is wrapped in "setTimeout", and without this polyfill
// you'd have to manually advance the timers for the response
// to finally resolve.
export const setTimeout = nodeSetTimeout


================================================
FILE: config/replaceCoreImports.js
================================================
const CORE_ESM_IMPORT_PATTERN = /from ["'](~\/core(.*))["'](;)?/gm
const CORE_CJS_IMPORT_PATTERN = /require\(["'](~\/core(.*))["']\)(;)?/gm

function getCoreImportPattern(isEsm) {
  return isEsm ? CORE_ESM_IMPORT_PATTERN : CORE_CJS_IMPORT_PATTERN
}

export function hasCoreImports(fileContents, isEsm) {
  return getCoreImportPattern(isEsm).test(fileContents)
}

export function replaceCoreImports(moduleFilePath, fileContents, isEsm) {
  return fileContents.replace(
    getCoreImportPattern(isEsm),
    (_, __, maybeSubmodulePath, maybeSemicolon) => {
      const submodulePath = maybeSubmodulePath || '/index'
      /**
       * @note Although all .d.ts are considered ESM, append different
       * file extension for d.mts files.
       */
      const extension = moduleFilePath.endsWith('.d.mts') ? '.mjs' : ''
      const semicolon = maybeSemicolon || ''

      return isEsm
        ? `from "../core${submodulePath}${extension}"${semicolon}`
        : `require("../core${submodulePath}")${semicolon}`
    },
  )
}


================================================
FILE: config/scripts/patch-ts.js
================================================
import fs from 'node:fs'
import { exec } from 'node:child_process'
import { promisify } from 'node:util'
import { invariant } from 'outvariant'
import * as glob from 'glob'
import { hasCoreImports, replaceCoreImports } from '../replaceCoreImports.js'

const execAsync = promisify(exec)

const BUILD_DIR = new URL('../../lib/', import.meta.url)

async function patchTypeDefs() {
  const typeDefsPaths = glob.sync('**/*.d.{ts,mts}', {
    cwd: BUILD_DIR,
    absolute: true,
  })
  const typeDefsWithCoreImports = typeDefsPaths
    .map((modulePath) => {
      const fileContents = fs.readFileSync(modulePath, 'utf8')
      /**
       * @note Treat all type definition files as ESM because even
       * CJS .d.ts use `import` statements.
       */
      if (hasCoreImports(fileContents, true)) {
        return [modulePath, fileContents]
      }
    })
    .filter(Boolean)

  if (typeDefsWithCoreImports.length === 0) {
    console.log(
      'Found no .d.ts modules containing the "~/core" import, skipping...',
    )
    return process.exit(0)
  }

  console.log(
    'Found %d module(s) with the "~/core" import, resolving...',
    typeDefsWithCoreImports.length,
  )

  for (const [typeDefsPath, fileContents] of typeDefsWithCoreImports) {
    // Treat ".d.ts" files as ESM to replace "import" statements.
    // Force no extension on the ".d.ts" imports.
    const nextFileContents = replaceCoreImports(
      typeDefsPath,
      fileContents,
      true,
    )
    fs.writeFileSync(typeDefsPath, nextFileContents, 'utf8')
    console.log('Successfully patched "%s"!', typeDefsPath)
  }

  console.log(
    'Imports resolved in %d file(s), verifying...',
    typeDefsWithCoreImports.length,
  )

  // Next, validate that we left no "~/core" imports unresolved.
  const result = await execAsync(
    `grep "~/core" ./**/*.d.{ts,mts} -R -l || exit 0`,
    {
      cwd: BUILD_DIR,
      shell: '/bin/bash',
    },
  )

  invariant(
    result.stderr === '',
    'Failed to validate the .d.ts modules for the presence of the "~/core" import. See the original error below.',
    result.stderr,
  )

  if (result.stdout !== '') {
    const modulesWithUnresolvedImports = result.stdout
      .split('\n')
      .filter(Boolean)

    console.error(
      `Found .d.ts modules containing unresolved "~/core" import after the patching:

${modulesWithUnresolvedImports.map((path) => `  - ${new URL(path, BUILD_DIR).pathname}`).join('\n')}
        `,
    )

    return process.exit(1)
  }

  // Ensure that the .d.ts files compile without errors after resolving the "~/core" imports.
  console.log('Compiling the .d.ts modules with tsc...')
  const tscCompilation = await execAsync(
    `tsc --noEmit --skipLibCheck ${typeDefsPaths.join(' ')}`,
    {
      cwd: BUILD_DIR,
    },
  )

  if (tscCompilation.stderr !== '') {
    console.error(
      'Failed to compile the .d.ts modules with tsc. See the original error below.',
      tscCompilation.stderr,
    )

    return process.exit(1)
  }

  // Ensure that CJS .d.ts file never reference .mjs files.
  const mjsInCjsResult = await execAsync(
    `grep ".mjs" ./**/*.d.ts -R -l || exit 0`,
    {
      cwd: BUILD_DIR,
      shell: '/bin/bash',
    },
  )

  invariant(
    mjsInCjsResult.stderr === '',
    'Failed to validate the .d.ts modules not referencing ".mjs" files. See the original error below.',
    mjsInCjsResult.stderr,
  )

  if (mjsInCjsResult.stdout !== '') {
    const modulesWithUnresolvedImports = mjsInCjsResult.stdout
      .split('\n')
      .filter(Boolean)

    console.error(
      `Found .d.ts modules referencing ".mjs" files after patching:

${modulesWithUnresolvedImports.map((path) => `  - ${new URL(path, BUILD_DIR).pathname}`).join('\n')}
        `,
    )

    return process.exit(1)
  }

  console.log(
    'The "~/core" imports resolved successfully in %d .d.ts modules! 🎉',
    typeDefsWithCoreImports.length,
  )
}

patchTypeDefs()


================================================
FILE: config/scripts/postinstall.js
================================================
import fs from 'node:fs'
import path from 'node:path'
import { execFileSync } from 'node:child_process'

// When executing the "postinstall" script, the "process.cwd" equals
// the package directory, not the parent project where the package is installed.
// NPM stores the parent project directory in the "INIT_CWD" env variable.
const parentPackageCwd = process.env.INIT_CWD

function postInstall() {
  const packageJson = JSON.parse(
    fs.readFileSync(path.resolve(parentPackageCwd, 'package.json'), 'utf8'),
  )

  if (!packageJson.msw || !packageJson.msw.workerDirectory) {
    return
  }

  const cliExecutable = path.resolve(process.cwd(), 'cli/index.js')

  try {
    /**
     * @note Call the "init" command directly. It will now copy the worker script
     * to all saved paths in "msw.workerDirectory"
     */
    execFileSync(process.execPath, [cliExecutable, 'init'], {
      cwd: parentPackageCwd,
    })
  } catch (error) {
    console.error(
      `[MSW] Failed to automatically update the worker script.\n\n${error}`,
    )
  }
}

postInstall()


================================================
FILE: config/scripts/smoke-test.sh
================================================
#!/bin/bash
set -e

COMMIT_HASH=$(git rev-parse HEAD)
MSW_VERSION="0.0.0-$COMMIT_HASH"
echo "Latest commit: $COMMIT_HASH"
echo "In-progress MSW version: $MSW_VERSION"

PKG_JSON_COPY="package.json.copy"
cp package.json $PKG_JSON_COPY

pnpm version $MSW_VERSION --no-git-tag-version --allow-same-version

echo ""
echo "Packing MSW..."
pnpm pack

EXAMPLES_REPO=https://github.com/mswjs/examples.git
EXAMPLES_DIR=./examples
echo ""
echo "Cloning the examples from "$EXAMPLES_REPO"..."

if [[ -d "$EXAMPLES_DIR" ]]; then
  echo "Examples already cloned, skipping..."
else
  git clone $EXAMPLES_REPO $EXAMPLES_DIR
fi

echo ""
echo "Installing dependencies..."
cd $EXAMPLES_DIR
pnpm install 

echo ""
echo "Linking MSW..."
pnpm add msw --filter="with-*" file:../../../msw-$MSW_VERSION.tgz
pnpm ls msw

echo ""
echo "Running tests..."
CI=1 pnpm test ; (cd ../ && mv $PKG_JSON_COPY ./package.json)


================================================
FILE: decisions/jest-support.md
================================================
# Jest support

With the introduction of [Mock Service Worker 2.0](https://mswjs.io/blog/introducing-msw-2.0), the library has made a significant step forward in the effort of embracing and promoting web standards. Since that release, its contributors have reported multiple issues with Node.js simply because MSW exposed developers to using standard Node.js APIs.

Betting on the web standards is one of the goals behind this project. One of such standards is ESM. It's the present and the future of JavaScript, and we are planning on switching to ESM-only in the years to come. For that transition to happen, we need to prioritize and, at times, make hard decisions.

**MSW offers no official support for Jest.** It doesn't mean MSW cannot be used in Jest. We maintain usage examples of both [Jest](https://github.com/mswjs/examples/tree/main/examples/with-jest) and [Jest+JSDOM](https://github.com/mswjs/examples/tree/main/examples/with-jest-jsdom) to attest to that. Although it's necessary to mention that those examples require additional setup to tackle underlying Jest or JSDOM issues.

What this means is that **we are not going to address any issues specific to Jest or JSDOM**. Those pose a significant time investment just to uncover another inconsistency between the browser and JSDOM, or the lacking features in Jest, like proper ESM support. That is not a reasonable use of the limited contributors' time. You will have a far better chance of getting your issue solved by reporting it to the Jest or JSDOM repo for the respective teams to address it.

## What's next?

> [!IMPORTANT]
> If you are experiencing issues with using MSW in Jest, **please verify them outside of Jest before reporting them**.

You can verify the issue in a plain Node.js script, or by copying your problematic test to [Vitest](https://vitest.dev/). Please note that we do not support issue reports from non-standard environments, like Deno or Bun either.

You can use one of our existing [Usage examples](https://github.com/mswjs/examples) as a template project to reproduce your issue.


================================================
FILE: decisions/linting-worker-script.md
================================================
# Linting the worker script

When linting your application, you may encounter warnings or errors originating from the `mockServiceWorker.js` script. Please refrain from opening pull requests to add the `ignore` pragma comments to the script itself.

## Solution

**Make sure that the worker script is ignored by your linting tools**. The worker script isn't a part of your application's code but a static asset. It must be ignored during linting and prettifying in the same way all your static assets in `/public` are ignored. Please configure your tools respectively.

If there are warnings/errors originating from the worker script, it's likely your public directory is not ignored by your linting tools. You may consider ignoring the entire public directory if that suits your project's conventions.


================================================
FILE: decisions/releases.md
================================================
# Releases

MSW uses the [Release](https://github.com/ossjs/release) library to automate its releases to NPM.

## Release schedule

The next version of **the library releases automatically every day**.

We do our best to choose the optimal release window to accumulate multiple changes under a single release. We do deviate from the release schedule in emergency cases, like when a critical issue has been fixed and needs an immediate release.

> [!IMPORTANT]
> Please do not ping the library maintainers to release a new version of MSW. Be patient and wait for the automated release to happen. Subscribe to any issue or pull request you are interested in, and you will be notified whenever it gets released.

## Preview releases

This repository is configured to **release work-in-progress pull requests** using [okg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new). Once the pull request in question is approved, it will automatically be published to a temporary registry. Follow the instructions in the automated comment to install the work-in-progress version of the package.


================================================
FILE: decisions/typescript-versioning.md
================================================
# TypeScript versioning

## Strict TypeScript peer dependency version

In the past, MSW set the explicit upper version range for the `typescript` peer dependency (`>= 4.4.x <= 5.1.x`). While that provides better stability and predictability, we acknowledge that it negatively impacts our users, forcing them to wait for MSW to update the TypeScript version range in order to migrate to newest versions of TypeScript in their projects.

> Context: TypeScript is [not distributed according to semver](https://github.com/microsoft/TypeScript/issues/14116). Instead, it's `{marketing}.{major}.{minor}` versioning pattern. This means that it may and does contain breaking changes across what consumers perceive as _minor_ versions. I've had numerous fights with this as it's not uncommon for TypeScript to exhibit different behavior across minor versions (the same types compile on 4.6, break on 4.7, then compile without issue on 4.8).

With this in mind, _we are removing the upper range_ of the `typescript` peer dependency. We have an [automated job](../.github/workflows/typescript-nightly.yml) in place that validates the latest build of MSW against the nightly releases of TypeScript, which should ensure early issue detection and help us resolve those issues before they happen.

## TypeScript version compliance

Every version within the `typescript` peer dependency version range must have a corresponding TypeScript compliance test to guarantee the library's operatbility on that version.

A compliance test is represented as a regular _typings test_ compiled using a specific version of TypeScript. You can learn more in the [typings tests](/test/typings).

The typings test will automatically attempt to look up `tsconfig.{major}.{minor}.json` file corresponding to the currently installed version of TypeScript. The compliance is then achieved by installing different TypeScript versions from the supported range and running the existing typings tests on that version.


================================================
FILE: eslint.config.mjs
================================================
// @ts-check

import eslint from '@eslint/js'
import tseslint from 'typescript-eslint'
import eslintConfigPrettier from 'eslint-config-prettier'
import eslintPluginPrettier from 'eslint-plugin-prettier/recommended'

export default tseslint.config(
  eslint.configs.recommended,
  eslintConfigPrettier,
  ...tseslint.configs.recommended,
  {
    languageOptions: {
      parserOptions: {
        ecmaVersion: 2020,
        sourceType: 'module',
      },
    },
    ignores: ['/lib', '/node', '/native', '/config', '/test'],
    rules: {
      'no-console': [
        'error',
        {
          allow: ['warn', 'error', 'group', 'groupCollapsed', 'groupEnd'],
        },
      ],
      'no-async-promise-executor': 'off',
      'require-yield': 'off',
      'no-empty-pattern': 'off',
      'no-control-regex': 'off',
      '@typescript-eslint/no-empty-object-type': 'off',
      '@typescript-eslint/prefer-ts-expect-error': 'error',
      '@typescript-eslint/no-explicit-any': 'off',
      '@typescript-eslint/explicit-module-boundary-types': 'off',
      '@typescript-eslint/ban-ts-comment': 'off',
      '@typescript-eslint/no-namespace': [
        'error',
        {
          allowDeclarations: true,
        },
      ],
      '@typescript-eslint/no-var-requires': 'off',
      '@typescript-eslint/no-unused-vars': [
        'error',
        {
          varsIgnorePattern: '^_',
          argsIgnorePattern: '^_',
        },
      ],
    },
  },
  // Unused variables are useful in test files, and type test files
  {
    files: [
      '**/*.test.ts',
      '**/*.test-d.ts',
      '**/*.mocks.ts',
      '**/*.setup.ts',
      '**/*.config.ts',
    ],
    rules: {
      'no-console': 'off',
      '@typescript-eslint/prefer-ts-expect-error': 'off',
      '@typescript-eslint/no-unused-vars': 'off',
    },
  },
  {
    files: ['**/*.test-d.ts'],
    rules: {
      '@typescript-eslint/no-unused-expressions': 'off',
    },
  },
  eslintPluginPrettier,
)


================================================
FILE: global.d.ts
================================================
declare module 'babel-minify' {
  export default function babelMinify(
    code: string,
    opts: Record<string, any>,
    babelOpts: Record<string, any>,
  ): { code: string }
}


================================================
FILE: knip.json
================================================
{
  "$schema": "https://unpkg.com/knip@5/schema.json",
  "entry": [
    "src/{core,browser,node,native}/index.ts!",
    "src/mockServiceWorker.js!",
    "cli/index.js!",
    "config/**/*.{js,ts}!",
    "test/**/*ts"
  ],
  "project": ["src/**/*.ts!", "cli/**/*.js!", "config/**/*.{js,ts}!"]
}


================================================
FILE: native/package.json
================================================
{
  "type": "commonjs",
  "browser": null,
  "main": "../lib/native/index.js",
  "module": "../lib/native/index.mjs",
  "types": "../lib/native/index.d.ts",
  "exports": {
    ".": {
      "react-native": {
        "import": {
          "types": "./../lib/native/index.d.mts",
          "default": "./../lib/native/index.mjs"
        },
        "default": {
          "types": "./../lib/native/index.d.ts",
          "default": "./../lib/native/index.js"
        }
      },
      "browser": null,
      "import": {
        "types": "./../lib/native/index.d.mts",
        "default": "./../lib/native/index.mjs"
      },
      "default": {
        "types": "./../lib/native/index.d.ts",
        "default": "./../lib/native/index.js"
      }
    }
  }
}


================================================
FILE: node/package.json
================================================
{
  "type": "commonjs",
  "browser": null,
  "main": "../lib/node/index.js",
  "module": "../lib/node/index.mjs",
  "types": "../lib/node/index.d.ts",
  "exports": {
    ".": {
      "module-sync": {
        "types": "./../lib/node/index.d.mts",
        "default": "./../lib/node/index.mjs"
      },
      "module": {
        "types": "./../lib/node/index.d.mts",
        "default": "./../lib/node/index.mjs"
      },
      "node": {
        "require": "./../lib/node/index.js",
        "import": "./../lib/node/index.mjs"
      },
      "import": {
        "types": "./../lib/node/index.d.mts",
        "default": "./../lib/node/index.mjs"
      },
      "browser": null,
      "react-native": null,
      "default": {
        "types": "./../lib/node/index.d.ts",
        "default": "./../lib/node/index.js"
      }
    }
  }
}


================================================
FILE: package.json
================================================
{
  "name": "msw",
  "version": "2.12.13",
  "description": "Seamless REST/GraphQL API mocking library for browser and Node.js.",
  "type": "commonjs",
  "main": "./lib/core/index.js",
  "module": "./lib/core/index.mjs",
  "types": "./lib/core/index.d.ts",
  "packageManager": "pnpm@9.15.0",
  "exports": {
    ".": {
      "module-sync": {
        "types": "./lib/core/index.d.mts",
        "default": "./lib/core/index.mjs"
      },
      "module": {
        "types": "./lib/core/index.d.mts",
        "default": "./lib/core/index.mjs"
      },
      "react-native": {
        "import": {
          "types": "./lib/core/index.d.mts",
          "default": "./lib/core/index.mjs"
        },
        "default": {
          "types": "./lib/core/index.d.ts",
          "default": "./lib/core/index.js"
        }
      },
      "import": {
        "types": "./lib/core/index.d.mts",
        "default": "./lib/core/index.mjs"
      },
      "default": {
        "types": "./lib/core/index.d.ts",
        "default": "./lib/core/index.js"
      }
    },
    "./browser": {
      "module-sync": {
        "types": "./lib/browser/index.d.mts",
        "default": "./lib/browser/index.mjs"
      },
      "module": {
        "types": "./lib/browser/index.d.mts",
        "default": "./lib/browser/index.mjs"
      },
      "browser": {
        "types": "./lib/browser/index.d.mts",
        "default": "./lib/browser/index.mjs"
      },
      "import": {
        "types": "./lib/browser/index.d.mts",
        "default": "./lib/browser/index.mjs"
      },
      "node": null,
      "react-native": null,
      "default": {
        "types": "./lib/browser/index.d.ts",
        "default": "./lib/browser/index.js"
      }
    },
    "./node": {
      "module-sync": {
        "types": "./lib/node/index.d.mts",
        "default": "./lib/node/index.mjs"
      },
      "module": {
        "types": "./lib/node/index.d.mts",
        "default": "./lib/node/index.mjs"
      },
      "node": {
        "require": "./lib/node/index.js",
        "import": "./lib/node/index.mjs"
      },
      "import": {
        "types": "./lib/node/index.d.mts",
        "default": "./lib/node/index.mjs"
      },
      "browser": null,
      "react-native": null,
      "default": {
        "types": "./lib/node/index.d.ts",
        "default": "./lib/node/index.js"
      }
    },
    "./native": {
      "browser": null,
      "react-native": {
        "import": {
          "types": "./lib/native/index.d.mts",
          "default": "./lib/native/index.mjs"
        },
        "default": {
          "types": "./lib/native/index.d.ts",
          "default": "./lib/native/index.js"
        }
      },
      "import": {
        "types": "./lib/native/index.d.mts",
        "default": "./lib/native/index.mjs"
      },
      "default": {
        "types": "./lib/native/index.d.ts",
        "default": "./lib/native/index.js"
      }
    },
    "./core/http": {
      "module-sync": {
        "types": "./lib/core/http.d.mts",
        "default": "./lib/core/http.mjs"
      },
      "module": {
        "types": "./lib/core/http.d.mts",
        "default": "./lib/core/http.mjs"
      },
      "import": {
        "types": "./lib/core/http.d.mts",
        "default": "./lib/core/http.mjs"
      },
      "default": {
        "types": "./lib/core/http.d.ts",
        "default": "./lib/core/http.js"
      }
    },
    "./core/graphql": {
      "module-sync": {
        "types": "./lib/core/graphql.d.mts",
        "default": "./lib/core/graphql.mjs"
      },
      "module": {
        "types": "./lib/core/graphql.d.mts",
        "default": "./lib/core/graphql.mjs"
      },
      "import": {
        "types": "./lib/core/graphql.d.mts",
        "default": "./lib/core/graphql.mjs"
      },
      "default": {
        "types": "./lib/core/graphql.d.ts",
        "default": "./lib/core/graphql.js"
      }
    },
    "./core/ws": {
      "module-sync": {
        "types": "./lib/core/ws.d.mts",
        "default": "./lib/core/ws.mjs"
      },
      "module": {
        "types": "./lib/core/ws.d.mts",
        "default": "./lib/core/ws.mjs"
      },
      "import": {
        "types": "./lib/core/ws.d.mts",
        "default": "./lib/core/ws.mjs"
      },
      "default": {
        "types": "./lib/core/ws.d.ts",
        "default": "./lib/core/ws.js"
      }
    },
    "./mockServiceWorker.js": "./lib/mockServiceWorker.js",
    "./package.json": "./package.json"
  },
  "bin": {
    "msw": "cli/index.js"
  },
  "engines": {
    "node": ">=18"
  },
  "scripts": {
    "start": "tsup --watch",
    "clean": "rimraf ./lib",
    "lint": "eslint \"{cli,src,test}/**/*.ts\"",
    "build": "pnpm clean && cross-env NODE_ENV=production tsup && pnpm patch:dts",
    "patch:dts": "node \"./config/scripts/patch-ts.js\"",
    "publint": "publint",
    "test": "pnpm test:unit && pnpm test:node && pnpm test:browser && pnpm test:native",
    "test:unit": "vitest",
    "test:node": "vitest --config=./test/node/vitest.config.ts",
    "test:native": "vitest --config=./test/native/vitest.config.ts",
    "test:browser": "playwright test -c ./test/browser/playwright.config.ts",
    "test:modules:node": "vitest run --config=./test/modules/node/vitest.config.ts",
    "test:modules:browser": "playwright test -c ./test/modules/browser/playwright.config.ts",
    "test:e2e": "vitest run --config=./test/e2e/vitest.config.ts",
    "test:ts": "vitest --config=./test/typings/vitest.config.ts",
    "prepare": "pnpm simple-git-hooks init",
    "prepack": "pnpm build",
    "release": "release publish",
    "postinstall": "node -e \"import('./config/scripts/postinstall.js').catch(() => void 0)\"",
    "knip": "knip"
  },
  "lint-staged": {
    "**/*.ts": [
      "eslint --fix"
    ],
    "**/*.{ts,json}": [
      "prettier --write"
    ]
  },
  "homepage": "https://mswjs.io",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/mswjs/msw.git"
  },
  "author": {
    "name": "Artem Zakharchenko",
    "url": "https://github.com/kettanaito"
  },
  "license": "MIT",
  "funding": "https://github.com/sponsors/mswjs",
  "files": [
    "config/package.json",
    "config/constants.js",
    "config/scripts/postinstall.js",
    "cli",
    "lib",
    "src",
    "browser",
    "node",
    "native",
    "LICENSE.md",
    "README.md"
  ],
  "keywords": [
    "api",
    "mock",
    "mocking",
    "worker",
    "prototype",
    "server",
    "service",
    "handler",
    "testing",
    "front-end",
    "back-end"
  ],
  "sideEffects": false,
  "dependencies": {
    "@inquirer/confirm": "^5.0.0",
    "@mswjs/interceptors": "^0.41.2",
    "@open-draft/deferred-promise": "^2.2.0",
    "@types/statuses": "^2.0.6",
    "cookie": "^1.0.2",
    "graphql": "^16.12.0",
    "headers-polyfill": "^4.0.2",
    "is-node-process": "^1.2.0",
    "outvariant": "^1.4.3",
    "path-to-regexp": "^6.3.0",
    "picocolors": "^1.1.1",
    "rettime": "^0.10.1",
    "statuses": "^2.0.2",
    "strict-event-emitter": "^0.5.1",
    "tough-cookie": "^6.0.0",
    "type-fest": "^5.2.0",
    "until-async": "^3.0.2",
    "yargs": "^17.7.2"
  },
  "devDependencies": {
    "@commitlint/cli": "^20.1.0",
    "@commitlint/config-conventional": "^20.0.0",
    "@epic-web/test-server": "^0.1.6",
    "@eslint/eslintrc": "^3.3.1",
    "@eslint/js": "^9.39.1",
    "@fastify/websocket": "^11.2.0",
    "@graphql-typed-document-node/core": "^3.2.0",
    "@open-draft/test-server": "^0.4.2",
    "@ossjs/release": "^0.10.1",
    "@playwright/test": "^1.50.1",
    "@types/express": "^5.0.5",
    "@types/json-bigint": "^1.0.4",
    "@types/node": "~20.19.25",
    "@types/serviceworker": "^0.0.167",
    "@typescript-eslint/eslint-plugin": "^8.47.0",
    "@typescript-eslint/parser": "^8.47.0",
    "@web/dev-server": "^0.4.6",
    "axios": "^1.13.5",
    "babel-minify": "^0.5.1",
    "commitizen": "^4.3.1",
    "cross-env": "^10.1.0",
    "cross-fetch": "^4.1.0",
    "cz-conventional-changelog": "3.3.0",
    "esbuild": "^0.27.0",
    "esbuild-loader": "^4.4.0",
    "eslint": "^9.39.1",
    "eslint-config-prettier": "^10.1.8",
    "eslint-plugin-prettier": "^5.5.4",
    "express": "^5.1.0",
    "fastify": "^5.6.2",
    "fs-teardown": "^0.3.0",
    "glob": "^13.0.0",
    "jsdom": "^25.0.1",
    "json-bigint": "^1.0.0",
    "knip": "^5.70.1",
    "lint-staged": "^15.2.10",
    "msw": "workspace:*",
    "page-with": "^0.6.1",
    "prettier": "^3.6.2",
    "publint": "^0.3.15",
    "regenerator-runtime": "^0.14.1",
    "rimraf": "^6.1.2",
    "simple-git-hooks": "^2.13.1",
    "tsup": "^8.5.1",
    "typescript": "^5.9.3",
    "typescript-eslint": "^8.47.0",
    "undici": "^7.16.0",
    "url-loader": "^4.1.1",
    "vitest": "^4.0.13",
    "vitest-environment-miniflare": "^2.14.4",
    "webpack": "^5.95.0",
    "webpack-http-server": "^0.5.0"
  },
  "peerDependencies": {
    "typescript": ">= 4.8.x"
  },
  "peerDependenciesMeta": {
    "typescript": {
      "optional": true
    }
  },
  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  },
  "simple-git-hooks": {
    "pre-commit": "pnpm lint-staged",
    "prepare-commit-msg": "grep -qE '^[^#]' .git/COMMIT_EDITMSG || (exec < /dev/tty && pnpm cz --hook || true)",
    "commit-msg": "pnpm commitlint --edit $1"
  }
}


================================================
FILE: release.config.json
================================================
{
  "$schema": "./node_modules/@ossjs/release/schema.json",
  "profiles": [
    {
      "name": "latest",
      "use": "NPM_CONFIG_PROVENANCE=true pnpm publish --no-git-checks"
    }
  ]
}


================================================
FILE: src/browser/global.browser.d.ts
================================================
declare const SERVICE_WORKER_CHECKSUM: string


================================================
FILE: src/browser/index.ts
================================================
export { setupWorker } from './setupWorker/setupWorker'
export type { SetupWorker, StartOptions } from './setupWorker/glossary'
export { SetupWorkerApi } from './setupWorker/setupWorker'


================================================
FILE: src/browser/setupWorker/glossary.ts
================================================
import { Emitter } from 'strict-event-emitter'
import type { HttpRequestEventMap, Interceptor } from '@mswjs/interceptors'
import type { DeferredPromise } from '@open-draft/deferred-promise'
import {
  LifeCycleEventEmitter,
  LifeCycleEventsMap,
  SharedOptions,
} from '~/core/sharedOptions'
import { RequestHandler } from '~/core/handlers/RequestHandler'
import type { RequiredDeep } from '~/core/typeUtils'
import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler'
import type { WorkerChannel } from '../utils/workerChannel'

export interface StringifiedResponse extends ResponseInit {
  body: string | ArrayBuffer | ReadableStream<Uint8Array> | null
}

export type SetupWorkerInternalContext = {
  isMockingEnabled: boolean
  workerStoppedAt?: number
  startOptions: RequiredDeep<StartOptions>
  workerPromise: DeferredPromise<ServiceWorker>
  registration: ServiceWorkerRegistration | undefined
  getRequestHandlers: () => Array<RequestHandler | WebSocketHandler>
  emitter: Emitter<LifeCycleEventsMap>
  keepAliveInterval?: number
  workerChannel: WorkerChannel
  fallbackInterceptor?: Interceptor<HttpRequestEventMap>
}

export type ServiceWorkerInstanceTuple = [
  ServiceWorker | null,
  ServiceWorkerRegistration,
]

export type FindWorker = (
  scriptUrl: string,
  mockServiceWorkerUrl: string,
) => boolean

export interface StartOptions extends SharedOptions {
  /**
   * Service Worker registration options.
   */
  serviceWorker?: {
    /**
     * Custom url to the worker script.
     * @default "/mockServiceWorker.js"
     */
    url?: string
    options?: RegistrationOptions
  }

  /**
   * Disables the logging of the intercepted requests
   * into browser's console.
   * @default false
   */
  quiet?: boolean

  /**
   * Defers any network requests until the Service Worker
   * instance is activated.
   * @default true
   */
  waitUntilReady?: boolean

  /**
   * A custom lookup function to find a Mock Service Worker in the list
   * of all registered Service Workers on the page.
   */
  findWorker?: FindWorker
}

export type StartReturnType = Promise<ServiceWorkerRegistration | undefined>

export type StartHandler = (
  options: RequiredDeep<StartOptions>,
  initialOptions: StartOptions,
) => StartReturnType

export type StopHandler = () => void

export interface SetupWorker {
  /**
   * Registers and activates the mock Service Worker.
   *
   * @see {@link https://mswjs.io/docs/api/setup-worker/start `worker.start()` API reference}
   */
  start: (options?: StartOptions) => StartReturnType

  /**
   * Stops requests interception for the current client.
   *
   * @see {@link https://mswjs.io/docs/api/setup-worker/stop `worker.stop()` API reference}
   */
  stop: StopHandler

  /**
   * Prepends given request handlers to the list of existing handlers.
   * @param {RequestHandler[]} handlers List of runtime request handlers.
   *
   * @see {@link https://mswjs.io/docs/api/setup-worker/use `worker.use()` API reference}
   */
  use: (...handlers: Array<RequestHandler | WebSocketHandler>) => void

  /**
   * Marks all request handlers that respond using `res.once()` as unused.
   *
   * @see {@link https://mswjs.io/docs/api/setup-worker/restore-handlers `worker.restoreHandlers()` API reference}
   */
  restoreHandlers: () => void

  /**
   * Resets request handlers to the initial list given to the `setupWorker` call, or to the explicit next request handlers list, if given.
   * @param {RequestHandler[]} nextHandlers List of the new initial request handlers.
   *
   * @see {@link https://mswjs.io/docs/api/setup-worker/reset-handlers `worker.resetHandlers()` API reference}
   */
  resetHandlers: (
    ...nextHandlers: Array<RequestHandler | WebSocketHandler>
  ) => void

  /**
   * Returns a readonly list of currently active request handlers.
   *
   * @see {@link https://mswjs.io/docs/api/setup-worker/list-handlers `worker.listHandlers()` API reference}
   */
  listHandlers(): ReadonlyArray<RequestHandler | WebSocketHandler>

  /**
   * Life-cycle events.
   * Life-cycle events allow you to subscribe to the internal library events occurring during the request/response handling.
   *
   * @see {@link https://mswjs.io/docs/api/life-cycle-events Life-cycle Events API reference}
   */
  events: LifeCycleEventEmitter<LifeCycleEventsMap>
}


================================================
FILE: src/browser/setupWorker/setupWorker.node.test.ts
================================================
/**
 * @vitest-environment node
 */
import { setupWorker } from './setupWorker'

test('returns an error when run in a Node.js environment', () => {
  expect(setupWorker).toThrow(
    '[MSW] Failed to execute `setupWorker` in a non-browser environment',
  )
})


================================================
FILE: src/browser/setupWorker/setupWorker.ts
================================================
import { invariant } from 'outvariant'
import { isNodeProcess } from 'is-node-process'
import { DeferredPromise } from '@open-draft/deferred-promise'
import type {
  SetupWorkerInternalContext,
  StartReturnType,
  StartOptions,
  SetupWorker,
} from './glossary'
import { RequestHandler } from '~/core/handlers/RequestHandler'
import { DEFAULT_START_OPTIONS } from './start/utils/prepareStartHandler'
import { createStartHandler } from './start/createStartHandler'
import { devUtils } from '~/core/utils/internal/devUtils'
import { SetupApi } from '~/core/SetupApi'
import { mergeRight } from '~/core/utils/internal/mergeRight'
import type { LifeCycleEventsMap } from '~/core/sharedOptions'
import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler'
import { webSocketInterceptor } from '~/core/ws/webSocketInterceptor'
import { handleWebSocketEvent } from '~/core/ws/handleWebSocketEvent'
import { attachWebSocketLogger } from '~/core/ws/utils/attachWebSocketLogger'
import { WorkerChannel } from '../utils/workerChannel'
import { createFallbackRequestListener } from './start/createFallbackRequestListener'
import { printStartMessage } from './start/utils/printStartMessage'
import { printStopMessage } from './stop/utils/printStopMessage'
import { supportsServiceWorker } from '../utils/supports'

export class SetupWorkerApi
  extends SetupApi<LifeCycleEventsMap>
  implements SetupWorker
{
  private context: SetupWorkerInternalContext

  constructor(...handlers: Array<RequestHandler | WebSocketHandler>) {
    super(...handlers)

    invariant(
      !isNodeProcess(),
      devUtils.formatMessage(
        'Failed to execute `setupWorker` in a non-browser environment. Consider using `setupServer` for Node.js environment instead.',
      ),
    )

    this.context = this.createWorkerContext()
  }

  private createWorkerContext(): SetupWorkerInternalContext {
    const workerPromise = new DeferredPromise<ServiceWorker>()

    return {
      // Mocking is not considered enabled until the worker
      // signals back the successful activation event.
      isMockingEnabled: false,
      startOptions: null as any,
      workerPromise,
      registration: undefined,
      getRequestHandlers: () => {
        return this.handlersController.currentHandlers()
      },
      emitter: this.emitter,
      workerChannel: new WorkerChannel({
        worker: workerPromise,
      }),
    }
  }

  public async start(options: StartOptions = {}): StartReturnType {
    if ('waitUntilReady' in options) {
      devUtils.warn(
        'The "waitUntilReady" option has been deprecated. Please remove it from this "worker.start()" call. Follow the recommended Browser integration (https://mswjs.io/docs/integrations/browser) to eliminate any race conditions between the Service Worker registration and any requests made by your application on initial render.',
      )
    }

    // Warn the developer on multiple "worker.start()" calls.
    // While this will not affect the worker in any way,
    // it likely indicates an issue with the developer's code.
    if (this.context.isMockingEnabled) {
      devUtils.warn(
        `Found a redundant "worker.start()" call. Note that starting the worker while mocking is already enabled will have no effect. Consider removing this "worker.start()" call.`,
      )
      return this.context.registration
    }

    this.context.workerStoppedAt = undefined

    this.context.startOptions = mergeRight(
      DEFAULT_START_OPTIONS,
      options,
    ) as SetupWorkerInternalContext['startOptions']

    // Enable the WebSocket interception.
    handleWebSocketEvent({
      getUnhandledRequestStrategy: () => {
        return this.context.startOptions.onUnhandledRequest
      },
      getHandlers: () => {
        return this.handlersController.currentHandlers()
      },
      onMockedConnection: (connection) => {
        if (!this.context.startOptions.quiet) {
          // Attach the logger for mocked connections since
          // those won't be visible in the browser's devtools.
          attachWebSocketLogger(connection)
        }
      },
      onPassthroughConnection() {},
    })
    webSocketInterceptor.apply()

    this.subscriptions.push(() => {
      webSocketInterceptor.dispose()
    })

    // Use a fallback interception algorithm in the environments
    // where the Service Worker API isn't supported.
    if (!supportsServiceWorker()) {
      const fallbackInterceptor = createFallbackRequestListener(
        this.context,
        this.context.startOptions,
      )

      this.subscriptions.push(() => {
        fallbackInterceptor.dispose()
      })

      this.context.isMockingEnabled = true

      printStartMessage({
        message: 'Mocking enabled (fallback mode).',
        quiet: this.context.startOptions.quiet,
      })

      return undefined
    }

    const startHandler = createStartHandler(this.context)
    const registration = await startHandler(this.context.startOptions, options)

    this.context.isMockingEnabled = true

    return registration
  }

  public stop(): void {
    super.dispose()

    if (!this.context.isMockingEnabled) {
      devUtils.warn(
        'Found a redundant "worker.stop()" call. Notice that stopping the worker after it has already been stopped has no effect. Consider removing this "worker.stop()" call.',
      )
      return
    }

    this.context.isMockingEnabled = false
    this.context.workerStoppedAt = Date.now()
    this.context.emitter.removeAllListeners()

    if (supportsServiceWorker()) {
      this.context.workerChannel.removeAllListeners('RESPONSE')
      window.clearInterval(this.context.keepAliveInterval)
    }

    // Post the internal stop message on the window
    // to let any logic know when the worker has stopped.
    // E.g. the WebSocket client manager needs this to know
    // when to clear its in-memory clients list.
    window.postMessage({ type: 'msw/worker:stop' })

    printStopMessage({
      quiet: this.context.startOptions?.quiet,
    })
  }
}

/**
 * Sets up a requests interception in the browser with the given request handlers.
 * @param {RequestHandler[]} handlers List of request handlers.
 *
 * @see {@link https://mswjs.io/docs/api/setup-worker `setupWorker()` API reference}
 */
export function setupWorker(
  ...handlers: Array<RequestHandler | WebSocketHandler>
): SetupWorker {
  return new SetupWorkerApi(...handlers)
}


================================================
FILE: src/browser/setupWorker/start/createFallbackRequestListener.ts
================================================
import {
  Interceptor,
  BatchInterceptor,
  HttpRequestEventMap,
} from '@mswjs/interceptors'
import { FetchInterceptor } from '@mswjs/interceptors/fetch'
import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest'
import { SetupWorkerInternalContext, StartOptions } from '../glossary'
import type { RequiredDeep } from '~/core/typeUtils'
import { handleRequest } from '~/core/utils/handleRequest'
import { isHandlerKind } from '~/core/utils/internal/isHandlerKind'

export function createFallbackRequestListener(
  context: SetupWorkerInternalContext,
  options: RequiredDeep<StartOptions>,
): Interceptor<HttpRequestEventMap> {
  const interceptor = new BatchInterceptor({
    name: 'fallback',
    interceptors: [new FetchInterceptor(), new XMLHttpRequestInterceptor()],
  })

  interceptor.on('request', async ({ request, requestId, controller }) => {
    const requestCloneForLogs = request.clone()

    const response = await handleRequest(
      request,
      requestId,
      context.getRequestHandlers().filter(isHandlerKind('RequestHandler')),
      options,
      context.emitter,
      {
        resolutionContext: {
          quiet: options.quiet,
        },
        onMockedResponse(_, { handler, parsedResult }) {
          if (!options.quiet) {
            context.emitter.once('response:mocked', ({ response }) => {
              handler.log({
                request: requestCloneForLogs,
                response,
                parsedResult,
              })
            })
          }
        },
      },
    )

    if (response) {
      controller.respondWith(response)
    }
  })

  interceptor.on(
    'response',
    ({ response, isMockedResponse, request, requestId }) => {
      context.emitter.emit(
        isMockedResponse ? 'response:mocked' : 'response:bypass',
        {
          response,
          request,
          requestId,
        },
      )
    },
  )

  interceptor.apply()

  return interceptor
}


================================================
FILE: src/browser/setupWorker/start/createRequestListener.ts
================================================
import { Emitter } from 'rettime'
import { StartOptions, SetupWorkerInternalContext } from '../glossary'
import { deserializeRequest } from '../../utils/deserializeRequest'
import { supportsReadableStreamTransfer } from '../../utils/supports'
import { RequestHandler } from '~/core/handlers/RequestHandler'
import { handleRequest } from '~/core/utils/handleRequest'
import { RequiredDeep } from '~/core/typeUtils'
import { devUtils } from '~/core/utils/internal/devUtils'
import { toResponseInit } from '~/core/utils/toResponseInit'
import { isHandlerKind } from '~/core/utils/internal/isHandlerKind'

const SUPPORTS_READABLE_STREAM_TRANSFER = supportsReadableStreamTransfer()

export const createRequestListener = (
  context: SetupWorkerInternalContext,
  options: RequiredDeep<StartOptions>,
): Emitter.ListenerType<typeof context.workerChannel, 'REQUEST'> => {
  return async (event) => {
    // Treat any incoming requests from the worker as passthrough
    // if `worker.stop()` has been called for this client.
    if (
      !context.isMockingEnabled &&
      context.workerStoppedAt &&
      event.data.interceptedAt > context.workerStoppedAt
    ) {
      event.postMessage('PASSTHROUGH')
      return
    }

    const requestId = event.data.id
    const request = deserializeRequest(event.data)
    const requestCloneForLogs = request.clone()

    // Make this the first request clone before the
    // request resolution pipeline even starts.
    // Store the clone in cache so the first matching
    // request handler would skip the cloning phase.
    const requestClone = request.clone()
    RequestHandler.cache.set(request, requestClone)

    try {
      await handleRequest(
        request,
        requestId,
        context.getRequestHandlers().filter(isHandlerKind('RequestHandler')),
        options,
        context.emitter,
        {
          resolutionContext: {
            quiet: options.quiet,
          },
          onPassthroughResponse() {
            event.postMessage('PASSTHROUGH')
          },
          async onMockedResponse(response, { handler, parsedResult }) {
            // Clone the mocked response so its body could be read
            // to buffer to be sent to the worker and also in the
            // ".log()" method of the request handler.
            const responseClone = response.clone()
            const responseCloneForLogs = response.clone()
            const responseInit = toResponseInit(response)

            /**
             * @note Safari doesn't support transferring a "ReadableStream".
             * Check that the browser supports that before sending it to the worker.
             */
            if (SUPPORTS_READABLE_STREAM_TRANSFER) {
              const responseStreamOrNull = response.body

              event.postMessage(
                'MOCK_RESPONSE',
                {
                  ...responseInit,
                  body: responseStreamOrNull,
                },
                responseStreamOrNull ? [responseStreamOrNull] : undefined,
              )
            } else {
              /**
               * @note If we are here, this means the current environment doesn't
               * support "ReadableStream" as transferable. In that case,
               * attempt to read the non-empty response body as ArrayBuffer, if it's not empty.
               * @see https://github.com/mswjs/msw/issues/1827
               */
              const responseBufferOrNull =
                response.body === null
                  ? null
                  : await responseClone.arrayBuffer()

              event.postMessage('MOCK_RESPONSE', {
                ...responseInit,
                body: responseBufferOrNull,
              })
            }

            if (!options.quiet) {
              context.emitter.once('response:mocked', () => {
                handler.log({
                  request: requestCloneForLogs,
                  response: responseCloneForLogs,
                  parsedResult,
                })
              })
            }
          },
        },
      )
    } catch (error) {
      if (error instanceof Error) {
        devUtils.error(
          `Uncaught exception in the request handler for "%s %s":

%s

This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/http/mocking-responses/error-responses`,
          request.method,
          request.url,
          error.stack ?? error,
        )

        // Treat all other exceptions in a request handler as unintended,
        // alerting that there is a problem that needs fixing.
        event.postMessage('MOCK_RESPONSE', {
          status: 500,
          statusText: 'Request Handler Error',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            name: error.name,
            message: error.message,
            stack: error.stack,
          }),
        })
      }
    }
  }
}


================================================
FILE: src/browser/setupWorker/start/createResponseListener.ts
================================================
import { FetchResponse } from '@mswjs/interceptors'
import type { Emitter } from 'rettime'
import type { SetupWorkerInternalContext } from '../glossary'
import { deserializeRequest } from '../../utils/deserializeRequest'

export function createResponseListener(
  context: SetupWorkerInternalContext,
): Emitter.ListenerType<typeof context.workerChannel, 'RESPONSE'> {
  return (event) => {
    const responseMessage = event.data
    const request = deserializeRequest(responseMessage.request)

    /**
     * CORS requests with `mode: "no-cors"` result in "opaque" responses.
     * That kind of responses cannot be manipulated in JavaScript due
     * to the security considerations.
     * @see https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
     * @see https://github.com/mswjs/msw/issues/529
     */
    if (responseMessage.response.type?.includes('opaque')) {
      return
    }

    const response =
      responseMessage.response.status === 0
        ? Response.error()
        : new FetchResponse(
            /**
             * Responses may be streams here, but when we create a response object
             * with null-body status codes, like 204, 205, 304 Response will
             * throw when passed a non-null body, so ensure it's null here
             * for those codes
             */
            FetchResponse.isResponseWithBody(responseMessage.response.status)
              ? responseMessage.response.body
              : null,
            {
              ...responseMessage.response,
              /**
               * Set response URL if it's not set already.
               * @see https://github.com/mswjs/msw/issues/2030
               * @see https://developer.mozilla.org/en-US/docs/Web/API/Response/url
               */
              url: request.url,
            },
          )

    context.emitter.emit(
      responseMessage.isMockedResponse ? 'response:mocked' : 'response:bypass',
      {
        requestId: responseMessage.request.id,
        request,
        response,
      },
    )
  }
}


================================================
FILE: src/browser/setupWorker/start/createStartHandler.ts
================================================
import { devUtils } from '~/core/utils/internal/devUtils'
import { getWorkerInstance } from './utils/getWorkerInstance'
import { enableMocking } from './utils/enableMocking'
import type { SetupWorkerInternalContext, StartHandler } from '../glossary'
import { createRequestListener } from './createRequestListener'
import { checkWorkerIntegrity } from '../../utils/checkWorkerIntegrity'
import { createResponseListener } from './createResponseListener'
import { validateWorkerScope } from './utils/validateWorkerScope'
import { DeferredPromise } from '@open-draft/deferred-promise'

export const createStartHandler = (
  context: SetupWorkerInternalContext,
): StartHandler => {
  return function start(options, customOptions) {
    const startWorkerInstance = async () => {
      // Remove all previously existing event listeners.
      // This way none of the listeners persists between Fast refresh
      // of the application's code.
      context.workerChannel.removeAllListeners()

      // Handle requests signaled by the worker.
      context.workerChannel.on(
        'REQUEST',
        createRequestListener(context, options),
      )

      // Handle responses signaled by the worker.
      context.workerChannel.on('RESPONSE', createResponseListener(context))

      const instance = await getWorkerInstance(
        options.serviceWorker.url,
        options.serviceWorker.options,
        options.findWorker,
      )

      const [worker, registration] = instance

      if (!worker) {
        const missingWorkerMessage = customOptions?.findWorker
          ? devUtils.formatMessage(
              `Failed to locate the Service Worker registration using a custom "findWorker" predicate.

Please ensure that the custom predicate properly locates the Service Worker registration at "%s".
More details: https://mswjs.io/docs/api/setup-worker/start#findworker
`,
              options.serviceWorker.url,
            )
          : devUtils.formatMessage(
              `Failed to locate the Service Worker registration.

This most likely means that the worker script URL "%s" cannot resolve against the actual public hostname (%s). This may happen if your application runs behind a proxy, or has a dynamic hostname.

Please consider using a custom "serviceWorker.url" option to point to the actual worker script location, or a custom "findWorker" option to resolve the Service Worker registration manually. More details: https://mswjs.io/docs/api/setup-worker/start`,
              options.serviceWorker.url,
              location.host,
            )

        throw new Error(missingWorkerMessage)
      }

      context.workerPromise.resolve(worker)
      context.registration = registration

      window.addEventListener('beforeunload', () => {
        if (worker.state !== 'redundant') {
          // Notify the Service Worker that this client has closed.
          // Internally, it's similar to disabling the mocking, only
          // client close event has a handler that self-terminates
          // the Service Worker when there are no open clients.
          context.workerChannel.postMessage('CLIENT_CLOSED')
        }

        // Make sure we're always clearing the interval - there are reports that not doing this can
        // cause memory leaks in headless browser environments.
        window.clearInterval(context.keepAliveInterval)

        // Notify others about this client disconnecting.
        // E.g. this will purge the in-memory WebSocket clients since
        // starting the worker again will assign them new IDs.
        window.postMessage({ type: 'msw/worker:stop' })
      })

      // Check if the active Service Worker has been generated
      // by the currently installed version of MSW.
      await checkWorkerIntegrity(context).catch((error) => {
        devUtils.error(
          'Error while checking the worker script integrity. Please report this on GitHub (https://github.com/mswjs/msw/issues) and include the original error below.',
        )
        console.error(error)
      })

      context.keepAliveInterval = window.setInterval(
        () => context.workerChannel.postMessage('KEEPALIVE_REQUEST'),
        5000,
      )

      // Warn the user when loading the page that lies outside
      // of the worker's scope.
      validateWorkerScope(registration, context.startOptions)

      return registration
    }

    const workerRegistration = startWorkerInstance().then(
      async (registration) => {
        const pendingInstance = registration.installing || registration.waiting

        if (pendingInstance) {
          const activationPromise = new DeferredPromise<void>()

          pendingInstance.addEventListener('statechange', () => {
            if (pendingInstance.state === 'activated') {
              activationPromise.resolve()
            }
          })

          // Wait until the worker is activated.
          // Assume the worker is already activated if there's no pending registration
          // (i.e. when reloading the page after a successful activation).
          await activationPromise
        }

        // Print the activation message only after the worker has been activated.
        await enableMocking(context, options).catch((error) => {
          devUtils.error(
            'Failed to enable mocking. Please report this on GitHub (https://github.com/mswjs/msw/issues) and include the original error below.',
          )
          throw error
        })

        return registration
      },
    )

    return workerRegistration
  }
}


================================================
FILE: src/browser/setupWorker/start/utils/enableMocking.ts
================================================
import { DeferredPromise } from '@open-draft/deferred-promise'
import type { StartOptions, SetupWorkerInternalContext } from '../../glossary'
import { printStartMessage } from './printStartMessage'

/**
 * Signals the worker to enable the interception of requests.
 */
export function enableMocking(
  context: SetupWorkerInternalContext,
  options: StartOptions,
): Promise<boolean> {
  const mockingEnabledPromise = new DeferredPromise<boolean>()

  context.workerChannel.postMessage('MOCK_ACTIVATE')
  context.workerChannel.once('MOCKING_ENABLED', async (event) => {
    context.isMockingEnabled = true
    const worker = await context.workerPromise

    printStartMessage({
      quiet: options.quiet,
      workerScope: context.registration?.scope,
      workerUrl: worker.scriptURL,
      client: event.data.client,
    })

    mockingEnabledPromise.resolve(true)
  })

  return mockingEnabledPromise
}


================================================
FILE: src/browser/setupWorker/start/utils/getWorkerByRegistration.ts
================================================
import { FindWorker } from '../../glossary'

/**
 * Attempts to resolve a Service Worker instance from a given registration,
 * regardless of its state (active, installing, waiting).
 */
export function getWorkerByRegistration(
  registration: ServiceWorkerRegistration,
  absoluteWorkerUrl: string,
  findWorker: FindWorker,
): ServiceWorker | null {
  const allStates = [
    registration.active,
    registration.installing,
    registration.waiting,
  ]
  const relevantStates = allStates.filter((state): state is ServiceWorker => {
    return state != null
  })
  const worker = relevantStates.find((worker) => {
    return findWorker(worker.scriptURL, absoluteWorkerUrl)
  })

  return worker || null
}


================================================
FILE: src/browser/setupWorker/start/utils/getWorkerInstance.ts
================================================
import { until } from 'until-async'
import { devUtils } from '~/core/utils/internal/devUtils'
import { getAbsoluteWorkerUrl } from '../../../utils/getAbsoluteWorkerUrl'
import { getWorkerByRegistration } from './getWorkerByRegistration'
import { ServiceWorkerInstanceTuple, FindWorker } from '../../glossary'

/**
 * Returns an active Service Worker instance.
 * When not found, registers a new Service Worker.
 */
export const getWorkerInstance = async (
  url: string,
  options: RegistrationOptions = {},
  findWorker: FindWorker,
): Promise<ServiceWorkerInstanceTuple> => {
  // Resolve the absolute Service Worker URL.
  const absoluteWorkerUrl = getAbsoluteWorkerUrl(url)

  const mockRegistrations = await navigator.serviceWorker
    .getRegistrations()
    .then((registrations) =>
      registrations.filter((registration) =>
        getWorkerByRegistration(registration, absoluteWorkerUrl, findWorker),
      ),
    )
  if (!navigator.serviceWorker.controller && mockRegistrations.length > 0) {
    // Reload the page when it has associated workers, but no active controller.
    // The absence of a controller can mean either:
    // - page has no Service Worker associated with it
    // - page has been hard-reloaded and its workers won't be used until the next reload.
    // Since we've checked that there are registrations associated with this page,
    // at this point we are sure it's hard reload that falls into this clause.
    location.reload()
  }

  const [existingRegistration] = mockRegistrations

  if (existingRegistration) {
    // Schedule the worker update in the background.
    // Update ensures the existing worker is up-to-date.
    existingRegistration.update()

    // Return the worker reference immediately.
    return [
      getWorkerByRegistration(
        existingRegistration,
        absoluteWorkerUrl,
        findWorker,
      ),
      existingRegistration,
    ]
  }

  // When the Service Worker wasn't found, register it anew and return the reference.
  const [registrationError, registrationResult] = await until<
    Error,
    ServiceWorkerInstanceTuple
  >(async () => {
    const registration = await navigator.serviceWorker.register(url, options)
    return [
      // Compare existing worker registration by its worker URL,
      // to prevent irrelevant workers to resolve here (such as Codesandbox worker).
      getWorkerByRegistration(registration, absoluteWorkerUrl, findWorker),
      registration,
    ]
  })

  // Handle Service Worker registration errors.
  if (registrationError) {
    const isWorkerMissing = registrationError.message.includes('(404)')

    // Produce a custom error message when given a non-existing Service Worker url.
    // Suggest developers to check their setup.
    if (isWorkerMissing) {
      const scopeUrl = new URL(options?.scope || '/', location.href)

      throw new Error(
        devUtils.formatMessage(`\
Failed to register a Service Worker for scope ('${scopeUrl.href}') with script ('${absoluteWorkerUrl}'): Service Worker script does not exist at the given path.

Did you forget to run "npx msw init <PUBLIC_DIR>"?

Learn more about creating the Service Worker script: https://mswjs.io/docs/cli/init`),
      )
    }

    // Fallback error message for any other registration errors.
    throw new Error(
      devUtils.formatMessage(
        'Failed to register the Service Worker:\n\n%s',
        registrationError.message,
      ),
    )
  }

  return registrationResult
}


================================================
FILE: src/browser/setupWorker/start/utils/prepareStartHandler.test.ts
================================================
import { SetupWorkerInternalContext, StartOptions } from '../../glossary'
import {
  DEFAULT_START_OPTIONS,
  resolveStartOptions,
  prepareStartHandler,
} from './prepareStartHandler'

describe('resolveStartOptions', () => {
  test('returns default options given no custom start options', () => {
    expect(resolveStartOptions()).toEqual(DEFAULT_START_OPTIONS)
    expect(resolveStartOptions(undefined)).toEqual(DEFAULT_START_OPTIONS)
    expect(resolveStartOptions({})).toEqual(DEFAULT_START_OPTIONS)
  })

  test('deeply merges the default and custom start options', () => {
    expect(
      resolveStartOptions({
        quiet: true,
        serviceWorker: {
          url: './custom.js',
        },
      }),
    ).toEqual({
      ...DEFAULT_START_OPTIONS,
      quiet: true,
      serviceWorker: {
        url: './custom.js',
        options: null,
      },
    })
  })
})

describe('prepareStartHandler', () => {
  test('exposes resolved start options to the generated star handler', () => {
    const createStartHandler = vi.fn()
    const context: SetupWorkerInternalContext = {} as any
    const startHandler = prepareStartHandler(createStartHandler, context)
    expect(startHandler).toBeInstanceOf(Function)

    const initialOptions: StartOptions = {
      quiet: true,
      serviceWorker: {
        url: './custom.js',
      },
    }
    const resolvedOptions = resolveStartOptions(initialOptions)
    startHandler(initialOptions)

    // Calls the handler creator with both resolved and initial options.
    expect(createStartHandler).toHaveBeenCalledWith(
      resolvedOptions,
      initialOptions,
    )

    // Sets the resolved options on the internal context.
    expect(context).toHaveProperty('startOptions', resolvedOptions)
  })
})


================================================
FILE: src/browser/setupWorker/start/utils/prepareStartHandler.ts
================================================
import { RequiredDeep } from '~/core/typeUtils'
import { mergeRight } from '~/core/utils/internal/mergeRight'
import {
  SetupWorker,
  SetupWorkerInternalContext,
  StartHandler,
  StartOptions,
} from '../../glossary'

export const DEFAULT_START_OPTIONS: RequiredDeep<StartOptions> = {
  serviceWorker: {
    url: '/mockServiceWorker.js',
    options: null as any,
  },
  quiet: false,
  waitUntilReady: true,
  onUnhandledRequest: 'warn',
  findWorker(scriptURL, mockServiceWorkerUrl) {
    return scriptURL === mockServiceWorkerUrl
  },
}

/**
 * Returns resolved worker start options, merging the default options
 * with the given custom options.
 */
export function resolveStartOptions(
  initialOptions?: StartOptions,
): RequiredDeep<StartOptions> {
  return mergeRight(
    DEFAULT_START_OPTIONS,
    initialOptions || {},
  ) as RequiredDeep<StartOptions>
}

export function prepareStartHandler(
  handler: StartHandler,
  context: SetupWorkerInternalContext,
): SetupWorker['start'] {
  return (initialOptions) => {
    context.startOptions = resolveStartOptions(initialOptions)
    return handler(context.startOptions, initialOptions || {})
  }
}


================================================
FILE: src/browser/setupWorker/start/utils/printStartMessage.test.ts
================================================
import { printStartMessage } from './printStartMessage'

beforeEach(() => {
  vi.spyOn(console, 'groupCollapsed').mockImplementation(() => void 0)
  vi.spyOn(console, 'log').mockImplementation(() => void 0)
})

afterEach(() => {
  vi.restoreAllMocks()
})

test('prints out a default start message into console', () => {
  printStartMessage({
    workerScope: 'http://localhost:3000/',
    workerUrl: 'http://localhost:3000/worker.js',
  })

  expect(console.groupCollapsed).toHaveBeenCalledWith(
    '%c[MSW] Mocking enabled.',
    expect.anything(),
  )

  // Includes a link to the documentation.
  expect(console.log).toHaveBeenCalledWith(
    '%cDocumentation: %chttps://mswjs.io/docs',
    expect.anything(),
    expect.anything(),
  )

  // Includes a link to the GitHub issues page.
  expect(console.log).toHaveBeenCalledWith(
    'Found an issue? https://github.com/mswjs/msw/issues',
  )

  // Includes service worker scope.
  expect(console.log).toHaveBeenCalledWith(
    'Worker scope:',
    'http://localhost:3000/',
  )

  // Includes service worker script location.
  expect(console.log).toHaveBeenCalledWith(
    'Worker script URL:',
    'http://localhost:3000/worker.js',
  )
})

test('supports printing a custom start message', () => {
  printStartMessage({ message: 'Custom start message' })

  expect(console.groupCollapsed).toHaveBeenCalledWith(
    '%c[MSW] Custom start message',
    expect.anything(),
  )
})

test('does not print any messages when log level is quiet', () => {
  printStartMessage({ quiet: true })

  expect(console.groupCollapsed).not.toHaveBeenCalled()
  expect(console.log).not.toHaveBeenCalled()
})

test('prints a worker scope in the start message', () => {
  printStartMessage({
    workerScope: 'http://localhost:3000/user',
  })

  expect(console.log).toHaveBeenCalledWith(
    'Worker scope:',
    'http://localhost:3000/user',
  )
})

test('prints a worker script url in the start message', () => {
  printStartMessage({
    workerUrl: 'http://localhost:3000/mockServiceWorker.js',
  })

  expect(console.log).toHaveBeenCalledWith(
    'Worker script URL:',
    'http://localhost:3000/mockServiceWorker.js',
  )
})


================================================
FILE: src/browser/setupWorker/start/utils/printStartMessage.ts
================================================
import type { ServiceWorkerIncomingEventsMap } from '../../glossary'
import { devUtils } from '~/core/utils/internal/devUtils'

interface PrintStartMessageArgs {
  quiet?: boolean
  message?: string
  workerUrl?: string
  workerScope?: string
  client?: ServiceWorkerIncomingEventsMap['MOCKING_ENABLED']['client']
}

/**
 * Prints a worker activation message in the browser's console.
 */
export function printStartMessage(args: PrintStartMessageArgs = {}) {
  if (args.quiet) {
    return
  }

  const message = args.message || 'Mocking enabled.'

  console.groupCollapsed(
    `%c${devUtils.formatMessage(message)}`,
    'color:orangered;font-weight:bold;',
  )
  // eslint-disable-next-line no-console
  console.log(
    '%cDocumentation: %chttps://mswjs.io/docs',
    'font-weight:bold',
    'font-weight:normal',
  )
  // eslint-disable-next-line no-console
  console.log('Found an issue? https://github.com/mswjs/msw/issues')

  if (args.workerUrl) {
    // eslint-disable-next-line no-console
    console.log('Worker script URL:', args.workerUrl)
  }

  if (args.workerScope) {
    // eslint-disable-next-line no-console
    console.log('Worker scope:', args.workerScope)
  }

  if (args.client) {
    // eslint-disable-next-line no-console
    console.log('Client ID: %s (%s)', args.client.id, args.client.frameType)
  }

  console.groupEnd()
}


================================================
FILE: src/browser/setupWorker/start/utils/validateWorkerScope.ts
================================================
import { devUtils } from '~/core/utils/internal/devUtils'
import { StartOptions } from '../../glossary'

export function validateWorkerScope(
  registration: ServiceWorkerRegistration,
  options?: StartOptions,
): void {
  if (!options?.quiet && !location.href.startsWith(registration.scope)) {
    devUtils.warn(
      `\
Cannot intercept requests on this page because it's outside of the worker's scope ("${registration.scope}"). If you wish to mock API requests on this page, you must resolve this scope issue.

- (Recommended) Register the worker at the root level ("/") of your application.
- Set the "Service-Worker-Allowed" response header to allow out-of-scope workers.\
`,
    )
  }
}


================================================
FILE: src/browser/setupWorker/stop/utils/printStopMessage.test.ts
================================================
import { printStopMessage } from './printStopMessage'

beforeAll(() => {
  vi.spyOn(global.console, 'log').mockImplementation(() => void 0)
})

afterEach(() => {
  vi.resetAllMocks()
})

afterAll(() => {
  vi.restoreAllMocks()
})

test('prints a stop message to the console', () => {
  printStopMessage()
  expect(console.log).toHaveBeenCalledWith(
    '%c[MSW] Mocking disabled.',
    'color:orangered;font-weight:bold;',
  )
})

test('does not print any message when log level is quiet', () => {
  printStopMessage({ quiet: true })
  expect(console.log).not.toHaveBeenCalled()
})


================================================
FILE: src/browser/setupWorker/stop/utils/printStopMessage.ts
================================================
import { devUtils } from '~/core/utils/internal/devUtils'

export function printStopMessage(args: { quiet?: boolean } = {}): void {
  if (args.quiet) {
    return
  }

  // eslint-disable-next-line no-console
  console.log(
    `%c${devUtils.formatMessage('Mocking disabled.')}`,
    'color:orangered;font-weight:bold;',
  )
}


================================================
FILE: src/browser/tsconfig.browser.build.json
================================================
{
  "extends": "./tsconfig.browser.json",
  "compilerOptions": {
    "composite": false
  }
}


================================================
FILE: src/browser/tsconfig.browser.json
================================================
{
  "extends": "../tsconfig.src.json",
  "compilerOptions": {
    // Expose browser-specific libraries only for the
    // source code under the "src/browser" directory.
    "lib": ["DOM", "WebWorker", "DOM.Iterable"]
  },
  "include": ["../../global.d.ts", "./global.browser.d.ts", "./**/*.ts"]
}


================================================
FILE: src/browser/utils/checkWorkerIntegrity.ts
================================================
import { devUtils } from '~/core/utils/internal/devUtils'
import type { SetupWorkerInternalContext } from '../setupWorker/glossary'
import { DeferredPromise } from '@open-draft/deferred-promise'

/**
 * Check whether the registered Service Worker has been
 * generated by the installed version of the library.
 * Prints a warning message if the worker scripts mismatch.
 */
export function checkWorkerIntegrity(
  context: SetupWorkerInternalContext,
): Promise<void> {
  const integrityCheckPromise = new DeferredPromise<void>()

  // Request the integrity checksum from the registered worker.
  context.workerChannel.postMessage('INTEGRITY_CHECK_REQUEST')
  context.workerChannel.once('INTEGRITY_CHECK_RESPONSE', (event) => {
    const { checksum, packageVersion } = event.data

    // Compare the response from the Service Worker and the
    // global variable set during the build.

    // The integrity is validated based on the worker script's checksum
    // that's derived from its minified content during the build.
    // The "SERVICE_WORKER_CHECKSUM" global variable is injected by the build.
    if (checksum !== SERVICE_WORKER_CHECKSUM) {
      devUtils.warn(
        `The currently registered Service Worker has been generated by a different version of MSW (${packageVersion}) and may not be fully compatible with the installed version.

It's recommended you update your worker script by running this command:

  \u2022 npx msw init <PUBLIC_DIR>

You can also automate this process and make the worker script update automatically upon the library installations. Read more: https://mswjs.io/docs/cli/init.`,
      )
    }

    integrityCheckPromise.resolve()
  })

  return integrityCheckPromise
}


================================================
FILE: src/browser/utils/deserializeRequest.ts
================================================
import { pruneGetRequestBody } from './pruneGetRequestBody'
import type { ServiceWorkerIncomingRequest } from '../setupWorker/glossary'

/**
 * Converts a given request received from the Service Worker
 * into a Fetch `Request` instance.
 */
export function deserializeRequest(
  serializedRequest: ServiceWorkerIncomingRequest,
): Request {
  return new Request(serializedRequest.url, {
    ...serializedRequest,
    body: pruneGetRequestBody(serializedRequest),
  })
}


================================================
FILE: src/browser/utils/getAbsoluteWorkerUrl.test.ts
================================================
// @vitest-environment jsdom
import { getAbsoluteWorkerUrl } from './getAbsoluteWorkerUrl'

const rawLocation = window.location

afterAll(() => {
  Object.defineProperty(window, 'location', {
    value: rawLocation,
  })
})

it('returns absolute worker url relatively to the root', () => {
  expect(getAbsoluteWorkerUrl('./worker.js')).toBe('http://localhost/worker.js')
})

it('returns an absolute worker url relatively to the current path', () => {
  Object.defineProperty(window, 'location', {
    value: {
      href: 'http://localhost/path/to/page',
    },
  })

  expect(getAbsoluteWorkerUrl('./worker.js')).toBe(
    'http://localhost/path/to/worker.js',
  )

  // Leading slash must still resolve to the root.
  expect(getAbsoluteWorkerUrl('/worker.js')).toBe('http://localhost/worker.js')
})


================================================
FILE: src/browser/utils/getAbsoluteWorkerUrl.ts
================================================
/**
 * Returns an absolute Service Worker URL based on the given
 * relative URL (known during the registration).
 */
export function getAbsoluteWorkerUrl(workerUrl: string): string {
  return new URL(workerUrl, location.href).href
}


================================================
FILE: src/browser/utils/pruneGetRequestBody.test.ts
================================================
/**
 * @vitest-environment jsdom
 */
import { TextEncoder } from 'util'
import { pruneGetRequestBody } from './pruneGetRequestBody'

test('sets empty GET request body to undefined', () => {
  expect(
    pruneGetRequestBody({
      method: 'GET',
    }),
  ).toBeUndefined()

  expect(
    pruneGetRequestBody({
      method: 'GET',
      // There's no such thing as a GET request with a body.
      body: new ArrayBuffer(5),
    }),
  ).toBeUndefined()
})

test('sets HEAD request body to undefined', () => {
  expect(
    pruneGetRequestBody({
      method: 'HEAD',
    }),
  ).toBeUndefined()

  expect(
    pruneGetRequestBody({
      method: 'HEAD',
      body: new ArrayBuffer(5),
    }),
  ).toBeUndefined()
})

test('ignores requests of the other methods than GET', () => {
  const body = new TextEncoder().encode('hello world')
  expect(
    pruneGetRequestBody({
      method: 'POST',
      body,
    }),
  ).toEqual(body)

  expect(
    pruneGetRequestBody({
      method: 'PUT',
      body,
    }),
  ).toEqual(body)
})


================================================
FILE: src/browser/utils/pruneGetRequestBody.ts
================================================
import type { ServiceWorkerIncomingRequest } from '../setupWorker/glossary'

type Input = Pick<ServiceWorkerIncomingRequest, 'method' | 'body'>

/**
 * Ensures that an empty GET request body is always represented as `undefined`.
 */
export function pruneGetRequestBody(
  request: Input,
): ServiceWorkerIncomingRequest['body'] {
  // Force HEAD/GET request body to always be empty.
  // The worker reads any request's body as ArrayBuffer,
  // and you cannot re-construct a GET/HEAD Request
  // with an ArrayBuffer, even if empty. Also note that
  // "request.body" is always undefined in the worker.
  if (['HEAD', 'GET'].includes(request.method)) {
    return undefined
  }

  return request.body
}


================================================
FILE: src/browser/utils/supports.ts
================================================
/**
 * Checks if the Service Worker API is supproted and available
 * in the current browsing context.
 */
export function supportsServiceWorker(): boolean {
  return (
    typeof navigator !== 'undefined' &&
    'serviceWorker' in navigator &&
    typeof location !== 'undefined' &&
    location.protocol !== 'file:'
  )
}

/**
 * Returns a boolean indicating whether the current browser
 * supports `ReadableStream` as a `Transferable` when posting
 * messages.
 */
export function supportsReadableStreamTransfer() {
  try {
    const stream = new ReadableStream({
      start: (controller) => controller.close(),
    })
    const message = new MessageChannel()
    message.port1.postMessage(stream, [stream])
    return true
  } catch {
    return false
  }
}


================================================
FILE: src/browser/utils/workerChannel.ts
================================================
import { invariant } from 'outvariant'
import { Emitter, TypedEvent } from 'rettime'
import { isObject } from '~/core/utils/internal/isObject'
import type { StringifiedResponse } from '../setupWorker/glossary'
import { supportsServiceWorker } from '../utils/supports'

export interface WorkerChannelOptions {
  worker: Promise<ServiceWorker>
}

export type WorkerChannelEventMap = {
  REQUEST: WorkerEvent<IncomingWorkerRequest>
  RESPONSE: WorkerEvent<IncomingWorkerResponse>
  MOCKING_ENABLED: WorkerEvent<{
    client: {
      id: string
      frameType: string
    }
  }>
  INTEGRITY_CHECK_RESPONSE: WorkerEvent<{
    packageVersion: string
    checksum: string
  }>
  KEEPALIVE_RESPONSE: TypedEvent<never>
}

/**
 * Request representation received from the worker message event.
 */
export interface IncomingWorkerRequest
  extends Omit<
    Request,
    | 'text'
    | 'body'
    | 'json'
    | 'blob'
    | 'arrayBuffer'
    | 'formData'
    | 'clone'
    | 'signal'
    | 'isHistoryNavigation'
    | 'isReloadNavigation'
  > {
  /**
   * Unique ID of the request generated once the request is
   * intercepted by the "fetch" event in the Service Worker.
   */
  id: string
  interceptedAt: number
  body?: ArrayBuffer | null
}

type IncomingWorkerResponse = {
  isMockedResponse: boolean
  request: IncomingWorkerRequest
  response: Pick<
    Response,
    'type' | 'ok' | 'status' | 'statusText' | 'body' | 'headers' | 'redirected'
  >
}

export type WorkerEventResponse = {
  MOCK_RESPONSE: [
    data: StringifiedResponse,
    transfer?: [ReadableStream<Uint8Array>],
  ]
  PASSTHROUGH: []
}

const SUPPORTS_SERVICE_WORKER = supportsServiceWorker()

export class WorkerEvent<
  DataType,
  ReturnType = any,
  EventType extends string = string,
> extends TypedEvent<DataType, ReturnType, EventType> {
  #workerEvent: MessageEvent

  constructor(workerEvent: MessageEvent) {
    const type = workerEvent.data.type as EventType
    const data = workerEvent.data.payload as DataType

    /**
     * @note This is the only place we're mapping { type, payload }
     * message structure of the worker. The client references the
     * payload via `event.data`.
     */
    super(
      // @ts-expect-error Troublesome `TypedEvent` extension.
      type,
      { data },
    )
    this.#workerEvent = workerEvent
  }

  get ports() {
    return this.#workerEvent.ports
  }

  /**
   * Reply directly to this event using its `MessagePort`.
   */
  public postMessage<Type extends keyof WorkerEventResponse>(
    type: Type,
    ...rest: WorkerEventResponse[Type]
  ): void {
    this.#workerEvent.ports[0].postMessage(
      { type, data: rest[0] },
      { transfer: rest[1] },
    )
  }
}

/**
 * Map of the events that can be sent to the Service Worker
 * from any execution context.
 */
type OutgoingWorkerEvents =
  | 'MOCK_ACTIVATE'
  | 'INTEGRITY_CHECK_REQUEST'
  | 'KEEPALIVE_REQUEST'
  | 'CLIENT_CLOSED'

export class WorkerChannel extends Emitter<WorkerChannelEventMap> {
  constructor(protected readonly options: WorkerChannelOptions) {
    super()

    if (!SUPPORTS_SERVICE_WORKER) {
      return
    }

    navigator.serviceWorker.addEventListener('message', async (event) => {
      const worker = await this.options.worker

      if (event.source != null && event.source !== worker) {
        return
      }

      if (event.data && isObject(event.data) && 'type' in event.data) {
        this.emit(new WorkerEvent<any, any, any>(event))
      }
    })
  }

  /**
   * Send data to the Service Worker controlling this client.
   * This triggers the `message` event listener on ServiceWorkerGlobalScope.
   */
  public postMessage(type: OutgoingWorkerEvents): void {
    invariant(
      SUPPORTS_SERVICE_WORKER,
      'Failed to post message on a WorkerChannel: the Service Worker API is unavailable in this context. This is likely an issue with MSW. Please report it on GitHub: https://github.com/mswjs/msw/issues',
    )

    this.options.worker.then((worker) => {
      worker.postMessage(type)
    })
  }
}


================================================
FILE: src/core/HttpResponse.test.ts
================================================
/**
 * @vitest-environment node
 */
import { TextEncoder } from 'util'
import { HttpResponse, kDefaultContentType } from './HttpResponse'

it('creates a plain response', async () => {
  const response = new HttpResponse(null, { status: 301 })
  expect(response.status).toBe(301)
  expect(response.statusText).toBe('Moved Permanently')
  expect(response.body).toBe(null)
  await expect(response.text()).resolves.toBe('')
  expect(Object.fromEntries(response.headers.entries())).toEqual({})
})

it('supports non-configurable status codes', () => {
  expect(new HttpResponse(null, { status: 101 })).toHaveProperty('status', 101)
})

describe('HttpResponse.text()', () => {
  it('creates a text response', async () => {
    const response = HttpResponse.text('hello world', { status: 201 })

    expect(response.status).toBe(201)
    expect(response.statusText).toBe('Created')
    expect(response.body).toBeInstanceOf(ReadableStream)
    await expect(response.text()).resolves.toBe('hello world')
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '11',
      'content-type': 'text/plain',
    })
    expect(kDefaultContentType in response).toBe(true)
  })

  it('creates a text response with special characters', async () => {
    const response = HttpResponse.text('안녕 세상', { status: 201 })

    expect(response.status).toBe(201)
    expect(response.statusText).toBe('Created')
    expect(response.body).toBeInstanceOf(ReadableStream)
    await expect(response.text()).resolves.toBe('안녕 세상')
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '13',
      'content-type': 'text/plain',
    })
  })

  it('allows overriding the "Content-Type" response header', async () => {
    const response = HttpResponse.text('hello world', {
      headers: { 'Content-Type': 'text/plain; charset=utf-8' },
    })

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    await expect(response.text()).resolves.toBe('hello world')
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '11',
      'content-type': 'text/plain; charset=utf-8',
    })
    expect(kDefaultContentType in response).toBe(false)
  })

  it('allows overriding the "Content-Length" response header', async () => {
    const response = HttpResponse.text('hello world', {
      headers: { 'Content-Length': '32' },
    })

    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '32',
      'content-type': 'text/plain',
    })
  })
})

describe('HttpResponse.json()', () => {
  it('creates a json response given an object', async () => {
    const response = HttpResponse.json({ firstName: 'John' })

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    expect(await response.json()).toEqual({ firstName: 'John' })
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '20',
      'content-type': 'application/json',
    })
    expect(kDefaultContentType in response).toBe(true)
  })

  it('creates a json response given an object with special characters', async () => {
    const response = HttpResponse.json({ firstName: '제로' })

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    expect(await response.json()).toEqual({ firstName: '제로' })
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '22',
      'content-type': 'application/json',
    })
  })

  it('creates a json response given an array', async () => {
    const response = HttpResponse.json([1, 2, 3])

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    expect(await response.json()).toEqual([1, 2, 3])
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '7',
      'content-type': 'application/json',
    })
  })

  it('creates a json response given a plain string', async () => {
    const response = HttpResponse.json(`"hello"`)

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    expect(await response.json()).toBe(`"hello"`)
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '11',
      'content-type': 'application/json',
    })
  })

  it('creates a json response given a number', async () => {
    const response = HttpResponse.json(123)

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    expect(await response.json()).toBe(123)
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '3',
      'content-type': 'application/json',
    })
  })

  it('creates a json response given a json ReadableStream', async () => {
    const encoder = new TextEncoder()
    const stream = new ReadableStream({
      start(controller) {
        controller.enqueue(encoder.encode(`{"firstName`))
        controller.enqueue(encoder.encode(`":"John`))
        controller.enqueue(encoder.encode(`"}`))
        controller.close()
      },
    })
    const response = HttpResponse.json(stream)

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    // A ReadableStream instance is not a valid body init
    // for the "Response.json()" static method. It gets serialized
    // into a plain object.
    expect(await response.json()).toEqual({})
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '2',
      'content-type': 'application/json',
    })
  })

  it('allows overriding the "Content-Type" response header', async () => {
    const response = HttpResponse.json(
      { a: 1 },
      {
        headers: {
          'Content-Type': 'application/hal+json',
        },
      },
    )

    expect(kDefaultContentType in response).toBe(false)
    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    expect(await response.json()).toEqual({ a: 1 })
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '7',
      'content-type': 'application/hal+json',
    })
  })

  it('allows overriding the "Content-Length" response header', async () => {
    const response = HttpResponse.json(
      { a: 1 },
      {
        headers: { 'Content-Length': '32' },
      },
    )

    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '32',
      'content-type': 'application/json',
    })
  })
})

describe('HttpResponse.xml()', () => {
  it('creates an xml response', async () => {
    const response = HttpResponse.xml('<user name="John" />')

    expect(kDefaultContentType in response).toBe(true)
    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    await expect(response.text()).resolves.toBe('<user name="John" />')
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-type': 'text/xml',
    })
    expect(kDefaultContentType in response).toBe(true)
  })

  it('allows overriding the "Content-Type" response header', async () => {
    const response = HttpResponse.xml('<user name="John" />', {
      headers: {
        'Content-Type': 'text/xml; charset=utf-8',
      },
    })

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    await expect(response.text()).resolves.toBe('<user name="John" />')
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-type': 'text/xml; charset=utf-8',
    })
    expect(kDefaultContentType in response).toBe(false)
  })
})

describe('HttpResponse.html()', () => {
  it('creates an html response', async () => {
    const response = HttpResponse.html('<p class="author">Jane Doe</p>')

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    await expect(response.text()).resolves.toBe(
      '<p class="author">Jane Doe</p>',
    )
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-type': 'text/html',
    })
    expect(kDefaultContentType in response).toBe(true)
  })

  it('allows overriding the "Content-Type" response header', async () => {
    const response = HttpResponse.html('<p class="author">Jane Doe</p>', {
      headers: {
        'Content-Type': 'text/html; charset=utf-8',
      },
    })

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)
    await expect(response.text()).resolves.toBe(
      '<p class="author">Jane Doe</p>',
    )
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-type': 'text/html; charset=utf-8',
    })
    expect(kDefaultContentType in response).toBe(false)
  })
})

describe('HttpResponse.arrayBuffer()', () => {
  it('creates an array buffer response', async () => {
    const buffer = new TextEncoder().encode('hello world')
    const response = HttpResponse.arrayBuffer(buffer)

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)

    const responseData = await response.arrayBuffer()
    expect(responseData).toEqual(buffer.buffer)
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '11',
      'content-type': 'application/octet-stream',
    })
    expect(kDefaultContentType in response).toBe(true)
  })

  it('allows overriding the "Content-Type" response header', async () => {
    const buffer = new TextEncoder().encode('hello world')
    const response = HttpResponse.arrayBuffer(buffer, {
      headers: {
        'Content-Type': 'text/plain; charset=utf-8',
      },
    })

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)

    const responseData = await response.arrayBuffer()
    expect(responseData).toEqual(buffer.buffer)
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '11',
      'content-type': 'text/plain; charset=utf-8',
    })
    expect(kDefaultContentType in response).toBe(false)
  })

  it('creates an array buffer response from a shared array buffer', async () => {
    const arrayBuffer = new TextEncoder().encode('hello world')

    // Copy the data from the array buffer to a shared array buffer
    const sharedBuffer = new SharedArrayBuffer(11)
    const sharedView = new Uint8Array(sharedBuffer)
    sharedView.set(arrayBuffer)

    const response = HttpResponse.arrayBuffer(sharedBuffer)

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)

    const responseData = await response.arrayBuffer()
    expect(responseData).toEqual(arrayBuffer.buffer)
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '11',
      'content-type': 'application/octet-stream',
    })
  })

  it('allows overriding the "Content-Type" response header for shared array buffers', async () => {
    const arrayBuffer = new TextEncoder().encode('hello world')

    // Copy the data from the array buffer to a shared array buffer
    const sharedBuffer = new SharedArrayBuffer(11)
    const sharedView = new Uint8Array(sharedBuffer)
    sharedView.set(arrayBuffer)

    const response = HttpResponse.arrayBuffer(sharedBuffer, {
      headers: {
        'Content-Type': 'text/plain; charset=utf-8',
      },
    })

    expect(response.status).toBe(200)
    expect(response.statusText).toBe('OK')
    expect(response.body).toBeInstanceOf(ReadableStream)

    const responseData = await response.arrayBuffer()
    expect(responseData).toEqual(arrayBuffer.buffer)
    expect(Object.fromEntries(response.headers.entries())).toEqual({
      'content-length': '11',
      'content-type': 'text/plain; charset=utf-8',
    })
    expect(kDefaultContentType in response).toBe(false)
  })
})

it('creates a form data response', async () => {
  const formData = new FormData()
  formData.append('firstName', 'John')
  const response = HttpResponse.formData(formData)

  expect(response.status).toBe(200)
  expect(response.statusText).toBe('OK')
  expect(response.body).toBeInstanceOf(ReadableStream)

  const responseData = await response.formData()
  expect(responseData.get('firstName')).toBe('John')
  expect(Object.fromEntries(response.headers.entries())).toEqual({
    'content-type': expect.stringContaining(
      'multipart/form-data; boundary=----',
    ),
  })
})


================================================
FILE: src/core/HttpResponse.ts
================================================
import { FetchResponse } from '@mswjs/interceptors'
import type { DefaultBodyType, JsonBodyType } from './handlers/RequestHandler'
import type { NoInfer } from './typeUtils'
import {
  decorateResponse,
  normalizeResponseInit,
} from './utils/HttpResponse/decorators'

export interface HttpResponseInit extends ResponseInit {
  type?: ResponseType
}

export const bodyType: unique symbol = Symbol('bodyType')
export type DefaultUnsafeFetchResponse = Response & {
  [bodyType]?: never
}

export interface StrictRequest<BodyType extends JsonBodyType> extends Request {
  json(): Promise<BodyType>
  clone(): StrictRequest<BodyType>
}

/**
 * Opaque `Response` type that supports strict body type.
 *
 * @deprecated Please use {@link HttpResponse} instead.
 */
export type StrictResponse<BodyType extends DefaultBodyType> =
  HttpResponse<BodyType>

export const kDefaultContentType = Symbol.for('kDefaultContentType')

/**
 * A drop-in replacement for the standard `Response` class
 * to allow additional features, like mocking the response `Set-Cookie` header.
 *
 * @example
 * new HttpResponse('Hello world', { status: 201 })
 * HttpResponse.json({ name: 'John' })
 * HttpResponse.formData(form)
 *
 * @see {@link https://mswjs.io/docs/api/http-response `HttpResponse` API reference}
 */
export class HttpResponse<
  BodyType extends DefaultBodyType,
> extends FetchResponse {
  readonly [bodyType]: BodyType = null as any

  constructor(body?: NoInfer<BodyType> | null, init?: HttpResponseInit) {
    const responseInit = normalizeResponseInit(init)
    super(body as BodyInit, responseInit)
    decorateResponse(this, responseInit)
  }

  static error(): HttpResponse<any> {
    return super.error() as HttpResponse<any>
  }

  /**
   * Create a `Response` with a `Content-Type: "text/plain"` body.
   * @example
   * HttpResponse.text('hello world')
   * HttpResponse.text('Error', { status: 500 })
   */
  static text<BodyType extends string>(
    body?: NoInfer<BodyType> | null,
    init?: HttpResponseInit,
  ): HttpResponse<BodyType> {
    const responseInit = normalizeResponseInit(init)
    const hasExplicitContentType = responseInit.headers.has('Content-Type')

    if (!hasExplicitContentType) {
      responseInit.headers.set('Content-Type', 'text/plain')
    }

    // Automatically set the "Content-Length" response header
    // for non-empty text responses. This enforces consistency and
    // brings mocked responses closer to production.
    if (!responseInit.headers.has('Content-Length')) {
      responseInit.headers.set(
        'Content-Length',
        body ? new Blob([body]).size.toString() : '0',
      )
    }

    const response = new HttpResponse(body, responseInit)

    if (!hasExplicitContentType) {
      Object.defineProperty(response, kDefaultContentType, {
        value: true,
        enumerable: false,
      })
    }

    return response
  }

  /**
   * Create a `Response` with a `Content-Type: "application/json"` body.
   * @example
   * HttpResponse.json({ firstName: 'John' })
   * HttpResponse.json({ error: 'Not Authorized' }, { status: 401 })
   */
  static json<BodyType extends JsonBodyType>(
    body?: NoInfer<BodyType> | null | undefined,
    init?: HttpResponseInit,
  ): HttpResponse<BodyType> {
    const responseInit = normalizeResponseInit(init)
    const hasExplicitContentType = responseInit.headers.has('Content-Type')

    if (!hasExplicitContentType) {
      responseInit.headers.set('Content-Type', 'application/json')
    }

    /**
     * @note TypeScript is incorrect here.
     * Stringifying undefined will return undefined.
     */
    const responseText = JSON.stringify(body) as string | undefined

    if (!responseInit.headers.has('Content-Length')) {
      responseInit.headers.set(
        'Content-Length',
        responseText ? new Blob([responseText]).size.toString() : '0',
      )
    }

    const response = new HttpResponse(responseText, responseInit)

    if (!hasExplicitContentType) {
      Object.defineProperty(response, kDefaultContentType, {
        value: true,
        enumerable: false,
      })
    }

    return response as HttpResponse<BodyType>
  }

  /**
   * Create a `Response` with a `Content-Type: "application/xml"` body.
   * @example
   * HttpResponse.xml(`<user name="John" />`)
   * HttpResponse.xml(`<article id="abc-123" />`, { status: 201 })
   */
  static xml<BodyType extends string>(
    body?: BodyType | null,
    init?: HttpResponseInit,
  ): HttpResponse<BodyType> {
    const responseInit = normalizeResponseInit(init)
    const hasExplicitContentType = responseInit.headers.has('Content-Type')

    if (!hasExplicitContentType) {
      responseInit.headers.set('Content-Type', 'text/xml')
    }

    const response = new HttpResponse(body, responseInit)

    if (!hasExplicitContentType) {
      Object.defineProperty(response, kDefaultContentType, {
        value: true,
        enumerable: false,
      })
    }

    return response as HttpResponse<BodyType>
  }

  /**
   * Create a `Response` with a `Content-Type: "text/html"` body.
   * @example
   * HttpResponse.html(`<p class="author">Jane Doe</p>`)
   * HttpResponse.html(`<main id="abc-123">Main text</main>`, { status: 201 })
   */
  static html<BodyType extends string>(
    body?: BodyType | null,
    init?: HttpResponseInit,
  ): HttpResponse<BodyType> {
    const responseInit = normalizeResponseInit(init)
    const hasExplicitContentType = responseInit.headers.has('Content-Type')

    if (!hasExplicitContentType) {
      responseInit.headers.set('Content-Type', 'text/html')
    }

    const response = new HttpResponse(body, responseInit)

    if (!hasExplicitContentType) {
      Object.defineProperty(response, kDefaultContentType, {
        value: true,
        enumerable: false,
      })
    }

    return response as HttpResponse<BodyType>
  }

  /**
   * Create a `Response` with an `ArrayBuffer` body.
   * @example
   * const buffer = new ArrayBuffer(3)
   * const view = new Uint8Array(buffer)
   * view.set([1, 2, 3])
   *
   * HttpResponse.arrayBuffer(buffer)
   */
  static arrayBuffer<BodyType extends ArrayBuffer | SharedArrayBuffer>(
    body?: BodyType,
    init?: HttpResponseInit,
  ): HttpResponse<BodyType> {
    const responseInit = normalizeResponseInit(init)
    const hasExplicitContentType = responseInit.headers.has('Content-Type')

    if (!hasExplicitContentType) {
      responseInit.headers.set('Content-Type', 'application/octet-stream')
    }

    if (body && !responseInit.headers.has('Content-Length')) {
      responseInit.headers.set('Content-Length', body.byteLength.toString())
    }

    const response = new HttpResponse(body, responseInit)

    if (!hasExplicitContentType) {
      Object.defineProperty(response, kDefaultContentType, {
        value: true,
        enumerable: false,
      })
    }

    return response as HttpResponse<BodyType>
  }

  /**
   * Create a `Response` with a `FormData` body.
   * @example
   * const data = new FormData()
   * data.set('name', 'Alice')
   *
   * HttpResponse.formData(data)
   */
  static formData(
    body?: FormData,
    init?: HttpResponseInit,
  ): HttpResponse<FormData> {
    return new HttpResponse(body, normalizeResponseInit(init))
  }
}


================================================
FILE: src/core/SetupApi.ts
================================================
import { invariant } from 'outvariant'
import { EventMap, Emitter } from 'strict-event-emitter'
import { RequestHandler } from './handlers/RequestHandler'
import { LifeCycleEventEmitter } from './sharedOptions'
import { devUtils } from './utils/internal/devUtils'
import { pipeEvents } from './utils/internal/pipeEvents'
import { toReadonlyArray } from './utils/internal/toReadonlyArray'
import { Disposable } from './utils/internal/Disposable'
import type { WebSocketHandler } from './handlers/WebSocketHandler'

export abstract class HandlersController {
  abstract prepend(
    runtimeHandlers: Array<RequestHandler | WebSocketHandler>,
  ): void
  abstract reset(nextHandles: Array<RequestHandler | WebSocketHandler>): void
  abstract currentHandlers(): Array<RequestHandler | WebSocketHandler>
}

export class InMemoryHandlersController implements HandlersController {
  private handlers: Array<RequestHandler | WebSocketHandler>

  constructor(
    private initialHandlers: Array<RequestHandler | WebSocketHandler>,
  ) {
    this.handlers = [...initialHandlers]
  }

  public prepend(
    runtimeHandles: Array<RequestHandler | WebSocketHandler>,
  ): void {
    this.handlers.unshift(...runtimeHandles)
  }

  public reset(nextHandlers: Array<RequestHandler | WebSocketHandler>): void {
    this.handlers =
      nextHandlers.length > 0 ? [...nextHandlers] : [...this.initialHandlers]
  }

  public currentHandlers(): Array<RequestHandler | WebSocketHandler> {
    return this.handlers
  }
}

/**
 * Generic class for the mock API setup.
 */
export abstract class SetupApi<EventsMap extends EventMap> extends Disposable {
  protected handlersController: HandlersController
  protected readonly emitter: Emitter<EventsMap>
  protected readonly publicEmitter: Emitter<EventsMap>

  public readonly events: LifeCycleEventEmitter<EventsMap>

  constructor(...initialHandlers: Array<RequestHandler | WebSocketHandler>) {
    super()

    invariant(
      this.validateHandlers(initialHandlers),
      devUtils.formatMessage(
        `Failed to apply given request handlers: invalid input. Did you forget to spread the request handlers Array?`,
      ),
    )

    this.handlersController = new InMemoryHandlersController(initialHandlers)

    this.emitter = new Emitter<EventsMap>()
    this.publicEmitter = new Emitter<EventsMap>()
    pipeEvents(this.emitter, this.publicEmitter)

    this.events = this.createLifeCycleEvents()

    this.subscriptions.push(() => {
      this.emitter.removeAllListeners()
      this.publicEmitter.removeAllListeners()
    })
  }

  private validateHandlers(handlers: ReadonlyArray<unknown>): boolean {
    // Guard against incorrect call signature of the setup API.
    return handlers.every((handler) => !Array.isArray(handler))
  }

  public use(
    ...runtimeHandlers: Array<RequestHandler | WebSocketHandler>
  ): void {
    invariant(
      this.validateHandlers(runtimeHandlers),
      devUtils.formatMessage(
        `Failed to call "use()" with the given request handlers: invalid input. Did you forget to spread the array of request handlers?`,
      ),
    )

    this.handlersController.prepend(runtimeHandlers)
  }

  public restoreHandlers(): void {
    this.handlersController.currentHandlers().forEach((handler) => {
      if ('isUsed' in handler) {
        handler.isUsed = false
      }
    })
  }

  public resetHandlers(
    ...nextHandlers: Array<RequestHandler | WebSocketHandler>
  ): void {
    this.handlersController.reset(nextHandlers)
  }

  public listHandlers(): ReadonlyArray<RequestHandler | WebSocketHandler> {
    return toReadonlyArray(this.handlersController.currentHandlers())
  }

  private createLifeCycleEvents(): LifeCycleEventEmitter<EventsMap> {
    return {
      on: (...args: any[]) => {
        return (this.publicEmitter.on as any)(...args)
      },
      removeListener: (...args: any[]) => {
        return (this.publicEmitter.removeListener as any)(...args)
      },
      removeAllListeners: (...args: any[]) => {
        return this.publicEmitter.removeAllListeners(...args)
      },
    }
  }
}


================================================
FILE: src/core/bypass.test.ts
================================================
/**
 * @vitest-environment jsdom
 */
import { bypass } from './bypass'

it('returns bypassed request given a request url string', async () => {
  const request = bypass('https://api.example.com/resource')

  // Relative URLs are rebased against the current location.
  expect(request.method).toBe('GET')
  expect(request.url).toBe('https://api.example.com/resource')
  expect(Array.from(request.headers)).toEqual([['accept', 'msw/passthrough']])
})

it('returns bypassed request given a request url', async () => {
  const request = bypass(new URL('/resource', 'https://api.example.com'))

  expect(request.url).toBe('https://api.example.com/resource')
  expect(Array.from(request.headers)).toEqual([['accept', 'msw/passthrough']])
})

it('returns bypassed request given request instance', async () => {
  const original = new Request('http://localhost/resource', {
    method: 'POST',
    headers: {
      accept: '*/*',
      'X-My-Header': 'value',
    },
    body: 'hello world',
  })
  const request = bypass(original)

  expect(request.method).toBe('POST')
  expect(request.url).toBe('http://localhost/resource')

  const bypassedRequestBody = await request.text()
  expect(original.bodyUsed).toBe(false)

  expect(bypassedRequestBody).toEqual(await original.text())
  expect(Array.from(request.headers)).toEqual([
    ['accept', '*/*, msw/passthrough'],
    ['content-type', 'text/plain;charset=UTF-8'],
    ['x-my-header', 'value'],
  ])
})

it('allows modifying the bypassed request instance', async () => {
  const original = new Request('http://localhost/resource', {
    method: 'POST',
    body: 'hello world',
  })
  const request = bypass(original, {
    method: 'PUT',
    headers: { 'x-modified-header': 'yes' },
  })

  expect(request.method).toBe('PUT')
  expect(Array.from(request.headers)).toEqual([
    ['accept', 'msw/passthrough'],
    ['x-modified-header', 'yes'],
  ])
  expect(original.bodyUsed).toBe(false)
  expect(request.bodyUsed).toBe(false)

  expect(await request.text()).toBe('hello world')
  expect(original.bodyUsed).toBe(false)
})

it('supports bypassing "keepalive: true" requests', async () => {
  const original = new Request('http://localhost/resource', {
    method: 'POST',
    keepalive: true,
  })
  const request = bypass(original)

  expect(request.method).toBe('POST')
  expect(request.url).toBe('http://localhost/resource')
  expect(request.body).toBeNull()
  expect(Array.from(request.headers)).toEqual([['accept', 'msw/passthrough']])
})


================================================
FILE: src/core/bypass.ts
================================================
import { invariant } from 'outvariant'

export type BypassRequestInput = string | URL | Request

/**
 * Creates a `Request` instance that will always be ignored by MSW.
 *
 * @example
 * import { bypass } from 'msw'
 *
 * fetch(bypass('/resource'))
 * fetch(bypass(new URL('/resource', 'https://example.com)))
 * fetch(bypass(new Request('https://example.com/resource')))
 *
 * @see {@link https://mswjs.io/docs/api/bypass `bypass()` API reference}
 */
export function bypass(input: BypassRequestInput, init?: RequestInit): Request {
  // Always create a new Request instance.
  // This way, the "init" modifications will propagate
  // to the bypass request instance automatically.
  const request = new Request(
    // If given a Request instance, clone it not to exhaust
    // the original request's body.
    input instanceof Request ? input.clone() : input,
    init,
  )

  invariant(
    !request.bodyUsed,
    'Failed to create a bypassed request to "%s %s": given request instance already has its body read. Make sure to clone the intercepted request if you wish to read its body before bypassing it.',
    request.method,
    request.url,
  )

  const requestClone = request.clone()

  /**
   * Send the internal request header that would instruct MSW
   * to perform this request as-is, ignoring any matching handlers.
   * @note Use the `accept` header to support scenarios when the
   * request cannot have headers (e.g. `sendBeacon` requests).
   */
  requestClone.headers.append('accept', 'msw/passthrough')

  return requestClone
}


================================================
FILE: src/core/delay.ts
================================================
import { isNodeProcess } from 'is-node-process'
import { hasRefCounted } from './utils/internal/hasRefCounted'

export const SET_TIMEOUT_MAX_ALLOWED_INT = 2147483647
export const MIN_SERVER_RESPONSE_TIME = 100
export const MAX_SERVER_RESPONSE_TIME = 400
export const NODE_SERVER_RESPONSE_TIME = 5

function getRealisticResponseTime(): number {
  if (isNodeProcess()) {
    return NODE_SERVER_RESPONSE_TIME
  }

  return Math.floor(
    Math.random() * (MAX_SERVER_RESPONSE_TIME - MIN_SERVER_RESPONSE_TIME) +
      MIN_SERVER_RESPONSE_TIME,
  )
}

export type DelayMode = 'real' | 'infinite'

/**
 * Delays the response by the given duration (ms).
 *
 * @example
 * await delay() // emulate realistic server response time
 * await delay(1200) // delay response by 1200ms
 * await delay('infinite') // delay response infinitely
 *
 * @see {@link https://mswjs.io/docs/api/delay `delay()` API reference}
 */
export async function delay(
  durationOrMode?: DelayMode | number,
): Promise<void> {
  let delayTime: number

  if (typeof durationOrMode === 'string') {
    switch (durationOrMode) {
      case 'infinite': {
        // Using `Infinity` as a delay value executes the response timeout immediately.
        // Instead, use the maximum allowed integer for `setTimeout`.
        delayTime = SET_TIMEOUT_MAX_ALLOWED_INT
        break
      }
      case 'real': {
        delayTime = getRealisticResponseTime()
        break
      }
      default: {
        throw new Error(
          `Failed to delay a response: unknown delay mode "${durationOrMode}". Please make sure you provide one of the supported modes ("real", "infinite") or a number.`,
        )
      }
    }
  } else if (typeof durationOrMode === 'undefined') {
    // Use random realistic server response time when no explicit delay duration was provided.
    delayTime = getRealisticResponseTime()
  } else {
    // Guard against passing values like `Infinity` or `Number.MAX_VALUE`
    // as the response delay duration. They don't produce the result you may expect.
    if (durationOrMode > SET_TIMEOUT_MAX_ALLOWED_INT) {
      throw new Error(
        `Failed to delay a response: provided delay duration (${durationOrMode}) exceeds the maximum allowed duration for "setTimeout" (${SET_TIMEOUT_MAX_ALLOWED_INT}). This will cause the response to be returned immediately. Please use a number within the allowed range to delay the response by exact duration, or consider the "infinite" delay mode to delay the response indefinitely.`,
      )
    }

    delayTime = durationOrMode
  }

  return new Promise((resolve) => {
    const timeoutId = setTimeout(resolve, delayTime)

    if (
      delayTime === SET_TIMEOUT_MAX_ALLOWED_INT &&
      isNodeProcess() &&
      hasRefCounted(timeoutId)
    ) {
      // Prevent the process from hanging if this is the only active ref.
      timeoutId.unref()
    }
  })
}


================================================
FILE: src/core/getResponse.test.ts
================================================
// @vitest-environment node
import { http } from './http'
import { getResponse } from './getResponse'

it('returns undefined given empty headers array', async () => {
  await expect(
    getResponse([], new Request('http://localhost/')),
  ).resolves.toBeUndefined()
})

it('returns undefined given no matching handlers', async () => {
  await expect(
    getResponse(
      [http.get('/product', () => void 0)],
      new Request('http://localhost/user'),
    ),
  ).resolves.toBeUndefined()
})

it('returns undefined given a matching handler that returned no response', async () => {
  await expect(
    getResponse(
      [http.get('*/user', () => void 0)],
      new Request('http://localhost/user'),
    ),
  ).resolves.toBeUndefined()
})

it('returns undefined given a matching handler that returned explicit undefined', async () => {
  await expect(
    getResponse(
      [http.get('*/user', () => undefined)],
      new Request('http://localhost/user'),
    ),
  ).resolves.toBeUndefined()
})

it('returns the response returned from a matching handler', async () => {
  const response = await getResponse(
    [http.get('*/user', () => Response.json({ name: 'John' }))],
    new Request('http://localhost/user'),
  )

  expect(response?.status).toBe(200)
  expect(response?.headers.get('Content-Type')).toBe('application/json')
  await expect(response?.json()).resolves.toEqual({ name: 'John' })
})

it('returns the response from the first matching handler if multiple match', async () => {
  const response = await getResponse(
    [
      http.get('*/user', () => Response.json({ name: 'John' })),
      http.get('*/user', () => Response.json({ name: 'Kate' })),
    ],
    new Request('http://localhost/user'),
  )

  expect(response?.status).toBe(200)
  expect(response?.headers.get('Content-Type')).toBe('application/json')
  await expect(response?.json()).resolves.toEqual({ name: 'John' })
})

it('supports custom base url', async () => {
  const response = await getResponse(
    [http.get('/resource', () => new Response('hello world'))],
    new Request('https://localhost:3000/resource'),
    {
      baseUrl: 'https://localhost:3000/',
    },
  )

  expect(response?.status).toBe(200)
  await expect(response?.text()).resolves.toBe('hello world')
})


================================================
FILE: src/core/getResponse.ts
================================================
import { createRequestId } from '@mswjs/interceptors'
import type { RequestHandler } from './handlers/RequestHandler'
import {
  executeHandlers,
  type ResponseResolutionContext,
} from './utils/executeHandlers'

/**
 * Finds a response for the given request instance
 * in the array of request handlers.
 * @param handlers The array of request handlers.
 * @param request The `Request` instance.
 * @param resolutionContext Request resolution options.
 * @returns {Response} A mocked response, if any.
 */
export const getResponse = async (
  handlers: Array<RequestHandler>,
  request: Request,
  resolutionContext?: ResponseResolutionContext,
): Promise<Response | undefined> => {
  const result = await executeHandlers({
    request,
    requestId: createRequestId(),
    handlers,
    resolutionContext,
  })

  return result?.response
}


================================================
FILE: src/core/graphql.test.ts
================================================
import { graphql } from './graphql'

test('exports supported GraphQL operation types', () => {
  expect(graphql).toBeDefined()
  expect(Object.keys(graphql)).toEqual([
    'query',
    'mutation',
    'operation',
    'link',
  ])
})


================================================
FILE: src/core/graphql.ts
================================================
import type { OperationTypeNode } from 'graphql'
import {
  ResponseResolver,
  RequestHandlerOptions,
} from './handlers/RequestHandler'
import {
  GraphQLHandler,
  GraphQLVariables,
  GraphQLOperationType,
  GraphQLResolverExtras,
  GraphQLResponseBody,
  GraphQLQuery,
  GraphQLPredicate,
} from './handlers/GraphQLHandler'
import type { Path } from './utils/matching/matchRequestUrl'

export type GraphQLRequestHandler = <
  Query extends GraphQLQuery = GraphQLQuery,
  Variables extends GraphQLVariables = GraphQLVariables,
>(
  predicate: GraphQLPredicate<Query, Variables>,
  resolver: GraphQLResponseResolver<
    [Query] extends [never] ? GraphQLQuery : Query,
    Variables
  >,
  options?: RequestHandlerOptions,
) => GraphQLHandler

export type GraphQLOperationHandler = <
  Query extends GraphQLQuery = GraphQLQuery,
  Variables extends GraphQLVariables = GraphQLVariables,
>(
  resolver: GraphQLResponseResolver<
    [Query] extends [never] ? GraphQLQuery : Query,
    Variables
  >,
  options?: RequestHandlerOptions,
) => GraphQLHandler

export type GraphQLResponseResolver<
  Query extends GraphQLQuery = GraphQLQuery,
  Variables extends GraphQLVariables = GraphQLVariables,
> = ResponseResolver<
  GraphQLResolverExtras<Variables>,
  null,
  GraphQLResponseBody<[Query] extends [never] ? GraphQLQuery : Query>
>

function createScopedGraphQLHandler(
  operationType: GraphQLOperationType,
  url: Path,
): GraphQLRequestHandler {
  return (predicate, resolver, options = {}) => {
    return new GraphQLHandler(operationType, predicate, url, resolver, options)
  }
}

function createGraphQLOperationHandler(url: Path): GraphQLOperationHandler {
  return (resolver, options) => {
    return new GraphQLHandler('all', new RegExp('.*'), url, resolver, options)
  }
}

export interface GraphQLLinkHandlers {
  query: GraphQLRequestHandler
  mutation: GraphQLRequestHandler
  operation: GraphQLOperationHandler
}

/**
 * A namespace to intercept and mock GraphQL operations
 *
 * @example
 * graphql.query('GetUser', resolver)
 * graphql.mutation('DeletePost', resolver)
 *
 * @see {@link https://mswjs.io/docs/api/graphql `graphql` API reference}
 */
export const graphql = {
  /**
   * Intercepts a GraphQL query by a given name.
   *
   * @example
   * graphql.query('GetUser', () => {
   *   return HttpResponse.json({ data: { user: { name: 'John' } } })
   * })
   *
   * @see {@link https://mswjs.io/docs/api/graphql#graphqlqueryqueryname-resolver `graphql.query()` API reference}
   */
  query: createScopedGraphQLHandler('query' as OperationTypeNode, '*'),

  /**
   * Intercepts a GraphQL mutation by its name.
   *
   * @example
   * graphql.mutation('SavePost', () => {
   *   return HttpResponse.json({ data: { post: { id: 'abc-123 } } })
   * })
   *
   * @see {@link https://mswjs.io/docs/api/graphql#graphqlmutationmutationname-resolver `graphql.query()` API reference}
   *
   */
  mutation: createScopedGraphQLHandler('mutation' as OperationTypeNode, '*'),

  /**
   * Intercepts any GraphQL operation, regardless of its type or name.
   *
   * @example
   * graphql.operation(() => {
   *   return HttpResponse.json({ data: { name: 'John' } })
   * })
   *
   * @see {@link https://mswjs.io/docs/api/graphql#graphqloperationresolver `graphql.operation()` API reference}
   */
  operation: createGraphQLOperationHandler('*'),

  /**
   * Intercepts GraphQL operations scoped by the given URL.
   *
   * @example
   * const github = graphql.link('https://api.github.com/graphql')
   * github.query('GetRepo', resolver)
   *
   * @see {@link https://mswjs.io/docs/api/graphql#graphqllinkurl `graphql.link()` API reference}
   */
  link(url: Path): GraphQLLinkHandlers {
    return {
      operation: createGraphQLOperationHandler(url),
      query: createScopedGraphQLHandler('query' as OperationTypeNode, url),
      mutation: createScopedGraphQLHandler(
        'mutation' as OperationTypeNode,
        url,
      ),
    }
  },
}


================================================
FILE: src/core/handlers/GraphQLHandler.test.ts
================================================
// @vitest-environment jsdom
import { createRequestId, encodeBuffer } from '@mswjs/interceptors'
import { OperationTypeNode, parse } from 'graphql'
import {
  GraphQLHandler,
  GraphQLRequestBody,
  GraphQLResolverExtras,
  isDocumentNode,
} from './GraphQLHandler'
import { HttpResponse } from '../HttpResponse'
import { ResponseResolver } from './RequestHandler'

const resolver: ResponseResolver<GraphQLResolverExtras<{ userId: string }>> = ({
  variables,
}) => {
  return HttpResponse.json({
    data: {
      user: {
        id: variables.userId,
      },
    },
  })
}

function createGetGraphQLRequest(
  body: GraphQLRequestBody<any>,
  graphqlEndpoint = 'https://example.com',
) {
  const requestUrl = new URL(graphqlEndpoint)
  requestUrl.searchParams.set('query', body?.query)
  requestUrl.searchParams.set('variables', JSON.stringify(body?.variables))
  return new Request(requestUrl)
}

function createPostGraphQLRequest(
  body: GraphQLRequestBody<any>,
  graphqlEndpoint = 'https://example.com',
) {
  return new Request(new URL(graphqlEndpoint), {
    method: 'POST',
    headers: new Headers({ 'Content-Type': 'application/json' }),
    body: encodeBuffer(JSON.stringify(body)),
  })
}

const GET_USER = `
  query GetUser {
    user {
      id
    }
  }
`

const LOGIN = `
  mutation Login {
    user {
      id
    }
  }
`

describe('info', () => {
  it('exposes request handler information for query', () => {
    const handler = new GraphQLHandler(
      OperationTypeNode.QUERY,
      'GetUser',
      '*',
      resolver,
    )

    expect(handler.info.header).toEqual('query GetUser (origin: *)')
    expect(handler.info.operationType).toEqual('query')
    expect(handler.info.operationName).toEqual('GetUser')
  })

  it('exposes request handler information for mutation', () => {
    const handler = new GraphQLHandler(
      OperationTypeNode.MUTATION,
      'Login',
      '*',
      resolver,
    )

    expect(handler.info.header).toEqual('mutation Login (origin: *)')
    expect(handler.info.operationType).toEqual('mutation')
    expect(handler.info.operationName).toEqual('Login')
  })

  it('parses a query operation name from a given DocumentNode', () => {
    const node = parse(`
      query GetUser {
        user {
          firstName
        }
      }
    `)

    const handler = new GraphQLHandler(
      OperationTypeNode.QUERY,
      node,
      '*',
      resolver,
    )

    expect(handler.info).toHaveProperty('header', 'query GetUser (origin: *)')
    expect(handler.info).toHaveProperty('operationType', 'query')
    expect(handler.info).toHaveProperty('operationName', 'GetUser')
  })

  it('parses a mutation operation name from a given DocumentNode', () => {
    const node = parse(`
      mutation Login {
        user {
          id
        }
      }
    `)
    const handler = new GraphQLHandler(
      OperationTypeNode.MUTATION,
      node,
      '*',
      resolver,
    )

    expect(handler.info).toHaveProperty('header', 'mutation Login (origin: *)')
    expect(handler.info).toHaveProperty('operationType', 'mutation')
    expect(handler.info).toHaveProperty('operationName', 'Login')
  })

  it('throws an exception given a DocumentNode with a mismatched operation type', () => {
    const node = parse(`
      mutation CreateUser {
        user {
          firstName
        }
      }
    `)

    expect(
      () => new GraphQLHandler(OperationTypeNode.QUERY, node, '*', resolver),
    ).toThrow(
      'Failed to create a GraphQL handler: provided a DocumentNode with a mismatched operation type (expected "query" but got "mutation").',
    )
  })
})

describe('parse', () => {
  describe('query', () => {
    it('parses a query without variables (GET)', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.QUERY,
        'GetUser',
        '*',
        resolver,
      )
      const request = createGetGraphQLRequest({
        query: GET_USER,
      })

      expect(await handler.parse({ request })).toEqual({
        cookies: {},
        match: {
          matches: true,
          params: {
            '0': 'https://example.com/',
          },
        },
        operationType: 'query',
        operationName: 'GetUser',
        query: GET_USER,
        variables: undefined,
      })
    })

    it('parses a query with variables (GET)', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.QUERY,
        'GetUser',
        '*',
        resolver,
      )
      const request = createGetGraphQLRequest({
        query: GET_USER,
        variables: {
          userId: 'abc-123',
        },
      })

      expect(await handler.parse({ request })).toEqual({
        cookies: {},
        match: {
          matches: true,
          params: {
            '0': 'https://example.com/',
          },
        },
        operationType: 'query',
        operationName: 'GetUser',
        query: GET_USER,
        variables: {
          userId: 'abc-123',
        },
      })
    })

    it('parses a query without variables (POST)', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.QUERY,
        'GetUser',
        '*',
        resolver,
      )
      const request = createPostGraphQLRequest({
        query: GET_USER,
      })

      expect(await handler.parse({ request })).toEqual({
        cookies: {},
        match: {
          matches: true,
          params: {
            '0': 'https://example.com/',
          },
        },
        operationType: 'query',
        operationName: 'GetUser',
        query: GET_USER,
        variables: undefined,
      })
    })

    it('parses a query with variables (POST)', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.QUERY,
        'GetUser',
        '*',
        resolver,
      )
      const request = createPostGraphQLRequest({
        query: GET_USER,
        variables: {
          userId: 'abc-123',
        },
      })

      expect(await handler.parse({ request })).toEqual({
        cookies: {},
        match: {
          matches: true,
          params: {
            '0': 'https://example.com/',
          },
        },
        operationType: 'query',
        operationName: 'GetUser',
        query: GET_USER,
        variables: {
          userId: 'abc-123',
        },
      })
    })
  })

  describe('mutation', () => {
    it('parses a mutation without variables (GET)', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.MUTATION,
        'GetUser',
        '*',
        resolver,
      )
      const request = createGetGraphQLRequest({
        query: LOGIN,
      })

      expect(await handler.parse({ request })).toEqual({
        cookies: {},
        match: {
          matches: true,
          params: {
            '0': 'https://example.com/',
          },
        },
        operationType: 'mutation',
        operationName: 'Login',
        query: LOGIN,
        variables: undefined,
      })
    })

    it('parses a mutation with variables (GET)', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.MUTATION,
        'GetUser',
        '*',
        resolver,
      )
      const request = createGetGraphQLRequest({
        query: LOGIN,
        variables: {
          userId: 'abc-123',
        },
      })

      expect(await handler.parse({ request })).toEqual({
        cookies: {},
        match: {
          matches: true,
          params: {
            '0': 'https://example.com/',
          },
        },
        operationType: 'mutation',
        operationName: 'Login',
        query: LOGIN,
        variables: {
          userId: 'abc-123',
        },
      })
    })

    it('parses a mutation without variables (POST)', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.MUTATION,
        'GetUser',
        '*',
        resolver,
      )
      const request = createPostGraphQLRequest({
        query: LOGIN,
      })

      expect(await handler.parse({ request })).toEqual({
        cookies: {},
        match: {
          matches: true,
          params: {
            '0': 'https://example.com/',
          },
        },
        operationType: 'mutation',
        operationName: 'Login',
        query: LOGIN,
        variables: undefined,
      })
    })

    it('parses a mutation with variables (POST)', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.MUTATION,
        'GetUser',
        '*',
        resolver,
      )
      const request = createPostGraphQLRequest({
        query: LOGIN,
        variables: {
          userId: 'abc-123',
        },
      })

      expect(await handler.parse({ request })).toEqual({
        cookies: {},
        match: {
          matches: true,
          params: {
            '0': 'https://example.com/',
          },
        },
        operationType: 'mutation',
        operationName: 'Login',
        query: LOGIN,
        variables: {
          userId: 'abc-123',
        },
      })
    })
  })

  describe('with endpoint configuration', () => {
    it('parses the request and parses grapqhl properties from it when the graphql.link endpoint matches', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.QUERY,
        'GetUser',
        'https://mswjs.com/graphql',
        resolver,
      )

      await expect(
        handler.parse({
          request: createGetGraphQLRequest(
            {
              query: GET_USER,
              variables: {
                userId: 'abc-123',
              },
            },
            'https://mswjs.com/graphql',
          ),
        }),
      ).resolves.toEqual({
        cookies: {},
        match: {
          matches: true,
          params: {},
        },
        operationType: 'query',
        operationName: 'GetUser',
        query: GET_USER,
        variables: {
          userId: 'abc-123',
        },
      })

      await expect(
        handler.parse({
          request: createPostGraphQLRequest(
            {
              query: GET_USER,
              variables: {
                userId: 'abc-123',
              },
            },
            'https://mswjs.com/graphql',
          ),
        }),
      ).resolves.toEqual({
        cookies: {},
        match: {
          matches: true,
          params: {},
        },
        operationType: 'query',
        operationName: 'GetUser',
        query: GET_USER,
        variables: {
          userId: 'abc-123',
        },
      })
    })

    it('parses a request but does not parse graphql properties from it graphql.link hostname does not match', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.QUERY,
        'GetUser',
        'https://mswjs.com/graphql',
        resolver,
      )

      await expect(
        handler.parse({
          request: createGetGraphQLRequest(
            {
              query: GET_USER,
              variables: {
                userId: 'abc-123',
              },
            },
            'https://example.com/graphql',
          ),
        }),
      ).resolves.toEqual({
        cookies: {},
        match: {
          matches: false,
          params: {},
        },
      })

      await expect(
        handler.parse({
          request: createPostGraphQLRequest(
            {
              query: GET_USER,
              variables: {
                userId: 'abc-123',
              },
            },
            'https://example.com/graphql',
          ),
        }),
      ).resolves.toEqual({
        cookies: {},
        match: {
          matches: false,
          params: {},
        },
      })
    })

    it('parses a request but does not parse graphql properties from it graphql.link pathname does not match', async () => {
      const handler = new GraphQLHandler(
        OperationTypeNode.QUERY,
        'GetUser',
        'https://mswjs.com/graphql',
        resolver,
      )

      await expect(
        handler.parse({
          request: createGetGraphQLRequest(
            {
              query: GET_USER,
              variables: {
                userId: 'abc-123',
              },
            },
            'https://mswjs.com/some/other/endpoint',
          ),
        }),
      ).resolves.toEqual({
        cookies: {},
        match: {
          matches: false,
          params: {},
        },
      })

      await expect(
        handler.parse({
          request: createPostGraphQLRequest(
            {
              query: GET_USER,
              variables: {
                userId: 'abc-123',
              },
            },
            'https://mswjs.com/some/other/endpoint',
          ),
        }),
      ).resolves.toEqual({
        cookies: {},
        match: {
Download .txt
gitextract_krzcz2ns/

├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── 01-issue-browser.yml
│   │   ├── 02-issue-nodejs.yml
│   │   └── 03-feature.yml
│   └── workflows/
│       ├── auto.yml
│       ├── ci.yml
│       ├── compat.yml
│       ├── lock-closed-issues.yml
│       ├── release-preview.yml
│       ├── release.yml
│       ├── smoke-test.yml
│       └── typescript-nightly.yml
├── .gitignore
├── .nvmrc
├── .prettierrc
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── browser/
│   └── package.json
├── cli/
│   ├── index.js
│   ├── init.js
│   ├── invariant.js
│   └── package.json
├── commitlint.config.js
├── config/
│   ├── constants.js
│   ├── copyServiceWorker.ts
│   ├── package.json
│   ├── plugins/
│   │   └── esbuild/
│   │       ├── copyWorkerPlugin.ts
│   │       ├── forceEsmExtensionsPlugin.ts
│   │       ├── graphQLImportPlugin.ts
│   │       └── resolveCoreImportsPlugin.ts
│   ├── polyfills-node.ts
│   ├── replaceCoreImports.js
│   └── scripts/
│       ├── patch-ts.js
│       ├── postinstall.js
│       └── smoke-test.sh
├── decisions/
│   ├── jest-support.md
│   ├── linting-worker-script.md
│   ├── releases.md
│   └── typescript-versioning.md
├── eslint.config.mjs
├── global.d.ts
├── knip.json
├── native/
│   └── package.json
├── node/
│   └── package.json
├── package.json
├── release.config.json
├── src/
│   ├── browser/
│   │   ├── global.browser.d.ts
│   │   ├── index.ts
│   │   ├── setupWorker/
│   │   │   ├── glossary.ts
│   │   │   ├── setupWorker.node.test.ts
│   │   │   ├── setupWorker.ts
│   │   │   ├── start/
│   │   │   │   ├── createFallbackRequestListener.ts
│   │   │   │   ├── createRequestListener.ts
│   │   │   │   ├── createResponseListener.ts
│   │   │   │   ├── createStartHandler.ts
│   │   │   │   └── utils/
│   │   │   │       ├── enableMocking.ts
│   │   │   │       ├── getWorkerByRegistration.ts
│   │   │   │       ├── getWorkerInstance.ts
│   │   │   │       ├── prepareStartHandler.test.ts
│   │   │   │       ├── prepareStartHandler.ts
│   │   │   │       ├── printStartMessage.test.ts
│   │   │   │       ├── printStartMessage.ts
│   │   │   │       └── validateWorkerScope.ts
│   │   │   └── stop/
│   │   │       └── utils/
│   │   │           ├── printStopMessage.test.ts
│   │   │           └── printStopMessage.ts
│   │   ├── tsconfig.browser.build.json
│   │   ├── tsconfig.browser.json
│   │   └── utils/
│   │       ├── checkWorkerIntegrity.ts
│   │       ├── deserializeRequest.ts
│   │       ├── getAbsoluteWorkerUrl.test.ts
│   │       ├── getAbsoluteWorkerUrl.ts
│   │       ├── pruneGetRequestBody.test.ts
│   │       ├── pruneGetRequestBody.ts
│   │       ├── supports.ts
│   │       └── workerChannel.ts
│   ├── core/
│   │   ├── HttpResponse.test.ts
│   │   ├── HttpResponse.ts
│   │   ├── SetupApi.ts
│   │   ├── bypass.test.ts
│   │   ├── bypass.ts
│   │   ├── delay.ts
│   │   ├── getResponse.test.ts
│   │   ├── getResponse.ts
│   │   ├── graphql.test.ts
│   │   ├── graphql.ts
│   │   ├── handlers/
│   │   │   ├── GraphQLHandler.test.ts
│   │   │   ├── GraphQLHandler.ts
│   │   │   ├── HttpHandler.test.ts
│   │   │   ├── HttpHandler.ts
│   │   │   ├── RequestHandler.ts
│   │   │   ├── WebSocketHandler.test.ts
│   │   │   ├── WebSocketHandler.ts
│   │   │   └── common.ts
│   │   ├── http.test.ts
│   │   ├── http.ts
│   │   ├── index.ts
│   │   ├── isCommonAssetRequest.ts
│   │   ├── passthrough.test.ts
│   │   ├── passthrough.ts
│   │   ├── sharedOptions.ts
│   │   ├── sse.ts
│   │   ├── typeUtils.ts
│   │   ├── utils/
│   │   │   ├── HttpResponse/
│   │   │   │   └── decorators.ts
│   │   │   ├── cookieStore.ts
│   │   │   ├── executeHandlers.ts
│   │   │   ├── handleRequest.test.ts
│   │   │   ├── handleRequest.ts
│   │   │   ├── internal/
│   │   │   │   ├── Disposable.ts
│   │   │   │   ├── checkGlobals.ts
│   │   │   │   ├── devUtils.test.ts
│   │   │   │   ├── devUtils.ts
│   │   │   │   ├── getCallFrame.test.ts
│   │   │   │   ├── getCallFrame.ts
│   │   │   │   ├── hasRefCounted.test.ts
│   │   │   │   ├── hasRefCounted.ts
│   │   │   │   ├── isHandlerKind.test.ts
│   │   │   │   ├── isHandlerKind.ts
│   │   │   │   ├── isIterable.test.ts
│   │   │   │   ├── isIterable.ts
│   │   │   │   ├── isObject.test.ts
│   │   │   │   ├── isObject.ts
│   │   │   │   ├── isStringEqual.test.ts
│   │   │   │   ├── isStringEqual.ts
│   │   │   │   ├── jsonParse.test.ts
│   │   │   │   ├── jsonParse.ts
│   │   │   │   ├── mergeRight.test.ts
│   │   │   │   ├── mergeRight.ts
│   │   │   │   ├── parseGraphQLRequest.test.ts
│   │   │   │   ├── parseGraphQLRequest.ts
│   │   │   │   ├── parseMultipartData.test.ts
│   │   │   │   ├── parseMultipartData.ts
│   │   │   │   ├── pipeEvents.test.ts
│   │   │   │   ├── pipeEvents.ts
│   │   │   │   ├── requestHandlerUtils.ts
│   │   │   │   ├── toReadonlyArray.test.ts
│   │   │   │   ├── toReadonlyArray.ts
│   │   │   │   ├── tryCatch.test.ts
│   │   │   │   └── tryCatch.ts
│   │   │   ├── logging/
│   │   │   │   ├── getStatusCodeColor.test.ts
│   │   │   │   ├── getStatusCodeColor.ts
│   │   │   │   ├── getTimestamp.test.ts
│   │   │   │   ├── getTimestamp.ts
│   │   │   │   ├── serializeRequest.test.ts
│   │   │   │   ├── serializeRequest.ts
│   │   │   │   ├── serializeResponse.test.ts
│   │   │   │   └── serializeResponse.ts
│   │   │   ├── matching/
│   │   │   │   ├── matchRequestUrl.test.ts
│   │   │   │   ├── matchRequestUrl.ts
│   │   │   │   ├── normalizePath.node.test.ts
│   │   │   │   ├── normalizePath.test.ts
│   │   │   │   └── normalizePath.ts
│   │   │   ├── request/
│   │   │   │   ├── getAllAcceptedMimeTypes.test.ts
│   │   │   │   ├── getAllAcceptedMimeTypes.ts
│   │   │   │   ├── getRequestCookies.ts
│   │   │   │   ├── onUnhandledRequest.node.test.ts
│   │   │   │   ├── onUnhandledRequest.test.ts
│   │   │   │   ├── onUnhandledRequest.ts
│   │   │   │   ├── storeResponseCookies.ts
│   │   │   │   ├── toPublicUrl.node.test.ts
│   │   │   │   ├── toPublicUrl.test.ts
│   │   │   │   └── toPublicUrl.ts
│   │   │   ├── toResponseInit.ts
│   │   │   └── url/
│   │   │       ├── cleanUrl.test.ts
│   │   │       ├── cleanUrl.ts
│   │   │       ├── getAbsoluteUrl.node.test.ts
│   │   │       ├── getAbsoluteUrl.test.ts
│   │   │       ├── getAbsoluteUrl.ts
│   │   │       ├── isAbsoluteUrl.test.ts
│   │   │       └── isAbsoluteUrl.ts
│   │   ├── ws/
│   │   │   ├── WebSocketClientManager.test.ts
│   │   │   ├── WebSocketClientManager.ts
│   │   │   ├── WebSocketClientStore.ts
│   │   │   ├── WebSocketIndexedDBClientStore.ts
│   │   │   ├── WebSocketMemoryClientStore.ts
│   │   │   ├── handleWebSocketEvent.ts
│   │   │   ├── utils/
│   │   │   │   ├── attachWebSocketLogger.ts
│   │   │   │   ├── getMessageLength.test.ts
│   │   │   │   ├── getMessageLength.ts
│   │   │   │   ├── getPublicData.test.ts
│   │   │   │   ├── getPublicData.ts
│   │   │   │   ├── truncateMessage.test.ts
│   │   │   │   └── truncateMessage.ts
│   │   │   └── webSocketInterceptor.ts
│   │   ├── ws.test.ts
│   │   └── ws.ts
│   ├── iife/
│   │   └── index.ts
│   ├── mockServiceWorker.js
│   ├── native/
│   │   └── index.ts
│   ├── node/
│   │   ├── SetupServerApi.ts
│   │   ├── SetupServerCommonApi.ts
│   │   ├── glossary.ts
│   │   ├── index.ts
│   │   └── setupServer.ts
│   ├── package.json
│   ├── shims/
│   │   ├── cookie.ts
│   │   └── statuses.ts
│   ├── tsconfig.core.build.json
│   ├── tsconfig.node.build.json
│   ├── tsconfig.node.json
│   ├── tsconfig.src.json
│   └── tsconfig.worker.json
├── test/
│   ├── README.md
│   ├── browser/
│   │   ├── graphql-api/
│   │   │   ├── anonymous-operation.mocks.ts
│   │   │   ├── anonymous-operation.test.ts
│   │   │   ├── cookies.mocks.ts
│   │   │   ├── cookies.test.ts
│   │   │   ├── custom-predicate.mocks.ts
│   │   │   ├── custom-predicate.test.ts
│   │   │   ├── document-node.mocks.ts
│   │   │   ├── errors.mocks.ts
│   │   │   ├── errors.test.ts
│   │   │   ├── extensions.mocks.ts
│   │   │   ├── extensions.test.ts
│   │   │   ├── link.mocks.ts
│   │   │   ├── link.test.ts
│   │   │   ├── logging.mocks.ts
│   │   │   ├── logging.test.ts
│   │   │   ├── multipart-data.mocks.ts
│   │   │   ├── multipart-data.test.ts
│   │   │   ├── mutation.mocks.ts
│   │   │   ├── mutation.test.ts
│   │   │   ├── operation-reference.mocks.ts
│   │   │   ├── operation-reference.test.ts
│   │   │   ├── operation.mocks.ts
│   │   │   ├── operation.test.ts
│   │   │   ├── query.mocks.ts
│   │   │   ├── query.test.ts
│   │   │   ├── response-patching.mocks.ts
│   │   │   ├── response-patching.test.ts
│   │   │   ├── variables.mocks.ts
│   │   │   └── variables.test.ts
│   │   ├── msw-api/
│   │   │   ├── context/
│   │   │   │   ├── delay.mocks.ts
│   │   │   │   └── delay.test.ts
│   │   │   ├── distribution/
│   │   │   │   ├── iife.mocks.js
│   │   │   │   └── iife.test.ts
│   │   │   ├── exception-handling.mocks.ts
│   │   │   ├── exception-handling.test.ts
│   │   │   ├── hard-reload.mocks.ts
│   │   │   ├── hard-reload.test.ts
│   │   │   ├── integrity-check-invalid.mocks.ts
│   │   │   ├── integrity-check-valid.mocks.ts
│   │   │   ├── integrity-check.test.ts
│   │   │   ├── regression/
│   │   │   │   ├── 2129-worker-use.mocks.ts
│   │   │   │   ├── 2129-worker-use.test.ts
│   │   │   │   ├── handle-stream.mocks.ts
│   │   │   │   ├── handle-stream.test.ts
│   │   │   │   ├── null-body.mocks.ts
│   │   │   │   └── null-body.test.ts
│   │   │   ├── req/
│   │   │   │   ├── passthrough.mocks.ts
│   │   │   │   └── passthrough.test.ts
│   │   │   ├── res/
│   │   │   │   ├── network-error.mocks.ts
│   │   │   │   └── network-error.test.ts
│   │   │   ├── setup-worker/
│   │   │   │   ├── fallback-mode/
│   │   │   │   │   ├── fallback-mode.mocks.ts
│   │   │   │   │   └── fallback-mode.test.ts
│   │   │   │   ├── input-validation.mocks.ts
│   │   │   │   ├── input-validation.test.ts
│   │   │   │   ├── life-cycle-events/
│   │   │   │   │   ├── on.mocks.ts
│   │   │   │   │   ├── on.test.ts
│   │   │   │   │   ├── removeAllListeners.test.ts
│   │   │   │   │   └── removeListener.test.ts
│   │   │   │   ├── listHandlers.mocks.ts
│   │   │   │   ├── listHandlers.test.ts
│   │   │   │   ├── resetHandlers.test.ts
│   │   │   │   ├── response-logging.test.ts
│   │   │   │   ├── restoreHandlers.test.ts
│   │   │   │   ├── scenarios/
│   │   │   │   │   ├── custom-transformers.mocks.ts
│   │   │   │   │   ├── custom-transformers.test.ts
│   │   │   │   │   ├── errors/
│   │   │   │   │   │   ├── internal-error.mocks.ts
│   │   │   │   │   │   ├── internal-error.test.ts
│   │   │   │   │   │   ├── network-error.mocks.ts
│   │   │   │   │   │   └── network-error.test.ts
│   │   │   │   │   ├── fall-through.mocks.ts
│   │   │   │   │   ├── fall-through.test.ts
│   │   │   │   │   ├── iframe/
│   │   │   │   │   │   ├── app.html
│   │   │   │   │   │   ├── iframe.mocks.ts
│   │   │   │   │   │   ├── iframe.test.ts
│   │   │   │   │   │   ├── multiple-workers/
│   │   │   │   │   │   │   ├── child.mocks.ts
│   │   │   │   │   │   │   ├── iframe-multiple-workers.test.ts
│   │   │   │   │   │   │   └── parent.mocks.ts
│   │   │   │   │   │   ├── page-in-iframe.html
│   │   │   │   │   │   └── page-in-nested-iframe.html
│   │   │   │   │   ├── iframe-isolated-response/
│   │   │   │   │   │   ├── app.html
│   │   │   │   │   │   ├── iframe-isolated-response.mocks.ts
│   │   │   │   │   │   ├── iframe-isolated-response.test.ts
│   │   │   │   │   │   ├── one.html
│   │   │   │   │   │   └── two.html
│   │   │   │   │   ├── scope/
│   │   │   │   │   │   ├── scope-nested-quiet.mocks.ts
│   │   │   │   │   │   ├── scope-nested.mocks.ts
│   │   │   │   │   │   ├── scope-root.mocks.ts
│   │   │   │   │   │   └── scope-validation.test.ts
│   │   │   │   │   ├── shared-worker/
│   │   │   │   │   │   ├── shared-worker.mocks.ts
│   │   │   │   │   │   ├── shared-worker.test.ts
│   │   │   │   │   │   └── worker.js
│   │   │   │   │   ├── text-event-stream.mocks.ts
│   │   │   │   │   └── text-event-stream.test.ts
│   │   │   │   ├── start/
│   │   │   │   │   ├── error.mocks.ts
│   │   │   │   │   ├── error.test.ts
│   │   │   │   │   ├── find-worker.error.mocks.ts
│   │   │   │   │   ├── find-worker.mocks.ts
│   │   │   │   │   ├── find-worker.test.ts
│   │   │   │   │   ├── on-unhandled-request/
│   │   │   │   │   │   ├── bypass.mocks.ts
│   │   │   │   │   │   ├── bypass.test.ts
│   │   │   │   │   │   ├── callback-print.mocks.ts
│   │   │   │   │   │   ├── callback-print.test.ts
│   │   │   │   │   │   ├── callback-throws.mocks.ts
│   │   │   │   │   │   ├── callback.mocks.ts
│   │   │   │   │   │   ├── callback.test.ts
│   │   │   │   │   │   ├── default.mocks.ts
│   │   │   │   │   │   ├── default.test.ts
│   │   │   │   │   │   ├── warn.mocks.ts
│   │   │   │   │   │   └── warn.test.ts
│   │   │   │   │   ├── options-sw-scope.mocks.ts
│   │   │   │   │   ├── options-sw-scope.test.ts
│   │   │   │   │   ├── quiet.mocks.ts
│   │   │   │   │   ├── quiet.test.ts
│   │   │   │   │   ├── start.mocks.ts
│   │   │   │   │   ├── start.test.ts
│   │   │   │   │   ├── warn-on-wait-until-ready.mocks.ts
│   │   │   │   │   ├── warn-on-wait-until-ready.test.ts
│   │   │   │   │   └── worker.delayed.js
│   │   │   │   ├── stop/
│   │   │   │   │   ├── in-flight-request.mocks.ts
│   │   │   │   │   ├── in-flight-request.test.ts
│   │   │   │   │   ├── quiet.mocks.ts
│   │   │   │   │   ├── quiet.test.ts
│   │   │   │   │   ├── removes-all-listeners.mocks.ts
│   │   │   │   │   └── removes-all-listeners.test.ts
│   │   │   │   ├── stop.mocks.ts
│   │   │   │   ├── stop.test.ts
│   │   │   │   ├── use.mocks.ts
│   │   │   │   ├── use.test.ts
│   │   │   │   ├── worker-passthrough-header.mocks.ts
│   │   │   │   └── worker-passthrough-header.test.ts
│   │   │   ├── unregister.mocks.ts
│   │   │   └── unregister.test.ts
│   │   ├── playwright.config.ts
│   │   ├── playwright.extend.ts
│   │   ├── rest-api/
│   │   │   ├── 204-response.test.ts
│   │   │   ├── 206-response.mocks.ts
│   │   │   ├── 206-response.test.ts
│   │   │   ├── basic.mocks.ts
│   │   │   ├── basic.test.ts
│   │   │   ├── body.mocks.ts
│   │   │   ├── body.test.ts
│   │   │   ├── context.mocks.ts
│   │   │   ├── context.test.ts
│   │   │   ├── cors.mocks.ts
│   │   │   ├── cors.test.ts
│   │   │   ├── generator.mocks.ts
│   │   │   ├── generator.test.ts
│   │   │   ├── headers-multiple.mocks.ts
│   │   │   ├── headers-multiple.test.ts
│   │   │   ├── logging.test.ts
│   │   │   ├── params.mocks.ts
│   │   │   ├── params.test.ts
│   │   │   ├── plain-response.mocks.ts
│   │   │   ├── plain-response.test.ts
│   │   │   ├── query-params-warning.mocks.ts
│   │   │   ├── query-params-warning.test.ts
│   │   │   ├── query.mocks.ts
│   │   │   ├── query.test.ts
│   │   │   ├── redirect.mocks.ts
│   │   │   ├── redirect.test.ts
│   │   │   ├── request/
│   │   │   │   ├── body/
│   │   │   │   │   ├── body-arraybuffer-range.mocks.ts
│   │   │   │   │   ├── body-arraybuffer-range.test.ts
│   │   │   │   │   ├── body-arraybuffer.test.ts
│   │   │   │   │   ├── body-form-data.page.html
│   │   │   │   │   ├── body-form-data.test.ts
│   │   │   │   │   ├── body-json.test.ts
│   │   │   │   │   ├── body-text.test.ts
│   │   │   │   │   └── body.mocks.ts
│   │   │   │   ├── matching/
│   │   │   │   │   ├── all.mocks.ts
│   │   │   │   │   ├── all.test.ts
│   │   │   │   │   ├── custom-predicate.mocks.ts
│   │   │   │   │   ├── custom-predicate.test.ts
│   │   │   │   │   ├── method.mocks.ts
│   │   │   │   │   ├── method.test.ts
│   │   │   │   │   ├── path-params-decode.mocks.ts
│   │   │   │   │   ├── path-params-decode.test.ts
│   │   │   │   │   ├── uri.mocks.ts
│   │   │   │   │   └── uri.test.ts
│   │   │   │   ├── request-cookies.mocks.ts
│   │   │   │   └── request-cookies.test.ts
│   │   │   ├── response/
│   │   │   │   ├── body/
│   │   │   │   │   ├── body-binary.mocks.ts
│   │   │   │   │   ├── body-binary.test.ts
│   │   │   │   │   ├── body-blob.mocks.ts
│   │   │   │   │   ├── body-blob.test.ts
│   │   │   │   │   ├── body-formdata.mocks.ts
│   │   │   │   │   ├── body-formdata.test.ts
│   │   │   │   │   ├── body-html.mocks.ts
│   │   │   │   │   ├── body-html.test.ts
│   │   │   │   │   ├── body-json.mocks.ts
│   │   │   │   │   ├── body-json.test.ts
│   │   │   │   │   ├── body-stream.mocks.ts
│   │   │   │   │   ├── body-stream.test.ts
│   │   │   │   │   ├── body-text.mocks.ts
│   │   │   │   │   ├── body-text.test.ts
│   │   │   │   │   ├── body-xml.mocks.ts
│   │   │   │   │   └── body-xml.test.ts
│   │   │   │   ├── response-cookies.mocks.ts
│   │   │   │   ├── response-cookies.test.ts
│   │   │   │   ├── response-error.mocks.ts
│   │   │   │   ├── response-error.test.ts
│   │   │   │   ├── throw-response.mocks.ts
│   │   │   │   └── throw-response.test.ts
│   │   │   ├── response-patching.mocks.ts
│   │   │   ├── response-patching.test.ts
│   │   │   ├── send-beacon.mocks.ts
│   │   │   ├── send-beacon.test.ts
│   │   │   ├── status.mocks.ts
│   │   │   ├── status.test.ts
│   │   │   ├── xhr.mocks.ts
│   │   │   └── xhr.test.ts
│   │   ├── setup/
│   │   │   ├── webpackHttpServer.ts
│   │   │   └── workerConsole.ts
│   │   ├── sse-api/
│   │   │   ├── sse.client.send.extraneous.test.ts
│   │   │   ├── sse.client.send.multiline.test.ts
│   │   │   ├── sse.client.send.test.ts
│   │   │   ├── sse.mocks.ts
│   │   │   ├── sse.quiet.test.ts
│   │   │   ├── sse.retry.test.ts
│   │   │   ├── sse.server.connect.test.ts
│   │   │   ├── sse.use.test.ts
│   │   │   └── sse.with-credentials.test.ts
│   │   ├── third-party/
│   │   │   ├── axios-upload.browser.test.ts
│   │   │   └── axios-upload.runtime.js
│   │   └── ws-api/
│   │       ├── ws.apply.browser.test.ts
│   │       ├── ws.client.send.test.ts
│   │       ├── ws.clients.browser.test.ts
│   │       ├── ws.intercept.client.browser.test.ts
│   │       ├── ws.intercept.server.browser.test.ts
│   │       ├── ws.logging.browser.test.ts
│   │       ├── ws.runtime.js
│   │       ├── ws.server.connect.browser.test.ts
│   │       └── ws.use.browser.test.ts
│   ├── e2e/
│   │   ├── auto-update-worker.node.test.ts
│   │   ├── cli-init.node.test.ts
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   ├── vitest.d.ts
│   │   └── vitest.global.setup.ts
│   ├── global.d.ts
│   ├── modules/
│   │   ├── browser/
│   │   │   ├── esm-browser.test.ts
│   │   │   └── playwright.config.ts
│   │   ├── module-utils.ts
│   │   └── node/
│   │       ├── esm-node.test.ts
│   │       ├── tsconfig.json
│   │       └── vitest.config.ts
│   ├── native/
│   │   ├── node-events.native.test.ts
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   └── vitest.setup.ts
│   ├── node/
│   │   ├── graphql-api/
│   │   │   ├── anonymous-operations.test.ts
│   │   │   ├── batched-queries.apollo.test.ts
│   │   │   ├── batched-queries.batched-execute.test.ts
│   │   │   ├── compatibility.node.test.ts
│   │   │   ├── content-type.test.ts
│   │   │   ├── cookies.test.ts
│   │   │   ├── custom-predicate.node.test.ts
│   │   │   ├── extensions.node.test.ts
│   │   │   ├── response-patching.node.test.ts
│   │   │   ├── typed-document-node.test.ts
│   │   │   └── typed-document-string.test.ts
│   │   ├── msw-api/
│   │   │   ├── context/
│   │   │   │   ├── delay-infinite.fixture.js
│   │   │   │   └── delay.node.test.ts
│   │   │   ├── req/
│   │   │   │   └── passthrough.node.test.ts
│   │   │   ├── res/
│   │   │   │   └── network-error.node.test.ts
│   │   │   └── setup-server/
│   │   │       ├── boundary/
│   │   │       │   ├── boundary.args.test.ts
│   │   │       │   ├── boundary.concurrency.test.ts
│   │   │       │   └── boundary.handlers.test.ts
│   │   │       ├── input-validation.node.test.ts
│   │   │       ├── life-cycle-events/
│   │   │       │   ├── on.node.test.ts
│   │   │       │   ├── removeAllListeners.node.test.ts
│   │   │       │   └── removeListener.node.test.ts
│   │   │       ├── listHandlers.node.test.ts
│   │   │       ├── resetHandlers.node.test.ts
│   │   │       ├── restoreHandlers.node.test.ts
│   │   │       ├── scenarios/
│   │   │       │   ├── cookies-request.node.test.ts
│   │   │       │   ├── custom-interceptors.node.test.ts
│   │   │       │   ├── custom-transformers.node.test.ts
│   │   │       │   ├── fake-timers.node.test.ts
│   │   │       │   ├── fall-through.node.test.ts
│   │   │       │   ├── fetch.node.test.ts
│   │   │       │   ├── generator.node.test.ts
│   │   │       │   ├── graphql.node.test.ts
│   │   │       │   ├── http.node.test.ts
│   │   │       │   ├── https.node.test.ts
│   │   │       │   ├── on-unhandled-request/
│   │   │       │   │   ├── bypass.node.test.ts
│   │   │       │   │   ├── callback-throws.node.test.ts
│   │   │       │   │   ├── callback.node.test.ts
│   │   │       │   │   ├── default.node.test.ts
│   │   │       │   │   ├── error.node.test.ts
│   │   │       │   │   └── warn.node.test.ts
│   │   │       │   ├── relative-url.node.test.ts
│   │   │       │   ├── response-patching.node.test.ts
│   │   │       │   └── xhr.node.test.ts
│   │   │       └── use.node.test.ts
│   │   ├── regressions/
│   │   │   ├── 2129-server-use.test.ts
│   │   │   ├── 2370-listen-after-close.test.ts
│   │   │   ├── many-request-handlers-jsdom.test.ts
│   │   │   ├── many-request-handlers.test.ts
│   │   │   ├── miniflare.node.test.ts
│   │   │   └── mixed-graphql-http-with-query-in-body.node.test.ts
│   │   ├── rest-api/
│   │   │   ├── cookies-inheritance.node.test.ts
│   │   │   ├── https.node.test.ts
│   │   │   ├── request/
│   │   │   │   ├── body/
│   │   │   │   │   ├── body-arraybuffer.node.test.ts
│   │   │   │   │   ├── body-blob.node.test.ts
│   │   │   │   │   ├── body-form-data.node.test.ts
│   │   │   │   │   ├── body-json.node.test.ts
│   │   │   │   │   ├── body-protobuf.node.test.ts
│   │   │   │   │   ├── body-text.node.test.ts
│   │   │   │   │   └── body-used.node.test.ts
│   │   │   │   └── matching/
│   │   │   │       ├── all.node.test.ts
│   │   │   │       ├── custom-predicate.node.test.ts
│   │   │   │       ├── path-params-decode.node.test.ts
│   │   │   │       ├── path-params-optional.node.test.ts
│   │   │   │       └── relative-url.node.test.ts
│   │   │   ├── response/
│   │   │   │   ├── body-binary.node.test.ts
│   │   │   │   ├── body-html.node.test.ts
│   │   │   │   ├── body-json.node.test.ts
│   │   │   │   ├── body-stream.node.test.ts
│   │   │   │   ├── body-text.node.test.ts
│   │   │   │   ├── body-xml.node.test.ts
│   │   │   │   ├── generator.test.ts
│   │   │   │   ├── response-cookies.test.ts
│   │   │   │   ├── response-error.test.ts
│   │   │   │   └── throw-response.node.test.ts
│   │   │   └── response-patching.node.test.ts
│   │   ├── third-party/
│   │   │   ├── axios-error-response.test.ts
│   │   │   ├── axios-timeout.node.test.ts
│   │   │   └── axios-upload.node.test.ts
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   └── ws-api/
│   │       ├── on-unhandled-request/
│   │       │   ├── callback.test.ts
│   │       │   ├── error.test.ts
│   │       │   └── warn.test.ts
│   │       ├── ws.apply.test.ts
│   │       ├── ws.event-patching.test.ts
│   │       ├── ws.intercept.client.test.ts
│   │       ├── ws.intercept.server.test.ts
│   │       ├── ws.server.connect.test.ts
│   │       ├── ws.stop-propagation.test.ts
│   │       ├── ws.unhandled-exception.test.ts
│   │       └── ws.use.test.ts
│   ├── package.json
│   ├── support/
│   │   ├── WebSocketServer.ts
│   │   ├── alias.ts
│   │   ├── environments/
│   │   │   └── vitest-environment-node-websocket.ts
│   │   ├── graphql.ts
│   │   ├── msw-esm/
│   │   │   └── package.json
│   │   ├── utils.ts
│   │   └── waitFor.ts
│   ├── tsconfig.json
│   └── typings/
│       ├── custom-handler.test-d.ts
│       ├── custom-resolver.test-d.ts
│       ├── graphql-custom-predicate.test-d.ts
│       ├── graphql-typed-document-node.test-d.ts
│       ├── graphql-typed-document-string.test-d.ts
│       ├── graphql.test-d.ts
│       ├── http-custom-predicate.test-d.ts
│       ├── http.test-d.ts
│       ├── regressions/
│       │   ├── default-resolver-type.test-d.ts
│       │   ├── request-handler-type.test-d.ts
│       │   └── response-body-type.test-d.ts
│       ├── resolver-generator.test-d.ts
│       ├── server.boundary.test-d.ts
│       ├── setup-server.test-d.ts
│       ├── setup-worker.test-d.ts
│       ├── sse.test-d.ts
│       ├── tsconfig.5.0.json
│       ├── tsconfig.5.1.json
│       ├── tsconfig.5.2.json
│       ├── tsconfig.5.3.json
│       ├── tsconfig.5.4.json
│       ├── tsconfig.5.5.json
│       ├── tsconfig.json
│       ├── vitest.config.ts
│       └── ws.test-d.ts
├── tsconfig.base.json
├── tsconfig.json
├── tsconfig.test.unit.json
├── tsup.config.ts
└── vitest.config.mts
Download .txt
SYMBOL INDEX (648 symbols across 210 files)

FILE: cli/init.js
  function init (line 8) | async function init(args) {
  function toAbsolutePath (line 99) | function toAbsolutePath(maybeAbsolutePath, cwd) {
  function copyWorkerScript (line 110) | async function copyWorkerScript(destination, cwd) {
  function printSuccessMessage (line 144) | function printSuccessMessage(paths) {
  function printFailureMessage (line 156) | function printFailureMessage(pathsWithErrors) {
  function saveWorkerDirectory (line 170) | function saveWorkerDirectory(packageJsonPath, publicDir) {
  function promptWorkerDirectoryUpdate (line 205) | function promptWorkerDirectoryUpdate(message, packageJsonPath, publicDir) {
  function normalizePath (line 224) | function normalizePath(input) {

FILE: cli/invariant.js
  function invariant (line 3) | function invariant(predicate, message, ...args) {

FILE: config/constants.js
  constant SERVICE_WORKER_SOURCE_PATH (line 4) | const SERVICE_WORKER_SOURCE_PATH = url.fileURLToPath(
  constant SERVICE_WORKER_BUILD_PATH (line 8) | const SERVICE_WORKER_BUILD_PATH = url.fileURLToPath(

FILE: config/copyServiceWorker.ts
  function copyServiceWorker (line 9) | async function copyServiceWorker(

FILE: config/plugins/esbuild/copyWorkerPlugin.ts
  constant SERVICE_WORKER_ENTRY_PATH (line 9) | const SERVICE_WORKER_ENTRY_PATH = path.resolve(
  constant SERVICE_WORKER_OUTPUT_PATH (line 14) | const SERVICE_WORKER_OUTPUT_PATH = path.resolve(
  function getChecksum (line 19) | function getChecksum(contents: string): string {
  function getWorkerChecksum (line 25) | function getWorkerChecksum(): string {
  function copyWorkerPlugin (line 30) | function copyWorkerPlugin(checksum: string): Plugin {

FILE: config/plugins/esbuild/forceEsmExtensionsPlugin.ts
  constant ESM_EXTENSION (line 3) | const ESM_EXTENSION = '.mjs'
  constant CJS_EXTENSION (line 4) | const CJS_EXTENSION = '.js'
  function forceEsmExtensionsPlugin (line 6) | function forceEsmExtensionsPlugin(): Plugin {
  constant CJS_RELATIVE_IMPORT_EXP (line 39) | const CJS_RELATIVE_IMPORT_EXP = /require\(["'](\..+)["']\)(;)?/gm
  constant ESM_RELATIVE_IMPORT_EXP (line 40) | const ESM_RELATIVE_IMPORT_EXP = /from ["'](\..+)["'](;)?/gm
  function modifyRelativeImports (line 42) | function modifyRelativeImports(contents: string, isEsm: boolean): string {

FILE: config/plugins/esbuild/graphQLImportPlugin.ts
  function graphqlImportPlugin (line 10) | function graphqlImportPlugin(): Plugin {

FILE: config/plugins/esbuild/resolveCoreImportsPlugin.ts
  function resolveCoreImportsPlugin (line 5) | function resolveCoreImportsPlugin(): Plugin {

FILE: config/replaceCoreImports.js
  constant CORE_ESM_IMPORT_PATTERN (line 1) | const CORE_ESM_IMPORT_PATTERN = /from ["'](~\/core(.*))["'](;)?/gm
  constant CORE_CJS_IMPORT_PATTERN (line 2) | const CORE_CJS_IMPORT_PATTERN = /require\(["'](~\/core(.*))["']\)(;)?/gm
  function getCoreImportPattern (line 4) | function getCoreImportPattern(isEsm) {
  function hasCoreImports (line 8) | function hasCoreImports(fileContents, isEsm) {
  function replaceCoreImports (line 12) | function replaceCoreImports(moduleFilePath, fileContents, isEsm) {

FILE: config/scripts/patch-ts.js
  constant BUILD_DIR (line 10) | const BUILD_DIR = new URL('../../lib/', import.meta.url)
  function patchTypeDefs (line 12) | async function patchTypeDefs() {

FILE: config/scripts/postinstall.js
  function postInstall (line 10) | function postInstall() {

FILE: src/browser/setupWorker/glossary.ts
  type StringifiedResponse (line 14) | interface StringifiedResponse extends ResponseInit {
  type SetupWorkerInternalContext (line 18) | type SetupWorkerInternalContext = {
  type ServiceWorkerInstanceTuple (line 31) | type ServiceWorkerInstanceTuple = [
  type FindWorker (line 36) | type FindWorker = (
  type StartOptions (line 41) | interface StartOptions extends SharedOptions {
  type StartReturnType (line 75) | type StartReturnType = Promise<ServiceWorkerRegistration | undefined>
  type StartHandler (line 77) | type StartHandler = (
  type StopHandler (line 82) | type StopHandler = () => void
  type SetupWorker (line 84) | interface SetupWorker {

FILE: src/browser/setupWorker/setupWorker.ts
  class SetupWorkerApi (line 27) | class SetupWorkerApi
    method constructor (line 33) | constructor(...handlers: Array<RequestHandler | WebSocketHandler>) {
    method createWorkerContext (line 46) | private createWorkerContext(): SetupWorkerInternalContext {
    method start (line 66) | public async start(options: StartOptions = {}): StartReturnType {
    method stop (line 143) | public stop(): void {
  function setupWorker (line 180) | function setupWorker(

FILE: src/browser/setupWorker/start/createFallbackRequestListener.ts
  function createFallbackRequestListener (line 13) | function createFallbackRequestListener(

FILE: src/browser/setupWorker/start/createRequestListener.ts
  constant SUPPORTS_READABLE_STREAM_TRANSFER (line 12) | const SUPPORTS_READABLE_STREAM_TRANSFER = supportsReadableStreamTransfer()
  method onPassthroughResponse (line 52) | onPassthroughResponse() {
  method onMockedResponse (line 55) | async onMockedResponse(response, { handler, parsedResult }) {

FILE: src/browser/setupWorker/start/createResponseListener.ts
  function createResponseListener (line 6) | function createResponseListener(

FILE: src/browser/setupWorker/start/utils/enableMocking.ts
  function enableMocking (line 8) | function enableMocking(

FILE: src/browser/setupWorker/start/utils/getWorkerByRegistration.ts
  function getWorkerByRegistration (line 7) | function getWorkerByRegistration(

FILE: src/browser/setupWorker/start/utils/prepareStartHandler.ts
  constant DEFAULT_START_OPTIONS (line 10) | const DEFAULT_START_OPTIONS: RequiredDeep<StartOptions> = {
  method findWorker (line 18) | findWorker(scriptURL, mockServiceWorkerUrl) {
  function resolveStartOptions (line 27) | function resolveStartOptions(
  function prepareStartHandler (line 36) | function prepareStartHandler(

FILE: src/browser/setupWorker/start/utils/printStartMessage.ts
  type PrintStartMessageArgs (line 4) | interface PrintStartMessageArgs {
  function printStartMessage (line 15) | function printStartMessage(args: PrintStartMessageArgs = {}) {

FILE: src/browser/setupWorker/start/utils/validateWorkerScope.ts
  function validateWorkerScope (line 4) | function validateWorkerScope(

FILE: src/browser/setupWorker/stop/utils/printStopMessage.ts
  function printStopMessage (line 3) | function printStopMessage(args: { quiet?: boolean } = {}): void {

FILE: src/browser/utils/checkWorkerIntegrity.ts
  function checkWorkerIntegrity (line 10) | function checkWorkerIntegrity(

FILE: src/browser/utils/deserializeRequest.ts
  function deserializeRequest (line 8) | function deserializeRequest(

FILE: src/browser/utils/getAbsoluteWorkerUrl.ts
  function getAbsoluteWorkerUrl (line 5) | function getAbsoluteWorkerUrl(workerUrl: string): string {

FILE: src/browser/utils/pruneGetRequestBody.ts
  type Input (line 3) | type Input = Pick<ServiceWorkerIncomingRequest, 'method' | 'body'>
  function pruneGetRequestBody (line 8) | function pruneGetRequestBody(

FILE: src/browser/utils/supports.ts
  function supportsServiceWorker (line 5) | function supportsServiceWorker(): boolean {
  function supportsReadableStreamTransfer (line 19) | function supportsReadableStreamTransfer() {

FILE: src/browser/utils/workerChannel.ts
  type WorkerChannelOptions (line 7) | interface WorkerChannelOptions {
  type WorkerChannelEventMap (line 11) | type WorkerChannelEventMap = {
  type IncomingWorkerRequest (line 30) | interface IncomingWorkerRequest
  type IncomingWorkerResponse (line 53) | type IncomingWorkerResponse = {
  type WorkerEventResponse (line 62) | type WorkerEventResponse = {
  constant SUPPORTS_SERVICE_WORKER (line 70) | const SUPPORTS_SERVICE_WORKER = supportsServiceWorker()
  class WorkerEvent (line 72) | class WorkerEvent<
    method constructor (line 79) | constructor(workerEvent: MessageEvent) {
    method ports (line 96) | get ports() {
    method postMessage (line 103) | public postMessage<Type extends keyof WorkerEventResponse>(
  type OutgoingWorkerEvents (line 118) | type OutgoingWorkerEvents =
  class WorkerChannel (line 124) | class WorkerChannel extends Emitter<WorkerChannelEventMap> {
    method constructor (line 125) | constructor(protected readonly options: WorkerChannelOptions) {
    method postMessage (line 149) | public postMessage(type: OutgoingWorkerEvents): void {

FILE: src/core/HttpResponse.test.ts
  method start (line 146) | start(controller) {

FILE: src/core/HttpResponse.ts
  type HttpResponseInit (line 9) | interface HttpResponseInit extends ResponseInit {
  type DefaultUnsafeFetchResponse (line 14) | type DefaultUnsafeFetchResponse = Response & {
  type StrictRequest (line 18) | interface StrictRequest<BodyType extends JsonBodyType> extends Request {
  type StrictResponse (line 28) | type StrictResponse<BodyType extends DefaultBodyType> =
  class HttpResponse (line 44) | class HttpResponse<
    method constructor (line 49) | constructor(body?: NoInfer<BodyType> | null, init?: HttpResponseInit) {
    method error (line 55) | static error(): HttpResponse<any> {
    method text (line 65) | static text<BodyType extends string>(
    method json (line 104) | static json<BodyType extends JsonBodyType>(
    method xml (line 146) | static xml<BodyType extends string>(
    method html (line 175) | static html<BodyType extends string>(
    method arrayBuffer (line 207) | static arrayBuffer<BodyType extends ArrayBuffer | SharedArrayBuffer>(
    method formData (line 242) | static formData(

FILE: src/core/SetupApi.ts
  class InMemoryHandlersController (line 19) | class InMemoryHandlersController implements HandlersController {
    method constructor (line 22) | constructor(
    method prepend (line 28) | public prepend(
    method reset (line 34) | public reset(nextHandlers: Array<RequestHandler | WebSocketHandler>): ...
    method currentHandlers (line 39) | public currentHandlers(): Array<RequestHandler | WebSocketHandler> {
  method constructor (line 54) | constructor(...initialHandlers: Array<RequestHandler | WebSocketHandler>) {
  method validateHandlers (line 78) | private validateHandlers(handlers: ReadonlyArray<unknown>): boolean {
  method use (line 83) | public use(
  method restoreHandlers (line 96) | public restoreHandlers(): void {
  method resetHandlers (line 104) | public resetHandlers(
  method listHandlers (line 110) | public listHandlers(): ReadonlyArray<RequestHandler | WebSocketHandler> {
  method createLifeCycleEvents (line 114) | private createLifeCycleEvents(): LifeCycleEventEmitter<EventsMap> {

FILE: src/core/bypass.ts
  type BypassRequestInput (line 3) | type BypassRequestInput = string | URL | Request
  function bypass (line 17) | function bypass(input: BypassRequestInput, init?: RequestInit): Request {

FILE: src/core/delay.ts
  constant SET_TIMEOUT_MAX_ALLOWED_INT (line 4) | const SET_TIMEOUT_MAX_ALLOWED_INT = 2147483647
  constant MIN_SERVER_RESPONSE_TIME (line 5) | const MIN_SERVER_RESPONSE_TIME = 100
  constant MAX_SERVER_RESPONSE_TIME (line 6) | const MAX_SERVER_RESPONSE_TIME = 400
  constant NODE_SERVER_RESPONSE_TIME (line 7) | const NODE_SERVER_RESPONSE_TIME = 5
  function getRealisticResponseTime (line 9) | function getRealisticResponseTime(): number {
  type DelayMode (line 20) | type DelayMode = 'real' | 'infinite'
  function delay (line 32) | async function delay(

FILE: src/core/graphql.ts
  type GraphQLRequestHandler (line 17) | type GraphQLRequestHandler = <
  type GraphQLOperationHandler (line 29) | type GraphQLOperationHandler = <
  type GraphQLResponseResolver (line 40) | type GraphQLResponseResolver<
  function createScopedGraphQLHandler (line 49) | function createScopedGraphQLHandler(
  function createGraphQLOperationHandler (line 58) | function createGraphQLOperationHandler(url: Path): GraphQLOperationHandl...
  type GraphQLLinkHandlers (line 64) | interface GraphQLLinkHandlers {
  method link (line 126) | link(url: Path): GraphQLLinkHandlers {

FILE: src/core/handlers/GraphQLHandler.test.ts
  function createGetGraphQLRequest (line 25) | function createGetGraphQLRequest(
  function createPostGraphQLRequest (line 35) | function createPostGraphQLRequest(
  constant GET_USER (line 46) | const GET_USER = `
  constant LOGIN (line 54) | const LOGIN = `

FILE: src/core/handlers/GraphQLHandler.ts
  type DocumentTypeDecoration (line 35) | interface DocumentTypeDecoration<
  type GraphQLOperationType (line 44) | type GraphQLOperationType = OperationTypeNode | 'all'
  type GraphQLHandlerNameSelector (line 45) | type GraphQLHandlerNameSelector = DocumentNode | RegExp | string
  type GraphQLQuery (line 47) | type GraphQLQuery = Record<string, any> | null
  type GraphQLVariables (line 48) | type GraphQLVariables = Record<string, any>
  type GraphQLHandlerInfo (line 50) | interface GraphQLHandlerInfo extends RequestHandlerDefaultInfo {
  type GraphQLRequestParsedResult (line 55) | type GraphQLRequestParsedResult = {
  type GraphQLResolverExtras (line 73) | type GraphQLResolverExtras<Variables extends GraphQLVariables> = {
  type GraphQLRequestBody (line 80) | type GraphQLRequestBody<VariablesType extends GraphQLVariables> =
  type GraphQLJsonRequestBody (line 86) | interface GraphQLJsonRequestBody<Variables extends GraphQLVariables> {
  type GraphQLResponseBody (line 91) | type GraphQLResponseBody<BodyType extends DefaultBodyType> =
  type GraphQLCustomPredicate (line 100) | type GraphQLCustomPredicate = (args: {
  type GraphQLCustomPredicateResult (line 109) | type GraphQLCustomPredicateResult = boolean | { matches: boolean }
  type GraphQLPredicate (line 111) | type GraphQLPredicate<Query = any, Variables = any> =
  function isDocumentNode (line 116) | function isDocumentNode(
  function isDocumentTypeDecoration (line 126) | function isDocumentTypeDecoration(
  class GraphQLHandler (line 132) | class GraphQLHandler extends RequestHandler<
    method #parseOperationName (line 144) | static #parseOperationName(
    method constructor (line 183) | constructor(
    method parseGraphQLRequestOrGetFromCache (line 224) | async parseGraphQLRequestOrGetFromCache(
    method parse (line 240) | async parse(args: { request: Request }): Promise<GraphQLRequestParsedR...
    method predicate (line 276) | async predicate(args: {
    method run (line 316) | public async run(args: {
    method matchOperationName (line 364) | private async matchOperationName(args: {
    method extendResolverArgs (line 395) | protected extendResolverArgs(args: {
    method log (line 408) | async log(args: {

FILE: src/core/handlers/HttpHandler.ts
  type HttpHandlerMethod (line 24) | type HttpHandlerMethod = string | RegExp
  type HttpHandlerInfo (line 26) | interface HttpHandlerInfo extends RequestHandlerDefaultInfo {
  type HttpMethods (line 31) | enum HttpMethods {
  type RequestQuery (line 41) | type RequestQuery = {
  type HttpRequestParsedResult (line 45) | type HttpRequestParsedResult = {
  type HttpRequestResolverExtras (line 50) | type HttpRequestResolverExtras<Params extends PathParams> = {
  type HttpCustomPredicate (line 55) | type HttpCustomPredicate<Params extends PathParams> = (args: {
  type HttpCustomPredicateResult (line 62) | type HttpCustomPredicateResult<Params extends PathParams> =
  type HttpRequestPredicate (line 69) | type HttpRequestPredicate<Params extends PathParams> =
  class HttpHandler (line 77) | class HttpHandler extends RequestHandler<
    method constructor (line 82) | constructor(
    method checkRedundantQueryParameters (line 104) | private checkRedundantQueryParameters() {
    method parse (line 123) | async parse(args: {
    method predicate (line 165) | async predicate(args: {
    method matchMethod (line 175) | private matchMethod(actualMethod: string): boolean {
    method extendResolverArgs (line 181) | protected extendResolverArgs(args: {
    method log (line 191) | async log(args: { request: Request; response: Response }) {

FILE: src/core/handlers/RequestHandler.ts
  type DefaultRequestMultipartBody (line 17) | type DefaultRequestMultipartBody = Record<
  type DefaultBodyType (line 22) | type DefaultBodyType =
  type JsonBodyType (line 31) | type JsonBodyType =
  type RequestHandlerDefaultInfo (line 39) | interface RequestHandlerDefaultInfo {
  type RequestHandlerInternalInfo (line 43) | interface RequestHandlerInternalInfo {
  type ResponseResolverReturnType (line 47) | type ResponseResolverReturnType<
  type MaybeAsyncResponseResolverReturnType (line 66) | type MaybeAsyncResponseResolverReturnType<
  type AsyncResponseResolverReturnType (line 70) | type AsyncResponseResolverReturnType<
  type ResponseResolverInfo (line 86) | type ResponseResolverInfo<
  type ResponseResolver (line 94) | type ResponseResolver<
  type RequestHandlerArgs (line 102) | interface RequestHandlerArgs<
  type RequestHandlerOptions (line 111) | interface RequestHandlerOptions {
  type RequestHandlerExecutionResult (line 115) | interface RequestHandlerExecutionResult<
  method constructor (line 160) | constructor(args: RequestHandlerArgs<HandlerInfo, HandlerOptions>) {
  method parse (line 197) | async parse(_args: {
  method test (line 211) | public async test(args: {
  method extendResolverArgs (line 227) | protected extendResolverArgs(_args: {
  method cloneRequestOrGetFromCache (line 237) | private cloneRequestOrGetFromCache(
  method run (line 256) | public async run(args: {
  method wrapResolver (line 336) | private wrapResolver(
  method createExecutionResult (line 377) | private createExecutionResult(args: {

FILE: src/core/handlers/WebSocketHandler.ts
  type WebSocketHandlerParsedResult (line 17) | type WebSocketHandlerParsedResult = {
  type WebSocketHandlerEventMap (line 21) | type WebSocketHandlerEventMap = {
  type WebSocketHandlerConnection (line 25) | interface WebSocketHandlerConnection {
  type WebSocketResolutionContext (line 32) | interface WebSocketResolutionContext {
  class WebSocketHandler (line 41) | class WebSocketHandler {
    method constructor (line 49) | constructor(protected readonly url: Path) {
    method parse (line 57) | public parse(args: {
    method predicate (line 90) | public predicate(args: {
    method run (line 97) | public async run(
    method connect (line 118) | protected connect(connection: WebSocketHandlerConnection): boolean {
    method #resolveWebSocketUrl (line 151) | #resolveWebSocketUrl(url: string, baseUrl?: string): string {
  function createStopPropagationListener (line 172) | function createStopPropagationListener(handler: WebSocketHandler) {

FILE: src/core/handlers/common.ts
  type HandlerKind (line 1) | type HandlerKind = 'RequestHandler' | 'EventHandler'

FILE: src/core/http.ts
  type HttpRequestHandler (line 14) | type HttpRequestHandler = <
  type HttpResponseResolver (line 28) | type HttpResponseResolver<
  function createHttpHandler (line 38) | function createHttpHandler<Method extends HttpMethods | RegExp>(

FILE: src/core/index.ts
  type AnyHandler (line 33) | type AnyHandler = HttpHandler | GraphQLHandler | WebSocketHandler

FILE: src/core/isCommonAssetRequest.ts
  function isCommonAssetRequest (line 18) | function isCommonAssetRequest(request: Request): boolean {

FILE: src/core/passthrough.ts
  function passthrough (line 17) | function passthrough(): HttpResponse<any> {

FILE: src/core/sharedOptions.ts
  type SharedOptions (line 4) | interface SharedOptions {
  type LifeCycleEventsMap (line 16) | type LifeCycleEventsMap = {
  type LifeCycleEventEmitter (line 64) | type LifeCycleEventEmitter<

FILE: src/core/sse.ts
  type EventMapConstraint (line 17) | type EventMapConstraint = {
  type ServerSentEventResolverExtras (line 23) | type ServerSentEventResolverExtras<
  type ServerSentEventResolver (line 31) | type ServerSentEventResolver<
  type ServerSentEventRequestHandler (line 36) | type ServerSentEventRequestHandler = <
  type ServerSentEventMessage (line 45) | type ServerSentEventMessage<
  constant SSE_RESPONSE_INIT (line 71) | const SSE_RESPONSE_INIT: ResponseInit = {
  class ServerSentEventHandler (line 79) | class ServerSentEventHandler<
    method constructor (line 84) | constructor(path: Path, resolver: ServerSentEventResolver<EventMap, an...
    method predicate (line 117) | async predicate(args: {
    method log (line 149) | async log(_args: { request: Request; response: Response }): Promise<vo...
    method #attachClientLogger (line 157) | #attachClientLogger(
  type Values (line 202) | type Values<T> = T[keyof T]
  type Identity (line 203) | type Identity<T> = { [K in keyof T]: T[K] } & unknown
  type ToEventDiscriminatedUnion (line 204) | type ToEventDiscriminatedUnion<T> = Values<{
  type ServerSentEventClientEventMap (line 224) | type ServerSentEventClientEventMap = {
  class ServerSentEventClient (line 237) | class ServerSentEventClient<
    method constructor (line 244) | constructor(args: {
    method send (line 256) | public send(payload: ServerSentEventMessage<EventMap>): void {
    method dispatchEvent (line 275) | public dispatchEvent(event: Event) {
    method error (line 305) | public error(): void {
    method close (line 313) | public close(): void {
    method #sendRetry (line 318) | #sendRetry(retry: number): void {
    method #sendMessage (line 324) | #sendMessage(message: {
  class ServerSentEventServer (line 363) | class ServerSentEventServer {
    method constructor (line 367) | constructor(args: { request: Request; client: ServerSentEventClient<an...
    method connect (line 376) | public connect(): EventSource {
  type ObservableEventSourceInit (line 430) | interface ObservableEventSourceInit extends EventSourceInit {
  type EventHandler (line 434) | type EventHandler<EventType extends Event> = (
  class ObservableEventSource (line 448) | class ObservableEventSource extends EventTarget implements EventSource {
    method constructor (line 470) | constructor(url: string | URL, init?: ObservableEventSourceInit) {
    method onopen (line 495) | get onopen(): EventHandler<Event> | null {
    method onopen (line 499) | set onopen(handler: EventHandler<Event>) {
    method onmessage (line 507) | get onmessage(): EventHandler<MessageEvent> | null {
    method onmessage (line 510) | set onmessage(handler: EventHandler<MessageEvent>) {
    method onerror (line 518) | get onerror(): EventHandler<Event> | null {
    method oneerror (line 521) | set oneerror(handler: EventHandler<Event>) {
    method addEventListener (line 545) | public addEventListener(
    method removeEventListener (line 573) | public removeEventListener(
    method dispatchEvent (line 585) | public dispatchEvent(event: Event): boolean {
    method close (line 589) | public close(): void {
    method connect (line 594) | private async connect() {
    method processResponse (line 606) | private processResponse(response: Response): void {
    method announceConnection (line 629) | private announceConnection(): void {
    method interpretResponseBody (line 638) | private interpretResponseBody(response: Response): void {
    method processResponseEndOfBody (line 680) | private processResponseEndOfBody(response: Response): void {
    method reestablishConnection (line 686) | private async reestablishConnection(): Promise<void> {
    method failConnection (line 711) | private failConnection(): void {
  function isNetworkError (line 725) | function isNetworkError(response: Response): boolean {
  type ControlCharacters (line 735) | const enum ControlCharacters {
  type EventSourceMessage (line 742) | interface EventSourceMessage {
  class EventSourceParsingStream (line 749) | class EventSourceParsingStream extends WritableStream {
    method constructor (line 764) | constructor(
    method resetMessage (line 787) | private resetMessage(): void {
    method processResponseBodyChunk (line 796) | private processResponseBodyChunk(chunk: Uint8Array): void {
    method processLine (line 864) | private processLine(line: Uint8Array, fieldLength: number): void {

FILE: src/core/typeUtils.ts
  type Fn (line 1) | type Fn = (...arg: any[]) => any
  type MaybePromise (line 3) | type MaybePromise<T> = T | Promise<T>
  type RequiredDeep (line 5) | type RequiredDeep<
  type NoInfer (line 26) | type NoInfer<T> = [T][T extends any ? 0 : never]

FILE: src/core/utils/HttpResponse/decorators.ts
  type HttpResponseDecoratedInit (line 9) | interface HttpResponseDecoratedInit extends HttpResponseInit {
  function normalizeResponseInit (line 15) | function normalizeResponseInit(
  function decorateResponse (line 30) | function decorateResponse(

FILE: src/core/utils/cookieStore.ts
  class CookieStore (line 11) | class CookieStore {
    method constructor (line 16) | constructor() {
    method getCookies (line 29) | public getCookies(url: string): Array<Cookie> {
    method setCookie (line 33) | public async setCookie(cookieName: string, url: string): Promise<void> {
    method getCookieStoreIndex (line 38) | private getCookieStoreIndex(): MemoryCookieStoreIndex {
    method persist (line 71) | private persist(): void {

FILE: src/core/utils/executeHandlers.ts
  type HandlersExecutionResult (line 6) | interface HandlersExecutionResult {
  type ResponseResolutionContext (line 12) | interface ResponseResolutionContext {

FILE: src/core/utils/handleRequest.test.ts
  function setup (line 20) | function setup() {

FILE: src/core/utils/handleRequest.ts
  type HandleRequestOptions (line 14) | interface HandleRequestOptions {
  function handleRequest (line 36) | async function handleRequest(

FILE: src/core/utils/internal/Disposable.ts
  type DisposableSubscription (line 1) | type DisposableSubscription = () => void
  class Disposable (line 3) | class Disposable {
    method dispose (line 6) | public dispose() {

FILE: src/core/utils/internal/checkGlobals.ts
  function checkGlobals (line 4) | function checkGlobals() {

FILE: src/core/utils/internal/devUtils.ts
  constant LIBRARY_PREFIX (line 3) | const LIBRARY_PREFIX = '[MSW]'
  function formatMessage (line 8) | function formatMessage(message: string, ...positionals: any[]): string {
  function warn (line 16) | function warn(message: string, ...positionals: any[]): void {
  function error (line 23) | function error(message: string, ...positionals: any[]): void {
  class InternalError (line 39) | class InternalError extends Error {
    method constructor (line 40) | constructor(message: string) {

FILE: src/core/utils/internal/getCallFrame.test.ts
  class ErrorWithStack (line 6) | class ErrorWithStack extends Error {
    method constructor (line 7) | constructor(stack: string[] | undefined | null) {

FILE: src/core/utils/internal/getCallFrame.ts
  constant SOURCE_FRAME (line 2) | const SOURCE_FRAME = /[/\\]msw[/\\]src[/\\](.+)/
  constant BUILD_FRAME (line 4) | const BUILD_FRAME =
  function getCallFrame (line 10) | function getCallFrame(error: Error) {

FILE: src/core/utils/internal/hasRefCounted.test.ts
  method ref (line 6) | ref() {}
  method unref (line 7) | unref() {}
  method ref (line 14) | ref() {}
  method unref (line 15) | unref() {}

FILE: src/core/utils/internal/hasRefCounted.ts
  function hasRefCounted (line 1) | function hasRefCounted<T extends object>(

FILE: src/core/utils/internal/isHandlerKind.test.ts
  class MyHandler (line 20) | class MyHandler extends RequestHandler {
    method constructor (line 21) | constructor() {
    method log (line 25) | log() {}
  class MyEventHandler (line 49) | class MyEventHandler extends WebSocketHandler {
    method constructor (line 50) | constructor() {

FILE: src/core/utils/internal/isHandlerKind.ts
  function isHandlerKind (line 10) | function isHandlerKind<K extends HandlerKind>(kind: K) {

FILE: src/core/utils/internal/isIterable.ts
  type Iterable (line 5) | interface Iterable<T, TReturn, TNext> {
  type AsyncIterable (line 13) | interface AsyncIterable<T, TReturn, TNext> {
  function isIterable (line 20) | function isIterable<IteratorType>(

FILE: src/core/utils/internal/isObject.ts
  function isObject (line 4) | function isObject(value: any): value is Record<string, any> {

FILE: src/core/utils/internal/isStringEqual.ts
  function isStringEqual (line 4) | function isStringEqual(actual: string, expected: string): boolean {

FILE: src/core/utils/internal/jsonParse.ts
  function jsonParse (line 5) | function jsonParse<ValueType extends Record<string, any>>(

FILE: src/core/utils/internal/mergeRight.ts
  function mergeRight (line 7) | function mergeRight(

FILE: src/core/utils/internal/parseGraphQLRequest.ts
  type GraphQLInput (line 12) | interface GraphQLInput {
  type ParsedGraphQLQuery (line 17) | interface ParsedGraphQLQuery {
  type ParsedGraphQLRequest (line 22) | type ParsedGraphQLRequest<
  function parseDocumentNode (line 31) | function parseDocumentNode(node: DocumentNode): ParsedGraphQLQuery {
  function parseQuery (line 42) | async function parseQuery(query: string): Promise<ParsedGraphQLQuery | E...
  type GraphQLParsedOperationsMap (line 60) | type GraphQLParsedOperationsMap = Record<string, string[]>
  type GraphQLMultipartRequestBody (line 61) | type GraphQLMultipartRequestBody = {
  function extractMultipartVariables (line 68) | function extractMultipartVariables<VariablesType extends GraphQLVariables>(
  function getGraphQLInput (line 100) | async function getGraphQLInput(request: Request): Promise<GraphQLInput |...
  function parseGraphQLRequest (line 183) | async function parseGraphQLRequest(

FILE: src/core/utils/internal/parseMultipartData.test.ts
  function testMultipartDataWithContentType (line 29) | async function testMultipartDataWithContentType(

FILE: src/core/utils/internal/parseMultipartData.ts
  type ParsedContentHeaders (line 4) | interface ParsedContentHeaders {
  type ContentDispositionDirective (line 10) | interface ContentDispositionDirective {
  function parseContentHeaders (line 17) | function parseContentHeaders(headersString: string): ParsedContentHeaders {
  function parseMultipartData (line 46) | function parseMultipartData<T extends DefaultRequestMultipartBody>(

FILE: src/core/utils/internal/pipeEvents.ts
  function pipeEvents (line 6) | function pipeEvents<Events extends EventMap>(

FILE: src/core/utils/internal/requestHandlerUtils.ts
  function use (line 3) | function use(
  function restoreHandlers (line 10) | function restoreHandlers(handlers: Array<RequestHandler>): void {
  function resetHandlers (line 16) | function resetHandlers(

FILE: src/core/utils/internal/toReadonlyArray.ts
  function toReadonlyArray (line 4) | function toReadonlyArray<T>(source: Array<T>): ReadonlyArray<T> {

FILE: src/core/utils/internal/tryCatch.ts
  function tryCatch (line 1) | function tryCatch<Fn extends (...args: any[]) => any>(

FILE: src/core/utils/logging/getStatusCodeColor.ts
  type StatusCodeColor (line 1) | enum StatusCodeColor {
  function getStatusCodeColor (line 10) | function getStatusCodeColor(status: number): StatusCodeColor {

FILE: src/core/utils/logging/getTimestamp.ts
  type GetTimestampOptions (line 1) | interface GetTimestampOptions {
  function getTimestamp (line 8) | function getTimestamp(options?: GetTimestampOptions): string {

FILE: src/core/utils/logging/serializeRequest.ts
  type LoggedRequest (line 1) | interface LoggedRequest {
  function serializeRequest (line 11) | async function serializeRequest(

FILE: src/core/utils/logging/serializeResponse.ts
  type SerializedResponse (line 5) | interface SerializedResponse {
  function serializeResponse (line 12) | async function serializeResponse(

FILE: src/core/utils/matching/matchRequestUrl.ts
  type Path (line 5) | type Path = string | RegExp
  type PathParams (line 6) | type PathParams<KeyType extends keyof any = string> = {
  type Match (line 10) | interface Match {
  function coercePath (line 19) | function coercePath(path: string): string {
  function matchRequestUrl (line 58) | function matchRequestUrl(url: URL, path: Path, baseUrl?: string): Match {
  function isPath (line 75) | function isPath(value: unknown): value is Path {

FILE: src/core/utils/matching/normalizePath.ts
  function normalizePath (line 13) | function normalizePath(path: Path, baseUrl?: string): Path {

FILE: src/core/utils/request/getAllAcceptedMimeTypes.ts
  function getAllAcceptedMimeTypes (line 12) | function getAllAcceptedMimeTypes(

FILE: src/core/utils/request/getRequestCookies.ts
  function parseCookies (line 7) | function parseCookies(input: string): Record<string, string> {
  function getAllDocumentCookies (line 20) | function getAllDocumentCookies() {
  function getDocumentCookies (line 24) | function getDocumentCookies(request: Request): Record<string, string> {
  function getAllRequestCookies (line 51) | function getAllRequestCookies(request: Request): Record<string, string> {

FILE: src/core/utils/request/onUnhandledRequest.ts
  type UnhandledRequestPrint (line 5) | interface UnhandledRequestPrint {
  type UnhandledRequestCallback (line 10) | type UnhandledRequestCallback = (
  type UnhandledRequestStrategy (line 15) | type UnhandledRequestStrategy =
  function onUnhandledRequest (line 21) | async function onUnhandledRequest(

FILE: src/core/utils/request/storeResponseCookies.ts
  function storeResponseCookies (line 4) | async function storeResponseCookies(

FILE: src/core/utils/request/toPublicUrl.ts
  function toPublicUrl (line 5) | function toPublicUrl(url: string | URL): string {

FILE: src/core/utils/toResponseInit.ts
  function toResponseInit (line 1) | function toResponseInit(response: Response): ResponseInit {

FILE: src/core/utils/url/cleanUrl.ts
  constant REDUNDANT_CHARACTERS_EXP (line 1) | const REDUNDANT_CHARACTERS_EXP = /[?|#].*$/g
  function cleanUrl (line 7) | function cleanUrl(path: string): string {

FILE: src/core/utils/url/getAbsoluteUrl.ts
  function getAbsoluteUrl (line 6) | function getAbsoluteUrl(path: string, baseUrl?: string): string {

FILE: src/core/utils/url/isAbsoluteUrl.ts
  function isAbsoluteUrl (line 4) | function isAbsoluteUrl(url: string): boolean {

FILE: src/core/ws.ts
  type WebSocketEventListener (line 23) | type WebSocketEventListener<
  type WebSocketLink (line 27) | type WebSocketLink = {
  function createWebSocketLinkHandler (line 92) | function createWebSocketLinkHandler(url: Path): WebSocketLink {

FILE: src/core/ws/WebSocketClientManager.test.ts
  class TestWebSocketTransport (line 26) | class TestWebSocketTransport extends EventTarget implements WebSocketTra...
    method send (line 27) | send(_data: WebSocketData): void {}
    method close (line 28) | close(_code?: number | undefined, _reason?: string | undefined): void {}

FILE: src/core/ws/WebSocketClientManager.ts
  type WebSocketBroadcastChannelMessage (line 10) | type WebSocketBroadcastChannelMessage =
  class WebSocketClientManager (line 31) | class WebSocketClientManager {
    method constructor (line 36) | constructor(private channel: BroadcastChannel) {
    method flushDatabaseToMemory (line 62) | private async flushDatabaseToMemory() {
    method removeRuntimeClients (line 86) | private async removeRuntimeClients(): Promise<void> {
    method clients (line 96) | get clients(): Set<WebSocketClientConnectionProtocol> {
    method notifyOthersAboutDatabaseUpdate (line 104) | private notifyOthersAboutDatabaseUpdate(): void {
    method addClient (line 108) | private async addClient(
    method addConnection (line 124) | public async addConnection(
  class WebSocketRemoteClientConnection (line 186) | class WebSocketRemoteClientConnection
    method constructor (line 189) | constructor(
    method send (line 195) | send(data: WebSocketData): void {
    method close (line 205) | close(code?: number | undefined, reason?: string | undefined): void {
    method addEventListener (line 216) | addEventListener<EventType extends keyof WebSocketClientEventMap>(
    method removeEventListener (line 229) | removeEventListener<EventType extends keyof WebSocketClientEventMap>(

FILE: src/core/ws/WebSocketClientStore.ts
  type SerializedWebSocketClient (line 3) | interface SerializedWebSocketClient {

FILE: src/core/ws/WebSocketIndexedDBClientStore.ts
  constant DB_NAME (line 8) | const DB_NAME = 'msw-websocket-clients'
  constant DB_STORE_NAME (line 9) | const DB_STORE_NAME = 'clients'
  class WebSocketIndexedDBClientStore (line 11) | class WebSocketIndexedDBClientStore implements WebSocketClientStore {
    method constructor (line 14) | constructor() {
    method add (line 18) | public async add(client: WebSocketClientConnectionProtocol): Promise<v...
    method getAll (line 48) | public async getAll(): Promise<Array<SerializedWebSocketClient>> {
    method deleteMany (line 70) | public async deleteMany(clientIds: Array<string>): Promise<void> {
    method createDatabase (line 93) | private async createDatabase(): Promise<IDBDatabase> {
    method getStore (line 136) | private async getStore(): Promise<IDBObjectStore> {

FILE: src/core/ws/WebSocketMemoryClientStore.ts
  class WebSocketMemoryClientStore (line 7) | class WebSocketMemoryClientStore implements WebSocketClientStore {
    method constructor (line 10) | constructor() {
    method add (line 14) | public async add(client: WebSocketClientConnectionProtocol): Promise<v...
    method getAll (line 18) | public getAll(): Promise<Array<SerializedWebSocketClient>> {
    method deleteMany (line 22) | public async deleteMany(clientIds: Array<string>): Promise<void> {

FILE: src/core/ws/handleWebSocketEvent.ts
  type HandleWebSocketEventOptions (line 11) | interface HandleWebSocketEventOptions {
  function handleWebSocketEvent (line 18) | function handleWebSocketEvent(options: HandleWebSocketEventOptions) {

FILE: src/core/ws/utils/attachWebSocketLogger.ts
  function attachWebSocketLogger (line 19) | function attachWebSocketLogger(
  function logConnectionOpen (line 113) | function logConnectionOpen(client: WebSocketClientConnection) {
  function logConnectionClose (line 126) | function logConnectionClose(event: CloseEvent) {
  function logClientError (line 142) | function logClientError(event: Event) {
  function logOutgoingClientMessage (line 161) | async function logOutgoingClientMessage(event: MessageEvent<WebSocketDat...
  function logOutgoingMockedClientMessage (line 184) | async function logOutgoingMockedClientMessage(
  function logIncomingMockedClientMessage (line 208) | async function logIncomingMockedClientMessage(
  function logIncomingServerMessage (line 228) | async function logIncomingServerMessage(event: MessageEvent<WebSocketDat...

FILE: src/core/ws/utils/getMessageLength.ts
  function getMessageLength (line 10) | function getMessageLength(data: WebSocketData): number {

FILE: src/core/ws/utils/getPublicData.ts
  function getPublicData (line 5) | async function getPublicData(data: WebSocketData): Promise<string> {

FILE: src/core/ws/utils/truncateMessage.ts
  constant MAX_LENGTH (line 1) | const MAX_LENGTH = 24
  function truncateMessage (line 3) | function truncateMessage(message: string): string {

FILE: src/mockServiceWorker.js
  constant PACKAGE_VERSION (line 10) | const PACKAGE_VERSION = '<PACKAGE_VERSION>'
  constant INTEGRITY_CHECKSUM (line 11) | const INTEGRITY_CHECKSUM = '<INTEGRITY_CHECKSUM>'
  constant IS_MOCKED_RESPONSE (line 12) | const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
  function handleRequest (line 124) | async function handleRequest(event, requestId, requestInterceptedAt) {
  function resolveMainClient (line 177) | async function resolveMainClient(event) {
  function getResponse (line 211) | async function getResponse(event, client, requestId, requestInterceptedA...
  function sendToClient (line 288) | function sendToClient(client, message, transferrables = []) {
  function respondWithMock (line 311) | function respondWithMock(response) {
  function serializeRequest (line 333) | async function serializeRequest(request) {

FILE: src/native/index.ts
  function setupServer (line 12) | function setupServer(

FILE: src/node/SetupServerApi.ts
  type RequestHandlersContext (line 14) | type RequestHandlersContext = {
  class AsyncHandlersController (line 24) | class AsyncHandlersController implements HandlersController {
    method constructor (line 27) | constructor(initialHandlers: Array<RequestHandler | WebSocketHandler>) {
    method context (line 31) | get context(): RequestHandlersContext {
    method prepend (line 35) | public prepend(runtimeHandlers: Array<RequestHandler | WebSocketHandle...
    method reset (line 39) | public reset(nextHandlers: Array<RequestHandler | WebSocketHandler>) {
    method currentHandlers (line 46) | public currentHandlers(): Array<RequestHandler | WebSocketHandler> {
  class SetupServerApi (line 51) | class SetupServerApi
    method constructor (line 55) | constructor(
    method boundary (line 68) | public boundary<Args extends Array<any>, R>(
    method close (line 83) | public close(): void {

FILE: src/node/SetupServerCommonApi.ts
  constant DEFAULT_LISTEN_OPTIONS (line 25) | const DEFAULT_LISTEN_OPTIONS: RequiredDeep<SharedOptions> = {
  class SetupServerCommonApi (line 29) | class SetupServerCommonApi
    method constructor (line 39) | constructor(
    method init (line 56) | private init(): void {
    method listen (line 135) | public listen(options: Partial<SharedOptions> = {}): void {
    method close (line 166) | public close(): void {

FILE: src/node/glossary.ts
  type SetupServerCommon (line 10) | interface SetupServerCommon {
  type SetupServer (line 62) | interface SetupServer extends SetupServerCommon {

FILE: test/browser/graphql-api/custom-predicate.test.ts
  constant PREDICATE_EXAMPLE (line 13) | const PREDICATE_EXAMPLE = new URL(

FILE: test/browser/graphql-api/extensions.mocks.ts
  type LoginQuery (line 4) | interface LoginQuery {

FILE: test/browser/graphql-api/link.mocks.ts
  type GetUserQuery (line 7) | interface GetUserQuery {
  type PaymentQuery (line 14) | interface PaymentQuery {
  type GetUserQuery (line 20) | interface GetUserQuery {

FILE: test/browser/graphql-api/link.test.ts
  constant LINK_EXAMPLE (line 5) | const LINK_EXAMPLE = new URL('./link.mocks.ts', import.meta.url)

FILE: test/browser/graphql-api/logging.mocks.ts
  type GetUserDetailQuery (line 4) | interface GetUserDetailQuery {
  type LoginQuery (line 11) | interface LoginQuery {

FILE: test/browser/graphql-api/logging.test.ts
  constant LOGGING_EXAMPLE (line 6) | const LOGGING_EXAMPLE = new URL('./logging.mocks.ts', import.meta.url)

FILE: test/browser/graphql-api/mutation.mocks.ts
  type LogoutQuery (line 4) | interface LogoutQuery {

FILE: test/browser/graphql-api/mutation.test.ts
  constant MUTATION_EXAMPLE (line 5) | const MUTATION_EXAMPLE = new URL('./mutation.mocks.ts', import.meta.url)
  function endpoint (line 11) | function endpoint(): string {

FILE: test/browser/graphql-api/operation-reference.test.ts
  constant OPERATION_REFERENCE_EXAMPLE (line 3) | const OPERATION_REFERENCE_EXAMPLE = new URL(

FILE: test/browser/graphql-api/operation.test.ts
  constant OPERATION_EXAMPLE (line 5) | const OPERATION_EXAMPLE = new URL('./operation.mocks.ts', import.meta.url)

FILE: test/browser/graphql-api/query.mocks.ts
  type GetUserDetailQuery (line 4) | interface GetUserDetailQuery {

FILE: test/browser/graphql-api/query.test.ts
  constant EXAMPLE_PATH (line 5) | const EXAMPLE_PATH = new URL('./query.mocks.ts', import.meta.url)

FILE: test/browser/graphql-api/response-patching.mocks.ts
  type GetUserQuery (line 5) | interface GetUserQuery {

FILE: test/browser/graphql-api/variables.mocks.ts
  type GetGitHubUserQuery (line 4) | interface GetGitHubUserQuery {
  type GetGitHubUserQueryVariables (line 11) | interface GetGitHubUserQueryVariables {
  type DeletePostQuery (line 15) | interface DeletePostQuery {
  type DeletePostQueryVariables (line 21) | interface DeletePostQueryVariables {
  type GetActiveUserQuery (line 25) | interface GetActiveUserQuery {
  type GetActiveUserQueryVariables (line 31) | interface GetActiveUserQueryVariables {

FILE: test/browser/graphql-api/variables.test.ts
  constant EXAMPLE_PATH (line 4) | const EXAMPLE_PATH = new URL('./variables.mocks.ts', import.meta.url)

FILE: test/browser/msw-api/context/delay.test.ts
  constant DELAY_EXAMPLE (line 3) | const DELAY_EXAMPLE = new URL('./delay.mocks.ts', import.meta.url)
  type Matchers (line 7) | interface Matchers<R> {
  method toRoughlyEqual (line 18) | toRoughlyEqual(actual: number, expected: number, deviation: number) {

FILE: test/browser/msw-api/distribution/iife.test.ts
  method beforeNavigation (line 12) | beforeNavigation(compilation) {

FILE: test/browser/msw-api/integrity-check.test.ts
  method beforeNavigation (line 52) | beforeNavigation(compilation) {

FILE: test/browser/msw-api/req/passthrough.test.ts
  constant PASSTHROUGH_EXAMPLE (line 5) | const PASSTHROUGH_EXAMPLE = new URL('./passthrough.mocks.ts', import.met...
  type ResponseBody (line 16) | interface ResponseBody {

FILE: test/browser/msw-api/setup-worker/fallback-mode/fallback-mode.test.ts
  function gotoStaticPage (line 18) | async function gotoStaticPage(page: Page, workerIndex: number): Promise<...
  type DirectFetchResponse (line 25) | interface DirectFetchResponse {
  function createFetchWithoutNetwork (line 32) | function createFetchWithoutNetwork(page: Page) {

FILE: test/browser/msw-api/setup-worker/life-cycle-events/on.test.ts
  constant ON_EXAMPLE (line 12) | const ON_EXAMPLE = new URL('./on.mocks.ts', import.meta.url)
  function getRequestId (line 30) | function getRequestId(messages: ConsoleMessages) {

FILE: test/browser/msw-api/setup-worker/life-cycle-events/removeAllListeners.test.ts
  constant ON_EXAMPLE (line 10) | const ON_EXAMPLE = new URL('./on.mocks.ts', import.meta.url)

FILE: test/browser/msw-api/setup-worker/listHandlers.test.ts
  constant LIST_HANDLER_EXAMPLE (line 13) | const LIST_HANDLER_EXAMPLE = new URL('./listHandlers.mocks.ts', import.m...

FILE: test/browser/msw-api/setup-worker/resetHandlers.test.ts
  constant USE_EXAMPLE (line 14) | const USE_EXAMPLE = new URL('./use.mocks.ts', import.meta.url)

FILE: test/browser/msw-api/setup-worker/response-logging.test.ts
  function createResponseLogRegexp (line 3) | function createResponseLogRegexp(username: string): RegExp {

FILE: test/browser/msw-api/setup-worker/scenarios/iframe-isolated-response/iframe-isolated-response.test.ts
  function getFrameById (line 9) | function getFrameById(id: string, page: Page): Frame {
  method beforeNavigation (line 30) | beforeNavigation(compilation) {

FILE: test/browser/msw-api/setup-worker/scenarios/iframe/iframe.test.ts
  type Window (line 6) | interface Window {
  function findFrame (line 11) | function findFrame(frame: Frame) {
  method beforeNavigation (line 25) | beforeNavigation(compilation) {
  method beforeNavigation (line 45) | beforeNavigation(compilation) {
  method beforeNavigation (line 71) | beforeNavigation(compilation) {

FILE: test/browser/msw-api/setup-worker/scenarios/scope/scope-validation.test.ts
  method beforeNavigation (line 13) | beforeNavigation(compilation) {
  method beforeNavigation (line 54) | beforeNavigation(compilation) {

FILE: test/browser/msw-api/setup-worker/scenarios/shared-worker/shared-worker.test.ts
  method beforeNavigation (line 15) | beforeNavigation(compilation) {

FILE: test/browser/msw-api/setup-worker/start/find-worker.mocks.ts
  method findWorker (line 15) | findWorker(scriptURL, mockServiceWorkerUrl) {

FILE: test/browser/msw-api/setup-worker/start/on-unhandled-request/callback-print.mocks.ts
  method onUnhandledRequest (line 11) | onUnhandledRequest(request, print) {

FILE: test/browser/msw-api/setup-worker/start/on-unhandled-request/callback-throws.mocks.ts
  method onUnhandledRequest (line 11) | onUnhandledRequest(request) {

FILE: test/browser/msw-api/setup-worker/start/on-unhandled-request/callback.mocks.ts
  method onUnhandledRequest (line 11) | onUnhandledRequest(request) {

FILE: test/browser/msw-api/setup-worker/start/start.mocks.ts
  method startWorker (line 12) | async startWorker() {

FILE: test/browser/msw-api/setup-worker/start/start.test.ts
  method beforeNavigation (line 14) | beforeNavigation(compilation) {

FILE: test/browser/msw-api/setup-worker/stop.test.ts
  function byStopMessage (line 97) | function byStopMessage(text: string): boolean {

FILE: test/browser/msw-api/setup-worker/stop/in-flight-request.test.ts
  method beforeNavigation (line 39) | beforeNavigation(compilation) {

FILE: test/browser/msw-api/setup-worker/stop/quiet.test.ts
  constant QUIET_EXAMPLE (line 10) | const QUIET_EXAMPLE = new URL('./quiet.mocks.ts', import.meta.url)

FILE: test/browser/msw-api/unregister.test.ts
  method beforeNavigation (line 20) | beforeNavigation(compilation) {

FILE: test/browser/playwright.extend.ts
  type TestFixtures (line 25) | interface TestFixtures {
  type FetchOptions (line 57) | interface FetchOptions {
  type GraphQLQueryOptions (line 62) | interface GraphQLQueryOptions {
  type GraphQLMultipartDataOptions (line 69) | interface GraphQLMultipartDataOptions {
  method createServer (line 75) | async createServer({}, use) {
  method webpackServer (line 86) | async webpackServer({}, use) {
  method loadExample (line 89) | async loadExample({ page, webpackServer, waitForMswActivation }, use) {
  method waitFor (line 138) | async waitFor({}, use) {
  method waitForMswActivation (line 141) | async waitForMswActivation({ spyOnConsole }, use) {
  method fetch (line 159) | async fetch({ page }, use) {
  method query (line 199) | async query({ page }, use) {
  method makeUrl (line 309) | async makeUrl({ webpackServer }, use) {
  method spyOnConsole (line 314) | async spyOnConsole({ page }, use) {
  method defineWebSocketServer (line 324) | async defineWebSocketServer({}, use) {

FILE: test/browser/rest-api/body.test.ts
  constant EXAMPLE_PATH (line 3) | const EXAMPLE_PATH = new URL('./body.mocks.ts', import.meta.url)

FILE: test/browser/rest-api/generator.test.ts
  type ExpectedResponseBody (line 3) | type ExpectedResponseBody =

FILE: test/browser/rest-api/headers-multiple.test.ts
  constant EXAMPLE_PATH (line 3) | const EXAMPLE_PATH = new URL('./headers-multiple.mocks.ts', import.meta....

FILE: test/browser/rest-api/params.mocks.ts
  type RequestParams (line 4) | type RequestParams = {

FILE: test/browser/rest-api/query.test.ts
  constant EXAMPLE_PATH (line 3) | const EXAMPLE_PATH = new URL('./query.mocks.ts', import.meta.url)

FILE: test/browser/rest-api/request/body/body-form-data.test.ts
  type Window (line 4) | interface Window {

FILE: test/browser/rest-api/request/matching/all.test.ts
  function forEachMethod (line 7) | function forEachMethod(

FILE: test/browser/rest-api/request/matching/custom-predicate.test.ts
  constant PREDICATE_EXAMPLE (line 12) | const PREDICATE_EXAMPLE = new URL(

FILE: test/browser/rest-api/request/request-cookies.test.ts
  function bakeCookies (line 4) | async function bakeCookies(page: Page, cookies: Array<string>) {

FILE: test/browser/rest-api/response-patching.test.ts
  method waitForResponse (line 87) | waitForResponse(res) {
  method waitForResponse (line 144) | waitForResponse(res) {
  method waitForResponse (line 182) | waitForResponse(res) {
  method waitForResponse (line 219) | waitForResponse(res) {

FILE: test/browser/rest-api/response/body/body-stream.mocks.ts
  method start (line 10) | async start(controller) {

FILE: test/browser/rest-api/send-beacon.test.ts
  method beforeNavigation (line 37) | beforeNavigation(compilation) {

FILE: test/browser/rest-api/status.test.ts
  constant EXAMPLE_PATH (line 3) | const EXAMPLE_PATH = new URL('./status.mocks.ts', import.meta.url)

FILE: test/browser/setup/webpackHttpServer.ts
  function getWebpackServer (line 12) | async function getWebpackServer(): Promise<WebpackHttpServer> {
  function startWebpackServer (line 22) | async function startWebpackServer(): Promise<WebpackHttpServer> {

FILE: test/browser/setup/workerConsole.ts
  type WorkerConsoleMessageType (line 5) | type WorkerConsoleMessageType =
  type WorkerConsoleEventMap (line 36) | type WorkerConsoleEventMap = {
  type InternalWorkerConsoleMessageData (line 40) | type InternalWorkerConsoleMessageData = {
  type Window (line 49) | interface Window {
  class WorkerConsole (line 57) | class WorkerConsole extends Emitter<WorkerConsoleEventMap> {
    method addMessage (line 60) | private addMessage(
    method init (line 68) | public async init(page: Page): Promise<void> {
    method removeAllListeners (line 107) | public removeAllListeners(...args: Array<any>) {
  function getWorkerScriptPatch (line 120) | function getWorkerScriptPatch(): string {

FILE: test/browser/sse-api/sse.client.send.multiline.test.ts
  constant EXAMPLE_URL (line 12) | const EXAMPLE_URL = new URL('./sse.mocks.ts', import.meta.url)

FILE: test/browser/sse-api/sse.client.send.test.ts
  constant EXAMPLE_URL (line 12) | const EXAMPLE_URL = new URL('./sse.mocks.ts', import.meta.url)

FILE: test/browser/sse-api/sse.quiet.test.ts
  constant EXAMPLE_URL (line 12) | const EXAMPLE_URL = new URL('./sse.mocks.ts', import.meta.url)

FILE: test/browser/sse-api/sse.retry.test.ts
  constant EXAMPLE_URL (line 12) | const EXAMPLE_URL = new URL('./sse.mocks.ts', import.meta.url)

FILE: test/browser/sse-api/sse.server.connect.test.ts
  constant EXAMPLE_URL (line 13) | const EXAMPLE_URL = new URL('./sse.mocks.ts', import.meta.url)
  method apply (line 16) | apply(target, thisArg, argArray) {
  method defineRoutes (line 32) | defineRoutes(routes) {
  method defineRoutes (line 88) | defineRoutes(routes) {
  method defineRoutes (line 144) | defineRoutes(routes) {
  method defineRoutes (line 202) | defineRoutes(routes) {
  method defineRoutes (line 254) | defineRoutes(routes) {

FILE: test/browser/sse-api/sse.use.test.ts
  constant EXAMPLE_URL (line 12) | const EXAMPLE_URL = new URL('./sse.mocks.ts', import.meta.url)

FILE: test/browser/sse-api/sse.with-credentials.test.ts
  constant EXAMPLE_URL (line 12) | const EXAMPLE_URL = new URL('./sse.mocks.ts', import.meta.url)

FILE: test/browser/third-party/axios-upload.runtime.js
  method onDownloadProgress (line 31) | onDownloadProgress(event) {

FILE: test/browser/ws-api/ws.apply.browser.test.ts
  type Window (line 6) | interface Window {

FILE: test/browser/ws-api/ws.client.send.test.ts
  type Window (line 7) | interface Window {
  function createSocketAndGetFirstMessage (line 59) | async function createSocketAndGetFirstMessage(page: Page) {

FILE: test/browser/ws-api/ws.clients.browser.test.ts
  type Window (line 6) | interface Window {

FILE: test/browser/ws-api/ws.intercept.client.browser.test.ts
  type Window (line 6) | interface Window {

FILE: test/browser/ws-api/ws.intercept.server.browser.test.ts
  type Window (line 6) | interface Window {

FILE: test/browser/ws-api/ws.logging.browser.test.ts
  type Window (line 6) | interface Window {

FILE: test/browser/ws-api/ws.server.connect.browser.test.ts
  type Window (line 6) | interface Window {

FILE: test/browser/ws-api/ws.use.browser.test.ts
  type Window (line 6) | interface Window {

FILE: test/e2e/auto-update-worker.node.test.ts
  constant TARBALL_PATH (line 6) | const TARBALL_PATH = inject('tarballPath')

FILE: test/e2e/cli-init.node.test.ts
  constant CLI_PATH (line 12) | const CLI_PATH = url.fileURLToPath(
  function readJson (line 16) | function readJson(filePath: string) {
  function init (line 43) | async function init(inlineArgs: Array<string>): ReturnType<typeof fsMock...

FILE: test/e2e/vitest.d.ts
  type ProvidedContext (line 2) | interface ProvidedContext {

FILE: test/e2e/vitest.global.setup.ts
  function setup (line 8) | function setup({ provide }: GlobalSetupContext) {

FILE: test/modules/browser/esm-browser.test.ts
  type DevServer (line 11) | type DevServer = Awaited<ReturnType<typeof startDevServer>>
  function getDevServerUrl (line 22) | function getDevServerUrl(): string {

FILE: test/modules/browser/playwright.config.ts
  constant TEST_DIR (line 4) | const TEST_DIR = url.fileURLToPath(new URL('./', import.meta.url))

FILE: test/modules/module-utils.ts
  function getLibraryTarball (line 7) | async function getLibraryTarball(): Promise<string> {
  function installLibrary (line 35) | async function installLibrary(projectPath: string) {

FILE: test/node/graphql-api/batched-queries.apollo.test.ts
  function batchedGraphQLQuery (line 33) | function batchedGraphQLQuery(url: string, handlers: Array<RequestHandler...

FILE: test/node/graphql-api/batched-queries.batched-execute.test.ts
  method fieldResolver (line 73) | async fieldResolver(source, args, context, info) {

FILE: test/node/msw-api/context/delay.node.test.ts
  function makeRequest (line 21) | async function makeRequest(url: string) {

FILE: test/node/msw-api/req/passthrough.node.test.ts
  type ResponseBody (line 19) | interface ResponseBody {

FILE: test/node/msw-api/setup-server/life-cycle-events/on.node.test.ts
  function spyOnEvents (line 14) | function spyOnEvents(server: SetupServerApi) {

FILE: test/node/msw-api/setup-server/scenarios/generator.node.test.ts
  type ExpectedResponseBody (line 67) | type ExpectedResponseBody = {
  type ExpectedResponseBody (line 91) | type ExpectedResponseBody =

FILE: test/node/msw-api/setup-server/scenarios/graphql.node.test.ts
  constant GET_USER_DETAIL (line 10) | const GET_USER_DETAIL = gql`
  constant LOGIN (line 20) | const LOGIN = gql`

FILE: test/node/msw-api/setup-server/scenarios/on-unhandled-request/callback-throws.node.test.ts
  method onUnhandledRequest (line 15) | onUnhandledRequest(request) {

FILE: test/node/msw-api/setup-server/scenarios/response-patching.node.test.ts
  type ResponseBody (line 17) | interface ResponseBody {

FILE: test/node/regressions/many-request-handlers-jsdom.test.ts
  constant NUMBER_OF_REQUEST_HANDLERS (line 20) | const NUMBER_OF_REQUEST_HANDLERS = 100

FILE: test/node/regressions/many-request-handlers.test.ts
  constant NUMBER_OF_REQUEST_HANDLERS (line 20) | const NUMBER_OF_REQUEST_HANDLERS = 100

FILE: test/node/rest-api/request/body/body-arraybuffer.node.test.ts
  function encodeBuffer (line 7) | function encodeBuffer(value: unknown) {

FILE: test/node/rest-api/request/matching/all.node.test.ts
  function forEachMethod (line 33) | async function forEachMethod(callback: (method: HttpMethods) => unknown) {

FILE: test/node/rest-api/response/body-binary.node.test.ts
  function getImageBuffer (line 9) | function getImageBuffer() {

FILE: test/node/rest-api/response/body-stream.node.test.ts
  type CustomMatchers (line 6) | interface CustomMatchers<R = unknown> {
  type Matchers (line 11) | interface Matchers<T = any> extends CustomMatchers<T> {}
  method toRoughlyEqual (line 19) | toRoughlyEqual(actual, expected, deviation) {
  method start (line 58) | start(controller) {
  method start (line 87) | async start(controller) {

FILE: test/node/rest-api/response/generator.test.ts
  function fetchJson (line 9) | async function fetchJson(input: string | URL | Request, init?: RequestIn...

FILE: test/support/WebSocketServer.ts
  type WebSocketEventMap (line 8) | type WebSocketEventMap = {
  class WebSocketServer (line 12) | class WebSocketServer extends Emitter<WebSocketEventMap> {
    method constructor (line 17) | constructor() {
    method url (line 33) | get url(): string {
    method listen (line 41) | public async listen(port = 0): Promise<void> {
    method resetState (line 51) | public resetState(): void {
    method closeAllClients (line 56) | public closeAllClients(): void {
    method close (line 62) | public async close(): Promise<void> {

FILE: test/support/alias.ts
  constant ROOT_URL (line 4) | const ROOT_URL = new URL('../../', import.meta.url)
  function fromRoot (line 6) | function fromRoot(...paths: Array<string>): string {

FILE: test/support/environments/vitest-environment-node-websocket.ts
  method setup (line 11) | async setup(global, options) {

FILE: test/support/graphql.ts
  type GraphQLClientOPtions (line 15) | interface GraphQLClientOPtions {
  type GraphQLOperationInput (line 20) | interface GraphQLOperationInput {
  function createGraphQLClient (line 30) | function createGraphQLClient(options: GraphQLClientOPtions) {
  class TypedDocumentString (line 58) | class TypedDocumentString<TResult, TVariables>
    method constructor (line 64) | constructor(
    method toString (line 71) | toString(): string & DocumentTypeDecoration<TResult, TVariables> {
  function createTypedDocumentString (line 76) | function createTypedDocumentString<TResult = any, TVariables = any>(
  function createTypedDocumentNode (line 82) | function createTypedDocumentNode<TResult = any, TVariables = any>(

FILE: test/support/utils.ts
  function sleep (line 5) | function sleep(duration: number) {
  function fromTemp (line 11) | function fromTemp(...segments: string[]) {
  function waitForClientRequest (line 17) | async function waitForClientRequest(request: ClientRequest): Promise<{

FILE: test/support/waitFor.ts
  constant RETRY_INTERVAL (line 3) | const RETRY_INTERVAL = 500
  constant MAX_RETRIES (line 4) | const MAX_RETRIES = 5
  function waitFor (line 6) | async function waitFor(fn: () => unknown): Promise<void> {

FILE: test/typings/custom-resolver.test-d.ts
  function withDelay (line 20) | function withDelay<
  function identityGraphQLResolver (line 48) | function identityGraphQLResolver<

FILE: test/typings/http.test-d.ts
  type Params (line 33) | type Params = { a: string; b: string[] }
  type Params (line 40) | type Params = { id: string }
  type PostPathParameters (line 47) | interface PostPathParameters {
  type ResponseBody (line 229) | type ResponseBody = {
  type ResponseBodyType (line 260) | type ResponseBodyType = { id: number }
  type ResponseBodyInterface (line 268) | interface ResponseBodyInterface {
  type ResponseBody (line 319) | type ResponseBody = {

FILE: test/typings/regressions/default-resolver-type.test-d.ts
  function handle (line 7) | function handle(resolver?: HttpResponseResolver<never, never, string>) {

FILE: test/typings/regressions/response-body-type.test-d.ts
  function myHandler (line 7) | function myHandler<CustomResponseBodyType extends DefaultBodyType>(

FILE: test/typings/vitest.config.ts
  constant TEST_ROOT (line 9) | const TEST_ROOT = url.fileURLToPath(new URL('./', import.meta.url))

FILE: tsup.config.ts
  constant SERVICE_WORKER_CHECKSUM (line 21) | const SERVICE_WORKER_CHECKSUM = getWorkerChecksum()
Condensed preview — 584 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,131K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 37,
    "preview": "github: mswjs\nopen_collective: mswjs\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/01-issue-browser.yml",
    "chars": 2382,
    "preview": "name: 'Bug report (Browser)'\ndescription: I experience unexpected behavior using the library in a browser.\nlabels: ['bug"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/02-issue-nodejs.yml",
    "chars": 2475,
    "preview": "name: 'Bug report (Node.js)'\ndescription: I experience unexpected behavior using the library in Node.js (Vitest/React Na"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/03-feature.yml",
    "chars": 1019,
    "preview": "name: 'Feature request'\ndescription: Propose a feature or improvement.\nlabels: [feature]\nbody:\n  - type: markdown\n    at"
  },
  {
    "path": ".github/workflows/auto.yml",
    "chars": 257,
    "preview": "name: auto\n\non: [push]\n\njobs:\n  cancel-previous-workflows:\n    runs-on: macos-latest\n    timeout-minutes: 3\n    steps:\n "
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 6219,
    "preview": "name: ci\n\non:\n  push:\n    branches: [main]\n  pull_request:\n  workflow_dispatch:\n\njobs:\n  build-20:\n    name: build (20)\n"
  },
  {
    "path": ".github/workflows/compat.yml",
    "chars": 2030,
    "preview": "name: compat\n\non:\n  push:\n    branches: [main]\n  pull_request:\n  workflow_dispatch:\n\njobs:\n  # Validate the package.json"
  },
  {
    "path": ".github/workflows/lock-closed-issues.yml",
    "chars": 357,
    "preview": "name: locked-closed-issues\n\non:\n  schedule:\n    - cron: '0 0 * * *'\n\npermissions:\n  issues: write\n\njobs:\n  action:\n    r"
  },
  {
    "path": ".github/workflows/release-preview.yml",
    "chars": 860,
    "preview": "name: release-preview\n\non:\n  push:\n    branches-ignore:\n      - 'main'\n    tags:\n      - '!**'\n  workflow_dispatch:\n\njob"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1994,
    "preview": "name: release\n\non:\n  schedule:\n    - cron: '0 1 * * *'\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on: macos-latest\n  "
  },
  {
    "path": ".github/workflows/smoke-test.yml",
    "chars": 812,
    "preview": "name: smoke-test\n\non:\n  # Always run smoke tests upon a successful\n  # \"ci\" job completion on \"main\".\n  workflow_run:\n  "
  },
  {
    "path": ".github/workflows/typescript-nightly.yml",
    "chars": 1833,
    "preview": "name: typescript-nightly\n\non:\n  schedule:\n    # Schedule to run nightly at midnight\n    - cron: '0 0 * * *'\n  workflow_d"
  },
  {
    "path": ".gitignore",
    "chars": 286,
    "preview": "__*\n.DS_*\nnode_modules\n/lib\ntmp\n*-error.log\n/package-lock.json\n/yarn.lock\nstats.html\n.vscode\n.idea\nmsw-*.tgz\n.husky/_\n.e"
  },
  {
    "path": ".nvmrc",
    "chars": 4,
    "preview": "v20\n"
  },
  {
    "path": ".prettierrc",
    "chars": 141,
    "preview": "{\n  \"arrowParens\": \"always\",\n  \"bracketSpacing\": true,\n  \"semi\": false,\n  \"useTabs\": false,\n  \"trailingComma\": \"all\",\n  "
  },
  {
    "path": "CHANGELOG.md",
    "chars": 220,
    "preview": "# Change Log\n\nThis project adheres to [Semantic Versioning](https://semver.org/).\nEvery release, along with the migratio"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 9370,
    "preview": "# Contributing\n\nHey! Thank you for deciding to contribute to Mock Service Worker! This page will help you land your firs"
  },
  {
    "path": "LICENSE.md",
    "chars": 1083,
    "preview": "MIT License\n\nCopyright (c) 2018–present Artem Zakharchenko\n\nPermission is hereby granted, free of charge, to any person "
  },
  {
    "path": "README.md",
    "chars": 11255,
    "preview": "<br />\n\n<p align=\"center\">\n  <img src=\"media/msw-logo.svg\" width=\"100\" alt=\"The Mock Service Worker logo\" />\n</p>\n\n<h1 a"
  },
  {
    "path": "browser/package.json",
    "chars": 841,
    "preview": "{\n  \"type\": \"module\",\n  \"main\": \"../lib/browser/index.js\",\n  \"module\": \"../lib/browser/index.mjs\",\n  \"types\": \"../lib/br"
  },
  {
    "path": "cli/index.js",
    "chars": 970,
    "preview": "#!/usr/bin/env node\nimport yargs from 'yargs'\nimport { init } from './init.js'\n\n// eslint-disable-next-line @typescript-"
  },
  {
    "path": "cli/init.js",
    "chars": 7343,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\nimport colors from 'picocolors'\nimport confirm from '@inquirer/con"
  },
  {
    "path": "cli/invariant.js",
    "chars": 227,
    "preview": "import colors from 'picocolors'\n\nexport function invariant(predicate, message, ...args) {\n  if (!predicate) {\n    // esl"
  },
  {
    "path": "cli/package.json",
    "chars": 23,
    "preview": "{\n  \"type\": \"module\"\n}\n"
  },
  {
    "path": "commitlint.config.js",
    "chars": 183,
    "preview": "module.exports = {\n  extends: ['@commitlint/config-conventional'],\n  rules: {\n    'body-max-line-length': [0, 'always', "
  },
  {
    "path": "config/constants.js",
    "chars": 347,
    "preview": "import url from 'node:url'\nimport path from 'node:path'\n\nexport const SERVICE_WORKER_SOURCE_PATH = url.fileURLToPath(\n  "
  },
  {
    "path": "config/copyServiceWorker.ts",
    "chars": 1625,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\nimport { until } from 'until-async'\n\n/**\n * Copies the given Servi"
  },
  {
    "path": "config/package.json",
    "chars": 23,
    "preview": "{\n  \"type\": \"module\"\n}\n"
  },
  {
    "path": "config/plugins/esbuild/copyWorkerPlugin.ts",
    "chars": 2133,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\nimport crypto from 'crypto'\nimport minify from 'babel-minify'\nimpo"
  },
  {
    "path": "config/plugins/esbuild/forceEsmExtensionsPlugin.ts",
    "chars": 2028,
    "preview": "import { type Plugin } from 'esbuild'\n\nexport const ESM_EXTENSION = '.mjs'\nexport const CJS_EXTENSION = '.js'\n\nexport fu"
  },
  {
    "path": "config/plugins/esbuild/graphQLImportPlugin.ts",
    "chars": 1242,
    "preview": "import fs from 'node:fs'\nimport type { Plugin } from 'esbuild'\n\n/**\n * A plugin to replace `require('graphql')` statemen"
  },
  {
    "path": "config/plugins/esbuild/resolveCoreImportsPlugin.ts",
    "chars": 796,
    "preview": "import { Plugin } from 'esbuild'\nimport { replaceCoreImports } from '../../replaceCoreImports.js'\nimport { ESM_EXTENSION"
  },
  {
    "path": "config/polyfills-node.ts",
    "chars": 349,
    "preview": "import { setTimeout as nodeSetTimeout } from 'timers'\n\n// Polyfill the global \"setTimeout\" so MSW could be used\n// with "
  },
  {
    "path": "config/replaceCoreImports.js",
    "chars": 1021,
    "preview": "const CORE_ESM_IMPORT_PATTERN = /from [\"'](~\\/core(.*))[\"'](;)?/gm\nconst CORE_CJS_IMPORT_PATTERN = /require\\([\"'](~\\/cor"
  },
  {
    "path": "config/scripts/patch-ts.js",
    "chars": 3916,
    "preview": "import fs from 'node:fs'\nimport { exec } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport { invari"
  },
  {
    "path": "config/scripts/postinstall.js",
    "chars": 1063,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\nimport { execFileSync } from 'node:child_process'\n\n// When executi"
  },
  {
    "path": "config/scripts/smoke-test.sh",
    "chars": 889,
    "preview": "#!/bin/bash\nset -e\n\nCOMMIT_HASH=$(git rev-parse HEAD)\nMSW_VERSION=\"0.0.0-$COMMIT_HASH\"\necho \"Latest commit: $COMMIT_HASH"
  },
  {
    "path": "decisions/jest-support.md",
    "chars": 2079,
    "preview": "# Jest support\n\nWith the introduction of [Mock Service Worker 2.0](https://mswjs.io/blog/introducing-msw-2.0), the libra"
  },
  {
    "path": "decisions/linting-worker-script.md",
    "chars": 803,
    "preview": "# Linting the worker script\n\nWhen linting your application, you may encounter warnings or errors originating from the `m"
  },
  {
    "path": "decisions/releases.md",
    "chars": 1086,
    "preview": "# Releases\n\nMSW uses the [Release](https://github.com/ossjs/release) library to automate its releases to NPM.\n\n## Releas"
  },
  {
    "path": "decisions/typescript-versioning.md",
    "chars": 1978,
    "preview": "# TypeScript versioning\n\n## Strict TypeScript peer dependency version\n\nIn the past, MSW set the explicit upper version r"
  },
  {
    "path": "eslint.config.mjs",
    "chars": 1962,
    "preview": "// @ts-check\n\nimport eslint from '@eslint/js'\nimport tseslint from 'typescript-eslint'\nimport eslintConfigPrettier from "
  },
  {
    "path": "global.d.ts",
    "chars": 180,
    "preview": "declare module 'babel-minify' {\n  export default function babelMinify(\n    code: string,\n    opts: Record<string, any>,\n"
  },
  {
    "path": "knip.json",
    "chars": 293,
    "preview": "{\n  \"$schema\": \"https://unpkg.com/knip@5/schema.json\",\n  \"entry\": [\n    \"src/{core,browser,node,native}/index.ts!\",\n    "
  },
  {
    "path": "native/package.json",
    "chars": 751,
    "preview": "{\n  \"type\": \"commonjs\",\n  \"browser\": null,\n  \"main\": \"../lib/native/index.js\",\n  \"module\": \"../lib/native/index.mjs\",\n  "
  },
  {
    "path": "node/package.json",
    "chars": 829,
    "preview": "{\n  \"type\": \"commonjs\",\n  \"browser\": null,\n  \"main\": \"../lib/node/index.js\",\n  \"module\": \"../lib/node/index.mjs\",\n  \"typ"
  },
  {
    "path": "package.json",
    "chars": 9266,
    "preview": "{\n  \"name\": \"msw\",\n  \"version\": \"2.12.13\",\n  \"description\": \"Seamless REST/GraphQL API mocking library for browser and N"
  },
  {
    "path": "release.config.json",
    "chars": 189,
    "preview": "{\n  \"$schema\": \"./node_modules/@ossjs/release/schema.json\",\n  \"profiles\": [\n    {\n      \"name\": \"latest\",\n      \"use\": \""
  },
  {
    "path": "src/browser/global.browser.d.ts",
    "chars": 46,
    "preview": "declare const SERVICE_WORKER_CHECKSUM: string\n"
  },
  {
    "path": "src/browser/index.ts",
    "chars": 187,
    "preview": "export { setupWorker } from './setupWorker/setupWorker'\nexport type { SetupWorker, StartOptions } from './setupWorker/gl"
  },
  {
    "path": "src/browser/setupWorker/glossary.ts",
    "chars": 4320,
    "preview": "import { Emitter } from 'strict-event-emitter'\nimport type { HttpRequestEventMap, Interceptor } from '@mswjs/interceptor"
  },
  {
    "path": "src/browser/setupWorker/setupWorker.node.test.ts",
    "chars": 260,
    "preview": "/**\n * @vitest-environment node\n */\nimport { setupWorker } from './setupWorker'\n\ntest('returns an error when run in a No"
  },
  {
    "path": "src/browser/setupWorker/setupWorker.ts",
    "chars": 6416,
    "preview": "import { invariant } from 'outvariant'\nimport { isNodeProcess } from 'is-node-process'\nimport { DeferredPromise } from '"
  },
  {
    "path": "src/browser/setupWorker/start/createFallbackRequestListener.ts",
    "chars": 1964,
    "preview": "import {\n  Interceptor,\n  BatchInterceptor,\n  HttpRequestEventMap,\n} from '@mswjs/interceptors'\nimport { FetchIntercepto"
  },
  {
    "path": "src/browser/setupWorker/start/createRequestListener.ts",
    "chars": 5110,
    "preview": "import { Emitter } from 'rettime'\nimport { StartOptions, SetupWorkerInternalContext } from '../glossary'\nimport { deseri"
  },
  {
    "path": "src/browser/setupWorker/start/createResponseListener.ts",
    "chars": 2044,
    "preview": "import { FetchResponse } from '@mswjs/interceptors'\nimport type { Emitter } from 'rettime'\nimport type { SetupWorkerInte"
  },
  {
    "path": "src/browser/setupWorker/start/createStartHandler.ts",
    "chars": 5537,
    "preview": "import { devUtils } from '~/core/utils/internal/devUtils'\nimport { getWorkerInstance } from './utils/getWorkerInstance'\n"
  },
  {
    "path": "src/browser/setupWorker/start/utils/enableMocking.ts",
    "chars": 909,
    "preview": "import { DeferredPromise } from '@open-draft/deferred-promise'\nimport type { StartOptions, SetupWorkerInternalContext } "
  },
  {
    "path": "src/browser/setupWorker/start/utils/getWorkerByRegistration.ts",
    "chars": 709,
    "preview": "import { FindWorker } from '../../glossary'\n\n/**\n * Attempts to resolve a Service Worker instance from a given registrat"
  },
  {
    "path": "src/browser/setupWorker/start/utils/getWorkerInstance.ts",
    "chars": 3481,
    "preview": "import { until } from 'until-async'\nimport { devUtils } from '~/core/utils/internal/devUtils'\nimport { getAbsoluteWorker"
  },
  {
    "path": "src/browser/setupWorker/start/utils/prepareStartHandler.test.ts",
    "chars": 1761,
    "preview": "import { SetupWorkerInternalContext, StartOptions } from '../../glossary'\nimport {\n  DEFAULT_START_OPTIONS,\n  resolveSta"
  },
  {
    "path": "src/browser/setupWorker/start/utils/prepareStartHandler.ts",
    "chars": 1159,
    "preview": "import { RequiredDeep } from '~/core/typeUtils'\nimport { mergeRight } from '~/core/utils/internal/mergeRight'\nimport {\n "
  },
  {
    "path": "src/browser/setupWorker/start/utils/printStartMessage.test.ts",
    "chars": 2166,
    "preview": "import { printStartMessage } from './printStartMessage'\n\nbeforeEach(() => {\n  vi.spyOn(console, 'groupCollapsed').mockIm"
  },
  {
    "path": "src/browser/setupWorker/start/utils/printStartMessage.ts",
    "chars": 1353,
    "preview": "import type { ServiceWorkerIncomingEventsMap } from '../../glossary'\nimport { devUtils } from '~/core/utils/internal/dev"
  },
  {
    "path": "src/browser/setupWorker/start/utils/validateWorkerScope.ts",
    "chars": 694,
    "preview": "import { devUtils } from '~/core/utils/internal/devUtils'\nimport { StartOptions } from '../../glossary'\n\nexport function"
  },
  {
    "path": "src/browser/setupWorker/stop/utils/printStopMessage.test.ts",
    "chars": 582,
    "preview": "import { printStopMessage } from './printStopMessage'\n\nbeforeAll(() => {\n  vi.spyOn(global.console, 'log').mockImplement"
  },
  {
    "path": "src/browser/setupWorker/stop/utils/printStopMessage.ts",
    "chars": 327,
    "preview": "import { devUtils } from '~/core/utils/internal/devUtils'\n\nexport function printStopMessage(args: { quiet?: boolean } = "
  },
  {
    "path": "src/browser/tsconfig.browser.build.json",
    "chars": 94,
    "preview": "{\n  \"extends\": \"./tsconfig.browser.json\",\n  \"compilerOptions\": {\n    \"composite\": false\n  }\n}\n"
  },
  {
    "path": "src/browser/tsconfig.browser.json",
    "chars": 298,
    "preview": "{\n  \"extends\": \"../tsconfig.src.json\",\n  \"compilerOptions\": {\n    // Expose browser-specific libraries only for the\n    "
  },
  {
    "path": "src/browser/utils/checkWorkerIntegrity.ts",
    "chars": 1711,
    "preview": "import { devUtils } from '~/core/utils/internal/devUtils'\nimport type { SetupWorkerInternalContext } from '../setupWorke"
  },
  {
    "path": "src/browser/utils/deserializeRequest.ts",
    "chars": 471,
    "preview": "import { pruneGetRequestBody } from './pruneGetRequestBody'\nimport type { ServiceWorkerIncomingRequest } from '../setupW"
  },
  {
    "path": "src/browser/utils/getAbsoluteWorkerUrl.test.ts",
    "chars": 801,
    "preview": "// @vitest-environment jsdom\nimport { getAbsoluteWorkerUrl } from './getAbsoluteWorkerUrl'\n\nconst rawLocation = window.l"
  },
  {
    "path": "src/browser/utils/getAbsoluteWorkerUrl.ts",
    "chars": 234,
    "preview": "/**\n * Returns an absolute Service Worker URL based on the given\n * relative URL (known during the registration).\n */\nex"
  },
  {
    "path": "src/browser/utils/pruneGetRequestBody.test.ts",
    "chars": 1032,
    "preview": "/**\n * @vitest-environment jsdom\n */\nimport { TextEncoder } from 'util'\nimport { pruneGetRequestBody } from './pruneGetR"
  },
  {
    "path": "src/browser/utils/pruneGetRequestBody.ts",
    "chars": 703,
    "preview": "import type { ServiceWorkerIncomingRequest } from '../setupWorker/glossary'\n\ntype Input = Pick<ServiceWorkerIncomingRequ"
  },
  {
    "path": "src/browser/utils/supports.ts",
    "chars": 763,
    "preview": "/**\n * Checks if the Service Worker API is supproted and available\n * in the current browsing context.\n */\nexport functi"
  },
  {
    "path": "src/browser/utils/workerChannel.ts",
    "chars": 4031,
    "preview": "import { invariant } from 'outvariant'\nimport { Emitter, TypedEvent } from 'rettime'\nimport { isObject } from '~/core/ut"
  },
  {
    "path": "src/core/HttpResponse.test.ts",
    "chars": 13223,
    "preview": "/**\n * @vitest-environment node\n */\nimport { TextEncoder } from 'util'\nimport { HttpResponse, kDefaultContentType } from"
  },
  {
    "path": "src/core/HttpResponse.ts",
    "chars": 7236,
    "preview": "import { FetchResponse } from '@mswjs/interceptors'\nimport type { DefaultBodyType, JsonBodyType } from './handlers/Reque"
  },
  {
    "path": "src/core/SetupApi.ts",
    "chars": 4087,
    "preview": "import { invariant } from 'outvariant'\nimport { EventMap, Emitter } from 'strict-event-emitter'\nimport { RequestHandler "
  },
  {
    "path": "src/core/bypass.test.ts",
    "chars": 2490,
    "preview": "/**\n * @vitest-environment jsdom\n */\nimport { bypass } from './bypass'\n\nit('returns bypassed request given a request url"
  },
  {
    "path": "src/core/bypass.ts",
    "chars": 1549,
    "preview": "import { invariant } from 'outvariant'\n\nexport type BypassRequestInput = string | URL | Request\n\n/**\n * Creates a `Reque"
  },
  {
    "path": "src/core/delay.ts",
    "chars": 2876,
    "preview": "import { isNodeProcess } from 'is-node-process'\nimport { hasRefCounted } from './utils/internal/hasRefCounted'\n\nexport c"
  },
  {
    "path": "src/core/getResponse.test.ts",
    "chars": 2271,
    "preview": "// @vitest-environment node\nimport { http } from './http'\nimport { getResponse } from './getResponse'\n\nit('returns undef"
  },
  {
    "path": "src/core/getResponse.ts",
    "chars": 844,
    "preview": "import { createRequestId } from '@mswjs/interceptors'\nimport type { RequestHandler } from './handlers/RequestHandler'\nim"
  },
  {
    "path": "src/core/graphql.test.ts",
    "chars": 234,
    "preview": "import { graphql } from './graphql'\n\ntest('exports supported GraphQL operation types', () => {\n  expect(graphql).toBeDef"
  },
  {
    "path": "src/core/graphql.ts",
    "chars": 3960,
    "preview": "import type { OperationTypeNode } from 'graphql'\nimport {\n  ResponseResolver,\n  RequestHandlerOptions,\n} from './handler"
  },
  {
    "path": "src/core/handlers/GraphQLHandler.test.ts",
    "chars": 20927,
    "preview": "// @vitest-environment jsdom\nimport { createRequestId, encodeBuffer } from '@mswjs/interceptors'\nimport { OperationTypeN"
  },
  {
    "path": "src/core/handlers/GraphQLHandler.ts",
    "chars": 13312,
    "preview": "import { invariant } from 'outvariant'\nimport {\n  parse,\n  type DocumentNode,\n  type GraphQLError,\n  type OperationTypeN"
  },
  {
    "path": "src/core/handlers/HttpHandler.test.ts",
    "chars": 7574,
    "preview": "// @vitest-environment jsdom\nimport { createRequestId } from '@mswjs/interceptors'\nimport { HttpHandler, HttpRequestReso"
  },
  {
    "path": "src/core/handlers/HttpHandler.ts",
    "chars": 6051,
    "preview": "import { ResponseResolutionContext } from '../utils/executeHandlers'\nimport { devUtils } from '../utils/internal/devUtil"
  },
  {
    "path": "src/core/handlers/RequestHandler.ts",
    "chars": 11340,
    "preview": "import { getCallFrame } from '../utils/internal/getCallFrame'\nimport {\n  AsyncIterable,\n  Iterable,\n  isIterable,\n} from"
  },
  {
    "path": "src/core/handlers/WebSocketHandler.test.ts",
    "chars": 2865,
    "preview": "import { WebSocketHandler } from './WebSocketHandler'\n\ndescribe('parse', () => {\n  it('matches an exact url', () => {\n  "
  },
  {
    "path": "src/core/handlers/WebSocketHandler.ts",
    "chars": 6201,
    "preview": "import { Emitter } from 'strict-event-emitter'\nimport { createRequestId, resolveWebSocketUrl } from '@mswjs/interceptors"
  },
  {
    "path": "src/core/handlers/common.ts",
    "chars": 60,
    "preview": "export type HandlerKind = 'RequestHandler' | 'EventHandler'\n"
  },
  {
    "path": "src/core/http.test.ts",
    "chars": 250,
    "preview": "import { http } from './http'\n\ntest('exports all REST API methods', () => {\n  expect(http).toBeDefined()\n  expect(Object"
  },
  {
    "path": "src/core/http.ts",
    "chars": 2045,
    "preview": "import {\n  DefaultBodyType,\n  RequestHandlerOptions,\n  ResponseResolver,\n} from './handlers/RequestHandler'\nimport {\n  H"
  },
  {
    "path": "src/core/index.ts",
    "chars": 3215,
    "preview": "import { checkGlobals } from './utils/internal/checkGlobals'\n\nexport { SetupApi } from './SetupApi'\n\n/* HTTP handlers */"
  },
  {
    "path": "src/core/isCommonAssetRequest.ts",
    "chars": 1238,
    "preview": "/**\n * Determines if the given request is a static asset request.\n * Useful when deciding which unhandled requests to ig"
  },
  {
    "path": "src/core/passthrough.test.ts",
    "chars": 373,
    "preview": "// @vitest-environment node\nimport { passthrough } from './passthrough'\n\nit('creates a 302 response with the intention h"
  },
  {
    "path": "src/core/passthrough.ts",
    "chars": 661,
    "preview": "import type { HttpResponse } from './HttpResponse'\n\n/**\n * Performs the intercepted request as-is.\n *\n * This stops requ"
  },
  {
    "path": "src/core/sharedOptions.ts",
    "chars": 1462,
    "preview": "import type { Emitter } from 'strict-event-emitter'\nimport type { UnhandledRequestStrategy } from './utils/request/onUnh"
  },
  {
    "path": "src/core/sse.ts",
    "chars": 24063,
    "preview": "import { invariant } from 'outvariant'\nimport { Emitter } from 'strict-event-emitter'\nimport type { ResponseResolver } f"
  },
  {
    "path": "src/core/typeUtils.ts",
    "chars": 757,
    "preview": "type Fn = (...arg: any[]) => any\n\nexport type MaybePromise<T> = T | Promise<T>\n\nexport type RequiredDeep<\n  Type,\n  U ex"
  },
  {
    "path": "src/core/utils/HttpResponse/decorators.ts",
    "chars": 2215,
    "preview": "import statuses from '../../../shims/statuses'\nimport { Headers as HeadersPolyfill } from 'headers-polyfill'\nimport type"
  },
  {
    "path": "src/core/utils/cookieStore.ts",
    "chars": 2521,
    "preview": "import { isNodeProcess } from 'is-node-process'\nimport { invariant } from 'outvariant'\nimport {\n  Cookie,\n  CookieJar,\n "
  },
  {
    "path": "src/core/utils/executeHandlers.ts",
    "chars": 1926,
    "preview": "import {\n  RequestHandler,\n  type RequestHandlerExecutionResult,\n} from '../handlers/RequestHandler'\n\nexport interface H"
  },
  {
    "path": "src/core/utils/handleRequest.test.ts",
    "chars": 16015,
    "preview": "// @vitest-environment jsdom\nimport { Emitter } from 'strict-event-emitter'\nimport { createRequestId } from '@mswjs/inte"
  },
  {
    "path": "src/core/utils/handleRequest.ts",
    "chars": 3711,
    "preview": "import { until } from 'until-async'\nimport { Emitter } from 'strict-event-emitter'\nimport { LifeCycleEventsMap, SharedOp"
  },
  {
    "path": "src/core/utils/internal/Disposable.ts",
    "chars": 307,
    "preview": "export type DisposableSubscription = () => void\n\nexport class Disposable {\n  protected subscriptions: Array<DisposableSu"
  },
  {
    "path": "src/core/utils/internal/checkGlobals.ts",
    "chars": 689,
    "preview": "import { invariant } from 'outvariant'\nimport { devUtils } from './devUtils'\n\nexport function checkGlobals() {\n  /**\n   "
  },
  {
    "path": "src/core/utils/internal/devUtils.test.ts",
    "chars": 675,
    "preview": "import { InternalError } from './devUtils'\n\ndescribe(InternalError, () => {\n  it('creates an InternalError instance', ()"
  },
  {
    "path": "src/core/utils/internal/devUtils.ts",
    "chars": 1099,
    "preview": "import { format } from 'outvariant'\n\nconst LIBRARY_PREFIX = '[MSW]'\n\n/**\n * Formats a given message by appending the lib"
  },
  {
    "path": "src/core/utils/internal/getCallFrame.test.ts",
    "chars": 7315,
    "preview": "/**\n * @vitest-environment jsdom\n */\nimport { getCallFrame } from './getCallFrame'\n\nclass ErrorWithStack extends Error {"
  },
  {
    "path": "src/core/utils/internal/getCallFrame.ts",
    "chars": 969,
    "preview": "// Ignore the source files traces for local testing.\nconst SOURCE_FRAME = /[/\\\\]msw[/\\\\]src[/\\\\](.+)/\n\nconst BUILD_FRAME"
  },
  {
    "path": "src/core/utils/internal/hasRefCounted.test.ts",
    "chars": 407,
    "preview": "import { hasRefCounted } from './hasRefCounted'\n\nit('returns true for objects with ref and unref methods', () => {\n  exp"
  },
  {
    "path": "src/core/utils/internal/hasRefCounted.ts",
    "chars": 223,
    "preview": "export function hasRefCounted<T extends object>(\n  value: T,\n): value is T & NodeJS.RefCounted {\n  return (\n    typeof R"
  },
  {
    "path": "src/core/utils/internal/isHandlerKind.test.ts",
    "chars": 2435,
    "preview": "import { GraphQLHandler } from '../../handlers/GraphQLHandler'\nimport { HttpHandler } from '../../handlers/HttpHandler'\n"
  },
  {
    "path": "src/core/utils/internal/isHandlerKind.ts",
    "chars": 713,
    "preview": "import type { HandlerKind } from '../../handlers/common'\nimport type { RequestHandler } from '../../handlers/RequestHand"
  },
  {
    "path": "src/core/utils/internal/isIterable.test.ts",
    "chars": 411,
    "preview": "import { isIterable } from './isIterable'\n\ntest('returns true given an iterator', () => {\n  expect(\n    isIterable(\n    "
  },
  {
    "path": "src/core/utils/internal/isIterable.ts",
    "chars": 879,
    "preview": "/**\n * This is the same as TypeScript's `Iterable`, but with all three type parameters.\n * @todo Remove once TypeScript "
  },
  {
    "path": "src/core/utils/internal/isObject.test.ts",
    "chars": 523,
    "preview": "import { isObject } from './isObject'\n\ntest('returns true given an object', () => {\n  expect(isObject({})).toBe(true)\n  "
  },
  {
    "path": "src/core/utils/internal/isObject.ts",
    "chars": 203,
    "preview": "/**\n * Determines if the given value is an object.\n */\nexport function isObject(value: any): value is Record<string, any"
  },
  {
    "path": "src/core/utils/internal/isStringEqual.test.ts",
    "chars": 1245,
    "preview": "import { isStringEqual } from './isStringEqual'\n\ndescribe('isStringEqual', () => {\n  describe('given two uppercase strin"
  },
  {
    "path": "src/core/utils/internal/isStringEqual.ts",
    "chars": 206,
    "preview": "/**\n * Performs a case-insensitive comparison of two given strings.\n */\nexport function isStringEqual(actual: string, ex"
  },
  {
    "path": "src/core/utils/internal/jsonParse.test.ts",
    "chars": 378,
    "preview": "import { jsonParse } from './jsonParse'\n\ntest('parses a given valid JSON string', () => {\n  expect(jsonParse(`{\"property"
  },
  {
    "path": "src/core/utils/internal/jsonParse.ts",
    "chars": 286,
    "preview": "/**\n * Parses a given value into a JSON.\n * Does not throw an exception on an invalid JSON string.\n */\nexport function j"
  },
  {
    "path": "src/core/utils/internal/mergeRight.test.ts",
    "chars": 677,
    "preview": "import { mergeRight } from './mergeRight'\n\ntest('shallowly merges two given objects', () => {\n  expect(mergeRight({ a: 1"
  },
  {
    "path": "src/core/utils/internal/mergeRight.ts",
    "chars": 740,
    "preview": "import { isObject } from './isObject'\n\n/**\n * Deeply merges two given objects with the right one\n * having a priority du"
  },
  {
    "path": "src/core/utils/internal/parseGraphQLRequest.test.ts",
    "chars": 3224,
    "preview": "/**\n * @vitest-environment jsdom\n */\nimport { encodeBuffer } from '@mswjs/interceptors'\nimport { OperationTypeNode } fro"
  },
  {
    "path": "src/core/utils/internal/parseGraphQLRequest.ts",
    "chars": 5704,
    "preview": "import type {\n  DocumentNode,\n  OperationDefinitionNode,\n  OperationTypeNode,\n} from 'graphql'\nimport type { GraphQLVari"
  },
  {
    "path": "src/core/utils/internal/parseMultipartData.test.ts",
    "chars": 2460,
    "preview": "/**\n * @vitest-environment jsdom\n */\nimport { parseMultipartData } from './parseMultipartData'\n\ntest('parses a given val"
  },
  {
    "path": "src/core/utils/internal/parseMultipartData.ts",
    "chars": 2779,
    "preview": "import { stringToHeaders } from 'headers-polyfill'\nimport { DefaultRequestMultipartBody } from '../../handlers/RequestHa"
  },
  {
    "path": "src/core/utils/internal/pipeEvents.test.ts",
    "chars": 456,
    "preview": "import { Emitter } from 'strict-event-emitter'\nimport { pipeEvents } from './pipeEvents'\n\nit('pipes events from the sour"
  },
  {
    "path": "src/core/utils/internal/pipeEvents.ts",
    "chars": 645,
    "preview": "import { Emitter, EventMap } from 'strict-event-emitter'\n\n/**\n * Pipes all emitted events from one emitter to another.\n "
  },
  {
    "path": "src/core/utils/internal/requestHandlerUtils.ts",
    "chars": 554,
    "preview": "import { RequestHandler } from '../../handlers/RequestHandler'\n\nexport function use(\n  currentHandlers: Array<RequestHan"
  },
  {
    "path": "src/core/utils/internal/toReadonlyArray.test.ts",
    "chars": 811,
    "preview": "import { toReadonlyArray } from './toReadonlyArray'\n\nit('creates a copy of an array', () => {\n  expect(toReadonlyArray(["
  },
  {
    "path": "src/core/utils/internal/toReadonlyArray.ts",
    "chars": 210,
    "preview": "/**\n * Creates an immutable copy of the given array.\n */\nexport function toReadonlyArray<T>(source: Array<T>): ReadonlyA"
  },
  {
    "path": "src/core/utils/internal/tryCatch.test.ts",
    "chars": 673,
    "preview": "import { tryCatch } from './tryCatch'\n\ntest('returns the function payload', () => {\n  const result = tryCatch(() => 'hel"
  },
  {
    "path": "src/core/utils/internal/tryCatch.ts",
    "chars": 254,
    "preview": "export function tryCatch<Fn extends (...args: any[]) => any>(\n  fn: Fn,\n  onException?: (error: Error) => void,\n): Retur"
  },
  {
    "path": "src/core/utils/logging/getStatusCodeColor.test.ts",
    "chars": 799,
    "preview": "import { getStatusCodeColor } from './getStatusCodeColor'\n\ntest('returns a green color for status codes lower than 300',"
  },
  {
    "path": "src/core/utils/logging/getStatusCodeColor.ts",
    "chars": 401,
    "preview": "export enum StatusCodeColor {\n  Success = '#69AB32',\n  Warning = '#F0BB4B',\n  Danger = '#E95F5D',\n}\n\n/**\n * Returns a HE"
  },
  {
    "path": "src/core/utils/logging/getTimestamp.test.ts",
    "chars": 987,
    "preview": "import { getTimestamp } from './getTimestamp'\n\nbeforeAll(() => {\n  vi.useFakeTimers()\n})\n\nafterAll(() => {\n  vi.useRealT"
  },
  {
    "path": "src/core/utils/logging/getTimestamp.ts",
    "chars": 518,
    "preview": "interface GetTimestampOptions {\n  milliseconds?: boolean\n}\n\n/**\n * Returns a timestamp string in a \"HH:MM:SS\" format.\n *"
  },
  {
    "path": "src/core/utils/logging/serializeRequest.test.ts",
    "chars": 705,
    "preview": "import { encodeBuffer } from '@mswjs/interceptors'\nimport { serializeRequest } from './serializeRequest'\n\ntest('serializ"
  },
  {
    "path": "src/core/utils/logging/serializeRequest.ts",
    "chars": 524,
    "preview": "export interface LoggedRequest {\n  url: URL\n  method: string\n  headers: Record<string, string>\n  body: string\n}\n\n/**\n * "
  },
  {
    "path": "src/core/utils/logging/serializeResponse.test.ts",
    "chars": 2114,
    "preview": "/**\n * @vitest-environment node\n */\nimport { encodeBuffer } from '@mswjs/interceptors'\nimport { serializeResponse } from"
  },
  {
    "path": "src/core/utils/logging/serializeResponse.ts",
    "chars": 917,
    "preview": "import statuses from '../../../shims/statuses'\n\nconst { message } = statuses\n\nexport interface SerializedResponse {\n  st"
  },
  {
    "path": "src/core/utils/matching/matchRequestUrl.test.ts",
    "chars": 4889,
    "preview": "/**\n * @vitest-environment jsdom\n */\nimport { coercePath, matchRequestUrl } from './matchRequestUrl'\n\ndescribe('matchReq"
  },
  {
    "path": "src/core/utils/matching/matchRequestUrl.ts",
    "chars": 2211,
    "preview": "import { match } from 'path-to-regexp'\nimport { getCleanUrl } from '@mswjs/interceptors'\nimport { normalizePath } from '"
  },
  {
    "path": "src/core/utils/matching/normalizePath.node.test.ts",
    "chars": 1351,
    "preview": "/**\n * @vitest-environment node\n */\nimport { normalizePath } from './normalizePath'\n\ntest('returns RegExp as-is', () => "
  },
  {
    "path": "src/core/utils/matching/normalizePath.test.ts",
    "chars": 1777,
    "preview": "/**\n * @vitest-environment jsdom\n */\nimport { normalizePath } from './normalizePath'\n\ntest('returns RegExp as-is', () =>"
  },
  {
    "path": "src/core/utils/matching/normalizePath.ts",
    "chars": 708,
    "preview": "import type { Path } from './matchRequestUrl'\nimport { cleanUrl } from '../url/cleanUrl'\nimport { getAbsoluteUrl } from "
  },
  {
    "path": "src/core/utils/request/getAllAcceptedMimeTypes.test.ts",
    "chars": 2543,
    "preview": "import { getAllAcceptedMimeTypes } from './getAllAcceptedMimeTypes'\n\nit('returns an empty array for null accept header',"
  },
  {
    "path": "src/core/utils/request/getAllAcceptedMimeTypes.ts",
    "chars": 1800,
    "preview": "/**\n * Returns all accepted mime types, ordered by precedence as defined\n * in [RFC 7231 Section 5.3.2](https://datatrac"
  },
  {
    "path": "src/core/utils/request/getRequestCookies.ts",
    "chars": 2398,
    "preview": "import {\n  parse as parseCookie,\n  serialize as serializeCookie,\n} from '../../../shims/cookie'\nimport { cookieStore } f"
  },
  {
    "path": "src/core/utils/request/onUnhandledRequest.node.test.ts",
    "chars": 1844,
    "preview": "// @vitest-environment node\nimport { onUnhandledRequest } from './onUnhandledRequest'\n\nconst fixtures = {\n  warningWitho"
  },
  {
    "path": "src/core/utils/request/onUnhandledRequest.test.ts",
    "chars": 7075,
    "preview": "// @vitest-environment jsdom\nimport {\n  onUnhandledRequest,\n  UnhandledRequestCallback,\n} from './onUnhandledRequest'\n\nc"
  },
  {
    "path": "src/core/utils/request/onUnhandledRequest.ts",
    "chars": 2732,
    "preview": "import { toPublicUrl } from './toPublicUrl'\nimport { InternalError, devUtils } from '../internal/devUtils'\nimport { isCo"
  },
  {
    "path": "src/core/utils/request/storeResponseCookies.ts",
    "chars": 499,
    "preview": "import { cookieStore } from '../cookieStore'\nimport { kSetCookie } from '../HttpResponse/decorators'\n\nexport async funct"
  },
  {
    "path": "src/core/utils/request/toPublicUrl.node.test.ts",
    "chars": 504,
    "preview": "// @vitest-environment node\nimport { toPublicUrl } from './toPublicUrl'\n\ntest('returns an absolute request URL without s"
  },
  {
    "path": "src/core/utils/request/toPublicUrl.test.ts",
    "chars": 541,
    "preview": "// @vitest-environment jsdom\nimport { toPublicUrl } from './toPublicUrl'\n\ntest('returns an absolute request URL without "
  },
  {
    "path": "src/core/utils/request/toPublicUrl.ts",
    "chars": 437,
    "preview": "/**\n * Returns a relative URL if the given request URL is relative\n * to the current origin. Otherwise returns an absolu"
  },
  {
    "path": "src/core/utils/toResponseInit.ts",
    "chars": 211,
    "preview": "export function toResponseInit(response: Response): ResponseInit {\n  return {\n    status: response.status,\n    statusTex"
  },
  {
    "path": "src/core/utils/url/cleanUrl.test.ts",
    "chars": 825,
    "preview": "import { cleanUrl } from './cleanUrl'\n\nit('removes query parameters from a URL string', () => {\n  expect(cleanUrl('/user"
  },
  {
    "path": "src/core/utils/url/cleanUrl.ts",
    "chars": 413,
    "preview": "const REDUNDANT_CHARACTERS_EXP = /[?|#].*$/g\n\n/**\n * Removes search parameters and the fragment\n * from a given URL stri"
  },
  {
    "path": "src/core/utils/url/getAbsoluteUrl.node.test.ts",
    "chars": 519,
    "preview": "/**\n * @vitest-environment node\n */\nimport { getAbsoluteUrl } from './getAbsoluteUrl'\n\nit('returns a given relative URL "
  },
  {
    "path": "src/core/utils/url/getAbsoluteUrl.test.ts",
    "chars": 1322,
    "preview": "// @vitest-environment jsdom\nimport { getAbsoluteUrl } from './getAbsoluteUrl'\n\nconst rawLocation = window.location\n\naft"
  },
  {
    "path": "src/core/utils/url/getAbsoluteUrl.ts",
    "chars": 734,
    "preview": "import { isAbsoluteUrl } from './isAbsoluteUrl'\n\n/**\n * Returns an absolute URL based on the given path.\n */\nexport func"
  },
  {
    "path": "src/core/utils/url/isAbsoluteUrl.test.ts",
    "chars": 888,
    "preview": "/**\n * @vitest-environment node\n */\nimport { isAbsoluteUrl } from './isAbsoluteUrl'\n\nit('returns true for the \"http\" sch"
  },
  {
    "path": "src/core/utils/url/isAbsoluteUrl.ts",
    "chars": 171,
    "preview": "/**\n * Determines if the given URL string is an absolute URL.\n */\nexport function isAbsoluteUrl(url: string): boolean {\n"
  },
  {
    "path": "src/core/ws/WebSocketClientManager.test.ts",
    "chars": 4903,
    "preview": "// @vitest-environment node-websocket\nimport { setMaxListeners } from 'node:events'\nimport {\n  WebSocketClientConnection"
  },
  {
    "path": "src/core/ws/WebSocketClientManager.ts",
    "chars": 7018,
    "preview": "import type {\n  WebSocketData,\n  WebSocketClientConnectionProtocol,\n  WebSocketClientEventMap,\n} from '@mswjs/intercepto"
  },
  {
    "path": "src/core/ws/WebSocketClientStore.ts",
    "chars": 432,
    "preview": "import type { WebSocketClientConnectionProtocol } from '@mswjs/interceptors/WebSocket'\n\nexport interface SerializedWebSo"
  },
  {
    "path": "src/core/ws/WebSocketIndexedDBClientStore.ts",
    "chars": 4083,
    "preview": "import { DeferredPromise } from '@open-draft/deferred-promise'\nimport { WebSocketClientConnectionProtocol } from '@mswjs"
  },
  {
    "path": "src/core/ws/WebSocketMemoryClientStore.ts",
    "chars": 796,
    "preview": "import { WebSocketClientConnectionProtocol } from '@mswjs/interceptors/WebSocket'\nimport {\n  SerializedWebSocketClient,\n"
  },
  {
    "path": "src/core/ws/handleWebSocketEvent.ts",
    "chars": 2213,
    "preview": "import type { WebSocketConnectionData } from '@mswjs/interceptors/WebSocket'\nimport { RequestHandler } from '../handlers"
  },
  {
    "path": "src/core/ws/utils/attachWebSocketLogger.ts",
    "chars": 6765,
    "preview": "import type {\n  WebSocketClientConnection,\n  WebSocketConnectionData,\n  WebSocketData,\n} from '@mswjs/interceptors/WebSo"
  },
  {
    "path": "src/core/ws/utils/getMessageLength.test.ts",
    "chars": 505,
    "preview": "import { getMessageLength } from './getMessageLength'\n\nit('returns the length of the string', () => {\n  expect(getMessag"
  },
  {
    "path": "src/core/ws/utils/getMessageLength.ts",
    "chars": 524,
    "preview": "import type { WebSocketData } from '@mswjs/interceptors/WebSocket'\nimport { isObject } from '../../utils/internal/isObje"
  },
  {
    "path": "src/core/ws/utils/getPublicData.test.ts",
    "chars": 1182,
    "preview": "import { getPublicData } from './getPublicData'\n\nit('returns a short string as-is', async () => {\n  expect(await getPubl"
  },
  {
    "path": "src/core/ws/utils/getPublicData.ts",
    "chars": 585,
    "preview": "import type { WebSocketData } from '@mswjs/interceptors/WebSocket'\nimport { isObject } from '../../utils/internal/isObje"
  },
  {
    "path": "src/core/ws/utils/truncateMessage.test.ts",
    "chars": 328,
    "preview": "import { truncateMessage } from './truncateMessage'\n\nit('returns a short string as-is', () => {\n  expect(truncateMessage"
  },
  {
    "path": "src/core/ws/utils/truncateMessage.ts",
    "chars": 190,
    "preview": "const MAX_LENGTH = 24\n\nexport function truncateMessage(message: string): string {\n  if (message.length <= MAX_LENGTH) {\n"
  },
  {
    "path": "src/core/ws/webSocketInterceptor.ts",
    "chars": 133,
    "preview": "import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket'\n\nexport const webSocketInterceptor = new WebSocketI"
  },
  {
    "path": "src/core/ws.test.ts",
    "chars": 674,
    "preview": "/**\n * @vitest-environment node-websocket\n */\nimport { ws } from './ws'\n\nit('exports the \"link()\" method', () => {\n  exp"
  },
  {
    "path": "src/core/ws.ts",
    "chars": 4900,
    "preview": "import { invariant } from 'outvariant'\nimport type {\n  WebSocketData,\n  WebSocketClientConnectionProtocol,\n} from '@mswj"
  },
  {
    "path": "src/iife/index.ts",
    "chars": 50,
    "preview": "export * from '~/core'\nexport * from '../browser'\n"
  },
  {
    "path": "src/mockServiceWorker.js",
    "chars": 9119,
    "preview": "/* eslint-disable */\n/* tslint:disable */\n\n/**\n * Mock Service Worker.\n * @see https://github.com/mswjs/msw\n * - Please "
  },
  {
    "path": "src/native/index.ts",
    "chars": 891,
    "preview": "import { FetchInterceptor } from '@mswjs/interceptors/fetch'\nimport { XMLHttpRequestInterceptor } from '@mswjs/intercept"
  },
  {
    "path": "src/node/SetupServerApi.ts",
    "chars": 2788,
    "preview": "import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { HttpRequestEventMap, Interceptor } from '@mswjs/inter"
  },
  {
    "path": "src/node/SetupServerCommonApi.ts",
    "chars": 5256,
    "preview": "/**\n * @note This API is extended by both \"msw/node\" and \"msw/native\"\n * so be minding about the things you import!\n */\n"
  },
  {
    "path": "src/node/glossary.ts",
    "chars": 2707,
    "preview": "import type { PartialDeep } from 'type-fest'\nimport type { RequestHandler } from '~/core/handlers/RequestHandler'\nimport"
  },
  {
    "path": "src/node/index.ts",
    "chars": 140,
    "preview": "export type { SetupServer } from './glossary'\nexport { SetupServerApi } from './SetupServerApi'\nexport { setupServer } f"
  },
  {
    "path": "src/node/setupServer.ts",
    "chars": 580,
    "preview": "import type { RequestHandler } from '~/core/handlers/RequestHandler'\nimport type { WebSocketHandler } from '~/core/handl"
  },
  {
    "path": "src/package.json",
    "chars": 23,
    "preview": "{\n  \"type\": \"module\"\n}\n"
  },
  {
    "path": "src/shims/cookie.ts",
    "chars": 261,
    "preview": "import * as allCookie from 'cookie'\nconst cookie = (allCookie as any).default || allCookie\n\nexport const parse = cookie."
  },
  {
    "path": "src/shims/statuses.ts",
    "chars": 204,
    "preview": "import * as allStatuses from 'statuses'\nconst statuses = (allStatuses as any).default || allStatuses\n\nexport const messa"
  },
  {
    "path": "src/tsconfig.core.build.json",
    "chars": 90,
    "preview": "{\n  \"extends\": \"./tsconfig.src.json\",\n  \"compilerOptions\": {\n    \"composite\": false\n  }\n}\n"
  },
  {
    "path": "src/tsconfig.node.build.json",
    "chars": 91,
    "preview": "{\n  \"extends\": \"./tsconfig.node.json\",\n  \"compilerOptions\": {\n    \"composite\": false\n  }\n}\n"
  }
]

// ... and 384 more files (download for full content)

About this extraction

This page contains the full source code of the mswjs/msw GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 584 files (1021.2 KB), approximately 272.3k tokens, and a symbol index with 648 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!