@depup/msw 3.0.2-depup.0 → 3.0.3-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,16 +13,17 @@ npm install @depup/msw
13
13
 
14
14
  | Field | Value |
15
15
  |-------|-------|
16
- | Original | [msw](https://www.npmjs.com/package/msw) @ 3.0.2 |
17
- | Processed | 2026-10-03 |
16
+ | Original | [msw](https://www.npmjs.com/package/msw) @ 3.0.3 |
17
+ | Processed | 2026-10-10 |
18
18
  | Smoke test | passed |
19
- | Deps updated | 2 |
19
+ | Deps updated | 3 |
20
20
 
21
21
  ## Dependency Changes
22
22
 
23
23
  | Dependency | From | To |
24
24
  |------------|------|-----|
25
- | @inquirer/confirm | ^6.0.11 | ^6.3.2 |
25
+ | @inquirer/confirm | ^6.0.11 | ^6.3.3 |
26
+ | @mswjs/interceptors | ^0.45.6 | ^0.45.7 |
26
27
  | type-fest | ^5.5.0 | ^5.10.0 |
27
28
 
28
29
  ---
package/changes.json CHANGED
@@ -2,13 +2,17 @@
2
2
  "bumped": {
3
3
  "@inquirer/confirm": {
4
4
  "from": "^6.0.11",
5
- "to": "^6.3.2"
5
+ "to": "^6.3.3"
6
+ },
7
+ "@mswjs/interceptors": {
8
+ "from": "^0.45.6",
9
+ "to": "^0.45.7"
6
10
  },
7
11
  "type-fest": {
8
12
  "from": "^5.5.0",
9
13
  "to": "^5.10.0"
10
14
  }
11
15
  },
12
- "timestamp": "2026-10-03T08:12:08.542Z",
13
- "totalUpdated": 2
16
+ "timestamp": "2026-10-10T04:42:22.570Z",
17
+ "totalUpdated": 3
14
18
  }
@@ -28,8 +28,9 @@ var Handler = class {
28
28
  /**
29
29
  * Release the resources held by this handler.
30
30
  *
31
- * @note This method is invoked automatically when the network is
32
- * disabled (e.g. `server.close()`). Override it in the handlers that
31
+ * @note This method is invoked automatically when the handler leaves
32
+ * the network: when the network is disabled (e.g. `server.close()`)
33
+ * or when a reset removes it (e.g. `server.resetHandlers()`). Override it in the handlers that
33
34
  * hold onto anything beyond a single frame, like timers, connections,
34
35
  * or event listeners. Returning a promise makes the network await
35
36
  * this handler's disposal before it tears itself down.
@@ -1 +1 @@
1
- {"version":3,"file":"cookie-store.js","names":[],"sources":["../../src/core/handlers/handler.ts","../../src/core/utils/internal/get-call-frame.ts","../../src/core/utils/internal/dev-utils.ts","../../src/core/utils/http-status-messages.ts","../../src/core/utils/response-decorators.ts","../../src/core/utils/internal/is-string-equal.ts","../../src/core/utils/logging/get-timestamp.ts","../../src/core/utils/url/is-absolute-url.ts","../../src/core/utils/url/get-absolute-url.ts","../../src/core/utils/matching/normalize-path.ts","../../src/core/utils/matching/match-request-url.ts","../../src/core/utils/request/to-public-url.ts","../../src/core/utils/internal/json-parse.ts","../../src/core/utils/cookie-store.ts"],"sourcesContent":["import type { MaybePromise } from '../type-utils'\n\nexport type HandlerKind = 'request' | 'websocket'\n\n/**\n * The base class for all the handlers.\n */\nexport abstract class Handler {\n /**\n * The kind of the network frame this handler handles.\n */\n abstract readonly kind: HandlerKind\n\n /**\n * Reset the runtime state this handler accumulated while handling\n * the network (e.g. generator resolver progress).\n *\n * @note This method is invoked automatically when the handlers are\n * reset (e.g. `server.resetHandlers()`).\n */\n public reset(): void {}\n\n /**\n * Restore this handler so it can handle the network again after\n * being exhausted (e.g. via `{ once: true }`).\n *\n * @note This method is invoked automatically when the handlers are\n * restored (e.g. `server.restoreHandlers()`).\n */\n public restore(): void {}\n\n /**\n * Release the resources held by this handler.\n *\n * @note This method is invoked automatically when the network is\n * disabled (e.g. `server.close()`). Override it in the handlers that\n * hold onto anything beyond a single frame, like timers, connections,\n * or event listeners. Returning a promise makes the network await\n * this handler's disposal before it tears itself down.\n */\n public dispose(): MaybePromise<void> {}\n}\n","// Ignore the source files traces for local testing.\nconst SOURCE_FRAME = /[/\\\\]msw[/\\\\]src[/\\\\](.+)/\n\nconst BUILD_FRAME =\n /(node_modules)?[/\\\\]lib[/\\\\](core|browser|node|iife)[/\\\\]|^[^/\\\\]*$/\n\n/**\n * Return the stack trace frame of a function's invocation.\n */\nexport function getCallFrame(error: Error) {\n // In <IE11, new Error may return an undefined stack\n const stack = error.stack\n\n if (!stack) {\n return\n }\n\n const frames: string[] = stack.split('\\n').slice(1)\n\n // Get the first frame that doesn't reference the library's internal trace.\n // Assume that frame is the invocation frame.\n const declarationFrame = frames.find((frame) => {\n return !(SOURCE_FRAME.test(frame) || BUILD_FRAME.test(frame))\n })\n\n if (!declarationFrame) {\n return\n }\n\n // Extract file reference from the stack frame.\n const declarationPath = declarationFrame\n .replace(/\\s*at [^()]*\\(([^)]+)\\)/, '$1')\n .replace(/^@/, '')\n return declarationPath\n}\n","import { format } from 'outvariant'\n\nconst LIBRARY_PREFIX = '[MSW]'\n\n/**\n * Formats a given message by appending the library's prefix string.\n */\nfunction formatMessage(message: string, ...positionals: any[]): string {\n const interpolatedMessage = format(message, ...positionals)\n return `${LIBRARY_PREFIX} ${interpolatedMessage}`\n}\n\n/**\n * Prints a library-specific warning.\n */\nfunction warn(message: string, ...positionals: any[]): void {\n console.warn(formatMessage(message, ...positionals))\n}\n\n/**\n * Prints a library-specific error.\n */\nfunction error(message: string, ...positionals: any[]): void {\n console.error(formatMessage(message, ...positionals))\n}\n\nexport const devUtils = {\n formatMessage,\n warn,\n error,\n}\n\n/**\n * Internal error instance.\n * Used to differentiate the library errors that must be forwarded\n * to the user from the unhandled exceptions. Use this if you don't\n * wish for the error to be coerced to a 500 fallback response.\n */\nexport class InternalError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'InternalError'\n }\n}\n","/**\n * Reason phrases of the known HTTP status codes.\n * @see https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml\n */\nexport const httpStatusMessages: Record<number, string> = {\n 100: 'Continue',\n 101: 'Switching Protocols',\n 102: 'Processing',\n 103: 'Early Hints',\n 200: 'OK',\n 201: 'Created',\n 202: 'Accepted',\n 203: 'Non-Authoritative Information',\n 204: 'No Content',\n 205: 'Reset Content',\n 206: 'Partial Content',\n 207: 'Multi-Status',\n 208: 'Already Reported',\n 226: 'IM Used',\n 300: 'Multiple Choices',\n 301: 'Moved Permanently',\n 302: 'Found',\n 303: 'See Other',\n 304: 'Not Modified',\n 305: 'Use Proxy',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 406: 'Not Acceptable',\n 407: 'Proxy Authentication Required',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 411: 'Length Required',\n 412: 'Precondition Failed',\n 413: 'Payload Too Large',\n 414: 'URI Too Long',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 417: 'Expectation Failed',\n 418: \"I'm a Teapot\",\n 421: 'Misdirected Request',\n 422: 'Unprocessable Entity',\n 423: 'Locked',\n 424: 'Failed Dependency',\n 425: 'Too Early',\n 426: 'Upgrade Required',\n 428: 'Precondition Required',\n 429: 'Too Many Requests',\n 431: 'Request Header Fields Too Large',\n 451: 'Unavailable For Legal Reasons',\n 500: 'Internal Server Error',\n 501: 'Not Implemented',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n 505: 'HTTP Version Not Supported',\n 506: 'Variant Also Negotiates',\n 507: 'Insufficient Storage',\n 508: 'Loop Detected',\n 509: 'Bandwidth Limit Exceeded',\n 510: 'Not Extended',\n 511: 'Network Authentication Required',\n}\n","import type { HttpResponse, HttpResponseInit } from '#http/http-response'\nimport { httpStatusMessages } from './http-status-messages'\n\nconst kSetCookie = Symbol('kSetCookie')\n\nexport interface HttpResponseDecoratedInit extends HttpResponseInit {\n status: number\n statusText: string\n headers: Headers\n}\n\nexport function normalizeResponseInit(\n init: HttpResponseInit = {},\n): HttpResponseDecoratedInit {\n const status = init?.status || 200\n const statusText = init?.statusText || httpStatusMessages[status] || ''\n const headers = new Headers(init?.headers)\n\n return {\n ...init,\n headers,\n status,\n statusText,\n }\n}\n\nexport function decorateResponse(\n response: HttpResponse<any>,\n init: HttpResponseDecoratedInit,\n): Response {\n // Allow mocking the response type.\n if (init.type) {\n Object.defineProperty(response, 'type', {\n value: init.type,\n enumerable: true,\n writable: false,\n })\n }\n\n const responseCookies = init.headers.getSetCookie()\n\n if (responseCookies) {\n // Record the raw \"Set-Cookie\" response header provided\n // in the HeadersInit. This is later used to store these cookies\n // in cookie jar and return the right cookies in the \"cookies\"\n // response resolver argument.\n Object.defineProperty(response, kSetCookie, {\n value: responseCookies,\n enumerable: false,\n writable: false,\n })\n }\n\n return response\n}\n\nexport function getRawSetCookie(response: Response): Array<string> {\n return Reflect.get(response, kSetCookie) || []\n}\n\n/**\n * Copy the given response own properties, like internal symbols,\n * onto another response. Used for faithful internal copying of responses.\n */\nexport function copyResponseOwnProperties(\n source: Response,\n target: Response,\n): void {\n for (const propertyName of Reflect.ownKeys(source)) {\n const descriptor = Object.getOwnPropertyDescriptor(source, propertyName)\n const existingDescriptor = Object.getOwnPropertyDescriptor(\n target,\n propertyName,\n )\n\n if (descriptor && existingDescriptor == null) {\n Object.defineProperty(target, propertyName, descriptor)\n }\n }\n}\n","/**\n * Performs a case-insensitive comparison of two given strings.\n */\nexport function isStringEqual(actual: string, expected: string): boolean {\n return actual.toLowerCase() === expected.toLowerCase()\n}\n","interface GetTimestampOptions {\n milliseconds?: boolean\n}\n\n/**\n * Returns a timestamp string in a \"HH:MM:SS\" format.\n */\nexport function getTimestamp(options?: GetTimestampOptions): string {\n const now = new Date()\n const timestamp = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`\n\n if (options?.milliseconds) {\n return `${timestamp}.${now.getMilliseconds().toString().padStart(3, '0')}`\n }\n\n return timestamp\n}\n","/**\n * Determines if the given URL string is an absolute URL.\n */\nexport function isAbsoluteUrl(url: string): boolean {\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url)\n}\n","import { isAbsoluteUrl } from './is-absolute-url'\n\n/**\n * Returns an absolute URL based on the given path.\n */\nexport function getAbsoluteUrl(path: string, baseUrl?: string): string {\n // already absolute URL\n if (isAbsoluteUrl(path)) {\n return path\n }\n\n // Ignore path with pattern start with *\n if (path.startsWith('*')) {\n return path\n }\n\n // Resolve a relative request URL against a given custom \"baseUrl\"\n // or the document baseURI (in the case of browser/browser-like environments).\n const origin = baseUrl || (typeof location !== 'undefined' && location.href)\n\n return origin\n ? // Encode and decode the path to preserve escaped characters.\n decodeURI(new URL(encodeURI(path), origin).href)\n : path\n}\n","import type { Path } from './match-request-url'\nimport { getCleanUrlString } from '#utils/get-clean-url-string'\nimport { getAbsoluteUrl } from '../url/get-absolute-url'\n\n/**\n * Normalizes a given request handler path:\n * - Preserves RegExp.\n * - Removes query parameters and hashes.\n * - Rebases relative URLs against the \"baseUrl\" or the current location.\n * - Preserves relative URLs in Node.js, unless specified otherwise.\n * - Preserves optional path parameters.\n */\nexport function normalizePath<ThisPath extends Path>(\n path: ThisPath,\n baseUrl?: string,\n): ThisPath {\n // RegExp paths do not need normalization.\n if (path instanceof RegExp) {\n return path\n }\n\n const maybeAbsoluteUrl = getAbsoluteUrl(path, baseUrl)\n\n return getCleanUrlString(maybeAbsoluteUrl) as ThisPath\n}\n","import { matchPattern } from '@msw/url'\nimport { getCleanUrl } from '@mswjs/interceptors'\nimport { normalizePath } from './normalize-path'\n\nexport type Path = string | RegExp\nexport type PathParams<KeyType extends keyof any = string> = {\n [ParamName in KeyType]?: string | ReadonlyArray<string>\n}\n\nexport interface Match {\n matches: boolean\n params?: PathParams\n}\n\nexport function isPath(value: unknown): value is Path {\n return typeof value === 'string' || value instanceof RegExp\n}\n\n/**\n * Match the given URL against a path pattern.\n */\nexport function matchRequestUrl(\n url: URL,\n pattern: Path,\n baseUrl?: string,\n): Match {\n const cleanUrl = getCleanUrl(url)\n\n if (pattern instanceof RegExp) {\n const match = pattern.flags.includes('g')\n ? [...cleanUrl.matchAll(pattern)].flat()\n : cleanUrl.match(pattern)\n\n return {\n matches: match != null && match.length > 0,\n params: Object.fromEntries(\n (match ?? []).slice(1).map((value, index) => [index, value]),\n ),\n }\n }\n\n // Resolve potentially realive patterns against the baseUrl.\n const normalizedPath = normalizePath(pattern, baseUrl)\n return matchPattern(normalizedPath, cleanUrl)\n}\n","/**\n * Returns a relative URL if the given request URL is relative\n * to the current origin. Otherwise returns an absolute URL.\n */\nexport function toPublicUrl(url: string | URL): string {\n const urlInstance = url instanceof URL ? url : new URL(url)\n\n if (\n typeof location !== 'undefined' &&\n urlInstance.origin === location.origin\n ) {\n return urlInstance.pathname\n }\n\n return urlInstance.origin + urlInstance.pathname\n}\n","/**\n * Parses a given value into a JSON.\n * Does not throw an exception on an invalid JSON string.\n */\nexport function jsonParse<ValueType extends Record<string, any>>(\n value: any,\n): ValueType | undefined {\n try {\n return JSON.parse(value)\n } catch {\n return undefined\n }\n}\n","import { isNodeProcess } from 'is-node-process'\nimport { invariant } from 'outvariant'\nimport {\n Cookie,\n CookieJar,\n MemoryCookieStore,\n type SerializedCookie,\n type MemoryCookieStoreIndex,\n} from 'tough-cookie'\nimport { jsonParse } from './internal/json-parse'\n\nclass CookieStore {\n #storageKey = '__msw-cookie-store__'\n #jar: CookieJar\n #memoryStore: MemoryCookieStore\n\n constructor() {\n invariant(\n typeof localStorage !== 'undefined',\n 'Failed to create a CookieStore: `localStorage` is not available in this environment. This is likely an issue with your environment, which has been detected as browser (or browser-like) environment and must implement global browser APIs correctly.',\n )\n\n this.#memoryStore = new MemoryCookieStore()\n this.#memoryStore.idx = this.getCookieStoreIndex()\n this.#jar = new CookieJar(this.#memoryStore)\n }\n\n public getCookies(url: string): Array<Cookie> {\n return this.#jar.getCookiesSync(url)\n }\n\n public async setCookie(cookieName: string, url: string): Promise<void> {\n await this.#jar.setCookie(cookieName, url)\n this.persist()\n }\n\n private getCookieStoreIndex(): MemoryCookieStoreIndex {\n if (\n typeof localStorage === 'undefined' ||\n typeof localStorage.getItem !== 'function'\n ) {\n return {}\n }\n\n const cookiesString = localStorage.getItem(this.#storageKey)\n if (cookiesString == null) {\n return {}\n }\n\n const rawCookies = jsonParse<Array<Record<string, unknown>>>(cookiesString)\n if (rawCookies == null) {\n return {}\n }\n\n const cookies: MemoryCookieStoreIndex = {}\n\n for (const rawCookie of rawCookies) {\n const cookie = Cookie.fromJSON(rawCookie)\n\n if (cookie != null && cookie.domain != null && cookie.path != null) {\n cookies[cookie.domain] ||= {}\n cookies[cookie.domain][cookie.path] ||= {}\n cookies[cookie.domain][cookie.path][cookie.key] = cookie\n }\n }\n\n return cookies\n }\n\n private persist(): void {\n if (\n typeof localStorage === 'undefined' ||\n typeof localStorage.setItem !== 'function'\n ) {\n return\n }\n\n const data: Array<SerializedCookie> = []\n const { idx } = this.#memoryStore\n\n for (const domain in idx) {\n for (const path in idx[domain]) {\n for (const key in idx[domain][path]) {\n data.push(idx[domain][path][key].toJSON())\n }\n }\n }\n\n try {\n localStorage.setItem(this.#storageKey, JSON.stringify(data))\n } catch {\n // Persisting cookies is best-effort. If the storage quota is exceeded,\n // keep the cookies in memory so the request handling continues.\n return\n }\n }\n}\n\n// Node.js has no implicit cookie jar. Leave cookie management to the client.\nexport const cookieStore = isNodeProcess() ? null : new CookieStore()\n"],"mappings":"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"}
1
+ {"version":3,"file":"cookie-store.js","names":[],"sources":["../../src/core/handlers/handler.ts","../../src/core/utils/internal/get-call-frame.ts","../../src/core/utils/internal/dev-utils.ts","../../src/core/utils/http-status-messages.ts","../../src/core/utils/response-decorators.ts","../../src/core/utils/internal/is-string-equal.ts","../../src/core/utils/logging/get-timestamp.ts","../../src/core/utils/url/is-absolute-url.ts","../../src/core/utils/url/get-absolute-url.ts","../../src/core/utils/matching/normalize-path.ts","../../src/core/utils/matching/match-request-url.ts","../../src/core/utils/request/to-public-url.ts","../../src/core/utils/internal/json-parse.ts","../../src/core/utils/cookie-store.ts"],"sourcesContent":["import type { MaybePromise } from '../type-utils'\n\nexport type HandlerKind = 'request' | 'websocket'\n\n/**\n * The base class for all the handlers.\n */\nexport abstract class Handler {\n /**\n * The kind of the network frame this handler handles.\n */\n abstract readonly kind: HandlerKind\n\n /**\n * Reset the runtime state this handler accumulated while handling\n * the network (e.g. generator resolver progress).\n *\n * @note This method is invoked automatically when the handlers are\n * reset (e.g. `server.resetHandlers()`).\n */\n public reset(): void {}\n\n /**\n * Restore this handler so it can handle the network again after\n * being exhausted (e.g. via `{ once: true }`).\n *\n * @note This method is invoked automatically when the handlers are\n * restored (e.g. `server.restoreHandlers()`).\n */\n public restore(): void {}\n\n /**\n * Release the resources held by this handler.\n *\n * @note This method is invoked automatically when the handler leaves\n * the network: when the network is disabled (e.g. `server.close()`)\n * or when a reset removes it (e.g. `server.resetHandlers()`). Override it in the handlers that\n * hold onto anything beyond a single frame, like timers, connections,\n * or event listeners. Returning a promise makes the network await\n * this handler's disposal before it tears itself down.\n */\n public dispose(): MaybePromise<void> {}\n}\n","// Ignore the source files traces for local testing.\nconst SOURCE_FRAME = /[/\\\\]msw[/\\\\]src[/\\\\](.+)/\n\nconst BUILD_FRAME =\n /(node_modules)?[/\\\\]lib[/\\\\](core|browser|node|iife)[/\\\\]|^[^/\\\\]*$/\n\n/**\n * Return the stack trace frame of a function's invocation.\n */\nexport function getCallFrame(error: Error) {\n // In <IE11, new Error may return an undefined stack\n const stack = error.stack\n\n if (!stack) {\n return\n }\n\n const frames: string[] = stack.split('\\n').slice(1)\n\n // Get the first frame that doesn't reference the library's internal trace.\n // Assume that frame is the invocation frame.\n const declarationFrame = frames.find((frame) => {\n return !(SOURCE_FRAME.test(frame) || BUILD_FRAME.test(frame))\n })\n\n if (!declarationFrame) {\n return\n }\n\n // Extract file reference from the stack frame.\n const declarationPath = declarationFrame\n .replace(/\\s*at [^()]*\\(([^)]+)\\)/, '$1')\n .replace(/^@/, '')\n return declarationPath\n}\n","import { format } from 'outvariant'\n\nconst LIBRARY_PREFIX = '[MSW]'\n\n/**\n * Formats a given message by appending the library's prefix string.\n */\nfunction formatMessage(message: string, ...positionals: any[]): string {\n const interpolatedMessage = format(message, ...positionals)\n return `${LIBRARY_PREFIX} ${interpolatedMessage}`\n}\n\n/**\n * Prints a library-specific warning.\n */\nfunction warn(message: string, ...positionals: any[]): void {\n console.warn(formatMessage(message, ...positionals))\n}\n\n/**\n * Prints a library-specific error.\n */\nfunction error(message: string, ...positionals: any[]): void {\n console.error(formatMessage(message, ...positionals))\n}\n\nexport const devUtils = {\n formatMessage,\n warn,\n error,\n}\n\n/**\n * Internal error instance.\n * Used to differentiate the library errors that must be forwarded\n * to the user from the unhandled exceptions. Use this if you don't\n * wish for the error to be coerced to a 500 fallback response.\n */\nexport class InternalError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'InternalError'\n }\n}\n","/**\n * Reason phrases of the known HTTP status codes.\n * @see https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml\n */\nexport const httpStatusMessages: Record<number, string> = {\n 100: 'Continue',\n 101: 'Switching Protocols',\n 102: 'Processing',\n 103: 'Early Hints',\n 200: 'OK',\n 201: 'Created',\n 202: 'Accepted',\n 203: 'Non-Authoritative Information',\n 204: 'No Content',\n 205: 'Reset Content',\n 206: 'Partial Content',\n 207: 'Multi-Status',\n 208: 'Already Reported',\n 226: 'IM Used',\n 300: 'Multiple Choices',\n 301: 'Moved Permanently',\n 302: 'Found',\n 303: 'See Other',\n 304: 'Not Modified',\n 305: 'Use Proxy',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 406: 'Not Acceptable',\n 407: 'Proxy Authentication Required',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 411: 'Length Required',\n 412: 'Precondition Failed',\n 413: 'Payload Too Large',\n 414: 'URI Too Long',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 417: 'Expectation Failed',\n 418: \"I'm a Teapot\",\n 421: 'Misdirected Request',\n 422: 'Unprocessable Entity',\n 423: 'Locked',\n 424: 'Failed Dependency',\n 425: 'Too Early',\n 426: 'Upgrade Required',\n 428: 'Precondition Required',\n 429: 'Too Many Requests',\n 431: 'Request Header Fields Too Large',\n 451: 'Unavailable For Legal Reasons',\n 500: 'Internal Server Error',\n 501: 'Not Implemented',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n 505: 'HTTP Version Not Supported',\n 506: 'Variant Also Negotiates',\n 507: 'Insufficient Storage',\n 508: 'Loop Detected',\n 509: 'Bandwidth Limit Exceeded',\n 510: 'Not Extended',\n 511: 'Network Authentication Required',\n}\n","import type { HttpResponse, HttpResponseInit } from '#http/http-response'\nimport { httpStatusMessages } from './http-status-messages'\n\nconst kSetCookie = Symbol('kSetCookie')\n\nexport interface HttpResponseDecoratedInit extends HttpResponseInit {\n status: number\n statusText: string\n headers: Headers\n}\n\nexport function normalizeResponseInit(\n init: HttpResponseInit = {},\n): HttpResponseDecoratedInit {\n const status = init?.status || 200\n const statusText = init?.statusText || httpStatusMessages[status] || ''\n const headers = new Headers(init?.headers)\n\n return {\n ...init,\n headers,\n status,\n statusText,\n }\n}\n\nexport function decorateResponse(\n response: HttpResponse<any>,\n init: HttpResponseDecoratedInit,\n): Response {\n // Allow mocking the response type.\n if (init.type) {\n Object.defineProperty(response, 'type', {\n value: init.type,\n enumerable: true,\n writable: false,\n })\n }\n\n const responseCookies = init.headers.getSetCookie()\n\n if (responseCookies) {\n // Record the raw \"Set-Cookie\" response header provided\n // in the HeadersInit. This is later used to store these cookies\n // in cookie jar and return the right cookies in the \"cookies\"\n // response resolver argument.\n Object.defineProperty(response, kSetCookie, {\n value: responseCookies,\n enumerable: false,\n writable: false,\n })\n }\n\n return response\n}\n\nexport function getRawSetCookie(response: Response): Array<string> {\n return Reflect.get(response, kSetCookie) || []\n}\n\n/**\n * Copy the given response own properties, like internal symbols,\n * onto another response. Used for faithful internal copying of responses.\n */\nexport function copyResponseOwnProperties(\n source: Response,\n target: Response,\n): void {\n for (const propertyName of Reflect.ownKeys(source)) {\n const descriptor = Object.getOwnPropertyDescriptor(source, propertyName)\n const existingDescriptor = Object.getOwnPropertyDescriptor(\n target,\n propertyName,\n )\n\n if (descriptor && existingDescriptor == null) {\n Object.defineProperty(target, propertyName, descriptor)\n }\n }\n}\n","/**\n * Performs a case-insensitive comparison of two given strings.\n */\nexport function isStringEqual(actual: string, expected: string): boolean {\n return actual.toLowerCase() === expected.toLowerCase()\n}\n","interface GetTimestampOptions {\n milliseconds?: boolean\n}\n\n/**\n * Returns a timestamp string in a \"HH:MM:SS\" format.\n */\nexport function getTimestamp(options?: GetTimestampOptions): string {\n const now = new Date()\n const timestamp = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`\n\n if (options?.milliseconds) {\n return `${timestamp}.${now.getMilliseconds().toString().padStart(3, '0')}`\n }\n\n return timestamp\n}\n","/**\n * Determines if the given URL string is an absolute URL.\n */\nexport function isAbsoluteUrl(url: string): boolean {\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url)\n}\n","import { isAbsoluteUrl } from './is-absolute-url'\n\n/**\n * Returns an absolute URL based on the given path.\n */\nexport function getAbsoluteUrl(path: string, baseUrl?: string): string {\n // already absolute URL\n if (isAbsoluteUrl(path)) {\n return path\n }\n\n // Ignore path with pattern start with *\n if (path.startsWith('*')) {\n return path\n }\n\n // Resolve a relative request URL against a given custom \"baseUrl\"\n // or the document baseURI (in the case of browser/browser-like environments).\n const origin = baseUrl || (typeof location !== 'undefined' && location.href)\n\n return origin\n ? // Encode and decode the path to preserve escaped characters.\n decodeURI(new URL(encodeURI(path), origin).href)\n : path\n}\n","import type { Path } from './match-request-url'\nimport { getCleanUrlString } from '#utils/get-clean-url-string'\nimport { getAbsoluteUrl } from '../url/get-absolute-url'\n\n/**\n * Normalizes a given request handler path:\n * - Preserves RegExp.\n * - Removes query parameters and hashes.\n * - Rebases relative URLs against the \"baseUrl\" or the current location.\n * - Preserves relative URLs in Node.js, unless specified otherwise.\n * - Preserves optional path parameters.\n */\nexport function normalizePath<ThisPath extends Path>(\n path: ThisPath,\n baseUrl?: string,\n): ThisPath {\n // RegExp paths do not need normalization.\n if (path instanceof RegExp) {\n return path\n }\n\n const maybeAbsoluteUrl = getAbsoluteUrl(path, baseUrl)\n\n return getCleanUrlString(maybeAbsoluteUrl) as ThisPath\n}\n","import { matchPattern } from '@msw/url'\nimport { getCleanUrl } from '@mswjs/interceptors'\nimport { normalizePath } from './normalize-path'\n\nexport type Path = string | RegExp\nexport type PathParams<KeyType extends keyof any = string> = {\n [ParamName in KeyType]?: string | ReadonlyArray<string>\n}\n\nexport interface Match {\n matches: boolean\n params?: PathParams\n}\n\nexport function isPath(value: unknown): value is Path {\n return typeof value === 'string' || value instanceof RegExp\n}\n\n/**\n * Match the given URL against a path pattern.\n */\nexport function matchRequestUrl(\n url: URL,\n pattern: Path,\n baseUrl?: string,\n): Match {\n const cleanUrl = getCleanUrl(url)\n\n if (pattern instanceof RegExp) {\n const match = pattern.flags.includes('g')\n ? [...cleanUrl.matchAll(pattern)].flat()\n : cleanUrl.match(pattern)\n\n return {\n matches: match != null && match.length > 0,\n params: Object.fromEntries(\n (match ?? []).slice(1).map((value, index) => [index, value]),\n ),\n }\n }\n\n // Resolve potentially realive patterns against the baseUrl.\n const normalizedPath = normalizePath(pattern, baseUrl)\n return matchPattern(normalizedPath, cleanUrl)\n}\n","/**\n * Returns a relative URL if the given request URL is relative\n * to the current origin. Otherwise returns an absolute URL.\n */\nexport function toPublicUrl(url: string | URL): string {\n const urlInstance = url instanceof URL ? url : new URL(url)\n\n if (\n typeof location !== 'undefined' &&\n urlInstance.origin === location.origin\n ) {\n return urlInstance.pathname\n }\n\n return urlInstance.origin + urlInstance.pathname\n}\n","/**\n * Parses a given value into a JSON.\n * Does not throw an exception on an invalid JSON string.\n */\nexport function jsonParse<ValueType extends Record<string, any>>(\n value: any,\n): ValueType | undefined {\n try {\n return JSON.parse(value)\n } catch {\n return undefined\n }\n}\n","import { isNodeProcess } from 'is-node-process'\nimport { invariant } from 'outvariant'\nimport {\n Cookie,\n CookieJar,\n MemoryCookieStore,\n type SerializedCookie,\n type MemoryCookieStoreIndex,\n} from 'tough-cookie'\nimport { jsonParse } from './internal/json-parse'\n\nclass CookieStore {\n #storageKey = '__msw-cookie-store__'\n #jar: CookieJar\n #memoryStore: MemoryCookieStore\n\n constructor() {\n invariant(\n typeof localStorage !== 'undefined',\n 'Failed to create a CookieStore: `localStorage` is not available in this environment. This is likely an issue with your environment, which has been detected as browser (or browser-like) environment and must implement global browser APIs correctly.',\n )\n\n this.#memoryStore = new MemoryCookieStore()\n this.#memoryStore.idx = this.getCookieStoreIndex()\n this.#jar = new CookieJar(this.#memoryStore)\n }\n\n public getCookies(url: string): Array<Cookie> {\n return this.#jar.getCookiesSync(url)\n }\n\n public async setCookie(cookieName: string, url: string): Promise<void> {\n await this.#jar.setCookie(cookieName, url)\n this.persist()\n }\n\n private getCookieStoreIndex(): MemoryCookieStoreIndex {\n if (\n typeof localStorage === 'undefined' ||\n typeof localStorage.getItem !== 'function'\n ) {\n return {}\n }\n\n const cookiesString = localStorage.getItem(this.#storageKey)\n if (cookiesString == null) {\n return {}\n }\n\n const rawCookies = jsonParse<Array<Record<string, unknown>>>(cookiesString)\n if (rawCookies == null) {\n return {}\n }\n\n const cookies: MemoryCookieStoreIndex = {}\n\n for (const rawCookie of rawCookies) {\n const cookie = Cookie.fromJSON(rawCookie)\n\n if (cookie != null && cookie.domain != null && cookie.path != null) {\n cookies[cookie.domain] ||= {}\n cookies[cookie.domain][cookie.path] ||= {}\n cookies[cookie.domain][cookie.path][cookie.key] = cookie\n }\n }\n\n return cookies\n }\n\n private persist(): void {\n if (\n typeof localStorage === 'undefined' ||\n typeof localStorage.setItem !== 'function'\n ) {\n return\n }\n\n const data: Array<SerializedCookie> = []\n const { idx } = this.#memoryStore\n\n for (const domain in idx) {\n for (const path in idx[domain]) {\n for (const key in idx[domain][path]) {\n data.push(idx[domain][path][key].toJSON())\n }\n }\n }\n\n try {\n localStorage.setItem(this.#storageKey, JSON.stringify(data))\n } catch {\n // Persisting cookies is best-effort. If the storage quota is exceeded,\n // keep the cookies in memory so the request handling continues.\n return\n }\n }\n}\n\n// Node.js has no implicit cookie jar. Leave cookie management to the client.\nexport const cookieStore = isNodeProcess() ? null : new CookieStore()\n"],"mappings":"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"}
@@ -79,7 +79,11 @@ type ExtractSourceEvents<Source> = Source extends NetworkSource<infer Frame> ? E
79
79
  declare abstract class NetworkSource<Frame extends AnyNetworkFrame = AnyNetworkFrame> {
80
80
  protected emitter: Emitter<NetworkSourceEventMap<Frame>>;
81
81
  constructor();
82
- abstract enable(): unknown | Promise<unknown>;
82
+ /**
83
+ * Enable this network source.
84
+ * @param context The resolved context of the network this source belongs to.
85
+ */
86
+ abstract enable(context?: NetworkFrameResolutionContext): unknown | Promise<unknown>;
83
87
  queue(frame: Frame): Promise<void>;
84
88
  on<Type extends keyof NetworkSourceEventMap<Frame>>(type: Type, listener: Emitter.Listener<typeof this.emitter, Type>, options?: TypedListenerOptions): void;
85
89
  disable(): void | Promise<void>;
@@ -93,16 +93,26 @@ var HandlersController = class {
93
93
  }
94
94
  reset(nextHandlers) {
95
95
  invariant(nextHandlers.length > 0 ? this.#validateHandlers(nextHandlers) : true, devUtils.formatMessage("Failed to replace initial handlers during reset: invalid handlers. Did you forget to spread the handlers array?"));
96
- for (const handler of this.currentHandlers()) handler.reset();
97
96
  const { initialHandlers } = this.getState();
97
+ const nextInitialHandlers = nextHandlers.length > 0 ? groupHandlersByKind(nextHandlers) : initialHandlers;
98
+ const currentHandlers = new Set(this.currentHandlers());
99
+ const nextHandlersSet = new Set(Object.values(nextInitialHandlers).flat().filter(Boolean));
100
+ for (const handler of currentHandlers.intersection(nextHandlersSet)) handler.reset();
101
+ for (const handler of currentHandlers.difference(nextHandlersSet)) try {
102
+ const disposal = handler.dispose();
103
+ if (disposal instanceof Promise) disposal.catch((error) => {
104
+ this.#printDisposalError(handler, error);
105
+ });
106
+ } catch (error) {
107
+ this.#printDisposalError(handler, error);
108
+ }
98
109
  if (nextHandlers.length === 0) {
99
110
  this.setState({ handlers: { ...initialHandlers } });
100
111
  return;
101
112
  }
102
- const normalizedNextHandlers = groupHandlersByKind(nextHandlers);
103
113
  this.setState({
104
- initialHandlers: normalizedNextHandlers,
105
- handlers: { ...normalizedNextHandlers }
114
+ initialHandlers: nextInitialHandlers,
115
+ handlers: { ...nextInitialHandlers }
106
116
  });
107
117
  }
108
118
  restore() {
@@ -119,6 +129,9 @@ var HandlersController = class {
119
129
  #validateHandlers(handlers) {
120
130
  return handlers.every((handler) => !Array.isArray(handler));
121
131
  }
132
+ #printDisposalError(handler, error) {
133
+ devUtils.error("Failed to dispose of \"%s\" handler removed during reset. Please see the original error below.\n%s", handler.kind, error);
134
+ }
122
135
  };
123
136
  var InMemoryHandlersController = class extends HandlersController {
124
137
  #handlers;
@@ -250,7 +263,7 @@ function defineNetwork(options) {
250
263
  const handlers = frame.getHandlers(handlersController);
251
264
  await frame.resolve(handlers, resolvedOptions.onUnhandledFrame || "warn", resolvedOptions.context);
252
265
  });
253
- return source.enable();
266
+ return source.enable(resolvedOptions.context);
254
267
  }));
255
268
  },
256
269
  disable() {
@@ -1 +1 @@
1
- {"version":3,"file":"interceptor-source.js","names":[],"sources":["../../src/core/experimental/sources/network-source.ts","../../src/core/experimental/handlers-controller.ts","../../src/core/utils/internal/to-readonly-array.ts","../../src/core/utils/internal/disposable.ts","../../src/core/experimental/define-network.ts","../../src/core/experimental/frames/network-frame.ts","../../src/core/utils/request/store-response-cookies.ts","../../src/core/experimental/request-utils.ts","../../src/core/experimental/on-unhandled-frame.ts","../../src/core/experimental/frames/http-frame.ts","../../src/core/experimental/frames/websocket-frame.ts","../../src/core/experimental/sources/interceptor-source.ts"],"sourcesContent":["import { Emitter, TypedEvent, type TypedListenerOptions } from 'rettime'\nimport type {\n AnyNetworkFrame,\n ExtractFrameEvents,\n} from '../frames/network-frame'\n\nclass NetworkFrameEvent<\n DataType = void,\n ReturnType = void,\n EventType extends string = string,\n> extends TypedEvent<DataType, ReturnType, EventType> {\n public frame: AnyNetworkFrame\n\n constructor(type: string, frame: AnyNetworkFrame) {\n super(...([type, {}] as any))\n this.frame = frame\n }\n}\n\ntype NetworkSourceEventMap<Frame extends AnyNetworkFrame> = {\n frame: NetworkFrameEvent<Frame>\n}\n\nexport type ExtractSourceEvents<Source> =\n Source extends NetworkSource<infer Frame> ? ExtractFrameEvents<Frame> : never\n\nexport abstract class NetworkSource<\n Frame extends AnyNetworkFrame = AnyNetworkFrame,\n> {\n protected emitter: Emitter<NetworkSourceEventMap<Frame>>\n\n constructor() {\n this.emitter = new Emitter()\n }\n\n public abstract enable(): unknown | Promise<unknown>\n\n public async queue(frame: Frame): Promise<void> {\n await this.emitter.emitAsPromise(\n // @ts-expect-error Trouble handling a conditional type parameter.\n new NetworkFrameEvent('frame', frame),\n )\n }\n\n public on<Type extends keyof NetworkSourceEventMap<Frame>>(\n type: Type,\n listener: Emitter.Listener<typeof this.emitter, Type>,\n options?: TypedListenerOptions,\n ): void {\n this.emitter.on(type, listener, options)\n }\n\n public disable(): void | Promise<void> {\n this.emitter.removeAllListeners()\n }\n}\n","import { invariant } from 'outvariant'\nimport type { HandlerKind } from '../handlers/handler'\nimport type { RequestHandler } from '../handlers/request-handler'\nimport type {\n WebSocketHandler,\n AnyWebSocketExtension,\n} from '#ws/websocket-handler'\nimport { devUtils } from '../utils/internal/dev-utils'\nimport type { MaybePromise } from '../type-utils'\nimport {\n getSiblingHandlers,\n isSiblingHandler,\n} from '../utils/internal/attach-sibling-handlers'\n\nexport type AnyHandler =\n RequestHandler | WebSocketHandler<AnyWebSocketExtension>\ntype HandlerOfKind<Kind extends HandlerKind> = Extract<\n AnyHandler,\n { kind: Kind }\n>\ntype HandlersMapOfKind<Kind extends HandlerKind> = {\n [K in Kind]?: Array<HandlerOfKind<K>>\n}\nexport type HandlersMap = HandlersMapOfKind<HandlerKind>\n\nfunction addHandlerToGroup<Kind extends HandlerKind>(\n groups: HandlersMapOfKind<Kind>,\n kind: Kind,\n handler: HandlerOfKind<Kind>,\n): void {\n const bucket = (groups[kind] ||= [])\n bucket.push(handler)\n}\n\nfunction prependHandlersToGroup<Kind extends HandlerKind>(\n groups: HandlersMapOfKind<Kind>,\n kind: Kind,\n overridesForKind: Array<HandlerOfKind<Kind>>,\n): void {\n const existingForKind = groups[kind]\n\n groups[kind] = existingForKind\n ? [\n ...overridesForKind,\n ...existingForKind.filter((existingHandler) => {\n return !overridesForKind.includes(existingHandler)\n }),\n ]\n : overridesForKind\n}\n\nexport function groupHandlersByKind(handlers: Array<AnyHandler>): HandlersMap {\n const groups: HandlersMap = {}\n const visitedHandlers = new Set<AnyHandler>()\n\n const visit = (handler: AnyHandler) => {\n if (visitedHandlers.has(handler)) {\n return\n }\n\n visitedHandlers.add(handler)\n addHandlerToGroup(groups, handler.kind, handler)\n\n // Recurse so siblings of siblings (user-composed handler\n // graphs) are grouped as well, not silently dropped.\n for (const sibling of getSiblingHandlers(handler)) {\n visit(sibling)\n }\n }\n\n for (const handler of handlers) {\n visit(handler)\n }\n\n return groups\n}\n\nexport interface HandlersControllerState {\n initialHandlers: HandlersMap\n handlers: HandlersMap\n}\n\nexport abstract class HandlersController {\n protected getInitialState(\n initialHandlers: Array<AnyHandler>,\n ): HandlersControllerState {\n invariant(\n this.#validateHandlers(initialHandlers),\n devUtils.formatMessage(\n 'Failed to apply given request handlers: invalid input. Did you forget to spread the request handlers Array?',\n ),\n )\n\n const normalizedInitialHandlers = groupHandlersByKind(initialHandlers)\n\n return {\n initialHandlers: normalizedInitialHandlers,\n handlers: { ...normalizedInitialHandlers },\n }\n }\n\n protected abstract getState(): HandlersControllerState\n protected abstract setState(nextState: Partial<HandlersControllerState>): void\n\n public currentHandlers(): Array<AnyHandler> {\n return Object.values(this.getState().handlers)\n .flat()\n .filter((handler) => handler != null)\n }\n\n /**\n * Return the list of explicitly registered handlers.\n * Unlike `currentHandlers()`, this excludes sibling handlers,\n * which are an implementation detail (e.g. the WebSocket upgrade\n * handler or the GraphQL subscription transport).\n */\n public listHandlers(): Array<AnyHandler> {\n return this.currentHandlers().filter((handler) => {\n return !isSiblingHandler(handler)\n })\n }\n\n /**\n * Return the list of handlers of the given kind.\n */\n public getHandlersByKind<Kind extends HandlerKind>(\n kind: Kind,\n ): Array<HandlerOfKind<Kind>> {\n return this.getState().handlers[kind] || []\n }\n\n public use(nextHandlers: Array<AnyHandler>): void {\n invariant(\n this.#validateHandlers(nextHandlers),\n devUtils.formatMessage(\n '[MSW] Failed to call \"use()\" with the given request handlers: invalid input. Did you forget to spread the array of request handlers?',\n ),\n )\n\n if (nextHandlers.length === 0) {\n return\n }\n\n const { handlers } = this.getState()\n const overrides = groupHandlersByKind(nextHandlers)\n\n // Prepend overrides to their respective kind buckets so they take\n // priority over existing handlers while preserving input order.\n // Drop existing references that reappear in the overrides (e.g. a\n // shared upgrade sibling from the same link) so a handler is never\n // registered twice.\n if (overrides.request) {\n prependHandlersToGroup(handlers, 'request', overrides.request)\n }\n\n if (overrides.websocket) {\n prependHandlersToGroup(handlers, 'websocket', overrides.websocket)\n }\n\n this.setState({ handlers })\n }\n\n public reset(nextHandlers: Array<AnyHandler>): void {\n invariant(\n nextHandlers.length > 0 ? this.#validateHandlers(nextHandlers) : true,\n devUtils.formatMessage(\n 'Failed to replace initial handlers during reset: invalid handlers. Did you forget to spread the handlers array?',\n ),\n )\n\n for (const handler of this.currentHandlers()) {\n handler.reset()\n }\n\n const { initialHandlers } = this.getState()\n\n if (nextHandlers.length === 0) {\n this.setState({\n handlers: { ...initialHandlers },\n })\n\n return\n }\n\n const normalizedNextHandlers = groupHandlersByKind(nextHandlers)\n\n this.setState({\n initialHandlers: normalizedNextHandlers,\n handlers: { ...normalizedNextHandlers },\n })\n }\n\n public restore(): void {\n for (const handler of this.currentHandlers()) {\n handler.restore()\n }\n }\n\n public dispose(): MaybePromise<void> {\n const pendingDisposals: Array<Promise<void>> = []\n\n for (const handler of this.currentHandlers()) {\n const disposal = handler.dispose()\n\n if (disposal instanceof Promise) {\n pendingDisposals.push(disposal)\n }\n }\n\n // Stay synchronous unless a handler actually disposes of\n // itself asynchronously.\n if (pendingDisposals.length > 0) {\n return Promise.all(pendingDisposals).then(() => {})\n }\n }\n\n #validateHandlers(handlers: Array<AnyHandler>): boolean {\n return handlers.every((handler) => !Array.isArray(handler))\n }\n}\n\nexport class InMemoryHandlersController extends HandlersController {\n #handlers: HandlersMap\n #initialHandlers: HandlersMap\n\n constructor(initialHandlers: Array<AnyHandler>) {\n super()\n\n const initialState = this.getInitialState(initialHandlers)\n\n this.#initialHandlers = initialState.initialHandlers\n this.#handlers = initialState.handlers\n }\n\n protected getState(): HandlersControllerState {\n return {\n initialHandlers: this.#initialHandlers,\n handlers: this.#handlers,\n }\n }\n\n protected setState(nextState: Partial<HandlersControllerState>): void {\n if (nextState.initialHandlers) {\n this.#initialHandlers = nextState.initialHandlers\n }\n\n if (nextState.handlers) {\n this.#handlers = nextState.handlers\n }\n }\n}\n","/**\n * Creates an immutable copy of the given array.\n */\nexport function toReadonlyArray<T>(source: Array<T>): ReadonlyArray<T> {\n const clone = [...source] as Array<T>\n Object.freeze(clone)\n return clone\n}\n","import { devUtils } from './dev-utils'\n\nexport type DisposableSubscription = () => void\n\nexport class Disposable {\n protected subscriptions: Array<DisposableSubscription> = []\n\n public dispose() {\n let subscription: DisposableSubscription | undefined\n const errors: Array<Error> = []\n\n while ((subscription = this.subscriptions.shift())) {\n try {\n subscription()\n } catch (error) {\n if (error instanceof Error) {\n errors.push(error)\n }\n }\n }\n\n if (errors.length > 0) {\n console.error(\n new AggregateError(\n errors,\n devUtils.formatMessage(\n 'Failed to dispose of some side effects. This is likely an issue with MSW, please report it on GitHub: https://github.com/mswjs/msw/issues',\n ),\n ),\n )\n }\n }\n}\n","import { invariant } from 'outvariant'\nimport { Emitter, type DefaultEventMap } from 'rettime'\nimport {\n NetworkSource,\n type ExtractSourceEvents,\n} from './sources/network-source'\nimport type { NetworkFrameResolutionContext } from './frames/network-frame'\nimport type { UnhandledFrameHandle } from './on-unhandled-frame'\nimport {\n HandlersController,\n InMemoryHandlersController,\n type AnyHandler,\n} from './handlers-controller'\nimport { toReadonlyArray } from '../utils/internal/to-readonly-array'\nimport { Disposable } from '../utils/internal/disposable'\nimport type { UnionToIntersection } from '../type-utils'\n\ntype MergeEventMaps<Sources extends Array<NetworkSource<any>>> =\n UnionToIntersection<ExtractSourceEvents<Sources[number]>> extends infer R\n ? R extends Record<string, any>\n ? R\n : DefaultEventMap\n : DefaultEventMap\n\ntype MaybePromise<T> =\n Extract<T, Promise<unknown>> extends never ? void : Promise<void>\n\nexport interface DefineNetworkOptions<\n Sources extends Array<NetworkSource<any>>,\n> {\n /**\n * List of the network sources.\n * Every network source emits frames, and every frame describes how\n * to handle the various network scenarios, like mocking a response,\n * erroring the request, or performing it as-is.\n */\n sources: Sources\n /**\n * List of handlers to describe the network.\n */\n handlers?: Array<AnyHandler> | HandlersController\n context?: NetworkFrameResolutionContext\n onUnhandledFrame?: UnhandledFrameHandle\n}\n\nexport interface NetworkApi<\n Sources extends Array<NetworkSource<any>>,\n> extends NetworkHandlersApi {\n readyState: NetworkReadyState\n /**\n * Enable the network interception and handling.\n */\n enable: () => MaybePromise<ReturnType<Sources[number]['enable']>>\n /**\n * Disable the network interception and handling.\n */\n disable: () => MaybePromise<ReturnType<Sources[number]['disable']>>\n /**\n * Configure the network instance with additional options.\n * The options provided in the `.configure()` call will override the same\n * options in the `defineNetwork()` call.\n */\n configure: (options: Partial<DefineNetworkOptions<Sources>>) => void\n events: Emitter<MergeEventMaps<Sources>>\n}\n\ninterface NetworkHandlersApi {\n use: (...handlers: Array<AnyHandler>) => void\n resetHandlers: (...handlers: Array<AnyHandler>) => void\n restoreHandlers: () => void\n listHandlers: () => ReadonlyArray<AnyHandler>\n}\n\nfunction colorlessPromiseAll<T>(values: Array<T>): MaybePromise<T>\nfunction colorlessPromiseAll(values: Array<unknown>): Promise<void> | void {\n const promises: Array<Promise<void>> = []\n\n for (const value of values) {\n if (value instanceof Promise) {\n promises.push(value)\n }\n }\n\n if (promises.length > 0) {\n return Promise.all(promises).then(() => {})\n }\n}\n\nexport enum NetworkReadyState {\n DISABLED,\n ENABLED,\n}\n\n/**\n * Define a network instance with the given configuration.\n * @example\n * import { InterceptorSource } from 'msw/experimental'\n * import { handlers } from './handlers'\n *\n * const network = defineNetwork({\n * sources: [new InterceptorSource({ interceptors })],\n * handlers,\n * })\n * await network.enable()\n */\nexport function defineNetwork<Sources extends Array<NetworkSource<any>>>(\n options: DefineNetworkOptions<Sources>,\n): NetworkApi<Sources> {\n let readyState: NetworkReadyState = NetworkReadyState.DISABLED\n const events = new Emitter<MergeEventMaps<Sources>>()\n const disposable = new Disposable()\n\n const deriveHandlersController = (\n handlers: DefineNetworkOptions<Sources>['handlers'],\n ) => {\n return handlers instanceof HandlersController\n ? handlers\n : new InMemoryHandlersController(handlers || [])\n }\n\n let resolvedOptions: DefineNetworkOptions<Sources> = {\n ...options,\n }\n\n /**\n * @note Create the handlers controller immediately because\n * certain setup APIs, like `setupServer`, don't await `.enable` (`.listen`).\n */\n let handlersController = deriveHandlersController(resolvedOptions.handlers)\n\n return {\n get readyState() {\n return readyState\n },\n events,\n configure(options) {\n invariant(\n readyState === NetworkReadyState.DISABLED,\n 'Failed to call \"configure()\" on the network: cannot configure an already enabled network.',\n )\n\n if (\n options.handlers &&\n !Object.is(options.handlers, resolvedOptions.handlers)\n ) {\n handlersController = deriveHandlersController(options.handlers)\n }\n\n resolvedOptions = {\n ...resolvedOptions,\n ...options,\n }\n },\n enable() {\n invariant(\n readyState === NetworkReadyState.DISABLED,\n 'Failed to call \"enable\" on the network: already enabled',\n )\n\n readyState = NetworkReadyState.ENABLED\n\n /**\n * @note Use a session object scoped to the current \"enable()\"\n * to prevent \"frame.events\" listeners from surviving across enable/disable cycles.\n * @see The note about `AbortController` below.\n */\n const session = { active: true }\n disposable['subscriptions'].push(() => {\n session.active = false\n })\n\n const result = resolvedOptions.sources.map((source) => {\n /**\n * @note Preemptively disable the network source before enabling.\n * This intentionally calls only the prototype method that clears the\n * event listeners and nothing else. This prevents the \"frame\" listeners\n * from accumulating across enable/disable in case the source is a singleton.\n */\n NetworkSource.prototype.disable.call(source)\n\n source.on('frame', async ({ frame }) => {\n frame.events.on('*', (event) => {\n /**\n * @note Prevent event forwarding manually and not via an AbortController\n * because certain runtimes, like Cloudflare, throw when referencing an\n * AbortController created in a different context. Bear in mind that the frame\n * events run in the patched request client context while the AbortController\n * is created outside, in the \"defineNetwork\" closure, which is a test context.\n */\n if (!session.active) {\n return\n }\n\n events.emit(event)\n })\n\n const handlers = frame.getHandlers(handlersController)\n\n await frame.resolve(\n handlers,\n resolvedOptions.onUnhandledFrame || 'warn',\n resolvedOptions.context,\n )\n })\n\n return source.enable()\n })\n\n return colorlessPromiseAll(result) as MaybePromise<\n ReturnType<Sources[number]['enable']>\n >\n },\n disable() {\n invariant(\n readyState === NetworkReadyState.ENABLED,\n 'Failed to call \"disable\" on the network: already disabled',\n )\n\n readyState = NetworkReadyState.DISABLED\n\n // Let the handlers release the resources they hold before\n // tearing down the network itself. Handlers may still need the\n // network while disposing of themselves (e.g. to close the\n // connections they own).\n const handlersDisposal = handlersController.dispose()\n disposable.dispose()\n\n /**\n * @note Tear down the sources synchronously, never behind the\n * handlers disposal. `disable()` is not always awaited (e.g.\n * `server.close()` is synchronous), and a deferred teardown would\n * race any `enable()` that follows, disabling the sources that the\n * new session has just enabled.\n */\n const sourcesDisposal = colorlessPromiseAll(\n resolvedOptions.sources.map((source) => source.disable()),\n )\n\n /**\n * @note Await both disposals so neither rejection goes unobserved.\n * Chaining them would leave the source disposal floating whenever\n * the handlers disposal rejects.\n */\n return (\n handlersDisposal instanceof Promise\n ? Promise.all([handlersDisposal, sourcesDisposal]).then(() => {})\n : sourcesDisposal\n ) as MaybePromise<ReturnType<Sources[number]['disable']>>\n },\n use(...handlers) {\n handlersController.use(handlers)\n },\n resetHandlers(...handlers) {\n handlersController.reset(handlers)\n },\n restoreHandlers() {\n handlersController.restore()\n },\n listHandlers() {\n return toReadonlyArray(handlersController.listHandlers())\n },\n }\n}\n","import { Emitter, type DefaultEventMap } from 'rettime'\nimport type { AnyHandler, HandlersController } from '../handlers-controller'\nimport type { UnhandledFrameHandle } from '../on-unhandled-frame'\n\nexport type AnyNetworkFrame = NetworkFrame<string, unknown, any>\n\nexport type ExtractFrameEvents<Frame> =\n Frame extends NetworkFrame<any, any, infer Events> ? Events : never\n\nexport interface NetworkFrameResolutionContext {\n baseUrl?: string | URL\n quiet?: boolean\n}\n\n/**\n * The base for the network frames. Extend this abstract class\n * to implement custom network frames.\n */\nexport abstract class NetworkFrame<\n Protocol extends string,\n Data,\n Events extends DefaultEventMap,\n> {\n public events: Emitter<Events>\n\n constructor(\n public readonly protocol: Protocol,\n public readonly data: Data,\n ) {\n this.events = new Emitter()\n }\n\n public abstract getHandlers(controller: HandlersController): Array<AnyHandler>\n\n /**\n * Resolve the current frame against the given list of handlers.\n * Optionally, use a custom resolution context to control behaviors\n * like `baseUrl`.\n *\n * Returns `true` if the frame was handled, `false` if it wasn't, and `null`\n * if its handling was skipped (e.g. the frame was bypassed).\n */\n public abstract resolve(\n handlers: Array<AnyHandler>,\n onUnhandledFrame: UnhandledFrameHandle,\n resolutionContext?: NetworkFrameResolutionContext,\n ): Promise<boolean | null>\n\n /**\n * Perform this network frame as-is.\n */\n public abstract passthrough(): void\n\n /**\n * Error the underling network frame.\n * @param reason The reason for the error.\n */\n public abstract errorWith(reason?: unknown): void\n\n /**\n * Get a message to be used when this frame is unhandled.\n */\n public abstract getUnhandledMessage(): Promise<string>\n}\n","import { cookieStore } from '../cookie-store'\nimport { getRawSetCookie } from '../response-decorators'\n\nexport async function storeResponseCookies(\n request: Request,\n response: Response,\n): Promise<void> {\n if (cookieStore === null) {\n return\n }\n\n for (const responseCookie of getRawSetCookie(response)) {\n await cookieStore.setCookie(responseCookie, request.url)\n }\n}\n","export function shouldBypassRequest(request: Request): boolean {\n return !!request.headers.get('accept')?.includes('msw/passthrough')\n}\n\n/**\n * Remove the internal passthrough instruction from the request's `Accept` header.\n */\nexport function deleteRequestPassthroughHeader(request: Request): void {\n const acceptHeader = request.headers.get('accept')\n\n /**\n * @note Remove the internal bypass request header.\n * In the browser, this is done by the worker script.\n * In Node.js, it has to be done here.\n */\n if (acceptHeader) {\n const nextAcceptHeader = acceptHeader.replace(/(,\\s+)?msw\\/passthrough/, '')\n\n if (nextAcceptHeader) {\n request.headers.set('accept', nextAcceptHeader)\n } else {\n request.headers.delete('accept')\n }\n }\n}\n","import { invariant } from 'outvariant'\nimport { isCommonAssetRequest } from '#utils/is-common-asset-request'\nimport { devUtils, InternalError } from '../utils/internal/dev-utils'\nimport { HttpNetworkFrame } from './frames/http-frame'\nimport type { AnyNetworkFrame } from './frames/network-frame'\n\nexport type UnhandledFrameHandle =\n UnhandledFrameStrategy | UnhandledFrameCallback\n\nexport type UnhandledFrameStrategy = 'bypass' | 'warn' | 'error'\n\nexport type UnhandledFrameCallback = (args: {\n frame: AnyNetworkFrame\n defaults: UnhandledFrameDefaults\n}) => Promise<void> | void\n\ntype UnhandledFrameDefaults = {\n warn: () => void\n error: () => void\n}\n\nexport async function executeUnhandledFrameHandle(\n frame: AnyNetworkFrame,\n handle: UnhandledFrameHandle,\n): Promise<void> {\n const printStrategyMessage = async (\n strategy: UnhandledFrameStrategy,\n ): Promise<void> => {\n if (strategy === 'bypass') {\n return\n }\n\n const message = await frame.getUnhandledMessage()\n\n switch (strategy) {\n case 'warn': {\n return devUtils.warn('Warning: %s', message)\n }\n\n case 'error': {\n return devUtils.error('Error: %s', message)\n }\n }\n }\n\n const applyStrategy = async (\n strategy: UnhandledFrameStrategy,\n ): Promise<void> => {\n invariant.as(\n InternalError,\n strategy === 'bypass' || strategy === 'warn' || strategy === 'error',\n devUtils.formatMessage(\n 'Failed to react to an unhandled network frame: unknown strategy \"%s\". Please provide one of the supported strategies (\"bypass\", \"warn\", \"error\") or a custom callback function as the value of the \"onUnhandledFrame\" option.',\n strategy,\n ),\n )\n\n if (strategy === 'bypass') {\n return\n }\n\n await printStrategyMessage(strategy)\n\n if (strategy === 'error') {\n return Promise.reject(\n new InternalError(\n devUtils.formatMessage(\n 'Cannot bypass a request when using the \"error\" strategy for the \"onUnhandledFrame\" option.',\n ),\n ),\n )\n }\n }\n\n if (typeof handle === 'function') {\n return handle({\n frame,\n defaults: {\n warn: printStrategyMessage.bind(null, 'warn'),\n /**\n * @note The defaults only print the corresponding messages now.\n * They do not affect the frame resolution (e.g. do not error the frame).\n * That is only for backward compatibility reasons. In the future, these should\n * be an alias to `applyStrategy.bind(null, 'error')` instead.\n */\n error: printStrategyMessage.bind(null, 'error'),\n },\n })\n }\n\n /**\n * Ignore unhandled common HTTP assets.\n * @note Calling this here applies the common assets check\n * only to the scenarios when `onUnhandledFrame` was set to a predefined strategy.\n * When using a custom function, you need to check for common assets manually.\n */\n if (\n frame instanceof HttpNetworkFrame &&\n isCommonAssetRequest(frame.data.request)\n ) {\n return\n }\n\n return applyStrategy(handle)\n}\n","import { TypedEvent } from 'rettime'\nimport { until } from 'until-async'\nimport { createRequestId } from '@mswjs/interceptors'\nimport {\n NetworkFrame,\n type NetworkFrameResolutionContext,\n} from './network-frame'\nimport { toPublicUrl } from '../../utils/request/to-public-url'\nimport { isStringEqual } from '../../utils/internal/is-string-equal'\nimport { executeHandlers } from '../../utils/execute-handlers'\nimport { storeResponseCookies } from '../../utils/request/store-response-cookies'\nimport { shouldBypassRequest } from '../request-utils'\nimport { isPassthroughResponse } from '#utils/passthrough'\nimport { devUtils } from '../../utils/internal/dev-utils'\nimport {\n executeUnhandledFrameHandle,\n type UnhandledFrameHandle,\n} from '../on-unhandled-frame'\nimport type { HandlersController } from '../handlers-controller'\nimport type { AnyHandler } from '../handlers-controller'\nimport type { RequestHandler } from '../../handlers/request-handler'\n\ninterface HttpNetworkFrameOptions {\n id?: string\n request: Request\n}\n\nclass RequestEvent<\n DataType extends { requestId: string; request: Request } = {\n requestId: string\n request: Request\n },\n ReturnType = void,\n EventType extends string = string,\n> extends TypedEvent<DataType, ReturnType, EventType> {\n public readonly requestId: string\n public readonly request: Request\n\n constructor(type: EventType, data: DataType) {\n super(...([type, {}] as any))\n this.requestId = data.requestId\n this.request = data.request\n }\n}\n\nexport class ResponseEvent<\n DataType extends {\n requestId: string\n request: Request\n response: Response\n } = {\n requestId: string\n request: Request\n response: Response\n },\n ReturnType = void,\n EventType extends string = string,\n> extends TypedEvent<DataType, ReturnType, EventType> {\n public readonly requestId: string\n public readonly request: Request\n public readonly response: Response\n\n constructor(type: EventType, data: DataType) {\n super(...([type, {}] as any))\n this.requestId = data.requestId\n this.request = data.request\n this.response = data.response\n }\n}\n\nclass UnhandledExceptionEvent<\n DataType extends {\n error: Error\n requestId: string\n request: Request\n } = {\n error: Error\n requestId: string\n request: Request\n },\n ReturnType = void,\n EventType extends string = string,\n> extends TypedEvent<DataType, ReturnType, EventType> {\n public readonly error: Error\n public readonly requestId: string\n public readonly request: Request\n\n constructor(type: EventType, data: DataType) {\n super(...([type, {}] as any))\n this.error = data.error\n this.requestId = data.requestId\n this.request = data.request\n }\n}\n\nexport type HttpNetworkFrameEventMap = {\n 'request:start': RequestEvent\n 'request:match': RequestEvent\n 'request:unhandled': RequestEvent\n 'request:end': RequestEvent\n 'response:mocked': ResponseEvent\n 'response:bypass': ResponseEvent\n unhandledException: UnhandledExceptionEvent\n}\n\nexport abstract class HttpNetworkFrame extends NetworkFrame<\n 'http',\n {\n id: string\n request: Request\n },\n HttpNetworkFrameEventMap\n> {\n constructor(options: HttpNetworkFrameOptions) {\n const id = options.id || createRequestId()\n super('http', { id, request: options.request })\n }\n\n public getHandlers(controller: HandlersController): Array<AnyHandler> {\n return controller.getHandlersByKind('request')\n }\n\n public abstract respondWith(response?: Response): void\n\n public async getUnhandledMessage(): Promise<string> {\n const { request } = this.data\n\n const url = new URL(request.url)\n const publicUrl = toPublicUrl(url) + url.search\n const requestBody =\n request.body == null ? null : await request.clone().text()\n\n const details = `\\n\\n \\u2022 ${request.method} ${publicUrl}\\n\\n${requestBody ? ` \\u2022 Request body: ${requestBody}\\n\\n` : ''}`\n const message = `intercepted a request without a matching request handler:${details}If you still wish to intercept this unhandled request, please create a request handler for it.\\nRead more: https://mswjs.io/docs/http/intercepting-requests`\n\n return message\n }\n\n public async resolve(\n handlers: Array<RequestHandler>,\n onUnhandledFrame: UnhandledFrameHandle,\n resolutionContext?: NetworkFrameResolutionContext,\n ): Promise<boolean | null> {\n const { id: requestId, request } = this.data\n const requestCloneForLogs = resolutionContext?.quiet\n ? null\n : request.clone()\n\n this.events.emit(new RequestEvent('request:start', { requestId, request }))\n\n // Requests wrapped in explicit \"bypass(request)\".\n if (shouldBypassRequest(request)) {\n this.events.emit(new RequestEvent('request:end', { requestId, request }))\n this.passthrough()\n return null\n }\n\n const [lookupError, lookupResult] = await until(() => {\n return executeHandlers({\n requestId,\n request,\n handlers,\n resolutionContext: {\n baseUrl: resolutionContext?.baseUrl?.toString(),\n quiet: resolutionContext?.quiet,\n },\n })\n })\n\n if (lookupError != null) {\n if (\n !this.events.emit(\n new UnhandledExceptionEvent('unhandledException', {\n error: lookupError,\n requestId,\n request,\n }),\n )\n ) {\n // Surface the error to the developer since they haven't handled it.\n console.error(lookupError)\n devUtils.error(\n 'Encountered an unhandled exception during the handler lookup for \"%s %s\". Please see the original error above.',\n request.method,\n request.url,\n )\n }\n\n this.errorWith(lookupError)\n return null\n }\n\n // No matching handlers.\n if (lookupResult == null) {\n /**\n * @note Unhandled CONNECT requests establish a tunnel through a proxy.\n * They are transport, not the request the developer cares about, so\n * they pass through silently regardless of the unhandled frame strategy.\n * The request sent through the tunnel gets its own resolution.\n */\n if (isStringEqual(request.method, 'CONNECT')) {\n this.events.emit(\n new RequestEvent('request:end', {\n requestId,\n request,\n }),\n )\n\n this.passthrough()\n return null\n }\n\n this.events.emit(\n new RequestEvent('request:unhandled', {\n requestId,\n request,\n }),\n )\n\n /**\n * @note The unhandled frame handle must be executed during the request resolution\n * since it can influence it (e.g. error the request if the \"error\" startegy was used).\n */\n await executeUnhandledFrameHandle(this, onUnhandledFrame).then(\n () => this.passthrough(),\n (error) => this.errorWith(error),\n )\n\n this.events.emit(\n new RequestEvent('request:end', {\n requestId,\n request,\n }),\n )\n\n return false\n }\n\n const { response, handler, parsedResult } = lookupResult\n\n this.events.emit(\n new RequestEvent('request:match', {\n requestId,\n request,\n }),\n )\n\n // Handlers that returned no mocked response.\n if (response == null) {\n this.events.emit(\n new RequestEvent('request:end', {\n requestId,\n request,\n }),\n )\n\n this.passthrough()\n return null\n }\n\n // Handlers that returned explicit `passthrough()`.\n if (isPassthroughResponse(response)) {\n this.events.emit(\n new RequestEvent('request:end', {\n requestId,\n request,\n }),\n )\n\n this.passthrough()\n return null\n }\n\n const responseCloneForLogs = resolutionContext?.quiet\n ? null\n : response.clone()\n\n await storeResponseCookies(request, response)\n\n this.respondWith(response)\n\n this.events.emit(\n new RequestEvent('request:end', {\n requestId,\n request,\n }),\n )\n\n if (!resolutionContext?.quiet) {\n handler.log({\n request: requestCloneForLogs!,\n response: responseCloneForLogs!,\n parsedResult,\n })\n }\n\n return true\n }\n}\n","import { TypedEvent } from 'rettime'\nimport type { GraphQLSubscriptionEvent } from '#graphql/graphql-subscription-event'\nimport type { WebSocketConnectionEventData } from '@mswjs/interceptors/WebSocket'\nimport {\n kConnect,\n kAutoConnect,\n type WebSocketHandler,\n type AnyWebSocketExtension,\n} from '#ws/websocket-handler'\nimport {\n NetworkFrame,\n type NetworkFrameResolutionContext,\n} from './network-frame'\nimport {\n executeUnhandledFrameHandle,\n type UnhandledFrameHandle,\n} from '../on-unhandled-frame'\nimport { devUtils } from '../../utils/internal/dev-utils'\nimport type { HandlersController } from '../handlers-controller'\nimport type { AnyHandler } from '../handlers-controller'\n\nexport interface WebSocketNetworkFrameOptions {\n connection: WebSocketConnectionEventData\n}\n\nexport type WebSocketNetworkFrameEventMap = {\n /**\n * Emitted when a WebSocket connection is intercepted,\n * before any handlers are resolved against it.\n */\n 'websocket:connection': WebSocketConnectionEvent\n /**\n * Emitted when the WebSocket connection errors.\n * This includes initial connection errors as well as runtime errors\n * after the connection has been established.\n */\n 'websocket:error': WebSocketErrorEvent\n 'graphql:subscription': GraphQLSubscriptionEvent\n unhandledException: WebSocketErrorEvent\n}\n\nclass WebSocketConnectionEvent<\n DataType extends {\n url: URL\n protocols: string | Array<string> | undefined\n } = { url: URL; protocols: string | Array<string> | undefined },\n ReturnType = void,\n EventType extends string = string,\n> extends TypedEvent<DataType, ReturnType, EventType> {\n public readonly url: URL\n public readonly protocols: string | Array<string> | undefined\n\n constructor(type: EventType, data: DataType) {\n super(...([type, {}] as any))\n this.url = data.url\n this.protocols = data.protocols\n }\n}\n\nclass WebSocketErrorEvent<\n DataType extends {\n url: URL\n protocols: string | Array<string> | undefined\n error: unknown\n } = {\n url: URL\n protocols: string | Array<string> | undefined\n error: unknown\n },\n ReturnType = void,\n EventType extends string = string,\n> extends WebSocketConnectionEvent<DataType, ReturnType, EventType> {\n public readonly error: unknown\n\n constructor(type: EventType, data: DataType) {\n super(type, data)\n this.error = data.error\n }\n}\n\nexport abstract class WebSocketNetworkFrame extends NetworkFrame<\n 'ws',\n {\n connection: WebSocketConnectionEventData\n },\n WebSocketNetworkFrameEventMap\n> {\n constructor(options: WebSocketNetworkFrameOptions) {\n super('ws', {\n connection: options.connection,\n })\n }\n\n public getHandlers(controller: HandlersController): Array<AnyHandler> {\n return controller.getHandlersByKind('websocket')\n }\n\n public async resolve(\n handlers: Array<WebSocketHandler<AnyWebSocketExtension>>,\n onUnhandledFrame: UnhandledFrameHandle,\n resolutionContext?: NetworkFrameResolutionContext,\n ): Promise<boolean | null> {\n const { connection } = this.data\n\n this.events.emit(\n new WebSocketConnectionEvent('websocket:connection', {\n url: connection.client.url,\n protocols: connection.info.protocols,\n }),\n )\n\n const handleSocketError = (event: Event) => {\n this.events.emit(\n new WebSocketErrorEvent('websocket:error', {\n url: connection.client.url,\n protocols: connection.info.protocols,\n error: getErrorFromEvent(event),\n }),\n )\n }\n\n connection.client.socket.addEventListener('error', handleSocketError)\n connection.client.socket.addEventListener(\n 'close',\n () => {\n connection.client.socket.removeEventListener('error', handleSocketError)\n },\n { once: true },\n )\n\n // No WebSocket handlers defined.\n if (handlers.length === 0) {\n await executeUnhandledFrameHandle(this, onUnhandledFrame).then(\n () => this.passthrough(),\n (error) => this.errorWith(error),\n )\n\n return false\n }\n\n let hasMatchingHandlers = false\n\n for (const handler of handlers) {\n const handlerConnection = await handler.run(connection, {\n baseUrl: resolutionContext?.baseUrl?.toString(),\n /**\n * @note Expose an emit-only reference to this frame's events\n * so the handlers can emit additional events not covered by\n * the frame (e.g. \"graphql:subscription\").\n */\n events: this.events,\n /**\n * @note Do not emit the handler's \"connection\" event when running the handler.\n * Use the run only to get the resolved connection object.\n */\n [kAutoConnect]: false,\n })\n\n if (!handlerConnection) {\n continue\n }\n\n hasMatchingHandlers = true\n\n /**\n * @note Attach the WebSocket logger *before* emitting the handler's \"connection\" event.\n * Connection event listeners may perform actions that should be reflected in the logs\n * (e.g. closing the connection immediately). If the logger is attached after the connection,\n * those actions cannot be properly logged.\n */\n const removeLogger = !resolutionContext?.quiet\n ? handler.log(connection)\n : undefined\n\n try {\n if (!handler[kConnect](handlerConnection)) {\n removeLogger?.()\n }\n } catch (error) {\n if (\n !this.events.emit(\n new WebSocketErrorEvent('unhandledException', {\n error,\n url: connection.client.url,\n protocols: connection.info.protocols,\n }),\n )\n ) {\n console.error(error)\n devUtils.error(\n 'Encountered an unhandled exception during the handler lookup for \"%s\". Please see the original error above.',\n connection.client.url,\n )\n }\n\n /**\n * @note Throw the caught error so it gets picked up by WebSocketInterceptor.\n * It's the interceptor who translates handler errors to WebSocket closures.\n */\n throw error\n }\n }\n\n // No matching WebSocket handlers found.\n if (!hasMatchingHandlers) {\n await executeUnhandledFrameHandle(this, onUnhandledFrame).then(\n () => this.passthrough(),\n (error) => this.errorWith(error),\n )\n\n return false\n }\n\n return true\n }\n\n public async getUnhandledMessage(): Promise<string> {\n const { connection } = this.data\n const details = `\\n\\n \\u2022 ${connection.client.url}\\n\\n`\n\n return `intercepted a WebSocket connection without a matching event handler:${details}If you still wish to intercept this unhandled connection, please create an event handler for it.\\nRead more: https://mswjs.io/docs/websocket`\n }\n}\n\n/**\n * Extract the error from the given \"error\" event, if any.\n * Supports both the `ErrorEvent.error` property and the `cause`\n * property that MSW sets when erroring the connection itself.\n */\nfunction getErrorFromEvent(event: Event): unknown {\n if ('error' in event && event.error != null) {\n return event.error\n }\n\n if ('cause' in event && event.cause != null) {\n return event.cause\n }\n\n return undefined\n}\n","import type { Interceptor, RequestController } from '@mswjs/interceptors'\nimport {\n BatchInterceptor,\n type HttpRequestEventMap,\n type HttpRequestEvent,\n type HttpResponseEvent,\n} from '@mswjs/interceptors'\nimport type {\n WebSocketClientConnection,\n WebSocketInterceptedConnection,\n WebSocketEventMap,\n} from '@mswjs/interceptors/WebSocket'\nimport { NetworkSource } from './network-source'\nimport { InternalError } from '../../utils/internal/dev-utils'\nimport { HttpNetworkFrame, ResponseEvent } from '../frames/http-frame'\nimport { WebSocketNetworkFrame } from '../frames/websocket-frame'\nimport { deleteRequestPassthroughHeader } from '../request-utils'\n\nexport interface InterceptorSourceOptions {\n interceptors: Array<Interceptor<HttpRequestEventMap | WebSocketEventMap>>\n}\n\n/**\n * Create a network source from the given list of interceptors.\n */\nexport class InterceptorSource extends NetworkSource {\n #interceptor: BatchInterceptor<\n InterceptorSourceOptions['interceptors'],\n HttpRequestEventMap & WebSocketEventMap\n >\n\n /**\n * @note Frames are keyed by the request instance, not the request ID.\n * The interceptor emits the same request instance on the \"request\"\n * and \"response\" events, so the frame can be looked up by identity.\n * A weak reference lets the frame be garbage collected alongside\n * its request once the request settles without producing a response\n * (e.g. a passthrough request failing with a network error).\n * @see https://github.com/mswjs/msw/issues/2792\n */\n #frames: WeakMap<Request, HttpNetworkFrame>\n\n constructor(options: InterceptorSourceOptions) {\n super()\n\n this.#interceptor = new BatchInterceptor({\n name: 'interceptor-source',\n interceptors: options.interceptors,\n })\n this.#frames = new WeakMap()\n }\n\n public enable(): void {\n this.#interceptor.apply()\n\n this.#interceptor\n .on('request', this.#handleRequest.bind(this))\n .on('response', this.#handleResponse.bind(this))\n .on('connection', this.#handleWebSocketConnection.bind(this))\n }\n\n public disable(): void {\n super.disable()\n this.#interceptor.dispose()\n\n /**\n * @todo We can also abort any pending frames here, given we implement\n * the `NetworkFrame.abort()` method.\n */\n this.#frames = new WeakMap()\n }\n\n async #handleRequest(event: HttpRequestEvent): Promise<void> {\n const { requestId, request, controller } = event\n const httpFrame = new InterceptorHttpNetworkFrame({\n id: requestId,\n request,\n controller,\n })\n\n this.#frames.set(request, httpFrame)\n await this.queue(httpFrame)\n }\n\n async #handleResponse({\n requestId,\n request,\n response,\n responseType,\n }: HttpResponseEvent): Promise<void> {\n const httpFrame = this.#frames.get(request)\n this.#frames.delete(request)\n\n if (httpFrame == null) {\n return\n }\n\n queueMicrotask(() => {\n try {\n httpFrame.events.emit(\n new ResponseEvent(\n responseType === 'mock' ? 'response:mocked' : 'response:bypass',\n {\n requestId,\n request,\n response,\n },\n ),\n )\n } finally {\n /**\n * @note Remove any listeners from this frame.\n * Past this point, it won't emit anything. The removal is crucial\n * to prevent \"rettime\" from keeping the abort cleanup listeners internally.\n * @see https://github.com/mswjs/msw/issues/2735\n */\n httpFrame.events.removeAllListeners()\n }\n })\n }\n\n async #handleWebSocketConnection(\n connection: WebSocketEventMap['connection'],\n ): Promise<void> {\n await this.queue(\n new InterceptorWebSocketNetworkFrame({\n connection,\n }),\n )\n }\n}\n\nclass InterceptorHttpNetworkFrame extends HttpNetworkFrame {\n #controller: RequestController\n\n constructor(options: {\n id: string\n request: Request\n controller: RequestController\n }) {\n super({\n id: options.id,\n request: options.request,\n })\n\n this.#controller = options.controller\n }\n\n public passthrough(): void {\n deleteRequestPassthroughHeader(this.data.request)\n }\n\n public respondWith(response?: Response): void {\n if (response) {\n this.#controller.respondWith(response)\n }\n }\n\n public errorWith(reason?: unknown): void {\n if (reason instanceof Response) {\n return this.respondWith(reason)\n }\n\n if (reason instanceof InternalError) {\n this.#controller.errorWith(reason)\n }\n\n throw reason\n }\n}\n\nclass InterceptorWebSocketNetworkFrame extends WebSocketNetworkFrame {\n /**\n * The in-process client connection, whose socket\n * the frame dispatches errors on.\n */\n readonly #client: WebSocketClientConnection\n\n constructor(args: { connection: WebSocketInterceptedConnection }) {\n super({ connection: args.connection })\n\n this.#client = args.connection.client\n\n /**\n * @note Provide a similar frame listener cleanup as for HTTP.\n * When the client connection closes, the handler can no longer be used.\n */\n args.connection.client.addEventListener(\n 'close',\n () => {\n this.events.removeAllListeners()\n },\n {\n once: true,\n },\n )\n }\n\n public errorWith(reason?: unknown): void {\n if (reason instanceof Error) {\n /**\n * Use `client.errorWith(reason)` in the future.\n * @see https://github.com/mswjs/interceptors/issues/747\n */\n const errorEvent = new Event('error')\n\n Object.defineProperty(errorEvent, 'cause', {\n enumerable: true,\n configurable: false,\n value: reason,\n })\n\n this.#client.socket.dispatchEvent(errorEvent)\n }\n }\n\n public passthrough() {\n this.data.connection.server.connect()\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"interceptor-source.js","names":[],"sources":["../../src/core/experimental/sources/network-source.ts","../../src/core/experimental/handlers-controller.ts","../../src/core/utils/internal/to-readonly-array.ts","../../src/core/utils/internal/disposable.ts","../../src/core/experimental/define-network.ts","../../src/core/experimental/frames/network-frame.ts","../../src/core/utils/request/store-response-cookies.ts","../../src/core/experimental/request-utils.ts","../../src/core/experimental/on-unhandled-frame.ts","../../src/core/experimental/frames/http-frame.ts","../../src/core/experimental/frames/websocket-frame.ts","../../src/core/experimental/sources/interceptor-source.ts"],"sourcesContent":["import { Emitter, TypedEvent, type TypedListenerOptions } from 'rettime'\nimport type {\n AnyNetworkFrame,\n ExtractFrameEvents,\n NetworkFrameResolutionContext,\n} from '../frames/network-frame'\n\nclass NetworkFrameEvent<\n DataType = void,\n ReturnType = void,\n EventType extends string = string,\n> extends TypedEvent<DataType, ReturnType, EventType> {\n public frame: AnyNetworkFrame\n\n constructor(type: string, frame: AnyNetworkFrame) {\n super(...([type, {}] as any))\n this.frame = frame\n }\n}\n\ntype NetworkSourceEventMap<Frame extends AnyNetworkFrame> = {\n frame: NetworkFrameEvent<Frame>\n}\n\nexport type ExtractSourceEvents<Source> =\n Source extends NetworkSource<infer Frame> ? ExtractFrameEvents<Frame> : never\n\nexport abstract class NetworkSource<\n Frame extends AnyNetworkFrame = AnyNetworkFrame,\n> {\n protected emitter: Emitter<NetworkSourceEventMap<Frame>>\n\n constructor() {\n this.emitter = new Emitter()\n }\n\n /**\n * Enable this network source.\n * @param context The resolved context of the network this source belongs to.\n */\n public abstract enable(\n context?: NetworkFrameResolutionContext,\n ): unknown | Promise<unknown>\n\n public async queue(frame: Frame): Promise<void> {\n await this.emitter.emitAsPromise(\n // @ts-expect-error Trouble handling a conditional type parameter.\n new NetworkFrameEvent('frame', frame),\n )\n }\n\n public on<Type extends keyof NetworkSourceEventMap<Frame>>(\n type: Type,\n listener: Emitter.Listener<typeof this.emitter, Type>,\n options?: TypedListenerOptions,\n ): void {\n this.emitter.on(type, listener, options)\n }\n\n public disable(): void | Promise<void> {\n this.emitter.removeAllListeners()\n }\n}\n","import { invariant } from 'outvariant'\nimport type { HandlerKind } from '../handlers/handler'\nimport type { RequestHandler } from '../handlers/request-handler'\nimport type {\n WebSocketHandler,\n AnyWebSocketExtension,\n} from '#ws/websocket-handler'\nimport { devUtils } from '../utils/internal/dev-utils'\nimport type { MaybePromise } from '../type-utils'\nimport {\n getSiblingHandlers,\n isSiblingHandler,\n} from '../utils/internal/attach-sibling-handlers'\n\nexport type AnyHandler =\n RequestHandler | WebSocketHandler<AnyWebSocketExtension>\ntype HandlerOfKind<Kind extends HandlerKind> = Extract<\n AnyHandler,\n { kind: Kind }\n>\ntype HandlersMapOfKind<Kind extends HandlerKind> = {\n [K in Kind]?: Array<HandlerOfKind<K>>\n}\nexport type HandlersMap = HandlersMapOfKind<HandlerKind>\n\nfunction addHandlerToGroup<Kind extends HandlerKind>(\n groups: HandlersMapOfKind<Kind>,\n kind: Kind,\n handler: HandlerOfKind<Kind>,\n): void {\n const bucket = (groups[kind] ||= [])\n bucket.push(handler)\n}\n\nfunction prependHandlersToGroup<Kind extends HandlerKind>(\n groups: HandlersMapOfKind<Kind>,\n kind: Kind,\n overridesForKind: Array<HandlerOfKind<Kind>>,\n): void {\n const existingForKind = groups[kind]\n\n groups[kind] = existingForKind\n ? [\n ...overridesForKind,\n ...existingForKind.filter((existingHandler) => {\n return !overridesForKind.includes(existingHandler)\n }),\n ]\n : overridesForKind\n}\n\nexport function groupHandlersByKind(handlers: Array<AnyHandler>): HandlersMap {\n const groups: HandlersMap = {}\n const visitedHandlers = new Set<AnyHandler>()\n\n const visit = (handler: AnyHandler) => {\n if (visitedHandlers.has(handler)) {\n return\n }\n\n visitedHandlers.add(handler)\n addHandlerToGroup(groups, handler.kind, handler)\n\n // Recurse so siblings of siblings (user-composed handler\n // graphs) are grouped as well, not silently dropped.\n for (const sibling of getSiblingHandlers(handler)) {\n visit(sibling)\n }\n }\n\n for (const handler of handlers) {\n visit(handler)\n }\n\n return groups\n}\n\nexport interface HandlersControllerState {\n initialHandlers: HandlersMap\n handlers: HandlersMap\n}\n\nexport abstract class HandlersController {\n protected getInitialState(\n initialHandlers: Array<AnyHandler>,\n ): HandlersControllerState {\n invariant(\n this.#validateHandlers(initialHandlers),\n devUtils.formatMessage(\n 'Failed to apply given request handlers: invalid input. Did you forget to spread the request handlers Array?',\n ),\n )\n\n const normalizedInitialHandlers = groupHandlersByKind(initialHandlers)\n\n return {\n initialHandlers: normalizedInitialHandlers,\n handlers: { ...normalizedInitialHandlers },\n }\n }\n\n protected abstract getState(): HandlersControllerState\n protected abstract setState(nextState: Partial<HandlersControllerState>): void\n\n public currentHandlers(): Array<AnyHandler> {\n return Object.values(this.getState().handlers)\n .flat()\n .filter((handler) => handler != null)\n }\n\n /**\n * Return the list of explicitly registered handlers.\n * Unlike `currentHandlers()`, this excludes sibling handlers,\n * which are an implementation detail (e.g. the WebSocket upgrade\n * handler or the GraphQL subscription transport).\n */\n public listHandlers(): Array<AnyHandler> {\n return this.currentHandlers().filter((handler) => {\n return !isSiblingHandler(handler)\n })\n }\n\n /**\n * Return the list of handlers of the given kind.\n */\n public getHandlersByKind<Kind extends HandlerKind>(\n kind: Kind,\n ): Array<HandlerOfKind<Kind>> {\n return this.getState().handlers[kind] || []\n }\n\n public use(nextHandlers: Array<AnyHandler>): void {\n invariant(\n this.#validateHandlers(nextHandlers),\n devUtils.formatMessage(\n '[MSW] Failed to call \"use()\" with the given request handlers: invalid input. Did you forget to spread the array of request handlers?',\n ),\n )\n\n if (nextHandlers.length === 0) {\n return\n }\n\n const { handlers } = this.getState()\n const overrides = groupHandlersByKind(nextHandlers)\n\n // Prepend overrides to their respective kind buckets so they take\n // priority over existing handlers while preserving input order.\n // Drop existing references that reappear in the overrides (e.g. a\n // shared upgrade sibling from the same link) so a handler is never\n // registered twice.\n if (overrides.request) {\n prependHandlersToGroup(handlers, 'request', overrides.request)\n }\n\n if (overrides.websocket) {\n prependHandlersToGroup(handlers, 'websocket', overrides.websocket)\n }\n\n this.setState({ handlers })\n }\n\n public reset(nextHandlers: Array<AnyHandler>): void {\n invariant(\n nextHandlers.length > 0 ? this.#validateHandlers(nextHandlers) : true,\n devUtils.formatMessage(\n 'Failed to replace initial handlers during reset: invalid handlers. Did you forget to spread the handlers array?',\n ),\n )\n\n const { initialHandlers } = this.getState()\n const nextInitialHandlers =\n nextHandlers.length > 0\n ? groupHandlersByKind(nextHandlers)\n : initialHandlers\n const currentHandlers = new Set(this.currentHandlers())\n const nextHandlersSet = new Set(\n Object.values(nextInitialHandlers).flat().filter(Boolean),\n )\n\n for (const handler of currentHandlers.intersection(nextHandlersSet)) {\n handler.reset()\n }\n\n // The handlers that leave the network with this reset release\n // whatever they hold (e.g. live connection bindings).\n // Resetting is synchronous, so their disposal is not awaited.\n for (const handler of currentHandlers.difference(nextHandlersSet)) {\n try {\n const disposal = handler.dispose()\n\n if (disposal instanceof Promise) {\n disposal.catch((error) => {\n this.#printDisposalError(handler, error)\n })\n }\n } catch (error) {\n // A failing disposal must not prevent the remaining handlers\n // from being disposed of, nor the removed handlers from being cleared.\n this.#printDisposalError(handler, error)\n }\n }\n\n if (nextHandlers.length === 0) {\n this.setState({\n handlers: { ...initialHandlers },\n })\n\n return\n }\n\n this.setState({\n initialHandlers: nextInitialHandlers,\n handlers: { ...nextInitialHandlers },\n })\n }\n\n public restore(): void {\n for (const handler of this.currentHandlers()) {\n handler.restore()\n }\n }\n\n public dispose(): MaybePromise<void> {\n const pendingDisposals: Array<Promise<void>> = []\n\n for (const handler of this.currentHandlers()) {\n const disposal = handler.dispose()\n\n if (disposal instanceof Promise) {\n pendingDisposals.push(disposal)\n }\n }\n\n // Stay synchronous unless a handler actually disposes of\n // itself asynchronously.\n if (pendingDisposals.length > 0) {\n return Promise.all(pendingDisposals).then(() => {})\n }\n }\n\n #validateHandlers(handlers: Array<AnyHandler>): boolean {\n return handlers.every((handler) => !Array.isArray(handler))\n }\n\n #printDisposalError(handler: AnyHandler, error: unknown): void {\n devUtils.error(\n 'Failed to dispose of \"%s\" handler removed during reset. Please see the original error below.\\n%s',\n handler.kind,\n error,\n )\n }\n}\n\nexport class InMemoryHandlersController extends HandlersController {\n #handlers: HandlersMap\n #initialHandlers: HandlersMap\n\n constructor(initialHandlers: Array<AnyHandler>) {\n super()\n\n const initialState = this.getInitialState(initialHandlers)\n\n this.#initialHandlers = initialState.initialHandlers\n this.#handlers = initialState.handlers\n }\n\n protected getState(): HandlersControllerState {\n return {\n initialHandlers: this.#initialHandlers,\n handlers: this.#handlers,\n }\n }\n\n protected setState(nextState: Partial<HandlersControllerState>): void {\n if (nextState.initialHandlers) {\n this.#initialHandlers = nextState.initialHandlers\n }\n\n if (nextState.handlers) {\n this.#handlers = nextState.handlers\n }\n }\n}\n","/**\n * Creates an immutable copy of the given array.\n */\nexport function toReadonlyArray<T>(source: Array<T>): ReadonlyArray<T> {\n const clone = [...source] as Array<T>\n Object.freeze(clone)\n return clone\n}\n","import { devUtils } from './dev-utils'\n\nexport type DisposableSubscription = () => void\n\nexport class Disposable {\n protected subscriptions: Array<DisposableSubscription> = []\n\n public dispose() {\n let subscription: DisposableSubscription | undefined\n const errors: Array<Error> = []\n\n while ((subscription = this.subscriptions.shift())) {\n try {\n subscription()\n } catch (error) {\n if (error instanceof Error) {\n errors.push(error)\n }\n }\n }\n\n if (errors.length > 0) {\n console.error(\n new AggregateError(\n errors,\n devUtils.formatMessage(\n 'Failed to dispose of some side effects. This is likely an issue with MSW, please report it on GitHub: https://github.com/mswjs/msw/issues',\n ),\n ),\n )\n }\n }\n}\n","import { invariant } from 'outvariant'\nimport { Emitter, type DefaultEventMap } from 'rettime'\nimport {\n NetworkSource,\n type ExtractSourceEvents,\n} from './sources/network-source'\nimport type { NetworkFrameResolutionContext } from './frames/network-frame'\nimport type { UnhandledFrameHandle } from './on-unhandled-frame'\nimport {\n HandlersController,\n InMemoryHandlersController,\n type AnyHandler,\n} from './handlers-controller'\nimport { toReadonlyArray } from '../utils/internal/to-readonly-array'\nimport { Disposable } from '../utils/internal/disposable'\nimport type { UnionToIntersection } from '../type-utils'\n\ntype MergeEventMaps<Sources extends Array<NetworkSource<any>>> =\n UnionToIntersection<ExtractSourceEvents<Sources[number]>> extends infer R\n ? R extends Record<string, any>\n ? R\n : DefaultEventMap\n : DefaultEventMap\n\ntype MaybePromise<T> =\n Extract<T, Promise<unknown>> extends never ? void : Promise<void>\n\nexport interface DefineNetworkOptions<\n Sources extends Array<NetworkSource<any>>,\n> {\n /**\n * List of the network sources.\n * Every network source emits frames, and every frame describes how\n * to handle the various network scenarios, like mocking a response,\n * erroring the request, or performing it as-is.\n */\n sources: Sources\n /**\n * List of handlers to describe the network.\n */\n handlers?: Array<AnyHandler> | HandlersController\n context?: NetworkFrameResolutionContext\n onUnhandledFrame?: UnhandledFrameHandle\n}\n\nexport interface NetworkApi<\n Sources extends Array<NetworkSource<any>>,\n> extends NetworkHandlersApi {\n readyState: NetworkReadyState\n /**\n * Enable the network interception and handling.\n */\n enable: () => MaybePromise<ReturnType<Sources[number]['enable']>>\n /**\n * Disable the network interception and handling.\n */\n disable: () => MaybePromise<ReturnType<Sources[number]['disable']>>\n /**\n * Configure the network instance with additional options.\n * The options provided in the `.configure()` call will override the same\n * options in the `defineNetwork()` call.\n */\n configure: (options: Partial<DefineNetworkOptions<Sources>>) => void\n events: Emitter<MergeEventMaps<Sources>>\n}\n\ninterface NetworkHandlersApi {\n use: (...handlers: Array<AnyHandler>) => void\n resetHandlers: (...handlers: Array<AnyHandler>) => void\n restoreHandlers: () => void\n listHandlers: () => ReadonlyArray<AnyHandler>\n}\n\nfunction colorlessPromiseAll<T>(values: Array<T>): MaybePromise<T>\nfunction colorlessPromiseAll(values: Array<unknown>): Promise<void> | void {\n const promises: Array<Promise<void>> = []\n\n for (const value of values) {\n if (value instanceof Promise) {\n promises.push(value)\n }\n }\n\n if (promises.length > 0) {\n return Promise.all(promises).then(() => {})\n }\n}\n\nexport enum NetworkReadyState {\n DISABLED,\n ENABLED,\n}\n\n/**\n * Define a network instance with the given configuration.\n * @example\n * import { InterceptorSource } from 'msw/experimental'\n * import { handlers } from './handlers'\n *\n * const network = defineNetwork({\n * sources: [new InterceptorSource({ interceptors })],\n * handlers,\n * })\n * await network.enable()\n */\nexport function defineNetwork<Sources extends Array<NetworkSource<any>>>(\n options: DefineNetworkOptions<Sources>,\n): NetworkApi<Sources> {\n let readyState: NetworkReadyState = NetworkReadyState.DISABLED\n const events = new Emitter<MergeEventMaps<Sources>>()\n const disposable = new Disposable()\n\n const deriveHandlersController = (\n handlers: DefineNetworkOptions<Sources>['handlers'],\n ) => {\n return handlers instanceof HandlersController\n ? handlers\n : new InMemoryHandlersController(handlers || [])\n }\n\n let resolvedOptions: DefineNetworkOptions<Sources> = {\n ...options,\n }\n\n /**\n * @note Create the handlers controller immediately because\n * certain setup APIs, like `setupServer`, don't await `.enable` (`.listen`).\n */\n let handlersController = deriveHandlersController(resolvedOptions.handlers)\n\n return {\n get readyState() {\n return readyState\n },\n events,\n configure(options) {\n invariant(\n readyState === NetworkReadyState.DISABLED,\n 'Failed to call \"configure()\" on the network: cannot configure an already enabled network.',\n )\n\n if (\n options.handlers &&\n !Object.is(options.handlers, resolvedOptions.handlers)\n ) {\n handlersController = deriveHandlersController(options.handlers)\n }\n\n resolvedOptions = {\n ...resolvedOptions,\n ...options,\n }\n },\n enable() {\n invariant(\n readyState === NetworkReadyState.DISABLED,\n 'Failed to call \"enable\" on the network: already enabled',\n )\n\n readyState = NetworkReadyState.ENABLED\n\n /**\n * @note Use a session object scoped to the current \"enable()\"\n * to prevent \"frame.events\" listeners from surviving across enable/disable cycles.\n * @see The note about `AbortController` below.\n */\n const session = { active: true }\n disposable['subscriptions'].push(() => {\n session.active = false\n })\n\n const result = resolvedOptions.sources.map((source) => {\n /**\n * @note Preemptively disable the network source before enabling.\n * This intentionally calls only the prototype method that clears the\n * event listeners and nothing else. This prevents the \"frame\" listeners\n * from accumulating across enable/disable in case the source is a singleton.\n */\n NetworkSource.prototype.disable.call(source)\n\n source.on('frame', async ({ frame }) => {\n frame.events.on('*', (event) => {\n /**\n * @note Prevent event forwarding manually and not via an AbortController\n * because certain runtimes, like Cloudflare, throw when referencing an\n * AbortController created in a different context. Bear in mind that the frame\n * events run in the patched request client context while the AbortController\n * is created outside, in the \"defineNetwork\" closure, which is a test context.\n */\n if (!session.active) {\n return\n }\n\n events.emit(event)\n })\n\n const handlers = frame.getHandlers(handlersController)\n\n await frame.resolve(\n handlers,\n resolvedOptions.onUnhandledFrame || 'warn',\n resolvedOptions.context,\n )\n })\n\n return source.enable(resolvedOptions.context)\n })\n\n return colorlessPromiseAll(result) as MaybePromise<\n ReturnType<Sources[number]['enable']>\n >\n },\n disable() {\n invariant(\n readyState === NetworkReadyState.ENABLED,\n 'Failed to call \"disable\" on the network: already disabled',\n )\n\n readyState = NetworkReadyState.DISABLED\n\n // Let the handlers release the resources they hold before\n // tearing down the network itself. Handlers may still need the\n // network while disposing of themselves (e.g. to close the\n // connections they own).\n const handlersDisposal = handlersController.dispose()\n disposable.dispose()\n\n /**\n * @note Tear down the sources synchronously, never behind the\n * handlers disposal. `disable()` is not always awaited (e.g.\n * `server.close()` is synchronous), and a deferred teardown would\n * race any `enable()` that follows, disabling the sources that the\n * new session has just enabled.\n */\n const sourcesDisposal = colorlessPromiseAll(\n resolvedOptions.sources.map((source) => source.disable()),\n )\n\n /**\n * @note Await both disposals so neither rejection goes unobserved.\n * Chaining them would leave the source disposal floating whenever\n * the handlers disposal rejects.\n */\n return (\n handlersDisposal instanceof Promise\n ? Promise.all([handlersDisposal, sourcesDisposal]).then(() => {})\n : sourcesDisposal\n ) as MaybePromise<ReturnType<Sources[number]['disable']>>\n },\n use(...handlers) {\n handlersController.use(handlers)\n },\n resetHandlers(...handlers) {\n handlersController.reset(handlers)\n },\n restoreHandlers() {\n handlersController.restore()\n },\n listHandlers() {\n return toReadonlyArray(handlersController.listHandlers())\n },\n }\n}\n","import { Emitter, type DefaultEventMap } from 'rettime'\nimport type { AnyHandler, HandlersController } from '../handlers-controller'\nimport type { UnhandledFrameHandle } from '../on-unhandled-frame'\n\nexport type AnyNetworkFrame = NetworkFrame<string, unknown, any>\n\nexport type ExtractFrameEvents<Frame> =\n Frame extends NetworkFrame<any, any, infer Events> ? Events : never\n\nexport interface NetworkFrameResolutionContext {\n baseUrl?: string | URL\n quiet?: boolean\n}\n\n/**\n * The base for the network frames. Extend this abstract class\n * to implement custom network frames.\n */\nexport abstract class NetworkFrame<\n Protocol extends string,\n Data,\n Events extends DefaultEventMap,\n> {\n public events: Emitter<Events>\n\n constructor(\n public readonly protocol: Protocol,\n public readonly data: Data,\n ) {\n this.events = new Emitter()\n }\n\n public abstract getHandlers(controller: HandlersController): Array<AnyHandler>\n\n /**\n * Resolve the current frame against the given list of handlers.\n * Optionally, use a custom resolution context to control behaviors\n * like `baseUrl`.\n *\n * Returns `true` if the frame was handled, `false` if it wasn't, and `null`\n * if its handling was skipped (e.g. the frame was bypassed).\n */\n public abstract resolve(\n handlers: Array<AnyHandler>,\n onUnhandledFrame: UnhandledFrameHandle,\n resolutionContext?: NetworkFrameResolutionContext,\n ): Promise<boolean | null>\n\n /**\n * Perform this network frame as-is.\n */\n public abstract passthrough(): void\n\n /**\n * Error the underling network frame.\n * @param reason The reason for the error.\n */\n public abstract errorWith(reason?: unknown): void\n\n /**\n * Get a message to be used when this frame is unhandled.\n */\n public abstract getUnhandledMessage(): Promise<string>\n}\n","import { cookieStore } from '../cookie-store'\nimport { getRawSetCookie } from '../response-decorators'\n\nexport async function storeResponseCookies(\n request: Request,\n response: Response,\n): Promise<void> {\n if (cookieStore === null) {\n return\n }\n\n for (const responseCookie of getRawSetCookie(response)) {\n await cookieStore.setCookie(responseCookie, request.url)\n }\n}\n","export function shouldBypassRequest(request: Request): boolean {\n return !!request.headers.get('accept')?.includes('msw/passthrough')\n}\n\n/**\n * Remove the internal passthrough instruction from the request's `Accept` header.\n */\nexport function deleteRequestPassthroughHeader(request: Request): void {\n const acceptHeader = request.headers.get('accept')\n\n /**\n * @note Remove the internal bypass request header.\n * In the browser, this is done by the worker script.\n * In Node.js, it has to be done here.\n */\n if (acceptHeader) {\n const nextAcceptHeader = acceptHeader.replace(/(,\\s+)?msw\\/passthrough/, '')\n\n if (nextAcceptHeader) {\n request.headers.set('accept', nextAcceptHeader)\n } else {\n request.headers.delete('accept')\n }\n }\n}\n","import { invariant } from 'outvariant'\nimport { isCommonAssetRequest } from '#utils/is-common-asset-request'\nimport { devUtils, InternalError } from '../utils/internal/dev-utils'\nimport { HttpNetworkFrame } from './frames/http-frame'\nimport type { AnyNetworkFrame } from './frames/network-frame'\n\nexport type UnhandledFrameHandle =\n UnhandledFrameStrategy | UnhandledFrameCallback\n\nexport type UnhandledFrameStrategy = 'bypass' | 'warn' | 'error'\n\nexport type UnhandledFrameCallback = (args: {\n frame: AnyNetworkFrame\n defaults: UnhandledFrameDefaults\n}) => Promise<void> | void\n\ntype UnhandledFrameDefaults = {\n warn: () => void\n error: () => void\n}\n\nexport async function executeUnhandledFrameHandle(\n frame: AnyNetworkFrame,\n handle: UnhandledFrameHandle,\n): Promise<void> {\n const printStrategyMessage = async (\n strategy: UnhandledFrameStrategy,\n ): Promise<void> => {\n if (strategy === 'bypass') {\n return\n }\n\n const message = await frame.getUnhandledMessage()\n\n switch (strategy) {\n case 'warn': {\n return devUtils.warn('Warning: %s', message)\n }\n\n case 'error': {\n return devUtils.error('Error: %s', message)\n }\n }\n }\n\n const applyStrategy = async (\n strategy: UnhandledFrameStrategy,\n ): Promise<void> => {\n invariant.as(\n InternalError,\n strategy === 'bypass' || strategy === 'warn' || strategy === 'error',\n devUtils.formatMessage(\n 'Failed to react to an unhandled network frame: unknown strategy \"%s\". Please provide one of the supported strategies (\"bypass\", \"warn\", \"error\") or a custom callback function as the value of the \"onUnhandledFrame\" option.',\n strategy,\n ),\n )\n\n if (strategy === 'bypass') {\n return\n }\n\n await printStrategyMessage(strategy)\n\n if (strategy === 'error') {\n return Promise.reject(\n new InternalError(\n devUtils.formatMessage(\n 'Cannot bypass a request when using the \"error\" strategy for the \"onUnhandledFrame\" option.',\n ),\n ),\n )\n }\n }\n\n if (typeof handle === 'function') {\n return handle({\n frame,\n defaults: {\n warn: printStrategyMessage.bind(null, 'warn'),\n /**\n * @note The defaults only print the corresponding messages now.\n * They do not affect the frame resolution (e.g. do not error the frame).\n * That is only for backward compatibility reasons. In the future, these should\n * be an alias to `applyStrategy.bind(null, 'error')` instead.\n */\n error: printStrategyMessage.bind(null, 'error'),\n },\n })\n }\n\n /**\n * Ignore unhandled common HTTP assets.\n * @note Calling this here applies the common assets check\n * only to the scenarios when `onUnhandledFrame` was set to a predefined strategy.\n * When using a custom function, you need to check for common assets manually.\n */\n if (\n frame instanceof HttpNetworkFrame &&\n isCommonAssetRequest(frame.data.request)\n ) {\n return\n }\n\n return applyStrategy(handle)\n}\n","import { TypedEvent } from 'rettime'\nimport { until } from 'until-async'\nimport { createRequestId } from '@mswjs/interceptors'\nimport {\n NetworkFrame,\n type NetworkFrameResolutionContext,\n} from './network-frame'\nimport { toPublicUrl } from '../../utils/request/to-public-url'\nimport { isStringEqual } from '../../utils/internal/is-string-equal'\nimport { executeHandlers } from '../../utils/execute-handlers'\nimport { storeResponseCookies } from '../../utils/request/store-response-cookies'\nimport { shouldBypassRequest } from '../request-utils'\nimport { isPassthroughResponse } from '#utils/passthrough'\nimport { devUtils } from '../../utils/internal/dev-utils'\nimport {\n executeUnhandledFrameHandle,\n type UnhandledFrameHandle,\n} from '../on-unhandled-frame'\nimport type { HandlersController } from '../handlers-controller'\nimport type { AnyHandler } from '../handlers-controller'\nimport type { RequestHandler } from '../../handlers/request-handler'\n\ninterface HttpNetworkFrameOptions {\n id?: string\n request: Request\n}\n\nclass RequestEvent<\n DataType extends { requestId: string; request: Request } = {\n requestId: string\n request: Request\n },\n ReturnType = void,\n EventType extends string = string,\n> extends TypedEvent<DataType, ReturnType, EventType> {\n public readonly requestId: string\n public readonly request: Request\n\n constructor(type: EventType, data: DataType) {\n super(...([type, {}] as any))\n this.requestId = data.requestId\n this.request = data.request\n }\n}\n\nexport class ResponseEvent<\n DataType extends {\n requestId: string\n request: Request\n response: Response\n } = {\n requestId: string\n request: Request\n response: Response\n },\n ReturnType = void,\n EventType extends string = string,\n> extends TypedEvent<DataType, ReturnType, EventType> {\n public readonly requestId: string\n public readonly request: Request\n public readonly response: Response\n\n constructor(type: EventType, data: DataType) {\n super(...([type, {}] as any))\n this.requestId = data.requestId\n this.request = data.request\n this.response = data.response\n }\n}\n\nclass UnhandledExceptionEvent<\n DataType extends {\n error: Error\n requestId: string\n request: Request\n } = {\n error: Error\n requestId: string\n request: Request\n },\n ReturnType = void,\n EventType extends string = string,\n> extends TypedEvent<DataType, ReturnType, EventType> {\n public readonly error: Error\n public readonly requestId: string\n public readonly request: Request\n\n constructor(type: EventType, data: DataType) {\n super(...([type, {}] as any))\n this.error = data.error\n this.requestId = data.requestId\n this.request = data.request\n }\n}\n\nexport type HttpNetworkFrameEventMap = {\n 'request:start': RequestEvent\n 'request:match': RequestEvent\n 'request:unhandled': RequestEvent\n 'request:end': RequestEvent\n 'response:mocked': ResponseEvent\n 'response:bypass': ResponseEvent\n unhandledException: UnhandledExceptionEvent\n}\n\nexport abstract class HttpNetworkFrame extends NetworkFrame<\n 'http',\n {\n id: string\n request: Request\n },\n HttpNetworkFrameEventMap\n> {\n constructor(options: HttpNetworkFrameOptions) {\n const id = options.id || createRequestId()\n super('http', { id, request: options.request })\n }\n\n public getHandlers(controller: HandlersController): Array<AnyHandler> {\n return controller.getHandlersByKind('request')\n }\n\n public abstract respondWith(response?: Response): void\n\n public async getUnhandledMessage(): Promise<string> {\n const { request } = this.data\n\n const url = new URL(request.url)\n const publicUrl = toPublicUrl(url) + url.search\n const requestBody =\n request.body == null ? null : await request.clone().text()\n\n const details = `\\n\\n \\u2022 ${request.method} ${publicUrl}\\n\\n${requestBody ? ` \\u2022 Request body: ${requestBody}\\n\\n` : ''}`\n const message = `intercepted a request without a matching request handler:${details}If you still wish to intercept this unhandled request, please create a request handler for it.\\nRead more: https://mswjs.io/docs/http/intercepting-requests`\n\n return message\n }\n\n public async resolve(\n handlers: Array<RequestHandler>,\n onUnhandledFrame: UnhandledFrameHandle,\n resolutionContext?: NetworkFrameResolutionContext,\n ): Promise<boolean | null> {\n const { id: requestId, request } = this.data\n const requestCloneForLogs = resolutionContext?.quiet\n ? null\n : request.clone()\n\n this.events.emit(new RequestEvent('request:start', { requestId, request }))\n\n // Requests wrapped in explicit \"bypass(request)\".\n if (shouldBypassRequest(request)) {\n this.events.emit(new RequestEvent('request:end', { requestId, request }))\n this.passthrough()\n return null\n }\n\n const [lookupError, lookupResult] = await until(() => {\n return executeHandlers({\n requestId,\n request,\n handlers,\n resolutionContext: {\n baseUrl: resolutionContext?.baseUrl?.toString(),\n quiet: resolutionContext?.quiet,\n },\n })\n })\n\n if (lookupError != null) {\n if (\n !this.events.emit(\n new UnhandledExceptionEvent('unhandledException', {\n error: lookupError,\n requestId,\n request,\n }),\n )\n ) {\n // Surface the error to the developer since they haven't handled it.\n console.error(lookupError)\n devUtils.error(\n 'Encountered an unhandled exception during the handler lookup for \"%s %s\". Please see the original error above.',\n request.method,\n request.url,\n )\n }\n\n this.errorWith(lookupError)\n return null\n }\n\n // No matching handlers.\n if (lookupResult == null) {\n /**\n * @note Unhandled CONNECT requests establish a tunnel through a proxy.\n * They are transport, not the request the developer cares about, so\n * they pass through silently regardless of the unhandled frame strategy.\n * The request sent through the tunnel gets its own resolution.\n */\n if (isStringEqual(request.method, 'CONNECT')) {\n this.events.emit(\n new RequestEvent('request:end', {\n requestId,\n request,\n }),\n )\n\n this.passthrough()\n return null\n }\n\n this.events.emit(\n new RequestEvent('request:unhandled', {\n requestId,\n request,\n }),\n )\n\n /**\n * @note The unhandled frame handle must be executed during the request resolution\n * since it can influence it (e.g. error the request if the \"error\" startegy was used).\n */\n await executeUnhandledFrameHandle(this, onUnhandledFrame).then(\n () => this.passthrough(),\n (error) => this.errorWith(error),\n )\n\n this.events.emit(\n new RequestEvent('request:end', {\n requestId,\n request,\n }),\n )\n\n return false\n }\n\n const { response, handler, parsedResult } = lookupResult\n\n this.events.emit(\n new RequestEvent('request:match', {\n requestId,\n request,\n }),\n )\n\n // Handlers that returned no mocked response.\n if (response == null) {\n this.events.emit(\n new RequestEvent('request:end', {\n requestId,\n request,\n }),\n )\n\n this.passthrough()\n return null\n }\n\n // Handlers that returned explicit `passthrough()`.\n if (isPassthroughResponse(response)) {\n this.events.emit(\n new RequestEvent('request:end', {\n requestId,\n request,\n }),\n )\n\n this.passthrough()\n return null\n }\n\n const responseCloneForLogs = resolutionContext?.quiet\n ? null\n : response.clone()\n\n await storeResponseCookies(request, response)\n\n this.respondWith(response)\n\n this.events.emit(\n new RequestEvent('request:end', {\n requestId,\n request,\n }),\n )\n\n if (!resolutionContext?.quiet) {\n handler.log({\n request: requestCloneForLogs!,\n response: responseCloneForLogs!,\n parsedResult,\n })\n }\n\n return true\n }\n}\n","import { TypedEvent } from 'rettime'\nimport type { GraphQLSubscriptionEvent } from '#graphql/graphql-subscription-event'\nimport type { WebSocketConnectionEventData } from '@mswjs/interceptors/WebSocket'\nimport {\n kConnect,\n kAutoConnect,\n type WebSocketHandler,\n type AnyWebSocketExtension,\n} from '#ws/websocket-handler'\nimport {\n NetworkFrame,\n type NetworkFrameResolutionContext,\n} from './network-frame'\nimport {\n executeUnhandledFrameHandle,\n type UnhandledFrameHandle,\n} from '../on-unhandled-frame'\nimport { devUtils } from '../../utils/internal/dev-utils'\nimport type { HandlersController } from '../handlers-controller'\nimport type { AnyHandler } from '../handlers-controller'\n\nexport interface WebSocketNetworkFrameOptions {\n connection: WebSocketConnectionEventData\n}\n\nexport type WebSocketNetworkFrameEventMap = {\n /**\n * Emitted when a WebSocket connection is intercepted,\n * before any handlers are resolved against it.\n */\n 'websocket:connection': WebSocketConnectionEvent\n /**\n * Emitted when the WebSocket connection errors.\n * This includes initial connection errors as well as runtime errors\n * after the connection has been established.\n */\n 'websocket:error': WebSocketErrorEvent\n 'graphql:subscription': GraphQLSubscriptionEvent\n unhandledException: WebSocketErrorEvent\n}\n\nclass WebSocketConnectionEvent<\n DataType extends {\n url: URL\n protocols: string | Array<string> | undefined\n } = { url: URL; protocols: string | Array<string> | undefined },\n ReturnType = void,\n EventType extends string = string,\n> extends TypedEvent<DataType, ReturnType, EventType> {\n public readonly url: URL\n public readonly protocols: string | Array<string> | undefined\n\n constructor(type: EventType, data: DataType) {\n super(...([type, {}] as any))\n this.url = data.url\n this.protocols = data.protocols\n }\n}\n\nclass WebSocketErrorEvent<\n DataType extends {\n url: URL\n protocols: string | Array<string> | undefined\n error: unknown\n } = {\n url: URL\n protocols: string | Array<string> | undefined\n error: unknown\n },\n ReturnType = void,\n EventType extends string = string,\n> extends WebSocketConnectionEvent<DataType, ReturnType, EventType> {\n public readonly error: unknown\n\n constructor(type: EventType, data: DataType) {\n super(type, data)\n this.error = data.error\n }\n}\n\nexport abstract class WebSocketNetworkFrame extends NetworkFrame<\n 'ws',\n {\n connection: WebSocketConnectionEventData\n },\n WebSocketNetworkFrameEventMap\n> {\n constructor(options: WebSocketNetworkFrameOptions) {\n super('ws', {\n connection: options.connection,\n })\n }\n\n public getHandlers(controller: HandlersController): Array<AnyHandler> {\n return controller.getHandlersByKind('websocket')\n }\n\n public async resolve(\n handlers: Array<WebSocketHandler<AnyWebSocketExtension>>,\n onUnhandledFrame: UnhandledFrameHandle,\n resolutionContext?: NetworkFrameResolutionContext,\n ): Promise<boolean | null> {\n const { connection } = this.data\n\n this.events.emit(\n new WebSocketConnectionEvent('websocket:connection', {\n url: connection.client.url,\n protocols: connection.info.protocols,\n }),\n )\n\n const handleSocketError = (event: Event) => {\n this.events.emit(\n new WebSocketErrorEvent('websocket:error', {\n url: connection.client.url,\n protocols: connection.info.protocols,\n error: getErrorFromEvent(event),\n }),\n )\n }\n\n connection.client.socket.addEventListener('error', handleSocketError)\n connection.client.socket.addEventListener(\n 'close',\n () => {\n connection.client.socket.removeEventListener('error', handleSocketError)\n },\n { once: true },\n )\n\n // No WebSocket handlers defined.\n if (handlers.length === 0) {\n await executeUnhandledFrameHandle(this, onUnhandledFrame).then(\n () => this.passthrough(),\n (error) => this.errorWith(error),\n )\n\n return false\n }\n\n let hasMatchingHandlers = false\n\n for (const handler of handlers) {\n const handlerConnection = await handler.run(connection, {\n baseUrl: resolutionContext?.baseUrl?.toString(),\n /**\n * @note Expose an emit-only reference to this frame's events\n * so the handlers can emit additional events not covered by\n * the frame (e.g. \"graphql:subscription\").\n */\n events: this.events,\n /**\n * @note Do not emit the handler's \"connection\" event when running the handler.\n * Use the run only to get the resolved connection object.\n */\n [kAutoConnect]: false,\n })\n\n if (!handlerConnection) {\n continue\n }\n\n hasMatchingHandlers = true\n\n /**\n * @note Attach the WebSocket logger *before* emitting the handler's \"connection\" event.\n * Connection event listeners may perform actions that should be reflected in the logs\n * (e.g. closing the connection immediately). If the logger is attached after the connection,\n * those actions cannot be properly logged.\n */\n const removeLogger = !resolutionContext?.quiet\n ? handler.log(connection)\n : undefined\n\n try {\n if (!handler[kConnect](handlerConnection)) {\n removeLogger?.()\n }\n } catch (error) {\n if (\n !this.events.emit(\n new WebSocketErrorEvent('unhandledException', {\n error,\n url: connection.client.url,\n protocols: connection.info.protocols,\n }),\n )\n ) {\n console.error(error)\n devUtils.error(\n 'Encountered an unhandled exception during the handler lookup for \"%s\". Please see the original error above.',\n connection.client.url,\n )\n }\n\n /**\n * @note Throw the caught error so it gets picked up by WebSocketInterceptor.\n * It's the interceptor who translates handler errors to WebSocket closures.\n */\n throw error\n }\n }\n\n // No matching WebSocket handlers found.\n if (!hasMatchingHandlers) {\n await executeUnhandledFrameHandle(this, onUnhandledFrame).then(\n () => this.passthrough(),\n (error) => this.errorWith(error),\n )\n\n return false\n }\n\n return true\n }\n\n public async getUnhandledMessage(): Promise<string> {\n const { connection } = this.data\n const details = `\\n\\n \\u2022 ${connection.client.url}\\n\\n`\n\n return `intercepted a WebSocket connection without a matching event handler:${details}If you still wish to intercept this unhandled connection, please create an event handler for it.\\nRead more: https://mswjs.io/docs/websocket`\n }\n}\n\n/**\n * Extract the error from the given \"error\" event, if any.\n * Supports both the `ErrorEvent.error` property and the `cause`\n * property that MSW sets when erroring the connection itself.\n */\nfunction getErrorFromEvent(event: Event): unknown {\n if ('error' in event && event.error != null) {\n return event.error\n }\n\n if ('cause' in event && event.cause != null) {\n return event.cause\n }\n\n return undefined\n}\n","import type { Interceptor, RequestController } from '@mswjs/interceptors'\nimport {\n BatchInterceptor,\n type HttpRequestEventMap,\n type HttpRequestEvent,\n type HttpResponseEvent,\n} from '@mswjs/interceptors'\nimport type {\n WebSocketClientConnection,\n WebSocketInterceptedConnection,\n WebSocketEventMap,\n} from '@mswjs/interceptors/WebSocket'\nimport { NetworkSource } from './network-source'\nimport { InternalError } from '../../utils/internal/dev-utils'\nimport { HttpNetworkFrame, ResponseEvent } from '../frames/http-frame'\nimport { WebSocketNetworkFrame } from '../frames/websocket-frame'\nimport { deleteRequestPassthroughHeader } from '../request-utils'\n\nexport interface InterceptorSourceOptions {\n interceptors: Array<Interceptor<HttpRequestEventMap | WebSocketEventMap>>\n}\n\n/**\n * Create a network source from the given list of interceptors.\n */\nexport class InterceptorSource extends NetworkSource {\n #interceptor: BatchInterceptor<\n InterceptorSourceOptions['interceptors'],\n HttpRequestEventMap & WebSocketEventMap\n >\n\n /**\n * @note Frames are keyed by the request instance, not the request ID.\n * The interceptor emits the same request instance on the \"request\"\n * and \"response\" events, so the frame can be looked up by identity.\n * A weak reference lets the frame be garbage collected alongside\n * its request once the request settles without producing a response\n * (e.g. a passthrough request failing with a network error).\n * @see https://github.com/mswjs/msw/issues/2792\n */\n #frames: WeakMap<Request, HttpNetworkFrame>\n\n constructor(options: InterceptorSourceOptions) {\n super()\n\n this.#interceptor = new BatchInterceptor({\n name: 'interceptor-source',\n interceptors: options.interceptors,\n })\n this.#frames = new WeakMap()\n }\n\n public enable(): void {\n this.#interceptor.apply()\n\n this.#interceptor\n .on('request', this.#handleRequest.bind(this))\n .on('response', this.#handleResponse.bind(this))\n .on('connection', this.#handleWebSocketConnection.bind(this))\n }\n\n public disable(): void {\n super.disable()\n this.#interceptor.dispose()\n\n /**\n * @todo We can also abort any pending frames here, given we implement\n * the `NetworkFrame.abort()` method.\n */\n this.#frames = new WeakMap()\n }\n\n async #handleRequest(event: HttpRequestEvent): Promise<void> {\n const { requestId, request, controller } = event\n const httpFrame = new InterceptorHttpNetworkFrame({\n id: requestId,\n request,\n controller,\n })\n\n this.#frames.set(request, httpFrame)\n await this.queue(httpFrame)\n }\n\n async #handleResponse({\n requestId,\n request,\n response,\n responseType,\n }: HttpResponseEvent): Promise<void> {\n const httpFrame = this.#frames.get(request)\n this.#frames.delete(request)\n\n if (httpFrame == null) {\n return\n }\n\n queueMicrotask(() => {\n try {\n httpFrame.events.emit(\n new ResponseEvent(\n responseType === 'mock' ? 'response:mocked' : 'response:bypass',\n {\n requestId,\n request,\n response,\n },\n ),\n )\n } finally {\n /**\n * @note Remove any listeners from this frame.\n * Past this point, it won't emit anything. The removal is crucial\n * to prevent \"rettime\" from keeping the abort cleanup listeners internally.\n * @see https://github.com/mswjs/msw/issues/2735\n */\n httpFrame.events.removeAllListeners()\n }\n })\n }\n\n async #handleWebSocketConnection(\n connection: WebSocketEventMap['connection'],\n ): Promise<void> {\n await this.queue(\n new InterceptorWebSocketNetworkFrame({\n connection,\n }),\n )\n }\n}\n\nclass InterceptorHttpNetworkFrame extends HttpNetworkFrame {\n #controller: RequestController\n\n constructor(options: {\n id: string\n request: Request\n controller: RequestController\n }) {\n super({\n id: options.id,\n request: options.request,\n })\n\n this.#controller = options.controller\n }\n\n public passthrough(): void {\n deleteRequestPassthroughHeader(this.data.request)\n }\n\n public respondWith(response?: Response): void {\n if (response) {\n this.#controller.respondWith(response)\n }\n }\n\n public errorWith(reason?: unknown): void {\n if (reason instanceof Response) {\n return this.respondWith(reason)\n }\n\n if (reason instanceof InternalError) {\n this.#controller.errorWith(reason)\n }\n\n throw reason\n }\n}\n\nclass InterceptorWebSocketNetworkFrame extends WebSocketNetworkFrame {\n /**\n * The in-process client connection, whose socket\n * the frame dispatches errors on.\n */\n readonly #client: WebSocketClientConnection\n\n constructor(args: { connection: WebSocketInterceptedConnection }) {\n super({ connection: args.connection })\n\n this.#client = args.connection.client\n\n /**\n * @note Provide a similar frame listener cleanup as for HTTP.\n * When the client connection closes, the handler can no longer be used.\n */\n args.connection.client.addEventListener(\n 'close',\n () => {\n this.events.removeAllListeners()\n },\n {\n once: true,\n },\n )\n }\n\n public errorWith(reason?: unknown): void {\n if (reason instanceof Error) {\n /**\n * Use `client.errorWith(reason)` in the future.\n * @see https://github.com/mswjs/interceptors/issues/747\n */\n const errorEvent = new Event('error')\n\n Object.defineProperty(errorEvent, 'cause', {\n enumerable: true,\n configurable: false,\n value: reason,\n })\n\n this.#client.socket.dispatchEvent(errorEvent)\n }\n }\n\n public passthrough() {\n this.data.connection.server.connect()\n }\n}\n"],"mappings":"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"}
@@ -42,8 +42,9 @@ declare abstract class Handler {
42
42
  /**
43
43
  * Release the resources held by this handler.
44
44
  *
45
- * @note This method is invoked automatically when the network is
46
- * disabled (e.g. `server.close()`). Override it in the handlers that
45
+ * @note This method is invoked automatically when the handler leaves
46
+ * the network: when the network is disabled (e.g. `server.close()`)
47
+ * or when a reset removes it (e.g. `server.resetHandlers()`). Override it in the handlers that
47
48
  * hold onto anything beyond a single frame, like timers, connections,
48
49
  * or event listeners. Returning a promise makes the network await
49
50
  * this handler's disposal before it tears itself down.
@@ -1,4 +1,4 @@
1
- import { h as WebSocketNetworkFrameEventMap, t as AnyHandler } from "../_chunks/handlers-controller.js";
1
+ import { h as WebSocketNetworkFrameEventMap, t as AnyHandler, y as NetworkFrameResolutionContext } from "../_chunks/handlers-controller.js";
2
2
  import { n as SharedOptions, t as LifeCycleEventEmitter } from "../_chunks/shared-options.js";
3
3
  import { c as HttpNetworkFrameEventMap, i as NetworkReadyState, n as DefineNetworkOptions, o as NetworkSource, s as HttpNetworkFrame, t as InterceptorSource } from "../_chunks/interceptor-source.js";
4
4
  import { Emitter, TypedEvent } from "rettime";
@@ -184,7 +184,6 @@ declare class WorkerChannel extends Emitter<WorkerChannelEventMap> {
184
184
  //#endregion
185
185
  //#region src/browser/sources/service-worker-source.d.ts
186
186
  interface ServiceWorkerSourceOptions {
187
- quiet?: boolean;
188
187
  serviceWorker: {
189
188
  url: string;
190
189
  options?: RegistrationOptions;
@@ -201,7 +200,7 @@ declare class ServiceWorkerSource extends NetworkSource<ServiceWorkerHttpNetwork
201
200
  static from(options: ServiceWorkerSourceOptions): Promise<ServiceWorkerSource>;
202
201
  workerPromise: Promise<[ServiceWorker, ServiceWorkerRegistration]>;
203
202
  constructor(options: ServiceWorkerSourceOptions);
204
- enable(): Promise<ServiceWorkerRegistration>;
203
+ enable(context?: NetworkFrameResolutionContext): Promise<ServiceWorkerRegistration>;
205
204
  disable(): Promise<void>;
206
205
  /**
207
206
  * Terminal teardown. Unregisters the Service Worker, tears down the channel,
@@ -222,14 +221,10 @@ declare class ServiceWorkerHttpNetworkFrame extends HttpNetworkFrame {
222
221
  }
223
222
  //#endregion
224
223
  //#region src/browser/sources/fallback-http-source.d.ts
225
- interface FallbackHttpSourceOptions {
226
- quiet?: boolean;
227
- }
228
224
  declare class FallbackHttpSource extends InterceptorSource {
229
225
  #private;
230
- private readonly options;
231
- constructor(options: FallbackHttpSourceOptions);
232
- enable(): void;
226
+ constructor();
227
+ enable(context?: NetworkFrameResolutionContext): void;
233
228
  disable(): void;
234
229
  }
235
230
  //#endregion