@mswjs/interceptors 0.32.1 → 0.33.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 +35 -7
- package/lib/browser/{chunk-732REFPX.mjs → chunk-5ETVT6GU.mjs} +28 -79
- package/lib/browser/chunk-5ETVT6GU.mjs.map +1 -0
- package/lib/browser/chunk-6MBJUL74.js +142 -0
- package/lib/browser/chunk-6MBJUL74.js.map +1 -0
- package/lib/browser/chunk-7A4UJNSW.mjs +196 -0
- package/lib/browser/chunk-7A4UJNSW.mjs.map +1 -0
- package/lib/browser/{chunk-PSX5J3RF.js → chunk-7GVJEW45.js} +30 -81
- package/lib/browser/chunk-7GVJEW45.js.map +1 -0
- package/lib/browser/{chunk-2CRB3JAQ.js → chunk-FXSPMSSQ.js} +1 -1
- package/lib/browser/chunk-FXSPMSSQ.js.map +1 -0
- package/lib/browser/{chunk-OMISYKWR.mjs → chunk-GGUENBDN.mjs} +1 -1
- package/lib/browser/chunk-GGUENBDN.mjs.map +1 -0
- package/lib/browser/chunk-NU2MPFD6.mjs +142 -0
- package/lib/browser/chunk-NU2MPFD6.mjs.map +1 -0
- package/lib/browser/chunk-VRKVKT62.js +196 -0
- package/lib/browser/chunk-VRKVKT62.js.map +1 -0
- package/lib/browser/glossary-7d7adb4b.d.ts +66 -0
- package/lib/browser/index.d.ts +1 -1
- package/lib/browser/index.js +2 -2
- package/lib/browser/index.mjs +1 -1
- package/lib/browser/interceptors/XMLHttpRequest/index.d.ts +2 -6
- package/lib/browser/interceptors/XMLHttpRequest/index.js +4 -4
- package/lib/browser/interceptors/XMLHttpRequest/index.mjs +3 -3
- package/lib/browser/interceptors/fetch/index.d.ts +1 -1
- package/lib/browser/interceptors/fetch/index.js +4 -4
- package/lib/browser/interceptors/fetch/index.mjs +3 -3
- package/lib/browser/presets/browser.d.ts +1 -1
- package/lib/browser/presets/browser.js +6 -6
- package/lib/browser/presets/browser.mjs +4 -4
- package/lib/node/{BatchInterceptor-2badedde.d.ts → BatchInterceptor-13d40c95.d.ts} +1 -1
- package/lib/node/{Interceptor-88ee47c0.d.ts → Interceptor-a31b1217.d.ts} +35 -13
- package/lib/node/RemoteHttpInterceptor.d.ts +2 -2
- package/lib/node/RemoteHttpInterceptor.js +55 -52
- package/lib/node/RemoteHttpInterceptor.js.map +1 -1
- package/lib/node/RemoteHttpInterceptor.mjs +53 -50
- package/lib/node/RemoteHttpInterceptor.mjs.map +1 -1
- package/lib/node/{chunk-5JMJ55U7.js → chunk-2MWIWEWV.js} +144 -113
- package/lib/node/chunk-2MWIWEWV.js.map +1 -0
- package/lib/node/{chunk-2COJKQQB.js → chunk-42632LKH.js} +3 -3
- package/lib/node/chunk-5WWNCLB3.js +196 -0
- package/lib/node/chunk-5WWNCLB3.js.map +1 -0
- package/lib/node/{chunk-TGTPXCLF.mjs → chunk-BUCULLYM.mjs} +1 -1
- package/lib/node/{chunk-TGTPXCLF.mjs.map → chunk-BUCULLYM.mjs.map} +1 -1
- package/lib/node/{chunk-OJ6O4LSC.mjs → chunk-BZ3Y7YV5.mjs} +1 -1
- package/lib/node/chunk-BZ3Y7YV5.mjs.map +1 -0
- package/lib/node/{chunk-3OJLYEWA.mjs → chunk-CU3YXMM4.mjs} +138 -107
- package/lib/node/chunk-CU3YXMM4.mjs.map +1 -0
- package/lib/node/{chunk-PNWPIDEL.mjs → chunk-HGQLG7KE.mjs} +2 -2
- package/lib/node/{chunk-EIBTX65O.js → chunk-IDEEMJ3F.js} +1 -1
- package/lib/node/chunk-IDEEMJ3F.js.map +1 -0
- package/lib/node/chunk-KY3RJ2M3.mjs +196 -0
- package/lib/node/chunk-KY3RJ2M3.mjs.map +1 -0
- package/lib/node/{chunk-PYD4E2EJ.js → chunk-P6QG76R3.js} +34 -85
- package/lib/node/chunk-P6QG76R3.js.map +1 -0
- package/lib/node/{chunk-DV4PBH4D.mjs → chunk-TOV4TYIX.mjs} +29 -80
- package/lib/node/chunk-TOV4TYIX.mjs.map +1 -0
- package/lib/node/{chunk-BFLYGQ6D.js → chunk-YGM3BCJU.js} +1 -1
- package/lib/node/chunk-YGM3BCJU.js.map +1 -0
- package/lib/node/index.d.ts +2 -2
- package/lib/node/index.js +4 -4
- package/lib/node/index.mjs +3 -3
- package/lib/node/interceptors/ClientRequest/index.d.ts +2 -2
- package/lib/node/interceptors/ClientRequest/index.js +4 -4
- package/lib/node/interceptors/ClientRequest/index.mjs +3 -3
- package/lib/node/interceptors/XMLHttpRequest/index.d.ts +2 -6
- package/lib/node/interceptors/XMLHttpRequest/index.js +5 -5
- package/lib/node/interceptors/XMLHttpRequest/index.mjs +4 -4
- package/lib/node/interceptors/fetch/index.d.ts +1 -1
- package/lib/node/interceptors/fetch/index.js +52 -123
- package/lib/node/interceptors/fetch/index.js.map +1 -1
- package/lib/node/interceptors/fetch/index.mjs +50 -121
- package/lib/node/interceptors/fetch/index.mjs.map +1 -1
- package/lib/node/presets/node.d.ts +1 -1
- package/lib/node/presets/node.js +7 -7
- package/lib/node/presets/node.mjs +5 -5
- package/package.json +2 -2
- package/src/InterceptorError.ts +7 -0
- package/src/RemoteHttpInterceptor.ts +62 -57
- package/src/RequestController.test.ts +49 -0
- package/src/RequestController.ts +81 -0
- package/src/glossary.ts +4 -6
- package/src/interceptors/ClientRequest/MockHttpSocket.ts +22 -16
- package/src/interceptors/ClientRequest/index.test.ts +2 -33
- package/src/interceptors/ClientRequest/index.ts +32 -82
- package/src/interceptors/ClientRequest/utils/recordRawHeaders.ts +170 -0
- package/src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts +1 -1
- package/src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts +27 -108
- package/src/interceptors/XMLHttpRequest/index.ts +0 -6
- package/src/interceptors/fetch/index.ts +52 -169
- package/src/utils/handleRequest.ts +213 -0
- package/src/utils/responseUtils.ts +4 -4
- package/lib/browser/chunk-2CRB3JAQ.js.map +0 -1
- package/lib/browser/chunk-732REFPX.mjs.map +0 -1
- package/lib/browser/chunk-MAEPOYB6.mjs +0 -213
- package/lib/browser/chunk-MAEPOYB6.mjs.map +0 -1
- package/lib/browser/chunk-MQJ3JOOK.js +0 -49
- package/lib/browser/chunk-MQJ3JOOK.js.map +0 -1
- package/lib/browser/chunk-OMISYKWR.mjs.map +0 -1
- package/lib/browser/chunk-OUWBQF3Z.mjs +0 -49
- package/lib/browser/chunk-OUWBQF3Z.mjs.map +0 -1
- package/lib/browser/chunk-PSX5J3RF.js.map +0 -1
- package/lib/browser/chunk-WBHIW62P.js +0 -213
- package/lib/browser/chunk-WBHIW62P.js.map +0 -1
- package/lib/browser/glossary-1c204f45.d.ts +0 -44
- package/lib/node/chunk-3OJLYEWA.mjs.map +0 -1
- package/lib/node/chunk-5JMJ55U7.js.map +0 -1
- package/lib/node/chunk-BFLYGQ6D.js.map +0 -1
- package/lib/node/chunk-DV4PBH4D.mjs.map +0 -1
- package/lib/node/chunk-EIBTX65O.js.map +0 -1
- package/lib/node/chunk-KWV3JXSI.mjs +0 -49
- package/lib/node/chunk-KWV3JXSI.mjs.map +0 -1
- package/lib/node/chunk-OJ6O4LSC.mjs.map +0 -1
- package/lib/node/chunk-PYD4E2EJ.js.map +0 -1
- package/lib/node/chunk-UXCYRE4F.js +0 -49
- package/lib/node/chunk-UXCYRE4F.js.map +0 -1
- package/src/utils/getRawFetchHeaders.test.ts +0 -50
- package/src/utils/getRawFetchHeaders.ts +0 -56
- package/src/utils/toInteractiveRequest.ts +0 -23
- /package/lib/node/{chunk-2COJKQQB.js.map → chunk-42632LKH.js.map} +0 -0
- /package/lib/node/{chunk-PNWPIDEL.mjs.map → chunk-HGQLG7KE.mjs.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/interceptors/ClientRequest/index.ts","../../src/interceptors/ClientRequest/MockHttpSocket.ts","../../src/interceptors/Socket/MockSocket.ts","../../src/interceptors/Socket/utils/normalizeSocketWriteArgs.ts","../../src/interceptors/Socket/utils/baseUrlFromConnectionOptions.ts","../../src/interceptors/Socket/utils/parseRawHeaders.ts","../../src/utils/getValueBySymbol.ts","../../src/utils/isObject.ts","../../src/utils/getRawFetchHeaders.ts","../../src/interceptors/ClientRequest/agents.ts","../../src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts","../../src/utils/getRequestOptionsByUrl.ts","../../src/utils/getUrlByRequestOptions.ts","../../src/utils/cloneObject.ts","../../src/utils/isNodeLikeError.ts"],"sourcesContent":["import http from 'node:http'\nimport https from 'node:https'\nimport { until } from '@open-draft/until'\nimport { Interceptor } from '../../Interceptor'\nimport type { HttpRequestEventMap } from '../../glossary'\nimport {\n kRequestId,\n MockHttpSocketRequestCallback,\n MockHttpSocketResponseCallback,\n} from './MockHttpSocket'\nimport { MockAgent, MockHttpsAgent } from './agents'\nimport { emitAsync } from '../../utils/emitAsync'\nimport { toInteractiveRequest } from '../../utils/toInteractiveRequest'\nimport { normalizeClientRequestArgs } from './utils/normalizeClientRequestArgs'\nimport { isNodeLikeError } from '../../utils/isNodeLikeError'\nimport { createServerErrorResponse } from '../../utils/responseUtils'\n\nexport class ClientRequestInterceptor extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('client-request-interceptor')\n\n constructor() {\n super(ClientRequestInterceptor.symbol)\n }\n\n protected setup(): void {\n const { get: originalGet, request: originalRequest } = http\n const { get: originalHttpsGet, request: originalHttpsRequest } = https\n\n const onRequest = this.onRequest.bind(this)\n const onResponse = this.onResponse.bind(this)\n\n http.request = new Proxy(http.request, {\n apply: (target, thisArg, args: Parameters<typeof http.request>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'http:',\n args\n )\n const mockAgent = new MockAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n http.get = new Proxy(http.get, {\n apply: (target, thisArg, args: Parameters<typeof http.get>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'http:',\n args\n )\n\n const mockAgent = new MockAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n //\n // HTTPS.\n //\n\n https.request = new Proxy(https.request, {\n apply: (target, thisArg, args: Parameters<typeof https.request>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'https:',\n args\n )\n\n const mockAgent = new MockHttpsAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n https.get = new Proxy(https.get, {\n apply: (target, thisArg, args: Parameters<typeof https.get>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'https:',\n args\n )\n\n const mockAgent = new MockHttpsAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n this.subscriptions.push(() => {\n http.get = originalGet\n http.request = originalRequest\n\n https.get = originalHttpsGet\n https.request = originalHttpsRequest\n })\n }\n\n private onRequest: MockHttpSocketRequestCallback = async ({\n request,\n socket,\n }) => {\n const requestId = Reflect.get(request, kRequestId)\n const { interactiveRequest, requestController } =\n toInteractiveRequest(request)\n\n // TODO: Abstract this bit. We are using it everywhere.\n this.emitter.once('request', ({ requestId: pendingRequestId }) => {\n if (pendingRequestId !== requestId) {\n return\n }\n\n if (requestController.responsePromise.state === 'pending') {\n this.logger.info(\n 'request has not been handled in listeners, executing fail-safe listener...'\n )\n\n requestController.responsePromise.resolve(undefined)\n }\n })\n\n const listenerResult = await until(async () => {\n await emitAsync(this.emitter, 'request', {\n requestId,\n request: interactiveRequest,\n })\n\n return await requestController.responsePromise\n })\n\n if (listenerResult.error) {\n // Treat thrown Responses as mocked responses.\n if (listenerResult.error instanceof Response) {\n socket.respondWith(listenerResult.error)\n return\n }\n\n // Allow mocking Node-like errors.\n if (isNodeLikeError(listenerResult.error)) {\n socket.errorWith(listenerResult.error)\n return\n }\n\n // Emit the \"unhandledException\" event to allow the client\n // to opt-out from the default handling of exceptions\n // as 500 error responses.\n if (this.emitter.listenerCount('unhandledException') > 0) {\n await emitAsync(this.emitter, 'unhandledException', {\n error: listenerResult.error,\n request,\n requestId,\n controller: {\n respondWith: socket.respondWith.bind(socket),\n errorWith: socket.errorWith.bind(socket),\n },\n })\n\n // After the listeners are done, if the socket is\n // not connecting anymore, the response was mocked.\n // If the socket has been destroyed, the error was mocked.\n // Treat both as the result of the listener's call.\n if (!socket.connecting || socket.destroyed) {\n return\n }\n }\n\n // Unhandled exceptions in the request listeners are\n // synonymous to unhandled exceptions on the server.\n // Those are represented as 500 error responses.\n socket.respondWith(createServerErrorResponse(listenerResult.error))\n return\n }\n\n const mockedResponse = listenerResult.data\n\n if (mockedResponse) {\n /**\n * @note The `.respondWith()` method will handle \"Response.error()\".\n * Maybe we should make all interceptors do that?\n */\n socket.respondWith(mockedResponse)\n return\n }\n\n socket.passthrough()\n }\n\n public onResponse: MockHttpSocketResponseCallback = async ({\n requestId,\n request,\n response,\n isMockedResponse,\n }) => {\n // Return the promise to when all the response event listeners\n // are finished.\n return emitAsync(this.emitter, 'response', {\n requestId,\n request,\n response,\n isMockedResponse,\n })\n }\n}\n","import net from 'node:net'\nimport {\n HTTPParser,\n type RequestHeadersCompleteCallback,\n type ResponseHeadersCompleteCallback,\n} from '_http_common'\nimport { IncomingMessage, ServerResponse } from 'node:http'\nimport { Readable } from 'node:stream'\nimport { invariant } from 'outvariant'\nimport { INTERNAL_REQUEST_ID_HEADER_NAME } from '../../Interceptor'\nimport { MockSocket } from '../Socket/MockSocket'\nimport type { NormalizedSocketWriteArgs } from '../Socket/utils/normalizeSocketWriteArgs'\nimport { isPropertyAccessible } from '../../utils/isPropertyAccessible'\nimport { baseUrlFromConnectionOptions } from '../Socket/utils/baseUrlFromConnectionOptions'\nimport { parseRawHeaders } from '../Socket/utils/parseRawHeaders'\nimport { getRawFetchHeaders } from '../../utils/getRawFetchHeaders'\nimport {\n createServerErrorResponse,\n RESPONSE_STATUS_CODES_WITHOUT_BODY,\n} from '../../utils/responseUtils'\nimport { createRequestId } from '../../createRequestId'\n\ntype HttpConnectionOptions = any\n\nexport type MockHttpSocketRequestCallback = (args: {\n requestId: string\n request: Request\n socket: MockHttpSocket\n}) => void\n\nexport type MockHttpSocketResponseCallback = (args: {\n requestId: string\n request: Request\n response: Response\n isMockedResponse: boolean\n socket: MockHttpSocket\n}) => Promise<void>\n\ninterface MockHttpSocketOptions {\n connectionOptions: HttpConnectionOptions\n createConnection: () => net.Socket\n onRequest: MockHttpSocketRequestCallback\n onResponse: MockHttpSocketResponseCallback\n}\n\nexport const kRequestId = Symbol('kRequestId')\n\nexport class MockHttpSocket extends MockSocket {\n private connectionOptions: HttpConnectionOptions\n private createConnection: () => net.Socket\n private baseUrl: URL\n\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n private responseListenersPromise?: Promise<void>\n\n private writeBuffer: Array<NormalizedSocketWriteArgs> = []\n private request?: Request\n private requestParser: HTTPParser<0>\n private requestStream?: Readable\n private shouldKeepAlive?: boolean\n\n private responseType: 'mock' | 'bypassed' = 'bypassed'\n private responseParser: HTTPParser<1>\n private responseStream?: Readable\n\n constructor(options: MockHttpSocketOptions) {\n super({\n write: (chunk, encoding, callback) => {\n this.writeBuffer.push([chunk, encoding, callback])\n\n if (chunk) {\n this.requestParser.execute(\n Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding)\n )\n }\n },\n read: (chunk) => {\n if (chunk !== null) {\n this.responseParser.execute(\n Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n )\n }\n },\n })\n\n this.connectionOptions = options.connectionOptions\n this.createConnection = options.createConnection\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n\n this.baseUrl = baseUrlFromConnectionOptions(this.connectionOptions)\n\n // Request parser.\n this.requestParser = new HTTPParser()\n this.requestParser.initialize(HTTPParser.REQUEST, {})\n this.requestParser[HTTPParser.kOnHeadersComplete] =\n this.onRequestStart.bind(this)\n this.requestParser[HTTPParser.kOnBody] = this.onRequestBody.bind(this)\n this.requestParser[HTTPParser.kOnMessageComplete] =\n this.onRequestEnd.bind(this)\n\n // Response parser.\n this.responseParser = new HTTPParser()\n this.responseParser.initialize(HTTPParser.RESPONSE, {})\n this.responseParser[HTTPParser.kOnHeadersComplete] =\n this.onResponseStart.bind(this)\n this.responseParser[HTTPParser.kOnBody] = this.onResponseBody.bind(this)\n this.responseParser[HTTPParser.kOnMessageComplete] =\n this.onResponseEnd.bind(this)\n\n // Once the socket is finished, nothing can write to it\n // anymore. It has also flushed any buffered chunks.\n this.once('finish', () => this.requestParser.free())\n\n if (this.baseUrl.protocol === 'https:') {\n Reflect.set(this, 'encrypted', true)\n // The server certificate is not the same as a CA\n // passed to the TLS socket connection options.\n Reflect.set(this, 'authorized', false)\n Reflect.set(this, 'getProtocol', () => 'TLSv1.3')\n Reflect.set(this, 'getSession', () => undefined)\n Reflect.set(this, 'isSessionReused', () => false)\n }\n }\n\n public emit(event: string | symbol, ...args: any[]): boolean {\n const emitEvent = super.emit.bind(this, event as any, ...args)\n\n if (this.responseListenersPromise) {\n this.responseListenersPromise.finally(emitEvent)\n return this.listenerCount(event) > 0\n }\n\n return emitEvent()\n }\n\n public destroy(error?: Error | undefined): this {\n // Destroy the response parser when the socket gets destroyed.\n // Normally, we shoud listen to the \"close\" event but it\n // can be suppressed by using the \"emitClose: false\" option.\n this.responseParser.free()\n\n if (error) {\n this.emit('error', error)\n }\n\n return super.destroy(error)\n }\n\n /**\n * Establish this Socket connection as-is and pipe\n * its data/events through this Socket.\n */\n public passthrough(): void {\n if (this.destroyed) {\n return\n }\n\n const socket = this.createConnection()\n\n // If the developer destroys the socket, destroy the original connection.\n this.once('error', (error) => {\n socket.destroy(error)\n })\n\n this.address = socket.address.bind(socket)\n\n // Flush the buffered \"socket.write()\" calls onto\n // the original socket instance (i.e. write request body).\n // Exhaust the \"requestBuffer\" in case this Socket\n // gets reused for different requests.\n let writeArgs: NormalizedSocketWriteArgs | undefined\n let headersWritten = false\n\n while ((writeArgs = this.writeBuffer.shift())) {\n if (writeArgs !== undefined) {\n if (!headersWritten) {\n const [chunk, encoding, callback] = writeArgs\n const chunkString = chunk.toString()\n const chunkBeforeRequestHeaders = chunkString.slice(\n 0,\n chunkString.indexOf('\\r\\n') + 2\n )\n const chunkAfterRequestHeaders = chunkString.slice(\n chunk.indexOf('\\r\\n\\r\\n')\n )\n const requestHeaders =\n getRawFetchHeaders(this.request!.headers) || this.request!.headers\n const requestHeadersString = Array.from(requestHeaders.entries())\n // Skip the internal request ID deduplication header.\n .filter(([name]) => name !== INTERNAL_REQUEST_ID_HEADER_NAME)\n .map(([name, value]) => `${name}: ${value}`)\n .join('\\r\\n')\n\n // Modify the HTTP request message headers\n // to reflect any changes to the request headers\n // from the \"request\" event listener.\n const headersChunk = `${chunkBeforeRequestHeaders}${requestHeadersString}${chunkAfterRequestHeaders}`\n socket.write(headersChunk, encoding, callback)\n headersWritten = true\n continue\n }\n\n socket.write(...writeArgs)\n }\n }\n\n // Forward TLS Socket properties onto this Socket instance\n // in the case of a TLS/SSL connection.\n if (Reflect.get(socket, 'encrypted')) {\n const tlsProperties = [\n 'encrypted',\n 'authorized',\n 'getProtocol',\n 'getSession',\n 'isSessionReused',\n ]\n\n tlsProperties.forEach((propertyName) => {\n Object.defineProperty(this, propertyName, {\n enumerable: true,\n get: () => {\n const value = Reflect.get(socket, propertyName)\n return typeof value === 'function' ? value.bind(socket) : value\n },\n })\n })\n }\n\n socket\n .on('lookup', (...args) => this.emit('lookup', ...args))\n .on('connect', () => {\n this.connecting = socket.connecting\n this.emit('connect')\n })\n .on('secureConnect', () => this.emit('secureConnect'))\n .on('secure', () => this.emit('secure'))\n .on('session', (session) => this.emit('session', session))\n .on('ready', () => this.emit('ready'))\n .on('drain', () => this.emit('drain'))\n .on('data', (chunk) => {\n // Push the original response to this socket\n // so it triggers the HTTP response parser. This unifies\n // the handling pipeline for original and mocked response.\n this.push(chunk)\n })\n .on('error', (error) => {\n Reflect.set(this, '_hadError', Reflect.get(socket, '_hadError'))\n this.emit('error', error)\n })\n .on('resume', () => this.emit('resume'))\n .on('timeout', () => this.emit('timeout'))\n .on('prefinish', () => this.emit('prefinish'))\n .on('finish', () => this.emit('finish'))\n .on('close', (hadError) => this.emit('close', hadError))\n .on('end', () => this.emit('end'))\n }\n\n /**\n * Convert the given Fetch API `Response` instance to an\n * HTTP message and push it to the socket.\n */\n public async respondWith(response: Response): Promise<void> {\n // Ignore the mocked response if the socket has been destroyed\n // (e.g. aborted or timed out),\n if (this.destroyed) {\n return\n }\n\n // Handle \"type: error\" responses.\n if (isPropertyAccessible(response, 'type') && response.type === 'error') {\n this.errorWith(new TypeError('Network error'))\n return\n }\n\n // First, emit all the connection events\n // to emulate a successful connection.\n this.mockConnect()\n this.responseType = 'mock'\n\n // Flush the write buffer to trigger write callbacks\n // if it hasn't been flushed already (e.g. someone started reading request stream).\n this.flushWriteBuffer()\n\n // Create a `ServerResponse` instance to delegate HTTP message parsing,\n // Transfer-Encoding, and other things to Node.js internals.\n const serverResponse = new ServerResponse(new IncomingMessage(this))\n\n /**\n * Assign a mock socket instance to the server response to\n * spy on the response chunk writes. Push the transformed response chunks\n * to this `MockHttpSocket` instance to trigger the \"data\" event.\n * @note Providing the same `MockSocket` instance when creating `ServerResponse`\n * does not have the same effect.\n * @see https://github.com/nodejs/node/blob/10099bb3f7fd97bb9dd9667188426866b3098e07/test/parallel/test-http-server-response-standalone.js#L32\n */\n serverResponse.assignSocket(\n new MockSocket({\n write: (chunk, encoding, callback) => {\n this.push(chunk, encoding)\n callback?.()\n },\n read() {},\n })\n )\n serverResponse.statusCode = response.status\n serverResponse.statusMessage = response.statusText\n\n /**\n * @note Remove the `Connection` and `Date` response headers\n * injected by `ServerResponse` by default. Those are required\n * from the server but the interceptor is NOT technically a server.\n * It's confusing to add response headers that the developer didn't\n * specify themselves. They can always add these if they wish.\n * @see https://www.rfc-editor.org/rfc/rfc9110#field.date\n * @see https://www.rfc-editor.org/rfc/rfc9110#field.connection\n */\n serverResponse.removeHeader('connection')\n serverResponse.removeHeader('date')\n\n // If the developer destroy the socket, gracefully destroy the response.\n this.once('error', () => {\n serverResponse.destroy()\n })\n\n // Get the raw headers stored behind the symbol to preserve name casing.\n const headers = getRawFetchHeaders(response.headers) || response.headers\n for (const [name, value] of headers) {\n serverResponse.setHeader(name, value)\n }\n\n if (response.body) {\n try {\n const reader = response.body.getReader()\n\n while (true) {\n const { done, value } = await reader.read()\n\n if (done) {\n serverResponse.end()\n break\n }\n\n serverResponse.write(value)\n }\n } catch (error) {\n // Coerce response stream errors to 500 responses.\n this.respondWith(createServerErrorResponse(error))\n return\n }\n } else {\n serverResponse.end()\n }\n\n // Close the socket if the connection wasn't marked as keep-alive.\n if (!this.shouldKeepAlive) {\n this.emit('readable')\n\n /**\n * @todo @fixme This is likely a hack.\n * Since we push null to the socket, it never propagates to the\n * parser, and the parser never calls \"onResponseEnd\" to close\n * the response stream. We are closing the stream here manually\n * but that shouldn't be the case.\n */\n this.responseStream?.push(null)\n this.push(null)\n }\n }\n\n /**\n * Close this socket connection with the given error.\n */\n public errorWith(error: Error): void {\n this.destroy(error)\n }\n\n private mockConnect(): void {\n // Calling this method immediately puts the socket\n // into the connected state.\n this.connecting = false\n\n const isIPv6 =\n net.isIPv6(this.connectionOptions.hostname) ||\n this.connectionOptions.family === 6\n const addressInfo = {\n address: isIPv6 ? '::1' : '127.0.0.1',\n family: isIPv6 ? 'IPv6' : 'IPv4',\n port: this.connectionOptions.port,\n }\n // Return fake address information for the socket.\n this.address = () => addressInfo\n this.emit(\n 'lookup',\n null,\n addressInfo.address,\n addressInfo.family === 'IPv6' ? 6 : 4,\n this.connectionOptions.host\n )\n this.emit('connect')\n this.emit('ready')\n\n if (this.baseUrl.protocol === 'https:') {\n this.emit('secure')\n this.emit('secureConnect')\n\n // A single TLS connection is represented by two \"session\" events.\n this.emit(\n 'session',\n this.connectionOptions.session ||\n Buffer.from('mock-session-renegotiate')\n )\n this.emit('session', Buffer.from('mock-session-resume'))\n }\n }\n\n private flushWriteBuffer(): void {\n let args: NormalizedSocketWriteArgs | undefined\n while ((args = this.writeBuffer.shift())) {\n args?.[2]?.()\n }\n }\n\n private onRequestStart: RequestHeadersCompleteCallback = (\n versionMajor,\n versionMinor,\n rawHeaders,\n _,\n path,\n __,\n ___,\n ____,\n shouldKeepAlive\n ) => {\n this.shouldKeepAlive = shouldKeepAlive\n\n const url = new URL(path, this.baseUrl)\n const method = this.connectionOptions.method || 'GET'\n const headers = parseRawHeaders(rawHeaders)\n const canHaveBody = method !== 'GET' && method !== 'HEAD'\n\n // Translate the basic authorization in the URL to the request header.\n // Constructing a Request instance with a URL containing auth is no-op.\n if (url.username || url.password) {\n if (!headers.has('authorization')) {\n headers.set('authorization', `Basic ${url.username}:${url.password}`)\n }\n url.username = ''\n url.password = ''\n }\n\n // Create a new stream for each request.\n // If this Socket is reused for multiple requests,\n // this ensures that each request gets its own stream.\n // One Socket instance can only handle one request at a time.\n if (canHaveBody) {\n this.requestStream = new Readable({\n /**\n * @note Provide the `read()` method so a `Readable` could be\n * used as the actual request body (the stream calls \"read()\").\n * We control the queue in the onRequestBody/End functions.\n */\n read: () => {\n // If the user attempts to read the request body,\n // flush the write buffer to trigger the callbacks.\n // This way, if the request stream ends in the write callback,\n // it will indeed end correctly.\n this.flushWriteBuffer()\n },\n })\n }\n\n const requestId = createRequestId()\n this.request = new Request(url, {\n method,\n headers,\n credentials: 'same-origin',\n // @ts-expect-error Undocumented Fetch property.\n duplex: canHaveBody ? 'half' : undefined,\n body: canHaveBody ? (Readable.toWeb(this.requestStream!) as any) : null,\n })\n\n Reflect.set(this.request, kRequestId, requestId)\n\n // Skip handling the request that's already being handled\n // by another (parent) interceptor. For example, XMLHttpRequest\n // is often implemented via ClientRequest in Node.js (e.g. JSDOM).\n // In that case, XHR interceptor will bubble down to the ClientRequest\n // interceptor. No need to try to handle that request again.\n /**\n * @fixme Stop relying on the \"X-Request-Id\" request header\n * to figure out if one interceptor has been invoked within another.\n * @see https://github.com/mswjs/interceptors/issues/378\n */\n if (this.request.headers.has(INTERNAL_REQUEST_ID_HEADER_NAME)) {\n this.passthrough()\n return\n }\n\n this.onRequest({\n requestId,\n request: this.request,\n socket: this,\n })\n }\n\n private onRequestBody(chunk: Buffer): void {\n invariant(\n this.requestStream,\n 'Failed to write to a request stream: stream does not exist'\n )\n\n this.requestStream.push(chunk)\n }\n\n private onRequestEnd(): void {\n // Request end can be called for requests without body.\n if (this.requestStream) {\n this.requestStream.push(null)\n }\n }\n\n private onResponseStart: ResponseHeadersCompleteCallback = (\n versionMajor,\n versionMinor,\n rawHeaders,\n method,\n url,\n status,\n statusText\n ) => {\n const headers = parseRawHeaders(rawHeaders)\n const canHaveBody = !RESPONSE_STATUS_CODES_WITHOUT_BODY.has(status)\n\n // Similarly, create a new stream for each response.\n if (canHaveBody) {\n this.responseStream = new Readable()\n }\n\n const response = new Response(\n /**\n * @note The Fetch API response instance exposed to the consumer\n * is created over the response stream of the HTTP parser. It is NOT\n * related to the Socket instance. This way, you can read response body\n * in response listener while the Socket instance delays the emission\n * of \"end\" and other events until those response listeners are finished.\n */\n canHaveBody ? (Readable.toWeb(this.responseStream!) as any) : null,\n {\n status,\n statusText,\n headers,\n }\n )\n\n invariant(\n this.request,\n 'Failed to handle a response: request does not exist'\n )\n\n /**\n * @fixme Stop relying on the \"X-Request-Id\" request header\n * to figure out if one interceptor has been invoked within another.\n * @see https://github.com/mswjs/interceptors/issues/378\n */\n if (this.request.headers.has(INTERNAL_REQUEST_ID_HEADER_NAME)) {\n return\n }\n\n this.responseListenersPromise = this.onResponse({\n response,\n isMockedResponse: this.responseType === 'mock',\n requestId: Reflect.get(this.request, kRequestId),\n request: this.request,\n socket: this,\n })\n }\n\n private onResponseBody(chunk: Buffer) {\n invariant(\n this.responseStream,\n 'Failed to write to a response stream: stream does not exist'\n )\n\n this.responseStream.push(chunk)\n }\n\n private onResponseEnd(): void {\n // Response end can be called for responses without body.\n if (this.responseStream) {\n this.responseStream.push(null)\n }\n }\n}\n","import net from 'node:net'\nimport {\n normalizeSocketWriteArgs,\n type WriteArgs,\n type WriteCallback,\n} from './utils/normalizeSocketWriteArgs'\n\nexport interface MockSocketOptions {\n write: (\n chunk: Buffer | string,\n encoding: BufferEncoding | undefined,\n callback?: WriteCallback\n ) => void\n\n read: (chunk: Buffer, encoding: BufferEncoding | undefined) => void\n}\n\nexport class MockSocket extends net.Socket {\n public connecting: boolean\n\n constructor(protected readonly options: MockSocketOptions) {\n super()\n this.connecting = false\n this.connect()\n\n this._final = (callback) => {\n callback(null)\n }\n }\n\n public connect() {\n // The connection will remain pending until\n // the consumer decides to handle it.\n this.connecting = true\n return this\n }\n\n public write(...args: Array<unknown>): boolean {\n const [chunk, encoding, callback] = normalizeSocketWriteArgs(\n args as WriteArgs\n )\n this.options.write(chunk, encoding, callback)\n return true\n }\n\n public end(...args: Array<unknown>) {\n const [chunk, encoding, callback] = normalizeSocketWriteArgs(\n args as WriteArgs\n )\n this.options.write(chunk, encoding, callback)\n\n return super.end.apply(this, args as any)\n }\n\n public push(chunk: any, encoding?: BufferEncoding): boolean {\n this.options.read(chunk, encoding)\n return super.push(chunk, encoding)\n }\n}\n","export type WriteCallback = (error?: Error | null) => void\n\nexport type WriteArgs =\n | [chunk: unknown, callback?: WriteCallback]\n | [chunk: unknown, encoding: BufferEncoding, callback?: WriteCallback]\n\nexport type NormalizedSocketWriteArgs = [\n chunk: any,\n encoding?: BufferEncoding,\n callback?: WriteCallback,\n]\n\n/**\n * Normalizes the arguments provided to the `Writable.prototype.write()`\n * and `Writable.prototype.end()`.\n */\nexport function normalizeSocketWriteArgs(\n args: WriteArgs\n): NormalizedSocketWriteArgs {\n const normalized: NormalizedSocketWriteArgs = [args[0], undefined, undefined]\n\n if (typeof args[1] === 'string') {\n normalized[1] = args[1]\n } else if (typeof args[1] === 'function') {\n normalized[2] = args[1]\n }\n\n if (typeof args[2] === 'function') {\n normalized[2] = args[2]\n }\n\n return normalized\n}\n","export function baseUrlFromConnectionOptions(options: any): URL {\n if ('href' in options) {\n return new URL(options.href)\n }\n\n const protocol = options.port === 443 ? 'https:' : 'http:'\n const host = options.host\n\n const url = new URL(`${protocol}//${host}`)\n\n if (options.port) {\n url.port = options.port.toString()\n }\n\n if (options.path) {\n url.pathname = options.path\n }\n\n if (options.auth) {\n const [username, password] = options.auth.split(':')\n url.username = username\n url.password = password\n }\n\n return url\n}\n","/**\n * Create a Fetch API `Headers` instance from the given raw headers list.\n */\nexport function parseRawHeaders(rawHeaders: Array<string>): Headers {\n const headers = new Headers()\n for (let line = 0; line < rawHeaders.length; line += 2) {\n headers.append(rawHeaders[line], rawHeaders[line + 1])\n }\n return headers\n}\n","/**\n * Returns the value behind the symbol with the given name.\n */\nexport function getValueBySymbol<T>(\n symbolName: string,\n source: object\n): T | undefined {\n const ownSymbols = Object.getOwnPropertySymbols(source)\n\n const symbol = ownSymbols.find((symbol) => {\n return symbol.description === symbolName\n })\n\n if (symbol) {\n return Reflect.get(source, symbol)\n }\n\n return\n}\n","/**\n * Determines if a given value is an instance of object.\n */\nexport function isObject<T>(value: any, loose = false): value is T {\n return loose\n ? Object.prototype.toString.call(value).startsWith('[object ')\n : Object.prototype.toString.call(value) === '[object Object]'\n}\n","import { getValueBySymbol } from './getValueBySymbol'\nimport { isObject } from './isObject'\n\ntype RawHeadersMap = Map<string, string>\ntype HeadersMapHeader = { name: string; value: string }\n\n/**\n * Returns raw headers from the given `Headers` instance.\n * @example\n * const headers = new Headers([\n * ['X-HeadeR-NamE', 'Value']\n * ])\n * getRawFetchHeaders(headers)\n * // { 'X-HeadeR-NamE': 'Value' }\n */\nexport function getRawFetchHeaders(\n headers: Headers\n): RawHeadersMap | undefined {\n const headersList = getValueBySymbol<object>('headers list', headers)\n\n if (!headersList) {\n return\n }\n\n const headersMap = getValueBySymbol<\n Map<string, string> | Map<string, HeadersMapHeader>\n >('headers map', headersList)\n\n /**\n * @note Older versions of Node.js (e.g. 18.8.0) keep headers map\n * as Map<normalizedHeaderName, value> without any means to tap\n * into raw header values. Detect that and return undefined.\n */\n if (!headersMap || !isHeadersMapWithRawHeaderNames(headersMap)) {\n return\n }\n\n // Raw headers is a map of { rawHeaderName: rawHeaderValue }\n const rawHeaders: RawHeadersMap = new Map<string, string>()\n\n headersMap.forEach(({ name, value }) => {\n rawHeaders.set(name, value)\n })\n\n return rawHeaders\n}\n\nfunction isHeadersMapWithRawHeaderNames(\n headersMap: Map<string, string> | Map<string, HeadersMapHeader>\n): headersMap is Map<string, HeadersMapHeader> {\n return Array.from(\n headersMap.values() as Iterable<string | HeadersMapHeader>\n ).every((value) => {\n return isObject<HeadersMapHeader>(value) && 'name' in value\n })\n}\n","import net from 'node:net'\nimport http from 'node:http'\nimport https from 'node:https'\nimport {\n MockHttpSocket,\n type MockHttpSocketRequestCallback,\n type MockHttpSocketResponseCallback,\n} from './MockHttpSocket'\n\ndeclare module 'node:http' {\n interface Agent {\n createConnection(options: any, callback: any): net.Socket\n }\n}\n\ninterface MockAgentOptions {\n customAgent?: http.RequestOptions['agent']\n onRequest: MockHttpSocketRequestCallback\n onResponse: MockHttpSocketResponseCallback\n}\n\nexport class MockAgent extends http.Agent {\n private customAgent?: http.RequestOptions['agent']\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n\n constructor(options: MockAgentOptions) {\n super()\n this.customAgent = options.customAgent\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n }\n\n public createConnection(options: any, callback: any) {\n const createConnection =\n (this.customAgent instanceof http.Agent &&\n this.customAgent.createConnection) ||\n super.createConnection\n\n const socket = new MockHttpSocket({\n connectionOptions: options,\n createConnection: createConnection.bind(this, options, callback),\n onRequest: this.onRequest.bind(this),\n onResponse: this.onResponse.bind(this),\n })\n\n return socket\n }\n}\n\nexport class MockHttpsAgent extends https.Agent {\n private customAgent?: https.RequestOptions['agent']\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n\n constructor(options: MockAgentOptions) {\n super()\n this.customAgent = options.customAgent\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n }\n\n public createConnection(options: any, callback: any) {\n const createConnection =\n (this.customAgent instanceof https.Agent &&\n this.customAgent.createConnection) ||\n super.createConnection\n\n const socket = new MockHttpSocket({\n connectionOptions: options,\n createConnection: createConnection.bind(this, options, callback),\n onRequest: this.onRequest.bind(this),\n onResponse: this.onResponse.bind(this),\n })\n\n return socket\n }\n}\n","import {\n Agent as HttpAgent,\n globalAgent as httpGlobalAgent,\n IncomingMessage,\n} from 'node:http'\nimport {\n RequestOptions,\n Agent as HttpsAgent,\n globalAgent as httpsGlobalAgent,\n} from 'node:https'\nimport {\n /**\n * @note Use the Node.js URL instead of the global URL\n * because environments like JSDOM may override the global,\n * breaking the compatibility with Node.js.\n * @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555\n */\n URL,\n Url as LegacyURL,\n parse as parseUrl,\n} from 'node:url'\nimport { Logger } from '@open-draft/logger'\nimport { getRequestOptionsByUrl } from '../../../utils/getRequestOptionsByUrl'\nimport {\n ResolvedRequestOptions,\n getUrlByRequestOptions,\n} from '../../../utils/getUrlByRequestOptions'\nimport { cloneObject } from '../../../utils/cloneObject'\nimport { isObject } from '../../../utils/isObject'\n\nconst logger = new Logger('http normalizeClientRequestArgs')\n\nexport type HttpRequestCallback = (response: IncomingMessage) => void\n\nexport type ClientRequestArgs =\n // Request without any arguments is also possible.\n | []\n | [string | URL | LegacyURL, HttpRequestCallback?]\n | [string | URL | LegacyURL, RequestOptions, HttpRequestCallback?]\n | [RequestOptions, HttpRequestCallback?]\n\nfunction resolveRequestOptions(\n args: ClientRequestArgs,\n url: URL\n): RequestOptions {\n // Calling `fetch` provides only URL to `ClientRequest`\n // without any `RequestOptions` or callback.\n if (typeof args[1] === 'undefined' || typeof args[1] === 'function') {\n logger.info('request options not provided, deriving from the url', url)\n return getRequestOptionsByUrl(url)\n }\n\n if (args[1]) {\n logger.info('has custom RequestOptions!', args[1])\n const requestOptionsFromUrl = getRequestOptionsByUrl(url)\n\n logger.info('derived RequestOptions from the URL:', requestOptionsFromUrl)\n\n /**\n * Clone the request options to lock their state\n * at the moment they are provided to `ClientRequest`.\n * @see https://github.com/mswjs/interceptors/issues/86\n */\n logger.info('cloning RequestOptions...')\n const clonedRequestOptions = cloneObject(args[1])\n logger.info('successfully cloned RequestOptions!', clonedRequestOptions)\n\n return {\n ...requestOptionsFromUrl,\n ...clonedRequestOptions,\n }\n }\n\n logger.info('using an empty object as request options')\n return {} as RequestOptions\n}\n\n/**\n * Overrides the given `URL` instance with the explicit properties provided\n * on the `RequestOptions` object. The options object takes precedence,\n * and will replace URL properties like \"host\", \"path\", and \"port\", if specified.\n */\nfunction overrideUrlByRequestOptions(url: URL, options: RequestOptions): URL {\n url.host = options.host || url.host\n url.hostname = options.hostname || url.hostname\n url.port = options.port ? options.port.toString() : url.port\n\n if (options.path) {\n const parsedOptionsPath = parseUrl(options.path, false)\n url.pathname = parsedOptionsPath.pathname || ''\n url.search = parsedOptionsPath.search || ''\n }\n\n return url\n}\n\nfunction resolveCallback(\n args: ClientRequestArgs\n): HttpRequestCallback | undefined {\n return typeof args[1] === 'function' ? args[1] : args[2]\n}\n\nexport type NormalizedClientRequestArgs = [\n url: URL,\n options: ResolvedRequestOptions,\n callback?: HttpRequestCallback,\n]\n\n/**\n * Normalizes parameters given to a `http.request` call\n * so it always has a `URL` and `RequestOptions`.\n */\nexport function normalizeClientRequestArgs(\n defaultProtocol: string,\n args: ClientRequestArgs\n): NormalizedClientRequestArgs {\n let url: URL\n let options: ResolvedRequestOptions\n let callback: HttpRequestCallback | undefined\n\n logger.info('arguments', args)\n logger.info('using default protocol:', defaultProtocol)\n\n // Support \"http.request()\" calls without any arguments.\n // That call results in a \"GET http://localhost\" request.\n if (args.length === 0) {\n const url = new URL('http://localhost')\n const options = resolveRequestOptions(args, url)\n return [url, options]\n }\n\n // Convert a url string into a URL instance\n // and derive request options from it.\n if (typeof args[0] === 'string') {\n logger.info('first argument is a location string:', args[0])\n\n url = new URL(args[0])\n logger.info('created a url:', url)\n\n const requestOptionsFromUrl = getRequestOptionsByUrl(url)\n logger.info('request options from url:', requestOptionsFromUrl)\n\n options = resolveRequestOptions(args, url)\n logger.info('resolved request options:', options)\n\n callback = resolveCallback(args)\n }\n // Handle a given URL instance as-is\n // and derive request options from it.\n else if (args[0] instanceof URL) {\n url = args[0]\n logger.info('first argument is a URL:', url)\n\n // Check if the second provided argument is RequestOptions.\n // If it is, check if \"options.path\" was set and rewrite it\n // on the input URL.\n // Do this before resolving options from the URL below\n // to prevent query string from being duplicated in the path.\n if (typeof args[1] !== 'undefined' && isObject<RequestOptions>(args[1])) {\n url = overrideUrlByRequestOptions(url, args[1])\n }\n\n options = resolveRequestOptions(args, url)\n logger.info('derived request options:', options)\n\n callback = resolveCallback(args)\n }\n // Handle a legacy URL instance and re-normalize from either a RequestOptions object\n // or a WHATWG URL.\n else if ('hash' in args[0] && !('method' in args[0])) {\n const [legacyUrl] = args\n logger.info('first argument is a legacy URL:', legacyUrl)\n\n if (legacyUrl.hostname === null) {\n /**\n * We are dealing with a relative url, so use the path as an \"option\" and\n * merge in any existing options, giving priority to exising options -- i.e. a path in any\n * existing options will take precedence over the one contained in the url. This is consistent\n * with the behaviour in ClientRequest.\n * @see https://github.com/nodejs/node/blob/d84f1312915fe45fe0febe888db692c74894c382/lib/_http_client.js#L122\n */\n logger.info('given legacy URL is relative (no hostname)')\n\n return isObject(args[1])\n ? normalizeClientRequestArgs(defaultProtocol, [\n { path: legacyUrl.path, ...args[1] },\n args[2],\n ])\n : normalizeClientRequestArgs(defaultProtocol, [\n { path: legacyUrl.path },\n args[1] as HttpRequestCallback,\n ])\n }\n\n logger.info('given legacy url is absolute')\n\n // We are dealing with an absolute URL, so convert to WHATWG and try again.\n const resolvedUrl = new URL(legacyUrl.href)\n\n return args[1] === undefined\n ? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl])\n : typeof args[1] === 'function'\n ? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl, args[1]])\n : normalizeClientRequestArgs(defaultProtocol, [\n resolvedUrl,\n args[1],\n args[2],\n ])\n }\n // Handle a given \"RequestOptions\" object as-is\n // and derive the URL instance from it.\n else if (isObject(args[0])) {\n options = { ... args[0] as any }\n logger.info('first argument is RequestOptions:', options)\n\n // When handling a \"RequestOptions\" object without an explicit \"protocol\",\n // infer the protocol from the request issuing module (http/https).\n options.protocol = options.protocol || defaultProtocol\n logger.info('normalized request options:', options)\n\n url = getUrlByRequestOptions(options)\n logger.info('created a URL from RequestOptions:', url.href)\n\n callback = resolveCallback(args)\n } else {\n throw new Error(\n `Failed to construct ClientRequest with these parameters: ${args}`\n )\n }\n\n options.protocol = options.protocol || url.protocol\n options.method = options.method || 'GET'\n\n /**\n * Infer a fallback agent from the URL protocol.\n * The interception is done on the \"ClientRequest\" level (\"NodeClientRequest\")\n * and it may miss the correct agent. Always align the agent\n * with the URL protocol, if not provided.\n *\n * @note Respect the \"agent: false\" value.\n */\n if (typeof options.agent === 'undefined') {\n const agent =\n options.protocol === 'https:'\n ? new HttpsAgent({\n rejectUnauthorized: options.rejectUnauthorized,\n })\n : new HttpAgent()\n\n options.agent = agent\n logger.info('resolved fallback agent:', agent)\n }\n\n /**\n * Ensure that the default Agent is always set.\n * This prevents the protocol mismatch for requests with { agent: false },\n * where the global Agent is inferred.\n * @see https://github.com/mswjs/msw/issues/1150\n * @see https://github.com/nodejs/node/blob/418ff70b810f0e7112d48baaa72932a56cfa213b/lib/_http_client.js#L130\n * @see https://github.com/nodejs/node/blob/418ff70b810f0e7112d48baaa72932a56cfa213b/lib/_http_client.js#L157-L159\n */\n if (!options._defaultAgent) {\n logger.info(\n 'has no default agent, setting the default agent for \"%s\"',\n options.protocol\n )\n\n options._defaultAgent =\n options.protocol === 'https:' ? httpsGlobalAgent : httpGlobalAgent\n }\n\n logger.info('successfully resolved url:', url.href)\n logger.info('successfully resolved options:', options)\n logger.info('successfully resolved callback:', callback)\n\n /**\n * @note If the user-provided URL is not a valid URL in Node.js,\n * (e.g. the one provided by the JSDOM polyfills), case it to\n * string. Otherwise, this throws on Node.js incompatibility\n * (`ERR_INVALID_ARG_TYPE` on the connection listener)\n * @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555\n */\n if (!(url instanceof URL)) {\n url = (url as any).toString()\n }\n\n return [url, options, callback]\n}\n","import { RequestOptions } from 'http'\n\n/**\n * Converts a URL instance into the RequestOptions object expected by\n * the `ClientRequest` class.\n * @see https://github.com/nodejs/node/blob/908292cf1f551c614a733d858528ffb13fb3a524/lib/internal/url.js#L1257\n */\nexport function getRequestOptionsByUrl(url: URL): RequestOptions {\n const options: RequestOptions = {\n method: 'GET',\n protocol: url.protocol,\n hostname:\n typeof url.hostname === 'string' && url.hostname.startsWith('[')\n ? url.hostname.slice(1, -1)\n : url.hostname,\n host: url.host,\n path: `${url.pathname}${url.search || ''}`,\n }\n\n if (!!url.port) {\n options.port = Number(url.port)\n }\n\n if (url.username || url.password) {\n options.auth = `${url.username}:${url.password}`\n }\n\n return options\n}\n","import { Agent } from 'http'\nimport { RequestOptions, Agent as HttpsAgent } from 'https'\nimport { Logger } from '@open-draft/logger'\n\nconst logger = new Logger('utils getUrlByRequestOptions')\n\n// Request instance constructed by the \"request\" library\n// has a \"self\" property that has a \"uri\" field. This is\n// reproducible by performing a \"XMLHttpRequest\" request in JSDOM.\nexport interface RequestSelf {\n uri?: URL\n}\n\nexport type ResolvedRequestOptions = RequestOptions & RequestSelf\n\nexport const DEFAULT_PATH = '/'\nconst DEFAULT_PROTOCOL = 'http:'\nconst DEFAULT_HOSTNAME = 'localhost'\nconst SSL_PORT = 443\n\nfunction getAgent(\n options: ResolvedRequestOptions\n): Agent | HttpsAgent | undefined {\n return options.agent instanceof Agent ? options.agent : undefined\n}\n\nfunction getProtocolByRequestOptions(options: ResolvedRequestOptions): string {\n if (options.protocol) {\n return options.protocol\n }\n\n const agent = getAgent(options)\n const agentProtocol = (agent as RequestOptions)?.protocol\n\n if (agentProtocol) {\n return agentProtocol\n }\n\n const port = getPortByRequestOptions(options)\n const isSecureRequest = options.cert || port === SSL_PORT\n\n return isSecureRequest ? 'https:' : options.uri?.protocol || DEFAULT_PROTOCOL\n}\n\nfunction getPortByRequestOptions(\n options: ResolvedRequestOptions\n): number | undefined {\n // Use the explicitly provided port.\n if (options.port) {\n return Number(options.port)\n }\n\n // Otherwise, try to resolve port from the agent.\n const agent = getAgent(options)\n\n if ((agent as HttpsAgent)?.options.port) {\n return Number((agent as HttpsAgent).options.port)\n }\n\n if ((agent as RequestOptions)?.defaultPort) {\n return Number((agent as RequestOptions).defaultPort)\n }\n\n // Lastly, return undefined indicating that the port\n // must inferred from the protocol. Do not infer it here.\n return undefined\n}\n\ninterface RequestAuth {\n username: string\n password: string\n}\n\nfunction getAuthByRequestOptions(\n options: ResolvedRequestOptions\n): RequestAuth | undefined {\n if (options.auth) {\n const [username, password] = options.auth.split(':')\n return { username, password }\n }\n}\n\n/**\n * Returns true if host looks like an IPv6 address without surrounding brackets\n * It assumes any host containing `:` is definitely not IPv4 and probably IPv6,\n * but note that this could include invalid IPv6 addresses as well.\n */\nfunction isRawIPv6Address(host: string): boolean {\n return host.includes(':') && !host.startsWith('[') && !host.endsWith(']')\n}\n\nfunction getHostname(options: ResolvedRequestOptions): string | undefined {\n let host = options.hostname || options.host\n\n if (host) {\n if (isRawIPv6Address(host)) {\n host = `[${host}]`\n }\n\n // Check the presence of the port, and if it's present,\n // remove it from the host, returning a hostname.\n return new URL(`http://${host}`).hostname\n }\n\n return DEFAULT_HOSTNAME\n}\n\n/**\n * Creates a `URL` instance from a given `RequestOptions` object.\n */\nexport function getUrlByRequestOptions(options: ResolvedRequestOptions): URL {\n logger.info('request options', options)\n\n if (options.uri) {\n logger.info(\n 'constructing url from explicitly provided \"options.uri\": %s',\n options.uri\n )\n return new URL(options.uri.href)\n }\n\n logger.info('figuring out url from request options...')\n\n const protocol = getProtocolByRequestOptions(options)\n logger.info('protocol', protocol)\n\n const port = getPortByRequestOptions(options)\n logger.info('port', port)\n\n const hostname = getHostname(options)\n logger.info('hostname', hostname)\n\n const path = options.path || DEFAULT_PATH\n logger.info('path', path)\n\n const credentials = getAuthByRequestOptions(options)\n logger.info('credentials', credentials)\n\n const authString = credentials\n ? `${credentials.username}:${credentials.password}@`\n : ''\n logger.info('auth string:', authString)\n\n const portString = typeof port !== 'undefined' ? `:${port}` : ''\n const url = new URL(`${protocol}//${hostname}${portString}${path}`)\n url.username = credentials?.username || ''\n url.password = credentials?.password || ''\n\n logger.info('created url:', url)\n\n return url\n}\n","import { Logger } from '@open-draft/logger'\n\nconst logger = new Logger('cloneObject')\n\nfunction isPlainObject(obj?: Record<string, any>): boolean {\n logger.info('is plain object?', obj)\n\n if (obj == null || !obj.constructor?.name) {\n logger.info('given object is undefined, not a plain object...')\n return false\n }\n\n logger.info('checking the object constructor:', obj.constructor.name)\n return obj.constructor.name === 'Object'\n}\n\nexport function cloneObject<ObjectType extends Record<string, any>>(\n obj: ObjectType\n): ObjectType {\n logger.info('cloning object:', obj)\n\n const enumerableProperties = Object.entries(obj).reduce<Record<string, any>>(\n (acc, [key, value]) => {\n logger.info('analyzing key-value pair:', key, value)\n\n // Recursively clone only plain objects, omitting class instances.\n acc[key] = isPlainObject(value) ? cloneObject(value) : value\n return acc\n },\n {}\n )\n\n return isPlainObject(obj)\n ? enumerableProperties\n : Object.assign(Object.getPrototypeOf(obj), enumerableProperties)\n}\n","export function isNodeLikeError(\n error: unknown\n): error is NodeJS.ErrnoException {\n if (error == null) {\n return false\n }\n\n if (!(error instanceof Error)) {\n return false\n }\n\n return 'code' in error && 'errno' in error\n}\n"],"mappings":"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","names":["http","https","net","symbol","net","URL","Logger","Logger","logger","logger","Logger","url","URL","options","http","https"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/interceptors/ClientRequest/index.ts","../../src/interceptors/ClientRequest/MockHttpSocket.ts","../../src/interceptors/Socket/MockSocket.ts","../../src/interceptors/Socket/utils/normalizeSocketWriteArgs.ts","../../src/interceptors/Socket/utils/baseUrlFromConnectionOptions.ts","../../src/interceptors/Socket/utils/parseRawHeaders.ts","../../src/utils/getValueBySymbol.ts","../../src/utils/isObject.ts","../../src/utils/getRawFetchHeaders.ts","../../src/interceptors/ClientRequest/agents.ts","../../src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts","../../src/utils/getRequestOptionsByUrl.ts","../../src/utils/getUrlByRequestOptions.ts","../../src/utils/cloneObject.ts","../../src/utils/isNodeLikeError.ts"],"names":["http","https","net","symbol","URL","Logger","logger","url","options"],"mappings":"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","sourcesContent":["import http from 'node:http'\nimport https from 'node:https'\nimport { until } from '@open-draft/until'\nimport { Interceptor } from '../../Interceptor'\nimport type { HttpRequestEventMap } from '../../glossary'\nimport {\n kRequestId,\n MockHttpSocketRequestCallback,\n MockHttpSocketResponseCallback,\n} from './MockHttpSocket'\nimport { MockAgent, MockHttpsAgent } from './agents'\nimport { emitAsync } from '../../utils/emitAsync'\nimport { toInteractiveRequest } from '../../utils/toInteractiveRequest'\nimport { normalizeClientRequestArgs } from './utils/normalizeClientRequestArgs'\nimport { isNodeLikeError } from '../../utils/isNodeLikeError'\nimport { createServerErrorResponse } from '../../utils/responseUtils'\n\nexport class ClientRequestInterceptor extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('client-request-interceptor')\n\n constructor() {\n super(ClientRequestInterceptor.symbol)\n }\n\n protected setup(): void {\n const { get: originalGet, request: originalRequest } = http\n const { get: originalHttpsGet, request: originalHttpsRequest } = https\n\n const onRequest = this.onRequest.bind(this)\n const onResponse = this.onResponse.bind(this)\n\n http.request = new Proxy(http.request, {\n apply: (target, thisArg, args: Parameters<typeof http.request>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'http:',\n args\n )\n const mockAgent = new MockAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n http.get = new Proxy(http.get, {\n apply: (target, thisArg, args: Parameters<typeof http.get>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'http:',\n args\n )\n\n const mockAgent = new MockAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n //\n // HTTPS.\n //\n\n https.request = new Proxy(https.request, {\n apply: (target, thisArg, args: Parameters<typeof https.request>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'https:',\n args\n )\n\n const mockAgent = new MockHttpsAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n https.get = new Proxy(https.get, {\n apply: (target, thisArg, args: Parameters<typeof https.get>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'https:',\n args\n )\n\n const mockAgent = new MockHttpsAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n this.subscriptions.push(() => {\n http.get = originalGet\n http.request = originalRequest\n\n https.get = originalHttpsGet\n https.request = originalHttpsRequest\n })\n }\n\n private onRequest: MockHttpSocketRequestCallback = async ({\n request,\n socket,\n }) => {\n const requestId = Reflect.get(request, kRequestId)\n const { interactiveRequest, requestController } =\n toInteractiveRequest(request)\n\n // TODO: Abstract this bit. We are using it everywhere.\n this.emitter.once('request', ({ requestId: pendingRequestId }) => {\n if (pendingRequestId !== requestId) {\n return\n }\n\n if (requestController.responsePromise.state === 'pending') {\n this.logger.info(\n 'request has not been handled in listeners, executing fail-safe listener...'\n )\n\n requestController.responsePromise.resolve(undefined)\n }\n })\n\n const listenerResult = await until(async () => {\n await emitAsync(this.emitter, 'request', {\n requestId,\n request: interactiveRequest,\n })\n\n return await requestController.responsePromise\n })\n\n if (listenerResult.error) {\n // Treat thrown Responses as mocked responses.\n if (listenerResult.error instanceof Response) {\n socket.respondWith(listenerResult.error)\n return\n }\n\n // Allow mocking Node-like errors.\n if (isNodeLikeError(listenerResult.error)) {\n socket.errorWith(listenerResult.error)\n return\n }\n\n // Emit the \"unhandledException\" event to allow the client\n // to opt-out from the default handling of exceptions\n // as 500 error responses.\n if (this.emitter.listenerCount('unhandledException') > 0) {\n await emitAsync(this.emitter, 'unhandledException', {\n error: listenerResult.error,\n request,\n requestId,\n controller: {\n respondWith: socket.respondWith.bind(socket),\n errorWith: socket.errorWith.bind(socket),\n },\n })\n\n // After the listeners are done, if the socket is\n // not connecting anymore, the response was mocked.\n // If the socket has been destroyed, the error was mocked.\n // Treat both as the result of the listener's call.\n if (!socket.connecting || socket.destroyed) {\n return\n }\n }\n\n // Unhandled exceptions in the request listeners are\n // synonymous to unhandled exceptions on the server.\n // Those are represented as 500 error responses.\n socket.respondWith(createServerErrorResponse(listenerResult.error))\n return\n }\n\n const mockedResponse = listenerResult.data\n\n if (mockedResponse) {\n /**\n * @note The `.respondWith()` method will handle \"Response.error()\".\n * Maybe we should make all interceptors do that?\n */\n socket.respondWith(mockedResponse)\n return\n }\n\n socket.passthrough()\n }\n\n public onResponse: MockHttpSocketResponseCallback = async ({\n requestId,\n request,\n response,\n isMockedResponse,\n }) => {\n // Return the promise to when all the response event listeners\n // are finished.\n return emitAsync(this.emitter, 'response', {\n requestId,\n request,\n response,\n isMockedResponse,\n })\n }\n}\n","import net from 'node:net'\nimport {\n HTTPParser,\n type RequestHeadersCompleteCallback,\n type ResponseHeadersCompleteCallback,\n} from '_http_common'\nimport { IncomingMessage, ServerResponse } from 'node:http'\nimport { Readable } from 'node:stream'\nimport { invariant } from 'outvariant'\nimport { INTERNAL_REQUEST_ID_HEADER_NAME } from '../../Interceptor'\nimport { MockSocket } from '../Socket/MockSocket'\nimport type { NormalizedSocketWriteArgs } from '../Socket/utils/normalizeSocketWriteArgs'\nimport { isPropertyAccessible } from '../../utils/isPropertyAccessible'\nimport { baseUrlFromConnectionOptions } from '../Socket/utils/baseUrlFromConnectionOptions'\nimport { parseRawHeaders } from '../Socket/utils/parseRawHeaders'\nimport { getRawFetchHeaders } from '../../utils/getRawFetchHeaders'\nimport {\n createServerErrorResponse,\n RESPONSE_STATUS_CODES_WITHOUT_BODY,\n} from '../../utils/responseUtils'\nimport { createRequestId } from '../../createRequestId'\n\ntype HttpConnectionOptions = any\n\nexport type MockHttpSocketRequestCallback = (args: {\n requestId: string\n request: Request\n socket: MockHttpSocket\n}) => void\n\nexport type MockHttpSocketResponseCallback = (args: {\n requestId: string\n request: Request\n response: Response\n isMockedResponse: boolean\n socket: MockHttpSocket\n}) => Promise<void>\n\ninterface MockHttpSocketOptions {\n connectionOptions: HttpConnectionOptions\n createConnection: () => net.Socket\n onRequest: MockHttpSocketRequestCallback\n onResponse: MockHttpSocketResponseCallback\n}\n\nexport const kRequestId = Symbol('kRequestId')\n\nexport class MockHttpSocket extends MockSocket {\n private connectionOptions: HttpConnectionOptions\n private createConnection: () => net.Socket\n private baseUrl: URL\n\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n private responseListenersPromise?: Promise<void>\n\n private writeBuffer: Array<NormalizedSocketWriteArgs> = []\n private request?: Request\n private requestParser: HTTPParser<0>\n private requestStream?: Readable\n private shouldKeepAlive?: boolean\n\n private responseType: 'mock' | 'bypassed' = 'bypassed'\n private responseParser: HTTPParser<1>\n private responseStream?: Readable\n\n constructor(options: MockHttpSocketOptions) {\n super({\n write: (chunk, encoding, callback) => {\n this.writeBuffer.push([chunk, encoding, callback])\n\n if (chunk) {\n this.requestParser.execute(\n Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding)\n )\n }\n },\n read: (chunk) => {\n if (chunk !== null) {\n this.responseParser.execute(\n Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n )\n }\n },\n })\n\n this.connectionOptions = options.connectionOptions\n this.createConnection = options.createConnection\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n\n this.baseUrl = baseUrlFromConnectionOptions(this.connectionOptions)\n\n // Request parser.\n this.requestParser = new HTTPParser()\n this.requestParser.initialize(HTTPParser.REQUEST, {})\n this.requestParser[HTTPParser.kOnHeadersComplete] =\n this.onRequestStart.bind(this)\n this.requestParser[HTTPParser.kOnBody] = this.onRequestBody.bind(this)\n this.requestParser[HTTPParser.kOnMessageComplete] =\n this.onRequestEnd.bind(this)\n\n // Response parser.\n this.responseParser = new HTTPParser()\n this.responseParser.initialize(HTTPParser.RESPONSE, {})\n this.responseParser[HTTPParser.kOnHeadersComplete] =\n this.onResponseStart.bind(this)\n this.responseParser[HTTPParser.kOnBody] = this.onResponseBody.bind(this)\n this.responseParser[HTTPParser.kOnMessageComplete] =\n this.onResponseEnd.bind(this)\n\n // Once the socket is finished, nothing can write to it\n // anymore. It has also flushed any buffered chunks.\n this.once('finish', () => this.requestParser.free())\n\n if (this.baseUrl.protocol === 'https:') {\n Reflect.set(this, 'encrypted', true)\n // The server certificate is not the same as a CA\n // passed to the TLS socket connection options.\n Reflect.set(this, 'authorized', false)\n Reflect.set(this, 'getProtocol', () => 'TLSv1.3')\n Reflect.set(this, 'getSession', () => undefined)\n Reflect.set(this, 'isSessionReused', () => false)\n }\n }\n\n public emit(event: string | symbol, ...args: any[]): boolean {\n const emitEvent = super.emit.bind(this, event as any, ...args)\n\n if (this.responseListenersPromise) {\n this.responseListenersPromise.finally(emitEvent)\n return this.listenerCount(event) > 0\n }\n\n return emitEvent()\n }\n\n public destroy(error?: Error | undefined): this {\n // Destroy the response parser when the socket gets destroyed.\n // Normally, we shoud listen to the \"close\" event but it\n // can be suppressed by using the \"emitClose: false\" option.\n this.responseParser.free()\n\n if (error) {\n this.emit('error', error)\n }\n\n return super.destroy(error)\n }\n\n /**\n * Establish this Socket connection as-is and pipe\n * its data/events through this Socket.\n */\n public passthrough(): void {\n if (this.destroyed) {\n return\n }\n\n const socket = this.createConnection()\n\n // If the developer destroys the socket, destroy the original connection.\n this.once('error', (error) => {\n socket.destroy(error)\n })\n\n this.address = socket.address.bind(socket)\n\n // Flush the buffered \"socket.write()\" calls onto\n // the original socket instance (i.e. write request body).\n // Exhaust the \"requestBuffer\" in case this Socket\n // gets reused for different requests.\n let writeArgs: NormalizedSocketWriteArgs | undefined\n let headersWritten = false\n\n while ((writeArgs = this.writeBuffer.shift())) {\n if (writeArgs !== undefined) {\n if (!headersWritten) {\n const [chunk, encoding, callback] = writeArgs\n const chunkString = chunk.toString()\n const chunkBeforeRequestHeaders = chunkString.slice(\n 0,\n chunkString.indexOf('\\r\\n') + 2\n )\n const chunkAfterRequestHeaders = chunkString.slice(\n chunk.indexOf('\\r\\n\\r\\n')\n )\n const requestHeaders =\n getRawFetchHeaders(this.request!.headers) || this.request!.headers\n const requestHeadersString = Array.from(requestHeaders.entries())\n // Skip the internal request ID deduplication header.\n .filter(([name]) => name !== INTERNAL_REQUEST_ID_HEADER_NAME)\n .map(([name, value]) => `${name}: ${value}`)\n .join('\\r\\n')\n\n // Modify the HTTP request message headers\n // to reflect any changes to the request headers\n // from the \"request\" event listener.\n const headersChunk = `${chunkBeforeRequestHeaders}${requestHeadersString}${chunkAfterRequestHeaders}`\n socket.write(headersChunk, encoding, callback)\n headersWritten = true\n continue\n }\n\n socket.write(...writeArgs)\n }\n }\n\n // Forward TLS Socket properties onto this Socket instance\n // in the case of a TLS/SSL connection.\n if (Reflect.get(socket, 'encrypted')) {\n const tlsProperties = [\n 'encrypted',\n 'authorized',\n 'getProtocol',\n 'getSession',\n 'isSessionReused',\n ]\n\n tlsProperties.forEach((propertyName) => {\n Object.defineProperty(this, propertyName, {\n enumerable: true,\n get: () => {\n const value = Reflect.get(socket, propertyName)\n return typeof value === 'function' ? value.bind(socket) : value\n },\n })\n })\n }\n\n socket\n .on('lookup', (...args) => this.emit('lookup', ...args))\n .on('connect', () => {\n this.connecting = socket.connecting\n this.emit('connect')\n })\n .on('secureConnect', () => this.emit('secureConnect'))\n .on('secure', () => this.emit('secure'))\n .on('session', (session) => this.emit('session', session))\n .on('ready', () => this.emit('ready'))\n .on('drain', () => this.emit('drain'))\n .on('data', (chunk) => {\n // Push the original response to this socket\n // so it triggers the HTTP response parser. This unifies\n // the handling pipeline for original and mocked response.\n this.push(chunk)\n })\n .on('error', (error) => {\n Reflect.set(this, '_hadError', Reflect.get(socket, '_hadError'))\n this.emit('error', error)\n })\n .on('resume', () => this.emit('resume'))\n .on('timeout', () => this.emit('timeout'))\n .on('prefinish', () => this.emit('prefinish'))\n .on('finish', () => this.emit('finish'))\n .on('close', (hadError) => this.emit('close', hadError))\n .on('end', () => this.emit('end'))\n }\n\n /**\n * Convert the given Fetch API `Response` instance to an\n * HTTP message and push it to the socket.\n */\n public async respondWith(response: Response): Promise<void> {\n // Ignore the mocked response if the socket has been destroyed\n // (e.g. aborted or timed out),\n if (this.destroyed) {\n return\n }\n\n // Handle \"type: error\" responses.\n if (isPropertyAccessible(response, 'type') && response.type === 'error') {\n this.errorWith(new TypeError('Network error'))\n return\n }\n\n // First, emit all the connection events\n // to emulate a successful connection.\n this.mockConnect()\n this.responseType = 'mock'\n\n // Flush the write buffer to trigger write callbacks\n // if it hasn't been flushed already (e.g. someone started reading request stream).\n this.flushWriteBuffer()\n\n // Create a `ServerResponse` instance to delegate HTTP message parsing,\n // Transfer-Encoding, and other things to Node.js internals.\n const serverResponse = new ServerResponse(new IncomingMessage(this))\n\n /**\n * Assign a mock socket instance to the server response to\n * spy on the response chunk writes. Push the transformed response chunks\n * to this `MockHttpSocket` instance to trigger the \"data\" event.\n * @note Providing the same `MockSocket` instance when creating `ServerResponse`\n * does not have the same effect.\n * @see https://github.com/nodejs/node/blob/10099bb3f7fd97bb9dd9667188426866b3098e07/test/parallel/test-http-server-response-standalone.js#L32\n */\n serverResponse.assignSocket(\n new MockSocket({\n write: (chunk, encoding, callback) => {\n this.push(chunk, encoding)\n callback?.()\n },\n read() {},\n })\n )\n serverResponse.statusCode = response.status\n serverResponse.statusMessage = response.statusText\n\n /**\n * @note Remove the `Connection` and `Date` response headers\n * injected by `ServerResponse` by default. Those are required\n * from the server but the interceptor is NOT technically a server.\n * It's confusing to add response headers that the developer didn't\n * specify themselves. They can always add these if they wish.\n * @see https://www.rfc-editor.org/rfc/rfc9110#field.date\n * @see https://www.rfc-editor.org/rfc/rfc9110#field.connection\n */\n serverResponse.removeHeader('connection')\n serverResponse.removeHeader('date')\n\n // If the developer destroy the socket, gracefully destroy the response.\n this.once('error', () => {\n serverResponse.destroy()\n })\n\n // Get the raw headers stored behind the symbol to preserve name casing.\n const headers = getRawFetchHeaders(response.headers) || response.headers\n for (const [name, value] of headers) {\n serverResponse.setHeader(name, value)\n }\n\n if (response.body) {\n try {\n const reader = response.body.getReader()\n\n while (true) {\n const { done, value } = await reader.read()\n\n if (done) {\n serverResponse.end()\n break\n }\n\n serverResponse.write(value)\n }\n } catch (error) {\n // Coerce response stream errors to 500 responses.\n this.respondWith(createServerErrorResponse(error))\n return\n }\n } else {\n serverResponse.end()\n }\n\n // Close the socket if the connection wasn't marked as keep-alive.\n if (!this.shouldKeepAlive) {\n this.emit('readable')\n\n /**\n * @todo @fixme This is likely a hack.\n * Since we push null to the socket, it never propagates to the\n * parser, and the parser never calls \"onResponseEnd\" to close\n * the response stream. We are closing the stream here manually\n * but that shouldn't be the case.\n */\n this.responseStream?.push(null)\n this.push(null)\n }\n }\n\n /**\n * Close this socket connection with the given error.\n */\n public errorWith(error: Error): void {\n this.destroy(error)\n }\n\n private mockConnect(): void {\n // Calling this method immediately puts the socket\n // into the connected state.\n this.connecting = false\n\n const isIPv6 =\n net.isIPv6(this.connectionOptions.hostname) ||\n this.connectionOptions.family === 6\n const addressInfo = {\n address: isIPv6 ? '::1' : '127.0.0.1',\n family: isIPv6 ? 'IPv6' : 'IPv4',\n port: this.connectionOptions.port,\n }\n // Return fake address information for the socket.\n this.address = () => addressInfo\n this.emit(\n 'lookup',\n null,\n addressInfo.address,\n addressInfo.family === 'IPv6' ? 6 : 4,\n this.connectionOptions.host\n )\n this.emit('connect')\n this.emit('ready')\n\n if (this.baseUrl.protocol === 'https:') {\n this.emit('secure')\n this.emit('secureConnect')\n\n // A single TLS connection is represented by two \"session\" events.\n this.emit(\n 'session',\n this.connectionOptions.session ||\n Buffer.from('mock-session-renegotiate')\n )\n this.emit('session', Buffer.from('mock-session-resume'))\n }\n }\n\n private flushWriteBuffer(): void {\n let args: NormalizedSocketWriteArgs | undefined\n while ((args = this.writeBuffer.shift())) {\n args?.[2]?.()\n }\n }\n\n private onRequestStart: RequestHeadersCompleteCallback = (\n versionMajor,\n versionMinor,\n rawHeaders,\n _,\n path,\n __,\n ___,\n ____,\n shouldKeepAlive\n ) => {\n this.shouldKeepAlive = shouldKeepAlive\n\n const url = new URL(path, this.baseUrl)\n const method = this.connectionOptions.method || 'GET'\n const headers = parseRawHeaders(rawHeaders)\n const canHaveBody = method !== 'GET' && method !== 'HEAD'\n\n // Translate the basic authorization in the URL to the request header.\n // Constructing a Request instance with a URL containing auth is no-op.\n if (url.username || url.password) {\n if (!headers.has('authorization')) {\n headers.set('authorization', `Basic ${url.username}:${url.password}`)\n }\n url.username = ''\n url.password = ''\n }\n\n // Create a new stream for each request.\n // If this Socket is reused for multiple requests,\n // this ensures that each request gets its own stream.\n // One Socket instance can only handle one request at a time.\n if (canHaveBody) {\n this.requestStream = new Readable({\n /**\n * @note Provide the `read()` method so a `Readable` could be\n * used as the actual request body (the stream calls \"read()\").\n * We control the queue in the onRequestBody/End functions.\n */\n read: () => {\n // If the user attempts to read the request body,\n // flush the write buffer to trigger the callbacks.\n // This way, if the request stream ends in the write callback,\n // it will indeed end correctly.\n this.flushWriteBuffer()\n },\n })\n }\n\n const requestId = createRequestId()\n this.request = new Request(url, {\n method,\n headers,\n credentials: 'same-origin',\n // @ts-expect-error Undocumented Fetch property.\n duplex: canHaveBody ? 'half' : undefined,\n body: canHaveBody ? (Readable.toWeb(this.requestStream!) as any) : null,\n })\n\n Reflect.set(this.request, kRequestId, requestId)\n\n // Skip handling the request that's already being handled\n // by another (parent) interceptor. For example, XMLHttpRequest\n // is often implemented via ClientRequest in Node.js (e.g. JSDOM).\n // In that case, XHR interceptor will bubble down to the ClientRequest\n // interceptor. No need to try to handle that request again.\n /**\n * @fixme Stop relying on the \"X-Request-Id\" request header\n * to figure out if one interceptor has been invoked within another.\n * @see https://github.com/mswjs/interceptors/issues/378\n */\n if (this.request.headers.has(INTERNAL_REQUEST_ID_HEADER_NAME)) {\n this.passthrough()\n return\n }\n\n this.onRequest({\n requestId,\n request: this.request,\n socket: this,\n })\n }\n\n private onRequestBody(chunk: Buffer): void {\n invariant(\n this.requestStream,\n 'Failed to write to a request stream: stream does not exist'\n )\n\n this.requestStream.push(chunk)\n }\n\n private onRequestEnd(): void {\n // Request end can be called for requests without body.\n if (this.requestStream) {\n this.requestStream.push(null)\n }\n }\n\n private onResponseStart: ResponseHeadersCompleteCallback = (\n versionMajor,\n versionMinor,\n rawHeaders,\n method,\n url,\n status,\n statusText\n ) => {\n const headers = parseRawHeaders(rawHeaders)\n const canHaveBody = !RESPONSE_STATUS_CODES_WITHOUT_BODY.has(status)\n\n // Similarly, create a new stream for each response.\n if (canHaveBody) {\n this.responseStream = new Readable()\n }\n\n const response = new Response(\n /**\n * @note The Fetch API response instance exposed to the consumer\n * is created over the response stream of the HTTP parser. It is NOT\n * related to the Socket instance. This way, you can read response body\n * in response listener while the Socket instance delays the emission\n * of \"end\" and other events until those response listeners are finished.\n */\n canHaveBody ? (Readable.toWeb(this.responseStream!) as any) : null,\n {\n status,\n statusText,\n headers,\n }\n )\n\n invariant(\n this.request,\n 'Failed to handle a response: request does not exist'\n )\n\n /**\n * @fixme Stop relying on the \"X-Request-Id\" request header\n * to figure out if one interceptor has been invoked within another.\n * @see https://github.com/mswjs/interceptors/issues/378\n */\n if (this.request.headers.has(INTERNAL_REQUEST_ID_HEADER_NAME)) {\n return\n }\n\n this.responseListenersPromise = this.onResponse({\n response,\n isMockedResponse: this.responseType === 'mock',\n requestId: Reflect.get(this.request, kRequestId),\n request: this.request,\n socket: this,\n })\n }\n\n private onResponseBody(chunk: Buffer) {\n invariant(\n this.responseStream,\n 'Failed to write to a response stream: stream does not exist'\n )\n\n this.responseStream.push(chunk)\n }\n\n private onResponseEnd(): void {\n // Response end can be called for responses without body.\n if (this.responseStream) {\n this.responseStream.push(null)\n }\n }\n}\n","import net from 'node:net'\nimport {\n normalizeSocketWriteArgs,\n type WriteArgs,\n type WriteCallback,\n} from './utils/normalizeSocketWriteArgs'\n\nexport interface MockSocketOptions {\n write: (\n chunk: Buffer | string,\n encoding: BufferEncoding | undefined,\n callback?: WriteCallback\n ) => void\n\n read: (chunk: Buffer, encoding: BufferEncoding | undefined) => void\n}\n\nexport class MockSocket extends net.Socket {\n public connecting: boolean\n\n constructor(protected readonly options: MockSocketOptions) {\n super()\n this.connecting = false\n this.connect()\n\n this._final = (callback) => {\n callback(null)\n }\n }\n\n public connect() {\n // The connection will remain pending until\n // the consumer decides to handle it.\n this.connecting = true\n return this\n }\n\n public write(...args: Array<unknown>): boolean {\n const [chunk, encoding, callback] = normalizeSocketWriteArgs(\n args as WriteArgs\n )\n this.options.write(chunk, encoding, callback)\n return true\n }\n\n public end(...args: Array<unknown>) {\n const [chunk, encoding, callback] = normalizeSocketWriteArgs(\n args as WriteArgs\n )\n this.options.write(chunk, encoding, callback)\n\n return super.end.apply(this, args as any)\n }\n\n public push(chunk: any, encoding?: BufferEncoding): boolean {\n this.options.read(chunk, encoding)\n return super.push(chunk, encoding)\n }\n}\n","export type WriteCallback = (error?: Error | null) => void\n\nexport type WriteArgs =\n | [chunk: unknown, callback?: WriteCallback]\n | [chunk: unknown, encoding: BufferEncoding, callback?: WriteCallback]\n\nexport type NormalizedSocketWriteArgs = [\n chunk: any,\n encoding?: BufferEncoding,\n callback?: WriteCallback,\n]\n\n/**\n * Normalizes the arguments provided to the `Writable.prototype.write()`\n * and `Writable.prototype.end()`.\n */\nexport function normalizeSocketWriteArgs(\n args: WriteArgs\n): NormalizedSocketWriteArgs {\n const normalized: NormalizedSocketWriteArgs = [args[0], undefined, undefined]\n\n if (typeof args[1] === 'string') {\n normalized[1] = args[1]\n } else if (typeof args[1] === 'function') {\n normalized[2] = args[1]\n }\n\n if (typeof args[2] === 'function') {\n normalized[2] = args[2]\n }\n\n return normalized\n}\n","export function baseUrlFromConnectionOptions(options: any): URL {\n if ('href' in options) {\n return new URL(options.href)\n }\n\n const protocol = options.port === 443 ? 'https:' : 'http:'\n const host = options.host\n\n const url = new URL(`${protocol}//${host}`)\n\n if (options.port) {\n url.port = options.port.toString()\n }\n\n if (options.path) {\n url.pathname = options.path\n }\n\n if (options.auth) {\n const [username, password] = options.auth.split(':')\n url.username = username\n url.password = password\n }\n\n return url\n}\n","/**\n * Create a Fetch API `Headers` instance from the given raw headers list.\n */\nexport function parseRawHeaders(rawHeaders: Array<string>): Headers {\n const headers = new Headers()\n for (let line = 0; line < rawHeaders.length; line += 2) {\n headers.append(rawHeaders[line], rawHeaders[line + 1])\n }\n return headers\n}\n","/**\n * Returns the value behind the symbol with the given name.\n */\nexport function getValueBySymbol<T>(\n symbolName: string,\n source: object\n): T | undefined {\n const ownSymbols = Object.getOwnPropertySymbols(source)\n\n const symbol = ownSymbols.find((symbol) => {\n return symbol.description === symbolName\n })\n\n if (symbol) {\n return Reflect.get(source, symbol)\n }\n\n return\n}\n","/**\n * Determines if a given value is an instance of object.\n */\nexport function isObject<T>(value: any, loose = false): value is T {\n return loose\n ? Object.prototype.toString.call(value).startsWith('[object ')\n : Object.prototype.toString.call(value) === '[object Object]'\n}\n","import { getValueBySymbol } from './getValueBySymbol'\nimport { isObject } from './isObject'\n\ntype RawHeadersMap = Map<string, string>\ntype HeadersMapHeader = { name: string; value: string }\n\n/**\n * Returns raw headers from the given `Headers` instance.\n * @example\n * const headers = new Headers([\n * ['X-HeadeR-NamE', 'Value']\n * ])\n * getRawFetchHeaders(headers)\n * // { 'X-HeadeR-NamE': 'Value' }\n */\nexport function getRawFetchHeaders(\n headers: Headers\n): RawHeadersMap | undefined {\n const headersList = getValueBySymbol<object>('headers list', headers)\n\n if (!headersList) {\n return\n }\n\n const headersMap = getValueBySymbol<\n Map<string, string> | Map<string, HeadersMapHeader>\n >('headers map', headersList)\n\n /**\n * @note Older versions of Node.js (e.g. 18.8.0) keep headers map\n * as Map<normalizedHeaderName, value> without any means to tap\n * into raw header values. Detect that and return undefined.\n */\n if (!headersMap || !isHeadersMapWithRawHeaderNames(headersMap)) {\n return\n }\n\n // Raw headers is a map of { rawHeaderName: rawHeaderValue }\n const rawHeaders: RawHeadersMap = new Map<string, string>()\n\n headersMap.forEach(({ name, value }) => {\n rawHeaders.set(name, value)\n })\n\n return rawHeaders\n}\n\nfunction isHeadersMapWithRawHeaderNames(\n headersMap: Map<string, string> | Map<string, HeadersMapHeader>\n): headersMap is Map<string, HeadersMapHeader> {\n return Array.from(\n headersMap.values() as Iterable<string | HeadersMapHeader>\n ).every((value) => {\n return isObject<HeadersMapHeader>(value) && 'name' in value\n })\n}\n","import net from 'node:net'\nimport http from 'node:http'\nimport https from 'node:https'\nimport {\n MockHttpSocket,\n type MockHttpSocketRequestCallback,\n type MockHttpSocketResponseCallback,\n} from './MockHttpSocket'\n\ndeclare module 'node:http' {\n interface Agent {\n createConnection(options: any, callback: any): net.Socket\n }\n}\n\ninterface MockAgentOptions {\n customAgent?: http.RequestOptions['agent']\n onRequest: MockHttpSocketRequestCallback\n onResponse: MockHttpSocketResponseCallback\n}\n\nexport class MockAgent extends http.Agent {\n private customAgent?: http.RequestOptions['agent']\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n\n constructor(options: MockAgentOptions) {\n super()\n this.customAgent = options.customAgent\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n }\n\n public createConnection(options: any, callback: any) {\n const createConnection =\n (this.customAgent instanceof http.Agent &&\n this.customAgent.createConnection) ||\n super.createConnection\n\n const socket = new MockHttpSocket({\n connectionOptions: options,\n createConnection: createConnection.bind(this, options, callback),\n onRequest: this.onRequest.bind(this),\n onResponse: this.onResponse.bind(this),\n })\n\n return socket\n }\n}\n\nexport class MockHttpsAgent extends https.Agent {\n private customAgent?: https.RequestOptions['agent']\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n\n constructor(options: MockAgentOptions) {\n super()\n this.customAgent = options.customAgent\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n }\n\n public createConnection(options: any, callback: any) {\n const createConnection =\n (this.customAgent instanceof https.Agent &&\n this.customAgent.createConnection) ||\n super.createConnection\n\n const socket = new MockHttpSocket({\n connectionOptions: options,\n createConnection: createConnection.bind(this, options, callback),\n onRequest: this.onRequest.bind(this),\n onResponse: this.onResponse.bind(this),\n })\n\n return socket\n }\n}\n","import {\n Agent as HttpAgent,\n globalAgent as httpGlobalAgent,\n IncomingMessage,\n} from 'node:http'\nimport {\n RequestOptions,\n Agent as HttpsAgent,\n globalAgent as httpsGlobalAgent,\n} from 'node:https'\nimport {\n /**\n * @note Use the Node.js URL instead of the global URL\n * because environments like JSDOM may override the global,\n * breaking the compatibility with Node.js.\n * @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555\n */\n URL,\n Url as LegacyURL,\n parse as parseUrl,\n} from 'node:url'\nimport { Logger } from '@open-draft/logger'\nimport { getRequestOptionsByUrl } from '../../../utils/getRequestOptionsByUrl'\nimport {\n ResolvedRequestOptions,\n getUrlByRequestOptions,\n} from '../../../utils/getUrlByRequestOptions'\nimport { cloneObject } from '../../../utils/cloneObject'\nimport { isObject } from '../../../utils/isObject'\n\nconst logger = new Logger('http normalizeClientRequestArgs')\n\nexport type HttpRequestCallback = (response: IncomingMessage) => void\n\nexport type ClientRequestArgs =\n // Request without any arguments is also possible.\n | []\n | [string | URL | LegacyURL, HttpRequestCallback?]\n | [string | URL | LegacyURL, RequestOptions, HttpRequestCallback?]\n | [RequestOptions, HttpRequestCallback?]\n\nfunction resolveRequestOptions(\n args: ClientRequestArgs,\n url: URL\n): RequestOptions {\n // Calling `fetch` provides only URL to `ClientRequest`\n // without any `RequestOptions` or callback.\n if (typeof args[1] === 'undefined' || typeof args[1] === 'function') {\n logger.info('request options not provided, deriving from the url', url)\n return getRequestOptionsByUrl(url)\n }\n\n if (args[1]) {\n logger.info('has custom RequestOptions!', args[1])\n const requestOptionsFromUrl = getRequestOptionsByUrl(url)\n\n logger.info('derived RequestOptions from the URL:', requestOptionsFromUrl)\n\n /**\n * Clone the request options to lock their state\n * at the moment they are provided to `ClientRequest`.\n * @see https://github.com/mswjs/interceptors/issues/86\n */\n logger.info('cloning RequestOptions...')\n const clonedRequestOptions = cloneObject(args[1])\n logger.info('successfully cloned RequestOptions!', clonedRequestOptions)\n\n return {\n ...requestOptionsFromUrl,\n ...clonedRequestOptions,\n }\n }\n\n logger.info('using an empty object as request options')\n return {} as RequestOptions\n}\n\n/**\n * Overrides the given `URL` instance with the explicit properties provided\n * on the `RequestOptions` object. The options object takes precedence,\n * and will replace URL properties like \"host\", \"path\", and \"port\", if specified.\n */\nfunction overrideUrlByRequestOptions(url: URL, options: RequestOptions): URL {\n url.host = options.host || url.host\n url.hostname = options.hostname || url.hostname\n url.port = options.port ? options.port.toString() : url.port\n\n if (options.path) {\n const parsedOptionsPath = parseUrl(options.path, false)\n url.pathname = parsedOptionsPath.pathname || ''\n url.search = parsedOptionsPath.search || ''\n }\n\n return url\n}\n\nfunction resolveCallback(\n args: ClientRequestArgs\n): HttpRequestCallback | undefined {\n return typeof args[1] === 'function' ? args[1] : args[2]\n}\n\nexport type NormalizedClientRequestArgs = [\n url: URL,\n options: ResolvedRequestOptions,\n callback?: HttpRequestCallback,\n]\n\n/**\n * Normalizes parameters given to a `http.request` call\n * so it always has a `URL` and `RequestOptions`.\n */\nexport function normalizeClientRequestArgs(\n defaultProtocol: string,\n args: ClientRequestArgs\n): NormalizedClientRequestArgs {\n let url: URL\n let options: ResolvedRequestOptions\n let callback: HttpRequestCallback | undefined\n\n logger.info('arguments', args)\n logger.info('using default protocol:', defaultProtocol)\n\n // Support \"http.request()\" calls without any arguments.\n // That call results in a \"GET http://localhost\" request.\n if (args.length === 0) {\n const url = new URL('http://localhost')\n const options = resolveRequestOptions(args, url)\n return [url, options]\n }\n\n // Convert a url string into a URL instance\n // and derive request options from it.\n if (typeof args[0] === 'string') {\n logger.info('first argument is a location string:', args[0])\n\n url = new URL(args[0])\n logger.info('created a url:', url)\n\n const requestOptionsFromUrl = getRequestOptionsByUrl(url)\n logger.info('request options from url:', requestOptionsFromUrl)\n\n options = resolveRequestOptions(args, url)\n logger.info('resolved request options:', options)\n\n callback = resolveCallback(args)\n }\n // Handle a given URL instance as-is\n // and derive request options from it.\n else if (args[0] instanceof URL) {\n url = args[0]\n logger.info('first argument is a URL:', url)\n\n // Check if the second provided argument is RequestOptions.\n // If it is, check if \"options.path\" was set and rewrite it\n // on the input URL.\n // Do this before resolving options from the URL below\n // to prevent query string from being duplicated in the path.\n if (typeof args[1] !== 'undefined' && isObject<RequestOptions>(args[1])) {\n url = overrideUrlByRequestOptions(url, args[1])\n }\n\n options = resolveRequestOptions(args, url)\n logger.info('derived request options:', options)\n\n callback = resolveCallback(args)\n }\n // Handle a legacy URL instance and re-normalize from either a RequestOptions object\n // or a WHATWG URL.\n else if ('hash' in args[0] && !('method' in args[0])) {\n const [legacyUrl] = args\n logger.info('first argument is a legacy URL:', legacyUrl)\n\n if (legacyUrl.hostname === null) {\n /**\n * We are dealing with a relative url, so use the path as an \"option\" and\n * merge in any existing options, giving priority to exising options -- i.e. a path in any\n * existing options will take precedence over the one contained in the url. This is consistent\n * with the behaviour in ClientRequest.\n * @see https://github.com/nodejs/node/blob/d84f1312915fe45fe0febe888db692c74894c382/lib/_http_client.js#L122\n */\n logger.info('given legacy URL is relative (no hostname)')\n\n return isObject(args[1])\n ? normalizeClientRequestArgs(defaultProtocol, [\n { path: legacyUrl.path, ...args[1] },\n args[2],\n ])\n : normalizeClientRequestArgs(defaultProtocol, [\n { path: legacyUrl.path },\n args[1] as HttpRequestCallback,\n ])\n }\n\n logger.info('given legacy url is absolute')\n\n // We are dealing with an absolute URL, so convert to WHATWG and try again.\n const resolvedUrl = new URL(legacyUrl.href)\n\n return args[1] === undefined\n ? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl])\n : typeof args[1] === 'function'\n ? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl, args[1]])\n : normalizeClientRequestArgs(defaultProtocol, [\n resolvedUrl,\n args[1],\n args[2],\n ])\n }\n // Handle a given \"RequestOptions\" object as-is\n // and derive the URL instance from it.\n else if (isObject(args[0])) {\n options = { ... args[0] as any }\n logger.info('first argument is RequestOptions:', options)\n\n // When handling a \"RequestOptions\" object without an explicit \"protocol\",\n // infer the protocol from the request issuing module (http/https).\n options.protocol = options.protocol || defaultProtocol\n logger.info('normalized request options:', options)\n\n url = getUrlByRequestOptions(options)\n logger.info('created a URL from RequestOptions:', url.href)\n\n callback = resolveCallback(args)\n } else {\n throw new Error(\n `Failed to construct ClientRequest with these parameters: ${args}`\n )\n }\n\n options.protocol = options.protocol || url.protocol\n options.method = options.method || 'GET'\n\n /**\n * Infer a fallback agent from the URL protocol.\n * The interception is done on the \"ClientRequest\" level (\"NodeClientRequest\")\n * and it may miss the correct agent. Always align the agent\n * with the URL protocol, if not provided.\n *\n * @note Respect the \"agent: false\" value.\n */\n if (typeof options.agent === 'undefined') {\n const agent =\n options.protocol === 'https:'\n ? new HttpsAgent({\n rejectUnauthorized: options.rejectUnauthorized,\n })\n : new HttpAgent()\n\n options.agent = agent\n logger.info('resolved fallback agent:', agent)\n }\n\n /**\n * Ensure that the default Agent is always set.\n * This prevents the protocol mismatch for requests with { agent: false },\n * where the global Agent is inferred.\n * @see https://github.com/mswjs/msw/issues/1150\n * @see https://github.com/nodejs/node/blob/418ff70b810f0e7112d48baaa72932a56cfa213b/lib/_http_client.js#L130\n * @see https://github.com/nodejs/node/blob/418ff70b810f0e7112d48baaa72932a56cfa213b/lib/_http_client.js#L157-L159\n */\n if (!options._defaultAgent) {\n logger.info(\n 'has no default agent, setting the default agent for \"%s\"',\n options.protocol\n )\n\n options._defaultAgent =\n options.protocol === 'https:' ? httpsGlobalAgent : httpGlobalAgent\n }\n\n logger.info('successfully resolved url:', url.href)\n logger.info('successfully resolved options:', options)\n logger.info('successfully resolved callback:', callback)\n\n /**\n * @note If the user-provided URL is not a valid URL in Node.js,\n * (e.g. the one provided by the JSDOM polyfills), case it to\n * string. Otherwise, this throws on Node.js incompatibility\n * (`ERR_INVALID_ARG_TYPE` on the connection listener)\n * @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555\n */\n if (!(url instanceof URL)) {\n url = (url as any).toString()\n }\n\n return [url, options, callback]\n}\n","import { RequestOptions } from 'http'\n\n/**\n * Converts a URL instance into the RequestOptions object expected by\n * the `ClientRequest` class.\n * @see https://github.com/nodejs/node/blob/908292cf1f551c614a733d858528ffb13fb3a524/lib/internal/url.js#L1257\n */\nexport function getRequestOptionsByUrl(url: URL): RequestOptions {\n const options: RequestOptions = {\n method: 'GET',\n protocol: url.protocol,\n hostname:\n typeof url.hostname === 'string' && url.hostname.startsWith('[')\n ? url.hostname.slice(1, -1)\n : url.hostname,\n host: url.host,\n path: `${url.pathname}${url.search || ''}`,\n }\n\n if (!!url.port) {\n options.port = Number(url.port)\n }\n\n if (url.username || url.password) {\n options.auth = `${url.username}:${url.password}`\n }\n\n return options\n}\n","import { Agent } from 'http'\nimport { RequestOptions, Agent as HttpsAgent } from 'https'\nimport { Logger } from '@open-draft/logger'\n\nconst logger = new Logger('utils getUrlByRequestOptions')\n\n// Request instance constructed by the \"request\" library\n// has a \"self\" property that has a \"uri\" field. This is\n// reproducible by performing a \"XMLHttpRequest\" request in JSDOM.\nexport interface RequestSelf {\n uri?: URL\n}\n\nexport type ResolvedRequestOptions = RequestOptions & RequestSelf\n\nexport const DEFAULT_PATH = '/'\nconst DEFAULT_PROTOCOL = 'http:'\nconst DEFAULT_HOSTNAME = 'localhost'\nconst SSL_PORT = 443\n\nfunction getAgent(\n options: ResolvedRequestOptions\n): Agent | HttpsAgent | undefined {\n return options.agent instanceof Agent ? options.agent : undefined\n}\n\nfunction getProtocolByRequestOptions(options: ResolvedRequestOptions): string {\n if (options.protocol) {\n return options.protocol\n }\n\n const agent = getAgent(options)\n const agentProtocol = (agent as RequestOptions)?.protocol\n\n if (agentProtocol) {\n return agentProtocol\n }\n\n const port = getPortByRequestOptions(options)\n const isSecureRequest = options.cert || port === SSL_PORT\n\n return isSecureRequest ? 'https:' : options.uri?.protocol || DEFAULT_PROTOCOL\n}\n\nfunction getPortByRequestOptions(\n options: ResolvedRequestOptions\n): number | undefined {\n // Use the explicitly provided port.\n if (options.port) {\n return Number(options.port)\n }\n\n // Otherwise, try to resolve port from the agent.\n const agent = getAgent(options)\n\n if ((agent as HttpsAgent)?.options.port) {\n return Number((agent as HttpsAgent).options.port)\n }\n\n if ((agent as RequestOptions)?.defaultPort) {\n return Number((agent as RequestOptions).defaultPort)\n }\n\n // Lastly, return undefined indicating that the port\n // must inferred from the protocol. Do not infer it here.\n return undefined\n}\n\ninterface RequestAuth {\n username: string\n password: string\n}\n\nfunction getAuthByRequestOptions(\n options: ResolvedRequestOptions\n): RequestAuth | undefined {\n if (options.auth) {\n const [username, password] = options.auth.split(':')\n return { username, password }\n }\n}\n\n/**\n * Returns true if host looks like an IPv6 address without surrounding brackets\n * It assumes any host containing `:` is definitely not IPv4 and probably IPv6,\n * but note that this could include invalid IPv6 addresses as well.\n */\nfunction isRawIPv6Address(host: string): boolean {\n return host.includes(':') && !host.startsWith('[') && !host.endsWith(']')\n}\n\nfunction getHostname(options: ResolvedRequestOptions): string | undefined {\n let host = options.hostname || options.host\n\n if (host) {\n if (isRawIPv6Address(host)) {\n host = `[${host}]`\n }\n\n // Check the presence of the port, and if it's present,\n // remove it from the host, returning a hostname.\n return new URL(`http://${host}`).hostname\n }\n\n return DEFAULT_HOSTNAME\n}\n\n/**\n * Creates a `URL` instance from a given `RequestOptions` object.\n */\nexport function getUrlByRequestOptions(options: ResolvedRequestOptions): URL {\n logger.info('request options', options)\n\n if (options.uri) {\n logger.info(\n 'constructing url from explicitly provided \"options.uri\": %s',\n options.uri\n )\n return new URL(options.uri.href)\n }\n\n logger.info('figuring out url from request options...')\n\n const protocol = getProtocolByRequestOptions(options)\n logger.info('protocol', protocol)\n\n const port = getPortByRequestOptions(options)\n logger.info('port', port)\n\n const hostname = getHostname(options)\n logger.info('hostname', hostname)\n\n const path = options.path || DEFAULT_PATH\n logger.info('path', path)\n\n const credentials = getAuthByRequestOptions(options)\n logger.info('credentials', credentials)\n\n const authString = credentials\n ? `${credentials.username}:${credentials.password}@`\n : ''\n logger.info('auth string:', authString)\n\n const portString = typeof port !== 'undefined' ? `:${port}` : ''\n const url = new URL(`${protocol}//${hostname}${portString}${path}`)\n url.username = credentials?.username || ''\n url.password = credentials?.password || ''\n\n logger.info('created url:', url)\n\n return url\n}\n","import { Logger } from '@open-draft/logger'\n\nconst logger = new Logger('cloneObject')\n\nfunction isPlainObject(obj?: Record<string, any>): boolean {\n logger.info('is plain object?', obj)\n\n if (obj == null || !obj.constructor?.name) {\n logger.info('given object is undefined, not a plain object...')\n return false\n }\n\n logger.info('checking the object constructor:', obj.constructor.name)\n return obj.constructor.name === 'Object'\n}\n\nexport function cloneObject<ObjectType extends Record<string, any>>(\n obj: ObjectType\n): ObjectType {\n logger.info('cloning object:', obj)\n\n const enumerableProperties = Object.entries(obj).reduce<Record<string, any>>(\n (acc, [key, value]) => {\n logger.info('analyzing key-value pair:', key, value)\n\n // Recursively clone only plain objects, omitting class instances.\n acc[key] = isPlainObject(value) ? cloneObject(value) : value\n return acc\n },\n {}\n )\n\n return isPlainObject(obj)\n ? enumerableProperties\n : Object.assign(Object.getPrototypeOf(obj), enumerableProperties)\n}\n","export function isNodeLikeError(\n error: unknown\n): error is NodeJS.ErrnoException {\n if (error == null) {\n return false\n }\n\n if (!(error instanceof Error)) {\n return false\n }\n\n return 'code' in error && 'errno' in error\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Interceptor.ts","../../src/createRequestId.ts","../../src/utils/isPropertyAccessible.ts","../../src/utils/responseUtils.ts"],"names":["InterceptorReadyState"],"mappings":"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","sourcesContent":["import { Logger } from '@open-draft/logger'\nimport { Emitter, Listener } from 'strict-event-emitter'\n\nexport type InterceptorEventMap = Record<string, any>\nexport type InterceptorSubscription = () => void\n\n/**\n * Request header name to detect when a single request\n * is being handled by nested interceptors (XHR -> ClientRequest).\n * Obscure by design to prevent collisions with user-defined headers.\n * Ideally, come up with the Interceptor-level mechanism for this.\n * @see https://github.com/mswjs/interceptors/issues/378\n */\nexport const INTERNAL_REQUEST_ID_HEADER_NAME =\n 'x-interceptors-internal-request-id'\n\nexport function getGlobalSymbol<V>(symbol: Symbol): V | undefined {\n return (\n // @ts-ignore https://github.com/Microsoft/TypeScript/issues/24587\n globalThis[symbol] || undefined\n )\n}\n\nfunction setGlobalSymbol(symbol: Symbol, value: any): void {\n // @ts-ignore\n globalThis[symbol] = value\n}\n\nexport function deleteGlobalSymbol(symbol: Symbol): void {\n // @ts-ignore\n delete globalThis[symbol]\n}\n\nexport enum InterceptorReadyState {\n INACTIVE = 'INACTIVE',\n APPLYING = 'APPLYING',\n APPLIED = 'APPLIED',\n DISPOSING = 'DISPOSING',\n DISPOSED = 'DISPOSED',\n}\n\nexport type ExtractEventNames<Events extends Record<string, any>> =\n Events extends Record<infer EventName, any> ? EventName : never\n\nexport class Interceptor<Events extends InterceptorEventMap> {\n protected emitter: Emitter<Events>\n protected subscriptions: Array<InterceptorSubscription>\n protected logger: Logger\n\n public readyState: InterceptorReadyState\n\n constructor(private readonly symbol: symbol) {\n this.readyState = InterceptorReadyState.INACTIVE\n\n this.emitter = new Emitter()\n this.subscriptions = []\n this.logger = new Logger(symbol.description!)\n\n // Do not limit the maximum number of listeners\n // so not to limit the maximum amount of parallel events emitted.\n this.emitter.setMaxListeners(0)\n\n this.logger.info('constructing the interceptor...')\n }\n\n /**\n * Determine if this interceptor can be applied\n * in the current environment.\n */\n protected checkEnvironment(): boolean {\n return true\n }\n\n /**\n * Apply this interceptor to the current process.\n * Returns an already running interceptor instance if it's present.\n */\n public apply(): void {\n const logger = this.logger.extend('apply')\n logger.info('applying the interceptor...')\n\n if (this.readyState === InterceptorReadyState.APPLIED) {\n logger.info('intercepted already applied!')\n return\n }\n\n const shouldApply = this.checkEnvironment()\n\n if (!shouldApply) {\n logger.info('the interceptor cannot be applied in this environment!')\n return\n }\n\n this.readyState = InterceptorReadyState.APPLYING\n\n // Whenever applying a new interceptor, check if it hasn't been applied already.\n // This enables to apply the same interceptor multiple times, for example from a different\n // interceptor, only proxying events but keeping the stubs in a single place.\n const runningInstance = this.getInstance()\n\n if (runningInstance) {\n logger.info('found a running instance, reusing...')\n\n // Proxy any listeners you set on this instance to the running instance.\n this.on = (event, listener) => {\n logger.info('proxying the \"%s\" listener', event)\n\n // Add listeners to the running instance so they appear\n // at the top of the event listeners list and are executed first.\n runningInstance.emitter.addListener(event, listener)\n\n // Ensure that once this interceptor instance is disposed,\n // it removes all listeners it has appended to the running interceptor instance.\n this.subscriptions.push(() => {\n runningInstance.emitter.removeListener(event, listener)\n logger.info('removed proxied \"%s\" listener!', event)\n })\n\n return this\n }\n\n this.readyState = InterceptorReadyState.APPLIED\n\n return\n }\n\n logger.info('no running instance found, setting up a new instance...')\n\n // Setup the interceptor.\n this.setup()\n\n // Store the newly applied interceptor instance globally.\n this.setInstance()\n\n this.readyState = InterceptorReadyState.APPLIED\n }\n\n /**\n * Setup the module augments and stubs necessary for this interceptor.\n * This method is not run if there's a running interceptor instance\n * to prevent instantiating an interceptor multiple times.\n */\n protected setup(): void {}\n\n /**\n * Listen to the interceptor's public events.\n */\n public on<EventName extends ExtractEventNames<Events>>(\n event: EventName,\n listener: Listener<Events[EventName]>\n ): this {\n const logger = this.logger.extend('on')\n\n if (\n this.readyState === InterceptorReadyState.DISPOSING ||\n this.readyState === InterceptorReadyState.DISPOSED\n ) {\n logger.info('cannot listen to events, already disposed!')\n return this\n }\n\n logger.info('adding \"%s\" event listener:', event, listener)\n\n this.emitter.on(event, listener)\n return this\n }\n\n public once<EventName extends ExtractEventNames<Events>>(\n event: EventName,\n listener: Listener<Events[EventName]>\n ): this {\n this.emitter.once(event, listener)\n return this\n }\n\n public off<EventName extends ExtractEventNames<Events>>(\n event: EventName,\n listener: Listener<Events[EventName]>\n ): this {\n this.emitter.off(event, listener)\n return this\n }\n\n public removeAllListeners<EventName extends ExtractEventNames<Events>>(\n event?: EventName\n ): this {\n this.emitter.removeAllListeners(event)\n return this\n }\n\n /**\n * Disposes of any side-effects this interceptor has introduced.\n */\n public dispose(): void {\n const logger = this.logger.extend('dispose')\n\n if (this.readyState === InterceptorReadyState.DISPOSED) {\n logger.info('cannot dispose, already disposed!')\n return\n }\n\n logger.info('disposing the interceptor...')\n this.readyState = InterceptorReadyState.DISPOSING\n\n if (!this.getInstance()) {\n logger.info('no interceptors running, skipping dispose...')\n return\n }\n\n // Delete the global symbol as soon as possible,\n // indicating that the interceptor is no longer running.\n this.clearInstance()\n\n logger.info('global symbol deleted:', getGlobalSymbol(this.symbol))\n\n if (this.subscriptions.length > 0) {\n logger.info('disposing of %d subscriptions...', this.subscriptions.length)\n\n for (const dispose of this.subscriptions) {\n dispose()\n }\n\n this.subscriptions = []\n\n logger.info('disposed of all subscriptions!', this.subscriptions.length)\n }\n\n this.emitter.removeAllListeners()\n logger.info('destroyed the listener!')\n\n this.readyState = InterceptorReadyState.DISPOSED\n }\n\n private getInstance(): this | undefined {\n const instance = getGlobalSymbol<this>(this.symbol)\n this.logger.info('retrieved global instance:', instance?.constructor?.name)\n return instance\n }\n\n private setInstance(): void {\n setGlobalSymbol(this.symbol, this)\n this.logger.info('set global instance!', this.symbol.description)\n }\n\n private clearInstance(): void {\n deleteGlobalSymbol(this.symbol)\n this.logger.info('cleared global instance!', this.symbol.description)\n }\n}\n","/**\n * Generate a random ID string to represent a request.\n * @example\n * createRequestId()\n * // \"f774b6c9c600f\"\n */\nexport function createRequestId(): string {\n return Math.random().toString(16).slice(2)\n}\n","/**\n * A function that validates if property access is possible on an object\n * without throwing. It returns `true` if the property access is possible\n * and `false` otherwise.\n *\n * Environments like miniflare will throw on property access on certain objects\n * like Request and Response, for unimplemented properties.\n */\nexport function isPropertyAccessible<Obj extends Record<string, any>>(\n obj: Obj,\n key: keyof Obj\n) {\n try {\n obj[key]\n return true\n } catch {\n return false\n }\n}\n","import { isPropertyAccessible } from './isPropertyAccessible'\n\n/**\n * Response status codes for responses that cannot have body.\n * @see https://fetch.spec.whatwg.org/#statuses\n */\nexport const RESPONSE_STATUS_CODES_WITHOUT_BODY = new Set([\n 101, 103, 204, 205, 304,\n])\n\n/**\n * Returns a boolean indicating whether the given response status\n * code represents a response that cannot have a body.\n */\nexport function isResponseWithoutBody(status: number): boolean {\n return RESPONSE_STATUS_CODES_WITHOUT_BODY.has(status)\n}\n\n/**\n * Creates a generic 500 Unhandled Exception response.\n */\nexport function createServerErrorResponse(body: unknown): Response {\n return new Response(\n JSON.stringify(\n body instanceof Error\n ? {\n name: body.name,\n message: body.message,\n stack: body.stack,\n }\n : body\n ),\n {\n status: 500,\n statusText: 'Unhandled Exception',\n headers: {\n 'Content-Type': 'application/json',\n },\n }\n )\n}\n\n/**\n * Checks if the given response is a `Response.error()`.\n *\n * @note Some environments, like Miniflare (Cloudflare) do not\n * implement the \"Response.type\" property and throw on its access.\n * Safely check if we can access \"type\" on \"Response\" before continuing.\n * @see https://github.com/mswjs/msw/issues/1834\n */\nexport function isResponseError(\n response: Response\n): response is Response & { type: 'error' } {\n return isPropertyAccessible(response, 'type') && response.type === 'error'\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/interceptors/XMLHttpRequest/index.ts","../../src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts","../../src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts","../../src/interceptors/XMLHttpRequest/utils/concatArrayBuffer.ts","../../src/interceptors/XMLHttpRequest/polyfills/EventPolyfill.ts","../../src/interceptors/XMLHttpRequest/polyfills/ProgressEventPolyfill.ts","../../src/interceptors/XMLHttpRequest/utils/createEvent.ts","../../src/utils/findPropertySource.ts","../../src/utils/createProxy.ts","../../src/interceptors/XMLHttpRequest/utils/isDomParserSupportedType.ts","../../src/utils/parseJson.ts","../../src/interceptors/XMLHttpRequest/utils/createResponse.ts"],"sourcesContent":["import { invariant } from 'outvariant'\nimport { Emitter } from 'strict-event-emitter'\nimport { HttpRequestEventMap, IS_PATCHED_MODULE } from '../../glossary'\nimport { InteractiveRequest } from '../../utils/toInteractiveRequest'\nimport { Interceptor } from '../../Interceptor'\nimport { createXMLHttpRequestProxy } from './XMLHttpRequestProxy'\n\nexport type XMLHttpRequestEventListener = (args: {\n request: InteractiveRequest\n requestId: string\n}) => Promise<void> | void\n\nexport type XMLHttpRequestEmitter = Emitter<HttpRequestEventMap>\n\nexport class XMLHttpRequestInterceptor extends Interceptor<HttpRequestEventMap> {\n static interceptorSymbol = Symbol('xhr')\n\n constructor() {\n super(XMLHttpRequestInterceptor.interceptorSymbol)\n }\n\n protected checkEnvironment() {\n return typeof globalThis.XMLHttpRequest !== 'undefined'\n }\n\n protected setup() {\n const logger = this.logger.extend('setup')\n\n logger.info('patching \"XMLHttpRequest\" module...')\n\n const PureXMLHttpRequest = globalThis.XMLHttpRequest\n\n invariant(\n !(PureXMLHttpRequest as any)[IS_PATCHED_MODULE],\n 'Failed to patch the \"XMLHttpRequest\" module: already patched.'\n )\n\n globalThis.XMLHttpRequest = createXMLHttpRequestProxy({\n emitter: this.emitter,\n logger: this.logger,\n })\n\n logger.info(\n 'native \"XMLHttpRequest\" module patched!',\n globalThis.XMLHttpRequest.name\n )\n\n Object.defineProperty(globalThis.XMLHttpRequest, IS_PATCHED_MODULE, {\n enumerable: true,\n configurable: true,\n value: true,\n })\n\n this.subscriptions.push(() => {\n Object.defineProperty(globalThis.XMLHttpRequest, IS_PATCHED_MODULE, {\n value: undefined,\n })\n\n globalThis.XMLHttpRequest = PureXMLHttpRequest\n logger.info(\n 'native \"XMLHttpRequest\" module restored!',\n globalThis.XMLHttpRequest.name\n )\n })\n }\n}\n","import { until } from '@open-draft/until'\nimport type { Logger } from '@open-draft/logger'\nimport { XMLHttpRequestEmitter } from '.'\nimport { toInteractiveRequest } from '../../utils/toInteractiveRequest'\nimport { emitAsync } from '../../utils/emitAsync'\nimport { XMLHttpRequestController } from './XMLHttpRequestController'\nimport {\n createServerErrorResponse,\n isResponseError,\n} from '../../utils/responseUtils'\n\nexport interface XMLHttpRequestProxyOptions {\n emitter: XMLHttpRequestEmitter\n logger: Logger\n}\n\n/**\n * Create a proxied `XMLHttpRequest` class.\n * The proxied class establishes spies on certain methods,\n * allowing us to intercept requests and respond to them.\n */\nexport function createXMLHttpRequestProxy({\n emitter,\n logger,\n}: XMLHttpRequestProxyOptions) {\n const XMLHttpRequestProxy = new Proxy(globalThis.XMLHttpRequest, {\n construct(target, args, newTarget) {\n logger.info('constructed new XMLHttpRequest')\n\n const originalRequest = Reflect.construct(\n target,\n args,\n newTarget\n ) as XMLHttpRequest\n\n /**\n * @note Forward prototype descriptors onto the proxied object.\n * XMLHttpRequest is implemented in JSDOM in a way that assigns\n * a bunch of descriptors, like \"set responseType()\" on the prototype.\n * With this propagation, we make sure that those descriptors trigger\n * when the user operates with the proxied request instance.\n */\n const prototypeDescriptors = Object.getOwnPropertyDescriptors(\n target.prototype\n )\n for (const propertyName in prototypeDescriptors) {\n Reflect.defineProperty(\n originalRequest,\n propertyName,\n prototypeDescriptors[propertyName]\n )\n }\n\n const xhrRequestController = new XMLHttpRequestController(\n originalRequest,\n logger\n )\n\n xhrRequestController.onRequest = async function ({ request, requestId }) {\n const { interactiveRequest, requestController } =\n toInteractiveRequest(request)\n\n this.logger.info('awaiting mocked response...')\n\n emitter.once('request', ({ requestId: pendingRequestId }) => {\n if (pendingRequestId !== requestId) {\n return\n }\n\n if (requestController.responsePromise.state === 'pending') {\n requestController.respondWith(undefined)\n }\n })\n\n const resolverResult = await until(async () => {\n this.logger.info(\n 'emitting the \"request\" event for %s listener(s)...',\n emitter.listenerCount('request')\n )\n\n await emitAsync(emitter, 'request', {\n request: interactiveRequest,\n requestId,\n })\n\n this.logger.info('all \"request\" listeners settled!')\n\n const mockedResponse = await requestController.responsePromise\n\n this.logger.info('event.respondWith called with:', mockedResponse)\n\n return mockedResponse\n })\n\n if (resolverResult.error) {\n this.logger.info(\n 'request listener threw an exception, aborting request...',\n resolverResult.error\n )\n\n // Treat thrown Responses as mocked responses.\n if (resolverResult.error instanceof Response) {\n if (isResponseError(resolverResult.error)) {\n xhrRequestController.errorWith(new TypeError('Network error'))\n } else {\n this.respondWith(resolverResult.error)\n }\n\n return\n }\n\n if (emitter.listenerCount('unhandledException') > 0) {\n // Emit the \"unhandledException\" event so the client can opt-out\n // from the default exception handling (producing 500 error responses).\n await emitAsync(emitter, 'unhandledException', {\n error: resolverResult.error,\n request,\n requestId,\n controller: {\n respondWith:\n xhrRequestController.respondWith.bind(xhrRequestController),\n errorWith:\n xhrRequestController.errorWith.bind(xhrRequestController),\n },\n })\n\n // If any of the \"unhandledException\" listeners handled the request,\n // do nothing. Note that mocked responses will dispatch\n // HEADERS_RECEIVED (2), then LOADING (3), and DONE (4) can take\n // time as the mocked response body finishes streaming.\n if (originalRequest.readyState > XMLHttpRequest.OPENED) {\n return\n }\n }\n\n // Unhandled exceptions in the request listeners are\n // synonymous to unhandled exceptions on the server.\n // Those are represented as 500 error responses.\n xhrRequestController.respondWith(\n createServerErrorResponse(resolverResult.error)\n )\n\n return\n }\n\n const mockedResponse = resolverResult.data\n\n if (typeof mockedResponse !== 'undefined') {\n this.logger.info(\n 'received mocked response: %d %s',\n mockedResponse.status,\n mockedResponse.statusText\n )\n\n if (isResponseError(mockedResponse)) {\n this.logger.info(\n 'received a network error response, rejecting the request promise...'\n )\n\n xhrRequestController.errorWith(new TypeError('Network error'))\n return\n }\n\n return xhrRequestController.respondWith(mockedResponse)\n }\n\n this.logger.info(\n 'no mocked response received, performing request as-is...'\n )\n }\n\n xhrRequestController.onResponse = async function ({\n response,\n isMockedResponse,\n request,\n requestId,\n }) {\n this.logger.info(\n 'emitting the \"response\" event for %s listener(s)...',\n emitter.listenerCount('response')\n )\n\n emitter.emit('response', {\n response,\n isMockedResponse,\n request,\n requestId,\n })\n }\n\n // Return the proxied request from the controller\n // so that the controller can react to the consumer's interactions\n // with this request (opening/sending/etc).\n return xhrRequestController.request\n },\n })\n\n return XMLHttpRequestProxy\n}\n","import { invariant } from 'outvariant'\nimport { isNodeProcess } from 'is-node-process'\nimport type { Logger } from '@open-draft/logger'\nimport { concatArrayBuffer } from './utils/concatArrayBuffer'\nimport { createEvent } from './utils/createEvent'\nimport {\n decodeBuffer,\n encodeBuffer,\n toArrayBuffer,\n} from '../../utils/bufferUtils'\nimport { createProxy } from '../../utils/createProxy'\nimport { isDomParserSupportedType } from './utils/isDomParserSupportedType'\nimport { parseJson } from '../../utils/parseJson'\nimport { createResponse } from './utils/createResponse'\nimport { INTERNAL_REQUEST_ID_HEADER_NAME } from '../../Interceptor'\nimport { createRequestId } from '../../createRequestId'\n\nconst IS_MOCKED_RESPONSE = Symbol('isMockedResponse')\nconst IS_NODE = isNodeProcess()\n\n/**\n * An `XMLHttpRequest` instance controller that allows us\n * to handle any given request instance (e.g. responding to it).\n */\nexport class XMLHttpRequestController {\n public request: XMLHttpRequest\n public requestId: string\n public onRequest?: (\n this: XMLHttpRequestController,\n args: {\n request: Request\n requestId: string\n }\n ) => Promise<void>\n public onResponse?: (\n this: XMLHttpRequestController,\n args: {\n response: Response\n isMockedResponse: boolean\n request: Request\n requestId: string\n }\n ) => void\n\n private method: string = 'GET'\n private url: URL = null as any\n private requestHeaders: Headers\n private requestBody?: XMLHttpRequestBodyInit | Document | null\n private responseBuffer: Uint8Array\n private events: Map<keyof XMLHttpRequestEventTargetEventMap, Array<Function>>\n\n constructor(readonly initialRequest: XMLHttpRequest, public logger: Logger) {\n this.events = new Map()\n this.requestId = createRequestId()\n this.requestHeaders = new Headers()\n this.responseBuffer = new Uint8Array()\n\n this.request = createProxy(initialRequest, {\n setProperty: ([propertyName, nextValue], invoke) => {\n switch (propertyName) {\n case 'ontimeout': {\n const eventName = propertyName.slice(\n 2\n ) as keyof XMLHttpRequestEventTargetEventMap\n\n /**\n * @note Proxy callbacks to event listeners because JSDOM has trouble\n * translating these properties to callbacks. It seemed to be operating\n * on events exclusively.\n */\n this.request.addEventListener(eventName, nextValue as any)\n\n return invoke()\n }\n\n default: {\n return invoke()\n }\n }\n },\n methodCall: ([methodName, args], invoke) => {\n switch (methodName) {\n case 'open': {\n const [method, url] = args as [string, string | undefined]\n\n if (typeof url === 'undefined') {\n this.method = 'GET'\n this.url = toAbsoluteUrl(method)\n } else {\n this.method = method\n this.url = toAbsoluteUrl(url)\n }\n\n this.logger = this.logger.extend(`${this.method} ${this.url.href}`)\n this.logger.info('open', this.method, this.url.href)\n\n return invoke()\n }\n\n case 'addEventListener': {\n const [eventName, listener] = args as [\n keyof XMLHttpRequestEventTargetEventMap,\n Function\n ]\n\n this.registerEvent(eventName, listener)\n this.logger.info('addEventListener', eventName, listener)\n\n return invoke()\n }\n\n case 'setRequestHeader': {\n const [name, value] = args as [string, string]\n this.requestHeaders.set(name, value)\n\n this.logger.info('setRequestHeader', name, value)\n\n return invoke()\n }\n\n case 'send': {\n const [body] = args as [\n body?: XMLHttpRequestBodyInit | Document | null\n ]\n\n if (body != null) {\n this.requestBody =\n typeof body === 'string' ? encodeBuffer(body) : body\n }\n\n this.request.addEventListener('load', () => {\n if (typeof this.onResponse !== 'undefined') {\n // Create a Fetch API Response representation of whichever\n // response this XMLHttpRequest received. Note those may\n // be either a mocked and the original response.\n const fetchResponse = createResponse(\n this.request,\n /**\n * The `response` property is the right way to read\n * the ambiguous response body, as the request's \"responseType\" may differ.\n * @see https://xhr.spec.whatwg.org/#the-response-attribute\n */\n this.request.response\n )\n\n // Notify the consumer about the response.\n this.onResponse.call(this, {\n response: fetchResponse,\n isMockedResponse: IS_MOCKED_RESPONSE in this.request,\n request: fetchRequest,\n requestId: this.requestId!,\n })\n }\n })\n\n // Delegate request handling to the consumer.\n const fetchRequest = this.toFetchApiRequest()\n const onceRequestSettled =\n this.onRequest?.call(this, {\n request: fetchRequest,\n requestId: this.requestId!,\n }) || Promise.resolve()\n\n onceRequestSettled.finally(() => {\n // If the consumer didn't handle the request perform it as-is.\n // Note that the request may not yet be DONE and may, in fact,\n // be LOADING while the \"respondWith\" method does its magic.\n if (this.request.readyState < this.request.LOADING) {\n this.logger.info(\n 'request callback settled but request has not been handled (readystate %d), performing as-is...',\n this.request.readyState\n )\n\n /**\n * @note Set the intercepted request ID on the original request in Node.js\n * so that if it triggers any other interceptors, they don't attempt\n * to process it once again.\n *\n * For instance, XMLHttpRequest is often implemented via \"http.ClientRequest\"\n * and we don't want for both XHR and ClientRequest interceptors to\n * handle the same request at the same time (e.g. emit the \"response\" event twice).\n */\n if (IS_NODE) {\n this.request.setRequestHeader(\n INTERNAL_REQUEST_ID_HEADER_NAME,\n this.requestId!\n )\n }\n\n return invoke()\n }\n })\n\n break\n }\n\n default: {\n return invoke()\n }\n }\n },\n })\n }\n\n private registerEvent(\n eventName: keyof XMLHttpRequestEventTargetEventMap,\n listener: Function\n ): void {\n const prevEvents = this.events.get(eventName) || []\n const nextEvents = prevEvents.concat(listener)\n this.events.set(eventName, nextEvents)\n\n this.logger.info('registered event \"%s\"', eventName, listener)\n }\n\n /**\n * Responds to the current request with the given\n * Fetch API `Response` instance.\n */\n public respondWith(response: Response): void {\n this.logger.info(\n 'responding with a mocked response: %d %s',\n response.status,\n response.statusText\n )\n\n /**\n * @note Since `XMLHttpRequestController` delegates the handling of the responses\n * to the \"load\" event listener that doesn't distinguish between the mocked and original\n * responses, mark the request that had a mocked response with a corresponding symbol.\n */\n define(this.request, IS_MOCKED_RESPONSE, true)\n\n define(this.request, 'status', response.status)\n define(this.request, 'statusText', response.statusText)\n define(this.request, 'responseURL', this.url.href)\n\n this.request.getResponseHeader = new Proxy(this.request.getResponseHeader, {\n apply: (_, __, args: [name: string]) => {\n this.logger.info('getResponseHeader', args[0])\n\n if (this.request.readyState < this.request.HEADERS_RECEIVED) {\n this.logger.info('headers not received yet, returning null')\n\n // Headers not received yet, nothing to return.\n return null\n }\n\n const headerValue = response.headers.get(args[0])\n this.logger.info(\n 'resolved response header \"%s\" to',\n args[0],\n headerValue\n )\n\n return headerValue\n },\n })\n\n this.request.getAllResponseHeaders = new Proxy(\n this.request.getAllResponseHeaders,\n {\n apply: () => {\n this.logger.info('getAllResponseHeaders')\n\n if (this.request.readyState < this.request.HEADERS_RECEIVED) {\n this.logger.info('headers not received yet, returning empty string')\n\n // Headers not received yet, nothing to return.\n return ''\n }\n\n const headersList = Array.from(response.headers.entries())\n const allHeaders = headersList\n .map(([headerName, headerValue]) => {\n return `${headerName}: ${headerValue}`\n })\n .join('\\r\\n')\n\n this.logger.info('resolved all response headers to', allHeaders)\n\n return allHeaders\n },\n }\n )\n\n // Update the response getters to resolve against the mocked response.\n Object.defineProperties(this.request, {\n response: {\n enumerable: true,\n configurable: false,\n get: () => this.response,\n },\n responseText: {\n enumerable: true,\n configurable: false,\n get: () => this.responseText,\n },\n responseXML: {\n enumerable: true,\n configurable: false,\n get: () => this.responseXML,\n },\n })\n\n const totalResponseBodyLength = response.headers.has('Content-Length')\n ? Number(response.headers.get('Content-Length'))\n : /**\n * @todo Infer the response body length from the response body.\n */\n undefined\n\n this.logger.info('calculated response body length', totalResponseBodyLength)\n\n this.trigger('loadstart', {\n loaded: 0,\n total: totalResponseBodyLength,\n })\n\n this.setReadyState(this.request.HEADERS_RECEIVED)\n this.setReadyState(this.request.LOADING)\n\n const finalizeResponse = () => {\n this.logger.info('finalizing the mocked response...')\n\n this.setReadyState(this.request.DONE)\n\n this.trigger('load', {\n loaded: this.responseBuffer.byteLength,\n total: totalResponseBodyLength,\n })\n\n this.trigger('loadend', {\n loaded: this.responseBuffer.byteLength,\n total: totalResponseBodyLength,\n })\n }\n\n if (response.body) {\n this.logger.info('mocked response has body, streaming...')\n\n const reader = response.body.getReader()\n\n const readNextResponseBodyChunk = async () => {\n const { value, done } = await reader.read()\n\n if (done) {\n this.logger.info('response body stream done!')\n finalizeResponse()\n return\n }\n\n if (value) {\n this.logger.info('read response body chunk:', value)\n this.responseBuffer = concatArrayBuffer(this.responseBuffer, value)\n\n this.trigger('progress', {\n loaded: this.responseBuffer.byteLength,\n total: totalResponseBodyLength,\n })\n }\n\n readNextResponseBodyChunk()\n }\n\n readNextResponseBodyChunk()\n } else {\n finalizeResponse()\n }\n }\n\n private responseBufferToText(): string {\n return decodeBuffer(this.responseBuffer)\n }\n\n get response(): unknown {\n this.logger.info(\n 'getResponse (responseType: %s)',\n this.request.responseType\n )\n\n if (this.request.readyState !== this.request.DONE) {\n return null\n }\n\n switch (this.request.responseType) {\n case 'json': {\n const responseJson = parseJson(this.responseBufferToText())\n this.logger.info('resolved response JSON', responseJson)\n\n return responseJson\n }\n\n case 'arraybuffer': {\n const arrayBuffer = toArrayBuffer(this.responseBuffer)\n this.logger.info('resolved response ArrayBuffer', arrayBuffer)\n\n return arrayBuffer\n }\n\n case 'blob': {\n const mimeType =\n this.request.getResponseHeader('Content-Type') || 'text/plain'\n const responseBlob = new Blob([this.responseBufferToText()], {\n type: mimeType,\n })\n\n this.logger.info(\n 'resolved response Blob (mime type: %s)',\n responseBlob,\n mimeType\n )\n\n return responseBlob\n }\n\n default: {\n const responseText = this.responseBufferToText()\n this.logger.info(\n 'resolving \"%s\" response type as text',\n this.request.responseType,\n responseText\n )\n\n return responseText\n }\n }\n }\n\n get responseText(): string {\n /**\n * Throw when trying to read the response body as text when the\n * \"responseType\" doesn't expect text. This just respects the spec better.\n * @see https://xhr.spec.whatwg.org/#the-responsetext-attribute\n */\n invariant(\n this.request.responseType === '' || this.request.responseType === 'text',\n 'InvalidStateError: The object is in invalid state.'\n )\n\n if (\n this.request.readyState !== this.request.LOADING &&\n this.request.readyState !== this.request.DONE\n ) {\n return ''\n }\n\n const responseText = this.responseBufferToText()\n this.logger.info('getResponseText: \"%s\"', responseText)\n\n return responseText\n }\n\n get responseXML(): Document | null {\n invariant(\n this.request.responseType === '' ||\n this.request.responseType === 'document',\n 'InvalidStateError: The object is in invalid state.'\n )\n\n if (this.request.readyState !== this.request.DONE) {\n return null\n }\n\n const contentType = this.request.getResponseHeader('Content-Type') || ''\n\n if (typeof DOMParser === 'undefined') {\n console.warn(\n 'Cannot retrieve XMLHttpRequest response body as XML: DOMParser is not defined. You are likely using an environment that is not browser or does not polyfill browser globals correctly.'\n )\n return null\n }\n\n if (isDomParserSupportedType(contentType)) {\n return new DOMParser().parseFromString(\n this.responseBufferToText(),\n contentType\n )\n }\n\n return null\n }\n\n public errorWith(error: Error): void {\n this.logger.info('responding with an error')\n\n this.setReadyState(this.request.DONE)\n this.trigger('error')\n this.trigger('loadend')\n }\n\n /**\n * Transitions this request's `readyState` to the given one.\n */\n private setReadyState(nextReadyState: number): void {\n this.logger.info(\n 'setReadyState: %d -> %d',\n this.request.readyState,\n nextReadyState\n )\n\n if (this.request.readyState === nextReadyState) {\n this.logger.info('ready state identical, skipping transition...')\n return\n }\n\n define(this.request, 'readyState', nextReadyState)\n\n this.logger.info('set readyState to: %d', nextReadyState)\n\n if (nextReadyState !== this.request.UNSENT) {\n this.logger.info('triggerring \"readystatechange\" event...')\n\n this.trigger('readystatechange')\n }\n }\n\n /**\n * Triggers given event on the `XMLHttpRequest` instance.\n */\n private trigger<\n EventName extends keyof (XMLHttpRequestEventTargetEventMap & {\n readystatechange: ProgressEvent<XMLHttpRequestEventTarget>\n })\n >(eventName: EventName, options?: ProgressEventInit): void {\n const callback = this.request[`on${eventName}`]\n const event = createEvent(this.request, eventName, options)\n\n this.logger.info('trigger \"%s\"', eventName, options || '')\n\n // Invoke direct callbacks.\n if (typeof callback === 'function') {\n this.logger.info('found a direct \"%s\" callback, calling...', eventName)\n callback.call(this.request, event)\n }\n\n // Invoke event listeners.\n for (const [registeredEventName, listeners] of this.events) {\n if (registeredEventName === eventName) {\n this.logger.info(\n 'found %d listener(s) for \"%s\" event, calling...',\n listeners.length,\n eventName\n )\n\n listeners.forEach((listener) => listener.call(this.request, event))\n }\n }\n }\n\n /**\n * Converts this `XMLHttpRequest` instance into a Fetch API `Request` instance.\n */\n public toFetchApiRequest(): Request {\n this.logger.info('converting request to a Fetch API Request...')\n\n const fetchRequest = new Request(this.url.href, {\n method: this.method,\n headers: this.requestHeaders,\n /**\n * @see https://xhr.spec.whatwg.org/#cross-origin-credentials\n */\n credentials: this.request.withCredentials ? 'include' : 'same-origin',\n body: ['GET', 'HEAD'].includes(this.method)\n ? null\n : (this.requestBody as BodyInit),\n })\n\n const proxyHeaders = createProxy(fetchRequest.headers, {\n methodCall: ([methodName, args], invoke) => {\n // Forward the latest state of the internal request headers\n // because the interceptor might have modified them\n // without responding to the request.\n switch (methodName) {\n case 'append':\n case 'set': {\n const [headerName, headerValue] = args as [string, string]\n this.request.setRequestHeader(headerName, headerValue)\n break\n }\n\n case 'delete': {\n const [headerName] = args as [string]\n console.warn(\n `XMLHttpRequest: Cannot remove a \"${headerName}\" header from the Fetch API representation of the \"${fetchRequest.method} ${fetchRequest.url}\" request. XMLHttpRequest headers cannot be removed.`\n )\n break\n }\n }\n\n return invoke()\n },\n })\n define(fetchRequest, 'headers', proxyHeaders)\n\n this.logger.info('converted request to a Fetch API Request!', fetchRequest)\n\n return fetchRequest\n }\n}\n\nfunction toAbsoluteUrl(url: string | URL): URL {\n /**\n * @note XMLHttpRequest interceptor may run in environments\n * that implement XMLHttpRequest but don't implement \"location\"\n * (for example, React Native). If that's the case, return the\n * input URL as-is (nothing to be relative to).\n * @see https://github.com/mswjs/msw/issues/1777\n */\n if (typeof location === 'undefined') {\n return new URL(url)\n }\n\n return new URL(url.toString(), location.href)\n}\n\nfunction define(\n target: object,\n property: string | symbol,\n value: unknown\n): void {\n Reflect.defineProperty(target, property, {\n // Ensure writable properties to allow redefining readonly properties.\n writable: true,\n enumerable: true,\n value,\n })\n}\n","/**\n * Concatenate two `Uint8Array` buffers.\n */\nexport function concatArrayBuffer(\n left: Uint8Array,\n right: Uint8Array\n): Uint8Array {\n const result = new Uint8Array(left.byteLength + right.byteLength)\n result.set(left, 0)\n result.set(right, left.byteLength)\n return result\n}\n","export class EventPolyfill implements Event {\n readonly AT_TARGET: number = 0\n readonly BUBBLING_PHASE: number = 0\n readonly CAPTURING_PHASE: number = 0\n readonly NONE: number = 0\n\n public type: string = ''\n public srcElement: EventTarget | null = null\n public target: EventTarget | null\n public currentTarget: EventTarget | null = null\n public eventPhase: number = 0\n public timeStamp: number\n public isTrusted: boolean = true\n public composed: boolean = false\n public cancelable: boolean = true\n public defaultPrevented: boolean = false\n public bubbles: boolean = true\n public lengthComputable: boolean = true\n public loaded: number = 0\n public total: number = 0\n\n cancelBubble: boolean = false\n returnValue: boolean = true\n\n constructor(\n type: string,\n options?: { target: EventTarget; currentTarget: EventTarget }\n ) {\n this.type = type\n this.target = options?.target || null\n this.currentTarget = options?.currentTarget || null\n this.timeStamp = Date.now()\n }\n\n public composedPath(): EventTarget[] {\n return []\n }\n\n public initEvent(type: string, bubbles?: boolean, cancelable?: boolean) {\n this.type = type\n this.bubbles = !!bubbles\n this.cancelable = !!cancelable\n }\n\n public preventDefault() {\n this.defaultPrevented = true\n }\n\n public stopPropagation() {}\n public stopImmediatePropagation() {}\n}\n","import { EventPolyfill } from './EventPolyfill'\n\nexport class ProgressEventPolyfill extends EventPolyfill {\n readonly lengthComputable: boolean\n readonly composed: boolean\n readonly loaded: number\n readonly total: number\n\n constructor(type: string, init?: ProgressEventInit) {\n super(type)\n\n this.lengthComputable = init?.lengthComputable || false\n this.composed = init?.composed || false\n this.loaded = init?.loaded || 0\n this.total = init?.total || 0\n }\n}\n","import { EventPolyfill } from '../polyfills/EventPolyfill'\nimport { ProgressEventPolyfill } from '../polyfills/ProgressEventPolyfill'\n\nconst SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== 'undefined'\n\nexport function createEvent(\n target: XMLHttpRequest,\n type: string,\n init?: ProgressEventInit\n): EventPolyfill {\n const progressEvents = [\n 'error',\n 'progress',\n 'loadstart',\n 'loadend',\n 'load',\n 'timeout',\n 'abort',\n ]\n\n /**\n * `ProgressEvent` is not supported in React Native.\n * @see https://github.com/mswjs/interceptors/issues/40\n */\n const ProgressEventClass = SUPPORTS_PROGRESS_EVENT\n ? ProgressEvent\n : ProgressEventPolyfill\n\n const event = progressEvents.includes(type)\n ? new ProgressEventClass(type, {\n lengthComputable: true,\n loaded: init?.loaded || 0,\n total: init?.total || 0,\n })\n : new EventPolyfill(type, {\n target,\n currentTarget: target,\n })\n\n return event\n}\n","/**\n * Returns the source object of the given property on the target object\n * (the target itself, any parent in its prototype, or null).\n */\nexport function findPropertySource(\n target: object,\n propertyName: string | symbol\n): object | null {\n if (!(propertyName in target)) {\n return null\n }\n\n const hasProperty = Object.prototype.hasOwnProperty.call(target, propertyName)\n if (hasProperty) {\n return target\n }\n\n const prototype = Reflect.getPrototypeOf(target)\n return prototype ? findPropertySource(prototype, propertyName) : null\n}\n","import { findPropertySource } from './findPropertySource'\n\nexport interface ProxyOptions<Target extends Record<string, any>> {\n constructorCall?(args: Array<unknown>, next: NextFunction<Target>): Target\n\n methodCall?<F extends keyof Target>(\n this: Target,\n data: [methodName: F, args: Array<unknown>],\n next: NextFunction<void>\n ): void\n\n setProperty?(\n data: [propertyName: string | symbol, nextValue: unknown],\n next: NextFunction<boolean>\n ): boolean\n\n getProperty?(\n data: [propertyName: string | symbol, receiver: Target],\n next: NextFunction<void>\n ): void\n}\n\nexport type NextFunction<ReturnType> = () => ReturnType\n\nexport function createProxy<Target extends object>(\n target: Target,\n options: ProxyOptions<Target>\n): Target {\n const proxy = new Proxy(target, optionsToProxyHandler(options))\n\n return proxy\n}\n\nfunction optionsToProxyHandler<T extends Record<string, any>>(\n options: ProxyOptions<T>\n): ProxyHandler<T> {\n const { constructorCall, methodCall, getProperty, setProperty } = options\n const handler: ProxyHandler<T> = {}\n\n if (typeof constructorCall !== 'undefined') {\n handler.construct = function (target, args, newTarget) {\n const next = Reflect.construct.bind(null, target as any, args, newTarget)\n return constructorCall.call(newTarget, args, next)\n }\n }\n\n handler.set = function (target, propertyName, nextValue) {\n const next = () => {\n const propertySource = findPropertySource(target, propertyName) || target\n const ownDescriptors = Reflect.getOwnPropertyDescriptor(\n propertySource,\n propertyName\n )\n\n // Respect any custom setters present for this property.\n if (typeof ownDescriptors?.set !== 'undefined') {\n ownDescriptors.set.apply(target, [nextValue])\n return true\n }\n\n // Otherwise, set the property on the source.\n return Reflect.defineProperty(propertySource, propertyName, {\n writable: true,\n enumerable: true,\n configurable: true,\n value: nextValue,\n })\n }\n\n if (typeof setProperty !== 'undefined') {\n return setProperty.call(target, [propertyName, nextValue], next)\n }\n\n return next()\n }\n\n handler.get = function (target, propertyName, receiver) {\n /**\n * @note Using `Reflect.get()` here causes \"TypeError: Illegal invocation\".\n */\n const next = () => target[propertyName as any]\n\n const value =\n typeof getProperty !== 'undefined'\n ? getProperty.call(target, [propertyName, receiver], next)\n : next()\n\n if (typeof value === 'function') {\n return (...args: Array<any>) => {\n const next = value.bind(target, ...args)\n\n if (typeof methodCall !== 'undefined') {\n return methodCall.call(target, [propertyName as any, args], next)\n }\n\n return next()\n }\n }\n\n return value\n }\n\n return handler\n}\n","export function isDomParserSupportedType(\n type: string\n): type is DOMParserSupportedType {\n const supportedTypes: Array<DOMParserSupportedType> = [\n 'application/xhtml+xml',\n 'application/xml',\n 'image/svg+xml',\n 'text/html',\n 'text/xml',\n ]\n return supportedTypes.some((supportedType) => {\n return type.startsWith(supportedType)\n })\n}\n","/**\n * Parses a given string into JSON.\n * Gracefully handles invalid JSON by returning `null`.\n */\nexport function parseJson(data: string): Record<string, unknown> | null {\n try {\n const json = JSON.parse(data)\n return json\n } catch (_) {\n return null\n }\n}\n","import { isResponseWithoutBody } from '../../../utils/responseUtils'\n\n/**\n * Creates a Fetch API `Response` instance from the given\n * `XMLHttpRequest` instance and a response body.\n */\nexport function createResponse(\n request: XMLHttpRequest,\n body: BodyInit | null\n): Response {\n /**\n * Handle XMLHttpRequest responses that must have null as the\n * response body when represented using Fetch API Response.\n * XMLHttpRequest response will always have an empty string\n * as the \"request.response\" in those cases, resulting in an error\n * when constructing a Response instance.\n * @see https://github.com/mswjs/interceptors/issues/379\n */\n const responseBodyOrNull = isResponseWithoutBody(request.status) ? null : body\n\n return new Response(responseBodyOrNull, {\n status: request.status,\n statusText: request.statusText,\n headers: createHeadersFromXMLHttpReqestHeaders(\n request.getAllResponseHeaders()\n ),\n })\n}\n\nfunction createHeadersFromXMLHttpReqestHeaders(headersString: string): Headers {\n const headers = new Headers()\n\n const lines = headersString.split(/[\\r\\n]+/)\n for (const line of lines) {\n if (line.trim() === '') {\n continue\n }\n\n const [name, ...parts] = line.split(': ')\n const value = parts.join(': ')\n\n headers.append(name, value)\n }\n\n return headers\n}\n"],"mappings":"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","names":["invariant","next","mockedResponse","invariant"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/glossary.ts"],"names":[],"mappings":";AAEO,IAAM,oBAAmC,OAAO,iBAAiB","sourcesContent":["import type { InteractiveRequest } from './utils/toInteractiveRequest'\n\nexport const IS_PATCHED_MODULE: unique symbol = Symbol('isPatchedModule')\n\nexport type RequestCredentials = 'omit' | 'include' | 'same-origin'\n\nexport type HttpRequestEventMap = {\n request: [\n args: {\n request: InteractiveRequest\n requestId: string\n }\n ]\n response: [\n args: {\n response: Response\n isMockedResponse: boolean\n request: Request\n requestId: string\n }\n ]\n unhandledException: [\n args: {\n error: unknown\n request: Request\n requestId: string\n controller: {\n respondWith(response: Response): void\n errorWith(error?: Error): void\n }\n }\n ]\n}\n"]}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
// src/utils/emitAsync.ts
|
|
2
|
-
async function emitAsync(emitter, eventName, ...data) {
|
|
3
|
-
const listners = emitter.listeners(eventName);
|
|
4
|
-
if (listners.length === 0) {
|
|
5
|
-
return;
|
|
6
|
-
}
|
|
7
|
-
for (const listener of listners) {
|
|
8
|
-
await listener.apply(emitter, data);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// src/utils/RequestController.ts
|
|
13
|
-
import { invariant } from "outvariant";
|
|
14
|
-
import { DeferredPromise } from "@open-draft/deferred-promise";
|
|
15
|
-
var RequestController = class {
|
|
16
|
-
constructor(request) {
|
|
17
|
-
this.request = request;
|
|
18
|
-
this.responsePromise = new DeferredPromise();
|
|
19
|
-
}
|
|
20
|
-
respondWith(response) {
|
|
21
|
-
invariant(
|
|
22
|
-
this.responsePromise.state === "pending",
|
|
23
|
-
'Failed to respond to "%s %s" request: the "request" event has already been responded to.',
|
|
24
|
-
this.request.method,
|
|
25
|
-
this.request.url
|
|
26
|
-
);
|
|
27
|
-
this.responsePromise.resolve(response);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// src/utils/toInteractiveRequest.ts
|
|
32
|
-
function toInteractiveRequest(request) {
|
|
33
|
-
const requestController = new RequestController(request);
|
|
34
|
-
Reflect.set(
|
|
35
|
-
request,
|
|
36
|
-
"respondWith",
|
|
37
|
-
requestController.respondWith.bind(requestController)
|
|
38
|
-
);
|
|
39
|
-
return {
|
|
40
|
-
interactiveRequest: request,
|
|
41
|
-
requestController
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export {
|
|
46
|
-
emitAsync,
|
|
47
|
-
toInteractiveRequest
|
|
48
|
-
};
|
|
49
|
-
//# sourceMappingURL=chunk-KWV3JXSI.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/emitAsync.ts","../../src/utils/RequestController.ts","../../src/utils/toInteractiveRequest.ts"],"sourcesContent":["import { Emitter, EventMap } from 'strict-event-emitter'\n\n/**\n * Emits an event on the given emitter but executes\n * the listeners sequentially. This accounts for asynchronous\n * listeners (e.g. those having \"sleep\" and handling the request).\n */\nexport async function emitAsync<\n Events extends EventMap,\n EventName extends keyof Events\n>(\n emitter: Emitter<Events>,\n eventName: EventName,\n ...data: Events[EventName]\n): Promise<void> {\n const listners = emitter.listeners(eventName)\n\n if (listners.length === 0) {\n return\n }\n\n for (const listener of listners) {\n await listener.apply(emitter, data)\n }\n}\n","import { invariant } from 'outvariant'\nimport { DeferredPromise } from '@open-draft/deferred-promise'\n\nexport class RequestController {\n public responsePromise: DeferredPromise<Response | undefined>\n\n constructor(protected request: Request) {\n this.responsePromise = new DeferredPromise()\n }\n\n public respondWith(response?: Response): void {\n invariant(\n this.responsePromise.state === 'pending',\n 'Failed to respond to \"%s %s\" request: the \"request\" event has already been responded to.',\n this.request.method,\n this.request.url\n )\n\n this.responsePromise.resolve(response)\n }\n}\n","import { RequestController } from './RequestController'\n\nexport type InteractiveRequest = globalThis.Request & {\n respondWith: RequestController['respondWith']\n}\n\nexport function toInteractiveRequest(request: Request): {\n interactiveRequest: InteractiveRequest\n requestController: RequestController\n} {\n const requestController = new RequestController(request)\n\n Reflect.set(\n request,\n 'respondWith',\n requestController.respondWith.bind(requestController)\n )\n\n return {\n interactiveRequest: request as InteractiveRequest,\n requestController,\n }\n}\n"],"mappings":";AAOA,eAAsB,UAIpB,SACA,cACG,MACY;AACf,QAAM,WAAW,QAAQ,UAAU,SAAS;AAE5C,MAAI,SAAS,WAAW,GAAG;AACzB;AAAA,EACF;AAEA,aAAW,YAAY,UAAU;AAC/B,UAAM,SAAS,MAAM,SAAS,IAAI;AAAA,EACpC;AACF;;;ACxBA,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAEzB,IAAM,oBAAN,MAAwB;AAAA,EAG7B,YAAsB,SAAkB;AAAlB;AACpB,SAAK,kBAAkB,IAAI,gBAAgB;AAAA,EAC7C;AAAA,EAEO,YAAY,UAA2B;AAC5C;AAAA,MACE,KAAK,gBAAgB,UAAU;AAAA,MAC/B;AAAA,MACA,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,IACf;AAEA,SAAK,gBAAgB,QAAQ,QAAQ;AAAA,EACvC;AACF;;;ACdO,SAAS,qBAAqB,SAGnC;AACA,QAAM,oBAAoB,IAAI,kBAAkB,OAAO;AAEvD,UAAQ;AAAA,IACN;AAAA,IACA;AAAA,IACA,kBAAkB,YAAY,KAAK,iBAAiB;AAAA,EACtD;AAEA,SAAO;AAAA,IACL,oBAAoB;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
|