@mswjs/interceptors 0.41.4 → 0.41.6

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.
Files changed (156) hide show
  1. package/lib/browser/{XMLHttpRequest-C2KXXdBy.cjs → XMLHttpRequest-DNly-bu0.cjs} +9 -21
  2. package/lib/browser/XMLHttpRequest-DNly-bu0.cjs.map +1 -0
  3. package/lib/browser/{XMLHttpRequest-Bbvn_AjX.mjs → XMLHttpRequest-DaQ73vVt.mjs} +9 -21
  4. package/lib/{node/XMLHttpRequest-BBbs-p9i.mjs.map → browser/XMLHttpRequest-DaQ73vVt.mjs.map} +1 -1
  5. package/lib/browser/{createRequestId-Cs4oXfa1.cjs → createRequestId-DOf8Ktjs.cjs} +1 -1
  6. package/lib/browser/{createRequestId-Cs4oXfa1.cjs.map → createRequestId-DOf8Ktjs.cjs.map} +1 -1
  7. package/lib/browser/{createRequestId-DQcIlohW.mjs → createRequestId-DYCsFHOi.mjs} +1 -1
  8. package/lib/browser/{createRequestId-DQcIlohW.mjs.map → createRequestId-DYCsFHOi.mjs.map} +1 -1
  9. package/lib/browser/{fetch-D4es-Apw.mjs → fetch-BS6cxWzo.mjs} +12 -20
  10. package/lib/browser/fetch-BS6cxWzo.mjs.map +1 -0
  11. package/lib/browser/{fetch-CJYWVliE.cjs → fetch-BmrYPMQ0.cjs} +12 -20
  12. package/lib/browser/fetch-BmrYPMQ0.cjs.map +1 -0
  13. package/lib/browser/{getRawRequest-DaxX6uMy.cjs → getRawRequest-B6GjFKAr.cjs} +22 -11
  14. package/lib/browser/getRawRequest-B6GjFKAr.cjs.map +1 -0
  15. package/lib/browser/{getRawRequest-Df640uw8.mjs → getRawRequest-BP--nUwn.mjs} +23 -6
  16. package/lib/browser/getRawRequest-BP--nUwn.mjs.map +1 -0
  17. package/lib/browser/{glossary-BdLS4k1H.d.cts → glossary-1lhZx6Aw.d.cts} +2 -3
  18. package/lib/browser/{glossary-DYwOrogs.d.mts → glossary-nkHWcwvY.d.mts} +2 -3
  19. package/lib/browser/{handleRequest--veikAod.cjs → handleRequest-BIte-8l8.cjs} +3 -3
  20. package/lib/browser/{handleRequest--veikAod.cjs.map → handleRequest-BIte-8l8.cjs.map} +1 -1
  21. package/lib/browser/{handleRequest-Dq1a55b4.mjs → handleRequest-CnDA8MVO.mjs} +3 -3
  22. package/lib/browser/{handleRequest-Dq1a55b4.mjs.map → handleRequest-CnDA8MVO.mjs.map} +1 -1
  23. package/lib/browser/hasConfigurableGlobal-B39W0thh.mjs +98 -0
  24. package/lib/browser/hasConfigurableGlobal-B39W0thh.mjs.map +1 -0
  25. package/lib/browser/hasConfigurableGlobal-B5o6PHq3.cjs +115 -0
  26. package/lib/browser/hasConfigurableGlobal-B5o6PHq3.cjs.map +1 -0
  27. package/lib/browser/index.cjs +2 -3
  28. package/lib/browser/index.d.cts +10 -2
  29. package/lib/browser/index.d.mts +10 -2
  30. package/lib/browser/index.mjs +3 -3
  31. package/lib/browser/interceptors/WebSocket/index.cjs +6 -10
  32. package/lib/browser/interceptors/WebSocket/index.cjs.map +1 -1
  33. package/lib/browser/interceptors/WebSocket/index.mjs +6 -10
  34. package/lib/browser/interceptors/WebSocket/index.mjs.map +1 -1
  35. package/lib/browser/interceptors/XMLHttpRequest/index.cjs +5 -4
  36. package/lib/browser/interceptors/XMLHttpRequest/index.d.cts +1 -1
  37. package/lib/browser/interceptors/XMLHttpRequest/index.d.mts +1 -1
  38. package/lib/browser/interceptors/XMLHttpRequest/index.mjs +5 -4
  39. package/lib/browser/interceptors/fetch/index.cjs +5 -4
  40. package/lib/browser/interceptors/fetch/index.d.cts +1 -1
  41. package/lib/browser/interceptors/fetch/index.d.mts +1 -1
  42. package/lib/browser/interceptors/fetch/index.mjs +5 -4
  43. package/lib/browser/presets/browser.cjs +6 -5
  44. package/lib/browser/presets/browser.cjs.map +1 -1
  45. package/lib/browser/presets/browser.mjs +6 -5
  46. package/lib/browser/presets/browser.mjs.map +1 -1
  47. package/lib/node/{BatchInterceptor-BxgAXyLw.mjs → BatchInterceptor-0prNZ0wK.mjs} +2 -2
  48. package/lib/node/{BatchInterceptor-BxgAXyLw.mjs.map → BatchInterceptor-0prNZ0wK.mjs.map} +1 -1
  49. package/lib/node/{BatchInterceptor-7u9fqQIe.cjs → BatchInterceptor-Bo8JunSK.cjs} +2 -2
  50. package/lib/node/{BatchInterceptor-7u9fqQIe.cjs.map → BatchInterceptor-Bo8JunSK.cjs.map} +1 -1
  51. package/lib/node/{BatchInterceptor-D7mXzHcQ.d.mts → BatchInterceptor-KKF8Q47I.d.cts} +2 -2
  52. package/lib/node/{BatchInterceptor-D_YqR8qU.d.cts → BatchInterceptor-rSr-NH_H.d.mts} +2 -2
  53. package/lib/node/{ClientRequest-Cl3Ky7Tw.mjs → ClientRequest-BquJl6T-.mjs} +5 -5
  54. package/lib/node/{ClientRequest-Cl3Ky7Tw.mjs.map → ClientRequest-BquJl6T-.mjs.map} +1 -1
  55. package/lib/node/{ClientRequest-CMSXChAM.cjs → ClientRequest-OY5NnrOh.cjs} +5 -5
  56. package/lib/node/{ClientRequest-CMSXChAM.cjs.map → ClientRequest-OY5NnrOh.cjs.map} +1 -1
  57. package/lib/node/{Interceptor-DJ2akVWI.d.cts → Interceptor-BsZ21ue0.d.cts} +2 -3
  58. package/lib/node/{Interceptor-DEazpLJd.d.mts → Interceptor-soD-WpQO.d.mts} +2 -3
  59. package/lib/node/RemoteHttpInterceptor.cjs +10 -9
  60. package/lib/node/RemoteHttpInterceptor.cjs.map +1 -1
  61. package/lib/node/RemoteHttpInterceptor.d.cts +3 -3
  62. package/lib/node/RemoteHttpInterceptor.d.mts +3 -3
  63. package/lib/node/RemoteHttpInterceptor.mjs +10 -9
  64. package/lib/node/RemoteHttpInterceptor.mjs.map +1 -1
  65. package/lib/node/{XMLHttpRequest-Dj3xJgke.cjs → XMLHttpRequest-C1KTngEF.cjs} +10 -23
  66. package/lib/node/XMLHttpRequest-C1KTngEF.cjs.map +1 -0
  67. package/lib/node/{XMLHttpRequest-BBbs-p9i.mjs → XMLHttpRequest-Cj07Pos7.mjs} +10 -23
  68. package/lib/{browser/XMLHttpRequest-Bbvn_AjX.mjs.map → node/XMLHttpRequest-Cj07Pos7.mjs.map} +1 -1
  69. package/lib/node/{bufferUtils-_8XfKIfX.mjs → bufferUtils-DxPxwff_.mjs} +1 -1
  70. package/lib/node/{bufferUtils-_8XfKIfX.mjs.map → bufferUtils-DxPxwff_.mjs.map} +1 -1
  71. package/lib/node/{bufferUtils-DiCTqG-7.cjs → bufferUtils-S5_-2eN4.cjs} +1 -1
  72. package/lib/node/{bufferUtils-DiCTqG-7.cjs.map → bufferUtils-S5_-2eN4.cjs.map} +1 -1
  73. package/lib/node/{fetch-BoCFyaYx.cjs → fetch-B9UiBg-M.cjs} +12 -21
  74. package/lib/node/fetch-B9UiBg-M.cjs.map +1 -0
  75. package/lib/node/{fetch-DmiwAmpu.mjs → fetch-UxWd1aQX.mjs} +12 -21
  76. package/lib/node/fetch-UxWd1aQX.mjs.map +1 -0
  77. package/lib/node/{fetchUtils-DE_q7tpr.cjs → fetchUtils-BAlG765A.cjs} +22 -1
  78. package/lib/node/{fetchUtils-DE_q7tpr.cjs.map → fetchUtils-BAlG765A.cjs.map} +1 -1
  79. package/lib/node/{fetchUtils-BTrdMHGp.mjs → fetchUtils-Bq0Mdmkv.mjs} +22 -1
  80. package/lib/node/{fetchUtils-BTrdMHGp.mjs.map → fetchUtils-Bq0Mdmkv.mjs.map} +1 -1
  81. package/lib/node/{getRawRequest-BavnMWh_.cjs → getRawRequest-B6znU6il.cjs} +1 -1
  82. package/lib/node/{getRawRequest-BavnMWh_.cjs.map → getRawRequest-B6znU6il.cjs.map} +1 -1
  83. package/lib/node/{getRawRequest-DnwmXyOW.mjs → getRawRequest-C2-1urzA.mjs} +1 -1
  84. package/lib/node/{getRawRequest-DnwmXyOW.mjs.map → getRawRequest-C2-1urzA.mjs.map} +1 -1
  85. package/lib/node/{handleRequest-pLIe3KKo.cjs → handleRequest-DUPo40Df.cjs} +2 -2
  86. package/lib/node/{handleRequest-pLIe3KKo.cjs.map → handleRequest-DUPo40Df.cjs.map} +1 -1
  87. package/lib/node/{handleRequest-CDabRyt1.mjs → handleRequest-u6jpjgrr.mjs} +2 -2
  88. package/lib/node/{handleRequest-CDabRyt1.mjs.map → handleRequest-u6jpjgrr.mjs.map} +1 -1
  89. package/lib/node/hasConfigurableGlobal-Befl_QJD.cjs +97 -0
  90. package/lib/node/hasConfigurableGlobal-Befl_QJD.cjs.map +1 -0
  91. package/lib/node/hasConfigurableGlobal-jN_-v3gp.mjs +85 -0
  92. package/lib/node/hasConfigurableGlobal-jN_-v3gp.mjs.map +1 -0
  93. package/lib/node/{index-BMbJ8FXL.d.cts → index-BJ5E5aW-.d.cts} +2 -2
  94. package/lib/node/{index-C0YAQ36w.d.mts → index-DfoF45ih.d.mts} +2 -2
  95. package/lib/node/index.cjs +4 -6
  96. package/lib/node/index.cjs.map +1 -1
  97. package/lib/node/index.d.cts +11 -3
  98. package/lib/node/index.d.mts +11 -3
  99. package/lib/node/index.mjs +5 -6
  100. package/lib/node/index.mjs.map +1 -1
  101. package/lib/node/interceptors/ClientRequest/index.cjs +4 -4
  102. package/lib/node/interceptors/ClientRequest/index.d.cts +1 -1
  103. package/lib/node/interceptors/ClientRequest/index.d.mts +2 -2
  104. package/lib/node/interceptors/ClientRequest/index.mjs +4 -4
  105. package/lib/node/interceptors/XMLHttpRequest/index.cjs +5 -4
  106. package/lib/node/interceptors/XMLHttpRequest/index.d.cts +1 -1
  107. package/lib/node/interceptors/XMLHttpRequest/index.d.mts +1 -1
  108. package/lib/node/interceptors/XMLHttpRequest/index.mjs +5 -4
  109. package/lib/node/interceptors/fetch/index.cjs +4 -3
  110. package/lib/node/interceptors/fetch/index.d.cts +1 -1
  111. package/lib/node/interceptors/fetch/index.d.mts +1 -1
  112. package/lib/node/interceptors/fetch/index.mjs +4 -3
  113. package/lib/node/{node-dKdAf3tC.cjs → node-DIKcnzhK.cjs} +2 -2
  114. package/lib/node/{node-dKdAf3tC.cjs.map → node-DIKcnzhK.cjs.map} +1 -1
  115. package/lib/node/{node-DwCc6iuP.mjs → node-lsdNwZEW.mjs} +2 -2
  116. package/lib/node/{node-DwCc6iuP.mjs.map → node-lsdNwZEW.mjs.map} +1 -1
  117. package/lib/node/presets/node.cjs +8 -7
  118. package/lib/node/presets/node.cjs.map +1 -1
  119. package/lib/node/presets/node.d.cts +1 -1
  120. package/lib/node/presets/node.d.mts +2 -2
  121. package/lib/node/presets/node.mjs +8 -7
  122. package/lib/node/presets/node.mjs.map +1 -1
  123. package/lib/node/utils/node/index.cjs +1 -1
  124. package/lib/node/utils/node/index.mjs +1 -1
  125. package/package.json +1 -1
  126. package/src/RemoteHttpInterceptor.ts +1 -1
  127. package/src/glossary.ts +3 -5
  128. package/src/interceptors/WebSocket/index.ts +8 -15
  129. package/src/interceptors/XMLHttpRequest/index.ts +12 -32
  130. package/src/interceptors/fetch/index.ts +10 -26
  131. package/src/utils/fetchUtils.test.ts +25 -1
  132. package/src/utils/fetchUtils.ts +28 -0
  133. package/src/utils/globalUtils.test.ts +144 -0
  134. package/src/utils/globalsRegistry.ts +107 -0
  135. package/src/utils/hasConfigurableGlobal.test.ts +11 -0
  136. package/src/utils/hasConfigurableGlobal.ts +9 -3
  137. package/lib/browser/XMLHttpRequest-C2KXXdBy.cjs.map +0 -1
  138. package/lib/browser/fetch-CJYWVliE.cjs.map +0 -1
  139. package/lib/browser/fetch-D4es-Apw.mjs.map +0 -1
  140. package/lib/browser/getRawRequest-DaxX6uMy.cjs.map +0 -1
  141. package/lib/browser/getRawRequest-Df640uw8.mjs.map +0 -1
  142. package/lib/browser/hasConfigurableGlobal-BvCTG97d.cjs +0 -45
  143. package/lib/browser/hasConfigurableGlobal-BvCTG97d.cjs.map +0 -1
  144. package/lib/browser/hasConfigurableGlobal-npXitu1-.mjs +0 -33
  145. package/lib/browser/hasConfigurableGlobal-npXitu1-.mjs.map +0 -1
  146. package/lib/node/XMLHttpRequest-Dj3xJgke.cjs.map +0 -1
  147. package/lib/node/fetch-BoCFyaYx.cjs.map +0 -1
  148. package/lib/node/fetch-DmiwAmpu.mjs.map +0 -1
  149. package/lib/node/glossary-BLKRyLBd.cjs +0 -12
  150. package/lib/node/glossary-BLKRyLBd.cjs.map +0 -1
  151. package/lib/node/glossary-glQBRnVD.mjs +0 -6
  152. package/lib/node/glossary-glQBRnVD.mjs.map +0 -1
  153. package/lib/node/hasConfigurableGlobal-C97fWuaA.cjs +0 -26
  154. package/lib/node/hasConfigurableGlobal-C97fWuaA.cjs.map +0 -1
  155. package/lib/node/hasConfigurableGlobal-DBJA0vjm.mjs +0 -20
  156. package/lib/node/hasConfigurableGlobal-DBJA0vjm.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { l as HttpRequestEventMap, r as Interceptor } from "../../Interceptor-DEazpLJd.mjs";
1
+ import { l as HttpRequestEventMap, r as Interceptor } from "../../Interceptor-soD-WpQO.mjs";
2
2
  import { Emitter } from "strict-event-emitter";
3
3
 
4
4
  //#region src/interceptors/XMLHttpRequest/index.d.ts
@@ -1,6 +1,7 @@
1
- import "../../fetchUtils-BTrdMHGp.mjs";
2
- import "../../bufferUtils-_8XfKIfX.mjs";
3
- import "../../handleRequest-CDabRyt1.mjs";
4
- import { t as XMLHttpRequestInterceptor } from "../../XMLHttpRequest-BBbs-p9i.mjs";
1
+ import "../../fetchUtils-Bq0Mdmkv.mjs";
2
+ import "../../bufferUtils-DxPxwff_.mjs";
3
+ import "../../handleRequest-u6jpjgrr.mjs";
4
+ import { t as XMLHttpRequestInterceptor } from "../../XMLHttpRequest-Cj07Pos7.mjs";
5
+ import "../../hasConfigurableGlobal-jN_-v3gp.mjs";
5
6
 
6
7
  export { XMLHttpRequestInterceptor };
@@ -1,5 +1,6 @@
1
- require('../../fetchUtils-DE_q7tpr.cjs');
2
- require('../../handleRequest-pLIe3KKo.cjs');
3
- const require_fetch = require('../../fetch-BoCFyaYx.cjs');
1
+ require('../../fetchUtils-BAlG765A.cjs');
2
+ require('../../handleRequest-DUPo40Df.cjs');
3
+ require('../../hasConfigurableGlobal-Befl_QJD.cjs');
4
+ const require_fetch = require('../../fetch-B9UiBg-M.cjs');
4
5
 
5
6
  exports.FetchInterceptor = require_fetch.FetchInterceptor;
@@ -1,4 +1,4 @@
1
- import { l as HttpRequestEventMap, r as Interceptor } from "../../Interceptor-DJ2akVWI.cjs";
1
+ import { l as HttpRequestEventMap, r as Interceptor } from "../../Interceptor-BsZ21ue0.cjs";
2
2
 
3
3
  //#region src/interceptors/fetch/index.d.ts
4
4
  declare class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
@@ -1,4 +1,4 @@
1
- import { l as HttpRequestEventMap, r as Interceptor } from "../../Interceptor-DEazpLJd.mjs";
1
+ import { l as HttpRequestEventMap, r as Interceptor } from "../../Interceptor-soD-WpQO.mjs";
2
2
 
3
3
  //#region src/interceptors/fetch/index.d.ts
4
4
  declare class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
@@ -1,5 +1,6 @@
1
- import "../../fetchUtils-BTrdMHGp.mjs";
2
- import "../../handleRequest-CDabRyt1.mjs";
3
- import { t as FetchInterceptor } from "../../fetch-DmiwAmpu.mjs";
1
+ import "../../fetchUtils-Bq0Mdmkv.mjs";
2
+ import "../../handleRequest-u6jpjgrr.mjs";
3
+ import "../../hasConfigurableGlobal-jN_-v3gp.mjs";
4
+ import { t as FetchInterceptor } from "../../fetch-UxWd1aQX.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-BavnMWh_.cjs');
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-dKdAf3tC.cjs.map
39
+ //# sourceMappingURL=node-DIKcnzhK.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-dKdAf3tC.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
+ {"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-DnwmXyOW.mjs";
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-DwCc6iuP.mjs.map
27
+ //# sourceMappingURL=node-lsdNwZEW.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-DwCc6iuP.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
+ {"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-DE_q7tpr.cjs');
2
- require('../bufferUtils-DiCTqG-7.cjs');
3
- const require_ClientRequest = require('../ClientRequest-CMSXChAM.cjs');
4
- require('../handleRequest-pLIe3KKo.cjs');
5
- require('../node-dKdAf3tC.cjs');
6
- const require_XMLHttpRequest = require('../XMLHttpRequest-Dj3xJgke.cjs');
7
- const require_fetch = require('../fetch-BoCFyaYx.cjs');
1
+ require('../fetchUtils-BAlG765A.cjs');
2
+ require('../bufferUtils-S5_-2eN4.cjs');
3
+ const require_ClientRequest = require('../ClientRequest-OY5NnrOh.cjs');
4
+ require('../handleRequest-DUPo40Df.cjs');
5
+ require('../node-DIKcnzhK.cjs');
6
+ const require_XMLHttpRequest = require('../XMLHttpRequest-C1KTngEF.cjs');
7
+ require('../hasConfigurableGlobal-Befl_QJD.cjs');
8
+ const require_fetch = require('../fetch-B9UiBg-M.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":";;;;;;;;;;;;;AAQA,mBAAe;CACb,IAAIA,gDAA0B;CAC9B,IAAIC,kDAA2B;CAC/B,IAAIC,gCAAkB;CACvB"}
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-BMbJ8FXL.cjs";
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-DEazpLJd.mjs";
2
- import { t as ClientRequestInterceptor } from "../index-C0YAQ36w.mjs";
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-BTrdMHGp.mjs";
2
- import "../bufferUtils-_8XfKIfX.mjs";
3
- import { t as ClientRequestInterceptor } from "../ClientRequest-Cl3Ky7Tw.mjs";
4
- import "../handleRequest-CDabRyt1.mjs";
5
- import "../node-DwCc6iuP.mjs";
6
- import { t as XMLHttpRequestInterceptor } from "../XMLHttpRequest-BBbs-p9i.mjs";
7
- import { t as FetchInterceptor } from "../fetch-DmiwAmpu.mjs";
1
+ import "../fetchUtils-Bq0Mdmkv.mjs";
2
+ import "../bufferUtils-DxPxwff_.mjs";
3
+ import { t as ClientRequestInterceptor } from "../ClientRequest-BquJl6T-.mjs";
4
+ import "../handleRequest-u6jpjgrr.mjs";
5
+ import "../node-lsdNwZEW.mjs";
6
+ import { t as XMLHttpRequestInterceptor } from "../XMLHttpRequest-Cj07Pos7.mjs";
7
+ import "../hasConfigurableGlobal-jN_-v3gp.mjs";
8
+ import { t as FetchInterceptor } from "../fetch-UxWd1aQX.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":";;;;;;;;;;;;;AAQA,mBAAe;CACb,IAAI,0BAA0B;CAC9B,IAAI,2BAA2B;CAC/B,IAAI,kBAAkB;CACvB"}
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,4 +1,4 @@
1
- const require_node = require('../../node-dKdAf3tC.cjs');
1
+ const require_node = require('../../node-DIKcnzhK.cjs');
2
2
 
3
3
  exports.getClientRequestBodyStream = require_node.getClientRequestBodyStream;
4
4
  exports.setRawRequestBodyStream = require_node.setRawRequestBodyStream;
@@ -1,3 +1,3 @@
1
- import { n as setRawRequestBodyStream, t as getClientRequestBodyStream } from "../../node-DwCc6iuP.mjs";
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.4",
5
+ "version": "0.41.6",
6
6
  "main": "./lib/node/index.cjs",
7
7
  "module": "./lib/node/index.mjs",
8
8
  "types": "./lib/node/index.d.cts",
@@ -189,7 +189,7 @@ export class RemoteHttpResolver extends Interceptor<HttpRequestEventMap> {
189
189
 
190
190
  this.logger.info('received mocked response!', { response })
191
191
 
192
- const responseClone = response.clone()
192
+ const responseClone = FetchResponse.clone(response)
193
193
  const responseText = await responseClone.text()
194
194
 
195
195
  // // Send the mocked response to the child process.
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 originalWebSocketDescriptor = Object.getOwnPropertyDescriptor(
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
- Object.defineProperty(globalThis, 'WebSocket', {
179
- value: WebSocketProxy,
180
- configurable: true,
181
- })
176
+ logger.info('patching global WebSocket...')
182
177
 
183
- this.subscriptions.push(() => {
184
- Object.defineProperty(
185
- globalThis,
186
- 'WebSocket',
187
- originalWebSocketDescriptor!
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, IS_PATCHED_MODULE } from '../../glossary'
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 "XMLHttpRequest" module...')
24
+ logger.info('patching global XMLHttpRequest...')
25
25
 
26
- const PureXMLHttpRequest = globalThis.XMLHttpRequest
27
-
28
- invariant(
29
- !(PureXMLHttpRequest as any)[IS_PATCHED_MODULE],
30
- 'Failed to patch the "XMLHttpRequest" module: already patched.'
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
- 'native "XMLHttpRequest" module patched!',
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, IS_PATCHED_MODULE } from '../../glossary'
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 pureFetch = globalThis.fetch
31
+ const logger = this.logger.extend('setup')
32
32
 
33
- invariant(
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
- globalThis.fetch = async (input, init) => {
35
+ const fetchProxy: typeof fetch = async (input, init) => {
39
36
  const requestId = createRequestId()
40
37
 
41
38
  /**
@@ -88,7 +85,7 @@ export class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
88
85
  if (this.emitter.listenerCount('response') > 0) {
89
86
  this.logger.info('emitting the "response" event...')
90
87
 
91
- const responseClone = originalResponse.clone()
88
+ const responseClone = FetchResponse.clone(originalResponse)
92
89
  await emitAsync(this.emitter, 'response', {
93
90
  response: responseClone,
94
91
  isMockedResponse: false,
@@ -159,7 +156,7 @@ export class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
159
156
  // Clone the mocked response for the "response" event listener.
160
157
  // This way, the listener can read the response and not lock its body
161
158
  // for the actual fetch consumer.
162
- response: response.clone(),
159
+ response: FetchResponse.clone(response),
163
160
  isMockedResponse: true,
164
161
  request,
165
162
  requestId,
@@ -192,23 +189,10 @@ export class FetchInterceptor extends Interceptor<HttpRequestEventMap> {
192
189
  return responsePromise
193
190
  }
194
191
 
195
- Object.defineProperty(globalThis.fetch, IS_PATCHED_MODULE, {
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
- globalThis.fetch = pureFetch
194
+ this.subscriptions.push(globalsRegistry.replaceGlobal('fetch', fetchProxy))
207
195
 
208
- this.logger.info(
209
- 'restored native "globalThis.fetch"!',
210
- globalThis.fetch.name
211
- )
212
- })
196
+ logger.info('global fetch patched!', globalThis.fetch.name)
213
197
  }
214
198
  }
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest'
2
- import { FetchRequest } from './fetchUtils'
2
+ import { FetchRequest, FetchResponse } from './fetchUtils'
3
3
 
4
4
  describe('FetchRequest', () => {
5
5
  const URL = 'https://example.com/'
@@ -83,3 +83,27 @@ describe('FetchRequest', () => {
83
83
  .toHaveProperty('body', expect.any(ReadableStream))
84
84
  })
85
85
  })
86
+
87
+ describe('FetchResponse', () => {
88
+ it('clones a regular response', () => {
89
+ const response = new Response('hello world')
90
+ expect(FetchResponse.clone(response)).toMatchObject(response)
91
+ })
92
+
93
+ it('returns a mocked 500 response if cloning throws', async () => {
94
+ const response = new Response('hello world')
95
+ const error = new Error('Cannot clone!')
96
+ response.clone = function () {
97
+ throw error
98
+ }
99
+
100
+ const clone = FetchResponse.clone(response)
101
+ expect.soft(clone.status).toBe(500)
102
+ expect.soft(clone.statusText).toBe('Unclonable Response')
103
+ await expect.soft(clone.json()).resolves.toEqual({
104
+ name: error.name,
105
+ message: error.message,
106
+ stack: error.stack,
107
+ })
108
+ })
109
+ })
@@ -218,6 +218,34 @@ export class FetchResponse extends Response {
218
218
  return headers
219
219
  }
220
220
 
221
+ /**
222
+ * Safely clones the given `Response`.
223
+ * Coerces response clone exceptions into 500 mocked responses.
224
+ * Handy in the environments that introduce arbitrary response
225
+ * cloning restrictions, like "101 Switching Protocols" cloning
226
+ * in "miniflare".
227
+ */
228
+ static clone(response: Response): Response {
229
+ try {
230
+ const clone = response.clone()
231
+ return clone
232
+ } catch (error) {
233
+ return Response.json(
234
+ error instanceof Error
235
+ ? {
236
+ name: error.name,
237
+ message: error.message,
238
+ stack: error.stack,
239
+ }
240
+ : {},
241
+ {
242
+ status: 500,
243
+ statusText: 'Unclonable Response',
244
+ }
245
+ )
246
+ }
247
+ }
248
+
221
249
  constructor(body?: BodyInit | null, init: FetchResponseInit = {}) {
222
250
  const status = init.status ?? 200
223
251
  const safeStatus = FetchResponse.isConfigurableStatusCode(status)
@@ -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
+ })