@mswjs/interceptors 0.41.4 → 0.41.5
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/lib/browser/{XMLHttpRequest-C2KXXdBy.cjs → XMLHttpRequest-DSAhl6_a.cjs} +9 -21
- package/lib/browser/XMLHttpRequest-DSAhl6_a.cjs.map +1 -0
- package/lib/browser/{XMLHttpRequest-Bbvn_AjX.mjs → XMLHttpRequest-DYyDAIJh.mjs} +9 -21
- package/lib/{node/XMLHttpRequest-BBbs-p9i.mjs.map → browser/XMLHttpRequest-DYyDAIJh.mjs.map} +1 -1
- package/lib/browser/{createRequestId-Cs4oXfa1.cjs → createRequestId-DOf8Ktjs.cjs} +1 -1
- package/lib/browser/{createRequestId-Cs4oXfa1.cjs.map → createRequestId-DOf8Ktjs.cjs.map} +1 -1
- package/lib/browser/{createRequestId-DQcIlohW.mjs → createRequestId-DYCsFHOi.mjs} +1 -1
- package/lib/browser/{createRequestId-DQcIlohW.mjs.map → createRequestId-DYCsFHOi.mjs.map} +1 -1
- package/lib/browser/{fetch-CJYWVliE.cjs → fetch-BMC2en2x.cjs} +10 -18
- package/lib/browser/fetch-BMC2en2x.cjs.map +1 -0
- package/lib/browser/{fetch-D4es-Apw.mjs → fetch-D5LGhx5i.mjs} +10 -18
- package/lib/browser/fetch-D5LGhx5i.mjs.map +1 -0
- package/lib/browser/{getRawRequest-DaxX6uMy.cjs → getRawRequest-B9kRTvjs.cjs} +1 -11
- package/lib/browser/getRawRequest-B9kRTvjs.cjs.map +1 -0
- package/lib/browser/{getRawRequest-Df640uw8.mjs → getRawRequest-BEw5hEOW.mjs} +2 -6
- package/lib/browser/getRawRequest-BEw5hEOW.mjs.map +1 -0
- package/lib/browser/{glossary-BdLS4k1H.d.cts → glossary-1lhZx6Aw.d.cts} +2 -3
- package/lib/browser/{glossary-DYwOrogs.d.mts → glossary-nkHWcwvY.d.mts} +2 -3
- package/lib/browser/{handleRequest--veikAod.cjs → handleRequest-BCtqvFSS.cjs} +3 -3
- package/lib/browser/{handleRequest--veikAod.cjs.map → handleRequest-BCtqvFSS.cjs.map} +1 -1
- package/lib/browser/{handleRequest-Dq1a55b4.mjs → handleRequest-DuUoGpfA.mjs} +3 -3
- package/lib/browser/{handleRequest-Dq1a55b4.mjs.map → handleRequest-DuUoGpfA.mjs.map} +1 -1
- package/lib/browser/hasConfigurableGlobal-B39W0thh.mjs +98 -0
- package/lib/browser/hasConfigurableGlobal-B39W0thh.mjs.map +1 -0
- package/lib/browser/hasConfigurableGlobal-B5o6PHq3.cjs +115 -0
- package/lib/browser/hasConfigurableGlobal-B5o6PHq3.cjs.map +1 -0
- package/lib/browser/index.cjs +2 -3
- package/lib/browser/index.d.cts +2 -2
- package/lib/browser/index.d.mts +2 -2
- package/lib/browser/index.mjs +3 -3
- package/lib/browser/interceptors/WebSocket/index.cjs +6 -10
- package/lib/browser/interceptors/WebSocket/index.cjs.map +1 -1
- package/lib/browser/interceptors/WebSocket/index.mjs +6 -10
- package/lib/browser/interceptors/WebSocket/index.mjs.map +1 -1
- package/lib/browser/interceptors/XMLHttpRequest/index.cjs +5 -4
- package/lib/browser/interceptors/XMLHttpRequest/index.d.cts +1 -1
- package/lib/browser/interceptors/XMLHttpRequest/index.d.mts +1 -1
- package/lib/browser/interceptors/XMLHttpRequest/index.mjs +5 -4
- package/lib/browser/interceptors/fetch/index.cjs +5 -4
- package/lib/browser/interceptors/fetch/index.d.cts +1 -1
- package/lib/browser/interceptors/fetch/index.d.mts +1 -1
- package/lib/browser/interceptors/fetch/index.mjs +5 -4
- package/lib/browser/presets/browser.cjs +6 -5
- package/lib/browser/presets/browser.cjs.map +1 -1
- package/lib/browser/presets/browser.mjs +6 -5
- package/lib/browser/presets/browser.mjs.map +1 -1
- package/lib/node/{BatchInterceptor-7u9fqQIe.cjs → BatchInterceptor-AZr7q8p_.cjs} +2 -2
- package/lib/node/{BatchInterceptor-7u9fqQIe.cjs.map → BatchInterceptor-AZr7q8p_.cjs.map} +1 -1
- package/lib/node/{BatchInterceptor-BxgAXyLw.mjs → BatchInterceptor-B2YAn5m9.mjs} +2 -2
- package/lib/node/{BatchInterceptor-BxgAXyLw.mjs.map → BatchInterceptor-B2YAn5m9.mjs.map} +1 -1
- package/lib/node/{BatchInterceptor-D7mXzHcQ.d.mts → BatchInterceptor-KKF8Q47I.d.cts} +2 -2
- package/lib/node/{BatchInterceptor-D_YqR8qU.d.cts → BatchInterceptor-rSr-NH_H.d.mts} +2 -2
- package/lib/node/{ClientRequest-Cl3Ky7Tw.mjs → ClientRequest-5WjHvs9Y.mjs} +5 -5
- package/lib/node/{ClientRequest-Cl3Ky7Tw.mjs.map → ClientRequest-5WjHvs9Y.mjs.map} +1 -1
- package/lib/node/{ClientRequest-CMSXChAM.cjs → ClientRequest-BgwQG-9G.cjs} +5 -5
- package/lib/node/{ClientRequest-CMSXChAM.cjs.map → ClientRequest-BgwQG-9G.cjs.map} +1 -1
- package/lib/node/{Interceptor-DJ2akVWI.d.cts → Interceptor-BsZ21ue0.d.cts} +2 -3
- package/lib/node/{Interceptor-DEazpLJd.d.mts → Interceptor-soD-WpQO.d.mts} +2 -3
- package/lib/node/RemoteHttpInterceptor.cjs +9 -8
- package/lib/node/RemoteHttpInterceptor.cjs.map +1 -1
- package/lib/node/RemoteHttpInterceptor.d.cts +3 -3
- package/lib/node/RemoteHttpInterceptor.d.mts +3 -3
- package/lib/node/RemoteHttpInterceptor.mjs +9 -8
- package/lib/node/RemoteHttpInterceptor.mjs.map +1 -1
- package/lib/node/{XMLHttpRequest-Dj3xJgke.cjs → XMLHttpRequest-B7sloBex.cjs} +10 -23
- package/lib/node/XMLHttpRequest-B7sloBex.cjs.map +1 -0
- package/lib/node/{XMLHttpRequest-BBbs-p9i.mjs → XMLHttpRequest-DmsdUGmj.mjs} +10 -23
- package/lib/{browser/XMLHttpRequest-Bbvn_AjX.mjs.map → node/XMLHttpRequest-DmsdUGmj.mjs.map} +1 -1
- package/lib/node/{bufferUtils-_8XfKIfX.mjs → bufferUtils-DxPxwff_.mjs} +1 -1
- package/lib/node/{bufferUtils-_8XfKIfX.mjs.map → bufferUtils-DxPxwff_.mjs.map} +1 -1
- package/lib/node/{bufferUtils-DiCTqG-7.cjs → bufferUtils-S5_-2eN4.cjs} +1 -1
- package/lib/node/{bufferUtils-DiCTqG-7.cjs.map → bufferUtils-S5_-2eN4.cjs.map} +1 -1
- package/lib/node/{fetch-DmiwAmpu.mjs → fetch-DDAGTtZi.mjs} +10 -19
- package/lib/node/fetch-DDAGTtZi.mjs.map +1 -0
- package/lib/node/{fetch-BoCFyaYx.cjs → fetch-uc7pNtPg.cjs} +10 -19
- package/lib/node/fetch-uc7pNtPg.cjs.map +1 -0
- package/lib/node/{fetchUtils-BTrdMHGp.mjs → fetchUtils-BJxD7wvl.mjs} +1 -1
- package/lib/node/{fetchUtils-BTrdMHGp.mjs.map → fetchUtils-BJxD7wvl.mjs.map} +1 -1
- package/lib/node/{fetchUtils-DE_q7tpr.cjs → fetchUtils-Dw6kQghF.cjs} +1 -1
- package/lib/node/{fetchUtils-DE_q7tpr.cjs.map → fetchUtils-Dw6kQghF.cjs.map} +1 -1
- package/lib/node/{getRawRequest-BavnMWh_.cjs → getRawRequest-B6znU6il.cjs} +1 -1
- package/lib/node/{getRawRequest-BavnMWh_.cjs.map → getRawRequest-B6znU6il.cjs.map} +1 -1
- package/lib/node/{getRawRequest-DnwmXyOW.mjs → getRawRequest-C2-1urzA.mjs} +1 -1
- package/lib/node/{getRawRequest-DnwmXyOW.mjs.map → getRawRequest-C2-1urzA.mjs.map} +1 -1
- package/lib/node/{handleRequest-CDabRyt1.mjs → handleRequest-DGfUg9bm.mjs} +2 -2
- package/lib/node/{handleRequest-CDabRyt1.mjs.map → handleRequest-DGfUg9bm.mjs.map} +1 -1
- package/lib/node/{handleRequest-pLIe3KKo.cjs → handleRequest-Dzg1d3e5.cjs} +2 -2
- package/lib/node/{handleRequest-pLIe3KKo.cjs.map → handleRequest-Dzg1d3e5.cjs.map} +1 -1
- package/lib/node/hasConfigurableGlobal-Befl_QJD.cjs +97 -0
- package/lib/node/hasConfigurableGlobal-Befl_QJD.cjs.map +1 -0
- package/lib/node/hasConfigurableGlobal-jN_-v3gp.mjs +85 -0
- package/lib/node/hasConfigurableGlobal-jN_-v3gp.mjs.map +1 -0
- package/lib/node/{index-BMbJ8FXL.d.cts → index-BJ5E5aW-.d.cts} +2 -2
- package/lib/node/{index-C0YAQ36w.d.mts → index-DfoF45ih.d.mts} +2 -2
- package/lib/node/index.cjs +4 -6
- package/lib/node/index.cjs.map +1 -1
- package/lib/node/index.d.cts +3 -3
- package/lib/node/index.d.mts +3 -3
- package/lib/node/index.mjs +5 -6
- package/lib/node/index.mjs.map +1 -1
- package/lib/node/interceptors/ClientRequest/index.cjs +4 -4
- package/lib/node/interceptors/ClientRequest/index.d.cts +1 -1
- package/lib/node/interceptors/ClientRequest/index.d.mts +2 -2
- package/lib/node/interceptors/ClientRequest/index.mjs +4 -4
- package/lib/node/interceptors/XMLHttpRequest/index.cjs +5 -4
- package/lib/node/interceptors/XMLHttpRequest/index.d.cts +1 -1
- package/lib/node/interceptors/XMLHttpRequest/index.d.mts +1 -1
- package/lib/node/interceptors/XMLHttpRequest/index.mjs +5 -4
- package/lib/node/interceptors/fetch/index.cjs +4 -3
- package/lib/node/interceptors/fetch/index.d.cts +1 -1
- package/lib/node/interceptors/fetch/index.d.mts +1 -1
- package/lib/node/interceptors/fetch/index.mjs +4 -3
- package/lib/node/{node-dKdAf3tC.cjs → node-DIKcnzhK.cjs} +2 -2
- package/lib/node/{node-dKdAf3tC.cjs.map → node-DIKcnzhK.cjs.map} +1 -1
- package/lib/node/{node-DwCc6iuP.mjs → node-lsdNwZEW.mjs} +2 -2
- package/lib/node/{node-DwCc6iuP.mjs.map → node-lsdNwZEW.mjs.map} +1 -1
- package/lib/node/presets/node.cjs +8 -7
- package/lib/node/presets/node.cjs.map +1 -1
- package/lib/node/presets/node.d.cts +1 -1
- package/lib/node/presets/node.d.mts +2 -2
- package/lib/node/presets/node.mjs +8 -7
- package/lib/node/presets/node.mjs.map +1 -1
- package/lib/node/utils/node/index.cjs +1 -1
- package/lib/node/utils/node/index.mjs +1 -1
- package/package.json +1 -1
- package/src/glossary.ts +3 -5
- package/src/interceptors/WebSocket/index.ts +8 -15
- package/src/interceptors/XMLHttpRequest/index.ts +12 -32
- package/src/interceptors/fetch/index.ts +8 -24
- package/src/utils/globalUtils.test.ts +144 -0
- package/src/utils/globalsRegistry.ts +107 -0
- package/src/utils/hasConfigurableGlobal.test.ts +11 -0
- package/src/utils/hasConfigurableGlobal.ts +9 -3
- package/lib/browser/XMLHttpRequest-C2KXXdBy.cjs.map +0 -1
- package/lib/browser/fetch-CJYWVliE.cjs.map +0 -1
- package/lib/browser/fetch-D4es-Apw.mjs.map +0 -1
- package/lib/browser/getRawRequest-DaxX6uMy.cjs.map +0 -1
- package/lib/browser/getRawRequest-Df640uw8.mjs.map +0 -1
- package/lib/browser/hasConfigurableGlobal-BvCTG97d.cjs +0 -45
- package/lib/browser/hasConfigurableGlobal-BvCTG97d.cjs.map +0 -1
- package/lib/browser/hasConfigurableGlobal-npXitu1-.mjs +0 -33
- package/lib/browser/hasConfigurableGlobal-npXitu1-.mjs.map +0 -1
- package/lib/node/XMLHttpRequest-Dj3xJgke.cjs.map +0 -1
- package/lib/node/fetch-BoCFyaYx.cjs.map +0 -1
- package/lib/node/fetch-DmiwAmpu.mjs.map +0 -1
- package/lib/node/glossary-BLKRyLBd.cjs +0 -12
- package/lib/node/glossary-BLKRyLBd.cjs.map +0 -1
- package/lib/node/glossary-glQBRnVD.mjs +0 -6
- package/lib/node/glossary-glQBRnVD.mjs.map +0 -1
- package/lib/node/hasConfigurableGlobal-C97fWuaA.cjs +0 -26
- package/lib/node/hasConfigurableGlobal-C97fWuaA.cjs.map +0 -1
- package/lib/node/hasConfigurableGlobal-DBJA0vjm.mjs +0 -20
- package/lib/node/hasConfigurableGlobal-DBJA0vjm.mjs.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import "../../fetchUtils-
|
|
2
|
-
import "../../handleRequest-
|
|
3
|
-
import
|
|
1
|
+
import "../../fetchUtils-BJxD7wvl.mjs";
|
|
2
|
+
import "../../handleRequest-DGfUg9bm.mjs";
|
|
3
|
+
import "../../hasConfigurableGlobal-jN_-v3gp.mjs";
|
|
4
|
+
import { t as FetchInterceptor } from "../../fetch-DDAGTtZi.mjs";
|
|
4
5
|
|
|
5
6
|
export { FetchInterceptor };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require('./chunk-CbDLau6x.cjs');
|
|
2
|
-
const require_getRawRequest = require('./getRawRequest-
|
|
2
|
+
const require_getRawRequest = require('./getRawRequest-B6znU6il.cjs');
|
|
3
3
|
let outvariant = require("outvariant");
|
|
4
4
|
let node_http = require("node:http");
|
|
5
5
|
let node_stream = require("node:stream");
|
|
@@ -36,4 +36,4 @@ Object.defineProperty(exports, 'setRawRequestBodyStream', {
|
|
|
36
36
|
return setRawRequestBodyStream;
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
-
//# sourceMappingURL=node-
|
|
39
|
+
//# sourceMappingURL=node-DIKcnzhK.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-
|
|
1
|
+
{"version":3,"file":"node-DIKcnzhK.cjs","names":["getRawRequest","ClientRequest","Readable"],"sources":["../../src/utils/node/index.ts"],"sourcesContent":["import { ClientRequest } from 'node:http'\nimport { Readable } from 'node:stream'\nimport { invariant } from 'outvariant'\nimport { getRawRequest } from '../../getRawRequest'\n\nconst kRawRequestBodyStream = Symbol('kRawRequestBodyStream')\n\n/**\n * Returns the request body stream of the given request.\n * @note This is only relevant in the context of `http.ClientRequest`.\n * This function will throw if the given `request` wasn't created based on\n * the `http.ClientRequest` instance.\n * You must rely on the web stream consumers for other request clients.\n */\nexport function getClientRequestBodyStream(request: Request): Readable {\n const rawRequest = getRawRequest(request)\n\n invariant(\n rawRequest instanceof ClientRequest,\n `Failed to retrieve raw request body stream: request is not an instance of \"http.ClientRequest\". Note that you can only use the \"getClientRequestBodyStream\" function with the requests issued by \"http.clientRequest\".`\n )\n\n const requestBodyStream = Reflect.get(request, kRawRequestBodyStream)\n\n invariant(\n requestBodyStream instanceof Readable,\n 'Failed to retrieve raw request body stream: corrupted stream (%s)',\n typeof requestBodyStream\n )\n\n return requestBodyStream\n}\n\nexport function setRawRequestBodyStream(\n request: Request,\n stream: Readable\n): void {\n Reflect.set(request, kRawRequestBodyStream, stream)\n}\n"],"mappings":";;;;;;;AAKA,MAAM,wBAAwB,OAAO,wBAAwB;;;;;;;;AAS7D,SAAgB,2BAA2B,SAA4B;AAGrE,2BAFmBA,oCAAc,QAAQ,YAGjBC,yBACtB,yNACD;CAED,MAAM,oBAAoB,QAAQ,IAAI,SAAS,sBAAsB;AAErE,2BACE,6BAA6BC,sBAC7B,qEACA,OAAO,kBACR;AAED,QAAO;;AAGT,SAAgB,wBACd,SACA,QACM;AACN,SAAQ,IAAI,SAAS,uBAAuB,OAAO"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as getRawRequest } from "./getRawRequest-
|
|
1
|
+
import { t as getRawRequest } from "./getRawRequest-C2-1urzA.mjs";
|
|
2
2
|
import { invariant } from "outvariant";
|
|
3
3
|
import { ClientRequest } from "node:http";
|
|
4
4
|
import { Readable } from "node:stream";
|
|
@@ -24,4 +24,4 @@ function setRawRequestBodyStream(request, stream) {
|
|
|
24
24
|
|
|
25
25
|
//#endregion
|
|
26
26
|
export { setRawRequestBodyStream as n, getClientRequestBodyStream as t };
|
|
27
|
-
//# sourceMappingURL=node-
|
|
27
|
+
//# sourceMappingURL=node-lsdNwZEW.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-
|
|
1
|
+
{"version":3,"file":"node-lsdNwZEW.mjs","names":[],"sources":["../../src/utils/node/index.ts"],"sourcesContent":["import { ClientRequest } from 'node:http'\nimport { Readable } from 'node:stream'\nimport { invariant } from 'outvariant'\nimport { getRawRequest } from '../../getRawRequest'\n\nconst kRawRequestBodyStream = Symbol('kRawRequestBodyStream')\n\n/**\n * Returns the request body stream of the given request.\n * @note This is only relevant in the context of `http.ClientRequest`.\n * This function will throw if the given `request` wasn't created based on\n * the `http.ClientRequest` instance.\n * You must rely on the web stream consumers for other request clients.\n */\nexport function getClientRequestBodyStream(request: Request): Readable {\n const rawRequest = getRawRequest(request)\n\n invariant(\n rawRequest instanceof ClientRequest,\n `Failed to retrieve raw request body stream: request is not an instance of \"http.ClientRequest\". Note that you can only use the \"getClientRequestBodyStream\" function with the requests issued by \"http.clientRequest\".`\n )\n\n const requestBodyStream = Reflect.get(request, kRawRequestBodyStream)\n\n invariant(\n requestBodyStream instanceof Readable,\n 'Failed to retrieve raw request body stream: corrupted stream (%s)',\n typeof requestBodyStream\n )\n\n return requestBodyStream\n}\n\nexport function setRawRequestBodyStream(\n request: Request,\n stream: Readable\n): void {\n Reflect.set(request, kRawRequestBodyStream, stream)\n}\n"],"mappings":";;;;;;AAKA,MAAM,wBAAwB,OAAO,wBAAwB;;;;;;;;AAS7D,SAAgB,2BAA2B,SAA4B;AAGrE,WAFmB,cAAc,QAAQ,YAGjB,eACtB,yNACD;CAED,MAAM,oBAAoB,QAAQ,IAAI,SAAS,sBAAsB;AAErE,WACE,6BAA6B,UAC7B,qEACA,OAAO,kBACR;AAED,QAAO;;AAGT,SAAgB,wBACd,SACA,QACM;AACN,SAAQ,IAAI,SAAS,uBAAuB,OAAO"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
require('../fetchUtils-
|
|
2
|
-
require('../bufferUtils-
|
|
3
|
-
const require_ClientRequest = require('../ClientRequest-
|
|
4
|
-
require('../handleRequest-
|
|
5
|
-
require('../node-
|
|
6
|
-
const require_XMLHttpRequest = require('../XMLHttpRequest-
|
|
7
|
-
|
|
1
|
+
require('../fetchUtils-Dw6kQghF.cjs');
|
|
2
|
+
require('../bufferUtils-S5_-2eN4.cjs');
|
|
3
|
+
const require_ClientRequest = require('../ClientRequest-BgwQG-9G.cjs');
|
|
4
|
+
require('../handleRequest-Dzg1d3e5.cjs');
|
|
5
|
+
require('../node-DIKcnzhK.cjs');
|
|
6
|
+
const require_XMLHttpRequest = require('../XMLHttpRequest-B7sloBex.cjs');
|
|
7
|
+
require('../hasConfigurableGlobal-Befl_QJD.cjs');
|
|
8
|
+
const require_fetch = require('../fetch-uc7pNtPg.cjs');
|
|
8
9
|
|
|
9
10
|
//#region src/presets/node.ts
|
|
10
11
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.cjs","names":["ClientRequestInterceptor","XMLHttpRequestInterceptor","FetchInterceptor"],"sources":["../../../src/presets/node.ts"],"sourcesContent":["import { ClientRequestInterceptor } from '../interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from '../interceptors/XMLHttpRequest'\nimport { FetchInterceptor } from '../interceptors/fetch'\n\n/**\n * The default preset provisions the interception of requests\n * regardless of their type (http/https/XMLHttpRequest).\n */\nexport default [\n new ClientRequestInterceptor(),\n new XMLHttpRequestInterceptor(),\n new FetchInterceptor(),\n] as const\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"node.cjs","names":["ClientRequestInterceptor","XMLHttpRequestInterceptor","FetchInterceptor"],"sources":["../../../src/presets/node.ts"],"sourcesContent":["import { ClientRequestInterceptor } from '../interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from '../interceptors/XMLHttpRequest'\nimport { FetchInterceptor } from '../interceptors/fetch'\n\n/**\n * The default preset provisions the interception of requests\n * regardless of their type (http/https/XMLHttpRequest).\n */\nexport default [\n new ClientRequestInterceptor(),\n new XMLHttpRequestInterceptor(),\n new FetchInterceptor(),\n] as const\n"],"mappings":";;;;;;;;;;;;;;AAQA,mBAAe;CACb,IAAIA,gDAA0B;CAC9B,IAAIC,kDAA2B;CAC/B,IAAIC,gCAAkB;CACvB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ClientRequestInterceptor } from "../index-
|
|
1
|
+
import { t as ClientRequestInterceptor } from "../index-BJ5E5aW-.cjs";
|
|
2
2
|
import { XMLHttpRequestInterceptor } from "../interceptors/XMLHttpRequest/index.cjs";
|
|
3
3
|
import { FetchInterceptor } from "../interceptors/fetch/index.cjs";
|
|
4
4
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "../Interceptor-
|
|
2
|
-
import { t as ClientRequestInterceptor } from "../index-
|
|
1
|
+
import "../Interceptor-soD-WpQO.mjs";
|
|
2
|
+
import { t as ClientRequestInterceptor } from "../index-DfoF45ih.mjs";
|
|
3
3
|
import { XMLHttpRequestInterceptor } from "../interceptors/XMLHttpRequest/index.mjs";
|
|
4
4
|
import { FetchInterceptor } from "../interceptors/fetch/index.mjs";
|
|
5
5
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import "../fetchUtils-
|
|
2
|
-
import "../bufferUtils-
|
|
3
|
-
import { t as ClientRequestInterceptor } from "../ClientRequest-
|
|
4
|
-
import "../handleRequest-
|
|
5
|
-
import "../node-
|
|
6
|
-
import { t as XMLHttpRequestInterceptor } from "../XMLHttpRequest-
|
|
7
|
-
import
|
|
1
|
+
import "../fetchUtils-BJxD7wvl.mjs";
|
|
2
|
+
import "../bufferUtils-DxPxwff_.mjs";
|
|
3
|
+
import { t as ClientRequestInterceptor } from "../ClientRequest-5WjHvs9Y.mjs";
|
|
4
|
+
import "../handleRequest-DGfUg9bm.mjs";
|
|
5
|
+
import "../node-lsdNwZEW.mjs";
|
|
6
|
+
import { t as XMLHttpRequestInterceptor } from "../XMLHttpRequest-DmsdUGmj.mjs";
|
|
7
|
+
import "../hasConfigurableGlobal-jN_-v3gp.mjs";
|
|
8
|
+
import { t as FetchInterceptor } from "../fetch-DDAGTtZi.mjs";
|
|
8
9
|
|
|
9
10
|
//#region src/presets/node.ts
|
|
10
11
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.mjs","names":[],"sources":["../../../src/presets/node.ts"],"sourcesContent":["import { ClientRequestInterceptor } from '../interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from '../interceptors/XMLHttpRequest'\nimport { FetchInterceptor } from '../interceptors/fetch'\n\n/**\n * The default preset provisions the interception of requests\n * regardless of their type (http/https/XMLHttpRequest).\n */\nexport default [\n new ClientRequestInterceptor(),\n new XMLHttpRequestInterceptor(),\n new FetchInterceptor(),\n] as const\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"node.mjs","names":[],"sources":["../../../src/presets/node.ts"],"sourcesContent":["import { ClientRequestInterceptor } from '../interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from '../interceptors/XMLHttpRequest'\nimport { FetchInterceptor } from '../interceptors/fetch'\n\n/**\n * The default preset provisions the interception of requests\n * regardless of their type (http/https/XMLHttpRequest).\n */\nexport default [\n new ClientRequestInterceptor(),\n new XMLHttpRequestInterceptor(),\n new FetchInterceptor(),\n] as const\n"],"mappings":";;;;;;;;;;;;;;AAQA,mBAAe;CACb,IAAI,0BAA0B;CAC9B,IAAI,2BAA2B;CAC/B,IAAI,kBAAkB;CACvB"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as setRawRequestBodyStream, t as getClientRequestBodyStream } from "../../node-
|
|
1
|
+
import { n as setRawRequestBodyStream, t as getClientRequestBodyStream } from "../../node-lsdNwZEW.mjs";
|
|
2
2
|
|
|
3
3
|
export { getClientRequestBodyStream, setRawRequestBodyStream };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"type": "commonjs",
|
|
3
3
|
"name": "@mswjs/interceptors",
|
|
4
4
|
"description": "Low-level HTTP/HTTPS/XHR/fetch request interception library.",
|
|
5
|
-
"version": "0.41.
|
|
5
|
+
"version": "0.41.5",
|
|
6
6
|
"main": "./lib/node/index.cjs",
|
|
7
7
|
"module": "./lib/node/index.mjs",
|
|
8
8
|
"types": "./lib/node/index.d.cts",
|
package/src/glossary.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { RequestController } from './RequestController'
|
|
2
2
|
|
|
3
|
-
export const IS_PATCHED_MODULE: unique symbol = Symbol('isPatchedModule')
|
|
4
|
-
|
|
5
3
|
/**
|
|
6
4
|
* @note Export `RequestController` as a type only.
|
|
7
5
|
* It's never meant to be created in the userland.
|
|
@@ -16,7 +14,7 @@ export type HttpRequestEventMap = {
|
|
|
16
14
|
request: Request
|
|
17
15
|
requestId: string
|
|
18
16
|
controller: RequestController
|
|
19
|
-
}
|
|
17
|
+
},
|
|
20
18
|
]
|
|
21
19
|
response: [
|
|
22
20
|
args: {
|
|
@@ -24,7 +22,7 @@ export type HttpRequestEventMap = {
|
|
|
24
22
|
isMockedResponse: boolean
|
|
25
23
|
request: Request
|
|
26
24
|
requestId: string
|
|
27
|
-
}
|
|
25
|
+
},
|
|
28
26
|
]
|
|
29
27
|
unhandledException: [
|
|
30
28
|
args: {
|
|
@@ -32,6 +30,6 @@ export type HttpRequestEventMap = {
|
|
|
32
30
|
request: Request
|
|
33
31
|
requestId: string
|
|
34
32
|
controller: RequestController
|
|
35
|
-
}
|
|
33
|
+
},
|
|
36
34
|
]
|
|
37
35
|
}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
import { bindEvent } from './utils/bindEvent'
|
|
19
19
|
import { hasConfigurableGlobal } from '../../utils/hasConfigurableGlobal'
|
|
20
20
|
import { emitAsync } from '../../utils/emitAsync'
|
|
21
|
+
import { globalsRegistry } from '../../utils/globalsRegistry'
|
|
21
22
|
|
|
22
23
|
export {
|
|
23
24
|
type WebSocketData,
|
|
@@ -80,10 +81,7 @@ export class WebSocketInterceptor extends Interceptor<WebSocketEventMap> {
|
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
protected setup(): void {
|
|
83
|
-
const
|
|
84
|
-
globalThis,
|
|
85
|
-
'WebSocket'
|
|
86
|
-
)
|
|
84
|
+
const logger = this.logger.extend('setup')
|
|
87
85
|
|
|
88
86
|
const WebSocketProxy = new Proxy(globalThis.WebSocket, {
|
|
89
87
|
construct: (
|
|
@@ -175,17 +173,12 @@ export class WebSocketInterceptor extends Interceptor<WebSocketEventMap> {
|
|
|
175
173
|
},
|
|
176
174
|
})
|
|
177
175
|
|
|
178
|
-
|
|
179
|
-
value: WebSocketProxy,
|
|
180
|
-
configurable: true,
|
|
181
|
-
})
|
|
176
|
+
logger.info('patching global WebSocket...')
|
|
182
177
|
|
|
183
|
-
this.subscriptions.push(
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
)
|
|
189
|
-
})
|
|
178
|
+
this.subscriptions.push(
|
|
179
|
+
globalsRegistry.replaceGlobal('WebSocket', WebSocketProxy)
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
logger.info('global WebSocket patched!', globalThis.WebSocket.name)
|
|
190
183
|
}
|
|
191
184
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { invariant } from 'outvariant'
|
|
2
1
|
import { Emitter } from 'strict-event-emitter'
|
|
3
|
-
import { HttpRequestEventMap
|
|
2
|
+
import { HttpRequestEventMap } from '../../glossary'
|
|
4
3
|
import { Interceptor } from '../../Interceptor'
|
|
5
4
|
import { createXMLHttpRequestProxy } from './XMLHttpRequestProxy'
|
|
6
5
|
import { hasConfigurableGlobal } from '../../utils/hasConfigurableGlobal'
|
|
6
|
+
import { globalsRegistry } from '../../utils/globalsRegistry'
|
|
7
7
|
|
|
8
8
|
export type XMLHttpRequestEmitter = Emitter<HttpRequestEventMap>
|
|
9
9
|
|
|
@@ -21,41 +21,21 @@ export class XMLHttpRequestInterceptor extends Interceptor<HttpRequestEventMap>
|
|
|
21
21
|
protected setup() {
|
|
22
22
|
const logger = this.logger.extend('setup')
|
|
23
23
|
|
|
24
|
-
logger.info('patching
|
|
24
|
+
logger.info('patching global XMLHttpRequest...')
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
this.subscriptions.push(
|
|
27
|
+
globalsRegistry.replaceGlobal(
|
|
28
|
+
'XMLHttpRequest',
|
|
29
|
+
createXMLHttpRequestProxy({
|
|
30
|
+
emitter: this.emitter,
|
|
31
|
+
logger: this.logger,
|
|
32
|
+
})
|
|
33
|
+
)
|
|
31
34
|
)
|
|
32
35
|
|
|
33
|
-
globalThis.XMLHttpRequest = createXMLHttpRequestProxy({
|
|
34
|
-
emitter: this.emitter,
|
|
35
|
-
logger: this.logger,
|
|
36
|
-
})
|
|
37
|
-
|
|
38
36
|
logger.info(
|
|
39
|
-
'
|
|
37
|
+
'global XMLHttpRequest patched!',
|
|
40
38
|
globalThis.XMLHttpRequest.name
|
|
41
39
|
)
|
|
42
|
-
|
|
43
|
-
Object.defineProperty(globalThis.XMLHttpRequest, IS_PATCHED_MODULE, {
|
|
44
|
-
enumerable: true,
|
|
45
|
-
configurable: true,
|
|
46
|
-
value: true,
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
this.subscriptions.push(() => {
|
|
50
|
-
Object.defineProperty(globalThis.XMLHttpRequest, IS_PATCHED_MODULE, {
|
|
51
|
-
value: undefined,
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
globalThis.XMLHttpRequest = PureXMLHttpRequest
|
|
55
|
-
logger.info(
|
|
56
|
-
'native "XMLHttpRequest" module restored!',
|
|
57
|
-
globalThis.XMLHttpRequest.name
|
|
58
|
-
)
|
|
59
|
-
})
|
|
60
40
|
}
|
|
61
41
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { invariant } from 'outvariant'
|
|
2
1
|
import { until } from '@open-draft/until'
|
|
3
2
|
import { DeferredPromise } from '@open-draft/deferred-promise'
|
|
4
|
-
import { HttpRequestEventMap
|
|
3
|
+
import { HttpRequestEventMap } from '../../glossary'
|
|
5
4
|
import { Interceptor } from '../../Interceptor'
|
|
6
5
|
import { RequestController } from '../../RequestController'
|
|
7
6
|
import { emitAsync } from '../../utils/emitAsync'
|
|
@@ -15,6 +14,7 @@ import { hasConfigurableGlobal } from '../../utils/hasConfigurableGlobal'
|
|
|
15
14
|
import { FetchRequest, FetchResponse } from '../../utils/fetchUtils'
|
|
16
15
|
import { setRawRequest } from '../../getRawRequest'
|
|
17
16
|
import { isResponseError } from '../../utils/responseUtils'
|
|
17
|
+
import { globalsRegistry } from '../../utils/globalsRegistry'
|
|
18
18
|
|
|
19
19
|
export class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
|
|
20
20
|
static symbol = Symbol('fetch')
|
|
@@ -28,14 +28,11 @@ export class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
protected async setup() {
|
|
31
|
-
const
|
|
31
|
+
const logger = this.logger.extend('setup')
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
!(pureFetch as any)[IS_PATCHED_MODULE],
|
|
35
|
-
'Failed to patch the "fetch" module: already patched.'
|
|
36
|
-
)
|
|
33
|
+
const pureFetch = globalThis.fetch
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
const fetchProxy: typeof fetch = async (input, init) => {
|
|
39
36
|
const requestId = createRequestId()
|
|
40
37
|
|
|
41
38
|
/**
|
|
@@ -192,23 +189,10 @@ export class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
|
|
|
192
189
|
return responsePromise
|
|
193
190
|
}
|
|
194
191
|
|
|
195
|
-
|
|
196
|
-
enumerable: true,
|
|
197
|
-
configurable: true,
|
|
198
|
-
value: true,
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
this.subscriptions.push(() => {
|
|
202
|
-
Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {
|
|
203
|
-
value: undefined,
|
|
204
|
-
})
|
|
192
|
+
logger.info('patching global fetch...')
|
|
205
193
|
|
|
206
|
-
|
|
194
|
+
this.subscriptions.push(globalsRegistry.replaceGlobal('fetch', fetchProxy))
|
|
207
195
|
|
|
208
|
-
|
|
209
|
-
'restored native "globalThis.fetch"!',
|
|
210
|
-
globalThis.fetch.name
|
|
211
|
-
)
|
|
212
|
-
})
|
|
196
|
+
logger.info('global fetch patched!', globalThis.fetch.name)
|
|
213
197
|
}
|
|
214
198
|
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { it, beforeEach, afterEach, expect, vi } from 'vitest'
|
|
2
|
+
import { globalsRegistry } from './globalsRegistry'
|
|
3
|
+
|
|
4
|
+
declare global {
|
|
5
|
+
var foo: { original: boolean }
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const realGlobalPrototype = Object.getPrototypeOf(global)
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
global.foo = { original: true }
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
Object.setPrototypeOf(global, realGlobalPrototype)
|
|
16
|
+
globalsRegistry.restoreAllGlobals()
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('replaces the global', () => {
|
|
20
|
+
globalsRegistry.replaceGlobal('foo', { original: false })
|
|
21
|
+
expect(global.foo).toEqual({ original: false })
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('replaces the global set on the prototype', () => {
|
|
25
|
+
function FakeGlobalScope() {}
|
|
26
|
+
FakeGlobalScope.prototype.foo = { prototype: true }
|
|
27
|
+
Object.setPrototypeOf(global, FakeGlobalScope.prototype)
|
|
28
|
+
Reflect.deleteProperty(global, 'foo')
|
|
29
|
+
|
|
30
|
+
expect(global.foo).toEqual({ prototype: true })
|
|
31
|
+
expect(FakeGlobalScope.prototype.foo).toEqual({ prototype: true })
|
|
32
|
+
|
|
33
|
+
globalsRegistry.replaceGlobal('foo', { original: false })
|
|
34
|
+
|
|
35
|
+
expect(global.foo).toEqual({ original: false })
|
|
36
|
+
expect(FakeGlobalScope.prototype.foo, 'Preserves prototype value').toEqual({
|
|
37
|
+
prototype: true,
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('replaces the global after it was restored', () => {
|
|
42
|
+
const restoreGlobal = globalsRegistry.replaceGlobal('foo', {
|
|
43
|
+
original: false,
|
|
44
|
+
})
|
|
45
|
+
expect(global.foo).toEqual({ original: false })
|
|
46
|
+
|
|
47
|
+
restoreGlobal()
|
|
48
|
+
expect(global.foo).toEqual({ original: true })
|
|
49
|
+
|
|
50
|
+
globalsRegistry.replaceGlobal('foo', { original: false })
|
|
51
|
+
expect(global.foo).toEqual({ original: false })
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('warns on replacing a non-existing global', () => {
|
|
55
|
+
vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
56
|
+
|
|
57
|
+
globalsRegistry.replaceGlobal(
|
|
58
|
+
// @ts-expect-error Intentionally invalid value.
|
|
59
|
+
'NON-EXISTING',
|
|
60
|
+
{ original: false }
|
|
61
|
+
)
|
|
62
|
+
expect(console.warn).toHaveBeenCalledExactlyOnceWith(
|
|
63
|
+
'Failed to replace a global value at "NON-EXISTING": not a global value.'
|
|
64
|
+
)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('throws if replacing an already replaced global', () => {
|
|
68
|
+
globalsRegistry.replaceGlobal('foo', { original: false })
|
|
69
|
+
expect(global.foo).toEqual({ original: false })
|
|
70
|
+
|
|
71
|
+
expect(() =>
|
|
72
|
+
globalsRegistry.replaceGlobal('foo', { original: false })
|
|
73
|
+
).toThrow('Failed to replace a global value at "foo": already replaced.')
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('does nothing if restoring an already restored global', () => {
|
|
77
|
+
const restoreGlobal = globalsRegistry.replaceGlobal('foo', {
|
|
78
|
+
original: false,
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
expect(global.foo).toEqual({ original: false })
|
|
82
|
+
|
|
83
|
+
restoreGlobal()
|
|
84
|
+
expect(global.foo).toEqual({ original: true })
|
|
85
|
+
|
|
86
|
+
restoreGlobal()
|
|
87
|
+
expect(global.foo).toEqual({ original: true })
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('restores the global', () => {
|
|
91
|
+
const restoreGlobal = globalsRegistry.replaceGlobal('foo', {
|
|
92
|
+
original: false,
|
|
93
|
+
})
|
|
94
|
+
expect(global.foo).toEqual({ original: false })
|
|
95
|
+
|
|
96
|
+
restoreGlobal()
|
|
97
|
+
expect(global.foo).toEqual({ original: true })
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('restores the global set on the prototype', () => {
|
|
101
|
+
function FakeGlobalScope() {}
|
|
102
|
+
FakeGlobalScope.prototype.foo = { prototype: true }
|
|
103
|
+
Object.setPrototypeOf(global, FakeGlobalScope.prototype)
|
|
104
|
+
Reflect.deleteProperty(global, 'foo')
|
|
105
|
+
|
|
106
|
+
expect(global.foo).toEqual({ prototype: true })
|
|
107
|
+
|
|
108
|
+
const restoreGlobal = globalsRegistry.replaceGlobal('foo', {
|
|
109
|
+
original: false,
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
expect(global.foo).toEqual({ original: false })
|
|
113
|
+
|
|
114
|
+
restoreGlobal()
|
|
115
|
+
expect(global.foo).toEqual({ prototype: true })
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('restores global to the original property descriptor', () => {
|
|
119
|
+
const descriptor: PropertyDescriptor = {
|
|
120
|
+
value: { original: true },
|
|
121
|
+
enumerable: false,
|
|
122
|
+
configurable: true,
|
|
123
|
+
writable: false,
|
|
124
|
+
}
|
|
125
|
+
Object.defineProperty(global, 'foo', descriptor)
|
|
126
|
+
expect(Object.getOwnPropertyDescriptor(global, 'foo')).toEqual(descriptor)
|
|
127
|
+
|
|
128
|
+
const restoreGlobal = globalsRegistry.replaceGlobal('foo', {
|
|
129
|
+
original: false,
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
expect(global.foo).toEqual({ original: false })
|
|
133
|
+
expect(Object.getOwnPropertyDescriptor(global, 'foo')).toEqual({
|
|
134
|
+
value: { original: false },
|
|
135
|
+
enumerable: true,
|
|
136
|
+
configurable: true,
|
|
137
|
+
writable: false,
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
restoreGlobal()
|
|
141
|
+
|
|
142
|
+
expect(global.foo).toEqual({ original: true })
|
|
143
|
+
expect(Object.getOwnPropertyDescriptor(global, 'foo')).toEqual(descriptor)
|
|
144
|
+
})
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { invariant } from 'outvariant'
|
|
2
|
+
|
|
3
|
+
class GlobalsRegistry {
|
|
4
|
+
#globals = new Map<keyof typeof globalThis, () => void>()
|
|
5
|
+
|
|
6
|
+
public replaceGlobal<K extends keyof typeof globalThis>(
|
|
7
|
+
key: K,
|
|
8
|
+
nextValue: (typeof globalThis)[K]
|
|
9
|
+
): () => void {
|
|
10
|
+
invariant(
|
|
11
|
+
!this.#globals.has(key),
|
|
12
|
+
`Failed to replace a global value at "${key}": already replaced.`
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const match = getDeepPropertyDescriptor(globalThis, key)
|
|
16
|
+
|
|
17
|
+
if (typeof match === 'undefined') {
|
|
18
|
+
console.warn(
|
|
19
|
+
`Failed to replace a global value at "${key}": not a global value.`
|
|
20
|
+
)
|
|
21
|
+
return () => {}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
Object.defineProperty(globalThis, key, {
|
|
25
|
+
value: nextValue,
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const restoreGlobal = () => {
|
|
31
|
+
if (!this.#globals.has(key)) {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (match.owner === globalThis) {
|
|
36
|
+
Object.defineProperty(match.owner, key, match.descriptor)
|
|
37
|
+
} else {
|
|
38
|
+
/**
|
|
39
|
+
* @todo Delete the proxy property set by the registry.
|
|
40
|
+
* If the owner isn't `globalThis`, the property is likely nested in the prototype.
|
|
41
|
+
* The registry does not meddle with those, they are left intact.
|
|
42
|
+
*/
|
|
43
|
+
Reflect.deleteProperty(globalThis, key)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
this.#globals.delete(key)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
this.#globals.set(key, restoreGlobal)
|
|
50
|
+
|
|
51
|
+
return restoreGlobal
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public restoreAllGlobals(): void {
|
|
55
|
+
const errors: Array<Error> = []
|
|
56
|
+
|
|
57
|
+
for (const [, restoreGlobal] of this.#globals) {
|
|
58
|
+
try {
|
|
59
|
+
restoreGlobal()
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (error instanceof Error) {
|
|
62
|
+
errors.push(error)
|
|
63
|
+
} else {
|
|
64
|
+
throw error
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (errors.length > 0) {
|
|
70
|
+
throw new AggregateError(errors, 'FOO!')
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const globalsRegistry = new GlobalsRegistry()
|
|
76
|
+
|
|
77
|
+
interface DeepDescriptorMatch {
|
|
78
|
+
owner: object
|
|
79
|
+
descriptor: PropertyDescriptor
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Returns a property descriptor for the given property on the owner.
|
|
84
|
+
* Walks down the prototype chain if the property does not exist on the owner.
|
|
85
|
+
* Handy for getting a global property descriptor where `globalThis` is
|
|
86
|
+
* replaced with a controlled class (e.g. ServiceWorkerGlobalScope).
|
|
87
|
+
*/
|
|
88
|
+
export function getDeepPropertyDescriptor<Owner extends object>(
|
|
89
|
+
owner: Owner,
|
|
90
|
+
key: keyof Owner
|
|
91
|
+
): DeepDescriptorMatch | undefined {
|
|
92
|
+
let currentOwner: Owner | null = owner
|
|
93
|
+
let descriptor: PropertyDescriptor | undefined
|
|
94
|
+
|
|
95
|
+
while (currentOwner) {
|
|
96
|
+
descriptor = Object.getOwnPropertyDescriptor(currentOwner, key)
|
|
97
|
+
|
|
98
|
+
if (descriptor) {
|
|
99
|
+
return {
|
|
100
|
+
owner: currentOwner,
|
|
101
|
+
descriptor,
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
currentOwner = Object.getPrototypeOf(currentOwner)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { vi, beforeAll, afterEach, afterAll, it, expect } from 'vitest'
|
|
2
2
|
import { hasConfigurableGlobal } from './hasConfigurableGlobal'
|
|
3
3
|
|
|
4
|
+
let originalGlobalPrototype = Object.getPrototypeOf(globalThis)
|
|
5
|
+
|
|
4
6
|
beforeAll(() => {
|
|
5
7
|
vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
6
8
|
})
|
|
7
9
|
|
|
8
10
|
afterEach(() => {
|
|
9
11
|
vi.clearAllMocks()
|
|
12
|
+
Object.setPrototypeOf(globalThis, originalGlobalPrototype)
|
|
10
13
|
})
|
|
11
14
|
|
|
12
15
|
afterAll(() => {
|
|
@@ -81,3 +84,11 @@ it('returns false and prints an error for global property that only has a getter
|
|
|
81
84
|
'[MSW] Failed to apply interceptor: the global `_onlyGetter` property is non-configurable. This is likely an issue with your environment. If you are using a framework, please open an issue about this in their repository.'
|
|
82
85
|
)
|
|
83
86
|
})
|
|
87
|
+
|
|
88
|
+
it('returns true for a property on a global prototype', () => {
|
|
89
|
+
function FakeGlobalScope() {}
|
|
90
|
+
FakeGlobalScope.prototype._prototypeGlobal = 123
|
|
91
|
+
Object.setPrototypeOf(globalThis, FakeGlobalScope.prototype)
|
|
92
|
+
|
|
93
|
+
expect(hasConfigurableGlobal('_prototypeGlobal')).toBe(true)
|
|
94
|
+
})
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
import { getDeepPropertyDescriptor } from './globalsRegistry'
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Returns a boolean indicating whether the given global property
|
|
3
5
|
* is defined and is configurable.
|
|
4
6
|
*/
|
|
5
|
-
export function hasConfigurableGlobal(
|
|
6
|
-
|
|
7
|
+
export function hasConfigurableGlobal(
|
|
8
|
+
propertyName: keyof typeof globalThis
|
|
9
|
+
): boolean {
|
|
10
|
+
const match = getDeepPropertyDescriptor(globalThis, propertyName)
|
|
7
11
|
|
|
8
12
|
// The property is not set at all.
|
|
9
|
-
if (typeof
|
|
13
|
+
if (typeof match === 'undefined') {
|
|
10
14
|
return false
|
|
11
15
|
}
|
|
12
16
|
|
|
17
|
+
const { descriptor } = match
|
|
18
|
+
|
|
13
19
|
// The property is set to a getter that returns undefined.
|
|
14
20
|
if (
|
|
15
21
|
typeof descriptor.get === 'function' &&
|