@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 @@
1
+ {"version":3,"file":"ClientRequest-Ca8Qykuv.mjs","names":["normalized: NormalizedSocketWriteArgs","options: MockSocketOptions","headers","inferredRawHeaders: RawHeaders","writeArgs: NormalizedSocketWriteArgs | undefined","logger","logger","parseUrl","url: URL","options: ResolvedRequestOptions","callback: HttpRequestCallback | undefined","url","URL","httpsGlobalAgent","httpGlobalAgent"],"sources":["../../src/interceptors/Socket/utils/normalizeSocketWriteArgs.ts","../../src/interceptors/Socket/MockSocket.ts","../../src/interceptors/Socket/utils/baseUrlFromConnectionOptions.ts","../../src/interceptors/ClientRequest/utils/recordRawHeaders.ts","../../src/interceptors/ClientRequest/utils/parserUtils.ts","../../src/interceptors/ClientRequest/MockHttpSocket.ts","../../src/interceptors/ClientRequest/agents.ts","../../src/utils/getUrlByRequestOptions.ts","../../src/utils/cloneObject.ts","../../src/interceptors/ClientRequest/utils/normalizeClientRequestArgs.ts","../../src/interceptors/ClientRequest/index.ts"],"sourcesContent":["export type WriteCallback = (error?: Error | null) => void\n\nexport type WriteArgs =\n | [chunk: unknown, callback?: WriteCallback]\n | [chunk: unknown, encoding: BufferEncoding, callback?: WriteCallback]\n\nexport type NormalizedSocketWriteArgs = [\n chunk: any,\n encoding?: BufferEncoding,\n callback?: WriteCallback,\n]\n\n/**\n * Normalizes the arguments provided to the `Writable.prototype.write()`\n * and `Writable.prototype.end()`.\n */\nexport function normalizeSocketWriteArgs(\n args: WriteArgs\n): NormalizedSocketWriteArgs {\n const normalized: NormalizedSocketWriteArgs = [args[0], undefined, undefined]\n\n if (typeof args[1] === 'string') {\n normalized[1] = args[1]\n } else if (typeof args[1] === 'function') {\n normalized[2] = args[1]\n }\n\n if (typeof args[2] === 'function') {\n normalized[2] = args[2]\n }\n\n return normalized\n}\n","import net from 'node:net'\nimport {\n normalizeSocketWriteArgs,\n type WriteArgs,\n type WriteCallback,\n} from './utils/normalizeSocketWriteArgs'\n\nexport interface MockSocketOptions {\n write: (\n chunk: Buffer | string,\n encoding: BufferEncoding | undefined,\n callback?: WriteCallback\n ) => void\n\n read: (chunk: Buffer, encoding: BufferEncoding | undefined) => void\n}\n\nexport class MockSocket extends net.Socket {\n public connecting: boolean\n\n constructor(protected readonly options: MockSocketOptions) {\n super()\n this.connecting = false\n this.connect()\n\n this._final = (callback) => {\n callback(null)\n }\n }\n\n public connect() {\n // The connection will remain pending until\n // the consumer decides to handle it.\n this.connecting = true\n return this\n }\n\n public write(...args: Array<unknown>): boolean {\n const [chunk, encoding, callback] = normalizeSocketWriteArgs(\n args as WriteArgs\n )\n this.options.write(chunk, encoding, callback)\n return true\n }\n\n public end(...args: Array<unknown>) {\n const [chunk, encoding, callback] = normalizeSocketWriteArgs(\n args as WriteArgs\n )\n this.options.write(chunk, encoding, callback)\n return super.end.apply(this, args as any)\n }\n\n public push(chunk: any, encoding?: BufferEncoding): boolean {\n this.options.read(chunk, encoding)\n return super.push(chunk, encoding)\n }\n}\n","export function baseUrlFromConnectionOptions(options: any): URL {\n if ('href' in options) {\n return new URL(options.href)\n }\n\n const protocol = options.port === 443 ? 'https:' : 'http:'\n const host = options.host\n\n const url = new URL(`${protocol}//${host}`)\n\n if (options.port) {\n url.port = options.port.toString()\n }\n\n if (options.path) {\n url.pathname = options.path\n }\n\n if (options.auth) {\n const [username, password] = options.auth.split(':')\n url.username = username\n url.password = password\n }\n\n return url\n}\n","type HeaderTuple = [string, string]\ntype RawHeaders = Array<HeaderTuple>\ntype SetHeaderBehavior = 'set' | 'append'\n\nconst kRawHeaders = Symbol('kRawHeaders')\nconst kRestorePatches = Symbol('kRestorePatches')\n\nfunction recordRawHeader(\n headers: Headers,\n args: HeaderTuple,\n behavior: SetHeaderBehavior\n) {\n ensureRawHeadersSymbol(headers, [])\n const rawHeaders = Reflect.get(headers, kRawHeaders) as RawHeaders\n\n if (behavior === 'set') {\n // When recording a set header, ensure we remove any matching existing headers.\n for (let index = rawHeaders.length - 1; index >= 0; index--) {\n if (rawHeaders[index][0].toLowerCase() === args[0].toLowerCase()) {\n rawHeaders.splice(index, 1)\n }\n }\n }\n\n rawHeaders.push(args)\n}\n\n/**\n * Define the raw headers symbol on the given `Headers` instance.\n * If the symbol already exists, this function does nothing.\n */\nfunction ensureRawHeadersSymbol(\n headers: Headers,\n rawHeaders: RawHeaders\n): void {\n if (Reflect.has(headers, kRawHeaders)) {\n return\n }\n\n defineRawHeadersSymbol(headers, rawHeaders)\n}\n\n/**\n * Define the raw headers symbol on the given `Headers` instance.\n * If the symbol already exists, it gets overridden.\n */\nfunction defineRawHeadersSymbol(headers: Headers, rawHeaders: RawHeaders) {\n Object.defineProperty(headers, kRawHeaders, {\n value: rawHeaders,\n enumerable: false,\n // Mark the symbol as configurable so its value can be overridden.\n // Overrides happen when merging raw headers from multiple sources.\n // E.g. new Request(new Request(url, { headers }), { headers })\n configurable: true,\n })\n}\n\n/**\n * Patch the global `Headers` class to store raw headers.\n * This is for compatibility with `IncomingMessage.prototype.rawHeaders`.\n *\n * @note Node.js has their own raw headers symbol but it\n * only records the first header name in case of multi-value headers.\n * Any other headers are normalized before comparing. This makes it\n * incompatible with the `rawHeaders` format.\n *\n * let h = new Headers()\n * h.append('X-Custom', 'one')\n * h.append('x-custom', 'two')\n * h[Symbol('headers map')] // Map { 'X-Custom' => 'one, two' }\n */\nexport function recordRawFetchHeaders() {\n // Prevent patching the Headers prototype multiple times.\n if (Reflect.get(Headers, kRestorePatches)) {\n return Reflect.get(Headers, kRestorePatches)\n }\n\n const {\n Headers: OriginalHeaders,\n Request: OriginalRequest,\n Response: OriginalResponse,\n } = globalThis\n const { set, append, delete: headersDeleteMethod } = Headers.prototype\n\n Object.defineProperty(Headers, kRestorePatches, {\n value: () => {\n Headers.prototype.set = set\n Headers.prototype.append = append\n Headers.prototype.delete = headersDeleteMethod\n globalThis.Headers = OriginalHeaders\n\n globalThis.Request = OriginalRequest\n globalThis.Response = OriginalResponse\n\n Reflect.deleteProperty(Headers, kRestorePatches)\n },\n enumerable: false,\n /**\n * @note Mark this property as configurable\n * so we can delete it using `Reflect.delete` during cleanup.\n */\n configurable: true,\n })\n\n Object.defineProperty(globalThis, 'Headers', {\n enumerable: true,\n writable: true,\n value: new Proxy(Headers, {\n construct(target, args, newTarget) {\n const headersInit = args[0] || []\n\n if (\n headersInit instanceof Headers &&\n Reflect.has(headersInit, kRawHeaders)\n ) {\n const headers = Reflect.construct(\n target,\n [Reflect.get(headersInit, kRawHeaders)],\n newTarget\n )\n ensureRawHeadersSymbol(headers, [\n /**\n * @note Spread the retrieved headers to clone them.\n * This prevents multiple Headers instances from pointing\n * at the same internal \"rawHeaders\" array.\n */\n ...Reflect.get(headersInit, kRawHeaders),\n ])\n return headers\n }\n\n const headers = Reflect.construct(target, args, newTarget)\n\n // Request/Response constructors will set the symbol\n // upon creating a new instance, using the raw developer\n // input as the raw headers. Skip the symbol altogether\n // in those cases because the input to Headers will be normalized.\n if (!Reflect.has(headers, kRawHeaders)) {\n const rawHeadersInit = Array.isArray(headersInit)\n ? headersInit\n : Object.entries(headersInit)\n ensureRawHeadersSymbol(headers, rawHeadersInit)\n }\n\n return headers\n },\n }),\n })\n\n Headers.prototype.set = new Proxy(Headers.prototype.set, {\n apply(target, thisArg, args: HeaderTuple) {\n recordRawHeader(thisArg, args, 'set')\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n Headers.prototype.append = new Proxy(Headers.prototype.append, {\n apply(target, thisArg, args: HeaderTuple) {\n recordRawHeader(thisArg, args, 'append')\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n Headers.prototype.delete = new Proxy(Headers.prototype.delete, {\n apply(target, thisArg, args: [string]) {\n const rawHeaders = Reflect.get(thisArg, kRawHeaders) as RawHeaders\n\n if (rawHeaders) {\n for (let index = rawHeaders.length - 1; index >= 0; index--) {\n if (rawHeaders[index][0].toLowerCase() === args[0].toLowerCase()) {\n rawHeaders.splice(index, 1)\n }\n }\n }\n\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n Object.defineProperty(globalThis, 'Request', {\n enumerable: true,\n writable: true,\n value: new Proxy(Request, {\n construct(target, args, newTarget) {\n const request = Reflect.construct(target, args, newTarget)\n const inferredRawHeaders: RawHeaders = []\n\n // Infer raw headers from a `Request` instance used as init.\n if (typeof args[0] === 'object' && args[0].headers != null) {\n inferredRawHeaders.push(...inferRawHeaders(args[0].headers))\n }\n\n // Infer raw headers from the \"headers\" init argument.\n if (typeof args[1] === 'object' && args[1].headers != null) {\n inferredRawHeaders.push(...inferRawHeaders(args[1].headers))\n }\n\n if (inferredRawHeaders.length > 0) {\n ensureRawHeadersSymbol(request.headers, inferredRawHeaders)\n }\n\n return request\n },\n }),\n })\n\n Object.defineProperty(globalThis, 'Response', {\n enumerable: true,\n writable: true,\n value: new Proxy(Response, {\n construct(target, args, newTarget) {\n const response = Reflect.construct(target, args, newTarget)\n\n if (typeof args[1] === 'object' && args[1].headers != null) {\n ensureRawHeadersSymbol(\n response.headers,\n inferRawHeaders(args[1].headers)\n )\n }\n\n return response\n },\n }),\n })\n}\n\nexport function restoreHeadersPrototype() {\n if (!Reflect.get(Headers, kRestorePatches)) {\n return\n }\n\n Reflect.get(Headers, kRestorePatches)()\n}\n\nexport function getRawFetchHeaders(headers: Headers): RawHeaders {\n // If the raw headers recording failed for some reason,\n // use the normalized header entries instead.\n if (!Reflect.has(headers, kRawHeaders)) {\n return Array.from(headers.entries())\n }\n\n const rawHeaders = Reflect.get(headers, kRawHeaders) as RawHeaders\n return rawHeaders.length > 0 ? rawHeaders : Array.from(headers.entries())\n}\n\n/**\n * Infers the raw headers from the given `HeadersInit` provided\n * to the Request/Response constructor.\n *\n * If the `init.headers` is a Headers instance, use it directly.\n * That means the headers were created standalone and already have\n * the raw headers stored.\n * If the `init.headers` is a HeadersInit, create a new Headers\n * instance out of it.\n */\nfunction inferRawHeaders(headers: HeadersInit): RawHeaders {\n if (headers instanceof Headers) {\n return Reflect.get(headers, kRawHeaders) || []\n }\n\n return Reflect.get(new Headers(headers), kRawHeaders)\n}\n","import type { Socket } from 'node:net'\nimport { HTTPParser } from '_http_common'\n\n/**\n * @see https://github.com/nodejs/node/blob/f3adc11e37b8bfaaa026ea85c1cf22e3a0e29ae9/lib/_http_common.js#L180\n */\nexport function freeParser(parser: HTTPParser<any>, socket?: Socket): void {\n if (parser._consumed) {\n parser.unconsume()\n }\n\n parser._headers = []\n parser._url = ''\n parser.socket = null\n parser.incoming = null\n parser.outgoing = null\n parser.maxHeaderPairs = 2000\n parser._consumed = false\n parser.onIncoming = null\n\n parser[HTTPParser.kOnHeaders] = null\n parser[HTTPParser.kOnHeadersComplete] = null\n parser[HTTPParser.kOnMessageBegin] = null\n parser[HTTPParser.kOnMessageComplete] = null\n parser[HTTPParser.kOnBody] = null\n parser[HTTPParser.kOnExecute] = null\n parser[HTTPParser.kOnTimeout] = null\n\n parser.remove()\n parser.free()\n\n if (socket) {\n /**\n * @note Unassigning the socket's parser will fail this assertion\n * if there's still some data being processed on the socket:\n * @see https://github.com/nodejs/node/blob/4e1f39b678b37017ac9baa0971e3aeecd3b67b51/lib/_http_client.js#L613\n */\n if (socket.destroyed) {\n // @ts-expect-error Node.js internals.\n socket.parser = null\n } else {\n socket.once('end', () => {\n // @ts-expect-error Node.js internals.\n socket.parser = null\n })\n }\n }\n}\n","import net from 'node:net'\nimport {\n type HeadersCallback,\n HTTPParser,\n type RequestHeadersCompleteCallback,\n type ResponseHeadersCompleteCallback,\n} from '_http_common'\nimport { STATUS_CODES, IncomingMessage, ServerResponse } from 'node:http'\nimport { Readable } from 'node:stream'\nimport { invariant } from 'outvariant'\nimport { INTERNAL_REQUEST_ID_HEADER_NAME } from '../../Interceptor'\nimport { MockSocket } from '../Socket/MockSocket'\nimport type { NormalizedSocketWriteArgs } from '../Socket/utils/normalizeSocketWriteArgs'\nimport { isPropertyAccessible } from '../../utils/isPropertyAccessible'\nimport { baseUrlFromConnectionOptions } from '../Socket/utils/baseUrlFromConnectionOptions'\nimport { createRequestId } from '../../createRequestId'\nimport { getRawFetchHeaders } from './utils/recordRawHeaders'\nimport { FetchResponse } from '../../utils/fetchUtils'\nimport { setRawRequest } from '../../getRawRequest'\nimport { setRawRequestBodyStream } from '../../utils/node'\nimport { freeParser } from './utils/parserUtils'\n\ntype HttpConnectionOptions = any\n\nexport type MockHttpSocketRequestCallback = (args: {\n requestId: string\n request: Request\n socket: MockHttpSocket\n}) => void\n\nexport type MockHttpSocketResponseCallback = (args: {\n requestId: string\n request: Request\n response: Response\n isMockedResponse: boolean\n socket: MockHttpSocket\n}) => Promise<void>\n\ninterface MockHttpSocketOptions {\n connectionOptions: HttpConnectionOptions\n createConnection: () => net.Socket\n onRequest: MockHttpSocketRequestCallback\n onResponse: MockHttpSocketResponseCallback\n}\n\nexport const kRequestId = Symbol('kRequestId')\n\nexport class MockHttpSocket extends MockSocket {\n private connectionOptions: HttpConnectionOptions\n private createConnection: () => net.Socket\n private baseUrl: URL\n\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n private responseListenersPromise?: Promise<void>\n\n private requestRawHeadersBuffer: Array<string> = []\n private responseRawHeadersBuffer: Array<string> = []\n private writeBuffer: Array<NormalizedSocketWriteArgs> = []\n private request?: Request\n private requestParser: HTTPParser<0>\n private requestStream?: Readable\n private shouldKeepAlive?: boolean\n\n private socketState: 'unknown' | 'mock' | 'passthrough' = 'unknown'\n private responseParser: HTTPParser<1>\n private responseStream?: Readable\n private originalSocket?: net.Socket\n\n constructor(options: MockHttpSocketOptions) {\n super({\n write: (chunk, encoding, callback) => {\n // Buffer the writes so they can be flushed in case of the original connection\n // and when reading the request body in the interceptor. If the connection has\n // been established, no need to buffer the chunks anymore, they will be forwarded.\n if (this.socketState !== 'passthrough') {\n this.writeBuffer.push([chunk, encoding, callback])\n }\n\n if (chunk) {\n /**\n * Forward any writes to the mock socket to the underlying original socket.\n * This ensures functional duplex connections, like WebSocket.\n * @see https://github.com/mswjs/interceptors/issues/682\n */\n if (this.socketState === 'passthrough') {\n this.originalSocket?.write(chunk, encoding, callback)\n }\n\n this.requestParser.execute(\n Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding)\n )\n }\n },\n read: (chunk) => {\n if (chunk !== null) {\n /**\n * @todo We need to free the parser if the connection has been\n * upgraded to a non-HTTP protocol. It won't be able to parse data\n * from that point onward anyway. No need to keep it in memory.\n */\n this.responseParser.execute(\n Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n )\n }\n },\n })\n\n this.connectionOptions = options.connectionOptions\n this.createConnection = options.createConnection\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n\n this.baseUrl = baseUrlFromConnectionOptions(this.connectionOptions)\n\n // Request parser.\n this.requestParser = new HTTPParser()\n this.requestParser.initialize(HTTPParser.REQUEST, {})\n this.requestParser[HTTPParser.kOnHeaders] = this.onRequestHeaders.bind(this)\n this.requestParser[HTTPParser.kOnHeadersComplete] =\n this.onRequestStart.bind(this)\n this.requestParser[HTTPParser.kOnBody] = this.onRequestBody.bind(this)\n this.requestParser[HTTPParser.kOnMessageComplete] =\n this.onRequestEnd.bind(this)\n\n // Response parser.\n this.responseParser = new HTTPParser()\n this.responseParser.initialize(HTTPParser.RESPONSE, {})\n this.responseParser[HTTPParser.kOnHeaders] =\n this.onResponseHeaders.bind(this)\n this.responseParser[HTTPParser.kOnHeadersComplete] =\n this.onResponseStart.bind(this)\n this.responseParser[HTTPParser.kOnBody] = this.onResponseBody.bind(this)\n this.responseParser[HTTPParser.kOnMessageComplete] =\n this.onResponseEnd.bind(this)\n\n // Once the socket is finished, nothing can write to it\n // anymore. It has also flushed any buffered chunks.\n this.once('finish', () => freeParser(this.requestParser, this))\n\n if (this.baseUrl.protocol === 'https:') {\n Reflect.set(this, 'encrypted', true)\n // The server certificate is not the same as a CA\n // passed to the TLS socket connection options.\n Reflect.set(this, 'authorized', false)\n Reflect.set(this, 'getProtocol', () => 'TLSv1.3')\n Reflect.set(this, 'getSession', () => undefined)\n Reflect.set(this, 'isSessionReused', () => false)\n Reflect.set(this, 'getCipher', () => ({\n name: 'AES256-SHA',\n standardName: 'TLS_RSA_WITH_AES_256_CBC_SHA',\n version: 'TLSv1.3',\n }))\n }\n }\n\n public emit(event: string | symbol, ...args: any[]): boolean {\n const emitEvent = super.emit.bind(this, event as any, ...args)\n\n if (this.responseListenersPromise) {\n this.responseListenersPromise.finally(emitEvent)\n return this.listenerCount(event) > 0\n }\n\n return emitEvent()\n }\n\n public destroy(error?: Error | undefined): this {\n // Destroy the response parser when the socket gets destroyed.\n // Normally, we should listen to the \"close\" event but it\n // can be suppressed by using the \"emitClose: false\" option.\n freeParser(this.responseParser, this)\n\n if (error) {\n this.emit('error', error)\n }\n\n return super.destroy(error)\n }\n\n /**\n * Establish this Socket connection as-is and pipe\n * its data/events through this Socket.\n */\n public passthrough(): void {\n this.socketState = 'passthrough'\n\n if (this.destroyed) {\n return\n }\n\n const socket = this.createConnection()\n this.originalSocket = socket\n\n /**\n * @note Inherit the original socket's connection handle.\n * Without this, each push to the mock socket results in a\n * new \"connection\" listener being added (i.e. buffering pushes).\n * @see https://github.com/nodejs/node/blob/b18153598b25485ce4f54d0c5cb830a9457691ee/lib/net.js#L734\n */\n if ('_handle' in socket) {\n Object.defineProperty(this, '_handle', {\n value: socket._handle,\n enumerable: true,\n writable: true,\n })\n }\n\n // The client-facing socket can be destroyed in two ways:\n // 1. The developer destroys the socket.\n // 2. The passthrough socket \"close\" is forwarded to the socket.\n this.once('close', () => {\n socket.removeAllListeners()\n\n // If the closure didn't originate from the passthrough socket, destroy it.\n if (!socket.destroyed) {\n socket.destroy()\n }\n\n this.originalSocket = undefined\n })\n\n this.address = socket.address.bind(socket)\n\n // Flush the buffered \"socket.write()\" calls onto\n // the original socket instance (i.e. write request body).\n // Exhaust the \"requestBuffer\" in case this Socket\n // gets reused for different requests.\n let writeArgs: NormalizedSocketWriteArgs | undefined\n let headersWritten = false\n\n while ((writeArgs = this.writeBuffer.shift())) {\n if (writeArgs !== undefined) {\n if (!headersWritten) {\n const [chunk, encoding, callback] = writeArgs\n const chunkString = chunk.toString()\n const chunkBeforeRequestHeaders = chunkString.slice(\n 0,\n chunkString.indexOf('\\r\\n') + 2\n )\n const chunkAfterRequestHeaders = chunkString.slice(\n chunk.indexOf('\\r\\n\\r\\n')\n )\n const rawRequestHeaders = getRawFetchHeaders(this.request!.headers)\n const requestHeadersString = rawRequestHeaders\n // Skip the internal request ID deduplication header.\n .filter(([name]) => {\n return name.toLowerCase() !== INTERNAL_REQUEST_ID_HEADER_NAME\n })\n .map(([name, value]) => `${name}: ${value}`)\n .join('\\r\\n')\n\n // Modify the HTTP request message headers\n // to reflect any changes to the request headers\n // from the \"request\" event listener.\n const headersChunk = `${chunkBeforeRequestHeaders}${requestHeadersString}${chunkAfterRequestHeaders}`\n socket.write(headersChunk, encoding, callback)\n headersWritten = true\n continue\n }\n\n socket.write(...writeArgs)\n }\n }\n\n // Forward TLS Socket properties onto this Socket instance\n // in the case of a TLS/SSL connection.\n if (Reflect.get(socket, 'encrypted')) {\n const tlsProperties = [\n 'encrypted',\n 'authorized',\n 'getProtocol',\n 'getSession',\n 'isSessionReused',\n 'getCipher',\n ]\n\n tlsProperties.forEach((propertyName) => {\n Object.defineProperty(this, propertyName, {\n enumerable: true,\n get: () => {\n const value = Reflect.get(socket, propertyName)\n return typeof value === 'function' ? value.bind(socket) : value\n },\n })\n })\n }\n\n socket\n .on('lookup', (...args) => this.emit('lookup', ...args))\n .on('connect', () => {\n this.connecting = socket.connecting\n this.emit('connect')\n })\n .on('secureConnect', () => this.emit('secureConnect'))\n .on('secure', () => this.emit('secure'))\n .on('session', (session) => this.emit('session', session))\n .on('ready', () => this.emit('ready'))\n .on('drain', () => this.emit('drain'))\n .on('data', (chunk) => {\n // Push the original response to this socket\n // so it triggers the HTTP response parser. This unifies\n // the handling pipeline for original and mocked response.\n this.push(chunk)\n })\n .on('error', (error) => {\n Reflect.set(this, '_hadError', Reflect.get(socket, '_hadError'))\n this.emit('error', error)\n })\n .on('resume', () => this.emit('resume'))\n .on('timeout', () => this.emit('timeout'))\n .on('prefinish', () => this.emit('prefinish'))\n .on('finish', () => this.emit('finish'))\n .on('close', (hadError) => this.emit('close', hadError))\n .on('end', () => this.emit('end'))\n }\n\n /**\n * Convert the given Fetch API `Response` instance to an\n * HTTP message and push it to the socket.\n */\n public async respondWith(response: Response): Promise<void> {\n // Ignore the mocked response if the socket has been destroyed\n // (e.g. aborted or timed out),\n if (this.destroyed) {\n return\n }\n\n // Prevent recursive calls.\n invariant(\n this.socketState !== 'mock',\n '[MockHttpSocket] Failed to respond to the \"%s %s\" request with \"%s %s\": the request has already been handled',\n this.request?.method,\n this.request?.url,\n response.status,\n response.statusText\n )\n\n // Handle \"type: error\" responses.\n if (isPropertyAccessible(response, 'type') && response.type === 'error') {\n this.errorWith(new TypeError('Network error'))\n return\n }\n\n // First, emit all the connection events\n // to emulate a successful connection.\n this.mockConnect()\n this.socketState = 'mock'\n\n // Flush the write buffer to trigger write callbacks\n // if it hasn't been flushed already (e.g. someone started reading request stream).\n this.flushWriteBuffer()\n\n // Create a `ServerResponse` instance to delegate HTTP message parsing,\n // Transfer-Encoding, and other things to Node.js internals.\n const serverResponse = new ServerResponse(new IncomingMessage(this))\n\n /**\n * Assign a mock socket instance to the server response to\n * spy on the response chunk writes. Push the transformed response chunks\n * to this `MockHttpSocket` instance to trigger the \"data\" event.\n * @note Providing the same `MockSocket` instance when creating `ServerResponse`\n * does not have the same effect.\n * @see https://github.com/nodejs/node/blob/10099bb3f7fd97bb9dd9667188426866b3098e07/test/parallel/test-http-server-response-standalone.js#L32\n */\n serverResponse.assignSocket(\n new MockSocket({\n write: (chunk, encoding, callback) => {\n this.push(chunk, encoding)\n callback?.()\n },\n read() {},\n })\n )\n\n /**\n * @note Remove the `Connection` and `Date` response headers\n * injected by `ServerResponse` by default. Those are required\n * from the server but the interceptor is NOT technically a server.\n * It's confusing to add response headers that the developer didn't\n * specify themselves. They can always add these if they wish.\n * @see https://www.rfc-editor.org/rfc/rfc9110#field.date\n * @see https://www.rfc-editor.org/rfc/rfc9110#field.connection\n */\n serverResponse.removeHeader('connection')\n serverResponse.removeHeader('date')\n\n const rawResponseHeaders = getRawFetchHeaders(response.headers)\n\n /**\n * @note Call `.writeHead` in order to set the raw response headers\n * in the same case as they were provided by the developer. Using\n * `.setHeader()`/`.appendHeader()` normalizes header names.\n */\n serverResponse.writeHead(\n response.status,\n response.statusText || STATUS_CODES[response.status],\n rawResponseHeaders\n )\n\n // If the developer destroy the socket, gracefully destroy the response.\n this.once('error', () => {\n serverResponse.destroy()\n })\n\n if (response.body) {\n try {\n const reader = response.body.getReader()\n\n while (true) {\n const { done, value } = await reader.read()\n\n if (done) {\n serverResponse.end()\n break\n }\n\n serverResponse.write(value)\n }\n } catch (error) {\n if (error instanceof Error) {\n serverResponse.destroy()\n /**\n * @note Destroy the request socket gracefully.\n * Response stream errors do NOT produce request errors.\n */\n this.destroy()\n return\n }\n\n serverResponse.destroy()\n throw error\n }\n } else {\n serverResponse.end()\n }\n\n // Close the socket if the connection wasn't marked as keep-alive.\n if (!this.shouldKeepAlive) {\n this.emit('readable')\n\n /**\n * @todo @fixme This is likely a hack.\n * Since we push null to the socket, it never propagates to the\n * parser, and the parser never calls \"onResponseEnd\" to close\n * the response stream. We are closing the stream here manually\n * but that shouldn't be the case.\n */\n this.responseStream?.push(null)\n this.push(null)\n }\n }\n\n /**\n * Close this socket connection with the given error.\n */\n public errorWith(error?: Error): void {\n this.destroy(error)\n }\n\n private mockConnect(): void {\n // Calling this method immediately puts the socket\n // into the connected state.\n this.connecting = false\n\n const isIPv6 =\n net.isIPv6(this.connectionOptions.hostname) ||\n this.connectionOptions.family === 6\n const addressInfo = {\n address: isIPv6 ? '::1' : '127.0.0.1',\n family: isIPv6 ? 'IPv6' : 'IPv4',\n port: this.connectionOptions.port,\n }\n // Return fake address information for the socket.\n this.address = () => addressInfo\n this.emit(\n 'lookup',\n null,\n addressInfo.address,\n addressInfo.family === 'IPv6' ? 6 : 4,\n this.connectionOptions.host\n )\n this.emit('connect')\n this.emit('ready')\n\n if (this.baseUrl.protocol === 'https:') {\n this.emit('secure')\n this.emit('secureConnect')\n\n // A single TLS connection is represented by two \"session\" events.\n this.emit(\n 'session',\n this.connectionOptions.session ||\n Buffer.from('mock-session-renegotiate')\n )\n this.emit('session', Buffer.from('mock-session-resume'))\n }\n }\n\n private flushWriteBuffer(): void {\n for (const writeCall of this.writeBuffer) {\n if (typeof writeCall[2] === 'function') {\n writeCall[2]()\n /**\n * @note Remove the callback from the write call\n * so it doesn't get called twice on passthrough\n * if `request.end()` was called within `request.write()`.\n * @see https://github.com/mswjs/interceptors/issues/684\n */\n writeCall[2] = undefined\n }\n }\n }\n\n /**\n * This callback might be called when the request is \"slow\":\n * - Request headers were fragmented across multiple TCP packages;\n * - Request headers were too large to be processed in a single run\n * (e.g. more than 30 request headers).\n * @note This is called before request start.\n */\n private onRequestHeaders: HeadersCallback = (rawHeaders) => {\n this.requestRawHeadersBuffer.push(...rawHeaders)\n }\n\n private onRequestStart: RequestHeadersCompleteCallback = (\n versionMajor,\n versionMinor,\n rawHeaders,\n _,\n path,\n __,\n ___,\n ____,\n shouldKeepAlive\n ) => {\n this.shouldKeepAlive = shouldKeepAlive\n\n const url = new URL(path || '', this.baseUrl)\n const method = this.connectionOptions.method?.toUpperCase() || 'GET'\n const headers = FetchResponse.parseRawHeaders([\n ...this.requestRawHeadersBuffer,\n ...(rawHeaders || []),\n ])\n this.requestRawHeadersBuffer.length = 0\n\n const canHaveBody = method !== 'GET' && method !== 'HEAD'\n\n // Translate the basic authorization in the URL to the request header.\n // Constructing a Request instance with a URL containing auth is no-op.\n if (url.username || url.password) {\n if (!headers.has('authorization')) {\n headers.set('authorization', `Basic ${url.username}:${url.password}`)\n }\n url.username = ''\n url.password = ''\n }\n\n // Create a new stream for each request.\n // If this Socket is reused for multiple requests,\n // this ensures that each request gets its own stream.\n // One Socket instance can only handle one request at a time.\n this.requestStream = new Readable({\n /**\n * @note Provide the `read()` method so a `Readable` could be\n * used as the actual request body (the stream calls \"read()\").\n * We control the queue in the onRequestBody/End functions.\n */\n read: () => {\n // If the user attempts to read the request body,\n // flush the write buffer to trigger the callbacks.\n // This way, if the request stream ends in the write callback,\n // it will indeed end correctly.\n this.flushWriteBuffer()\n },\n })\n\n const requestId = createRequestId()\n this.request = new Request(url, {\n method,\n headers,\n credentials: 'same-origin',\n // @ts-expect-error Undocumented Fetch property.\n duplex: canHaveBody ? 'half' : undefined,\n body: canHaveBody ? (Readable.toWeb(this.requestStream!) as any) : null,\n })\n\n Reflect.set(this.request, kRequestId, requestId)\n\n // Set the raw `http.ClientRequest` instance on the request instance.\n // This is useful for cases like getting the raw headers of the request.\n setRawRequest(this.request, Reflect.get(this, '_httpMessage'))\n\n // Create a copy of the request body stream and store it on the request.\n // This is only needed for the consumers who wish to read the request body stream\n // of requests that cannot have a body per Fetch API specification (i.e. GET, HEAD).\n setRawRequestBodyStream(this.request, this.requestStream)\n\n // Skip handling the request that's already being handled\n // by another (parent) interceptor. For example, XMLHttpRequest\n // is often implemented via ClientRequest in Node.js (e.g. JSDOM).\n // In that case, XHR interceptor will bubble down to the ClientRequest\n // interceptor. No need to try to handle that request again.\n /**\n * @fixme Stop relying on the \"X-Request-Id\" request header\n * to figure out if one interceptor has been invoked within another.\n * @see https://github.com/mswjs/interceptors/issues/378\n */\n if (this.request.headers.has(INTERNAL_REQUEST_ID_HEADER_NAME)) {\n this.passthrough()\n return\n }\n\n this.onRequest({\n requestId,\n request: this.request,\n socket: this,\n })\n }\n\n private onRequestBody(chunk: Buffer): void {\n invariant(\n this.requestStream,\n 'Failed to write to a request stream: stream does not exist'\n )\n\n this.requestStream.push(chunk)\n }\n\n private onRequestEnd(): void {\n // Request end can be called for requests without body.\n if (this.requestStream) {\n this.requestStream.push(null)\n }\n }\n\n /**\n * This callback might be called when the response is \"slow\":\n * - Response headers were fragmented across multiple TCP packages;\n * - Response headers were too large to be processed in a single run\n * (e.g. more than 30 response headers).\n * @note This is called before response start.\n */\n private onResponseHeaders: HeadersCallback = (rawHeaders) => {\n this.responseRawHeadersBuffer.push(...rawHeaders)\n }\n\n private onResponseStart: ResponseHeadersCompleteCallback = (\n versionMajor,\n versionMinor,\n rawHeaders,\n method,\n url,\n status,\n statusText\n ) => {\n const headers = FetchResponse.parseRawHeaders([\n ...this.responseRawHeadersBuffer,\n ...(rawHeaders || []),\n ])\n this.responseRawHeadersBuffer.length = 0\n\n const response = new FetchResponse(\n /**\n * @note The Fetch API response instance exposed to the consumer\n * is created over the response stream of the HTTP parser. It is NOT\n * related to the Socket instance. This way, you can read response body\n * in response listener while the Socket instance delays the emission\n * of \"end\" and other events until those response listeners are finished.\n */\n FetchResponse.isResponseWithBody(status)\n ? (Readable.toWeb(\n (this.responseStream = new Readable({ read() {} }))\n ) as any)\n : null,\n {\n url,\n status,\n statusText,\n headers,\n }\n )\n\n invariant(\n this.request,\n 'Failed to handle a response: request does not exist'\n )\n\n FetchResponse.setUrl(this.request.url, response)\n\n /**\n * @fixme Stop relying on the \"X-Request-Id\" request header\n * to figure out if one interceptor has been invoked within another.\n * @see https://github.com/mswjs/interceptors/issues/378\n */\n if (this.request.headers.has(INTERNAL_REQUEST_ID_HEADER_NAME)) {\n return\n }\n\n this.responseListenersPromise = this.onResponse({\n response,\n isMockedResponse: this.socketState === 'mock',\n requestId: Reflect.get(this.request, kRequestId),\n request: this.request,\n socket: this,\n })\n }\n\n private onResponseBody(chunk: Buffer) {\n invariant(\n this.responseStream,\n 'Failed to write to a response stream: stream does not exist'\n )\n\n this.responseStream.push(chunk)\n }\n\n private onResponseEnd(): void {\n // Response end can be called for responses without body.\n if (this.responseStream) {\n this.responseStream.push(null)\n }\n }\n}\n","/**\n * Here's how requests are handled in Node.js:\n *\n * 1. http.ClientRequest instance calls `agent.addRequest(request, options, cb)`.\n * 2. Agent creates a new socket: `agent.createSocket(options, cb)`.\n * 3. Agent creates a new connection: `agent.createConnection(options, cb)`.\n */\nimport net from 'node:net'\nimport http from 'node:http'\nimport https from 'node:https'\nimport {\n MockHttpSocket,\n type MockHttpSocketRequestCallback,\n type MockHttpSocketResponseCallback,\n} from './MockHttpSocket'\n\ndeclare module 'node:http' {\n interface Agent {\n options?: http.AgentOptions\n createConnection(options: any, callback: any): net.Socket\n }\n}\n\ninterface MockAgentOptions {\n customAgent?: http.RequestOptions['agent']\n onRequest: MockHttpSocketRequestCallback\n onResponse: MockHttpSocketResponseCallback\n}\n\nexport class MockAgent extends http.Agent {\n private customAgent?: http.RequestOptions['agent']\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n\n constructor(options: MockAgentOptions) {\n super()\n this.customAgent = options.customAgent\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n }\n\n public createConnection(options: any, callback: any): net.Socket {\n const createConnection =\n this.customAgent instanceof http.Agent\n ? this.customAgent.createConnection\n : super.createConnection\n\n const createConnectionOptions =\n this.customAgent instanceof http.Agent\n ? {\n ...options,\n ...this.customAgent.options,\n }\n : options\n\n const socket = new MockHttpSocket({\n connectionOptions: options,\n createConnection: createConnection.bind(\n this.customAgent || this,\n createConnectionOptions,\n callback\n ),\n onRequest: this.onRequest.bind(this),\n onResponse: this.onResponse.bind(this),\n })\n\n return socket\n }\n}\n\nexport class MockHttpsAgent extends https.Agent {\n private customAgent?: https.RequestOptions['agent']\n private onRequest: MockHttpSocketRequestCallback\n private onResponse: MockHttpSocketResponseCallback\n\n constructor(options: MockAgentOptions) {\n super()\n this.customAgent = options.customAgent\n this.onRequest = options.onRequest\n this.onResponse = options.onResponse\n }\n\n public createConnection(options: any, callback: any): net.Socket {\n const createConnection =\n this.customAgent instanceof http.Agent\n ? this.customAgent.createConnection\n : super.createConnection\n\n const createConnectionOptions =\n this.customAgent instanceof http.Agent\n ? {\n ...options,\n ...this.customAgent.options,\n }\n : options\n\n const socket = new MockHttpSocket({\n connectionOptions: options,\n createConnection: createConnection.bind(\n this.customAgent || this,\n createConnectionOptions,\n callback\n ),\n onRequest: this.onRequest.bind(this),\n onResponse: this.onResponse.bind(this),\n })\n\n return socket\n }\n}\n","import { Agent } from 'http'\nimport { RequestOptions, Agent as HttpsAgent } from 'https'\nimport { Logger } from '@open-draft/logger'\n\nconst logger = new Logger('utils getUrlByRequestOptions')\n\n// Request instance constructed by the \"request\" library\n// has a \"self\" property that has a \"uri\" field. This is\n// reproducible by performing a \"XMLHttpRequest\" request in JSDOM.\nexport interface RequestSelf {\n uri?: URL\n}\n\nexport type ResolvedRequestOptions = RequestOptions & RequestSelf\n\nexport const DEFAULT_PATH = '/'\nconst DEFAULT_PROTOCOL = 'http:'\nconst DEFAULT_HOSTNAME = 'localhost'\nconst SSL_PORT = 443\n\nfunction getAgent(\n options: ResolvedRequestOptions\n): Agent | HttpsAgent | undefined {\n return options.agent instanceof Agent ? options.agent : undefined\n}\n\nfunction getProtocolByRequestOptions(options: ResolvedRequestOptions): string {\n if (options.protocol) {\n return options.protocol\n }\n\n const agent = getAgent(options)\n const agentProtocol = (agent as RequestOptions)?.protocol\n\n if (agentProtocol) {\n return agentProtocol\n }\n\n const port = getPortByRequestOptions(options)\n const isSecureRequest = options.cert || port === SSL_PORT\n\n return isSecureRequest ? 'https:' : options.uri?.protocol || DEFAULT_PROTOCOL\n}\n\nfunction getPortByRequestOptions(\n options: ResolvedRequestOptions\n): number | undefined {\n // Use the explicitly provided port.\n if (options.port) {\n return Number(options.port)\n }\n\n // Otherwise, try to resolve port from the agent.\n const agent = getAgent(options)\n\n if ((agent as HttpsAgent)?.options.port) {\n return Number((agent as HttpsAgent).options.port)\n }\n\n if ((agent as RequestOptions)?.defaultPort) {\n return Number((agent as RequestOptions).defaultPort)\n }\n\n // Lastly, return undefined indicating that the port\n // must inferred from the protocol. Do not infer it here.\n return undefined\n}\n\ninterface RequestAuth {\n username: string\n password: string\n}\n\nfunction getAuthByRequestOptions(\n options: ResolvedRequestOptions\n): RequestAuth | undefined {\n if (options.auth) {\n const [username, password] = options.auth.split(':')\n return { username, password }\n }\n}\n\n/**\n * Returns true if host looks like an IPv6 address without surrounding brackets\n * It assumes any host containing `:` is definitely not IPv4 and probably IPv6,\n * but note that this could include invalid IPv6 addresses as well.\n */\nfunction isRawIPv6Address(host: string): boolean {\n return host.includes(':') && !host.startsWith('[') && !host.endsWith(']')\n}\n\nfunction getHostname(options: ResolvedRequestOptions): string | undefined {\n let host = options.hostname || options.host\n\n if (host) {\n if (isRawIPv6Address(host)) {\n host = `[${host}]`\n }\n\n // Check the presence of the port, and if it's present,\n // remove it from the host, returning a hostname.\n return new URL(`http://${host}`).hostname\n }\n\n return DEFAULT_HOSTNAME\n}\n\n/**\n * Creates a `URL` instance from a given `RequestOptions` object.\n */\nexport function getUrlByRequestOptions(options: ResolvedRequestOptions): URL {\n logger.info('request options', options)\n\n if (options.uri) {\n logger.info(\n 'constructing url from explicitly provided \"options.uri\": %s',\n options.uri\n )\n return new URL(options.uri.href)\n }\n\n logger.info('figuring out url from request options...')\n\n const protocol = getProtocolByRequestOptions(options)\n logger.info('protocol', protocol)\n\n const port = getPortByRequestOptions(options)\n logger.info('port', port)\n\n const hostname = getHostname(options)\n logger.info('hostname', hostname)\n\n const path = options.path || DEFAULT_PATH\n logger.info('path', path)\n\n const credentials = getAuthByRequestOptions(options)\n logger.info('credentials', credentials)\n\n const authString = credentials\n ? `${credentials.username}:${credentials.password}@`\n : ''\n logger.info('auth string:', authString)\n\n const portString = typeof port !== 'undefined' ? `:${port}` : ''\n const url = new URL(`${protocol}//${hostname}${portString}${path}`)\n url.username = credentials?.username || ''\n url.password = credentials?.password || ''\n\n logger.info('created url:', url)\n\n return url\n}\n","import { Logger } from '@open-draft/logger'\n\nconst logger = new Logger('cloneObject')\n\nfunction isPlainObject(obj?: Record<string, any>): boolean {\n logger.info('is plain object?', obj)\n\n if (obj == null || !obj.constructor?.name) {\n logger.info('given object is undefined, not a plain object...')\n return false\n }\n\n logger.info('checking the object constructor:', obj.constructor.name)\n return obj.constructor.name === 'Object'\n}\n\nexport function cloneObject<ObjectType extends Record<string, any>>(\n obj: ObjectType\n): ObjectType {\n logger.info('cloning object:', obj)\n\n const enumerableProperties = Object.entries(obj).reduce<Record<string, any>>(\n (acc, [key, value]) => {\n logger.info('analyzing key-value pair:', key, value)\n\n // Recursively clone only plain objects, omitting class instances.\n acc[key] = isPlainObject(value) ? cloneObject(value) : value\n return acc\n },\n {}\n )\n\n return isPlainObject(obj)\n ? enumerableProperties\n : Object.assign(Object.getPrototypeOf(obj), enumerableProperties)\n}\n","import { urlToHttpOptions } from 'node:url'\nimport {\n Agent as HttpAgent,\n globalAgent as httpGlobalAgent,\n IncomingMessage,\n} from 'node:http'\nimport {\n RequestOptions,\n Agent as HttpsAgent,\n globalAgent as httpsGlobalAgent,\n} from 'node:https'\nimport {\n /**\n * @note Use the Node.js URL instead of the global URL\n * because environments like JSDOM may override the global,\n * breaking the compatibility with Node.js.\n * @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555\n */\n URL,\n Url as LegacyURL,\n parse as parseUrl,\n} from 'node:url'\nimport { Logger } from '@open-draft/logger'\nimport {\n ResolvedRequestOptions,\n getUrlByRequestOptions,\n} from '../../../utils/getUrlByRequestOptions'\nimport { cloneObject } from '../../../utils/cloneObject'\nimport { isObject } from '../../../utils/isObject'\n\nconst logger = new Logger('http normalizeClientRequestArgs')\n\nexport type HttpRequestCallback = (response: IncomingMessage) => void\n\nexport type ClientRequestArgs =\n // Request without any arguments is also possible.\n | []\n | [string | URL | LegacyURL, HttpRequestCallback?]\n | [string | URL | LegacyURL, RequestOptions, HttpRequestCallback?]\n | [RequestOptions, HttpRequestCallback?]\n\nfunction resolveRequestOptions(\n args: ClientRequestArgs,\n url: URL\n): RequestOptions {\n // Calling `fetch` provides only URL to `ClientRequest`\n // without any `RequestOptions` or callback.\n if (typeof args[1] === 'undefined' || typeof args[1] === 'function') {\n logger.info('request options not provided, deriving from the url', url)\n return urlToHttpOptions(url)\n }\n\n if (args[1]) {\n logger.info('has custom RequestOptions!', args[1])\n const requestOptionsFromUrl = urlToHttpOptions(url)\n\n logger.info('derived RequestOptions from the URL:', requestOptionsFromUrl)\n\n /**\n * Clone the request options to lock their state\n * at the moment they are provided to `ClientRequest`.\n * @see https://github.com/mswjs/interceptors/issues/86\n */\n logger.info('cloning RequestOptions...')\n const clonedRequestOptions = cloneObject(args[1])\n logger.info('successfully cloned RequestOptions!', clonedRequestOptions)\n\n return {\n ...requestOptionsFromUrl,\n ...clonedRequestOptions,\n }\n }\n\n logger.info('using an empty object as request options')\n return {} as RequestOptions\n}\n\n/**\n * Overrides the given `URL` instance with the explicit properties provided\n * on the `RequestOptions` object. The options object takes precedence,\n * and will replace URL properties like \"host\", \"path\", and \"port\", if specified.\n */\nfunction overrideUrlByRequestOptions(url: URL, options: RequestOptions): URL {\n url.host = options.host || url.host\n url.hostname = options.hostname || url.hostname\n url.port = options.port ? options.port.toString() : url.port\n\n if (options.path) {\n const parsedOptionsPath = parseUrl(options.path, false)\n url.pathname = parsedOptionsPath.pathname || ''\n url.search = parsedOptionsPath.search || ''\n }\n\n return url\n}\n\nfunction resolveCallback(\n args: ClientRequestArgs\n): HttpRequestCallback | undefined {\n return typeof args[1] === 'function' ? args[1] : args[2]\n}\n\nexport type NormalizedClientRequestArgs = [\n url: URL,\n options: ResolvedRequestOptions,\n callback?: HttpRequestCallback\n]\n\n/**\n * Normalizes parameters given to a `http.request` call\n * so it always has a `URL` and `RequestOptions`.\n */\nexport function normalizeClientRequestArgs(\n defaultProtocol: string,\n args: ClientRequestArgs\n): NormalizedClientRequestArgs {\n let url: URL\n let options: ResolvedRequestOptions\n let callback: HttpRequestCallback | undefined\n\n logger.info('arguments', args)\n logger.info('using default protocol:', defaultProtocol)\n\n // Support \"http.request()\" calls without any arguments.\n // That call results in a \"GET http://localhost\" request.\n if (args.length === 0) {\n const url = new URL('http://localhost')\n const options = resolveRequestOptions(args, url)\n return [url, options]\n }\n\n // Convert a url string into a URL instance\n // and derive request options from it.\n if (typeof args[0] === 'string') {\n logger.info('first argument is a location string:', args[0])\n\n url = new URL(args[0])\n logger.info('created a url:', url)\n\n const requestOptionsFromUrl = urlToHttpOptions(url)\n logger.info('request options from url:', requestOptionsFromUrl)\n\n options = resolveRequestOptions(args, url)\n logger.info('resolved request options:', options)\n\n callback = resolveCallback(args)\n }\n // Handle a given URL instance as-is\n // and derive request options from it.\n else if (args[0] instanceof URL) {\n url = args[0]\n logger.info('first argument is a URL:', url)\n\n // Check if the second provided argument is RequestOptions.\n // If it is, check if \"options.path\" was set and rewrite it\n // on the input URL.\n // Do this before resolving options from the URL below\n // to prevent query string from being duplicated in the path.\n if (typeof args[1] !== 'undefined' && isObject<RequestOptions>(args[1])) {\n url = overrideUrlByRequestOptions(url, args[1])\n }\n\n options = resolveRequestOptions(args, url)\n logger.info('derived request options:', options)\n\n callback = resolveCallback(args)\n }\n // Handle a legacy URL instance and re-normalize from either a RequestOptions object\n // or a WHATWG URL.\n else if ('hash' in args[0] && !('method' in args[0])) {\n const [legacyUrl] = args\n logger.info('first argument is a legacy URL:', legacyUrl)\n\n if (legacyUrl.hostname === null) {\n /**\n * We are dealing with a relative url, so use the path as an \"option\" and\n * merge in any existing options, giving priority to existing options -- i.e. a path in any\n * existing options will take precedence over the one contained in the url. This is consistent\n * with the behaviour in ClientRequest.\n * @see https://github.com/nodejs/node/blob/d84f1312915fe45fe0febe888db692c74894c382/lib/_http_client.js#L122\n */\n logger.info('given legacy URL is relative (no hostname)')\n\n return isObject(args[1])\n ? normalizeClientRequestArgs(defaultProtocol, [\n { path: legacyUrl.path, ...args[1] },\n args[2],\n ])\n : normalizeClientRequestArgs(defaultProtocol, [\n { path: legacyUrl.path },\n args[1] as HttpRequestCallback,\n ])\n }\n\n logger.info('given legacy url is absolute')\n\n // We are dealing with an absolute URL, so convert to WHATWG and try again.\n const resolvedUrl = new URL(legacyUrl.href)\n\n return args[1] === undefined\n ? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl])\n : typeof args[1] === 'function'\n ? normalizeClientRequestArgs(defaultProtocol, [resolvedUrl, args[1]])\n : normalizeClientRequestArgs(defaultProtocol, [\n resolvedUrl,\n args[1],\n args[2],\n ])\n }\n // Handle a given \"RequestOptions\" object as-is\n // and derive the URL instance from it.\n else if (isObject(args[0])) {\n options = { ...(args[0] as any) }\n logger.info('first argument is RequestOptions:', options)\n\n // When handling a \"RequestOptions\" object without an explicit \"protocol\",\n // infer the protocol from the request issuing module (http/https).\n options.protocol = options.protocol || defaultProtocol\n logger.info('normalized request options:', options)\n\n url = getUrlByRequestOptions(options)\n logger.info('created a URL from RequestOptions:', url.href)\n\n callback = resolveCallback(args)\n } else {\n throw new Error(\n `Failed to construct ClientRequest with these parameters: ${args}`\n )\n }\n\n options.protocol = options.protocol || url.protocol\n options.method = options.method || 'GET'\n\n /**\n * Ensure that the default Agent is always set.\n * This prevents the protocol mismatch for requests with { agent: false },\n * where the global Agent is inferred.\n * @see https://github.com/mswjs/msw/issues/1150\n * @see https://github.com/nodejs/node/blob/418ff70b810f0e7112d48baaa72932a56cfa213b/lib/_http_client.js#L130\n * @see https://github.com/nodejs/node/blob/418ff70b810f0e7112d48baaa72932a56cfa213b/lib/_http_client.js#L157-L159\n */\n if (!options._defaultAgent) {\n logger.info(\n 'has no default agent, setting the default agent for \"%s\"',\n options.protocol\n )\n\n options._defaultAgent =\n options.protocol === 'https:' ? httpsGlobalAgent : httpGlobalAgent\n }\n\n logger.info('successfully resolved url:', url.href)\n logger.info('successfully resolved options:', options)\n logger.info('successfully resolved callback:', callback)\n\n /**\n * @note If the user-provided URL is not a valid URL in Node.js,\n * (e.g. the one provided by the JSDOM polyfills), case it to\n * string. Otherwise, this throws on Node.js incompatibility\n * (`ERR_INVALID_ARG_TYPE` on the connection listener)\n * @see https://github.com/node-fetch/node-fetch/issues/1376#issuecomment-966435555\n */\n if (!(url instanceof URL)) {\n url = (url as any).toString()\n }\n\n return [url, options, callback]\n}\n","import http from 'node:http'\nimport https from 'node:https'\nimport { Interceptor } from '../../Interceptor'\nimport type { HttpRequestEventMap } from '../../glossary'\nimport {\n kRequestId,\n MockHttpSocketRequestCallback,\n MockHttpSocketResponseCallback,\n} from './MockHttpSocket'\nimport { MockAgent, MockHttpsAgent } from './agents'\nimport { RequestController } from '../../RequestController'\nimport { emitAsync } from '../../utils/emitAsync'\nimport { normalizeClientRequestArgs } from './utils/normalizeClientRequestArgs'\nimport { handleRequest } from '../../utils/handleRequest'\nimport {\n recordRawFetchHeaders,\n restoreHeadersPrototype,\n} from './utils/recordRawHeaders'\n\nexport class ClientRequestInterceptor extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('client-request-interceptor')\n\n constructor() {\n super(ClientRequestInterceptor.symbol)\n }\n\n protected setup(): void {\n const {\n ClientRequest: OriginalClientRequest,\n get: originalGet,\n request: originalRequest,\n } = http\n const { get: originalHttpsGet, request: originalHttpsRequest } = https\n\n const onRequest = this.onRequest.bind(this)\n const onResponse = this.onResponse.bind(this)\n\n // Support requests performed via the `ClientRequest` constructor directly.\n http.ClientRequest = new Proxy(http.ClientRequest, {\n construct: (target, args: Parameters<typeof http.request>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'http:',\n args\n )\n\n // Create a mock agent instance appropriate for the request protocol.\n const Agent = options.protocol === 'https:' ? MockHttpsAgent : MockAgent\n const mockAgent = new Agent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.construct(target, [url, options, callback])\n },\n })\n\n http.request = new Proxy(http.request, {\n apply: (target, thisArg, args: Parameters<typeof http.request>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'http:',\n args\n )\n const mockAgent = new MockAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n http.get = new Proxy(http.get, {\n apply: (target, thisArg, args: Parameters<typeof http.get>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'http:',\n args\n )\n\n const mockAgent = new MockAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n //\n // HTTPS.\n //\n\n https.request = new Proxy(https.request, {\n apply: (target, thisArg, args: Parameters<typeof https.request>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'https:',\n args\n )\n\n const mockAgent = new MockHttpsAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n https.get = new Proxy(https.get, {\n apply: (target, thisArg, args: Parameters<typeof https.get>) => {\n const [url, options, callback] = normalizeClientRequestArgs(\n 'https:',\n args\n )\n\n const mockAgent = new MockHttpsAgent({\n customAgent: options.agent,\n onRequest,\n onResponse,\n })\n options.agent = mockAgent\n\n return Reflect.apply(target, thisArg, [url, options, callback])\n },\n })\n\n // Spy on `Header.prototype.set` and `Header.prototype.append` calls\n // and record the raw header names provided. This is to support\n // `IncomingMessage.prototype.rawHeaders`.\n recordRawFetchHeaders()\n\n this.subscriptions.push(() => {\n http.ClientRequest = OriginalClientRequest\n\n http.get = originalGet\n http.request = originalRequest\n\n https.get = originalHttpsGet\n https.request = originalHttpsRequest\n\n restoreHeadersPrototype()\n })\n }\n\n private onRequest: MockHttpSocketRequestCallback = async ({\n request,\n socket,\n }) => {\n const controller = new RequestController(request, {\n passthrough() {\n socket.passthrough()\n },\n async respondWith(response) {\n await socket.respondWith(response)\n },\n errorWith(reason) {\n if (reason instanceof Error) {\n socket.errorWith(reason)\n }\n },\n })\n\n await handleRequest({\n request,\n requestId: Reflect.get(request, kRequestId),\n controller,\n emitter: this.emitter,\n })\n }\n\n public onResponse: MockHttpSocketResponseCallback = async ({\n requestId,\n request,\n response,\n isMockedResponse,\n }) => {\n // Return the promise to when all the response event listeners\n // are finished.\n return emitAsync(this.emitter, 'response', {\n requestId,\n request,\n response,\n isMockedResponse,\n })\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ import { Logger } from "@open-draft/logger";
2
+ import { Emitter, Listener } from "strict-event-emitter";
3
+
4
+ //#region src/RequestController.d.ts
5
+ interface RequestControllerSource {
6
+ passthrough(): void;
7
+ respondWith(response: Response): void;
8
+ errorWith(reason?: unknown): void;
9
+ }
10
+ declare class RequestController {
11
+ #private;
12
+ protected readonly request: Request;
13
+ protected readonly source: RequestControllerSource;
14
+ static PENDING: 0;
15
+ static PASSTHROUGH: 1;
16
+ static RESPONSE: 2;
17
+ static ERROR: 3;
18
+ readyState: number;
19
+ /**
20
+ * A Promise that resolves when this controller handles a request.
21
+ * See `controller.readyState` for more information on the handling result.
22
+ */
23
+ handled: Promise<void>;
24
+ constructor(request: Request, source: RequestControllerSource);
25
+ /**
26
+ * Perform this request as-is.
27
+ */
28
+ passthrough(): Promise<void>;
29
+ /**
30
+ * Respond to this request with the given `Response` instance.
31
+ *
32
+ * @example
33
+ * controller.respondWith(new Response())
34
+ * controller.respondWith(Response.json({ id }))
35
+ * controller.respondWith(Response.error())
36
+ */
37
+ respondWith(response: Response): void;
38
+ /**
39
+ * Error this request with the given reason.
40
+ *
41
+ * @example
42
+ * controller.errorWith()
43
+ * controller.errorWith(new Error('Oops!'))
44
+ * controller.errorWith({ message: 'Oops!'})
45
+ */
46
+ errorWith(reason?: unknown): void;
47
+ }
48
+ //#endregion
49
+ //#region src/glossary.d.ts
50
+ declare const IS_PATCHED_MODULE: unique symbol;
51
+ type RequestCredentials = 'omit' | 'include' | 'same-origin';
52
+ type HttpRequestEventMap = {
53
+ request: [args: {
54
+ request: Request;
55
+ requestId: string;
56
+ controller: RequestController;
57
+ }];
58
+ response: [args: {
59
+ response: Response;
60
+ isMockedResponse: boolean;
61
+ request: Request;
62
+ requestId: string;
63
+ }];
64
+ unhandledException: [args: {
65
+ error: unknown;
66
+ request: Request;
67
+ requestId: string;
68
+ controller: RequestController;
69
+ }];
70
+ };
71
+ //#endregion
72
+ //#region src/Interceptor.d.ts
73
+ type InterceptorEventMap = Record<string, any>;
74
+ type InterceptorSubscription = () => void;
75
+ /**
76
+ * Request header name to detect when a single request
77
+ * is being handled by nested interceptors (XHR -> ClientRequest).
78
+ * Obscure by design to prevent collisions with user-defined headers.
79
+ * Ideally, come up with the Interceptor-level mechanism for this.
80
+ * @see https://github.com/mswjs/interceptors/issues/378
81
+ */
82
+ declare const INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
83
+ declare function getGlobalSymbol<V>(symbol: Symbol): V | undefined;
84
+ declare function deleteGlobalSymbol(symbol: Symbol): void;
85
+ declare enum InterceptorReadyState {
86
+ INACTIVE = "INACTIVE",
87
+ APPLYING = "APPLYING",
88
+ APPLIED = "APPLIED",
89
+ DISPOSING = "DISPOSING",
90
+ DISPOSED = "DISPOSED",
91
+ }
92
+ type ExtractEventNames<Events extends Record<string, any>> = Events extends Record<infer EventName, any> ? EventName : never;
93
+ declare class Interceptor<Events extends InterceptorEventMap> {
94
+ private readonly symbol;
95
+ protected emitter: Emitter<Events>;
96
+ protected subscriptions: Array<InterceptorSubscription>;
97
+ protected logger: Logger;
98
+ readyState: InterceptorReadyState;
99
+ constructor(symbol: symbol);
100
+ /**
101
+ * Determine if this interceptor can be applied
102
+ * in the current environment.
103
+ */
104
+ protected checkEnvironment(): boolean;
105
+ /**
106
+ * Apply this interceptor to the current process.
107
+ * Returns an already running interceptor instance if it's present.
108
+ */
109
+ apply(): void;
110
+ /**
111
+ * Setup the module augments and stubs necessary for this interceptor.
112
+ * This method is not run if there's a running interceptor instance
113
+ * to prevent instantiating an interceptor multiple times.
114
+ */
115
+ protected setup(): void;
116
+ /**
117
+ * Listen to the interceptor's public events.
118
+ */
119
+ on<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
120
+ once<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
121
+ off<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
122
+ removeAllListeners<EventName extends ExtractEventNames<Events>>(event?: EventName): this;
123
+ /**
124
+ * Disposes of any side-effects this interceptor has introduced.
125
+ */
126
+ dispose(): void;
127
+ private getInstance;
128
+ private setInstance;
129
+ private clearInstance;
130
+ }
131
+ //#endregion
132
+ export { InterceptorReadyState as a, getGlobalSymbol as c, RequestCredentials as d, RequestController as f, InterceptorEventMap as i, HttpRequestEventMap as l, INTERNAL_REQUEST_ID_HEADER_NAME as n, InterceptorSubscription as o, RequestControllerSource as p, Interceptor as r, deleteGlobalSymbol as s, ExtractEventNames as t, IS_PATCHED_MODULE as u };
133
+ //# sourceMappingURL=Interceptor-DEazpLJd.d.mts.map
@@ -0,0 +1,133 @@
1
+ import { Logger } from "@open-draft/logger";
2
+ import { Emitter, Listener } from "strict-event-emitter";
3
+
4
+ //#region src/RequestController.d.ts
5
+ interface RequestControllerSource {
6
+ passthrough(): void;
7
+ respondWith(response: Response): void;
8
+ errorWith(reason?: unknown): void;
9
+ }
10
+ declare class RequestController {
11
+ #private;
12
+ protected readonly request: Request;
13
+ protected readonly source: RequestControllerSource;
14
+ static PENDING: 0;
15
+ static PASSTHROUGH: 1;
16
+ static RESPONSE: 2;
17
+ static ERROR: 3;
18
+ readyState: number;
19
+ /**
20
+ * A Promise that resolves when this controller handles a request.
21
+ * See `controller.readyState` for more information on the handling result.
22
+ */
23
+ handled: Promise<void>;
24
+ constructor(request: Request, source: RequestControllerSource);
25
+ /**
26
+ * Perform this request as-is.
27
+ */
28
+ passthrough(): Promise<void>;
29
+ /**
30
+ * Respond to this request with the given `Response` instance.
31
+ *
32
+ * @example
33
+ * controller.respondWith(new Response())
34
+ * controller.respondWith(Response.json({ id }))
35
+ * controller.respondWith(Response.error())
36
+ */
37
+ respondWith(response: Response): void;
38
+ /**
39
+ * Error this request with the given reason.
40
+ *
41
+ * @example
42
+ * controller.errorWith()
43
+ * controller.errorWith(new Error('Oops!'))
44
+ * controller.errorWith({ message: 'Oops!'})
45
+ */
46
+ errorWith(reason?: unknown): void;
47
+ }
48
+ //#endregion
49
+ //#region src/glossary.d.ts
50
+ declare const IS_PATCHED_MODULE: unique symbol;
51
+ type RequestCredentials = 'omit' | 'include' | 'same-origin';
52
+ type HttpRequestEventMap = {
53
+ request: [args: {
54
+ request: Request;
55
+ requestId: string;
56
+ controller: RequestController;
57
+ }];
58
+ response: [args: {
59
+ response: Response;
60
+ isMockedResponse: boolean;
61
+ request: Request;
62
+ requestId: string;
63
+ }];
64
+ unhandledException: [args: {
65
+ error: unknown;
66
+ request: Request;
67
+ requestId: string;
68
+ controller: RequestController;
69
+ }];
70
+ };
71
+ //#endregion
72
+ //#region src/Interceptor.d.ts
73
+ type InterceptorEventMap = Record<string, any>;
74
+ type InterceptorSubscription = () => void;
75
+ /**
76
+ * Request header name to detect when a single request
77
+ * is being handled by nested interceptors (XHR -> ClientRequest).
78
+ * Obscure by design to prevent collisions with user-defined headers.
79
+ * Ideally, come up with the Interceptor-level mechanism for this.
80
+ * @see https://github.com/mswjs/interceptors/issues/378
81
+ */
82
+ declare const INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id";
83
+ declare function getGlobalSymbol<V>(symbol: Symbol): V | undefined;
84
+ declare function deleteGlobalSymbol(symbol: Symbol): void;
85
+ declare enum InterceptorReadyState {
86
+ INACTIVE = "INACTIVE",
87
+ APPLYING = "APPLYING",
88
+ APPLIED = "APPLIED",
89
+ DISPOSING = "DISPOSING",
90
+ DISPOSED = "DISPOSED",
91
+ }
92
+ type ExtractEventNames<Events extends Record<string, any>> = Events extends Record<infer EventName, any> ? EventName : never;
93
+ declare class Interceptor<Events extends InterceptorEventMap> {
94
+ private readonly symbol;
95
+ protected emitter: Emitter<Events>;
96
+ protected subscriptions: Array<InterceptorSubscription>;
97
+ protected logger: Logger;
98
+ readyState: InterceptorReadyState;
99
+ constructor(symbol: symbol);
100
+ /**
101
+ * Determine if this interceptor can be applied
102
+ * in the current environment.
103
+ */
104
+ protected checkEnvironment(): boolean;
105
+ /**
106
+ * Apply this interceptor to the current process.
107
+ * Returns an already running interceptor instance if it's present.
108
+ */
109
+ apply(): void;
110
+ /**
111
+ * Setup the module augments and stubs necessary for this interceptor.
112
+ * This method is not run if there's a running interceptor instance
113
+ * to prevent instantiating an interceptor multiple times.
114
+ */
115
+ protected setup(): void;
116
+ /**
117
+ * Listen to the interceptor's public events.
118
+ */
119
+ on<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
120
+ once<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
121
+ off<EventName extends ExtractEventNames<Events>>(event: EventName, listener: Listener<Events[EventName]>): this;
122
+ removeAllListeners<EventName extends ExtractEventNames<Events>>(event?: EventName): this;
123
+ /**
124
+ * Disposes of any side-effects this interceptor has introduced.
125
+ */
126
+ dispose(): void;
127
+ private getInstance;
128
+ private setInstance;
129
+ private clearInstance;
130
+ }
131
+ //#endregion
132
+ export { InterceptorReadyState as a, getGlobalSymbol as c, RequestCredentials as d, RequestController as f, InterceptorEventMap as i, HttpRequestEventMap as l, INTERNAL_REQUEST_ID_HEADER_NAME as n, InterceptorSubscription as o, RequestControllerSource as p, Interceptor as r, deleteGlobalSymbol as s, ExtractEventNames as t, IS_PATCHED_MODULE as u };
133
+ //# sourceMappingURL=Interceptor-DJ2akVWI.d.cts.map
@@ -0,0 +1,154 @@
1
+ const require_fetchUtils = require('./fetchUtils-BaY5iWXw.cjs');
2
+ const require_BatchInterceptor = require('./BatchInterceptor-3LnAnLTx.cjs');
3
+ require('./bufferUtils-DiCTqG-7.cjs');
4
+ const require_ClientRequest = require('./ClientRequest-2rDe54Ui.cjs');
5
+ const require_handleRequest = require('./handleRequest-Bb7Y-XLw.cjs');
6
+ require('./node-dKdAf3tC.cjs');
7
+ const require_XMLHttpRequest = require('./XMLHttpRequest-B7kJdYYI.cjs');
8
+ const require_fetch = require('./fetch-BmXpK10r.cjs');
9
+
10
+ //#region src/RemoteHttpInterceptor.ts
11
+ var RemoteHttpInterceptor = class extends require_BatchInterceptor.BatchInterceptor {
12
+ constructor() {
13
+ super({
14
+ name: "remote-interceptor",
15
+ interceptors: [
16
+ new require_ClientRequest.ClientRequestInterceptor(),
17
+ new require_XMLHttpRequest.XMLHttpRequestInterceptor(),
18
+ new require_fetch.FetchInterceptor()
19
+ ]
20
+ });
21
+ }
22
+ setup() {
23
+ super.setup();
24
+ let handleParentMessage;
25
+ this.on("request", async ({ request, requestId, controller }) => {
26
+ const serializedRequest = JSON.stringify({
27
+ id: requestId,
28
+ method: request.method,
29
+ url: request.url,
30
+ headers: Array.from(request.headers.entries()),
31
+ credentials: request.credentials,
32
+ body: ["GET", "HEAD"].includes(request.method) ? null : await request.text()
33
+ });
34
+ this.logger.info("sent serialized request to the child:", serializedRequest);
35
+ process.send?.(`request:${serializedRequest}`);
36
+ const responsePromise = new Promise((resolve) => {
37
+ handleParentMessage = (message) => {
38
+ if (typeof message !== "string") return resolve();
39
+ if (message.startsWith(`response:${requestId}`)) {
40
+ const [, serializedResponse] = message.match(/^response:.+?:(.+)$/) || [];
41
+ if (!serializedResponse) return resolve();
42
+ const responseInit = JSON.parse(serializedResponse);
43
+ const mockedResponse = new require_fetchUtils.FetchResponse(responseInit.body, {
44
+ url: request.url,
45
+ status: responseInit.status,
46
+ statusText: responseInit.statusText,
47
+ headers: responseInit.headers
48
+ });
49
+ /**
50
+ * @todo Support "errorWith" as well.
51
+ * This response handling from the child is incomplete.
52
+ */
53
+ controller.respondWith(mockedResponse);
54
+ return resolve();
55
+ }
56
+ };
57
+ });
58
+ this.logger.info("add \"message\" listener to the parent process", handleParentMessage);
59
+ process.addListener("message", handleParentMessage);
60
+ return responsePromise;
61
+ });
62
+ this.subscriptions.push(() => {
63
+ process.removeListener("message", handleParentMessage);
64
+ });
65
+ }
66
+ };
67
+ function requestReviver(key, value) {
68
+ switch (key) {
69
+ case "url": return new URL(value);
70
+ case "headers": return new Headers(value);
71
+ default: return value;
72
+ }
73
+ }
74
+ var RemoteHttpResolver = class RemoteHttpResolver extends require_fetchUtils.Interceptor {
75
+ static {
76
+ this.symbol = Symbol("remote-resolver");
77
+ }
78
+ constructor(options) {
79
+ super(RemoteHttpResolver.symbol);
80
+ this.process = options.process;
81
+ }
82
+ setup() {
83
+ const logger = this.logger.extend("setup");
84
+ const handleChildMessage = async (message) => {
85
+ logger.info("received message from child!", message);
86
+ if (typeof message !== "string" || !message.startsWith("request:")) {
87
+ logger.info("unknown message, ignoring...");
88
+ return;
89
+ }
90
+ const [, serializedRequest] = message.match(/^request:(.+)$/) || [];
91
+ if (!serializedRequest) return;
92
+ const requestJson = JSON.parse(serializedRequest, requestReviver);
93
+ logger.info("parsed intercepted request", requestJson);
94
+ const request = new Request(requestJson.url, {
95
+ method: requestJson.method,
96
+ headers: new Headers(requestJson.headers),
97
+ credentials: requestJson.credentials,
98
+ body: requestJson.body
99
+ });
100
+ const controller = new require_fetchUtils.RequestController(request, {
101
+ passthrough: () => {},
102
+ respondWith: async (response) => {
103
+ if (require_handleRequest.isResponseError(response)) {
104
+ this.logger.info("received a network error!", { response });
105
+ throw new Error("Not implemented");
106
+ }
107
+ this.logger.info("received mocked response!", { response });
108
+ const responseClone = response.clone();
109
+ const responseText = await responseClone.text();
110
+ const serializedResponse = JSON.stringify({
111
+ status: response.status,
112
+ statusText: response.statusText,
113
+ headers: Array.from(response.headers.entries()),
114
+ body: responseText
115
+ });
116
+ this.process.send(`response:${requestJson.id}:${serializedResponse}`, (error) => {
117
+ if (error) return;
118
+ this.emitter.emit("response", {
119
+ request,
120
+ requestId: requestJson.id,
121
+ response: responseClone,
122
+ isMockedResponse: true
123
+ });
124
+ });
125
+ logger.info("sent serialized mocked response to the parent:", serializedResponse);
126
+ },
127
+ errorWith: (reason) => {
128
+ this.logger.info("request has errored!", { error: reason });
129
+ throw new Error("Not implemented");
130
+ }
131
+ });
132
+ await require_handleRequest.handleRequest({
133
+ request,
134
+ requestId: requestJson.id,
135
+ controller,
136
+ emitter: this.emitter
137
+ });
138
+ };
139
+ this.subscriptions.push(() => {
140
+ this.process.removeListener("message", handleChildMessage);
141
+ logger.info("removed the \"message\" listener from the child process!");
142
+ });
143
+ logger.info("adding a \"message\" listener to the child process");
144
+ this.process.addListener("message", handleChildMessage);
145
+ this.process.once("error", () => this.dispose());
146
+ this.process.once("exit", () => this.dispose());
147
+ }
148
+ };
149
+
150
+ //#endregion
151
+ exports.RemoteHttpInterceptor = RemoteHttpInterceptor;
152
+ exports.RemoteHttpResolver = RemoteHttpResolver;
153
+ exports.requestReviver = requestReviver;
154
+ //# sourceMappingURL=RemoteHttpInterceptor.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RemoteHttpInterceptor.cjs","names":["BatchInterceptor","ClientRequestInterceptor","XMLHttpRequestInterceptor","FetchInterceptor","handleParentMessage: NodeJS.MessageListener","FetchResponse","Interceptor","handleChildMessage: NodeJS.MessageListener","RequestController","isResponseError","handleRequest"],"sources":["../../src/RemoteHttpInterceptor.ts"],"sourcesContent":["import { ChildProcess } from 'child_process'\nimport { HttpRequestEventMap } from './glossary'\nimport { Interceptor } from './Interceptor'\nimport { BatchInterceptor } from './BatchInterceptor'\nimport { ClientRequestInterceptor } from './interceptors/ClientRequest'\nimport { XMLHttpRequestInterceptor } from './interceptors/XMLHttpRequest'\nimport { FetchInterceptor } from './interceptors/fetch'\nimport { handleRequest } from './utils/handleRequest'\nimport { RequestController } from './RequestController'\nimport { FetchResponse } from './utils/fetchUtils'\nimport { isResponseError } from './utils/responseUtils'\n\nexport interface SerializedRequest {\n id: string\n url: string\n method: string\n headers: Array<[string, string]>\n credentials: RequestCredentials\n body: string\n}\n\ninterface RevivedRequest extends Omit<SerializedRequest, 'url' | 'headers'> {\n url: URL\n headers: Headers\n}\n\nexport interface SerializedResponse {\n status: number\n statusText: string\n headers: Array<[string, string]>\n body: string\n}\n\nexport class RemoteHttpInterceptor extends BatchInterceptor<\n [ClientRequestInterceptor, XMLHttpRequestInterceptor, FetchInterceptor]\n> {\n constructor() {\n super({\n name: 'remote-interceptor',\n interceptors: [\n new ClientRequestInterceptor(),\n new XMLHttpRequestInterceptor(),\n new FetchInterceptor(),\n ],\n })\n }\n\n protected setup() {\n super.setup()\n\n let handleParentMessage: NodeJS.MessageListener\n\n this.on('request', async ({ request, requestId, controller }) => {\n // Send the stringified intercepted request to\n // the parent process where the remote resolver is established.\n const serializedRequest = JSON.stringify({\n id: requestId,\n method: request.method,\n url: request.url,\n headers: Array.from(request.headers.entries()),\n credentials: request.credentials,\n body: ['GET', 'HEAD'].includes(request.method)\n ? null\n : await request.text(),\n } as SerializedRequest)\n\n this.logger.info(\n 'sent serialized request to the child:',\n serializedRequest\n )\n\n process.send?.(`request:${serializedRequest}`)\n\n const responsePromise = new Promise<void>((resolve) => {\n handleParentMessage = (message) => {\n if (typeof message !== 'string') {\n return resolve()\n }\n\n if (message.startsWith(`response:${requestId}`)) {\n const [, serializedResponse] =\n message.match(/^response:.+?:(.+)$/) || []\n\n if (!serializedResponse) {\n return resolve()\n }\n\n const responseInit = JSON.parse(\n serializedResponse\n ) as SerializedResponse\n\n const mockedResponse = new FetchResponse(responseInit.body, {\n url: request.url,\n status: responseInit.status,\n statusText: responseInit.statusText,\n headers: responseInit.headers,\n })\n\n /**\n * @todo Support \"errorWith\" as well.\n * This response handling from the child is incomplete.\n */\n\n controller.respondWith(mockedResponse)\n return resolve()\n }\n }\n })\n\n // Listen for the mocked response message from the parent.\n this.logger.info(\n 'add \"message\" listener to the parent process',\n handleParentMessage\n )\n process.addListener('message', handleParentMessage)\n\n return responsePromise\n })\n\n this.subscriptions.push(() => {\n process.removeListener('message', handleParentMessage)\n })\n }\n}\n\nexport function requestReviver(key: string, value: any) {\n switch (key) {\n case 'url':\n return new URL(value)\n\n case 'headers':\n return new Headers(value)\n\n default:\n return value\n }\n}\n\nexport interface RemoveResolverOptions {\n process: ChildProcess\n}\n\nexport class RemoteHttpResolver extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol('remote-resolver')\n private process: ChildProcess\n\n constructor(options: RemoveResolverOptions) {\n super(RemoteHttpResolver.symbol)\n this.process = options.process\n }\n\n protected setup() {\n const logger = this.logger.extend('setup')\n\n const handleChildMessage: NodeJS.MessageListener = async (message) => {\n logger.info('received message from child!', message)\n\n if (typeof message !== 'string' || !message.startsWith('request:')) {\n logger.info('unknown message, ignoring...')\n return\n }\n\n const [, serializedRequest] = message.match(/^request:(.+)$/) || []\n if (!serializedRequest) {\n return\n }\n\n const requestJson = JSON.parse(\n serializedRequest,\n requestReviver\n ) as RevivedRequest\n\n logger.info('parsed intercepted request', requestJson)\n\n const request = new Request(requestJson.url, {\n method: requestJson.method,\n headers: new Headers(requestJson.headers),\n credentials: requestJson.credentials,\n body: requestJson.body,\n })\n\n const controller = new RequestController(request, {\n passthrough: () => {},\n respondWith: async (response) => {\n if (isResponseError(response)) {\n this.logger.info('received a network error!', { response })\n throw new Error('Not implemented')\n }\n\n this.logger.info('received mocked response!', { response })\n\n const responseClone = response.clone()\n const responseText = await responseClone.text()\n\n // // Send the mocked response to the child process.\n const serializedResponse = JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n body: responseText,\n } as SerializedResponse)\n\n this.process.send(\n `response:${requestJson.id}:${serializedResponse}`,\n (error) => {\n if (error) {\n return\n }\n\n // Emit an optimistic \"response\" event at this point,\n // not to rely on the back-and-forth signaling for the sake of the event.\n this.emitter.emit('response', {\n request,\n requestId: requestJson.id,\n response: responseClone,\n isMockedResponse: true,\n })\n }\n )\n\n logger.info(\n 'sent serialized mocked response to the parent:',\n serializedResponse\n )\n },\n errorWith: (reason) => {\n this.logger.info('request has errored!', { error: reason })\n throw new Error('Not implemented')\n },\n })\n\n await handleRequest({\n request,\n requestId: requestJson.id,\n controller,\n emitter: this.emitter,\n })\n }\n\n this.subscriptions.push(() => {\n this.process.removeListener('message', handleChildMessage)\n logger.info('removed the \"message\" listener from the child process!')\n })\n\n logger.info('adding a \"message\" listener to the child process')\n this.process.addListener('message', handleChildMessage)\n\n this.process.once('error', () => this.dispose())\n this.process.once('exit', () => this.dispose())\n }\n}\n"],"mappings":"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"}