@mswjs/interceptors 0.41.9 → 0.42.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 +274 -228
- package/lib/browser/{bufferUtils-BiiO6HZv.mjs → buffer-utils-DJj7YzLG.js} +3 -3
- package/lib/browser/buffer-utils-DJj7YzLG.js.map +1 -0
- package/lib/browser/create-request-id-DlEd4GOA.js +184 -0
- package/lib/browser/create-request-id-DlEd4GOA.js.map +1 -0
- package/lib/browser/{getRawRequest-B1BqgWG6.mjs → fetch-utils-zxA_SD66.js} +123 -52
- package/lib/browser/fetch-utils-zxA_SD66.js.map +1 -0
- package/lib/browser/handle-request-CIOa9O-N.js +167 -0
- package/lib/browser/handle-request-CIOa9O-N.js.map +1 -0
- package/lib/{node/hasConfigurableGlobal-BiTmog1u.mjs → browser/has-configurable-global-Cew-dYqk.js} +5 -7
- package/lib/browser/has-configurable-global-Cew-dYqk.js.map +1 -0
- package/lib/browser/http-CB9rQ7i_.d.ts +105 -0
- package/lib/browser/{index.d.cts → index.d.ts} +33 -38
- package/lib/browser/index.js +130 -0
- package/lib/browser/index.js.map +1 -0
- package/lib/browser/interceptor-dtJZ_9QT.d.ts +50 -0
- package/lib/browser/interceptors/WebSocket/index.d.ts +2 -0
- package/lib/browser/interceptors/WebSocket/{index.mjs → index.js} +39 -30
- package/lib/browser/interceptors/WebSocket/index.js.map +1 -0
- package/lib/browser/interceptors/XMLHttpRequest/web.d.ts +11 -0
- package/lib/browser/interceptors/XMLHttpRequest/web.js +2 -0
- package/lib/browser/interceptors/fetch/web.d.ts +14 -0
- package/lib/browser/interceptors/fetch/web.js +2 -0
- package/lib/browser/presets/browser.d.ts +11 -0
- package/lib/browser/presets/browser.js +12 -0
- package/lib/browser/presets/browser.js.map +1 -0
- package/lib/browser/{resolveWebSocketUrl-C83-x9iE.mjs → resolve-web-socket-url-CSvNPLGi.js} +3 -3
- package/lib/browser/resolve-web-socket-url-CSvNPLGi.js.map +1 -0
- package/lib/browser/web-BjVDkiX0.js +248 -0
- package/lib/browser/web-BjVDkiX0.js.map +1 -0
- package/lib/browser/{XMLHttpRequest-DrZAf3w6.mjs → web-C2oKsT3Q.js} +327 -255
- package/lib/browser/web-C2oKsT3Q.js.map +1 -0
- package/lib/browser/{interceptors/WebSocket/index.d.cts → websocket-CC0nB0md.d.ts} +41 -33
- package/lib/node/batch-interceptor-ByEZVih3.js +119 -0
- package/lib/node/batch-interceptor-ByEZVih3.js.map +1 -0
- package/lib/node/batch-interceptor-CPjFK2td.d.ts +28 -0
- package/lib/node/buffer-utils-BvPY1Tc-.js +187 -0
- package/lib/node/buffer-utils-BvPY1Tc-.js.map +1 -0
- package/lib/node/fetch-utils-Dw1PsmtX.js +568 -0
- package/lib/node/fetch-utils-Dw1PsmtX.js.map +1 -0
- package/lib/node/has-configurable-global-CJCh_g1I.js +22 -0
- package/lib/node/has-configurable-global-CJCh_g1I.js.map +1 -0
- package/lib/node/http-CB9rQ7i_.d.ts +105 -0
- package/lib/{browser/interceptors/WebSocket/index.d.mts → node/index.d.ts} +120 -60
- package/lib/node/{index.mjs → index.js} +8 -11
- package/lib/node/index.js.map +1 -0
- package/lib/node/interceptor-dtJZ_9QT.d.ts +50 -0
- package/lib/node/interceptors/ClientRequest/index.d.ts +14 -0
- package/lib/node/interceptors/ClientRequest/index.js +67 -0
- package/lib/node/interceptors/ClientRequest/index.js.map +1 -0
- package/lib/node/interceptors/XMLHttpRequest/node.d.ts +12 -0
- package/lib/node/interceptors/XMLHttpRequest/node.js +74 -0
- package/lib/node/interceptors/XMLHttpRequest/node.js.map +1 -0
- package/lib/node/interceptors/fetch/node.d.ts +18 -0
- package/lib/node/interceptors/fetch/node.js +83 -0
- package/lib/node/interceptors/fetch/node.js.map +1 -0
- package/lib/node/interceptors/http/index.d.ts +14 -0
- package/lib/node/interceptors/http/index.js +32 -0
- package/lib/node/interceptors/http/index.js.map +1 -0
- package/lib/node/interceptors/net/index.d.ts +203 -0
- package/lib/node/interceptors/net/index.js +2 -0
- package/lib/node/llhttp/constants.cjs +485 -0
- package/lib/node/llhttp/constants.d.cts +957 -0
- package/lib/node/llhttp/llhttp.wasm +0 -0
- package/lib/node/net-DtMnyEeg.js +1388 -0
- package/lib/node/net-DtMnyEeg.js.map +1 -0
- package/lib/node/presets/node.d.ts +12 -0
- package/lib/node/presets/node.js +17 -0
- package/lib/node/presets/node.js.map +1 -0
- package/lib/node/{RemoteHttpInterceptor.d.cts → remote-http-interceptor.d.ts} +12 -11
- package/lib/node/{RemoteHttpInterceptor.mjs → remote-http-interceptor.js} +38 -33
- package/lib/node/remote-http-interceptor.js.map +1 -0
- package/lib/node/source-lP0yyEtA.js +1990 -0
- package/lib/node/source-lP0yyEtA.js.map +1 -0
- package/package.json +79 -118
- package/src/batch-interceptor.test.ts +475 -0
- package/src/batch-interceptor.ts +244 -0
- package/src/{createRequestId.test.ts → create-request-id.test.ts} +1 -2
- package/src/disposable.ts +13 -0
- package/src/events/http.ts +92 -0
- package/src/events/websocket.ts +47 -0
- package/src/glossary.ts +1 -27
- package/src/index.ts +18 -10
- package/src/interceptor.test.ts +279 -0
- package/src/interceptor.ts +139 -0
- package/src/interceptors/ClientRequest/index.test.ts +21 -39
- package/src/interceptors/ClientRequest/index.ts +64 -179
- package/src/interceptors/ClientRequest/utils/{recordRawHeaders.test.ts → record-raw-headers.test.ts} +1 -2
- package/src/interceptors/ClientRequest/utils/{recordRawHeaders.ts → record-raw-headers.ts} +29 -2
- package/src/interceptors/WebSocket/index.ts +33 -50
- package/src/interceptors/WebSocket/utils/{bindEvent.test.ts → bind-event.test.ts} +1 -2
- package/src/interceptors/WebSocket/utils/events.test.ts +0 -1
- package/src/interceptors/WebSocket/{WebSocketClassTransport.ts → web-socket-class-transport.ts} +3 -3
- package/src/interceptors/WebSocket/{WebSocketClientConnection.ts → web-socket-client-connection.ts} +4 -4
- package/src/interceptors/WebSocket/{WebSocketOverride.ts → web-socket-override.ts} +6 -7
- package/src/interceptors/WebSocket/{WebSocketServerConnection.ts → web-socket-server-connection.ts} +4 -4
- package/src/interceptors/WebSocket/{WebSocketTransport.ts → web-socket-transport.ts} +1 -1
- package/src/interceptors/XMLHttpRequest/node.ts +104 -0
- package/src/interceptors/XMLHttpRequest/polyfills/{ProgressEventPolyfill.ts → progress-event-polyfill.ts} +1 -1
- package/src/interceptors/XMLHttpRequest/utils/{concateArrayBuffer.test.ts → concat-array-buffer.test.ts} +1 -2
- package/src/interceptors/XMLHttpRequest/utils/{concatArrayBuffer.ts → concat-array-buffer.ts} +1 -1
- package/src/interceptors/XMLHttpRequest/utils/{createEvent.test.ts → create-event.test.ts} +3 -4
- package/src/interceptors/XMLHttpRequest/utils/{createEvent.ts → create-event.ts} +2 -2
- package/src/interceptors/XMLHttpRequest/utils/{createResponse.ts → create-response.ts} +1 -1
- package/src/interceptors/XMLHttpRequest/utils/{getBodyByteLength.test.ts → get-body-byte-length.test.ts} +1 -2
- package/src/interceptors/XMLHttpRequest/web.ts +34 -0
- package/src/interceptors/XMLHttpRequest/{XMLHttpRequestController.ts → xml-http-request-controller.ts} +363 -204
- package/src/interceptors/XMLHttpRequest/{XMLHttpRequestProxy.ts → xml-http-request-proxy.ts} +28 -25
- package/src/interceptors/fetch/node.ts +103 -0
- package/src/interceptors/fetch/utils/{followRedirect.ts → follow-redirect.ts} +1 -1
- package/src/interceptors/fetch/web.ts +217 -0
- package/src/interceptors/http/forward-events.test.ts +86 -0
- package/src/interceptors/http/forward-events.ts +139 -0
- package/src/interceptors/http/http-parser/index.ts +310 -0
- package/src/interceptors/http/http-parser/llhttp/constants.cjs +485 -0
- package/src/interceptors/http/http-parser/llhttp/constants.d.cts +957 -0
- package/src/interceptors/http/http-parser/llhttp/llhttp.wasm +0 -0
- package/src/interceptors/http/http-parser.ts +138 -0
- package/src/interceptors/http/index.ts +34 -0
- package/src/interceptors/http/source.ts +688 -0
- package/src/interceptors/net/index.ts +368 -0
- package/src/interceptors/net/socket-controller.ts +1476 -0
- package/src/interceptors/net/utils/address-info.ts +54 -0
- package/src/interceptors/net/utils/connection-options-to-url.ts +56 -0
- package/src/interceptors/net/utils/flush-writes.ts +57 -0
- package/src/interceptors/net/utils/get-tls-connect-options.ts +23 -0
- package/src/interceptors/net/utils/normalize-net-connect-args.test.ts +233 -0
- package/src/interceptors/net/utils/normalize-net-connect-args.ts +121 -0
- package/src/interceptors/net/utils/normalize-tls-connect-args.ts +50 -0
- package/src/presets/browser.ts +4 -4
- package/src/presets/node.ts +4 -4
- package/src/{RemoteHttpInterceptor.ts → remote-http-interceptor.ts} +55 -42
- package/src/request-context.ts +40 -0
- package/src/{RequestController.test.ts → request-controller.test.ts} +37 -3
- package/src/{RequestController.ts → request-controller.ts} +33 -11
- package/src/utils/{bufferUtils.test.ts → buffer-utils.test.ts} +1 -2
- package/src/utils/buffer-utils.ts +37 -0
- package/src/utils/{cloneObject.test.ts → clone-object.test.ts} +1 -2
- package/src/utils/{cloneObject.ts → clone-object.ts} +8 -8
- package/src/utils/{createProxy.test.ts → create-proxy.test.ts} +6 -4
- package/src/utils/{createProxy.ts → create-proxy.ts} +1 -1
- package/src/utils/{fetchUtils.test.ts → fetch-utils.test.ts} +1 -1
- package/src/utils/{fetchUtils.ts → fetch-utils.ts} +28 -3
- package/src/utils/{findPropertySource.test.ts → find-property-source.test.ts} +1 -2
- package/src/utils/{getCleanUrl.test.ts → get-clean-url.test.ts} +1 -2
- package/src/utils/{getUrlByRequestOptions.test.ts → get-url-by-request-options.test.ts} +4 -8
- package/src/utils/{getUrlByRequestOptions.ts → get-url-by-request-options.ts} +16 -16
- package/src/utils/{getValueBySymbol.test.ts → get-value-by-symbol.test.ts} +1 -2
- package/src/utils/{handleRequest.ts → handle-request.ts} +61 -41
- package/src/utils/{hasConfigurableGlobal.test.ts → has-configurable-global.test.ts} +1 -2
- package/src/utils/{hasConfigurableGlobal.ts → has-configurable-global.ts} +2 -4
- package/src/utils/{isObject.test.ts → is-object.test.ts} +1 -2
- package/src/utils/logger.test.ts +154 -0
- package/src/utils/logger.ts +154 -0
- package/src/utils/{parseJson.test.ts → parse-json.test.ts} +1 -2
- package/src/utils/{patchesRegistry.test.ts → patches-registry.test.ts} +1 -1
- package/src/utils/{patchesRegistry.ts → patches-registry.ts} +1 -1
- package/src/utils/{responseUtils.ts → response-utils.ts} +25 -2
- package/ClientRequest/package.json +0 -11
- package/RemoteHttpInterceptor/package.json +0 -11
- package/WebSocket/package.json +0 -12
- package/XMLHttpRequest/package.json +0 -12
- package/fetch/package.json +0 -12
- package/lib/browser/Interceptor-Deczogc8.d.cts +0 -65
- package/lib/browser/Interceptor-gqKgs-aF.d.mts +0 -65
- package/lib/browser/XMLHttpRequest-DrZAf3w6.mjs.map +0 -1
- package/lib/browser/XMLHttpRequest-gXuzzX1g.cjs +0 -751
- package/lib/browser/XMLHttpRequest-gXuzzX1g.cjs.map +0 -1
- package/lib/browser/bufferUtils-BiiO6HZv.mjs.map +0 -1
- package/lib/browser/bufferUtils-Uc0eRItL.cjs +0 -38
- package/lib/browser/bufferUtils-Uc0eRItL.cjs.map +0 -1
- package/lib/browser/createRequestId-DOf8Ktjs.cjs +0 -205
- package/lib/browser/createRequestId-DOf8Ktjs.cjs.map +0 -1
- package/lib/browser/createRequestId-DYCsFHOi.mjs +0 -170
- package/lib/browser/createRequestId-DYCsFHOi.mjs.map +0 -1
- package/lib/browser/fetch-5IMPqr9e.mjs +0 -236
- package/lib/browser/fetch-5IMPqr9e.mjs.map +0 -1
- package/lib/browser/fetch-Bt9rMY9c.cjs +0 -241
- package/lib/browser/fetch-Bt9rMY9c.cjs.map +0 -1
- package/lib/browser/getRawRequest-B1BqgWG6.mjs.map +0 -1
- package/lib/browser/getRawRequest-DdfaiPVH.cjs +0 -376
- package/lib/browser/getRawRequest-DdfaiPVH.cjs.map +0 -1
- package/lib/browser/glossary-1lhZx6Aw.d.cts +0 -69
- package/lib/browser/glossary-nkHWcwvY.d.mts +0 -69
- package/lib/browser/handleRequest-CJim54xG.cjs +0 -191
- package/lib/browser/handleRequest-CJim54xG.cjs.map +0 -1
- package/lib/browser/handleRequest-CPPgsG7s.mjs +0 -180
- package/lib/browser/handleRequest-CPPgsG7s.mjs.map +0 -1
- package/lib/browser/hasConfigurableGlobal-C8zq1MCg.mjs +0 -109
- package/lib/browser/hasConfigurableGlobal-C8zq1MCg.mjs.map +0 -1
- package/lib/browser/hasConfigurableGlobal-CS7adEvV.cjs +0 -126
- package/lib/browser/hasConfigurableGlobal-CS7adEvV.cjs.map +0 -1
- package/lib/browser/index.cjs +0 -70
- package/lib/browser/index.cjs.map +0 -1
- package/lib/browser/index.d.mts +0 -125
- package/lib/browser/index.mjs +0 -56
- package/lib/browser/index.mjs.map +0 -1
- package/lib/browser/interceptors/WebSocket/index.cjs +0 -618
- package/lib/browser/interceptors/WebSocket/index.cjs.map +0 -1
- package/lib/browser/interceptors/WebSocket/index.mjs.map +0 -1
- package/lib/browser/interceptors/XMLHttpRequest/index.cjs +0 -8
- package/lib/browser/interceptors/XMLHttpRequest/index.d.cts +0 -15
- package/lib/browser/interceptors/XMLHttpRequest/index.d.mts +0 -15
- package/lib/browser/interceptors/XMLHttpRequest/index.mjs +0 -8
- package/lib/browser/interceptors/fetch/index.cjs +0 -7
- package/lib/browser/interceptors/fetch/index.d.cts +0 -13
- package/lib/browser/interceptors/fetch/index.d.mts +0 -13
- package/lib/browser/interceptors/fetch/index.mjs +0 -7
- package/lib/browser/presets/browser.cjs +0 -18
- package/lib/browser/presets/browser.cjs.map +0 -1
- package/lib/browser/presets/browser.d.cts +0 -12
- package/lib/browser/presets/browser.d.mts +0 -14
- package/lib/browser/presets/browser.mjs +0 -18
- package/lib/browser/presets/browser.mjs.map +0 -1
- package/lib/browser/resolveWebSocketUrl-6K6EgqsA.cjs +0 -31
- package/lib/browser/resolveWebSocketUrl-6K6EgqsA.cjs.map +0 -1
- package/lib/browser/resolveWebSocketUrl-C83-x9iE.mjs.map +0 -1
- package/lib/node/BatchInterceptor-BGhH8z1z.cjs +0 -49
- package/lib/node/BatchInterceptor-BGhH8z1z.cjs.map +0 -1
- package/lib/node/BatchInterceptor-C4-RX5rg.mjs +0 -44
- package/lib/node/BatchInterceptor-C4-RX5rg.mjs.map +0 -1
- package/lib/node/BatchInterceptor-KKF8Q47I.d.cts +0 -26
- package/lib/node/BatchInterceptor-rSr-NH_H.d.mts +0 -26
- package/lib/node/ClientRequest-2loAH7xM.cjs +0 -1058
- package/lib/node/ClientRequest-2loAH7xM.cjs.map +0 -1
- package/lib/node/ClientRequest-DGhBX21V.mjs +0 -1049
- package/lib/node/ClientRequest-DGhBX21V.mjs.map +0 -1
- package/lib/node/Interceptor-BsZ21ue0.d.cts +0 -132
- package/lib/node/Interceptor-soD-WpQO.d.mts +0 -132
- package/lib/node/RemoteHttpInterceptor.cjs +0 -155
- package/lib/node/RemoteHttpInterceptor.cjs.map +0 -1
- package/lib/node/RemoteHttpInterceptor.d.mts +0 -39
- package/lib/node/RemoteHttpInterceptor.mjs.map +0 -1
- package/lib/node/XMLHttpRequest-BtDNZipW.cjs +0 -752
- package/lib/node/XMLHttpRequest-BtDNZipW.cjs.map +0 -1
- package/lib/node/XMLHttpRequest-Dw6Wm-UU.mjs +0 -746
- package/lib/node/XMLHttpRequest-Dw6Wm-UU.mjs.map +0 -1
- package/lib/node/bufferUtils-DxPxwff_.mjs +0 -20
- package/lib/node/bufferUtils-DxPxwff_.mjs.map +0 -1
- package/lib/node/bufferUtils-S5_-2eN4.cjs +0 -38
- package/lib/node/bufferUtils-S5_-2eN4.cjs.map +0 -1
- package/lib/node/chunk-CbDLau6x.cjs +0 -34
- package/lib/node/fetch-CaC3rGEu.mjs +0 -252
- package/lib/node/fetch-CaC3rGEu.mjs.map +0 -1
- package/lib/node/fetch-D2ClLNN-.cjs +0 -259
- package/lib/node/fetch-D2ClLNN-.cjs.map +0 -1
- package/lib/node/fetchUtils-BKJ1XmiO.mjs +0 -480
- package/lib/node/fetchUtils-BKJ1XmiO.mjs.map +0 -1
- package/lib/node/fetchUtils-umV5xXBy.cjs +0 -546
- package/lib/node/fetchUtils-umV5xXBy.cjs.map +0 -1
- package/lib/node/getRawRequest-B6znU6il.cjs +0 -36
- package/lib/node/getRawRequest-B6znU6il.cjs.map +0 -1
- package/lib/node/getRawRequest-C2-1urzA.mjs +0 -24
- package/lib/node/getRawRequest-C2-1urzA.mjs.map +0 -1
- package/lib/node/handleRequest-C-cKYjIh.cjs +0 -222
- package/lib/node/handleRequest-C-cKYjIh.cjs.map +0 -1
- package/lib/node/handleRequest-FIQv5pwH.mjs +0 -192
- package/lib/node/handleRequest-FIQv5pwH.mjs.map +0 -1
- package/lib/node/hasConfigurableGlobal-BiTmog1u.mjs.map +0 -1
- package/lib/node/hasConfigurableGlobal-MjY06_Ok.cjs +0 -108
- package/lib/node/hasConfigurableGlobal-MjY06_Ok.cjs.map +0 -1
- package/lib/node/index-BJ5E5aW-.d.cts +0 -113
- package/lib/node/index-DfoF45ih.d.mts +0 -113
- package/lib/node/index.cjs +0 -53
- package/lib/node/index.cjs.map +0 -1
- package/lib/node/index.d.cts +0 -104
- package/lib/node/index.d.mts +0 -104
- package/lib/node/index.mjs.map +0 -1
- package/lib/node/interceptors/ClientRequest/index.cjs +0 -6
- package/lib/node/interceptors/ClientRequest/index.d.cts +0 -2
- package/lib/node/interceptors/ClientRequest/index.d.mts +0 -3
- package/lib/node/interceptors/ClientRequest/index.mjs +0 -6
- package/lib/node/interceptors/XMLHttpRequest/index.cjs +0 -7
- package/lib/node/interceptors/XMLHttpRequest/index.d.cts +0 -14
- package/lib/node/interceptors/XMLHttpRequest/index.d.mts +0 -14
- package/lib/node/interceptors/XMLHttpRequest/index.mjs +0 -7
- package/lib/node/interceptors/fetch/index.cjs +0 -6
- package/lib/node/interceptors/fetch/index.d.cts +0 -12
- package/lib/node/interceptors/fetch/index.d.mts +0 -12
- package/lib/node/interceptors/fetch/index.mjs +0 -6
- package/lib/node/node-DIKcnzhK.cjs +0 -39
- package/lib/node/node-DIKcnzhK.cjs.map +0 -1
- package/lib/node/node-lsdNwZEW.mjs +0 -27
- package/lib/node/node-lsdNwZEW.mjs.map +0 -1
- package/lib/node/presets/node.cjs +0 -23
- package/lib/node/presets/node.cjs.map +0 -1
- package/lib/node/presets/node.d.cts +0 -13
- package/lib/node/presets/node.d.mts +0 -15
- package/lib/node/presets/node.mjs +0 -23
- package/lib/node/presets/node.mjs.map +0 -1
- package/lib/node/utils/node/index.cjs +0 -4
- package/lib/node/utils/node/index.d.cts +0 -16
- package/lib/node/utils/node/index.d.mts +0 -16
- package/lib/node/utils/node/index.mjs +0 -3
- package/presets/browser/package.json +0 -5
- package/presets/node/package.json +0 -11
- package/src/BatchInterceptor.test.ts +0 -255
- package/src/BatchInterceptor.ts +0 -96
- package/src/Interceptor.test.ts +0 -205
- package/src/Interceptor.ts +0 -249
- package/src/getRawRequest.ts +0 -21
- package/src/interceptors/ClientRequest/MockHttpSocket.ts +0 -724
- package/src/interceptors/ClientRequest/agents.ts +0 -110
- package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.test.ts +0 -54
- package/src/interceptors/ClientRequest/utils/getIncomingMessageBody.ts +0 -45
- package/src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.test.ts +0 -427
- package/src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts +0 -268
- package/src/interceptors/ClientRequest/utils/parserUtils.ts +0 -48
- package/src/interceptors/Socket/MockSocket.test.ts +0 -264
- package/src/interceptors/Socket/MockSocket.ts +0 -58
- package/src/interceptors/Socket/utils/baseUrlFromConnectionOptions.ts +0 -26
- package/src/interceptors/Socket/utils/normalizeSocketWriteArgs.test.ts +0 -52
- package/src/interceptors/Socket/utils/normalizeSocketWriteArgs.ts +0 -33
- package/src/interceptors/XMLHttpRequest/index.ts +0 -40
- package/src/interceptors/fetch/index.ts +0 -203
- package/src/utils/bufferUtils.ts +0 -22
- package/src/utils/canParseUrl.ts +0 -13
- package/src/utils/emitAsync.ts +0 -25
- package/src/utils/nextTick.ts +0 -11
- package/src/utils/node/index.ts +0 -39
- /package/src/{createRequestId.ts → create-request-id.ts} +0 -0
- /package/src/{InterceptorError.ts → interceptor-error.ts} +0 -0
- /package/src/interceptors/WebSocket/utils/{bindEvent.ts → bind-event.ts} +0 -0
- /package/src/interceptors/XMLHttpRequest/polyfills/{EventPolyfill.ts → event-polyfill.ts} +0 -0
- /package/src/interceptors/XMLHttpRequest/utils/{getBodyByteLength.ts → get-body-byte-length.ts} +0 -0
- /package/src/interceptors/XMLHttpRequest/utils/{isDomParserSupportedType.ts → is-dom-parser-supported-type.ts} +0 -0
- /package/src/interceptors/fetch/utils/{createNetworkError.ts → create-network-error.ts} +0 -0
- /package/src/utils/{findPropertySource.ts → find-property-source.ts} +0 -0
- /package/src/utils/{getCleanUrl.ts → get-clean-url.ts} +0 -0
- /package/src/utils/{getValueBySymbol.ts → get-value-by-symbol.ts} +0 -0
- /package/src/utils/{isNodeLikeError.ts → is-node-like-error.ts} +0 -0
- /package/src/utils/{isObject.ts → is-object.ts} +0 -0
- /package/src/utils/{isPropertyAccessible.ts → is-property-accessible.ts} +0 -0
- /package/src/utils/{parseJson.ts → parse-json.ts} +0 -0
- /package/src/utils/{resolveWebSocketUrl.ts → resolve-web-socket-url.ts} +0 -0
|
@@ -1,26 +1,26 @@
|
|
|
1
|
+
import { until } from '@open-draft/until'
|
|
1
2
|
import { invariant } from 'outvariant'
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
import { concatArrayBuffer } from './utils/
|
|
5
|
-
import { createEvent } from './utils/
|
|
3
|
+
import type { Logger } from '../../utils/logger'
|
|
4
|
+
import type { HttpResponseType } from '../../events/http'
|
|
5
|
+
import { concatArrayBuffer } from './utils/concat-array-buffer'
|
|
6
|
+
import { createEvent } from './utils/create-event'
|
|
6
7
|
import {
|
|
7
8
|
decodeBuffer,
|
|
8
9
|
encodeBuffer,
|
|
9
10
|
toArrayBuffer,
|
|
10
|
-
} from '../../utils/
|
|
11
|
-
import { createProxy } from '../../utils/
|
|
12
|
-
import { isDomParserSupportedType } from './utils/
|
|
13
|
-
import { parseJson } from '../../utils/
|
|
14
|
-
import { createResponse } from './utils/
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { FetchRequest } from '../../utils/fetchUtils'
|
|
11
|
+
} from '../../utils/buffer-utils'
|
|
12
|
+
import { createProxy } from '../../utils/create-proxy'
|
|
13
|
+
import { isDomParserSupportedType } from './utils/is-dom-parser-supported-type'
|
|
14
|
+
import { parseJson } from '../../utils/parse-json'
|
|
15
|
+
import { createResponse } from './utils/create-response'
|
|
16
|
+
import { createRequestId } from '../../create-request-id'
|
|
17
|
+
import { getBodyByteLength } from './utils/get-body-byte-length'
|
|
18
|
+
import { FetchRequest, FetchResponse } from '../../utils/fetch-utils'
|
|
19
|
+
import { isResponseError } from '../../utils/response-utils'
|
|
20
20
|
|
|
21
21
|
const kIsRequestHandled = Symbol('kIsRequestHandled')
|
|
22
|
-
const IS_NODE = isNodeProcess()
|
|
23
22
|
const kFetchRequest = Symbol('kFetchRequest')
|
|
23
|
+
const MAX_REDIRECTS = 20
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* An `XMLHttpRequest` instance controller that allows us
|
|
@@ -40,7 +40,7 @@ export class XMLHttpRequestController {
|
|
|
40
40
|
this: XMLHttpRequestController,
|
|
41
41
|
args: {
|
|
42
42
|
response: Response
|
|
43
|
-
|
|
43
|
+
responseType: HttpResponseType
|
|
44
44
|
request: Request
|
|
45
45
|
requestId: string
|
|
46
46
|
}
|
|
@@ -48,10 +48,13 @@ export class XMLHttpRequestController {
|
|
|
48
48
|
|
|
49
49
|
[kIsRequestHandled]: boolean;
|
|
50
50
|
[kFetchRequest]?: Request
|
|
51
|
+
|
|
52
|
+
private sync: boolean = false
|
|
51
53
|
private method: string = 'GET'
|
|
52
54
|
private url: URL = null as any
|
|
53
55
|
private requestHeaders: Headers
|
|
54
|
-
private responseBuffer: Uint8Array
|
|
56
|
+
private responseBuffer: Uint8Array<ArrayBuffer>
|
|
57
|
+
private redirectCount: number
|
|
55
58
|
private events: Map<keyof XMLHttpRequestEventTargetEventMap, Array<Function>>
|
|
56
59
|
private uploadEvents: Map<
|
|
57
60
|
keyof XMLHttpRequestEventTargetEventMap,
|
|
@@ -64,6 +67,7 @@ export class XMLHttpRequestController {
|
|
|
64
67
|
) {
|
|
65
68
|
this[kIsRequestHandled] = false
|
|
66
69
|
|
|
70
|
+
this.redirectCount = 0
|
|
67
71
|
this.events = new Map()
|
|
68
72
|
this.uploadEvents = new Map()
|
|
69
73
|
this.requestId = createRequestId()
|
|
@@ -71,32 +75,16 @@ export class XMLHttpRequestController {
|
|
|
71
75
|
this.responseBuffer = new Uint8Array()
|
|
72
76
|
|
|
73
77
|
this.request = createProxy(initialRequest, {
|
|
74
|
-
setProperty: ([propertyName, nextValue], invoke) => {
|
|
75
|
-
switch (propertyName) {
|
|
76
|
-
case 'ontimeout': {
|
|
77
|
-
const eventName = propertyName.slice(
|
|
78
|
-
2
|
|
79
|
-
) as keyof XMLHttpRequestEventTargetEventMap
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* @note Proxy callbacks to event listeners because JSDOM has trouble
|
|
83
|
-
* translating these properties to callbacks. It seemed to be operating
|
|
84
|
-
* on events exclusively.
|
|
85
|
-
*/
|
|
86
|
-
this.request.addEventListener(eventName, nextValue as any)
|
|
87
|
-
|
|
88
|
-
return invoke()
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
default: {
|
|
92
|
-
return invoke()
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
78
|
methodCall: ([methodName, args], invoke) => {
|
|
97
79
|
switch (methodName) {
|
|
98
80
|
case 'open': {
|
|
99
|
-
const [method, url] = args as [
|
|
81
|
+
const [method, url, async] = args as [
|
|
82
|
+
string,
|
|
83
|
+
string | undefined,
|
|
84
|
+
boolean | undefined,
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
this.sync = !(async ?? true)
|
|
100
88
|
|
|
101
89
|
if (typeof url === 'undefined') {
|
|
102
90
|
this.method = 'GET'
|
|
@@ -106,8 +94,7 @@ export class XMLHttpRequestController {
|
|
|
106
94
|
this.url = toAbsoluteUrl(url)
|
|
107
95
|
}
|
|
108
96
|
|
|
109
|
-
this.logger
|
|
110
|
-
this.logger.info('open', this.method, this.url.href)
|
|
97
|
+
this.logger.verbose('open %s %s', this.method, this.url.href)
|
|
111
98
|
|
|
112
99
|
return invoke()
|
|
113
100
|
}
|
|
@@ -119,7 +106,7 @@ export class XMLHttpRequestController {
|
|
|
119
106
|
]
|
|
120
107
|
|
|
121
108
|
this.registerEvent(eventName, listener)
|
|
122
|
-
this.logger.
|
|
109
|
+
this.logger.verbose('addEventListener', eventName, listener)
|
|
123
110
|
|
|
124
111
|
return invoke()
|
|
125
112
|
}
|
|
@@ -128,7 +115,7 @@ export class XMLHttpRequestController {
|
|
|
128
115
|
const [name, value] = args as [string, string]
|
|
129
116
|
this.requestHeaders.set(name, value)
|
|
130
117
|
|
|
131
|
-
this.logger.
|
|
118
|
+
this.logger.verbose('setRequestHeader', name, value)
|
|
132
119
|
|
|
133
120
|
return invoke()
|
|
134
121
|
}
|
|
@@ -138,6 +125,13 @@ export class XMLHttpRequestController {
|
|
|
138
125
|
body?: XMLHttpRequestBodyInit | Document | null,
|
|
139
126
|
]
|
|
140
127
|
|
|
128
|
+
if (this.sync) {
|
|
129
|
+
console.warn(
|
|
130
|
+
`Failed to intercept an XMLHttpRequest (${this.method} ${this.url}): synchronous requests are not supported. This request will be performed as-is.`
|
|
131
|
+
)
|
|
132
|
+
return invoke()
|
|
133
|
+
}
|
|
134
|
+
|
|
141
135
|
this.request.addEventListener('load', () => {
|
|
142
136
|
if (typeof this.onResponse !== 'undefined') {
|
|
143
137
|
// Create a Fetch API Response representation of whichever
|
|
@@ -156,7 +150,7 @@ export class XMLHttpRequestController {
|
|
|
156
150
|
// Notify the consumer about the response.
|
|
157
151
|
this.onResponse.call(this, {
|
|
158
152
|
response: fetchResponse,
|
|
159
|
-
|
|
153
|
+
responseType: this[kIsRequestHandled] ? 'mock' : 'original',
|
|
160
154
|
request: fetchRequest,
|
|
161
155
|
requestId: this.requestId!,
|
|
162
156
|
})
|
|
@@ -184,27 +178,11 @@ export class XMLHttpRequestController {
|
|
|
184
178
|
onceRequestSettled.finally(() => {
|
|
185
179
|
// If the consumer didn't handle the request (called `.respondWith()`) perform it as-is.
|
|
186
180
|
if (!this[kIsRequestHandled]) {
|
|
187
|
-
this.logger.
|
|
181
|
+
this.logger.verbose(
|
|
188
182
|
'request callback settled but request has not been handled (readystate %d), performing as-is...',
|
|
189
183
|
this.request.readyState
|
|
190
184
|
)
|
|
191
185
|
|
|
192
|
-
/**
|
|
193
|
-
* @note Set the intercepted request ID on the original request in Node.js
|
|
194
|
-
* so that if it triggers any other interceptors, they don't attempt
|
|
195
|
-
* to process it once again.
|
|
196
|
-
*
|
|
197
|
-
* For instance, XMLHttpRequest is often implemented via "http.ClientRequest"
|
|
198
|
-
* and we don't want for both XHR and ClientRequest interceptors to
|
|
199
|
-
* handle the same request at the same time (e.g. emit the "response" event twice).
|
|
200
|
-
*/
|
|
201
|
-
if (IS_NODE) {
|
|
202
|
-
this.request.setRequestHeader(
|
|
203
|
-
INTERNAL_REQUEST_ID_HEADER_NAME,
|
|
204
|
-
this.requestId!
|
|
205
|
-
)
|
|
206
|
-
}
|
|
207
|
-
|
|
208
186
|
return invoke()
|
|
209
187
|
}
|
|
210
188
|
})
|
|
@@ -254,7 +232,7 @@ export class XMLHttpRequestController {
|
|
|
254
232
|
Function,
|
|
255
233
|
]
|
|
256
234
|
this.registerUploadEvent(eventName, listener)
|
|
257
|
-
this.logger.
|
|
235
|
+
this.logger.verbose('upload.addEventListener', eventName, listener)
|
|
258
236
|
|
|
259
237
|
return invoke()
|
|
260
238
|
}
|
|
@@ -272,7 +250,7 @@ export class XMLHttpRequestController {
|
|
|
272
250
|
const nextEvents = prevEvents.concat(listener)
|
|
273
251
|
this.events.set(eventName, nextEvents)
|
|
274
252
|
|
|
275
|
-
this.logger.
|
|
253
|
+
this.logger.verbose('registered event "%s"', eventName, listener)
|
|
276
254
|
}
|
|
277
255
|
|
|
278
256
|
private registerUploadEvent(
|
|
@@ -283,7 +261,7 @@ export class XMLHttpRequestController {
|
|
|
283
261
|
const nextEvents = prevEvents.concat(listener)
|
|
284
262
|
this.uploadEvents.set(eventName, nextEvents)
|
|
285
263
|
|
|
286
|
-
this.logger.
|
|
264
|
+
this.logger.verbose('registered upload event "%s"', eventName, listener)
|
|
287
265
|
}
|
|
288
266
|
|
|
289
267
|
/**
|
|
@@ -301,92 +279,13 @@ export class XMLHttpRequestController {
|
|
|
301
279
|
*/
|
|
302
280
|
this[kIsRequestHandled] = true
|
|
303
281
|
|
|
304
|
-
|
|
305
|
-
* Dispatch request upload events for requests with a body.
|
|
306
|
-
* @see https://github.com/mswjs/interceptors/issues/573
|
|
307
|
-
*/
|
|
308
|
-
if (this[kFetchRequest]) {
|
|
309
|
-
const totalRequestBodyLength = await getBodyByteLength(
|
|
310
|
-
this[kFetchRequest]
|
|
311
|
-
)
|
|
312
|
-
|
|
313
|
-
this.trigger('loadstart', this.request.upload, {
|
|
314
|
-
loaded: 0,
|
|
315
|
-
total: totalRequestBodyLength,
|
|
316
|
-
})
|
|
317
|
-
this.trigger('progress', this.request.upload, {
|
|
318
|
-
loaded: totalRequestBodyLength,
|
|
319
|
-
total: totalRequestBodyLength,
|
|
320
|
-
})
|
|
321
|
-
this.trigger('load', this.request.upload, {
|
|
322
|
-
loaded: totalRequestBodyLength,
|
|
323
|
-
total: totalRequestBodyLength,
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
this.trigger('loadend', this.request.upload, {
|
|
327
|
-
loaded: totalRequestBodyLength,
|
|
328
|
-
total: totalRequestBodyLength,
|
|
329
|
-
})
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
this.logger.info(
|
|
282
|
+
this.logger.verbose(
|
|
333
283
|
'responding with a mocked response: %d %s',
|
|
334
284
|
response.status,
|
|
335
285
|
response.statusText
|
|
336
286
|
)
|
|
337
287
|
|
|
338
|
-
|
|
339
|
-
define(this.request, 'statusText', response.statusText)
|
|
340
|
-
define(this.request, 'responseURL', this.url.href)
|
|
341
|
-
|
|
342
|
-
this.request.getResponseHeader = new Proxy(this.request.getResponseHeader, {
|
|
343
|
-
apply: (_, __, args: [name: string]) => {
|
|
344
|
-
this.logger.info('getResponseHeader', args[0])
|
|
345
|
-
|
|
346
|
-
if (this.request.readyState < this.request.HEADERS_RECEIVED) {
|
|
347
|
-
this.logger.info('headers not received yet, returning null')
|
|
348
|
-
|
|
349
|
-
// Headers not received yet, nothing to return.
|
|
350
|
-
return null
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
const headerValue = response.headers.get(args[0])
|
|
354
|
-
this.logger.info(
|
|
355
|
-
'resolved response header "%s" to',
|
|
356
|
-
args[0],
|
|
357
|
-
headerValue
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
return headerValue
|
|
361
|
-
},
|
|
362
|
-
})
|
|
363
|
-
|
|
364
|
-
this.request.getAllResponseHeaders = new Proxy(
|
|
365
|
-
this.request.getAllResponseHeaders,
|
|
366
|
-
{
|
|
367
|
-
apply: () => {
|
|
368
|
-
this.logger.info('getAllResponseHeaders')
|
|
369
|
-
|
|
370
|
-
if (this.request.readyState < this.request.HEADERS_RECEIVED) {
|
|
371
|
-
this.logger.info('headers not received yet, returning empty string')
|
|
372
|
-
|
|
373
|
-
// Headers not received yet, nothing to return.
|
|
374
|
-
return ''
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const headersList = Array.from(response.headers.entries())
|
|
378
|
-
const allHeaders = headersList
|
|
379
|
-
.map(([headerName, headerValue]) => {
|
|
380
|
-
return `${headerName}: ${headerValue}`
|
|
381
|
-
})
|
|
382
|
-
.join('\r\n')
|
|
383
|
-
|
|
384
|
-
this.logger.info('resolved all response headers to', allHeaders)
|
|
385
|
-
|
|
386
|
-
return allHeaders
|
|
387
|
-
},
|
|
388
|
-
}
|
|
389
|
-
)
|
|
288
|
+
FetchResponse.setUrl(this.url.href, response)
|
|
390
289
|
|
|
391
290
|
// Update the response getters to resolve against the mocked response.
|
|
392
291
|
Object.defineProperties(this.request, {
|
|
@@ -407,65 +306,278 @@ export class XMLHttpRequestController {
|
|
|
407
306
|
},
|
|
408
307
|
})
|
|
409
308
|
|
|
410
|
-
|
|
309
|
+
// 1. Fire a progress event named loadstart at this with 0 and 0.
|
|
310
|
+
this.trigger('loadstart', this.request, { loaded: 0, total: 0 })
|
|
411
311
|
|
|
412
|
-
|
|
312
|
+
// 2. Let requestBodyTransmitted be 0.
|
|
313
|
+
let requestBodyTransmitted = 0
|
|
314
|
+
let uploadComplete = false
|
|
413
315
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
316
|
+
if (this[kFetchRequest]) {
|
|
317
|
+
const requestBodyLength = await getBodyByteLength(
|
|
318
|
+
this[kFetchRequest].clone()
|
|
319
|
+
)
|
|
418
320
|
|
|
419
|
-
|
|
420
|
-
|
|
321
|
+
// 5. If this’s upload complete flag is unset and this’s upload listener flag is set, then fire a progress event named loadstart at this’s upload object with requestBodyTransmitted and requestBodyLength.
|
|
322
|
+
if (!uploadComplete) {
|
|
323
|
+
this.trigger('loadstart', this.request.upload, {
|
|
324
|
+
loaded: 0,
|
|
325
|
+
total: requestBodyLength,
|
|
326
|
+
})
|
|
327
|
+
}
|
|
421
328
|
|
|
422
|
-
|
|
423
|
-
|
|
329
|
+
const processRequestBodyChunkLength = (bytesLength: number) => {
|
|
330
|
+
requestBodyTransmitted += bytesLength
|
|
424
331
|
|
|
332
|
+
if (requestBodyTransmitted < requestBodyLength) {
|
|
333
|
+
this.trigger('progress', this.request.upload, {
|
|
334
|
+
loaded: requestBodyTransmitted,
|
|
335
|
+
total: requestBodyLength,
|
|
336
|
+
})
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const processRequestEndOfBody = () => {
|
|
341
|
+
uploadComplete = true
|
|
342
|
+
|
|
343
|
+
this.trigger('progress', this.request.upload, {
|
|
344
|
+
loaded: requestBodyTransmitted,
|
|
345
|
+
total: requestBodyLength,
|
|
346
|
+
})
|
|
347
|
+
this.trigger('load', this.request.upload, {
|
|
348
|
+
loaded: requestBodyTransmitted,
|
|
349
|
+
total: requestBodyLength,
|
|
350
|
+
})
|
|
351
|
+
this.trigger('loadend', this.request.upload, {
|
|
352
|
+
loaded: requestBodyTransmitted,
|
|
353
|
+
total: requestBodyLength,
|
|
354
|
+
})
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (this[kFetchRequest]?.body != null) {
|
|
358
|
+
const reader = this[kFetchRequest].body.getReader()
|
|
359
|
+
|
|
360
|
+
while (true) {
|
|
361
|
+
const { value, done } = await reader.read()
|
|
362
|
+
|
|
363
|
+
if (done) {
|
|
364
|
+
processRequestEndOfBody()
|
|
365
|
+
break
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
processRequestBodyChunkLength(value.byteLength)
|
|
369
|
+
}
|
|
370
|
+
} else {
|
|
371
|
+
processRequestEndOfBody()
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
let timedOut = false
|
|
376
|
+
const responseReadController = new AbortController()
|
|
377
|
+
|
|
378
|
+
const requestErrorSteps = (
|
|
379
|
+
event: keyof XMLHttpRequestEventTargetEventMap
|
|
380
|
+
) => {
|
|
425
381
|
this.setReadyState(this.request.DONE)
|
|
426
382
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
383
|
+
if (!uploadComplete) {
|
|
384
|
+
this.trigger(event, this.request.upload, {
|
|
385
|
+
loaded: 0,
|
|
386
|
+
total: 0,
|
|
387
|
+
})
|
|
388
|
+
this.trigger('loadend', this.request.upload, {
|
|
389
|
+
loaded: 0,
|
|
390
|
+
total: 0,
|
|
391
|
+
})
|
|
392
|
+
}
|
|
431
393
|
|
|
432
|
-
this.trigger(
|
|
433
|
-
|
|
434
|
-
total: totalResponseBodyLength,
|
|
435
|
-
})
|
|
394
|
+
this.trigger(event, this.request, { loaded: 0, total: 0 })
|
|
395
|
+
this.trigger('loadend', this.request, { loaded: 0, total: 0 })
|
|
436
396
|
}
|
|
437
397
|
|
|
438
|
-
|
|
439
|
-
|
|
398
|
+
const processResponse = async (response: Response) => {
|
|
399
|
+
const handleErrors = () => {
|
|
400
|
+
if (timedOut) {
|
|
401
|
+
requestErrorSteps('timeout')
|
|
402
|
+
} else if (responseReadController.signal.aborted) {
|
|
403
|
+
requestErrorSteps('abort')
|
|
404
|
+
} else if (isResponseError(response)) {
|
|
405
|
+
requestErrorSteps('error')
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
handleErrors()
|
|
410
|
+
|
|
411
|
+
define(this.request, 'status', response.status)
|
|
412
|
+
define(this.request, 'statusText', response.statusText)
|
|
413
|
+
|
|
414
|
+
if (!this.request.responseURL) {
|
|
415
|
+
define(this.request, 'responseURL', response.url)
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (isResponseError(response)) {
|
|
419
|
+
return
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* @note The response body length is derived ONLY from the "content-length" header.
|
|
424
|
+
* If that response header is not set, the "total" in all progress events must be 0.
|
|
425
|
+
*/
|
|
426
|
+
const responseBodyLength = Number(
|
|
427
|
+
response.headers.get('content-length') ?? '0'
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
this.setReadyState(this.request.HEADERS_RECEIVED)
|
|
431
|
+
|
|
432
|
+
let receivedBytes = 0
|
|
433
|
+
let lastReceivedResponseBytesAt = performance.now()
|
|
440
434
|
|
|
441
|
-
const
|
|
435
|
+
const processResponseBodyChunk = (bytesLength: number) => {
|
|
436
|
+
receivedBytes += bytesLength
|
|
442
437
|
|
|
443
|
-
|
|
444
|
-
const
|
|
438
|
+
const now = performance.now()
|
|
439
|
+
const shouldBuffer =
|
|
440
|
+
now - lastReceivedResponseBytesAt <= 60 &&
|
|
441
|
+
receivedBytes < responseBodyLength
|
|
442
|
+
lastReceivedResponseBytesAt = now
|
|
445
443
|
|
|
446
|
-
if (
|
|
447
|
-
this.logger.info('response body stream done!')
|
|
448
|
-
finalizeResponse()
|
|
444
|
+
if (shouldBuffer) {
|
|
449
445
|
return
|
|
450
446
|
}
|
|
451
447
|
|
|
452
|
-
if (
|
|
453
|
-
this.
|
|
454
|
-
|
|
448
|
+
if (this.request.readyState === this.request.HEADERS_RECEIVED) {
|
|
449
|
+
this.setReadyState(this.request.LOADING, false)
|
|
450
|
+
}
|
|
455
451
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
452
|
+
this.trigger('readystatechange', this.request)
|
|
453
|
+
this.trigger('progress', this.request, {
|
|
454
|
+
loaded: receivedBytes,
|
|
455
|
+
total: responseBodyLength,
|
|
456
|
+
})
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const processResponseBodyError = () => {
|
|
460
|
+
requestErrorSteps('error')
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const processResponseEndOfBody = async () => {
|
|
464
|
+
handleErrors()
|
|
465
|
+
|
|
466
|
+
if (isResponseError(response)) {
|
|
467
|
+
return
|
|
460
468
|
}
|
|
461
469
|
|
|
462
|
-
|
|
470
|
+
// 3. Let transmitted be xhr’s received bytes’s length.
|
|
471
|
+
let transmitted = receivedBytes
|
|
472
|
+
|
|
473
|
+
// 9. Fire an event named readystatechange at xhr.
|
|
474
|
+
this.setReadyState(this.request.DONE)
|
|
475
|
+
// 10. Fire a progress event named load at xhr with transmitted and length.
|
|
476
|
+
this.trigger('load', this.request, {
|
|
477
|
+
loaded: transmitted,
|
|
478
|
+
total: responseBodyLength,
|
|
479
|
+
})
|
|
480
|
+
// 11. Fire a progress event named loadend at xhr with transmitted and length.
|
|
481
|
+
this.trigger('loadend', this.request, {
|
|
482
|
+
loaded: transmitted,
|
|
483
|
+
total: responseBodyLength,
|
|
484
|
+
})
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// 7. If this’s response’s body is null, then run handle response end-of-body for this and return.
|
|
488
|
+
if (response.body == null) {
|
|
489
|
+
processResponseEndOfBody()
|
|
490
|
+
} else {
|
|
491
|
+
const reader = response.body.getReader()
|
|
492
|
+
|
|
493
|
+
while (true) {
|
|
494
|
+
if (responseReadController.signal.aborted) {
|
|
495
|
+
break
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
try {
|
|
499
|
+
const { value, done } = await reader.read()
|
|
500
|
+
|
|
501
|
+
if (done) {
|
|
502
|
+
processResponseEndOfBody()
|
|
503
|
+
return
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
processResponseBodyChunk(value.byteLength)
|
|
507
|
+
this.responseBuffer = concatArrayBuffer(this.responseBuffer, value)
|
|
508
|
+
} catch {
|
|
509
|
+
processResponseBodyError()
|
|
510
|
+
}
|
|
511
|
+
}
|
|
463
512
|
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Redirects are followed as a part of the fetch controller. Since we don't have one,
|
|
516
|
+
// retrieve the final response and then continue with processing it instead of the mocked one.
|
|
517
|
+
const [redirectError, finalResponse] = await until(() => {
|
|
518
|
+
return this.followRedirects(response)
|
|
519
|
+
})
|
|
464
520
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
finalizeResponse()
|
|
521
|
+
if (redirectError) {
|
|
522
|
+
return
|
|
468
523
|
}
|
|
524
|
+
|
|
525
|
+
processResponse(finalResponse)
|
|
526
|
+
|
|
527
|
+
// 12.1, 12.2.
|
|
528
|
+
if (this.request.timeout) {
|
|
529
|
+
setTimeout(() => {
|
|
530
|
+
if (this.request.readyState !== this.request.DONE) {
|
|
531
|
+
timedOut = true
|
|
532
|
+
responseReadController.abort()
|
|
533
|
+
}
|
|
534
|
+
}, this.request.timeout)
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
this.request.getResponseHeader = new Proxy(this.request.getResponseHeader, {
|
|
538
|
+
apply: (_, __, args: [name: string]) => {
|
|
539
|
+
this.logger.verbose('getResponseHeader', args[0])
|
|
540
|
+
|
|
541
|
+
if (this.request.readyState < this.request.HEADERS_RECEIVED) {
|
|
542
|
+
this.logger.verbose('headers not received yet, returning null')
|
|
543
|
+
return null
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
const headerValue = finalResponse.headers.get(args[0])
|
|
547
|
+
this.logger.verbose(
|
|
548
|
+
'resolved response header "%s" to',
|
|
549
|
+
args[0],
|
|
550
|
+
headerValue
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
return headerValue
|
|
554
|
+
},
|
|
555
|
+
})
|
|
556
|
+
|
|
557
|
+
this.request.getAllResponseHeaders = new Proxy(
|
|
558
|
+
this.request.getAllResponseHeaders,
|
|
559
|
+
{
|
|
560
|
+
apply: () => {
|
|
561
|
+
this.logger.verbose('getAllResponseHeaders')
|
|
562
|
+
|
|
563
|
+
if (this.request.readyState < this.request.HEADERS_RECEIVED) {
|
|
564
|
+
this.logger.verbose('headers not received yet, returning empty string')
|
|
565
|
+
return ''
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
const headersList = Array.from(finalResponse.headers)
|
|
569
|
+
const allHeaders = headersList
|
|
570
|
+
.map(([headerName, headerValue]) => {
|
|
571
|
+
return `${headerName}: ${headerValue}`
|
|
572
|
+
})
|
|
573
|
+
.join('\r\n')
|
|
574
|
+
|
|
575
|
+
this.logger.verbose('resolved all response headers to', allHeaders)
|
|
576
|
+
|
|
577
|
+
return allHeaders
|
|
578
|
+
},
|
|
579
|
+
}
|
|
580
|
+
)
|
|
469
581
|
}
|
|
470
582
|
|
|
471
583
|
private responseBufferToText(): string {
|
|
@@ -473,7 +585,7 @@ export class XMLHttpRequestController {
|
|
|
473
585
|
}
|
|
474
586
|
|
|
475
587
|
get response(): unknown {
|
|
476
|
-
this.logger.
|
|
588
|
+
this.logger.verbose(
|
|
477
589
|
'getResponse (responseType: %s)',
|
|
478
590
|
this.request.responseType
|
|
479
591
|
)
|
|
@@ -485,14 +597,14 @@ export class XMLHttpRequestController {
|
|
|
485
597
|
switch (this.request.responseType) {
|
|
486
598
|
case 'json': {
|
|
487
599
|
const responseJson = parseJson(this.responseBufferToText())
|
|
488
|
-
this.logger.
|
|
600
|
+
this.logger.verbose('resolved response JSON', responseJson)
|
|
489
601
|
|
|
490
602
|
return responseJson
|
|
491
603
|
}
|
|
492
604
|
|
|
493
605
|
case 'arraybuffer': {
|
|
494
606
|
const arrayBuffer = toArrayBuffer(this.responseBuffer)
|
|
495
|
-
this.logger.
|
|
607
|
+
this.logger.verbose('resolved response ArrayBuffer', arrayBuffer)
|
|
496
608
|
|
|
497
609
|
return arrayBuffer
|
|
498
610
|
}
|
|
@@ -504,7 +616,7 @@ export class XMLHttpRequestController {
|
|
|
504
616
|
type: mimeType,
|
|
505
617
|
})
|
|
506
618
|
|
|
507
|
-
this.logger.
|
|
619
|
+
this.logger.verbose(
|
|
508
620
|
'resolved response Blob (mime type: %s)',
|
|
509
621
|
responseBlob,
|
|
510
622
|
mimeType
|
|
@@ -515,7 +627,7 @@ export class XMLHttpRequestController {
|
|
|
515
627
|
|
|
516
628
|
default: {
|
|
517
629
|
const responseText = this.responseBufferToText()
|
|
518
|
-
this.logger.
|
|
630
|
+
this.logger.verbose(
|
|
519
631
|
'resolving "%s" response type as text',
|
|
520
632
|
this.request.responseType,
|
|
521
633
|
responseText
|
|
@@ -545,7 +657,7 @@ export class XMLHttpRequestController {
|
|
|
545
657
|
}
|
|
546
658
|
|
|
547
659
|
const responseText = this.responseBufferToText()
|
|
548
|
-
this.logger.
|
|
660
|
+
this.logger.verbose('getResponseText: "%s"', responseText)
|
|
549
661
|
|
|
550
662
|
return responseText
|
|
551
663
|
}
|
|
@@ -580,13 +692,55 @@ export class XMLHttpRequestController {
|
|
|
580
692
|
return null
|
|
581
693
|
}
|
|
582
694
|
|
|
695
|
+
private async followRedirects(response: Response): Promise<Response> {
|
|
696
|
+
const redirectLocation = response.headers.get('location')
|
|
697
|
+
|
|
698
|
+
if (
|
|
699
|
+
!redirectLocation ||
|
|
700
|
+
!FetchResponse.isRedirectResponse(response.status)
|
|
701
|
+
) {
|
|
702
|
+
return response
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
this.redirectCount++
|
|
706
|
+
|
|
707
|
+
if (this.redirectCount > MAX_REDIRECTS) {
|
|
708
|
+
throw new Error('Too many redirects')
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
const redirectUrl = new URL(redirectLocation, location.href)
|
|
712
|
+
const redirectMethod = FetchResponse.isResponseWithBody(response.status)
|
|
713
|
+
? this.method
|
|
714
|
+
: 'GET'
|
|
715
|
+
|
|
716
|
+
const redirectResponse = await new Promise<Response>((resolve, reject) => {
|
|
717
|
+
const request = new XMLHttpRequest()
|
|
718
|
+
request.responseType = this.request.responseType
|
|
719
|
+
|
|
720
|
+
request.addEventListener('load', () => {
|
|
721
|
+
this.url = new URL(request.responseURL)
|
|
722
|
+
resolve(createResponse(request, request.response))
|
|
723
|
+
})
|
|
724
|
+
|
|
725
|
+
request.addEventListener('error', () => {
|
|
726
|
+
this.errorWith()
|
|
727
|
+
reject(new Error('Redirect request failed'))
|
|
728
|
+
})
|
|
729
|
+
|
|
730
|
+
request.open(redirectMethod, redirectUrl.href)
|
|
731
|
+
request.send()
|
|
732
|
+
})
|
|
733
|
+
|
|
734
|
+
return this.followRedirects(redirectResponse)
|
|
735
|
+
}
|
|
736
|
+
|
|
583
737
|
public errorWith(error?: Error): void {
|
|
584
738
|
/**
|
|
585
739
|
* @note Mark this request as handled even if it received a mock error.
|
|
586
740
|
* This prevents the controller from trying to perform this request as-is.
|
|
587
741
|
*/
|
|
588
742
|
this[kIsRequestHandled] = true
|
|
589
|
-
this.logger.
|
|
743
|
+
this.logger.verbose('responding with an error')
|
|
590
744
|
|
|
591
745
|
this.setReadyState(this.request.DONE)
|
|
592
746
|
this.trigger('error', this.request)
|
|
@@ -596,24 +750,31 @@ export class XMLHttpRequestController {
|
|
|
596
750
|
/**
|
|
597
751
|
* Transitions this request's `readyState` to the given one.
|
|
598
752
|
*/
|
|
599
|
-
private setReadyState(
|
|
600
|
-
|
|
753
|
+
private setReadyState(
|
|
754
|
+
nextReadyState: number,
|
|
755
|
+
triggerReadyStateChangeEvent = true
|
|
756
|
+
): void {
|
|
757
|
+
this.logger.verbose(
|
|
601
758
|
'setReadyState: %d -> %d',
|
|
602
759
|
this.request.readyState,
|
|
603
760
|
nextReadyState
|
|
604
761
|
)
|
|
605
762
|
|
|
606
763
|
if (this.request.readyState === nextReadyState) {
|
|
607
|
-
this.logger.
|
|
764
|
+
this.logger.verbose('ready state identical, skipping transition...')
|
|
608
765
|
return
|
|
609
766
|
}
|
|
610
767
|
|
|
611
768
|
define(this.request, 'readyState', nextReadyState)
|
|
612
769
|
|
|
613
|
-
this.logger.
|
|
770
|
+
this.logger.verbose('set readyState to: %d', nextReadyState)
|
|
771
|
+
|
|
772
|
+
if (!triggerReadyStateChangeEvent) {
|
|
773
|
+
return
|
|
774
|
+
}
|
|
614
775
|
|
|
615
776
|
if (nextReadyState !== this.request.UNSENT) {
|
|
616
|
-
this.logger.
|
|
777
|
+
this.logger.verbose('triggering "readystatechange" event...')
|
|
617
778
|
|
|
618
779
|
this.trigger('readystatechange', this.request)
|
|
619
780
|
}
|
|
@@ -634,11 +795,11 @@ export class XMLHttpRequestController {
|
|
|
634
795
|
const callback = (target as XMLHttpRequest)[`on${eventName}`]
|
|
635
796
|
const event = createEvent(target, eventName, options)
|
|
636
797
|
|
|
637
|
-
this.logger.
|
|
798
|
+
this.logger.verbose('trigger "%s"', eventName, options || '')
|
|
638
799
|
|
|
639
800
|
// Invoke direct callbacks.
|
|
640
801
|
if (typeof callback === 'function') {
|
|
641
|
-
this.logger.
|
|
802
|
+
this.logger.verbose('found a direct "%s" callback, calling...', eventName)
|
|
642
803
|
callback.call(target as XMLHttpRequest, event)
|
|
643
804
|
}
|
|
644
805
|
|
|
@@ -648,7 +809,7 @@ export class XMLHttpRequestController {
|
|
|
648
809
|
|
|
649
810
|
for (const [registeredEventName, listeners] of events) {
|
|
650
811
|
if (registeredEventName === eventName) {
|
|
651
|
-
this.logger.
|
|
812
|
+
this.logger.verbose(
|
|
652
813
|
'found %d listener(s) for "%s" event, calling...',
|
|
653
814
|
listeners.length,
|
|
654
815
|
eventName
|
|
@@ -665,7 +826,7 @@ export class XMLHttpRequestController {
|
|
|
665
826
|
private toFetchApiRequest(
|
|
666
827
|
body: XMLHttpRequestBodyInit | Document | null | undefined
|
|
667
828
|
): Request {
|
|
668
|
-
this.logger.
|
|
829
|
+
this.logger.verbose('converting request to a Fetch API Request...')
|
|
669
830
|
|
|
670
831
|
// If the `Document` is used as the body of this XMLHttpRequest,
|
|
671
832
|
// set its inner text as the Fetch API Request body.
|
|
@@ -679,9 +840,7 @@ export class XMLHttpRequestController {
|
|
|
679
840
|
* @see https://xhr.spec.whatwg.org/#cross-origin-credentials
|
|
680
841
|
*/
|
|
681
842
|
credentials: this.request.withCredentials ? 'include' : 'same-origin',
|
|
682
|
-
body:
|
|
683
|
-
? null
|
|
684
|
-
: resolvedBody,
|
|
843
|
+
body: resolvedBody,
|
|
685
844
|
})
|
|
686
845
|
|
|
687
846
|
const proxyHeaders = createProxy(fetchRequest.headers, {
|
|
@@ -710,9 +869,9 @@ export class XMLHttpRequestController {
|
|
|
710
869
|
},
|
|
711
870
|
})
|
|
712
871
|
define(fetchRequest, 'headers', proxyHeaders)
|
|
713
|
-
setRawRequest(fetchRequest, this.request)
|
|
872
|
+
// setRawRequest(fetchRequest, this.request)
|
|
714
873
|
|
|
715
|
-
this.logger.
|
|
874
|
+
this.logger.verbose('converted request to a Fetch API Request!', fetchRequest)
|
|
716
875
|
|
|
717
876
|
return fetchRequest
|
|
718
877
|
}
|