@mswjs/interceptors 0.40.0 → 0.41.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.
Files changed (275) hide show
  1. package/ClientRequest/package.json +7 -2
  2. package/RemoteHttpInterceptor/package.json +7 -2
  3. package/WebSocket/package.json +9 -2
  4. package/XMLHttpRequest/package.json +9 -3
  5. package/fetch/package.json +9 -3
  6. package/lib/browser/Interceptor-2mUoKZL1.d.mts +65 -0
  7. package/lib/browser/Interceptor-Deczogc8.d.cts +65 -0
  8. package/lib/browser/XMLHttpRequest-BUfglQD1.cjs +761 -0
  9. package/lib/browser/XMLHttpRequest-BUfglQD1.cjs.map +1 -0
  10. package/lib/browser/XMLHttpRequest-DS5fc8Qs.mjs +756 -0
  11. package/lib/browser/XMLHttpRequest-DS5fc8Qs.mjs.map +1 -0
  12. package/lib/browser/bufferUtils-BiiO6HZv.mjs +20 -0
  13. package/lib/browser/bufferUtils-BiiO6HZv.mjs.map +1 -0
  14. package/lib/browser/bufferUtils-Uc0eRItL.cjs +38 -0
  15. package/lib/browser/bufferUtils-Uc0eRItL.cjs.map +1 -0
  16. package/lib/browser/createRequestId-Cs4oXfa1.cjs +205 -0
  17. package/lib/browser/createRequestId-Cs4oXfa1.cjs.map +1 -0
  18. package/lib/browser/createRequestId-DQcIlohW.mjs +170 -0
  19. package/lib/browser/createRequestId-DQcIlohW.mjs.map +1 -0
  20. package/lib/browser/fetch-BHcqM3z7.cjs +253 -0
  21. package/lib/browser/fetch-BHcqM3z7.cjs.map +1 -0
  22. package/lib/browser/fetch-DSJoynSF.mjs +248 -0
  23. package/lib/browser/fetch-DSJoynSF.mjs.map +1 -0
  24. package/lib/browser/getRawRequest-BTaNLFr0.mjs +218 -0
  25. package/lib/browser/getRawRequest-BTaNLFr0.mjs.map +1 -0
  26. package/lib/browser/getRawRequest-zx8rUJL2.cjs +259 -0
  27. package/lib/browser/getRawRequest-zx8rUJL2.cjs.map +1 -0
  28. package/lib/browser/glossary-BdLS4k1H.d.cts +70 -0
  29. package/lib/browser/glossary-gEEJhK4S.d.mts +70 -0
  30. package/lib/browser/handleRequest-DI6a7Dty.cjs +189 -0
  31. package/lib/browser/handleRequest-DI6a7Dty.cjs.map +1 -0
  32. package/lib/browser/handleRequest-DxGbCTbb.mjs +178 -0
  33. package/lib/browser/handleRequest-DxGbCTbb.mjs.map +1 -0
  34. package/lib/browser/hasConfigurableGlobal-C8kXFDic.mjs +33 -0
  35. package/lib/browser/hasConfigurableGlobal-C8kXFDic.mjs.map +1 -0
  36. package/lib/browser/hasConfigurableGlobal-D7S3l5h6.cjs +45 -0
  37. package/lib/browser/hasConfigurableGlobal-D7S3l5h6.cjs.map +1 -0
  38. package/lib/browser/index.cjs +68 -0
  39. package/lib/browser/index.cjs.map +1 -0
  40. package/lib/browser/index.d.cts +87 -0
  41. package/lib/browser/index.d.mts +87 -0
  42. package/lib/browser/index.mjs +49 -77
  43. package/lib/browser/index.mjs.map +1 -1
  44. package/lib/browser/interceptors/WebSocket/index.cjs +641 -0
  45. package/lib/browser/interceptors/WebSocket/index.cjs.map +1 -0
  46. package/lib/browser/interceptors/WebSocket/index.d.cts +277 -0
  47. package/lib/browser/interceptors/WebSocket/index.d.mts +277 -0
  48. package/lib/browser/interceptors/WebSocket/index.mjs +607 -694
  49. package/lib/browser/interceptors/WebSocket/index.mjs.map +1 -1
  50. package/lib/browser/interceptors/XMLHttpRequest/index.cjs +7 -0
  51. package/lib/browser/interceptors/XMLHttpRequest/index.d.cts +15 -0
  52. package/lib/browser/interceptors/XMLHttpRequest/index.d.mts +15 -0
  53. package/lib/browser/interceptors/XMLHttpRequest/index.mjs +7 -12
  54. package/lib/browser/interceptors/fetch/index.cjs +6 -0
  55. package/lib/browser/interceptors/fetch/index.d.cts +13 -0
  56. package/lib/browser/interceptors/fetch/index.d.mts +13 -0
  57. package/lib/browser/interceptors/fetch/index.mjs +6 -11
  58. package/lib/browser/presets/browser.cjs +17 -0
  59. package/lib/browser/presets/browser.cjs.map +1 -0
  60. package/lib/browser/presets/browser.d.cts +12 -0
  61. package/lib/browser/presets/browser.d.mts +14 -0
  62. package/lib/browser/presets/browser.mjs +15 -19
  63. package/lib/browser/presets/browser.mjs.map +1 -1
  64. package/lib/node/BatchInterceptor-3LnAnLTx.cjs +49 -0
  65. package/lib/node/BatchInterceptor-3LnAnLTx.cjs.map +1 -0
  66. package/lib/node/BatchInterceptor-D7mXzHcQ.d.mts +26 -0
  67. package/lib/node/BatchInterceptor-DFaBPilf.mjs +44 -0
  68. package/lib/node/BatchInterceptor-DFaBPilf.mjs.map +1 -0
  69. package/lib/node/BatchInterceptor-D_YqR8qU.d.cts +26 -0
  70. package/lib/node/ClientRequest-2rDe54Ui.cjs +1043 -0
  71. package/lib/node/ClientRequest-2rDe54Ui.cjs.map +1 -0
  72. package/lib/node/ClientRequest-Ca8Qykuv.mjs +1034 -0
  73. package/lib/node/ClientRequest-Ca8Qykuv.mjs.map +1 -0
  74. package/lib/node/Interceptor-DEazpLJd.d.mts +133 -0
  75. package/lib/node/Interceptor-DJ2akVWI.d.cts +133 -0
  76. package/lib/node/RemoteHttpInterceptor.cjs +154 -0
  77. package/lib/node/RemoteHttpInterceptor.cjs.map +1 -0
  78. package/lib/node/RemoteHttpInterceptor.d.cts +39 -0
  79. package/lib/node/RemoteHttpInterceptor.d.mts +39 -0
  80. package/lib/node/RemoteHttpInterceptor.mjs +145 -190
  81. package/lib/node/RemoteHttpInterceptor.mjs.map +1 -1
  82. package/lib/node/XMLHttpRequest-B7kJdYYI.cjs +763 -0
  83. package/lib/node/XMLHttpRequest-B7kJdYYI.cjs.map +1 -0
  84. package/lib/node/XMLHttpRequest-C8dIZpds.mjs +757 -0
  85. package/lib/node/XMLHttpRequest-C8dIZpds.mjs.map +1 -0
  86. package/lib/node/bufferUtils-DiCTqG-7.cjs +38 -0
  87. package/lib/node/bufferUtils-DiCTqG-7.cjs.map +1 -0
  88. package/lib/node/bufferUtils-_8XfKIfX.mjs +20 -0
  89. package/lib/node/bufferUtils-_8XfKIfX.mjs.map +1 -0
  90. package/lib/node/chunk-CbDLau6x.cjs +34 -0
  91. package/lib/node/fetch-BmXpK10r.cjs +272 -0
  92. package/lib/node/fetch-BmXpK10r.cjs.map +1 -0
  93. package/lib/node/fetch-G1DVwDKG.mjs +265 -0
  94. package/lib/node/fetch-G1DVwDKG.mjs.map +1 -0
  95. package/lib/node/fetchUtils-BaY5iWXw.cjs +419 -0
  96. package/lib/node/fetchUtils-BaY5iWXw.cjs.map +1 -0
  97. package/lib/node/fetchUtils-CoU35g3M.mjs +359 -0
  98. package/lib/node/fetchUtils-CoU35g3M.mjs.map +1 -0
  99. package/lib/node/getRawRequest-BavnMWh_.cjs +36 -0
  100. package/lib/node/getRawRequest-BavnMWh_.cjs.map +1 -0
  101. package/lib/node/getRawRequest-DnwmXyOW.mjs +24 -0
  102. package/lib/node/getRawRequest-DnwmXyOW.mjs.map +1 -0
  103. package/lib/node/glossary-BLKRyLBd.cjs +12 -0
  104. package/lib/node/glossary-BLKRyLBd.cjs.map +1 -0
  105. package/lib/node/glossary-glQBRnVD.mjs +6 -0
  106. package/lib/node/glossary-glQBRnVD.mjs.map +1 -0
  107. package/lib/node/handleRequest-Bb7Y-XLw.cjs +220 -0
  108. package/lib/node/handleRequest-Bb7Y-XLw.cjs.map +1 -0
  109. package/lib/node/handleRequest-Y97UwBbF.mjs +190 -0
  110. package/lib/node/handleRequest-Y97UwBbF.mjs.map +1 -0
  111. package/lib/node/hasConfigurableGlobal-C97fWuaA.cjs +26 -0
  112. package/lib/node/hasConfigurableGlobal-C97fWuaA.cjs.map +1 -0
  113. package/lib/node/hasConfigurableGlobal-DBJA0vjm.mjs +20 -0
  114. package/lib/node/hasConfigurableGlobal-DBJA0vjm.mjs.map +1 -0
  115. package/lib/node/index-BMbJ8FXL.d.cts +113 -0
  116. package/lib/node/index-C0YAQ36w.d.mts +113 -0
  117. package/lib/node/index.cjs +30 -0
  118. package/lib/node/index.cjs.map +1 -0
  119. package/lib/node/index.d.cts +66 -0
  120. package/lib/node/index.d.mts +66 -0
  121. package/lib/node/index.mjs +13 -41
  122. package/lib/node/index.mjs.map +1 -1
  123. package/lib/node/interceptors/ClientRequest/index.cjs +6 -0
  124. package/lib/node/interceptors/ClientRequest/index.d.cts +2 -0
  125. package/lib/node/interceptors/ClientRequest/index.d.mts +3 -0
  126. package/lib/node/interceptors/ClientRequest/index.mjs +6 -11
  127. package/lib/node/interceptors/XMLHttpRequest/index.cjs +6 -0
  128. package/lib/node/interceptors/XMLHttpRequest/index.d.cts +14 -0
  129. package/lib/node/interceptors/XMLHttpRequest/index.d.mts +14 -0
  130. package/lib/node/interceptors/XMLHttpRequest/index.mjs +6 -13
  131. package/lib/node/interceptors/fetch/index.cjs +5 -0
  132. package/lib/node/interceptors/fetch/index.d.cts +12 -0
  133. package/lib/node/interceptors/fetch/index.d.mts +12 -0
  134. package/lib/node/interceptors/fetch/index.mjs +5 -12
  135. package/lib/node/node-DwCc6iuP.mjs +27 -0
  136. package/lib/node/node-DwCc6iuP.mjs.map +1 -0
  137. package/lib/node/node-dKdAf3tC.cjs +39 -0
  138. package/lib/node/node-dKdAf3tC.cjs.map +1 -0
  139. package/lib/node/presets/node.cjs +22 -0
  140. package/lib/node/presets/node.cjs.map +1 -0
  141. package/lib/node/presets/node.d.cts +13 -0
  142. package/lib/node/presets/node.d.mts +15 -0
  143. package/lib/node/presets/node.mjs +18 -23
  144. package/lib/node/presets/node.mjs.map +1 -1
  145. package/lib/node/utils/node/index.cjs +4 -0
  146. package/lib/node/utils/node/{index.d.ts → index.d.cts} +5 -2
  147. package/lib/node/utils/node/index.d.mts +16 -0
  148. package/lib/node/utils/node/index.mjs +3 -10
  149. package/package.json +33 -59
  150. package/presets/browser/package.json +2 -3
  151. package/presets/node/package.json +7 -2
  152. package/src/interceptors/ClientRequest/MockHttpSocket.ts +21 -8
  153. package/src/interceptors/ClientRequest/utils/parserUtils.ts +48 -0
  154. package/src/interceptors/WebSocket/WebSocketClientConnection.ts +3 -5
  155. package/src/interceptors/WebSocket/WebSocketOverride.ts +51 -5
  156. package/src/interceptors/WebSocket/WebSocketServerConnection.ts +3 -5
  157. package/src/interceptors/WebSocket/index.ts +4 -1
  158. package/src/interceptors/XMLHttpRequest/utils/getBodyByteLength.test.ts +2 -2
  159. package/lib/browser/Interceptor-af98b768.d.ts +0 -63
  160. package/lib/browser/chunk-2HUMWGRD.js +0 -37
  161. package/lib/browser/chunk-2HUMWGRD.js.map +0 -1
  162. package/lib/browser/chunk-2MCNQOY3.js +0 -851
  163. package/lib/browser/chunk-2MCNQOY3.js.map +0 -1
  164. package/lib/browser/chunk-57RIRQUY.js +0 -218
  165. package/lib/browser/chunk-57RIRQUY.js.map +0 -1
  166. package/lib/browser/chunk-6HYIRFX2.mjs +0 -22
  167. package/lib/browser/chunk-6HYIRFX2.mjs.map +0 -1
  168. package/lib/browser/chunk-FW45TRCB.js +0 -178
  169. package/lib/browser/chunk-FW45TRCB.js.map +0 -1
  170. package/lib/browser/chunk-JQ2S7G56.js +0 -185
  171. package/lib/browser/chunk-JQ2S7G56.js.map +0 -1
  172. package/lib/browser/chunk-LIKZF2VU.mjs +0 -218
  173. package/lib/browser/chunk-LIKZF2VU.mjs.map +0 -1
  174. package/lib/browser/chunk-LK6DILFK.js +0 -22
  175. package/lib/browser/chunk-LK6DILFK.js.map +0 -1
  176. package/lib/browser/chunk-MNT2FUCH.js +0 -301
  177. package/lib/browser/chunk-MNT2FUCH.js.map +0 -1
  178. package/lib/browser/chunk-VOUOVDAW.mjs +0 -178
  179. package/lib/browser/chunk-VOUOVDAW.mjs.map +0 -1
  180. package/lib/browser/chunk-VYSDLBSS.mjs +0 -37
  181. package/lib/browser/chunk-VYSDLBSS.mjs.map +0 -1
  182. package/lib/browser/chunk-WADP6VHN.mjs +0 -851
  183. package/lib/browser/chunk-WADP6VHN.mjs.map +0 -1
  184. package/lib/browser/chunk-WOWPV4GR.mjs +0 -301
  185. package/lib/browser/chunk-WOWPV4GR.mjs.map +0 -1
  186. package/lib/browser/chunk-Z5TSB3T6.mjs +0 -185
  187. package/lib/browser/chunk-Z5TSB3T6.mjs.map +0 -1
  188. package/lib/browser/glossary-f7ee1c9d.d.ts +0 -74
  189. package/lib/browser/index.d.ts +0 -82
  190. package/lib/browser/index.js +0 -83
  191. package/lib/browser/index.js.map +0 -1
  192. package/lib/browser/interceptors/WebSocket/index.d.ts +0 -271
  193. package/lib/browser/interceptors/WebSocket/index.js +0 -721
  194. package/lib/browser/interceptors/WebSocket/index.js.map +0 -1
  195. package/lib/browser/interceptors/XMLHttpRequest/index.d.ts +0 -14
  196. package/lib/browser/interceptors/XMLHttpRequest/index.js +0 -12
  197. package/lib/browser/interceptors/XMLHttpRequest/index.js.map +0 -1
  198. package/lib/browser/interceptors/XMLHttpRequest/index.mjs.map +0 -1
  199. package/lib/browser/interceptors/fetch/index.d.ts +0 -13
  200. package/lib/browser/interceptors/fetch/index.js +0 -11
  201. package/lib/browser/interceptors/fetch/index.js.map +0 -1
  202. package/lib/browser/interceptors/fetch/index.mjs.map +0 -1
  203. package/lib/browser/presets/browser.d.ts +0 -14
  204. package/lib/browser/presets/browser.js +0 -21
  205. package/lib/browser/presets/browser.js.map +0 -1
  206. package/lib/node/BatchInterceptor-cb9a2eee.d.ts +0 -24
  207. package/lib/node/Interceptor-dc0a39b5.d.ts +0 -136
  208. package/lib/node/RemoteHttpInterceptor.d.ts +0 -44
  209. package/lib/node/RemoteHttpInterceptor.js +0 -197
  210. package/lib/node/RemoteHttpInterceptor.js.map +0 -1
  211. package/lib/node/chunk-5UGIB6OX.mjs +0 -1126
  212. package/lib/node/chunk-5UGIB6OX.mjs.map +0 -1
  213. package/lib/node/chunk-5V3SIIW2.mjs +0 -853
  214. package/lib/node/chunk-5V3SIIW2.mjs.map +0 -1
  215. package/lib/node/chunk-6B3ZQOO2.js +0 -853
  216. package/lib/node/chunk-6B3ZQOO2.js.map +0 -1
  217. package/lib/node/chunk-6HYIRFX2.mjs +0 -22
  218. package/lib/node/chunk-6HYIRFX2.mjs.map +0 -1
  219. package/lib/node/chunk-6YM4PLBI.mjs +0 -7
  220. package/lib/node/chunk-6YM4PLBI.mjs.map +0 -1
  221. package/lib/node/chunk-73NOP3T5.js +0 -7
  222. package/lib/node/chunk-73NOP3T5.js.map +0 -1
  223. package/lib/node/chunk-7Q53NNPV.js +0 -189
  224. package/lib/node/chunk-7Q53NNPV.js.map +0 -1
  225. package/lib/node/chunk-DOWWQYXZ.js +0 -369
  226. package/lib/node/chunk-DOWWQYXZ.js.map +0 -1
  227. package/lib/node/chunk-FRZQJNBO.js +0 -318
  228. package/lib/node/chunk-FRZQJNBO.js.map +0 -1
  229. package/lib/node/chunk-GKN5RBVR.mjs +0 -32
  230. package/lib/node/chunk-GKN5RBVR.mjs.map +0 -1
  231. package/lib/node/chunk-J5MULIHT.js +0 -51
  232. package/lib/node/chunk-J5MULIHT.js.map +0 -1
  233. package/lib/node/chunk-JXGB54LE.mjs +0 -369
  234. package/lib/node/chunk-JXGB54LE.mjs.map +0 -1
  235. package/lib/node/chunk-LK6DILFK.js +0 -22
  236. package/lib/node/chunk-LK6DILFK.js.map +0 -1
  237. package/lib/node/chunk-OFW5L5ET.mjs +0 -318
  238. package/lib/node/chunk-OFW5L5ET.mjs.map +0 -1
  239. package/lib/node/chunk-PFGO5BSM.js +0 -25
  240. package/lib/node/chunk-PFGO5BSM.js.map +0 -1
  241. package/lib/node/chunk-R6T7CL5E.mjs +0 -189
  242. package/lib/node/chunk-R6T7CL5E.mjs.map +0 -1
  243. package/lib/node/chunk-SQ6RHTJR.mjs +0 -51
  244. package/lib/node/chunk-SQ6RHTJR.mjs.map +0 -1
  245. package/lib/node/chunk-SRMAQGPM.js +0 -30
  246. package/lib/node/chunk-SRMAQGPM.js.map +0 -1
  247. package/lib/node/chunk-T3TW4P64.js +0 -32
  248. package/lib/node/chunk-T3TW4P64.js.map +0 -1
  249. package/lib/node/chunk-TX5GBTFY.mjs +0 -25
  250. package/lib/node/chunk-TX5GBTFY.mjs.map +0 -1
  251. package/lib/node/chunk-VYO5XDY2.js +0 -1126
  252. package/lib/node/chunk-VYO5XDY2.js.map +0 -1
  253. package/lib/node/chunk-YWNGXXUQ.mjs +0 -30
  254. package/lib/node/chunk-YWNGXXUQ.mjs.map +0 -1
  255. package/lib/node/index.d.ts +0 -61
  256. package/lib/node/index.js +0 -45
  257. package/lib/node/index.js.map +0 -1
  258. package/lib/node/interceptors/ClientRequest/index.d.ts +0 -110
  259. package/lib/node/interceptors/ClientRequest/index.js +0 -11
  260. package/lib/node/interceptors/ClientRequest/index.js.map +0 -1
  261. package/lib/node/interceptors/ClientRequest/index.mjs.map +0 -1
  262. package/lib/node/interceptors/XMLHttpRequest/index.d.ts +0 -13
  263. package/lib/node/interceptors/XMLHttpRequest/index.js +0 -13
  264. package/lib/node/interceptors/XMLHttpRequest/index.js.map +0 -1
  265. package/lib/node/interceptors/XMLHttpRequest/index.mjs.map +0 -1
  266. package/lib/node/interceptors/fetch/index.d.ts +0 -12
  267. package/lib/node/interceptors/fetch/index.js +0 -12
  268. package/lib/node/interceptors/fetch/index.js.map +0 -1
  269. package/lib/node/interceptors/fetch/index.mjs.map +0 -1
  270. package/lib/node/presets/node.d.ts +0 -15
  271. package/lib/node/presets/node.js +0 -27
  272. package/lib/node/presets/node.js.map +0 -1
  273. package/lib/node/utils/node/index.js +0 -10
  274. package/lib/node/utils/node/index.js.map +0 -1
  275. package/lib/node/utils/node/index.mjs.map +0 -1
@@ -1,721 +1,634 @@
1
- import {
2
- emitAsync,
3
- hasConfigurableGlobal
4
- } from "../../chunk-VYSDLBSS.mjs";
5
- import {
6
- Interceptor,
7
- createRequestId
8
- } from "../../chunk-Z5TSB3T6.mjs";
1
+ import { r as Interceptor, t as createRequestId } from "../../createRequestId-DQcIlohW.mjs";
2
+ import { n as emitAsync, t as hasConfigurableGlobal } from "../../hasConfigurableGlobal-C8kXFDic.mjs";
3
+ import { DeferredPromise } from "@open-draft/deferred-promise";
4
+ import { invariant } from "outvariant";
9
5
 
10
- // src/interceptors/WebSocket/utils/bindEvent.ts
6
+ //#region src/interceptors/WebSocket/utils/bindEvent.ts
11
7
  function bindEvent(target, event) {
12
- Object.defineProperties(event, {
13
- target: {
14
- value: target,
15
- enumerable: true,
16
- writable: true
17
- },
18
- currentTarget: {
19
- value: target,
20
- enumerable: true,
21
- writable: true
22
- }
23
- });
24
- return event;
8
+ Object.defineProperties(event, {
9
+ target: {
10
+ value: target,
11
+ enumerable: true,
12
+ writable: true
13
+ },
14
+ currentTarget: {
15
+ value: target,
16
+ enumerable: true,
17
+ writable: true
18
+ }
19
+ });
20
+ return event;
25
21
  }
26
22
 
27
- // src/interceptors/WebSocket/utils/events.ts
28
- var kCancelable = Symbol("kCancelable");
29
- var kDefaultPrevented = Symbol("kDefaultPrevented");
23
+ //#endregion
24
+ //#region src/interceptors/WebSocket/utils/events.ts
25
+ const kCancelable = Symbol("kCancelable");
26
+ const kDefaultPrevented = Symbol("kDefaultPrevented");
27
+ /**
28
+ * A `MessageEvent` superset that supports event cancellation
29
+ * in Node.js. It's rather non-intrusive so it can be safely
30
+ * used in the browser as well.
31
+ *
32
+ * @see https://github.com/nodejs/node/issues/51767
33
+ */
30
34
  var CancelableMessageEvent = class extends MessageEvent {
31
- constructor(type, init) {
32
- super(type, init);
33
- this[kCancelable] = !!init.cancelable;
34
- this[kDefaultPrevented] = false;
35
- }
36
- get cancelable() {
37
- return this[kCancelable];
38
- }
39
- set cancelable(nextCancelable) {
40
- this[kCancelable] = nextCancelable;
41
- }
42
- get defaultPrevented() {
43
- return this[kDefaultPrevented];
44
- }
45
- set defaultPrevented(nextDefaultPrevented) {
46
- this[kDefaultPrevented] = nextDefaultPrevented;
47
- }
48
- preventDefault() {
49
- if (this.cancelable && !this[kDefaultPrevented]) {
50
- this[kDefaultPrevented] = true;
51
- }
52
- }
35
+ constructor(type, init) {
36
+ super(type, init);
37
+ this[kCancelable] = !!init.cancelable;
38
+ this[kDefaultPrevented] = false;
39
+ }
40
+ get cancelable() {
41
+ return this[kCancelable];
42
+ }
43
+ set cancelable(nextCancelable) {
44
+ this[kCancelable] = nextCancelable;
45
+ }
46
+ get defaultPrevented() {
47
+ return this[kDefaultPrevented];
48
+ }
49
+ set defaultPrevented(nextDefaultPrevented) {
50
+ this[kDefaultPrevented] = nextDefaultPrevented;
51
+ }
52
+ preventDefault() {
53
+ if (this.cancelable && !this[kDefaultPrevented]) this[kDefaultPrevented] = true;
54
+ }
53
55
  };
54
- kCancelable, kDefaultPrevented;
55
56
  var CloseEvent = class extends Event {
56
- constructor(type, init = {}) {
57
- super(type, init);
58
- this.code = init.code === void 0 ? 0 : init.code;
59
- this.reason = init.reason === void 0 ? "" : init.reason;
60
- this.wasClean = init.wasClean === void 0 ? false : init.wasClean;
61
- }
57
+ constructor(type, init = {}) {
58
+ super(type, init);
59
+ this.code = init.code === void 0 ? 0 : init.code;
60
+ this.reason = init.reason === void 0 ? "" : init.reason;
61
+ this.wasClean = init.wasClean === void 0 ? false : init.wasClean;
62
+ }
62
63
  };
63
64
  var CancelableCloseEvent = class extends CloseEvent {
64
- constructor(type, init = {}) {
65
- super(type, init);
66
- this[kCancelable] = !!init.cancelable;
67
- this[kDefaultPrevented] = false;
68
- }
69
- get cancelable() {
70
- return this[kCancelable];
71
- }
72
- set cancelable(nextCancelable) {
73
- this[kCancelable] = nextCancelable;
74
- }
75
- get defaultPrevented() {
76
- return this[kDefaultPrevented];
77
- }
78
- set defaultPrevented(nextDefaultPrevented) {
79
- this[kDefaultPrevented] = nextDefaultPrevented;
80
- }
81
- preventDefault() {
82
- if (this.cancelable && !this[kDefaultPrevented]) {
83
- this[kDefaultPrevented] = true;
84
- }
85
- }
65
+ constructor(type, init = {}) {
66
+ super(type, init);
67
+ this[kCancelable] = !!init.cancelable;
68
+ this[kDefaultPrevented] = false;
69
+ }
70
+ get cancelable() {
71
+ return this[kCancelable];
72
+ }
73
+ set cancelable(nextCancelable) {
74
+ this[kCancelable] = nextCancelable;
75
+ }
76
+ get defaultPrevented() {
77
+ return this[kDefaultPrevented];
78
+ }
79
+ set defaultPrevented(nextDefaultPrevented) {
80
+ this[kDefaultPrevented] = nextDefaultPrevented;
81
+ }
82
+ preventDefault() {
83
+ if (this.cancelable && !this[kDefaultPrevented]) this[kDefaultPrevented] = true;
84
+ }
86
85
  };
87
- kCancelable, kDefaultPrevented;
88
86
 
89
- // src/interceptors/WebSocket/WebSocketClientConnection.ts
90
- var kEmitter = Symbol("kEmitter");
91
- var kBoundListener = Symbol("kBoundListener");
92
- var WebSocketClientConnectionProtocol = class {
93
- };
87
+ //#endregion
88
+ //#region src/interceptors/WebSocket/WebSocketClientConnection.ts
89
+ const kEmitter$1 = Symbol("kEmitter");
90
+ const kBoundListener$1 = Symbol("kBoundListener");
91
+ var WebSocketClientConnectionProtocol = class {};
92
+ /**
93
+ * The WebSocket client instance represents an incoming
94
+ * client connection. The user can control the connection,
95
+ * send and receive events.
96
+ */
94
97
  var WebSocketClientConnection = class {
95
- constructor(socket, transport) {
96
- this.socket = socket;
97
- this.transport = transport;
98
- this.id = createRequestId();
99
- this.url = new URL(socket.url);
100
- this[kEmitter] = new EventTarget();
101
- this.transport.addEventListener("outgoing", (event) => {
102
- const message = bindEvent(
103
- this.socket,
104
- new CancelableMessageEvent("message", {
105
- data: event.data,
106
- origin: event.origin,
107
- cancelable: true
108
- })
109
- );
110
- this[kEmitter].dispatchEvent(message);
111
- if (message.defaultPrevented) {
112
- event.preventDefault();
113
- }
114
- });
115
- this.transport.addEventListener("close", (event) => {
116
- this[kEmitter].dispatchEvent(
117
- bindEvent(this.socket, new CloseEvent("close", event))
118
- );
119
- });
120
- }
121
- /**
122
- * Listen for the outgoing events from the connected WebSocket client.
123
- */
124
- addEventListener(type, listener, options) {
125
- if (!Reflect.has(listener, kBoundListener)) {
126
- const boundListener = listener.bind(this.socket);
127
- Object.defineProperty(listener, kBoundListener, {
128
- value: boundListener,
129
- enumerable: false,
130
- configurable: false
131
- });
132
- }
133
- this[kEmitter].addEventListener(
134
- type,
135
- Reflect.get(listener, kBoundListener),
136
- options
137
- );
138
- }
139
- /**
140
- * Removes the listener for the given event.
141
- */
142
- removeEventListener(event, listener, options) {
143
- this[kEmitter].removeEventListener(
144
- event,
145
- Reflect.get(listener, kBoundListener),
146
- options
147
- );
148
- }
149
- /**
150
- * Send data to the connected client.
151
- */
152
- send(data) {
153
- this.transport.send(data);
154
- }
155
- /**
156
- * Close the WebSocket connection.
157
- * @param {number} code A status code (see https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1).
158
- * @param {string} reason A custom connection close reason.
159
- */
160
- close(code, reason) {
161
- this.transport.close(code, reason);
162
- }
98
+ constructor(socket, transport) {
99
+ this.socket = socket;
100
+ this.transport = transport;
101
+ this.id = createRequestId();
102
+ this.url = new URL(socket.url);
103
+ this[kEmitter$1] = new EventTarget();
104
+ this.transport.addEventListener("outgoing", (event) => {
105
+ const message = bindEvent(this.socket, new CancelableMessageEvent("message", {
106
+ data: event.data,
107
+ origin: event.origin,
108
+ cancelable: true
109
+ }));
110
+ this[kEmitter$1].dispatchEvent(message);
111
+ if (message.defaultPrevented) event.preventDefault();
112
+ });
113
+ /**
114
+ * Emit the "close" event on the "client" connection
115
+ * whenever the underlying transport is closed.
116
+ * @note "client.close()" does NOT dispatch the "close"
117
+ * event on the WebSocket because it uses non-configurable
118
+ * close status code. Thus, we listen to the transport
119
+ * instead of the WebSocket's "close" event.
120
+ */
121
+ this.transport.addEventListener("close", (event) => {
122
+ this[kEmitter$1].dispatchEvent(bindEvent(this.socket, new CloseEvent("close", event)));
123
+ });
124
+ }
125
+ /**
126
+ * Listen for the outgoing events from the connected WebSocket client.
127
+ */
128
+ addEventListener(type, listener, options) {
129
+ if (!Reflect.has(listener, kBoundListener$1)) {
130
+ const boundListener = listener.bind(this.socket);
131
+ Object.defineProperty(listener, kBoundListener$1, {
132
+ value: boundListener,
133
+ enumerable: false,
134
+ configurable: false
135
+ });
136
+ }
137
+ this[kEmitter$1].addEventListener(type, Reflect.get(listener, kBoundListener$1), options);
138
+ }
139
+ /**
140
+ * Removes the listener for the given event.
141
+ */
142
+ removeEventListener(event, listener, options) {
143
+ this[kEmitter$1].removeEventListener(event, Reflect.get(listener, kBoundListener$1), options);
144
+ }
145
+ /**
146
+ * Send data to the connected client.
147
+ */
148
+ send(data) {
149
+ this.transport.send(data);
150
+ }
151
+ /**
152
+ * Close the WebSocket connection.
153
+ * @param {number} code A status code (see https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1).
154
+ * @param {string} reason A custom connection close reason.
155
+ */
156
+ close(code, reason) {
157
+ this.transport.close(code, reason);
158
+ }
163
159
  };
164
- kEmitter;
165
160
 
166
- // src/interceptors/WebSocket/WebSocketServerConnection.ts
167
- import { invariant as invariant2 } from "outvariant";
168
-
169
- // src/interceptors/WebSocket/WebSocketOverride.ts
170
- import { invariant } from "outvariant";
171
- import { DeferredPromise } from "@open-draft/deferred-promise";
172
- var WEBSOCKET_CLOSE_CODE_RANGE_ERROR = "InvalidAccessError: close code out of user configurable range";
173
- var kPassthroughPromise = Symbol("kPassthroughPromise");
174
- var kOnSend = Symbol("kOnSend");
175
- var kClose = Symbol("kClose");
161
+ //#endregion
162
+ //#region src/interceptors/WebSocket/WebSocketOverride.ts
163
+ const WEBSOCKET_CLOSE_CODE_RANGE_ERROR = "InvalidAccessError: close code out of user configurable range";
164
+ const kPassthroughPromise = Symbol("kPassthroughPromise");
165
+ const kOnSend = Symbol("kOnSend");
166
+ const kClose = Symbol("kClose");
176
167
  var WebSocketOverride = class extends EventTarget {
177
- constructor(url, protocols) {
178
- super();
179
- this.CONNECTING = 0;
180
- this.OPEN = 1;
181
- this.CLOSING = 2;
182
- this.CLOSED = 3;
183
- this._onopen = null;
184
- this._onmessage = null;
185
- this._onerror = null;
186
- this._onclose = null;
187
- this.url = url.toString();
188
- this.protocol = "";
189
- this.extensions = "";
190
- this.binaryType = "blob";
191
- this.readyState = this.CONNECTING;
192
- this.bufferedAmount = 0;
193
- this[kPassthroughPromise] = new DeferredPromise();
194
- queueMicrotask(async () => {
195
- if (await this[kPassthroughPromise]) {
196
- return;
197
- }
198
- this.protocol = typeof protocols === "string" ? protocols : Array.isArray(protocols) && protocols.length > 0 ? protocols[0] : "";
199
- if (this.readyState === this.CONNECTING) {
200
- this.readyState = this.OPEN;
201
- this.dispatchEvent(bindEvent(this, new Event("open")));
202
- }
203
- });
204
- }
205
- set onopen(listener) {
206
- this.removeEventListener("open", this._onopen);
207
- this._onopen = listener;
208
- if (listener !== null) {
209
- this.addEventListener("open", listener);
210
- }
211
- }
212
- get onopen() {
213
- return this._onopen;
214
- }
215
- set onmessage(listener) {
216
- this.removeEventListener(
217
- "message",
218
- this._onmessage
219
- );
220
- this._onmessage = listener;
221
- if (listener !== null) {
222
- this.addEventListener("message", listener);
223
- }
224
- }
225
- get onmessage() {
226
- return this._onmessage;
227
- }
228
- set onerror(listener) {
229
- this.removeEventListener("error", this._onerror);
230
- this._onerror = listener;
231
- if (listener !== null) {
232
- this.addEventListener("error", listener);
233
- }
234
- }
235
- get onerror() {
236
- return this._onerror;
237
- }
238
- set onclose(listener) {
239
- this.removeEventListener("close", this._onclose);
240
- this._onclose = listener;
241
- if (listener !== null) {
242
- this.addEventListener("close", listener);
243
- }
244
- }
245
- get onclose() {
246
- return this._onclose;
247
- }
248
- /**
249
- * @see https://websockets.spec.whatwg.org/#ref-for-dom-websocket-send%E2%91%A0
250
- */
251
- send(data) {
252
- if (this.readyState === this.CONNECTING) {
253
- this.close();
254
- throw new DOMException("InvalidStateError");
255
- }
256
- if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) {
257
- return;
258
- }
259
- this.bufferedAmount += getDataSize(data);
260
- queueMicrotask(() => {
261
- var _a;
262
- this.bufferedAmount = 0;
263
- (_a = this[kOnSend]) == null ? void 0 : _a.call(this, data);
264
- });
265
- }
266
- close(code = 1e3, reason) {
267
- invariant(code, WEBSOCKET_CLOSE_CODE_RANGE_ERROR);
268
- invariant(
269
- code === 1e3 || code >= 3e3 && code <= 4999,
270
- WEBSOCKET_CLOSE_CODE_RANGE_ERROR
271
- );
272
- this[kClose](code, reason);
273
- }
274
- [(kPassthroughPromise, kOnSend, kClose)](code = 1e3, reason, wasClean = true) {
275
- if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) {
276
- return;
277
- }
278
- this.readyState = this.CLOSING;
279
- queueMicrotask(() => {
280
- this.readyState = this.CLOSED;
281
- this.dispatchEvent(
282
- bindEvent(
283
- this,
284
- new CloseEvent("close", {
285
- code,
286
- reason,
287
- wasClean
288
- })
289
- )
290
- );
291
- this._onopen = null;
292
- this._onmessage = null;
293
- this._onerror = null;
294
- this._onclose = null;
295
- });
296
- }
297
- addEventListener(type, listener, options) {
298
- return super.addEventListener(
299
- type,
300
- listener,
301
- options
302
- );
303
- }
304
- removeEventListener(type, callback, options) {
305
- return super.removeEventListener(type, callback, options);
306
- }
168
+ static {
169
+ this.CONNECTING = 0;
170
+ }
171
+ static {
172
+ this.OPEN = 1;
173
+ }
174
+ static {
175
+ this.CLOSING = 2;
176
+ }
177
+ static {
178
+ this.CLOSED = 3;
179
+ }
180
+ constructor(url, protocols) {
181
+ super();
182
+ this.CONNECTING = 0;
183
+ this.OPEN = 1;
184
+ this.CLOSING = 2;
185
+ this.CLOSED = 3;
186
+ this._onopen = null;
187
+ this._onmessage = null;
188
+ this._onerror = null;
189
+ this._onclose = null;
190
+ this.url = resolveWebSocketUrl(url);
191
+ this.protocol = "";
192
+ this.extensions = "";
193
+ this.binaryType = "blob";
194
+ this.readyState = this.CONNECTING;
195
+ this.bufferedAmount = 0;
196
+ this[kPassthroughPromise] = new DeferredPromise();
197
+ queueMicrotask(async () => {
198
+ if (await this[kPassthroughPromise]) return;
199
+ this.protocol = typeof protocols === "string" ? protocols : Array.isArray(protocols) && protocols.length > 0 ? protocols[0] : "";
200
+ /**
201
+ * @note Check that nothing has prevented this connection
202
+ * (e.g. called `client.close()` in the connection listener).
203
+ * If the connection has been prevented, never dispatch the open event,.
204
+ */
205
+ if (this.readyState === this.CONNECTING) {
206
+ this.readyState = this.OPEN;
207
+ this.dispatchEvent(bindEvent(this, new Event("open")));
208
+ }
209
+ });
210
+ }
211
+ set onopen(listener) {
212
+ this.removeEventListener("open", this._onopen);
213
+ this._onopen = listener;
214
+ if (listener !== null) this.addEventListener("open", listener);
215
+ }
216
+ get onopen() {
217
+ return this._onopen;
218
+ }
219
+ set onmessage(listener) {
220
+ this.removeEventListener("message", this._onmessage);
221
+ this._onmessage = listener;
222
+ if (listener !== null) this.addEventListener("message", listener);
223
+ }
224
+ get onmessage() {
225
+ return this._onmessage;
226
+ }
227
+ set onerror(listener) {
228
+ this.removeEventListener("error", this._onerror);
229
+ this._onerror = listener;
230
+ if (listener !== null) this.addEventListener("error", listener);
231
+ }
232
+ get onerror() {
233
+ return this._onerror;
234
+ }
235
+ set onclose(listener) {
236
+ this.removeEventListener("close", this._onclose);
237
+ this._onclose = listener;
238
+ if (listener !== null) this.addEventListener("close", listener);
239
+ }
240
+ get onclose() {
241
+ return this._onclose;
242
+ }
243
+ /**
244
+ * @see https://websockets.spec.whatwg.org/#ref-for-dom-websocket-send%E2%91%A0
245
+ */
246
+ send(data) {
247
+ if (this.readyState === this.CONNECTING) {
248
+ this.close();
249
+ throw new DOMException("InvalidStateError");
250
+ }
251
+ if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) return;
252
+ this.bufferedAmount += getDataSize(data);
253
+ queueMicrotask(() => {
254
+ this.bufferedAmount = 0;
255
+ /**
256
+ * @note Notify the parent about outgoing data.
257
+ * This notifies the transport and the connection
258
+ * listens to the outgoing data to emit the "message" event.
259
+ */
260
+ this[kOnSend]?.(data);
261
+ });
262
+ }
263
+ close(code = 1e3, reason) {
264
+ invariant(code, WEBSOCKET_CLOSE_CODE_RANGE_ERROR);
265
+ invariant(code === 1e3 || code >= 3e3 && code <= 4999, WEBSOCKET_CLOSE_CODE_RANGE_ERROR);
266
+ this[kClose](code, reason);
267
+ }
268
+ [kClose](code = 1e3, reason, wasClean = true) {
269
+ /**
270
+ * @note Move this check here so that even internal closures,
271
+ * like those triggered by the `server` connection, are not
272
+ * performed twice.
273
+ */
274
+ if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) return;
275
+ this.readyState = this.CLOSING;
276
+ queueMicrotask(() => {
277
+ this.readyState = this.CLOSED;
278
+ this.dispatchEvent(bindEvent(this, new CloseEvent("close", {
279
+ code,
280
+ reason,
281
+ wasClean
282
+ })));
283
+ this._onopen = null;
284
+ this._onmessage = null;
285
+ this._onerror = null;
286
+ this._onclose = null;
287
+ });
288
+ }
289
+ addEventListener(type, listener, options) {
290
+ return super.addEventListener(type, listener, options);
291
+ }
292
+ removeEventListener(type, callback, options) {
293
+ return super.removeEventListener(type, callback, options);
294
+ }
307
295
  };
308
- WebSocketOverride.CONNECTING = 0;
309
- WebSocketOverride.OPEN = 1;
310
- WebSocketOverride.CLOSING = 2;
311
- WebSocketOverride.CLOSED = 3;
312
296
  function getDataSize(data) {
313
- if (typeof data === "string") {
314
- return data.length;
315
- }
316
- if (data instanceof Blob) {
317
- return data.size;
318
- }
319
- return data.byteLength;
297
+ if (typeof data === "string") return data.length;
298
+ if (data instanceof Blob) return data.size;
299
+ return data.byteLength;
300
+ }
301
+ /**
302
+ * Resolve potentially relative WebSocket URLs the same way
303
+ * the browser does (replace the protocol, use the origin, etc).
304
+ *
305
+ * @see https://websockets.spec.whatwg.org//#dom-websocket-websocket
306
+ */
307
+ function resolveWebSocketUrl(url) {
308
+ if (typeof url === "string") return resolveWebSocketUrl(new URL(url, typeof location !== "undefined" ? location.href : void 0));
309
+ if (url.protocol === "http:") url.protocol = "ws:";
310
+ else if (url.protocol === "https:") url.protocol = "wss:";
311
+ if (url.protocol !== "ws:" && url.protocol !== "wss:")
312
+ /**
313
+ * @note These errors are modeled after the browser errors.
314
+ * The exact error messages aren't provided in the specification.
315
+ * Node.js uses more obscure error messages that I don't wish to replicate.
316
+ */
317
+ throw new SyntaxError(`Failed to construct 'WebSocket': The URL's scheme must be either 'http', 'https', 'ws', or 'wss'. '${url.protocol}' is not allowed.`);
318
+ if (url.hash !== "") throw new SyntaxError(`Failed to construct 'WebSocket': The URL contains a fragment identifier ('${url.hash}'). Fragment identifiers are not allowed in WebSocket URLs.`);
319
+ return url.href;
320
320
  }
321
321
 
322
- // src/interceptors/WebSocket/WebSocketServerConnection.ts
323
- var kEmitter2 = Symbol("kEmitter");
324
- var kBoundListener2 = Symbol("kBoundListener");
325
- var kSend = Symbol("kSend");
326
- var WebSocketServerConnectionProtocol = class {
327
- };
322
+ //#endregion
323
+ //#region src/interceptors/WebSocket/WebSocketServerConnection.ts
324
+ const kEmitter = Symbol("kEmitter");
325
+ const kBoundListener = Symbol("kBoundListener");
326
+ const kSend = Symbol("kSend");
327
+ var WebSocketServerConnectionProtocol = class {};
328
+ /**
329
+ * The WebSocket server instance represents the actual production
330
+ * WebSocket server connection. It's idle by default but you can
331
+ * establish it by calling `server.connect()`.
332
+ */
328
333
  var WebSocketServerConnection = class {
329
- constructor(client, transport, createConnection) {
330
- this.client = client;
331
- this.transport = transport;
332
- this.createConnection = createConnection;
333
- this[kEmitter2] = new EventTarget();
334
- this.mockCloseController = new AbortController();
335
- this.realCloseController = new AbortController();
336
- this.transport.addEventListener("outgoing", (event) => {
337
- if (typeof this.realWebSocket === "undefined") {
338
- return;
339
- }
340
- queueMicrotask(() => {
341
- if (!event.defaultPrevented) {
342
- this[kSend](event.data);
343
- }
344
- });
345
- });
346
- this.transport.addEventListener(
347
- "incoming",
348
- this.handleIncomingMessage.bind(this)
349
- );
350
- }
351
- /**
352
- * The `WebSocket` instance connected to the original server.
353
- * Accessing this before calling `server.connect()` will throw.
354
- */
355
- get socket() {
356
- invariant2(
357
- this.realWebSocket,
358
- 'Cannot access "socket" on the original WebSocket server object: the connection is not open. Did you forget to call `server.connect()`?'
359
- );
360
- return this.realWebSocket;
361
- }
362
- /**
363
- * Open connection to the original WebSocket server.
364
- */
365
- connect() {
366
- invariant2(
367
- !this.realWebSocket || this.realWebSocket.readyState !== WebSocket.OPEN,
368
- 'Failed to call "connect()" on the original WebSocket instance: the connection already open'
369
- );
370
- const realWebSocket = this.createConnection();
371
- realWebSocket.binaryType = this.client.binaryType;
372
- realWebSocket.addEventListener(
373
- "open",
374
- (event) => {
375
- this[kEmitter2].dispatchEvent(
376
- bindEvent(this.realWebSocket, new Event("open", event))
377
- );
378
- },
379
- { once: true }
380
- );
381
- realWebSocket.addEventListener("message", (event) => {
382
- this.transport.dispatchEvent(
383
- bindEvent(
384
- this.realWebSocket,
385
- new MessageEvent("incoming", {
386
- data: event.data,
387
- origin: event.origin
388
- })
389
- )
390
- );
391
- });
392
- this.client.addEventListener(
393
- "close",
394
- (event) => {
395
- this.handleMockClose(event);
396
- },
397
- {
398
- signal: this.mockCloseController.signal
399
- }
400
- );
401
- realWebSocket.addEventListener(
402
- "close",
403
- (event) => {
404
- this.handleRealClose(event);
405
- },
406
- {
407
- signal: this.realCloseController.signal
408
- }
409
- );
410
- realWebSocket.addEventListener("error", () => {
411
- const errorEvent = bindEvent(
412
- realWebSocket,
413
- new Event("error", { cancelable: true })
414
- );
415
- this[kEmitter2].dispatchEvent(errorEvent);
416
- if (!errorEvent.defaultPrevented) {
417
- this.client.dispatchEvent(bindEvent(this.client, new Event("error")));
418
- }
419
- });
420
- this.realWebSocket = realWebSocket;
421
- }
422
- /**
423
- * Listen for the incoming events from the original WebSocket server.
424
- */
425
- addEventListener(event, listener, options) {
426
- if (!Reflect.has(listener, kBoundListener2)) {
427
- const boundListener = listener.bind(this.client);
428
- Object.defineProperty(listener, kBoundListener2, {
429
- value: boundListener,
430
- enumerable: false
431
- });
432
- }
433
- this[kEmitter2].addEventListener(
434
- event,
435
- Reflect.get(listener, kBoundListener2),
436
- options
437
- );
438
- }
439
- /**
440
- * Remove the listener for the given event.
441
- */
442
- removeEventListener(event, listener, options) {
443
- this[kEmitter2].removeEventListener(
444
- event,
445
- Reflect.get(listener, kBoundListener2),
446
- options
447
- );
448
- }
449
- /**
450
- * Send data to the original WebSocket server.
451
- * @example
452
- * server.send('hello')
453
- * server.send(new Blob(['hello']))
454
- * server.send(new TextEncoder().encode('hello'))
455
- */
456
- send(data) {
457
- this[kSend](data);
458
- }
459
- [(kEmitter2, kSend)](data) {
460
- const { realWebSocket } = this;
461
- invariant2(
462
- realWebSocket,
463
- 'Failed to call "server.send()" for "%s": the connection is not open. Did you forget to call "server.connect()"?',
464
- this.client.url
465
- );
466
- if (realWebSocket.readyState === WebSocket.CLOSING || realWebSocket.readyState === WebSocket.CLOSED) {
467
- return;
468
- }
469
- if (realWebSocket.readyState === WebSocket.CONNECTING) {
470
- realWebSocket.addEventListener(
471
- "open",
472
- () => {
473
- realWebSocket.send(data);
474
- },
475
- { once: true }
476
- );
477
- return;
478
- }
479
- realWebSocket.send(data);
480
- }
481
- /**
482
- * Close the actual server connection.
483
- */
484
- close() {
485
- const { realWebSocket } = this;
486
- invariant2(
487
- realWebSocket,
488
- 'Failed to close server connection for "%s": the connection is not open. Did you forget to call "server.connect()"?',
489
- this.client.url
490
- );
491
- this.realCloseController.abort();
492
- if (realWebSocket.readyState === WebSocket.CLOSING || realWebSocket.readyState === WebSocket.CLOSED) {
493
- return;
494
- }
495
- realWebSocket.close();
496
- queueMicrotask(() => {
497
- this[kEmitter2].dispatchEvent(
498
- bindEvent(
499
- this.realWebSocket,
500
- new CancelableCloseEvent("close", {
501
- /**
502
- * @note `server.close()` in the interceptor
503
- * always results in clean closures.
504
- */
505
- code: 1e3,
506
- cancelable: true
507
- })
508
- )
509
- );
510
- });
511
- }
512
- handleIncomingMessage(event) {
513
- const messageEvent = bindEvent(
514
- event.target,
515
- new CancelableMessageEvent("message", {
516
- data: event.data,
517
- origin: event.origin,
518
- cancelable: true
519
- })
520
- );
521
- this[kEmitter2].dispatchEvent(messageEvent);
522
- if (!messageEvent.defaultPrevented) {
523
- this.client.dispatchEvent(
524
- bindEvent(
525
- /**
526
- * @note Bind the forwarded original server events
527
- * to the mock WebSocket instance so it would
528
- * dispatch them straight away.
529
- */
530
- this.client,
531
- // Clone the message event again to prevent
532
- // the "already being dispatched" exception.
533
- new MessageEvent("message", {
534
- data: event.data,
535
- origin: event.origin
536
- })
537
- )
538
- );
539
- }
540
- }
541
- handleMockClose(_event) {
542
- if (this.realWebSocket) {
543
- this.realWebSocket.close();
544
- }
545
- }
546
- handleRealClose(event) {
547
- this.mockCloseController.abort();
548
- const closeEvent = bindEvent(
549
- this.realWebSocket,
550
- new CancelableCloseEvent("close", {
551
- code: event.code,
552
- reason: event.reason,
553
- wasClean: event.wasClean,
554
- cancelable: true
555
- })
556
- );
557
- this[kEmitter2].dispatchEvent(closeEvent);
558
- if (!closeEvent.defaultPrevented) {
559
- this.client[kClose](event.code, event.reason);
560
- }
561
- }
334
+ constructor(client, transport, createConnection) {
335
+ this.client = client;
336
+ this.transport = transport;
337
+ this.createConnection = createConnection;
338
+ this[kEmitter] = new EventTarget();
339
+ this.mockCloseController = new AbortController();
340
+ this.realCloseController = new AbortController();
341
+ this.transport.addEventListener("outgoing", (event) => {
342
+ if (typeof this.realWebSocket === "undefined") return;
343
+ queueMicrotask(() => {
344
+ if (!event.defaultPrevented)
345
+ /**
346
+ * @note Use the internal send mechanism so consumers can tell
347
+ * apart direct user calls to `server.send()` and internal calls.
348
+ * E.g. MSW has to ignore this internal call to log out messages correctly.
349
+ */
350
+ this[kSend](event.data);
351
+ });
352
+ });
353
+ this.transport.addEventListener("incoming", this.handleIncomingMessage.bind(this));
354
+ }
355
+ /**
356
+ * The `WebSocket` instance connected to the original server.
357
+ * Accessing this before calling `server.connect()` will throw.
358
+ */
359
+ get socket() {
360
+ invariant(this.realWebSocket, "Cannot access \"socket\" on the original WebSocket server object: the connection is not open. Did you forget to call `server.connect()`?");
361
+ return this.realWebSocket;
362
+ }
363
+ /**
364
+ * Open connection to the original WebSocket server.
365
+ */
366
+ connect() {
367
+ invariant(!this.realWebSocket || this.realWebSocket.readyState !== WebSocket.OPEN, "Failed to call \"connect()\" on the original WebSocket instance: the connection already open");
368
+ const realWebSocket = this.createConnection();
369
+ realWebSocket.binaryType = this.client.binaryType;
370
+ realWebSocket.addEventListener("open", (event) => {
371
+ this[kEmitter].dispatchEvent(bindEvent(this.realWebSocket, new Event("open", event)));
372
+ }, { once: true });
373
+ realWebSocket.addEventListener("message", (event) => {
374
+ this.transport.dispatchEvent(bindEvent(this.realWebSocket, new MessageEvent("incoming", {
375
+ data: event.data,
376
+ origin: event.origin
377
+ })));
378
+ });
379
+ this.client.addEventListener("close", (event) => {
380
+ this.handleMockClose(event);
381
+ }, { signal: this.mockCloseController.signal });
382
+ realWebSocket.addEventListener("close", (event) => {
383
+ this.handleRealClose(event);
384
+ }, { signal: this.realCloseController.signal });
385
+ realWebSocket.addEventListener("error", () => {
386
+ const errorEvent = bindEvent(realWebSocket, new Event("error", { cancelable: true }));
387
+ this[kEmitter].dispatchEvent(errorEvent);
388
+ if (!errorEvent.defaultPrevented) this.client.dispatchEvent(bindEvent(this.client, new Event("error")));
389
+ });
390
+ this.realWebSocket = realWebSocket;
391
+ }
392
+ /**
393
+ * Listen for the incoming events from the original WebSocket server.
394
+ */
395
+ addEventListener(event, listener, options) {
396
+ if (!Reflect.has(listener, kBoundListener)) {
397
+ const boundListener = listener.bind(this.client);
398
+ Object.defineProperty(listener, kBoundListener, {
399
+ value: boundListener,
400
+ enumerable: false
401
+ });
402
+ }
403
+ this[kEmitter].addEventListener(event, Reflect.get(listener, kBoundListener), options);
404
+ }
405
+ /**
406
+ * Remove the listener for the given event.
407
+ */
408
+ removeEventListener(event, listener, options) {
409
+ this[kEmitter].removeEventListener(event, Reflect.get(listener, kBoundListener), options);
410
+ }
411
+ /**
412
+ * Send data to the original WebSocket server.
413
+ * @example
414
+ * server.send('hello')
415
+ * server.send(new Blob(['hello']))
416
+ * server.send(new TextEncoder().encode('hello'))
417
+ */
418
+ send(data) {
419
+ this[kSend](data);
420
+ }
421
+ [kSend](data) {
422
+ const { realWebSocket } = this;
423
+ invariant(realWebSocket, "Failed to call \"server.send()\" for \"%s\": the connection is not open. Did you forget to call \"server.connect()\"?", this.client.url);
424
+ if (realWebSocket.readyState === WebSocket.CLOSING || realWebSocket.readyState === WebSocket.CLOSED) return;
425
+ if (realWebSocket.readyState === WebSocket.CONNECTING) {
426
+ realWebSocket.addEventListener("open", () => {
427
+ realWebSocket.send(data);
428
+ }, { once: true });
429
+ return;
430
+ }
431
+ realWebSocket.send(data);
432
+ }
433
+ /**
434
+ * Close the actual server connection.
435
+ */
436
+ close() {
437
+ const { realWebSocket } = this;
438
+ invariant(realWebSocket, "Failed to close server connection for \"%s\": the connection is not open. Did you forget to call \"server.connect()\"?", this.client.url);
439
+ this.realCloseController.abort();
440
+ if (realWebSocket.readyState === WebSocket.CLOSING || realWebSocket.readyState === WebSocket.CLOSED) return;
441
+ realWebSocket.close();
442
+ queueMicrotask(() => {
443
+ this[kEmitter].dispatchEvent(bindEvent(this.realWebSocket, new CancelableCloseEvent("close", {
444
+ code: 1e3,
445
+ cancelable: true
446
+ })));
447
+ });
448
+ }
449
+ handleIncomingMessage(event) {
450
+ const messageEvent = bindEvent(event.target, new CancelableMessageEvent("message", {
451
+ data: event.data,
452
+ origin: event.origin,
453
+ cancelable: true
454
+ }));
455
+ /**
456
+ * @note Emit "message" event on the server connection
457
+ * instance to let the interceptor know about these
458
+ * incoming events from the original server. In that listener,
459
+ * the interceptor can modify or skip the event forwarding
460
+ * to the mock WebSocket instance.
461
+ */
462
+ this[kEmitter].dispatchEvent(messageEvent);
463
+ /**
464
+ * @note Forward the incoming server events to the client.
465
+ * Preventing the default on the message event stops this.
466
+ */
467
+ if (!messageEvent.defaultPrevented) this.client.dispatchEvent(bindEvent(
468
+ /**
469
+ * @note Bind the forwarded original server events
470
+ * to the mock WebSocket instance so it would
471
+ * dispatch them straight away.
472
+ */
473
+ this.client,
474
+ new MessageEvent("message", {
475
+ data: event.data,
476
+ origin: event.origin
477
+ })
478
+ ));
479
+ }
480
+ handleMockClose(_event) {
481
+ if (this.realWebSocket) this.realWebSocket.close();
482
+ }
483
+ handleRealClose(event) {
484
+ this.mockCloseController.abort();
485
+ const closeEvent = bindEvent(this.realWebSocket, new CancelableCloseEvent("close", {
486
+ code: event.code,
487
+ reason: event.reason,
488
+ wasClean: event.wasClean,
489
+ cancelable: true
490
+ }));
491
+ this[kEmitter].dispatchEvent(closeEvent);
492
+ if (!closeEvent.defaultPrevented) this.client[kClose](event.code, event.reason);
493
+ }
562
494
  };
563
495
 
564
- // src/interceptors/WebSocket/WebSocketClassTransport.ts
496
+ //#endregion
497
+ //#region src/interceptors/WebSocket/WebSocketClassTransport.ts
498
+ /**
499
+ * Abstraction over the given mock `WebSocket` instance that allows
500
+ * for controlling that instance (e.g. sending and receiving messages).
501
+ */
565
502
  var WebSocketClassTransport = class extends EventTarget {
566
- constructor(socket) {
567
- super();
568
- this.socket = socket;
569
- this.socket.addEventListener("close", (event) => {
570
- this.dispatchEvent(bindEvent(this.socket, new CloseEvent("close", event)));
571
- });
572
- this.socket[kOnSend] = (data) => {
573
- this.dispatchEvent(
574
- bindEvent(
575
- this.socket,
576
- // Dispatch this as cancelable because "client" connection
577
- // re-creates this message event (cannot dispatch the same event).
578
- new CancelableMessageEvent("outgoing", {
579
- data,
580
- origin: this.socket.url,
581
- cancelable: true
582
- })
583
- )
584
- );
585
- };
586
- }
587
- addEventListener(type, callback, options) {
588
- return super.addEventListener(type, callback, options);
589
- }
590
- dispatchEvent(event) {
591
- return super.dispatchEvent(event);
592
- }
593
- send(data) {
594
- queueMicrotask(() => {
595
- if (this.socket.readyState === this.socket.CLOSING || this.socket.readyState === this.socket.CLOSED) {
596
- return;
597
- }
598
- const dispatchEvent = () => {
599
- this.socket.dispatchEvent(
600
- bindEvent(
601
- /**
602
- * @note Setting this event's "target" to the
603
- * WebSocket override instance is important.
604
- * This way it can tell apart original incoming events
605
- * (must be forwarded to the transport) from the
606
- * mocked message events like the one below
607
- * (must be dispatched on the client instance).
608
- */
609
- this.socket,
610
- new MessageEvent("message", {
611
- data,
612
- origin: this.socket.url
613
- })
614
- )
615
- );
616
- };
617
- if (this.socket.readyState === this.socket.CONNECTING) {
618
- this.socket.addEventListener(
619
- "open",
620
- () => {
621
- dispatchEvent();
622
- },
623
- { once: true }
624
- );
625
- } else {
626
- dispatchEvent();
627
- }
628
- });
629
- }
630
- close(code, reason) {
631
- this.socket[kClose](code, reason);
632
- }
503
+ constructor(socket) {
504
+ super();
505
+ this.socket = socket;
506
+ this.socket.addEventListener("close", (event) => {
507
+ this.dispatchEvent(bindEvent(this.socket, new CloseEvent("close", event)));
508
+ });
509
+ /**
510
+ * Emit the "outgoing" event on the transport
511
+ * whenever the WebSocket client sends data ("ws.send()").
512
+ */
513
+ this.socket[kOnSend] = (data) => {
514
+ this.dispatchEvent(bindEvent(this.socket, new CancelableMessageEvent("outgoing", {
515
+ data,
516
+ origin: this.socket.url,
517
+ cancelable: true
518
+ })));
519
+ };
520
+ }
521
+ addEventListener(type, callback, options) {
522
+ return super.addEventListener(type, callback, options);
523
+ }
524
+ dispatchEvent(event) {
525
+ return super.dispatchEvent(event);
526
+ }
527
+ send(data) {
528
+ queueMicrotask(() => {
529
+ if (this.socket.readyState === this.socket.CLOSING || this.socket.readyState === this.socket.CLOSED) return;
530
+ const dispatchEvent = () => {
531
+ this.socket.dispatchEvent(bindEvent(
532
+ /**
533
+ * @note Setting this event's "target" to the
534
+ * WebSocket override instance is important.
535
+ * This way it can tell apart original incoming events
536
+ * (must be forwarded to the transport) from the
537
+ * mocked message events like the one below
538
+ * (must be dispatched on the client instance).
539
+ */
540
+ this.socket,
541
+ new MessageEvent("message", {
542
+ data,
543
+ origin: this.socket.url
544
+ })
545
+ ));
546
+ };
547
+ if (this.socket.readyState === this.socket.CONNECTING) this.socket.addEventListener("open", () => {
548
+ dispatchEvent();
549
+ }, { once: true });
550
+ else dispatchEvent();
551
+ });
552
+ }
553
+ close(code, reason) {
554
+ /**
555
+ * @note Call the internal close method directly
556
+ * to allow closing the connection with the status codes
557
+ * that are non-configurable by the user (> 1000 <= 1015).
558
+ */
559
+ this.socket[kClose](code, reason);
560
+ }
633
561
  };
634
562
 
635
- // src/interceptors/WebSocket/index.ts
636
- var _WebSocketInterceptor = class extends Interceptor {
637
- constructor() {
638
- super(_WebSocketInterceptor.symbol);
639
- }
640
- checkEnvironment() {
641
- return hasConfigurableGlobal("WebSocket");
642
- }
643
- setup() {
644
- const originalWebSocketDescriptor = Object.getOwnPropertyDescriptor(
645
- globalThis,
646
- "WebSocket"
647
- );
648
- const WebSocketProxy = new Proxy(globalThis.WebSocket, {
649
- construct: (target, args, newTarget) => {
650
- const [url, protocols] = args;
651
- const createConnection = () => {
652
- return Reflect.construct(target, args, newTarget);
653
- };
654
- const socket = new WebSocketOverride(url, protocols);
655
- const transport = new WebSocketClassTransport(socket);
656
- queueMicrotask(async () => {
657
- try {
658
- const server = new WebSocketServerConnection(
659
- socket,
660
- transport,
661
- createConnection
662
- );
663
- const hasConnectionListeners = this.emitter.listenerCount("connection") > 0;
664
- await emitAsync(this.emitter, "connection", {
665
- client: new WebSocketClientConnection(socket, transport),
666
- server,
667
- info: {
668
- protocols
669
- }
670
- });
671
- if (hasConnectionListeners) {
672
- socket[kPassthroughPromise].resolve(false);
673
- } else {
674
- socket[kPassthroughPromise].resolve(true);
675
- server.connect();
676
- server.addEventListener("open", () => {
677
- socket.dispatchEvent(bindEvent(socket, new Event("open")));
678
- if (server["realWebSocket"]) {
679
- socket.protocol = server["realWebSocket"].protocol;
680
- }
681
- });
682
- }
683
- } catch (error) {
684
- if (error instanceof Error) {
685
- socket.dispatchEvent(new Event("error"));
686
- if (socket.readyState !== WebSocket.CLOSING && socket.readyState !== WebSocket.CLOSED) {
687
- socket[kClose](1011, error.message, false);
688
- }
689
- console.error(error);
690
- }
691
- }
692
- });
693
- return socket;
694
- }
695
- });
696
- Object.defineProperty(globalThis, "WebSocket", {
697
- value: WebSocketProxy,
698
- configurable: true
699
- });
700
- this.subscriptions.push(() => {
701
- Object.defineProperty(
702
- globalThis,
703
- "WebSocket",
704
- originalWebSocketDescriptor
705
- );
706
- });
707
- }
708
- };
709
- var WebSocketInterceptor = _WebSocketInterceptor;
710
- WebSocketInterceptor.symbol = Symbol("websocket");
711
- export {
712
- CancelableCloseEvent,
713
- CancelableMessageEvent,
714
- CloseEvent,
715
- WebSocketClientConnection,
716
- WebSocketClientConnectionProtocol,
717
- WebSocketInterceptor,
718
- WebSocketServerConnection,
719
- WebSocketServerConnectionProtocol
563
+ //#endregion
564
+ //#region src/interceptors/WebSocket/index.ts
565
+ /**
566
+ * Intercept the outgoing WebSocket connections created using
567
+ * the global `WebSocket` class.
568
+ */
569
+ var WebSocketInterceptor = class WebSocketInterceptor extends Interceptor {
570
+ static {
571
+ this.symbol = Symbol("websocket");
572
+ }
573
+ constructor() {
574
+ super(WebSocketInterceptor.symbol);
575
+ }
576
+ checkEnvironment() {
577
+ return hasConfigurableGlobal("WebSocket");
578
+ }
579
+ setup() {
580
+ const originalWebSocketDescriptor = Object.getOwnPropertyDescriptor(globalThis, "WebSocket");
581
+ const WebSocketProxy = new Proxy(globalThis.WebSocket, { construct: (target, args, newTarget) => {
582
+ const [url, protocols] = args;
583
+ const createConnection = () => {
584
+ return Reflect.construct(target, args, newTarget);
585
+ };
586
+ const socket = new WebSocketOverride(url, protocols);
587
+ const transport = new WebSocketClassTransport(socket);
588
+ queueMicrotask(async () => {
589
+ try {
590
+ const server = new WebSocketServerConnection(socket, transport, createConnection);
591
+ const hasConnectionListeners = this.emitter.listenerCount("connection") > 0;
592
+ await emitAsync(this.emitter, "connection", {
593
+ client: new WebSocketClientConnection(socket, transport),
594
+ server,
595
+ info: { protocols }
596
+ });
597
+ if (hasConnectionListeners) socket[kPassthroughPromise].resolve(false);
598
+ else {
599
+ socket[kPassthroughPromise].resolve(true);
600
+ server.connect();
601
+ server.addEventListener("open", () => {
602
+ socket.dispatchEvent(bindEvent(socket, new Event("open")));
603
+ if (server["realWebSocket"]) socket.protocol = server["realWebSocket"].protocol;
604
+ });
605
+ }
606
+ } catch (error) {
607
+ /**
608
+ * @note Translate unhandled exceptions during the connection
609
+ * handling (i.e. interceptor exceptions) as WebSocket connection
610
+ * closures with error. This prevents from the exceptions occurring
611
+ * in `queueMicrotask` from being process-wide and uncatchable.
612
+ */
613
+ if (error instanceof Error) {
614
+ socket.dispatchEvent(new Event("error"));
615
+ if (socket.readyState !== WebSocket.CLOSING && socket.readyState !== WebSocket.CLOSED) socket[kClose](1011, error.message, false);
616
+ console.error(error);
617
+ }
618
+ }
619
+ });
620
+ return socket;
621
+ } });
622
+ Object.defineProperty(globalThis, "WebSocket", {
623
+ value: WebSocketProxy,
624
+ configurable: true
625
+ });
626
+ this.subscriptions.push(() => {
627
+ Object.defineProperty(globalThis, "WebSocket", originalWebSocketDescriptor);
628
+ });
629
+ }
720
630
  };
631
+
632
+ //#endregion
633
+ export { CancelableCloseEvent, CancelableMessageEvent, CloseEvent, WebSocketClientConnection, WebSocketClientConnectionProtocol, WebSocketInterceptor, WebSocketServerConnection, WebSocketServerConnectionProtocol };
721
634
  //# sourceMappingURL=index.mjs.map