@mswjs/interceptors 0.39.8 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) 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 -75
  43. package/lib/browser/index.mjs.map +1 -1
  44. package/lib/browser/interceptors/WebSocket/index.cjs +621 -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 +587 -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 -186
  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 -39
  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 +34 -59
  150. package/presets/browser/package.json +2 -3
  151. package/presets/node/package.json +7 -2
  152. package/src/RemoteHttpInterceptor.ts +18 -13
  153. package/src/RequestController.test.ts +78 -31
  154. package/src/RequestController.ts +63 -39
  155. package/src/index.ts +4 -0
  156. package/src/interceptors/ClientRequest/MockHttpSocket.ts +43 -9
  157. package/src/interceptors/ClientRequest/index.ts +14 -18
  158. package/src/interceptors/ClientRequest/utils/parserUtils.ts +48 -0
  159. package/src/interceptors/WebSocket/index.ts +4 -1
  160. package/src/interceptors/XMLHttpRequest/XMLHttpRequestController.ts +45 -35
  161. package/src/interceptors/XMLHttpRequest/XMLHttpRequestProxy.ts +24 -21
  162. package/src/interceptors/XMLHttpRequest/utils/getBodyByteLength.test.ts +2 -2
  163. package/src/interceptors/fetch/index.ts +61 -50
  164. package/src/utils/handleRequest.ts +65 -95
  165. package/lib/browser/Interceptor-af98b768.d.ts +0 -63
  166. package/lib/browser/chunk-2HUMWGRD.js +0 -37
  167. package/lib/browser/chunk-2HUMWGRD.js.map +0 -1
  168. package/lib/browser/chunk-2QICSCCS.js +0 -238
  169. package/lib/browser/chunk-2QICSCCS.js.map +0 -1
  170. package/lib/browser/chunk-3RXCRGL2.mjs +0 -117
  171. package/lib/browser/chunk-3RXCRGL2.mjs.map +0 -1
  172. package/lib/browser/chunk-6HYIRFX2.mjs +0 -22
  173. package/lib/browser/chunk-6HYIRFX2.mjs.map +0 -1
  174. package/lib/browser/chunk-E3CCOBRX.js +0 -846
  175. package/lib/browser/chunk-E3CCOBRX.js.map +0 -1
  176. package/lib/browser/chunk-E7UVBHVO.mjs +0 -846
  177. package/lib/browser/chunk-E7UVBHVO.mjs.map +0 -1
  178. package/lib/browser/chunk-H74PGQ4Y.js +0 -296
  179. package/lib/browser/chunk-H74PGQ4Y.js.map +0 -1
  180. package/lib/browser/chunk-LK6DILFK.js +0 -22
  181. package/lib/browser/chunk-LK6DILFK.js.map +0 -1
  182. package/lib/browser/chunk-PTTUYYVR.mjs +0 -238
  183. package/lib/browser/chunk-PTTUYYVR.mjs.map +0 -1
  184. package/lib/browser/chunk-Q7K2XAEP.mjs +0 -296
  185. package/lib/browser/chunk-Q7K2XAEP.mjs.map +0 -1
  186. package/lib/browser/chunk-QED3Q6Z2.mjs +0 -169
  187. package/lib/browser/chunk-QED3Q6Z2.mjs.map +0 -1
  188. package/lib/browser/chunk-T7TBRNJZ.js +0 -117
  189. package/lib/browser/chunk-T7TBRNJZ.js.map +0 -1
  190. package/lib/browser/chunk-TIPR373R.js +0 -169
  191. package/lib/browser/chunk-TIPR373R.js.map +0 -1
  192. package/lib/browser/chunk-VYSDLBSS.mjs +0 -37
  193. package/lib/browser/chunk-VYSDLBSS.mjs.map +0 -1
  194. package/lib/browser/glossary-7152281e.d.ts +0 -69
  195. package/lib/browser/index.d.ts +0 -83
  196. package/lib/browser/index.js +0 -81
  197. package/lib/browser/index.js.map +0 -1
  198. package/lib/browser/interceptors/WebSocket/index.d.ts +0 -271
  199. package/lib/browser/interceptors/WebSocket/index.js +0 -721
  200. package/lib/browser/interceptors/WebSocket/index.js.map +0 -1
  201. package/lib/browser/interceptors/XMLHttpRequest/index.d.ts +0 -15
  202. package/lib/browser/interceptors/XMLHttpRequest/index.js +0 -12
  203. package/lib/browser/interceptors/XMLHttpRequest/index.js.map +0 -1
  204. package/lib/browser/interceptors/XMLHttpRequest/index.mjs.map +0 -1
  205. package/lib/browser/interceptors/fetch/index.d.ts +0 -14
  206. package/lib/browser/interceptors/fetch/index.js +0 -11
  207. package/lib/browser/interceptors/fetch/index.js.map +0 -1
  208. package/lib/browser/interceptors/fetch/index.mjs.map +0 -1
  209. package/lib/browser/presets/browser.d.ts +0 -15
  210. package/lib/browser/presets/browser.js +0 -21
  211. package/lib/browser/presets/browser.js.map +0 -1
  212. package/lib/node/BatchInterceptor-5b72232f.d.ts +0 -24
  213. package/lib/node/Interceptor-bc5a9d8e.d.ts +0 -130
  214. package/lib/node/RemoteHttpInterceptor.d.ts +0 -45
  215. package/lib/node/RemoteHttpInterceptor.js +0 -193
  216. package/lib/node/RemoteHttpInterceptor.js.map +0 -1
  217. package/lib/node/chunk-3CNGDJFB.mjs +0 -313
  218. package/lib/node/chunk-3CNGDJFB.mjs.map +0 -1
  219. package/lib/node/chunk-3GJB4JDF.mjs +0 -14
  220. package/lib/node/chunk-3GJB4JDF.mjs.map +0 -1
  221. package/lib/node/chunk-4NEYTVWD.mjs +0 -848
  222. package/lib/node/chunk-4NEYTVWD.mjs.map +0 -1
  223. package/lib/node/chunk-4YBV77DG.js +0 -32
  224. package/lib/node/chunk-4YBV77DG.js.map +0 -1
  225. package/lib/node/chunk-6HYIRFX2.mjs +0 -22
  226. package/lib/node/chunk-6HYIRFX2.mjs.map +0 -1
  227. package/lib/node/chunk-6YM4PLBI.mjs +0 -7
  228. package/lib/node/chunk-6YM4PLBI.mjs.map +0 -1
  229. package/lib/node/chunk-72ZIHMEB.js +0 -249
  230. package/lib/node/chunk-72ZIHMEB.js.map +0 -1
  231. package/lib/node/chunk-73NOP3T5.js +0 -7
  232. package/lib/node/chunk-73NOP3T5.js.map +0 -1
  233. package/lib/node/chunk-A7Q4RTDJ.mjs +0 -249
  234. package/lib/node/chunk-A7Q4RTDJ.mjs.map +0 -1
  235. package/lib/node/chunk-A7U44ARP.js +0 -268
  236. package/lib/node/chunk-A7U44ARP.js.map +0 -1
  237. package/lib/node/chunk-EKNRB5ZS.mjs +0 -1115
  238. package/lib/node/chunk-EKNRB5ZS.mjs.map +0 -1
  239. package/lib/node/chunk-IHJSPMYM.mjs +0 -268
  240. package/lib/node/chunk-IHJSPMYM.mjs.map +0 -1
  241. package/lib/node/chunk-LK6DILFK.js +0 -22
  242. package/lib/node/chunk-LK6DILFK.js.map +0 -1
  243. package/lib/node/chunk-N4ZZFE24.js +0 -1115
  244. package/lib/node/chunk-N4ZZFE24.js.map +0 -1
  245. package/lib/node/chunk-PFGO5BSM.js +0 -25
  246. package/lib/node/chunk-PFGO5BSM.js.map +0 -1
  247. package/lib/node/chunk-R6JVCM7X.js +0 -51
  248. package/lib/node/chunk-R6JVCM7X.js.map +0 -1
  249. package/lib/node/chunk-RC2XPCC4.mjs +0 -51
  250. package/lib/node/chunk-RC2XPCC4.mjs.map +0 -1
  251. package/lib/node/chunk-SMXZPJEA.js +0 -14
  252. package/lib/node/chunk-SMXZPJEA.js.map +0 -1
  253. package/lib/node/chunk-TJDMZZXE.mjs +0 -32
  254. package/lib/node/chunk-TJDMZZXE.mjs.map +0 -1
  255. package/lib/node/chunk-TX5GBTFY.mjs +0 -25
  256. package/lib/node/chunk-TX5GBTFY.mjs.map +0 -1
  257. package/lib/node/chunk-VV2LUF5K.js +0 -848
  258. package/lib/node/chunk-VV2LUF5K.js.map +0 -1
  259. package/lib/node/chunk-Z5LWCBZS.js +0 -313
  260. package/lib/node/chunk-Z5LWCBZS.js.map +0 -1
  261. package/lib/node/index.d.ts +0 -62
  262. package/lib/node/index.js +0 -43
  263. package/lib/node/index.js.map +0 -1
  264. package/lib/node/interceptors/ClientRequest/index.d.ts +0 -111
  265. package/lib/node/interceptors/ClientRequest/index.js +0 -11
  266. package/lib/node/interceptors/ClientRequest/index.js.map +0 -1
  267. package/lib/node/interceptors/ClientRequest/index.mjs.map +0 -1
  268. package/lib/node/interceptors/XMLHttpRequest/index.d.ts +0 -14
  269. package/lib/node/interceptors/XMLHttpRequest/index.js +0 -13
  270. package/lib/node/interceptors/XMLHttpRequest/index.js.map +0 -1
  271. package/lib/node/interceptors/XMLHttpRequest/index.mjs.map +0 -1
  272. package/lib/node/interceptors/fetch/index.d.ts +0 -13
  273. package/lib/node/interceptors/fetch/index.js +0 -12
  274. package/lib/node/interceptors/fetch/index.js.map +0 -1
  275. package/lib/node/interceptors/fetch/index.mjs.map +0 -1
  276. package/lib/node/presets/node.d.ts +0 -16
  277. package/lib/node/presets/node.js +0 -27
  278. package/lib/node/presets/node.js.map +0 -1
  279. package/lib/node/utils/node/index.js +0 -10
  280. package/lib/node/utils/node/index.js.map +0 -1
  281. package/lib/node/utils/node/index.mjs.map +0 -1
  282. package/src/utils/RequestController.ts +0 -21
@@ -0,0 +1,1043 @@
1
+ const require_chunk = require('./chunk-CbDLau6x.cjs');
2
+ const require_fetchUtils = require('./fetchUtils-BaY5iWXw.cjs');
3
+ const require_getRawRequest = require('./getRawRequest-BavnMWh_.cjs');
4
+ const require_handleRequest = require('./handleRequest-Bb7Y-XLw.cjs');
5
+ const require_node = require('./node-dKdAf3tC.cjs');
6
+ let _open_draft_logger = require("@open-draft/logger");
7
+ let outvariant = require("outvariant");
8
+ let node_http = require("node:http");
9
+ node_http = require_chunk.__toESM(node_http);
10
+ let node_https = require("node:https");
11
+ node_https = require_chunk.__toESM(node_https);
12
+ let node_net = require("node:net");
13
+ node_net = require_chunk.__toESM(node_net);
14
+ let _http_common = require("_http_common");
15
+ let node_stream = require("node:stream");
16
+ let node_url = require("node:url");
17
+ let http = require("http");
18
+
19
+ //#region src/interceptors/Socket/utils/normalizeSocketWriteArgs.ts
20
+ /**
21
+ * Normalizes the arguments provided to the `Writable.prototype.write()`
22
+ * and `Writable.prototype.end()`.
23
+ */
24
+ function normalizeSocketWriteArgs(args) {
25
+ const normalized = [
26
+ args[0],
27
+ void 0,
28
+ void 0
29
+ ];
30
+ if (typeof args[1] === "string") normalized[1] = args[1];
31
+ else if (typeof args[1] === "function") normalized[2] = args[1];
32
+ if (typeof args[2] === "function") normalized[2] = args[2];
33
+ return normalized;
34
+ }
35
+
36
+ //#endregion
37
+ //#region src/interceptors/Socket/MockSocket.ts
38
+ var MockSocket = class extends node_net.default.Socket {
39
+ constructor(options) {
40
+ super();
41
+ this.options = options;
42
+ this.connecting = false;
43
+ this.connect();
44
+ this._final = (callback) => {
45
+ callback(null);
46
+ };
47
+ }
48
+ connect() {
49
+ this.connecting = true;
50
+ return this;
51
+ }
52
+ write(...args) {
53
+ const [chunk, encoding, callback] = normalizeSocketWriteArgs(args);
54
+ this.options.write(chunk, encoding, callback);
55
+ return true;
56
+ }
57
+ end(...args) {
58
+ const [chunk, encoding, callback] = normalizeSocketWriteArgs(args);
59
+ this.options.write(chunk, encoding, callback);
60
+ return super.end.apply(this, args);
61
+ }
62
+ push(chunk, encoding) {
63
+ this.options.read(chunk, encoding);
64
+ return super.push(chunk, encoding);
65
+ }
66
+ };
67
+
68
+ //#endregion
69
+ //#region src/interceptors/Socket/utils/baseUrlFromConnectionOptions.ts
70
+ function baseUrlFromConnectionOptions(options) {
71
+ if ("href" in options) return new URL(options.href);
72
+ const protocol = options.port === 443 ? "https:" : "http:";
73
+ const host = options.host;
74
+ const url = new URL(`${protocol}//${host}`);
75
+ if (options.port) url.port = options.port.toString();
76
+ if (options.path) url.pathname = options.path;
77
+ if (options.auth) {
78
+ const [username, password] = options.auth.split(":");
79
+ url.username = username;
80
+ url.password = password;
81
+ }
82
+ return url;
83
+ }
84
+
85
+ //#endregion
86
+ //#region src/interceptors/ClientRequest/utils/recordRawHeaders.ts
87
+ const kRawHeaders = Symbol("kRawHeaders");
88
+ const kRestorePatches = Symbol("kRestorePatches");
89
+ function recordRawHeader(headers, args, behavior) {
90
+ ensureRawHeadersSymbol(headers, []);
91
+ const rawHeaders = Reflect.get(headers, kRawHeaders);
92
+ if (behavior === "set") {
93
+ for (let index = rawHeaders.length - 1; index >= 0; index--) if (rawHeaders[index][0].toLowerCase() === args[0].toLowerCase()) rawHeaders.splice(index, 1);
94
+ }
95
+ rawHeaders.push(args);
96
+ }
97
+ /**
98
+ * Define the raw headers symbol on the given `Headers` instance.
99
+ * If the symbol already exists, this function does nothing.
100
+ */
101
+ function ensureRawHeadersSymbol(headers, rawHeaders) {
102
+ if (Reflect.has(headers, kRawHeaders)) return;
103
+ defineRawHeadersSymbol(headers, rawHeaders);
104
+ }
105
+ /**
106
+ * Define the raw headers symbol on the given `Headers` instance.
107
+ * If the symbol already exists, it gets overridden.
108
+ */
109
+ function defineRawHeadersSymbol(headers, rawHeaders) {
110
+ Object.defineProperty(headers, kRawHeaders, {
111
+ value: rawHeaders,
112
+ enumerable: false,
113
+ configurable: true
114
+ });
115
+ }
116
+ /**
117
+ * Patch the global `Headers` class to store raw headers.
118
+ * This is for compatibility with `IncomingMessage.prototype.rawHeaders`.
119
+ *
120
+ * @note Node.js has their own raw headers symbol but it
121
+ * only records the first header name in case of multi-value headers.
122
+ * Any other headers are normalized before comparing. This makes it
123
+ * incompatible with the `rawHeaders` format.
124
+ *
125
+ * let h = new Headers()
126
+ * h.append('X-Custom', 'one')
127
+ * h.append('x-custom', 'two')
128
+ * h[Symbol('headers map')] // Map { 'X-Custom' => 'one, two' }
129
+ */
130
+ function recordRawFetchHeaders() {
131
+ if (Reflect.get(Headers, kRestorePatches)) return Reflect.get(Headers, kRestorePatches);
132
+ const { Headers: OriginalHeaders, Request: OriginalRequest, Response: OriginalResponse } = globalThis;
133
+ const { set, append, delete: headersDeleteMethod } = Headers.prototype;
134
+ Object.defineProperty(Headers, kRestorePatches, {
135
+ value: () => {
136
+ Headers.prototype.set = set;
137
+ Headers.prototype.append = append;
138
+ Headers.prototype.delete = headersDeleteMethod;
139
+ globalThis.Headers = OriginalHeaders;
140
+ globalThis.Request = OriginalRequest;
141
+ globalThis.Response = OriginalResponse;
142
+ Reflect.deleteProperty(Headers, kRestorePatches);
143
+ },
144
+ enumerable: false,
145
+ configurable: true
146
+ });
147
+ Object.defineProperty(globalThis, "Headers", {
148
+ enumerable: true,
149
+ writable: true,
150
+ value: new Proxy(Headers, { construct(target, args, newTarget) {
151
+ const headersInit = args[0] || [];
152
+ if (headersInit instanceof Headers && Reflect.has(headersInit, kRawHeaders)) {
153
+ const headers$1 = Reflect.construct(target, [Reflect.get(headersInit, kRawHeaders)], newTarget);
154
+ ensureRawHeadersSymbol(headers$1, [...Reflect.get(headersInit, kRawHeaders)]);
155
+ return headers$1;
156
+ }
157
+ const headers = Reflect.construct(target, args, newTarget);
158
+ if (!Reflect.has(headers, kRawHeaders)) ensureRawHeadersSymbol(headers, Array.isArray(headersInit) ? headersInit : Object.entries(headersInit));
159
+ return headers;
160
+ } })
161
+ });
162
+ Headers.prototype.set = new Proxy(Headers.prototype.set, { apply(target, thisArg, args) {
163
+ recordRawHeader(thisArg, args, "set");
164
+ return Reflect.apply(target, thisArg, args);
165
+ } });
166
+ Headers.prototype.append = new Proxy(Headers.prototype.append, { apply(target, thisArg, args) {
167
+ recordRawHeader(thisArg, args, "append");
168
+ return Reflect.apply(target, thisArg, args);
169
+ } });
170
+ Headers.prototype.delete = new Proxy(Headers.prototype.delete, { apply(target, thisArg, args) {
171
+ const rawHeaders = Reflect.get(thisArg, kRawHeaders);
172
+ if (rawHeaders) {
173
+ for (let index = rawHeaders.length - 1; index >= 0; index--) if (rawHeaders[index][0].toLowerCase() === args[0].toLowerCase()) rawHeaders.splice(index, 1);
174
+ }
175
+ return Reflect.apply(target, thisArg, args);
176
+ } });
177
+ Object.defineProperty(globalThis, "Request", {
178
+ enumerable: true,
179
+ writable: true,
180
+ value: new Proxy(Request, { construct(target, args, newTarget) {
181
+ const request = Reflect.construct(target, args, newTarget);
182
+ const inferredRawHeaders = [];
183
+ if (typeof args[0] === "object" && args[0].headers != null) inferredRawHeaders.push(...inferRawHeaders(args[0].headers));
184
+ if (typeof args[1] === "object" && args[1].headers != null) inferredRawHeaders.push(...inferRawHeaders(args[1].headers));
185
+ if (inferredRawHeaders.length > 0) ensureRawHeadersSymbol(request.headers, inferredRawHeaders);
186
+ return request;
187
+ } })
188
+ });
189
+ Object.defineProperty(globalThis, "Response", {
190
+ enumerable: true,
191
+ writable: true,
192
+ value: new Proxy(Response, { construct(target, args, newTarget) {
193
+ const response = Reflect.construct(target, args, newTarget);
194
+ if (typeof args[1] === "object" && args[1].headers != null) ensureRawHeadersSymbol(response.headers, inferRawHeaders(args[1].headers));
195
+ return response;
196
+ } })
197
+ });
198
+ }
199
+ function restoreHeadersPrototype() {
200
+ if (!Reflect.get(Headers, kRestorePatches)) return;
201
+ Reflect.get(Headers, kRestorePatches)();
202
+ }
203
+ function getRawFetchHeaders(headers) {
204
+ if (!Reflect.has(headers, kRawHeaders)) return Array.from(headers.entries());
205
+ const rawHeaders = Reflect.get(headers, kRawHeaders);
206
+ return rawHeaders.length > 0 ? rawHeaders : Array.from(headers.entries());
207
+ }
208
+ /**
209
+ * Infers the raw headers from the given `HeadersInit` provided
210
+ * to the Request/Response constructor.
211
+ *
212
+ * If the `init.headers` is a Headers instance, use it directly.
213
+ * That means the headers were created standalone and already have
214
+ * the raw headers stored.
215
+ * If the `init.headers` is a HeadersInit, create a new Headers
216
+ * instance out of it.
217
+ */
218
+ function inferRawHeaders(headers) {
219
+ if (headers instanceof Headers) return Reflect.get(headers, kRawHeaders) || [];
220
+ return Reflect.get(new Headers(headers), kRawHeaders);
221
+ }
222
+
223
+ //#endregion
224
+ //#region src/interceptors/ClientRequest/utils/parserUtils.ts
225
+ /**
226
+ * @see https://github.com/nodejs/node/blob/f3adc11e37b8bfaaa026ea85c1cf22e3a0e29ae9/lib/_http_common.js#L180
227
+ */
228
+ function freeParser(parser, socket) {
229
+ if (parser._consumed) parser.unconsume();
230
+ parser._headers = [];
231
+ parser._url = "";
232
+ parser.socket = null;
233
+ parser.incoming = null;
234
+ parser.outgoing = null;
235
+ parser.maxHeaderPairs = 2e3;
236
+ parser._consumed = false;
237
+ parser.onIncoming = null;
238
+ parser[_http_common.HTTPParser.kOnHeaders] = null;
239
+ parser[_http_common.HTTPParser.kOnHeadersComplete] = null;
240
+ parser[_http_common.HTTPParser.kOnMessageBegin] = null;
241
+ parser[_http_common.HTTPParser.kOnMessageComplete] = null;
242
+ parser[_http_common.HTTPParser.kOnBody] = null;
243
+ parser[_http_common.HTTPParser.kOnExecute] = null;
244
+ parser[_http_common.HTTPParser.kOnTimeout] = null;
245
+ parser.remove();
246
+ parser.free();
247
+ if (socket)
248
+ /**
249
+ * @note Unassigning the socket's parser will fail this assertion
250
+ * if there's still some data being processed on the socket:
251
+ * @see https://github.com/nodejs/node/blob/4e1f39b678b37017ac9baa0971e3aeecd3b67b51/lib/_http_client.js#L613
252
+ */
253
+ if (socket.destroyed) socket.parser = null;
254
+ else socket.once("end", () => {
255
+ socket.parser = null;
256
+ });
257
+ }
258
+
259
+ //#endregion
260
+ //#region src/interceptors/ClientRequest/MockHttpSocket.ts
261
+ const kRequestId = Symbol("kRequestId");
262
+ var MockHttpSocket = class extends MockSocket {
263
+ constructor(options) {
264
+ super({
265
+ write: (chunk, encoding, callback) => {
266
+ if (this.socketState !== "passthrough") this.writeBuffer.push([
267
+ chunk,
268
+ encoding,
269
+ callback
270
+ ]);
271
+ if (chunk) {
272
+ /**
273
+ * Forward any writes to the mock socket to the underlying original socket.
274
+ * This ensures functional duplex connections, like WebSocket.
275
+ * @see https://github.com/mswjs/interceptors/issues/682
276
+ */
277
+ if (this.socketState === "passthrough") this.originalSocket?.write(chunk, encoding, callback);
278
+ this.requestParser.execute(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding));
279
+ }
280
+ },
281
+ read: (chunk) => {
282
+ if (chunk !== null)
283
+ /**
284
+ * @todo We need to free the parser if the connection has been
285
+ * upgraded to a non-HTTP protocol. It won't be able to parse data
286
+ * from that point onward anyway. No need to keep it in memory.
287
+ */
288
+ this.responseParser.execute(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
289
+ }
290
+ });
291
+ this.requestRawHeadersBuffer = [];
292
+ this.responseRawHeadersBuffer = [];
293
+ this.writeBuffer = [];
294
+ this.socketState = "unknown";
295
+ this.onRequestHeaders = (rawHeaders) => {
296
+ this.requestRawHeadersBuffer.push(...rawHeaders);
297
+ };
298
+ this.onRequestStart = (versionMajor, versionMinor, rawHeaders, _, path, __, ___, ____, shouldKeepAlive) => {
299
+ this.shouldKeepAlive = shouldKeepAlive;
300
+ const url = new URL(path || "", this.baseUrl);
301
+ const method = this.connectionOptions.method?.toUpperCase() || "GET";
302
+ const headers = require_fetchUtils.FetchResponse.parseRawHeaders([...this.requestRawHeadersBuffer, ...rawHeaders || []]);
303
+ this.requestRawHeadersBuffer.length = 0;
304
+ const canHaveBody = method !== "GET" && method !== "HEAD";
305
+ if (url.username || url.password) {
306
+ if (!headers.has("authorization")) headers.set("authorization", `Basic ${url.username}:${url.password}`);
307
+ url.username = "";
308
+ url.password = "";
309
+ }
310
+ this.requestStream = new node_stream.Readable({ read: () => {
311
+ this.flushWriteBuffer();
312
+ } });
313
+ const requestId = require_fetchUtils.createRequestId();
314
+ this.request = new Request(url, {
315
+ method,
316
+ headers,
317
+ credentials: "same-origin",
318
+ duplex: canHaveBody ? "half" : void 0,
319
+ body: canHaveBody ? node_stream.Readable.toWeb(this.requestStream) : null
320
+ });
321
+ Reflect.set(this.request, kRequestId, requestId);
322
+ require_getRawRequest.setRawRequest(this.request, Reflect.get(this, "_httpMessage"));
323
+ require_node.setRawRequestBodyStream(this.request, this.requestStream);
324
+ /**
325
+ * @fixme Stop relying on the "X-Request-Id" request header
326
+ * to figure out if one interceptor has been invoked within another.
327
+ * @see https://github.com/mswjs/interceptors/issues/378
328
+ */
329
+ if (this.request.headers.has(require_fetchUtils.INTERNAL_REQUEST_ID_HEADER_NAME)) {
330
+ this.passthrough();
331
+ return;
332
+ }
333
+ this.onRequest({
334
+ requestId,
335
+ request: this.request,
336
+ socket: this
337
+ });
338
+ };
339
+ this.onResponseHeaders = (rawHeaders) => {
340
+ this.responseRawHeadersBuffer.push(...rawHeaders);
341
+ };
342
+ this.onResponseStart = (versionMajor, versionMinor, rawHeaders, method, url, status, statusText) => {
343
+ const headers = require_fetchUtils.FetchResponse.parseRawHeaders([...this.responseRawHeadersBuffer, ...rawHeaders || []]);
344
+ this.responseRawHeadersBuffer.length = 0;
345
+ const response = new require_fetchUtils.FetchResponse(
346
+ /**
347
+ * @note The Fetch API response instance exposed to the consumer
348
+ * is created over the response stream of the HTTP parser. It is NOT
349
+ * related to the Socket instance. This way, you can read response body
350
+ * in response listener while the Socket instance delays the emission
351
+ * of "end" and other events until those response listeners are finished.
352
+ */
353
+ require_fetchUtils.FetchResponse.isResponseWithBody(status) ? node_stream.Readable.toWeb(this.responseStream = new node_stream.Readable({ read() {} })) : null,
354
+ {
355
+ url,
356
+ status,
357
+ statusText,
358
+ headers
359
+ }
360
+ );
361
+ (0, outvariant.invariant)(this.request, "Failed to handle a response: request does not exist");
362
+ require_fetchUtils.FetchResponse.setUrl(this.request.url, response);
363
+ /**
364
+ * @fixme Stop relying on the "X-Request-Id" request header
365
+ * to figure out if one interceptor has been invoked within another.
366
+ * @see https://github.com/mswjs/interceptors/issues/378
367
+ */
368
+ if (this.request.headers.has(require_fetchUtils.INTERNAL_REQUEST_ID_HEADER_NAME)) return;
369
+ this.responseListenersPromise = this.onResponse({
370
+ response,
371
+ isMockedResponse: this.socketState === "mock",
372
+ requestId: Reflect.get(this.request, kRequestId),
373
+ request: this.request,
374
+ socket: this
375
+ });
376
+ };
377
+ this.connectionOptions = options.connectionOptions;
378
+ this.createConnection = options.createConnection;
379
+ this.onRequest = options.onRequest;
380
+ this.onResponse = options.onResponse;
381
+ this.baseUrl = baseUrlFromConnectionOptions(this.connectionOptions);
382
+ this.requestParser = new _http_common.HTTPParser();
383
+ this.requestParser.initialize(_http_common.HTTPParser.REQUEST, {});
384
+ this.requestParser[_http_common.HTTPParser.kOnHeaders] = this.onRequestHeaders.bind(this);
385
+ this.requestParser[_http_common.HTTPParser.kOnHeadersComplete] = this.onRequestStart.bind(this);
386
+ this.requestParser[_http_common.HTTPParser.kOnBody] = this.onRequestBody.bind(this);
387
+ this.requestParser[_http_common.HTTPParser.kOnMessageComplete] = this.onRequestEnd.bind(this);
388
+ this.responseParser = new _http_common.HTTPParser();
389
+ this.responseParser.initialize(_http_common.HTTPParser.RESPONSE, {});
390
+ this.responseParser[_http_common.HTTPParser.kOnHeaders] = this.onResponseHeaders.bind(this);
391
+ this.responseParser[_http_common.HTTPParser.kOnHeadersComplete] = this.onResponseStart.bind(this);
392
+ this.responseParser[_http_common.HTTPParser.kOnBody] = this.onResponseBody.bind(this);
393
+ this.responseParser[_http_common.HTTPParser.kOnMessageComplete] = this.onResponseEnd.bind(this);
394
+ this.once("finish", () => freeParser(this.requestParser, this));
395
+ if (this.baseUrl.protocol === "https:") {
396
+ Reflect.set(this, "encrypted", true);
397
+ Reflect.set(this, "authorized", false);
398
+ Reflect.set(this, "getProtocol", () => "TLSv1.3");
399
+ Reflect.set(this, "getSession", () => void 0);
400
+ Reflect.set(this, "isSessionReused", () => false);
401
+ Reflect.set(this, "getCipher", () => ({
402
+ name: "AES256-SHA",
403
+ standardName: "TLS_RSA_WITH_AES_256_CBC_SHA",
404
+ version: "TLSv1.3"
405
+ }));
406
+ }
407
+ }
408
+ emit(event, ...args) {
409
+ const emitEvent = super.emit.bind(this, event, ...args);
410
+ if (this.responseListenersPromise) {
411
+ this.responseListenersPromise.finally(emitEvent);
412
+ return this.listenerCount(event) > 0;
413
+ }
414
+ return emitEvent();
415
+ }
416
+ destroy(error) {
417
+ freeParser(this.responseParser, this);
418
+ if (error) this.emit("error", error);
419
+ return super.destroy(error);
420
+ }
421
+ /**
422
+ * Establish this Socket connection as-is and pipe
423
+ * its data/events through this Socket.
424
+ */
425
+ passthrough() {
426
+ this.socketState = "passthrough";
427
+ if (this.destroyed) return;
428
+ const socket = this.createConnection();
429
+ this.originalSocket = socket;
430
+ /**
431
+ * @note Inherit the original socket's connection handle.
432
+ * Without this, each push to the mock socket results in a
433
+ * new "connection" listener being added (i.e. buffering pushes).
434
+ * @see https://github.com/nodejs/node/blob/b18153598b25485ce4f54d0c5cb830a9457691ee/lib/net.js#L734
435
+ */
436
+ if ("_handle" in socket) Object.defineProperty(this, "_handle", {
437
+ value: socket._handle,
438
+ enumerable: true,
439
+ writable: true
440
+ });
441
+ this.once("close", () => {
442
+ socket.removeAllListeners();
443
+ if (!socket.destroyed) socket.destroy();
444
+ this.originalSocket = void 0;
445
+ });
446
+ this.address = socket.address.bind(socket);
447
+ let writeArgs;
448
+ let headersWritten = false;
449
+ while (writeArgs = this.writeBuffer.shift()) if (writeArgs !== void 0) {
450
+ if (!headersWritten) {
451
+ const [chunk, encoding, callback] = writeArgs;
452
+ const chunkString = chunk.toString();
453
+ const chunkBeforeRequestHeaders = chunkString.slice(0, chunkString.indexOf("\r\n") + 2);
454
+ const chunkAfterRequestHeaders = chunkString.slice(chunk.indexOf("\r\n\r\n"));
455
+ const headersChunk = `${chunkBeforeRequestHeaders}${getRawFetchHeaders(this.request.headers).filter(([name]) => {
456
+ return name.toLowerCase() !== require_fetchUtils.INTERNAL_REQUEST_ID_HEADER_NAME;
457
+ }).map(([name, value]) => `${name}: ${value}`).join("\r\n")}${chunkAfterRequestHeaders}`;
458
+ socket.write(headersChunk, encoding, callback);
459
+ headersWritten = true;
460
+ continue;
461
+ }
462
+ socket.write(...writeArgs);
463
+ }
464
+ if (Reflect.get(socket, "encrypted")) [
465
+ "encrypted",
466
+ "authorized",
467
+ "getProtocol",
468
+ "getSession",
469
+ "isSessionReused",
470
+ "getCipher"
471
+ ].forEach((propertyName) => {
472
+ Object.defineProperty(this, propertyName, {
473
+ enumerable: true,
474
+ get: () => {
475
+ const value = Reflect.get(socket, propertyName);
476
+ return typeof value === "function" ? value.bind(socket) : value;
477
+ }
478
+ });
479
+ });
480
+ socket.on("lookup", (...args) => this.emit("lookup", ...args)).on("connect", () => {
481
+ this.connecting = socket.connecting;
482
+ this.emit("connect");
483
+ }).on("secureConnect", () => this.emit("secureConnect")).on("secure", () => this.emit("secure")).on("session", (session) => this.emit("session", session)).on("ready", () => this.emit("ready")).on("drain", () => this.emit("drain")).on("data", (chunk) => {
484
+ this.push(chunk);
485
+ }).on("error", (error) => {
486
+ Reflect.set(this, "_hadError", Reflect.get(socket, "_hadError"));
487
+ this.emit("error", error);
488
+ }).on("resume", () => this.emit("resume")).on("timeout", () => this.emit("timeout")).on("prefinish", () => this.emit("prefinish")).on("finish", () => this.emit("finish")).on("close", (hadError) => this.emit("close", hadError)).on("end", () => this.emit("end"));
489
+ }
490
+ /**
491
+ * Convert the given Fetch API `Response` instance to an
492
+ * HTTP message and push it to the socket.
493
+ */
494
+ async respondWith(response) {
495
+ if (this.destroyed) return;
496
+ (0, outvariant.invariant)(this.socketState !== "mock", "[MockHttpSocket] Failed to respond to the \"%s %s\" request with \"%s %s\": the request has already been handled", this.request?.method, this.request?.url, response.status, response.statusText);
497
+ if (require_handleRequest.isPropertyAccessible(response, "type") && response.type === "error") {
498
+ this.errorWith(/* @__PURE__ */ new TypeError("Network error"));
499
+ return;
500
+ }
501
+ this.mockConnect();
502
+ this.socketState = "mock";
503
+ this.flushWriteBuffer();
504
+ const serverResponse = new node_http.ServerResponse(new node_http.IncomingMessage(this));
505
+ /**
506
+ * Assign a mock socket instance to the server response to
507
+ * spy on the response chunk writes. Push the transformed response chunks
508
+ * to this `MockHttpSocket` instance to trigger the "data" event.
509
+ * @note Providing the same `MockSocket` instance when creating `ServerResponse`
510
+ * does not have the same effect.
511
+ * @see https://github.com/nodejs/node/blob/10099bb3f7fd97bb9dd9667188426866b3098e07/test/parallel/test-http-server-response-standalone.js#L32
512
+ */
513
+ serverResponse.assignSocket(new MockSocket({
514
+ write: (chunk, encoding, callback) => {
515
+ this.push(chunk, encoding);
516
+ callback?.();
517
+ },
518
+ read() {}
519
+ }));
520
+ /**
521
+ * @note Remove the `Connection` and `Date` response headers
522
+ * injected by `ServerResponse` by default. Those are required
523
+ * from the server but the interceptor is NOT technically a server.
524
+ * It's confusing to add response headers that the developer didn't
525
+ * specify themselves. They can always add these if they wish.
526
+ * @see https://www.rfc-editor.org/rfc/rfc9110#field.date
527
+ * @see https://www.rfc-editor.org/rfc/rfc9110#field.connection
528
+ */
529
+ serverResponse.removeHeader("connection");
530
+ serverResponse.removeHeader("date");
531
+ const rawResponseHeaders = getRawFetchHeaders(response.headers);
532
+ /**
533
+ * @note Call `.writeHead` in order to set the raw response headers
534
+ * in the same case as they were provided by the developer. Using
535
+ * `.setHeader()`/`.appendHeader()` normalizes header names.
536
+ */
537
+ serverResponse.writeHead(response.status, response.statusText || node_http.STATUS_CODES[response.status], rawResponseHeaders);
538
+ this.once("error", () => {
539
+ serverResponse.destroy();
540
+ });
541
+ if (response.body) try {
542
+ const reader = response.body.getReader();
543
+ while (true) {
544
+ const { done, value } = await reader.read();
545
+ if (done) {
546
+ serverResponse.end();
547
+ break;
548
+ }
549
+ serverResponse.write(value);
550
+ }
551
+ } catch (error) {
552
+ if (error instanceof Error) {
553
+ serverResponse.destroy();
554
+ /**
555
+ * @note Destroy the request socket gracefully.
556
+ * Response stream errors do NOT produce request errors.
557
+ */
558
+ this.destroy();
559
+ return;
560
+ }
561
+ serverResponse.destroy();
562
+ throw error;
563
+ }
564
+ else serverResponse.end();
565
+ if (!this.shouldKeepAlive) {
566
+ this.emit("readable");
567
+ /**
568
+ * @todo @fixme This is likely a hack.
569
+ * Since we push null to the socket, it never propagates to the
570
+ * parser, and the parser never calls "onResponseEnd" to close
571
+ * the response stream. We are closing the stream here manually
572
+ * but that shouldn't be the case.
573
+ */
574
+ this.responseStream?.push(null);
575
+ this.push(null);
576
+ }
577
+ }
578
+ /**
579
+ * Close this socket connection with the given error.
580
+ */
581
+ errorWith(error) {
582
+ this.destroy(error);
583
+ }
584
+ mockConnect() {
585
+ this.connecting = false;
586
+ const isIPv6 = node_net.default.isIPv6(this.connectionOptions.hostname) || this.connectionOptions.family === 6;
587
+ const addressInfo = {
588
+ address: isIPv6 ? "::1" : "127.0.0.1",
589
+ family: isIPv6 ? "IPv6" : "IPv4",
590
+ port: this.connectionOptions.port
591
+ };
592
+ this.address = () => addressInfo;
593
+ this.emit("lookup", null, addressInfo.address, addressInfo.family === "IPv6" ? 6 : 4, this.connectionOptions.host);
594
+ this.emit("connect");
595
+ this.emit("ready");
596
+ if (this.baseUrl.protocol === "https:") {
597
+ this.emit("secure");
598
+ this.emit("secureConnect");
599
+ this.emit("session", this.connectionOptions.session || Buffer.from("mock-session-renegotiate"));
600
+ this.emit("session", Buffer.from("mock-session-resume"));
601
+ }
602
+ }
603
+ flushWriteBuffer() {
604
+ for (const writeCall of this.writeBuffer) if (typeof writeCall[2] === "function") {
605
+ writeCall[2]();
606
+ /**
607
+ * @note Remove the callback from the write call
608
+ * so it doesn't get called twice on passthrough
609
+ * if `request.end()` was called within `request.write()`.
610
+ * @see https://github.com/mswjs/interceptors/issues/684
611
+ */
612
+ writeCall[2] = void 0;
613
+ }
614
+ }
615
+ onRequestBody(chunk) {
616
+ (0, outvariant.invariant)(this.requestStream, "Failed to write to a request stream: stream does not exist");
617
+ this.requestStream.push(chunk);
618
+ }
619
+ onRequestEnd() {
620
+ if (this.requestStream) this.requestStream.push(null);
621
+ }
622
+ onResponseBody(chunk) {
623
+ (0, outvariant.invariant)(this.responseStream, "Failed to write to a response stream: stream does not exist");
624
+ this.responseStream.push(chunk);
625
+ }
626
+ onResponseEnd() {
627
+ if (this.responseStream) this.responseStream.push(null);
628
+ }
629
+ };
630
+
631
+ //#endregion
632
+ //#region src/interceptors/ClientRequest/agents.ts
633
+ var MockAgent = class extends node_http.default.Agent {
634
+ constructor(options) {
635
+ super();
636
+ this.customAgent = options.customAgent;
637
+ this.onRequest = options.onRequest;
638
+ this.onResponse = options.onResponse;
639
+ }
640
+ createConnection(options, callback) {
641
+ const createConnection = this.customAgent instanceof node_http.default.Agent ? this.customAgent.createConnection : super.createConnection;
642
+ const createConnectionOptions = this.customAgent instanceof node_http.default.Agent ? {
643
+ ...options,
644
+ ...this.customAgent.options
645
+ } : options;
646
+ return new MockHttpSocket({
647
+ connectionOptions: options,
648
+ createConnection: createConnection.bind(this.customAgent || this, createConnectionOptions, callback),
649
+ onRequest: this.onRequest.bind(this),
650
+ onResponse: this.onResponse.bind(this)
651
+ });
652
+ }
653
+ };
654
+ var MockHttpsAgent = class extends node_https.default.Agent {
655
+ constructor(options) {
656
+ super();
657
+ this.customAgent = options.customAgent;
658
+ this.onRequest = options.onRequest;
659
+ this.onResponse = options.onResponse;
660
+ }
661
+ createConnection(options, callback) {
662
+ const createConnection = this.customAgent instanceof node_http.default.Agent ? this.customAgent.createConnection : super.createConnection;
663
+ const createConnectionOptions = this.customAgent instanceof node_http.default.Agent ? {
664
+ ...options,
665
+ ...this.customAgent.options
666
+ } : options;
667
+ return new MockHttpSocket({
668
+ connectionOptions: options,
669
+ createConnection: createConnection.bind(this.customAgent || this, createConnectionOptions, callback),
670
+ onRequest: this.onRequest.bind(this),
671
+ onResponse: this.onResponse.bind(this)
672
+ });
673
+ }
674
+ };
675
+
676
+ //#endregion
677
+ //#region src/utils/getUrlByRequestOptions.ts
678
+ const logger$2 = new _open_draft_logger.Logger("utils getUrlByRequestOptions");
679
+ const DEFAULT_PATH = "/";
680
+ const DEFAULT_PROTOCOL = "http:";
681
+ const DEFAULT_HOSTNAME = "localhost";
682
+ const SSL_PORT = 443;
683
+ function getAgent(options) {
684
+ return options.agent instanceof http.Agent ? options.agent : void 0;
685
+ }
686
+ function getProtocolByRequestOptions(options) {
687
+ if (options.protocol) return options.protocol;
688
+ const agentProtocol = getAgent(options)?.protocol;
689
+ if (agentProtocol) return agentProtocol;
690
+ const port = getPortByRequestOptions(options);
691
+ return options.cert || port === SSL_PORT ? "https:" : options.uri?.protocol || DEFAULT_PROTOCOL;
692
+ }
693
+ function getPortByRequestOptions(options) {
694
+ if (options.port) return Number(options.port);
695
+ const agent = getAgent(options);
696
+ if (agent?.options.port) return Number(agent.options.port);
697
+ if (agent?.defaultPort) return Number(agent.defaultPort);
698
+ }
699
+ function getAuthByRequestOptions(options) {
700
+ if (options.auth) {
701
+ const [username, password] = options.auth.split(":");
702
+ return {
703
+ username,
704
+ password
705
+ };
706
+ }
707
+ }
708
+ /**
709
+ * Returns true if host looks like an IPv6 address without surrounding brackets
710
+ * It assumes any host containing `:` is definitely not IPv4 and probably IPv6,
711
+ * but note that this could include invalid IPv6 addresses as well.
712
+ */
713
+ function isRawIPv6Address(host) {
714
+ return host.includes(":") && !host.startsWith("[") && !host.endsWith("]");
715
+ }
716
+ function getHostname(options) {
717
+ let host = options.hostname || options.host;
718
+ if (host) {
719
+ if (isRawIPv6Address(host)) host = `[${host}]`;
720
+ return new URL(`http://${host}`).hostname;
721
+ }
722
+ return DEFAULT_HOSTNAME;
723
+ }
724
+ /**
725
+ * Creates a `URL` instance from a given `RequestOptions` object.
726
+ */
727
+ function getUrlByRequestOptions(options) {
728
+ logger$2.info("request options", options);
729
+ if (options.uri) {
730
+ logger$2.info("constructing url from explicitly provided \"options.uri\": %s", options.uri);
731
+ return new URL(options.uri.href);
732
+ }
733
+ logger$2.info("figuring out url from request options...");
734
+ const protocol = getProtocolByRequestOptions(options);
735
+ logger$2.info("protocol", protocol);
736
+ const port = getPortByRequestOptions(options);
737
+ logger$2.info("port", port);
738
+ const hostname = getHostname(options);
739
+ logger$2.info("hostname", hostname);
740
+ const path = options.path || DEFAULT_PATH;
741
+ logger$2.info("path", path);
742
+ const credentials = getAuthByRequestOptions(options);
743
+ logger$2.info("credentials", credentials);
744
+ const authString = credentials ? `${credentials.username}:${credentials.password}@` : "";
745
+ logger$2.info("auth string:", authString);
746
+ const portString = typeof port !== "undefined" ? `:${port}` : "";
747
+ const url = new URL(`${protocol}//${hostname}${portString}${path}`);
748
+ url.username = credentials?.username || "";
749
+ url.password = credentials?.password || "";
750
+ logger$2.info("created url:", url);
751
+ return url;
752
+ }
753
+
754
+ //#endregion
755
+ //#region src/utils/cloneObject.ts
756
+ const logger$1 = new _open_draft_logger.Logger("cloneObject");
757
+ function isPlainObject(obj) {
758
+ logger$1.info("is plain object?", obj);
759
+ if (obj == null || !obj.constructor?.name) {
760
+ logger$1.info("given object is undefined, not a plain object...");
761
+ return false;
762
+ }
763
+ logger$1.info("checking the object constructor:", obj.constructor.name);
764
+ return obj.constructor.name === "Object";
765
+ }
766
+ function cloneObject(obj) {
767
+ logger$1.info("cloning object:", obj);
768
+ const enumerableProperties = Object.entries(obj).reduce((acc, [key, value]) => {
769
+ logger$1.info("analyzing key-value pair:", key, value);
770
+ acc[key] = isPlainObject(value) ? cloneObject(value) : value;
771
+ return acc;
772
+ }, {});
773
+ return isPlainObject(obj) ? enumerableProperties : Object.assign(Object.getPrototypeOf(obj), enumerableProperties);
774
+ }
775
+
776
+ //#endregion
777
+ //#region src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts
778
+ const logger = new _open_draft_logger.Logger("http normalizeClientRequestArgs");
779
+ function resolveRequestOptions(args, url) {
780
+ if (typeof args[1] === "undefined" || typeof args[1] === "function") {
781
+ logger.info("request options not provided, deriving from the url", url);
782
+ return (0, node_url.urlToHttpOptions)(url);
783
+ }
784
+ if (args[1]) {
785
+ logger.info("has custom RequestOptions!", args[1]);
786
+ const requestOptionsFromUrl = (0, node_url.urlToHttpOptions)(url);
787
+ logger.info("derived RequestOptions from the URL:", requestOptionsFromUrl);
788
+ /**
789
+ * Clone the request options to lock their state
790
+ * at the moment they are provided to `ClientRequest`.
791
+ * @see https://github.com/mswjs/interceptors/issues/86
792
+ */
793
+ logger.info("cloning RequestOptions...");
794
+ const clonedRequestOptions = cloneObject(args[1]);
795
+ logger.info("successfully cloned RequestOptions!", clonedRequestOptions);
796
+ return {
797
+ ...requestOptionsFromUrl,
798
+ ...clonedRequestOptions
799
+ };
800
+ }
801
+ logger.info("using an empty object as request options");
802
+ return {};
803
+ }
804
+ /**
805
+ * Overrides the given `URL` instance with the explicit properties provided
806
+ * on the `RequestOptions` object. The options object takes precedence,
807
+ * and will replace URL properties like "host", "path", and "port", if specified.
808
+ */
809
+ function overrideUrlByRequestOptions(url, options) {
810
+ url.host = options.host || url.host;
811
+ url.hostname = options.hostname || url.hostname;
812
+ url.port = options.port ? options.port.toString() : url.port;
813
+ if (options.path) {
814
+ const parsedOptionsPath = (0, node_url.parse)(options.path, false);
815
+ url.pathname = parsedOptionsPath.pathname || "";
816
+ url.search = parsedOptionsPath.search || "";
817
+ }
818
+ return url;
819
+ }
820
+ function resolveCallback(args) {
821
+ return typeof args[1] === "function" ? args[1] : args[2];
822
+ }
823
+ /**
824
+ * Normalizes parameters given to a `http.request` call
825
+ * so it always has a `URL` and `RequestOptions`.
826
+ */
827
+ function normalizeClientRequestArgs(defaultProtocol, args) {
828
+ let url;
829
+ let options;
830
+ let callback;
831
+ logger.info("arguments", args);
832
+ logger.info("using default protocol:", defaultProtocol);
833
+ if (args.length === 0) {
834
+ const url$1 = new node_url.URL("http://localhost");
835
+ return [url$1, resolveRequestOptions(args, url$1)];
836
+ }
837
+ if (typeof args[0] === "string") {
838
+ logger.info("first argument is a location string:", args[0]);
839
+ url = new node_url.URL(args[0]);
840
+ logger.info("created a url:", url);
841
+ const requestOptionsFromUrl = (0, node_url.urlToHttpOptions)(url);
842
+ logger.info("request options from url:", requestOptionsFromUrl);
843
+ options = resolveRequestOptions(args, url);
844
+ logger.info("resolved request options:", options);
845
+ callback = resolveCallback(args);
846
+ } else if (args[0] instanceof node_url.URL) {
847
+ url = args[0];
848
+ logger.info("first argument is a URL:", url);
849
+ if (typeof args[1] !== "undefined" && require_handleRequest.isObject(args[1])) url = overrideUrlByRequestOptions(url, args[1]);
850
+ options = resolveRequestOptions(args, url);
851
+ logger.info("derived request options:", options);
852
+ callback = resolveCallback(args);
853
+ } else if ("hash" in args[0] && !("method" in args[0])) {
854
+ const [legacyUrl] = args;
855
+ logger.info("first argument is a legacy URL:", legacyUrl);
856
+ if (legacyUrl.hostname === null) {
857
+ /**
858
+ * We are dealing with a relative url, so use the path as an "option" and
859
+ * merge in any existing options, giving priority to existing options -- i.e. a path in any
860
+ * existing options will take precedence over the one contained in the url. This is consistent
861
+ * with the behaviour in ClientRequest.
862
+ * @see https://github.com/nodejs/node/blob/d84f1312915fe45fe0febe888db692c74894c382/lib/_http_client.js#L122
863
+ */
864
+ logger.info("given legacy URL is relative (no hostname)");
865
+ return require_handleRequest.isObject(args[1]) ? normalizeClientRequestArgs(defaultProtocol, [{
866
+ path: legacyUrl.path,
867
+ ...args[1]
868
+ }, args[2]]) : normalizeClientRequestArgs(defaultProtocol, [{ path: legacyUrl.path }, args[1]]);
869
+ }
870
+ logger.info("given legacy url is absolute");
871
+ const resolvedUrl = new node_url.URL(legacyUrl.href);
872
+ return args[1] === void 0 ? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl]) : typeof args[1] === "function" ? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl, args[1]]) : normalizeClientRequestArgs(defaultProtocol, [
873
+ resolvedUrl,
874
+ args[1],
875
+ args[2]
876
+ ]);
877
+ } else if (require_handleRequest.isObject(args[0])) {
878
+ options = { ...args[0] };
879
+ logger.info("first argument is RequestOptions:", options);
880
+ options.protocol = options.protocol || defaultProtocol;
881
+ logger.info("normalized request options:", options);
882
+ url = getUrlByRequestOptions(options);
883
+ logger.info("created a URL from RequestOptions:", url.href);
884
+ callback = resolveCallback(args);
885
+ } else throw new Error(`Failed to construct ClientRequest with these parameters: ${args}`);
886
+ options.protocol = options.protocol || url.protocol;
887
+ options.method = options.method || "GET";
888
+ /**
889
+ * Ensure that the default Agent is always set.
890
+ * This prevents the protocol mismatch for requests with { agent: false },
891
+ * where the global Agent is inferred.
892
+ * @see https://github.com/mswjs/msw/issues/1150
893
+ * @see https://github.com/nodejs/node/blob/418ff70b810f0e7112d48baaa72932a56cfa213b/lib/_http_client.js#L130
894
+ * @see https://github.com/nodejs/node/blob/418ff70b810f0e7112d48baaa72932a56cfa213b/lib/_http_client.js#L157-L159
895
+ */
896
+ if (!options._defaultAgent) {
897
+ logger.info("has no default agent, setting the default agent for \"%s\"", options.protocol);
898
+ options._defaultAgent = options.protocol === "https:" ? node_https.globalAgent : node_http.globalAgent;
899
+ }
900
+ logger.info("successfully resolved url:", url.href);
901
+ logger.info("successfully resolved options:", options);
902
+ logger.info("successfully resolved callback:", callback);
903
+ /**
904
+ * @note If the user-provided URL is not a valid URL in Node.js,
905
+ * (e.g. the one provided by the JSDOM polyfills), case it to
906
+ * string. Otherwise, this throws on Node.js incompatibility
907
+ * (`ERR_INVALID_ARG_TYPE` on the connection listener)
908
+ * @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555
909
+ */
910
+ if (!(url instanceof node_url.URL)) url = url.toString();
911
+ return [
912
+ url,
913
+ options,
914
+ callback
915
+ ];
916
+ }
917
+
918
+ //#endregion
919
+ //#region src/interceptors/ClientRequest/index.ts
920
+ var ClientRequestInterceptor = class ClientRequestInterceptor extends require_fetchUtils.Interceptor {
921
+ static {
922
+ this.symbol = Symbol("client-request-interceptor");
923
+ }
924
+ constructor() {
925
+ super(ClientRequestInterceptor.symbol);
926
+ this.onRequest = async ({ request, socket }) => {
927
+ const controller = new require_fetchUtils.RequestController(request, {
928
+ passthrough() {
929
+ socket.passthrough();
930
+ },
931
+ async respondWith(response) {
932
+ await socket.respondWith(response);
933
+ },
934
+ errorWith(reason) {
935
+ if (reason instanceof Error) socket.errorWith(reason);
936
+ }
937
+ });
938
+ await require_handleRequest.handleRequest({
939
+ request,
940
+ requestId: Reflect.get(request, kRequestId),
941
+ controller,
942
+ emitter: this.emitter
943
+ });
944
+ };
945
+ this.onResponse = async ({ requestId, request, response, isMockedResponse }) => {
946
+ return require_handleRequest.emitAsync(this.emitter, "response", {
947
+ requestId,
948
+ request,
949
+ response,
950
+ isMockedResponse
951
+ });
952
+ };
953
+ }
954
+ setup() {
955
+ const { ClientRequest: OriginalClientRequest, get: originalGet, request: originalRequest } = node_http.default;
956
+ const { get: originalHttpsGet, request: originalHttpsRequest } = node_https.default;
957
+ const onRequest = this.onRequest.bind(this);
958
+ const onResponse = this.onResponse.bind(this);
959
+ node_http.default.ClientRequest = new Proxy(node_http.default.ClientRequest, { construct: (target, args) => {
960
+ const [url, options, callback] = normalizeClientRequestArgs("http:", args);
961
+ options.agent = new (options.protocol === "https:" ? MockHttpsAgent : MockAgent)({
962
+ customAgent: options.agent,
963
+ onRequest,
964
+ onResponse
965
+ });
966
+ return Reflect.construct(target, [
967
+ url,
968
+ options,
969
+ callback
970
+ ]);
971
+ } });
972
+ node_http.default.request = new Proxy(node_http.default.request, { apply: (target, thisArg, args) => {
973
+ const [url, options, callback] = normalizeClientRequestArgs("http:", args);
974
+ options.agent = new MockAgent({
975
+ customAgent: options.agent,
976
+ onRequest,
977
+ onResponse
978
+ });
979
+ return Reflect.apply(target, thisArg, [
980
+ url,
981
+ options,
982
+ callback
983
+ ]);
984
+ } });
985
+ node_http.default.get = new Proxy(node_http.default.get, { apply: (target, thisArg, args) => {
986
+ const [url, options, callback] = normalizeClientRequestArgs("http:", args);
987
+ options.agent = new MockAgent({
988
+ customAgent: options.agent,
989
+ onRequest,
990
+ onResponse
991
+ });
992
+ return Reflect.apply(target, thisArg, [
993
+ url,
994
+ options,
995
+ callback
996
+ ]);
997
+ } });
998
+ node_https.default.request = new Proxy(node_https.default.request, { apply: (target, thisArg, args) => {
999
+ const [url, options, callback] = normalizeClientRequestArgs("https:", args);
1000
+ options.agent = new MockHttpsAgent({
1001
+ customAgent: options.agent,
1002
+ onRequest,
1003
+ onResponse
1004
+ });
1005
+ return Reflect.apply(target, thisArg, [
1006
+ url,
1007
+ options,
1008
+ callback
1009
+ ]);
1010
+ } });
1011
+ node_https.default.get = new Proxy(node_https.default.get, { apply: (target, thisArg, args) => {
1012
+ const [url, options, callback] = normalizeClientRequestArgs("https:", args);
1013
+ options.agent = new MockHttpsAgent({
1014
+ customAgent: options.agent,
1015
+ onRequest,
1016
+ onResponse
1017
+ });
1018
+ return Reflect.apply(target, thisArg, [
1019
+ url,
1020
+ options,
1021
+ callback
1022
+ ]);
1023
+ } });
1024
+ recordRawFetchHeaders();
1025
+ this.subscriptions.push(() => {
1026
+ node_http.default.ClientRequest = OriginalClientRequest;
1027
+ node_http.default.get = originalGet;
1028
+ node_http.default.request = originalRequest;
1029
+ node_https.default.get = originalHttpsGet;
1030
+ node_https.default.request = originalHttpsRequest;
1031
+ restoreHeadersPrototype();
1032
+ });
1033
+ }
1034
+ };
1035
+
1036
+ //#endregion
1037
+ Object.defineProperty(exports, 'ClientRequestInterceptor', {
1038
+ enumerable: true,
1039
+ get: function () {
1040
+ return ClientRequestInterceptor;
1041
+ }
1042
+ });
1043
+ //# sourceMappingURL=ClientRequest-2rDe54Ui.cjs.map