@mswjs/interceptors 0.41.9 → 0.42.1
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-Bk5YX1AM.js +720 -0
- package/lib/browser/create-request-id-Bk5YX1AM.js.map +1 -0
- package/lib/browser/{getRawRequest-B1BqgWG6.mjs → fetch-utils-CUOrwEQf.js} +123 -52
- package/lib/browser/fetch-utils-CUOrwEQf.js.map +1 -0
- package/lib/browser/handle-request-CqVvBhcw.js +167 -0
- package/lib/browser/handle-request-CqVvBhcw.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/{XMLHttpRequest-DrZAf3w6.mjs → web-BcKSQghf.js} +327 -255
- package/lib/browser/web-BcKSQghf.js.map +1 -0
- package/lib/browser/web-CdcYFjgm.js +248 -0
- package/lib/browser/web-CdcYFjgm.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
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type DisposableSubscription = () => void
|
|
2
|
+
|
|
3
|
+
export class Disposable {
|
|
4
|
+
protected subscriptions: Array<DisposableSubscription> = []
|
|
5
|
+
|
|
6
|
+
public dispose() {
|
|
7
|
+
let subscription: DisposableSubscription | undefined
|
|
8
|
+
|
|
9
|
+
while ((subscription = this.subscriptions.pop())) {
|
|
10
|
+
subscription()
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { TypedEvent } from 'rettime'
|
|
2
|
+
import type { RequestController } from '../request-controller'
|
|
3
|
+
|
|
4
|
+
export interface HttpRequestEventData {
|
|
5
|
+
request: Request
|
|
6
|
+
requestId: string
|
|
7
|
+
initiator: unknown
|
|
8
|
+
controller: RequestController
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class HttpRequestEvent<
|
|
12
|
+
DataType extends HttpRequestEventData = HttpRequestEventData,
|
|
13
|
+
> extends TypedEvent<DataType, void, 'request'> {
|
|
14
|
+
public request: Request
|
|
15
|
+
public requestId: string
|
|
16
|
+
public initiator: unknown
|
|
17
|
+
public controller: RequestController
|
|
18
|
+
|
|
19
|
+
constructor(data: DataType) {
|
|
20
|
+
super(...(['request', {}] as any))
|
|
21
|
+
|
|
22
|
+
this.request = data.request
|
|
23
|
+
this.requestId = data.requestId
|
|
24
|
+
this.initiator = data.initiator
|
|
25
|
+
this.controller = data.controller
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type HttpResponseType = 'mock' | 'original'
|
|
30
|
+
|
|
31
|
+
interface HttpResponseEventData {
|
|
32
|
+
response: Response
|
|
33
|
+
responseType: HttpResponseType
|
|
34
|
+
request: Request
|
|
35
|
+
requestId: string
|
|
36
|
+
initiator: unknown
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class HttpResponseEvent<
|
|
40
|
+
DataType extends HttpResponseEventData = HttpResponseEventData,
|
|
41
|
+
> extends TypedEvent<DataType, void, 'response'> {
|
|
42
|
+
public response: Response
|
|
43
|
+
public responseType: HttpResponseType
|
|
44
|
+
public request: Request
|
|
45
|
+
public requestId: string
|
|
46
|
+
public initiator: unknown
|
|
47
|
+
|
|
48
|
+
constructor(data: DataType) {
|
|
49
|
+
super(...(['response', {}] as any))
|
|
50
|
+
|
|
51
|
+
this.response = data.response
|
|
52
|
+
this.responseType = data.responseType
|
|
53
|
+
this.request = data.request
|
|
54
|
+
this.requestId = data.requestId
|
|
55
|
+
this.initiator = data.initiator
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface UnhandledHttpExceptionEventData {
|
|
60
|
+
error: unknown
|
|
61
|
+
request: Request
|
|
62
|
+
requestId: string
|
|
63
|
+
initiator: unknown
|
|
64
|
+
controller: RequestController
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export class UnhandledHttpException<
|
|
68
|
+
DataType extends UnhandledHttpExceptionEventData =
|
|
69
|
+
UnhandledHttpExceptionEventData,
|
|
70
|
+
> extends TypedEvent<DataType, void, 'unhandledException'> {
|
|
71
|
+
public error: unknown
|
|
72
|
+
public request: Request
|
|
73
|
+
public requestId: string
|
|
74
|
+
public initiator: unknown
|
|
75
|
+
public controller: RequestController
|
|
76
|
+
|
|
77
|
+
constructor(data: DataType) {
|
|
78
|
+
super(...(['unhandledException', {}] as any))
|
|
79
|
+
|
|
80
|
+
this.error = data.error
|
|
81
|
+
this.request = data.request
|
|
82
|
+
this.requestId = data.requestId
|
|
83
|
+
this.initiator = data.initiator
|
|
84
|
+
this.controller = data.controller
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type HttpRequestEventMap = {
|
|
89
|
+
request: HttpRequestEvent
|
|
90
|
+
response: HttpResponseEvent
|
|
91
|
+
unhandledException: UnhandledHttpException
|
|
92
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { TypedEvent } from 'rettime'
|
|
2
|
+
import type {
|
|
3
|
+
WebSocketClientConnection,
|
|
4
|
+
WebSocketServerConnection,
|
|
5
|
+
} from '../interceptors/WebSocket'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The connection information.
|
|
9
|
+
*/
|
|
10
|
+
interface WebSocketConnectionInfo {
|
|
11
|
+
/**
|
|
12
|
+
* The protocols supported by the WebSocket client.
|
|
13
|
+
*/
|
|
14
|
+
protocols: string | Array<string> | undefined
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface WebSocketConnectionEventData {
|
|
18
|
+
/**
|
|
19
|
+
* The incoming WebSocket client connection.
|
|
20
|
+
*/
|
|
21
|
+
client: WebSocketClientConnection
|
|
22
|
+
/**
|
|
23
|
+
* The original WebSocket server connection.
|
|
24
|
+
*/
|
|
25
|
+
server: WebSocketServerConnection
|
|
26
|
+
info: WebSocketConnectionInfo
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class WebSocketConnectionEvent<
|
|
30
|
+
DataType extends WebSocketConnectionEventData = WebSocketConnectionEventData,
|
|
31
|
+
> extends TypedEvent<DataType, void, 'connection'> {
|
|
32
|
+
public client: WebSocketClientConnection
|
|
33
|
+
public server: WebSocketServerConnection
|
|
34
|
+
public info: WebSocketConnectionInfo
|
|
35
|
+
|
|
36
|
+
constructor(data: DataType) {
|
|
37
|
+
super(...(['connection', {}] as any))
|
|
38
|
+
|
|
39
|
+
this.client = data.client
|
|
40
|
+
this.server = data.server
|
|
41
|
+
this.info = data.info
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type WebSocketEventMap = {
|
|
46
|
+
connection: WebSocketConnectionEvent
|
|
47
|
+
}
|
package/src/glossary.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RequestController } from './
|
|
1
|
+
import type { RequestController } from './request-controller'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @note Export `RequestController` as a type only.
|
|
@@ -7,29 +7,3 @@ import type { RequestController } from './RequestController'
|
|
|
7
7
|
export type { RequestController }
|
|
8
8
|
|
|
9
9
|
export type RequestCredentials = 'omit' | 'include' | 'same-origin'
|
|
10
|
-
|
|
11
|
-
export type HttpRequestEventMap = {
|
|
12
|
-
request: [
|
|
13
|
-
args: {
|
|
14
|
-
request: Request
|
|
15
|
-
requestId: string
|
|
16
|
-
controller: RequestController
|
|
17
|
-
},
|
|
18
|
-
]
|
|
19
|
-
response: [
|
|
20
|
-
args: {
|
|
21
|
-
response: Response
|
|
22
|
-
isMockedResponse: boolean
|
|
23
|
-
request: Request
|
|
24
|
-
requestId: string
|
|
25
|
-
},
|
|
26
|
-
]
|
|
27
|
-
unhandledException: [
|
|
28
|
-
args: {
|
|
29
|
-
error: unknown
|
|
30
|
-
request: Request
|
|
31
|
-
requestId: string
|
|
32
|
-
controller: RequestController
|
|
33
|
-
},
|
|
34
|
-
]
|
|
35
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
1
|
+
export { Interceptor } from './interceptor'
|
|
2
|
+
export { BatchInterceptor } from './batch-interceptor'
|
|
3
|
+
export { InterceptorError } from './interceptor-error'
|
|
4
4
|
export {
|
|
5
5
|
RequestController,
|
|
6
6
|
type RequestControllerSource,
|
|
7
|
-
} from './
|
|
7
|
+
} from './request-controller'
|
|
8
|
+
export type {
|
|
9
|
+
HttpRequestEventMap,
|
|
10
|
+
HttpRequestEvent,
|
|
11
|
+
HttpResponseEvent,
|
|
12
|
+
} from './events/http'
|
|
13
|
+
export type {
|
|
14
|
+
WebSocketEventMap,
|
|
15
|
+
WebSocketConnectionEvent,
|
|
16
|
+
} from './events/websocket'
|
|
8
17
|
|
|
9
18
|
/* Utils */
|
|
10
|
-
export { createRequestId } from './
|
|
11
|
-
export { getCleanUrl } from './utils/
|
|
12
|
-
export { encodeBuffer, decodeBuffer } from './utils/
|
|
13
|
-
export { FetchRequest, FetchResponse } from './utils/
|
|
14
|
-
export {
|
|
15
|
-
export { resolveWebSocketUrl } from './utils/resolveWebSocketUrl'
|
|
19
|
+
export { createRequestId } from './create-request-id'
|
|
20
|
+
export { getCleanUrl } from './utils/get-clean-url'
|
|
21
|
+
export { encodeBuffer, decodeBuffer } from './utils/buffer-utils'
|
|
22
|
+
export { FetchRequest, FetchResponse } from './utils/fetch-utils'
|
|
23
|
+
export { resolveWebSocketUrl } from './utils/resolve-web-socket-url'
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { TypedEvent } from 'rettime'
|
|
2
|
+
import { Interceptor, InterceptorReadyState } from './interceptor'
|
|
3
|
+
|
|
4
|
+
it('nesting interceptors', async () => {
|
|
5
|
+
const socketSetup = vi.fn()
|
|
6
|
+
const protocolSetup = vi.fn()
|
|
7
|
+
|
|
8
|
+
class SocketInterceptor extends Interceptor<{
|
|
9
|
+
data: TypedEvent<string | number>
|
|
10
|
+
}> {
|
|
11
|
+
static symbol = Symbol.for('socket-interceptor')
|
|
12
|
+
|
|
13
|
+
protected predicate(): boolean {
|
|
14
|
+
return true
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
protected setup(): void {
|
|
18
|
+
socketSetup()
|
|
19
|
+
|
|
20
|
+
queueMicrotask(() => {
|
|
21
|
+
this.emitter.emit(new TypedEvent('data', { data: 1 }))
|
|
22
|
+
this.emitter.emit(new TypedEvent('data', { data: 'hello' }))
|
|
23
|
+
this.emitter.emit(new TypedEvent('data', { data: 2 }))
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
class ProtocolInterceptor extends Interceptor<{
|
|
29
|
+
request: TypedEvent<string | number>
|
|
30
|
+
}> {
|
|
31
|
+
static symbol = Symbol.for('protocol-interceptor')
|
|
32
|
+
|
|
33
|
+
protected predicate(): boolean {
|
|
34
|
+
return true
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected setup(): void {
|
|
38
|
+
protocolSetup()
|
|
39
|
+
|
|
40
|
+
const socket = Interceptor.singleton(SocketInterceptor)
|
|
41
|
+
socket.apply(this)
|
|
42
|
+
this.subscriptions.push(() => {
|
|
43
|
+
socket.dispose(this)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const controller = new AbortController()
|
|
47
|
+
this.subscriptions.push(() => controller.abort())
|
|
48
|
+
|
|
49
|
+
socket.on(
|
|
50
|
+
'data',
|
|
51
|
+
({ data }) => {
|
|
52
|
+
this.emitter.emit(new TypedEvent('request', { data }))
|
|
53
|
+
},
|
|
54
|
+
{ signal: controller.signal }
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
class NumberInterceptor extends Interceptor<{
|
|
60
|
+
number: TypedEvent<number>
|
|
61
|
+
}> {
|
|
62
|
+
static symbol = Symbol.for('number-interceptor')
|
|
63
|
+
|
|
64
|
+
protected predicate(): boolean {
|
|
65
|
+
return true
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
protected setup(): void {
|
|
69
|
+
const protocol = Interceptor.singleton(ProtocolInterceptor)
|
|
70
|
+
protocol.apply(this)
|
|
71
|
+
this.subscriptions.push(() => {
|
|
72
|
+
protocol.dispose(this)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const controller = new AbortController()
|
|
76
|
+
this.subscriptions.push(() => controller.abort())
|
|
77
|
+
|
|
78
|
+
protocol.on(
|
|
79
|
+
'request',
|
|
80
|
+
({ data }) => {
|
|
81
|
+
if (typeof data === 'number') {
|
|
82
|
+
this.emitter.emit(new TypedEvent('number', { data }))
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
{ signal: controller.signal }
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
class StringInterceptor extends Interceptor<{
|
|
91
|
+
string: TypedEvent<string>
|
|
92
|
+
}> {
|
|
93
|
+
static symbol = Symbol.for('string-interceptor')
|
|
94
|
+
|
|
95
|
+
protected predicate(): boolean {
|
|
96
|
+
return true
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
protected setup(): void {
|
|
100
|
+
const protocol = Interceptor.singleton(ProtocolInterceptor)
|
|
101
|
+
protocol.apply(this)
|
|
102
|
+
this.subscriptions.push(() => {
|
|
103
|
+
protocol.dispose(this)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
const controller = new AbortController()
|
|
107
|
+
this.subscriptions.push(() => controller.abort())
|
|
108
|
+
|
|
109
|
+
protocol.on(
|
|
110
|
+
'request',
|
|
111
|
+
({ data }) => {
|
|
112
|
+
if (typeof data === 'string') {
|
|
113
|
+
this.emitter.emit(new TypedEvent('string', { data }))
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{ signal: controller.signal }
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const numberListener = vi.fn()
|
|
122
|
+
const numberInterceptor = new NumberInterceptor()
|
|
123
|
+
numberInterceptor.on('number', ({ data }) => numberListener(data))
|
|
124
|
+
numberInterceptor.apply()
|
|
125
|
+
|
|
126
|
+
const stringListener = vi.fn()
|
|
127
|
+
const stringInterceptor = new StringInterceptor()
|
|
128
|
+
stringInterceptor.on('string', ({ data }) => stringListener(data))
|
|
129
|
+
stringInterceptor.apply()
|
|
130
|
+
|
|
131
|
+
expect(socketSetup).toHaveBeenCalledOnce()
|
|
132
|
+
expect(protocolSetup).toHaveBeenCalledOnce()
|
|
133
|
+
|
|
134
|
+
await expect.poll(() => numberListener).toHaveBeenCalledTimes(2)
|
|
135
|
+
|
|
136
|
+
const protocolInterceptor = Interceptor.singleton(ProtocolInterceptor)
|
|
137
|
+
|
|
138
|
+
numberInterceptor.dispose()
|
|
139
|
+
expect(protocolInterceptor.readyState).toBe(InterceptorReadyState.ACTIVE)
|
|
140
|
+
|
|
141
|
+
stringInterceptor.dispose()
|
|
142
|
+
expect(protocolInterceptor.readyState).toBe(InterceptorReadyState.DISPOSED)
|
|
143
|
+
|
|
144
|
+
expect(numberListener).toHaveBeenNthCalledWith(1, 1)
|
|
145
|
+
expect(numberListener).toHaveBeenNthCalledWith(2, 2)
|
|
146
|
+
expect(stringListener).toHaveBeenCalledExactlyOnceWith('hello')
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('treats an interceptor as a singleton via "Interceptor.singleton()"', () => {
|
|
150
|
+
const setup = vi.fn()
|
|
151
|
+
const dispose = vi.fn()
|
|
152
|
+
|
|
153
|
+
class MyInterceptor extends Interceptor<{ test: TypedEvent }> {
|
|
154
|
+
protected predicate(): boolean {
|
|
155
|
+
return true
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
protected setup(): void {
|
|
159
|
+
setup()
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public dispose(): void {
|
|
163
|
+
super.dispose()
|
|
164
|
+
dispose()
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const interceptor = Interceptor.singleton(MyInterceptor)
|
|
169
|
+
expect(setup).not.toHaveBeenCalled()
|
|
170
|
+
|
|
171
|
+
interceptor.apply()
|
|
172
|
+
expect(setup).toHaveBeenCalledOnce()
|
|
173
|
+
|
|
174
|
+
{
|
|
175
|
+
const interceptor = Interceptor.singleton(MyInterceptor)
|
|
176
|
+
expect(setup).toHaveBeenCalledOnce()
|
|
177
|
+
|
|
178
|
+
interceptor.dispose()
|
|
179
|
+
expect(dispose).toHaveBeenCalledOnce()
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
interceptor.dispose()
|
|
183
|
+
expect(dispose).toHaveBeenCalledTimes(2)
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it('keeps an interceptor active until all owners dispose', () => {
|
|
187
|
+
const setup = vi.fn()
|
|
188
|
+
const teardown = vi.fn()
|
|
189
|
+
|
|
190
|
+
class MyInterceptor extends Interceptor<{}> {
|
|
191
|
+
protected predicate(): boolean {
|
|
192
|
+
return true
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
protected setup(): void {
|
|
196
|
+
setup()
|
|
197
|
+
this.subscriptions.push(teardown)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const interceptor = new MyInterceptor()
|
|
202
|
+
const primaryOwner = {}
|
|
203
|
+
const secondaryOwner = {}
|
|
204
|
+
|
|
205
|
+
interceptor.apply(primaryOwner)
|
|
206
|
+
interceptor.apply(primaryOwner)
|
|
207
|
+
interceptor.apply(secondaryOwner)
|
|
208
|
+
|
|
209
|
+
expect(setup).toHaveBeenCalledOnce()
|
|
210
|
+
|
|
211
|
+
interceptor.dispose(primaryOwner)
|
|
212
|
+
|
|
213
|
+
expect(interceptor.readyState).toBe(InterceptorReadyState.ACTIVE)
|
|
214
|
+
expect(teardown).not.toHaveBeenCalled()
|
|
215
|
+
|
|
216
|
+
interceptor.dispose(secondaryOwner)
|
|
217
|
+
|
|
218
|
+
expect(interceptor.readyState).toBe(InterceptorReadyState.DISPOSED)
|
|
219
|
+
expect(teardown).toHaveBeenCalledOnce()
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
it('treats repeated public application as one ownership lease', () => {
|
|
223
|
+
class MyInterceptor extends Interceptor<{}> {
|
|
224
|
+
protected predicate(): boolean {
|
|
225
|
+
return true
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
protected setup(): void {}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const interceptor = new MyInterceptor()
|
|
232
|
+
|
|
233
|
+
interceptor.apply()
|
|
234
|
+
interceptor.apply()
|
|
235
|
+
interceptor.dispose()
|
|
236
|
+
|
|
237
|
+
expect(interceptor.readyState).toBe(InterceptorReadyState.DISPOSED)
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
it('removes all listeners when the interceptor is disposed', () => {
|
|
241
|
+
class MyInterceptor extends Interceptor<{ test: TypedEvent }> {
|
|
242
|
+
protected predicate(): boolean {
|
|
243
|
+
return true
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
protected setup(): void {}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const interceptor = new MyInterceptor()
|
|
250
|
+
interceptor.apply()
|
|
251
|
+
|
|
252
|
+
const listener = vi.fn()
|
|
253
|
+
interceptor.on('test', listener)
|
|
254
|
+
|
|
255
|
+
interceptor.dispose()
|
|
256
|
+
|
|
257
|
+
interceptor['emitter'].emit(new TypedEvent('test'))
|
|
258
|
+
expect(listener).not.toHaveBeenCalled()
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
it('applies the interceptor after disposal', () => {
|
|
262
|
+
class MyInterceptor extends Interceptor<{}> {
|
|
263
|
+
protected predicate(): boolean {
|
|
264
|
+
return true
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
protected setup(): void {}
|
|
268
|
+
}
|
|
269
|
+
const interceptor = new MyInterceptor()
|
|
270
|
+
|
|
271
|
+
interceptor.apply()
|
|
272
|
+
expect(interceptor.readyState).toBe(InterceptorReadyState.ACTIVE)
|
|
273
|
+
|
|
274
|
+
interceptor.dispose()
|
|
275
|
+
expect(interceptor.readyState).toBe(InterceptorReadyState.DISPOSED)
|
|
276
|
+
|
|
277
|
+
interceptor.apply()
|
|
278
|
+
expect(interceptor.readyState).toBe(InterceptorReadyState.ACTIVE)
|
|
279
|
+
})
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Emitter, type DefaultEventMap } from 'rettime'
|
|
2
|
+
import { Disposable } from './disposable'
|
|
3
|
+
import { createLogger, type Logger } from './utils/logger'
|
|
4
|
+
|
|
5
|
+
export enum InterceptorReadyState {
|
|
6
|
+
INACTIVE = 'INACTIVE',
|
|
7
|
+
ACTIVE = 'ACTIVE',
|
|
8
|
+
DISPOSED = 'DISPOSED',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare global {
|
|
12
|
+
var __MSW_INTERCEPTORS_REGISTRY: Map<symbol, Interceptor<any>> | undefined
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const interceptorsRegistry = (globalThis.__MSW_INTERCEPTORS_REGISTRY ??=
|
|
16
|
+
new Map<symbol, Interceptor<any>>())
|
|
17
|
+
|
|
18
|
+
export abstract class Interceptor<
|
|
19
|
+
Events extends DefaultEventMap,
|
|
20
|
+
> extends Disposable {
|
|
21
|
+
declare ['constructor']: typeof Interceptor
|
|
22
|
+
|
|
23
|
+
protected emitter: Emitter<Events>
|
|
24
|
+
protected readonly logger: Logger
|
|
25
|
+
|
|
26
|
+
public readyState: InterceptorReadyState
|
|
27
|
+
|
|
28
|
+
static readonly symbol: symbol
|
|
29
|
+
|
|
30
|
+
#owners: Set<object>
|
|
31
|
+
|
|
32
|
+
static singleton<T extends Interceptor<any>>(
|
|
33
|
+
InterceptorClass: (new () => T) & { symbol: symbol }
|
|
34
|
+
): T {
|
|
35
|
+
const symbol = InterceptorClass.symbol
|
|
36
|
+
const existing = interceptorsRegistry.get(symbol)
|
|
37
|
+
|
|
38
|
+
if (existing instanceof InterceptorClass) {
|
|
39
|
+
return existing
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const newInstance = new InterceptorClass()
|
|
43
|
+
interceptorsRegistry.set(symbol, newInstance)
|
|
44
|
+
return newInstance
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
constructor() {
|
|
48
|
+
super()
|
|
49
|
+
|
|
50
|
+
this.#owners = new Set()
|
|
51
|
+
this.readyState = InterceptorReadyState.INACTIVE
|
|
52
|
+
this.emitter = new Emitter()
|
|
53
|
+
this.logger = createLogger(this.#getLoggerNamespace())
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
protected abstract predicate(): boolean
|
|
57
|
+
protected abstract setup(): void
|
|
58
|
+
|
|
59
|
+
public apply(owner: object = this): void {
|
|
60
|
+
if (this.#owners.has(owner)) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (
|
|
65
|
+
this.readyState !== InterceptorReadyState.ACTIVE &&
|
|
66
|
+
!this.predicate()
|
|
67
|
+
) {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this.#owners.add(owner)
|
|
72
|
+
|
|
73
|
+
if (this.readyState === InterceptorReadyState.ACTIVE) {
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
this.setup()
|
|
79
|
+
this.readyState = InterceptorReadyState.ACTIVE
|
|
80
|
+
this.logger.info('apply')
|
|
81
|
+
} catch (error) {
|
|
82
|
+
this.dispose(owner)
|
|
83
|
+
throw error
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public dispose(owner: object = this): void {
|
|
88
|
+
if (!this.#owners.delete(owner)) {
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (this.#owners.size > 0) {
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
super.dispose()
|
|
97
|
+
this.emitter.removeAllListeners()
|
|
98
|
+
this.readyState = InterceptorReadyState.DISPOSED
|
|
99
|
+
this.logger.info('disable')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public on: Emitter<Events>['on'] = (type, listener, options) => {
|
|
103
|
+
return this.emitter.on(type, listener, options)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public once: Emitter<Events>['once'] = (type, listener, options) => {
|
|
107
|
+
return this.emitter.once(type, listener, options)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public listeners: Emitter<Events>['listeners'] = (type) => {
|
|
111
|
+
return this.emitter.listeners(type)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public listenerCount: Emitter<Events>['listenerCount'] = (type) => {
|
|
115
|
+
return this.emitter.listenerCount(type)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public removeListener: Emitter<Events>['removeListener'] = (
|
|
119
|
+
type,
|
|
120
|
+
listener
|
|
121
|
+
) => {
|
|
122
|
+
return this.emitter.removeListener(type, listener)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public removeAllListeners: Emitter<Events>['removeAllListeners'] = (type) => {
|
|
126
|
+
this.logger.info('removeAllListeners %o', { eventType: type ?? '*' })
|
|
127
|
+
return this.emitter.removeAllListeners(type)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#getLoggerNamespace(): string {
|
|
131
|
+
const symbolDescription = this.constructor.symbol?.description
|
|
132
|
+
|
|
133
|
+
if (symbolDescription) {
|
|
134
|
+
return symbolDescription.replace(/-interceptor$/, '')
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return this.constructor.name.replace(/Interceptor$/, '')
|
|
138
|
+
}
|
|
139
|
+
}
|