monitor-transfer-dsh 0.0.0-stage → 0.1.2

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 (367) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +51 -2
  3. package/cordis.patch.yml +4 -0
  4. package/lib/client.js +381 -0
  5. package/lib/index.js +267 -0
  6. package/package.json +67 -3
  7. package/skill/SKILL.md +48 -0
  8. package/skill/tools/node_modules/.package-lock.json +163 -0
  9. package/skill/tools/node_modules/pg/LICENSE +21 -0
  10. package/skill/tools/node_modules/pg/README.md +96 -0
  11. package/skill/tools/node_modules/pg/esm/index.mjs +20 -0
  12. package/skill/tools/node_modules/pg/lib/client.js +846 -0
  13. package/skill/tools/node_modules/pg/lib/connection-parameters.js +184 -0
  14. package/skill/tools/node_modules/pg/lib/connection.js +250 -0
  15. package/skill/tools/node_modules/pg/lib/crypto/cert-signatures.js +122 -0
  16. package/skill/tools/node_modules/pg/lib/crypto/sasl.js +262 -0
  17. package/skill/tools/node_modules/pg/lib/crypto/utils.js +89 -0
  18. package/skill/tools/node_modules/pg/lib/defaults.js +94 -0
  19. package/skill/tools/node_modules/pg/lib/index.js +73 -0
  20. package/skill/tools/node_modules/pg/lib/native/client.js +428 -0
  21. package/skill/tools/node_modules/pg/lib/native/index.js +2 -0
  22. package/skill/tools/node_modules/pg/lib/native/query.js +167 -0
  23. package/skill/tools/node_modules/pg/lib/query.js +263 -0
  24. package/skill/tools/node_modules/pg/lib/result.js +109 -0
  25. package/skill/tools/node_modules/pg/lib/stream.js +83 -0
  26. package/skill/tools/node_modules/pg/lib/type-overrides.js +35 -0
  27. package/skill/tools/node_modules/pg/lib/utils.js +225 -0
  28. package/skill/tools/node_modules/pg/package.json +76 -0
  29. package/skill/tools/node_modules/pg-cloudflare/LICENSE +21 -0
  30. package/skill/tools/node_modules/pg-cloudflare/README.md +112 -0
  31. package/skill/tools/node_modules/pg-cloudflare/dist/empty.d.ts +2 -0
  32. package/skill/tools/node_modules/pg-cloudflare/dist/empty.js +6 -0
  33. package/skill/tools/node_modules/pg-cloudflare/dist/empty.js.map +1 -0
  34. package/skill/tools/node_modules/pg-cloudflare/dist/index.d.ts +29 -0
  35. package/skill/tools/node_modules/pg-cloudflare/dist/index.js +171 -0
  36. package/skill/tools/node_modules/pg-cloudflare/dist/index.js.map +1 -0
  37. package/skill/tools/node_modules/pg-cloudflare/esm/index.mjs +3 -0
  38. package/skill/tools/node_modules/pg-cloudflare/package.json +39 -0
  39. package/skill/tools/node_modules/pg-cloudflare/src/empty.ts +3 -0
  40. package/skill/tools/node_modules/pg-cloudflare/src/index.ts +187 -0
  41. package/skill/tools/node_modules/pg-cloudflare/src/types.d.ts +25 -0
  42. package/skill/tools/node_modules/pg-connection-string/LICENSE +21 -0
  43. package/skill/tools/node_modules/pg-connection-string/README.md +105 -0
  44. package/skill/tools/node_modules/pg-connection-string/esm/index.mjs +8 -0
  45. package/skill/tools/node_modules/pg-connection-string/index.d.ts +37 -0
  46. package/skill/tools/node_modules/pg-connection-string/index.js +237 -0
  47. package/skill/tools/node_modules/pg-connection-string/package.json +51 -0
  48. package/skill/tools/node_modules/pg-int8/LICENSE +13 -0
  49. package/skill/tools/node_modules/pg-int8/README.md +16 -0
  50. package/skill/tools/node_modules/pg-int8/index.js +100 -0
  51. package/skill/tools/node_modules/pg-int8/package.json +24 -0
  52. package/skill/tools/node_modules/pg-pool/LICENSE +21 -0
  53. package/skill/tools/node_modules/pg-pool/README.md +357 -0
  54. package/skill/tools/node_modules/pg-pool/esm/index.mjs +5 -0
  55. package/skill/tools/node_modules/pg-pool/index.js +517 -0
  56. package/skill/tools/node_modules/pg-pool/package.json +51 -0
  57. package/skill/tools/node_modules/pg-protocol/LICENSE +21 -0
  58. package/skill/tools/node_modules/pg-protocol/README.md +3 -0
  59. package/skill/tools/node_modules/pg-protocol/dist/b.d.ts +1 -0
  60. package/skill/tools/node_modules/pg-protocol/dist/b.js +23 -0
  61. package/skill/tools/node_modules/pg-protocol/dist/b.js.map +1 -0
  62. package/skill/tools/node_modules/pg-protocol/dist/buffer-reader.d.ts +14 -0
  63. package/skill/tools/node_modules/pg-protocol/dist/buffer-reader.js +55 -0
  64. package/skill/tools/node_modules/pg-protocol/dist/buffer-reader.js.map +1 -0
  65. package/skill/tools/node_modules/pg-protocol/dist/buffer-writer.d.ts +21 -0
  66. package/skill/tools/node_modules/pg-protocol/dist/buffer-writer.js +113 -0
  67. package/skill/tools/node_modules/pg-protocol/dist/buffer-writer.js.map +1 -0
  68. package/skill/tools/node_modules/pg-protocol/dist/inbound-parser.test.d.ts +1 -0
  69. package/skill/tools/node_modules/pg-protocol/dist/inbound-parser.test.js +538 -0
  70. package/skill/tools/node_modules/pg-protocol/dist/inbound-parser.test.js.map +1 -0
  71. package/skill/tools/node_modules/pg-protocol/dist/index.d.ts +5 -0
  72. package/skill/tools/node_modules/pg-protocol/dist/index.js +15 -0
  73. package/skill/tools/node_modules/pg-protocol/dist/index.js.map +1 -0
  74. package/skill/tools/node_modules/pg-protocol/dist/messages.d.ts +161 -0
  75. package/skill/tools/node_modules/pg-protocol/dist/messages.js +160 -0
  76. package/skill/tools/node_modules/pg-protocol/dist/messages.js.map +1 -0
  77. package/skill/tools/node_modules/pg-protocol/dist/outbound-serializer.test.d.ts +1 -0
  78. package/skill/tools/node_modules/pg-protocol/dist/outbound-serializer.test.js +325 -0
  79. package/skill/tools/node_modules/pg-protocol/dist/outbound-serializer.test.js.map +1 -0
  80. package/skill/tools/node_modules/pg-protocol/dist/parser.d.ts +22 -0
  81. package/skill/tools/node_modules/pg-protocol/dist/parser.js +325 -0
  82. package/skill/tools/node_modules/pg-protocol/dist/parser.js.map +1 -0
  83. package/skill/tools/node_modules/pg-protocol/dist/serializer.d.ts +42 -0
  84. package/skill/tools/node_modules/pg-protocol/dist/serializer.js +198 -0
  85. package/skill/tools/node_modules/pg-protocol/dist/serializer.js.map +1 -0
  86. package/skill/tools/node_modules/pg-protocol/esm/index.js +11 -0
  87. package/skill/tools/node_modules/pg-protocol/package.json +44 -0
  88. package/skill/tools/node_modules/pg-protocol/src/b.ts +25 -0
  89. package/skill/tools/node_modules/pg-protocol/src/buffer-reader.ts +58 -0
  90. package/skill/tools/node_modules/pg-protocol/src/buffer-writer.ts +120 -0
  91. package/skill/tools/node_modules/pg-protocol/src/inbound-parser.test.ts +585 -0
  92. package/skill/tools/node_modules/pg-protocol/src/index.ts +11 -0
  93. package/skill/tools/node_modules/pg-protocol/src/messages.ts +262 -0
  94. package/skill/tools/node_modules/pg-protocol/src/outbound-serializer.test.ts +356 -0
  95. package/skill/tools/node_modules/pg-protocol/src/parser.ts +414 -0
  96. package/skill/tools/node_modules/pg-protocol/src/serializer.ts +286 -0
  97. package/skill/tools/node_modules/pg-protocol/src/testing/buffer-list.ts +67 -0
  98. package/skill/tools/node_modules/pg-protocol/src/testing/test-buffers.ts +166 -0
  99. package/skill/tools/node_modules/pg-types/.travis.yml +7 -0
  100. package/skill/tools/node_modules/pg-types/Makefile +14 -0
  101. package/skill/tools/node_modules/pg-types/README.md +75 -0
  102. package/skill/tools/node_modules/pg-types/index.d.ts +137 -0
  103. package/skill/tools/node_modules/pg-types/index.js +47 -0
  104. package/skill/tools/node_modules/pg-types/index.test-d.ts +21 -0
  105. package/skill/tools/node_modules/pg-types/lib/arrayParser.js +11 -0
  106. package/skill/tools/node_modules/pg-types/lib/binaryParsers.js +257 -0
  107. package/skill/tools/node_modules/pg-types/lib/builtins.js +73 -0
  108. package/skill/tools/node_modules/pg-types/lib/textParsers.js +215 -0
  109. package/skill/tools/node_modules/pg-types/package.json +42 -0
  110. package/skill/tools/node_modules/pg-types/test/index.js +24 -0
  111. package/skill/tools/node_modules/pg-types/test/types.js +597 -0
  112. package/skill/tools/node_modules/pgpass/README.md +74 -0
  113. package/skill/tools/node_modules/pgpass/lib/helper.js +233 -0
  114. package/skill/tools/node_modules/pgpass/lib/index.js +23 -0
  115. package/skill/tools/node_modules/pgpass/package.json +41 -0
  116. package/skill/tools/node_modules/postgres-array/index.d.ts +4 -0
  117. package/skill/tools/node_modules/postgres-array/index.js +97 -0
  118. package/skill/tools/node_modules/postgres-array/license +21 -0
  119. package/skill/tools/node_modules/postgres-array/package.json +35 -0
  120. package/skill/tools/node_modules/postgres-array/readme.md +43 -0
  121. package/skill/tools/node_modules/postgres-bytea/index.js +33 -0
  122. package/skill/tools/node_modules/postgres-bytea/license +21 -0
  123. package/skill/tools/node_modules/postgres-bytea/package.json +34 -0
  124. package/skill/tools/node_modules/postgres-bytea/readme.md +34 -0
  125. package/skill/tools/node_modules/postgres-date/index.js +116 -0
  126. package/skill/tools/node_modules/postgres-date/license +21 -0
  127. package/skill/tools/node_modules/postgres-date/package.json +33 -0
  128. package/skill/tools/node_modules/postgres-date/readme.md +49 -0
  129. package/skill/tools/node_modules/postgres-interval/index.d.ts +20 -0
  130. package/skill/tools/node_modules/postgres-interval/index.js +125 -0
  131. package/skill/tools/node_modules/postgres-interval/license +21 -0
  132. package/skill/tools/node_modules/postgres-interval/package.json +36 -0
  133. package/skill/tools/node_modules/postgres-interval/readme.md +48 -0
  134. package/skill/tools/node_modules/split2/LICENSE +13 -0
  135. package/skill/tools/node_modules/split2/README.md +85 -0
  136. package/skill/tools/node_modules/split2/bench.js +27 -0
  137. package/skill/tools/node_modules/split2/index.js +141 -0
  138. package/skill/tools/node_modules/split2/package.json +39 -0
  139. package/skill/tools/node_modules/split2/test.js +409 -0
  140. package/skill/tools/node_modules/undici/LICENSE +21 -0
  141. package/skill/tools/node_modules/undici/README.md +828 -0
  142. package/skill/tools/node_modules/undici/docs/docs/api/Agent.md +291 -0
  143. package/skill/tools/node_modules/undici/docs/docs/api/BalancedPool.md +297 -0
  144. package/skill/tools/node_modules/undici/docs/docs/api/CacheStorage.md +188 -0
  145. package/skill/tools/node_modules/undici/docs/docs/api/CacheStore.md +375 -0
  146. package/skill/tools/node_modules/undici/docs/docs/api/Client.md +538 -0
  147. package/skill/tools/node_modules/undici/docs/docs/api/ClientStats.md +93 -0
  148. package/skill/tools/node_modules/undici/docs/docs/api/Connector.md +198 -0
  149. package/skill/tools/node_modules/undici/docs/docs/api/ContentType.md +97 -0
  150. package/skill/tools/node_modules/undici/docs/docs/api/Cookies.md +179 -0
  151. package/skill/tools/node_modules/undici/docs/docs/api/Debug.md +78 -0
  152. package/skill/tools/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +518 -0
  153. package/skill/tools/node_modules/undici/docs/docs/api/Dispatcher.md +842 -0
  154. package/skill/tools/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +171 -0
  155. package/skill/tools/node_modules/undici/docs/docs/api/Errors.md +624 -0
  156. package/skill/tools/node_modules/undici/docs/docs/api/EventSource.md +358 -0
  157. package/skill/tools/node_modules/undici/docs/docs/api/Fetch.md +721 -0
  158. package/skill/tools/node_modules/undici/docs/docs/api/GlobalInstallation.md +121 -0
  159. package/skill/tools/node_modules/undici/docs/docs/api/H2CClient.md +386 -0
  160. package/skill/tools/node_modules/undici/docs/docs/api/Interceptors.md +439 -0
  161. package/skill/tools/node_modules/undici/docs/docs/api/MockAgent.md +622 -0
  162. package/skill/tools/node_modules/undici/docs/docs/api/MockCallHistory.md +371 -0
  163. package/skill/tools/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +206 -0
  164. package/skill/tools/node_modules/undici/docs/docs/api/MockClient.md +199 -0
  165. package/skill/tools/node_modules/undici/docs/docs/api/MockErrors.md +63 -0
  166. package/skill/tools/node_modules/undici/docs/docs/api/MockPool.md +618 -0
  167. package/skill/tools/node_modules/undici/docs/docs/api/Pool.md +278 -0
  168. package/skill/tools/node_modules/undici/docs/docs/api/PoolStats.md +141 -0
  169. package/skill/tools/node_modules/undici/docs/docs/api/ProxyAgent.md +248 -0
  170. package/skill/tools/node_modules/undici/docs/docs/api/RedirectHandler.md +279 -0
  171. package/skill/tools/node_modules/undici/docs/docs/api/RetryAgent.md +136 -0
  172. package/skill/tools/node_modules/undici/docs/docs/api/RetryHandler.md +200 -0
  173. package/skill/tools/node_modules/undici/docs/docs/api/RoundRobinPool.md +239 -0
  174. package/skill/tools/node_modules/undici/docs/docs/api/SnapshotAgent.md +361 -0
  175. package/skill/tools/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +256 -0
  176. package/skill/tools/node_modules/undici/docs/docs/api/Util.md +82 -0
  177. package/skill/tools/node_modules/undici/docs/docs/api/WebSocket.md +536 -0
  178. package/skill/tools/node_modules/undici/docs/docs/api/api-lifecycle.md +159 -0
  179. package/skill/tools/node_modules/undici/docs/docs/best-practices/client-certificate.md +66 -0
  180. package/skill/tools/node_modules/undici/docs/docs/best-practices/crawling.md +60 -0
  181. package/skill/tools/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +233 -0
  182. package/skill/tools/node_modules/undici/docs/docs/best-practices/mocking-request.md +192 -0
  183. package/skill/tools/node_modules/undici/docs/docs/best-practices/proxy.md +129 -0
  184. package/skill/tools/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +226 -0
  185. package/skill/tools/node_modules/undici/docs/docs/best-practices/writing-tests.md +65 -0
  186. package/skill/tools/node_modules/undici/docs/docs/getting-started.md +281 -0
  187. package/skill/tools/node_modules/undici/docs/docs/index.md +793 -0
  188. package/skill/tools/node_modules/undici/docs/docs/site.json +125 -0
  189. package/skill/tools/node_modules/undici/docs/docs/type-map.json +79 -0
  190. package/skill/tools/node_modules/undici/index-fetch.js +65 -0
  191. package/skill/tools/node_modules/undici/index.d.ts +3 -0
  192. package/skill/tools/node_modules/undici/index.js +236 -0
  193. package/skill/tools/node_modules/undici/lib/api/abort-signal.js +59 -0
  194. package/skill/tools/node_modules/undici/lib/api/api-connect.js +112 -0
  195. package/skill/tools/node_modules/undici/lib/api/api-pipeline.js +265 -0
  196. package/skill/tools/node_modules/undici/lib/api/api-request.js +244 -0
  197. package/skill/tools/node_modules/undici/lib/api/api-stream.js +270 -0
  198. package/skill/tools/node_modules/undici/lib/api/api-upgrade.js +121 -0
  199. package/skill/tools/node_modules/undici/lib/api/index.js +7 -0
  200. package/skill/tools/node_modules/undici/lib/api/readable.js +615 -0
  201. package/skill/tools/node_modules/undici/lib/cache/memory-cache-store.js +314 -0
  202. package/skill/tools/node_modules/undici/lib/cache/sqlite-cache-store.js +593 -0
  203. package/skill/tools/node_modules/undici/lib/core/connect.js +198 -0
  204. package/skill/tools/node_modules/undici/lib/core/constants.js +131 -0
  205. package/skill/tools/node_modules/undici/lib/core/diagnostics.js +227 -0
  206. package/skill/tools/node_modules/undici/lib/core/errors.js +534 -0
  207. package/skill/tools/node_modules/undici/lib/core/request.js +582 -0
  208. package/skill/tools/node_modules/undici/lib/core/socks5-client.js +422 -0
  209. package/skill/tools/node_modules/undici/lib/core/socks5-utils.js +212 -0
  210. package/skill/tools/node_modules/undici/lib/core/symbols.js +81 -0
  211. package/skill/tools/node_modules/undici/lib/core/tree.js +160 -0
  212. package/skill/tools/node_modules/undici/lib/core/util.js +1035 -0
  213. package/skill/tools/node_modules/undici/lib/dispatcher/agent.js +181 -0
  214. package/skill/tools/node_modules/undici/lib/dispatcher/balanced-pool.js +217 -0
  215. package/skill/tools/node_modules/undici/lib/dispatcher/client-h1.js +1846 -0
  216. package/skill/tools/node_modules/undici/lib/dispatcher/client-h2.js +1989 -0
  217. package/skill/tools/node_modules/undici/lib/dispatcher/client.js +749 -0
  218. package/skill/tools/node_modules/undici/lib/dispatcher/dispatcher-base.js +198 -0
  219. package/skill/tools/node_modules/undici/lib/dispatcher/dispatcher.js +58 -0
  220. package/skill/tools/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +127 -0
  221. package/skill/tools/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +190 -0
  222. package/skill/tools/node_modules/undici/lib/dispatcher/fixed-queue.js +135 -0
  223. package/skill/tools/node_modules/undici/lib/dispatcher/h2c-client.js +51 -0
  224. package/skill/tools/node_modules/undici/lib/dispatcher/parser-h1.js +1065 -0
  225. package/skill/tools/node_modules/undici/lib/dispatcher/pool-base.js +347 -0
  226. package/skill/tools/node_modules/undici/lib/dispatcher/pool.js +229 -0
  227. package/skill/tools/node_modules/undici/lib/dispatcher/proxy-agent.js +418 -0
  228. package/skill/tools/node_modules/undici/lib/dispatcher/retry-agent.js +48 -0
  229. package/skill/tools/node_modules/undici/lib/dispatcher/round-robin-pool.js +169 -0
  230. package/skill/tools/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +350 -0
  231. package/skill/tools/node_modules/undici/lib/encoding/index.js +33 -0
  232. package/skill/tools/node_modules/undici/lib/global.js +82 -0
  233. package/skill/tools/node_modules/undici/lib/handler/cache-handler.js +1222 -0
  234. package/skill/tools/node_modules/undici/lib/handler/cache-revalidation-handler.js +134 -0
  235. package/skill/tools/node_modules/undici/lib/handler/decorator-handler.js +76 -0
  236. package/skill/tools/node_modules/undici/lib/handler/deduplication-handler.js +540 -0
  237. package/skill/tools/node_modules/undici/lib/handler/redirect-handler.js +284 -0
  238. package/skill/tools/node_modules/undici/lib/handler/retry-handler.js +686 -0
  239. package/skill/tools/node_modules/undici/lib/interceptor/cache.js +771 -0
  240. package/skill/tools/node_modules/undici/lib/interceptor/decompress.js +574 -0
  241. package/skill/tools/node_modules/undici/lib/interceptor/deduplicate.js +118 -0
  242. package/skill/tools/node_modules/undici/lib/interceptor/dns.js +593 -0
  243. package/skill/tools/node_modules/undici/lib/interceptor/dump.js +99 -0
  244. package/skill/tools/node_modules/undici/lib/interceptor/redirect.js +21 -0
  245. package/skill/tools/node_modules/undici/lib/interceptor/response-error.js +139 -0
  246. package/skill/tools/node_modules/undici/lib/interceptor/retry.js +19 -0
  247. package/skill/tools/node_modules/undici/lib/llhttp/constants.d.ts +195 -0
  248. package/skill/tools/node_modules/undici/lib/llhttp/constants.js +531 -0
  249. package/skill/tools/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
  250. package/skill/tools/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
  251. package/skill/tools/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
  252. package/skill/tools/node_modules/undici/lib/llhttp/utils.js +12 -0
  253. package/skill/tools/node_modules/undici/lib/milo/LICENSE.md +7 -0
  254. package/skill/tools/node_modules/undici/lib/milo/no-simd.js +1002 -0
  255. package/skill/tools/node_modules/undici/lib/milo/simd.js +1002 -0
  256. package/skill/tools/node_modules/undici/lib/mock/mock-agent.js +255 -0
  257. package/skill/tools/node_modules/undici/lib/mock/mock-call-history.js +248 -0
  258. package/skill/tools/node_modules/undici/lib/mock/mock-client.js +68 -0
  259. package/skill/tools/node_modules/undici/lib/mock/mock-errors.js +29 -0
  260. package/skill/tools/node_modules/undici/lib/mock/mock-interceptor.js +227 -0
  261. package/skill/tools/node_modules/undici/lib/mock/mock-pool.js +68 -0
  262. package/skill/tools/node_modules/undici/lib/mock/mock-symbols.js +32 -0
  263. package/skill/tools/node_modules/undici/lib/mock/mock-utils.js +730 -0
  264. package/skill/tools/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
  265. package/skill/tools/node_modules/undici/lib/mock/snapshot-agent.js +371 -0
  266. package/skill/tools/node_modules/undici/lib/mock/snapshot-recorder.js +624 -0
  267. package/skill/tools/node_modules/undici/lib/mock/snapshot-utils.js +159 -0
  268. package/skill/tools/node_modules/undici/lib/util/cache.js +764 -0
  269. package/skill/tools/node_modules/undici/lib/util/date.js +670 -0
  270. package/skill/tools/node_modules/undici/lib/util/runtime-features.js +93 -0
  271. package/skill/tools/node_modules/undici/lib/util/stats.js +32 -0
  272. package/skill/tools/node_modules/undici/lib/util/timers.js +425 -0
  273. package/skill/tools/node_modules/undici/lib/web/cache/cache.js +871 -0
  274. package/skill/tools/node_modules/undici/lib/web/cache/cachestorage.js +158 -0
  275. package/skill/tools/node_modules/undici/lib/web/cache/util.js +45 -0
  276. package/skill/tools/node_modules/undici/lib/web/cookies/constants.js +12 -0
  277. package/skill/tools/node_modules/undici/lib/web/cookies/index.js +211 -0
  278. package/skill/tools/node_modules/undici/lib/web/cookies/parse.js +318 -0
  279. package/skill/tools/node_modules/undici/lib/web/cookies/util.js +371 -0
  280. package/skill/tools/node_modules/undici/lib/web/eventsource/eventsource-stream.js +575 -0
  281. package/skill/tools/node_modules/undici/lib/web/eventsource/eventsource.js +547 -0
  282. package/skill/tools/node_modules/undici/lib/web/eventsource/util.js +60 -0
  283. package/skill/tools/node_modules/undici/lib/web/fetch/LICENSE +21 -0
  284. package/skill/tools/node_modules/undici/lib/web/fetch/body.js +583 -0
  285. package/skill/tools/node_modules/undici/lib/web/fetch/constants.js +131 -0
  286. package/skill/tools/node_modules/undici/lib/web/fetch/data-url.js +596 -0
  287. package/skill/tools/node_modules/undici/lib/web/fetch/formdata-parser.js +594 -0
  288. package/skill/tools/node_modules/undici/lib/web/fetch/formdata.js +272 -0
  289. package/skill/tools/node_modules/undici/lib/web/fetch/global.js +40 -0
  290. package/skill/tools/node_modules/undici/lib/web/fetch/headers.js +722 -0
  291. package/skill/tools/node_modules/undici/lib/web/fetch/index.js +2451 -0
  292. package/skill/tools/node_modules/undici/lib/web/fetch/request.js +1117 -0
  293. package/skill/tools/node_modules/undici/lib/web/fetch/response.js +638 -0
  294. package/skill/tools/node_modules/undici/lib/web/fetch/util.js +1530 -0
  295. package/skill/tools/node_modules/undici/lib/web/infra/index.js +244 -0
  296. package/skill/tools/node_modules/undici/lib/web/subresource-integrity/Readme.md +9 -0
  297. package/skill/tools/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +307 -0
  298. package/skill/tools/node_modules/undici/lib/web/webidl/index.js +992 -0
  299. package/skill/tools/node_modules/undici/lib/web/websocket/connection.js +350 -0
  300. package/skill/tools/node_modules/undici/lib/web/websocket/constants.js +126 -0
  301. package/skill/tools/node_modules/undici/lib/web/websocket/events.js +348 -0
  302. package/skill/tools/node_modules/undici/lib/web/websocket/frame.js +127 -0
  303. package/skill/tools/node_modules/undici/lib/web/websocket/permessage-deflate.js +105 -0
  304. package/skill/tools/node_modules/undici/lib/web/websocket/receiver.js +530 -0
  305. package/skill/tools/node_modules/undici/lib/web/websocket/sender.js +109 -0
  306. package/skill/tools/node_modules/undici/lib/web/websocket/stream/websocketerror.js +107 -0
  307. package/skill/tools/node_modules/undici/lib/web/websocket/stream/websocketstream.js +511 -0
  308. package/skill/tools/node_modules/undici/lib/web/websocket/util.js +347 -0
  309. package/skill/tools/node_modules/undici/lib/web/websocket/websocket.js +783 -0
  310. package/skill/tools/node_modules/undici/package.json +154 -0
  311. package/skill/tools/node_modules/undici/scripts/strip-comments.js +10 -0
  312. package/skill/tools/node_modules/undici/types/README.md +6 -0
  313. package/skill/tools/node_modules/undici/types/agent.d.ts +30 -0
  314. package/skill/tools/node_modules/undici/types/api.d.ts +43 -0
  315. package/skill/tools/node_modules/undici/types/balanced-pool.d.ts +30 -0
  316. package/skill/tools/node_modules/undici/types/cache-interceptor.d.ts +189 -0
  317. package/skill/tools/node_modules/undici/types/cache.d.ts +36 -0
  318. package/skill/tools/node_modules/undici/types/client-stats.d.ts +15 -0
  319. package/skill/tools/node_modules/undici/types/client.d.ts +190 -0
  320. package/skill/tools/node_modules/undici/types/connector.d.ts +37 -0
  321. package/skill/tools/node_modules/undici/types/content-type.d.ts +21 -0
  322. package/skill/tools/node_modules/undici/types/cookies.d.ts +30 -0
  323. package/skill/tools/node_modules/undici/types/diagnostics-channel.d.ts +75 -0
  324. package/skill/tools/node_modules/undici/types/dispatcher.d.ts +253 -0
  325. package/skill/tools/node_modules/undici/types/dispatcher1-wrapper.d.ts +7 -0
  326. package/skill/tools/node_modules/undici/types/env-http-proxy-agent.d.ts +22 -0
  327. package/skill/tools/node_modules/undici/types/errors.d.ts +202 -0
  328. package/skill/tools/node_modules/undici/types/eventsource.d.ts +66 -0
  329. package/skill/tools/node_modules/undici/types/fetch.d.ts +235 -0
  330. package/skill/tools/node_modules/undici/types/formdata.d.ts +108 -0
  331. package/skill/tools/node_modules/undici/types/global-dispatcher.d.ts +9 -0
  332. package/skill/tools/node_modules/undici/types/global-origin.d.ts +7 -0
  333. package/skill/tools/node_modules/undici/types/h2c-client.d.ts +73 -0
  334. package/skill/tools/node_modules/undici/types/handlers.d.ts +16 -0
  335. package/skill/tools/node_modules/undici/types/header.d.ts +165 -0
  336. package/skill/tools/node_modules/undici/types/index.d.ts +93 -0
  337. package/skill/tools/node_modules/undici/types/interceptors.d.ts +87 -0
  338. package/skill/tools/node_modules/undici/types/mock-agent.d.ts +69 -0
  339. package/skill/tools/node_modules/undici/types/mock-call-history.d.ts +111 -0
  340. package/skill/tools/node_modules/undici/types/mock-client.d.ts +27 -0
  341. package/skill/tools/node_modules/undici/types/mock-errors.d.ts +12 -0
  342. package/skill/tools/node_modules/undici/types/mock-interceptor.d.ts +98 -0
  343. package/skill/tools/node_modules/undici/types/mock-pool.d.ts +27 -0
  344. package/skill/tools/node_modules/undici/types/patch.d.ts +29 -0
  345. package/skill/tools/node_modules/undici/types/pool-stats.d.ts +19 -0
  346. package/skill/tools/node_modules/undici/types/pool.d.ts +39 -0
  347. package/skill/tools/node_modules/undici/types/proxy-agent.d.ts +36 -0
  348. package/skill/tools/node_modules/undici/types/readable.d.ts +68 -0
  349. package/skill/tools/node_modules/undici/types/retry-agent.d.ts +8 -0
  350. package/skill/tools/node_modules/undici/types/retry-handler.d.ts +125 -0
  351. package/skill/tools/node_modules/undici/types/round-robin-pool.d.ts +39 -0
  352. package/skill/tools/node_modules/undici/types/snapshot-agent.d.ts +113 -0
  353. package/skill/tools/node_modules/undici/types/socks5-proxy-agent.d.ts +27 -0
  354. package/skill/tools/node_modules/undici/types/util.d.ts +18 -0
  355. package/skill/tools/node_modules/undici/types/utility.d.ts +7 -0
  356. package/skill/tools/node_modules/undici/types/webidl.d.ts +352 -0
  357. package/skill/tools/node_modules/undici/types/websocket.d.ts +188 -0
  358. package/skill/tools/node_modules/xtend/.jshintrc +30 -0
  359. package/skill/tools/node_modules/xtend/LICENSE +20 -0
  360. package/skill/tools/node_modules/xtend/README.md +32 -0
  361. package/skill/tools/node_modules/xtend/immutable.js +19 -0
  362. package/skill/tools/node_modules/xtend/mutable.js +17 -0
  363. package/skill/tools/node_modules/xtend/package.json +55 -0
  364. package/skill/tools/node_modules/xtend/test.js +103 -0
  365. package/skill/tools/package-lock.json +172 -0
  366. package/skill/tools/package.json +9 -0
  367. package/skill/tools/transfer_core.js +414 -0
@@ -0,0 +1,624 @@
1
+ 'use strict'
2
+
3
+ const { writeFile, readFile, mkdir } = require('node:fs/promises')
4
+ const { dirname, resolve } = require('node:path')
5
+ const { setTimeout, clearTimeout } = require('node:timers')
6
+ const { InvalidArgumentError, UndiciError } = require('../core/errors')
7
+ const { setHeader } = require('../core/util')
8
+ const { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require('./snapshot-utils')
9
+
10
+ /**
11
+ * @typedef {Object} SnapshotRequestOptions
12
+ * @property {string} method - HTTP method (e.g. 'GET', 'POST', etc.)
13
+ * @property {string} path - Request path
14
+ * @property {string} origin - Request origin (base URL)
15
+ * @property {import('./snapshot-utils').Headers|import('./snapshot-utils').UndiciHeaders} headers - Request headers
16
+ * @property {import('./snapshot-utils').NormalizedHeaders} _normalizedHeaders - Request headers as a lowercase object
17
+ * @property {string|Buffer} [body] - Request body (optional)
18
+ */
19
+
20
+ /**
21
+ * @typedef {Object} SnapshotEntryRequest
22
+ * @property {string} method - HTTP method (e.g. 'GET', 'POST', etc.)
23
+ * @property {string} url - Full URL of the request
24
+ * @property {import('./snapshot-utils').NormalizedHeaders} headers - Normalized headers as a lowercase object
25
+ * @property {string|Buffer} [body] - Request body (optional)
26
+ */
27
+
28
+ /**
29
+ * @typedef {Object} SnapshotEntryResponse
30
+ * @property {number} statusCode - HTTP status code of the response
31
+ * @property {import('./snapshot-utils').NormalizedHeaders} headers - Normalized response headers as a lowercase object
32
+ * @property {string} body - Response body as a base64url encoded string
33
+ * @property {Object} [trailers] - Optional response trailers
34
+ */
35
+
36
+ /**
37
+ * @typedef {Object} SnapshotEntry
38
+ * @property {SnapshotEntryRequest} request - The request object
39
+ * @property {Array<SnapshotEntryResponse>} responses - Array of response objects
40
+ * @property {number} callCount - Number of times this snapshot has been called
41
+ * @property {string} timestamp - ISO timestamp of when the snapshot was created
42
+ */
43
+
44
+ /**
45
+ * @typedef {Object} SnapshotRecorderMatchOptions
46
+ * @property {Array<string>} [matchHeaders=[]] - Headers to match (empty array means match all headers)
47
+ * @property {Array<string>} [ignoreHeaders=[]] - Headers to ignore for matching
48
+ * @property {Array<string>} [excludeHeaders=[]] - Headers to exclude from matching
49
+ * @property {boolean} [matchBody=true] - Whether to match request body
50
+ * @property {(body: string|Buffer|null|undefined) => string} [normalizeBody] - Function to normalize the body before matching (e.g. strip timestamps)
51
+ * @property {boolean} [matchQuery=true] - Whether to match query parameters
52
+ * @property {(query: URLSearchParams) => string} [normalizeQuery] - Function to normalize query parameters before matching (e.g. strip volatile params)
53
+ * @property {boolean} [caseSensitive=false] - Whether header matching is case-sensitive
54
+ */
55
+
56
+ /**
57
+ * @typedef {Object} SnapshotRecorderOptions
58
+ * @property {string} [snapshotPath] - Path to save/load snapshots
59
+ * @property {import('./snapshot-utils').SnapshotMode} [mode='record'] - Mode: 'record' or 'playback'
60
+ * @property {number} [maxSnapshots=Infinity] - Maximum number of snapshots to keep
61
+ * @property {boolean} [autoFlush=false] - Whether to automatically flush snapshots to disk
62
+ * @property {number} [flushInterval=30000] - Auto-flush interval in milliseconds (default: 30 seconds)
63
+ * @property {Array<string|RegExp>} [excludeUrls=[]] - URLs to exclude from recording
64
+ * @property {function} [shouldRecord=null] - Function to filter requests for recording
65
+ * @property {function} [shouldPlayback=null] - Function to filter requests
66
+ */
67
+
68
+ /**
69
+ * @typedef {Object} SnapshotFormattedRequest
70
+ * @property {string} method - HTTP method (e.g. 'GET', 'POST', etc.)
71
+ * @property {string} url - Full URL of the request (with query parameters if matchQuery is true)
72
+ * @property {import('./snapshot-utils').NormalizedHeaders} headers - Normalized headers as a lowercase object
73
+ * @property {string} body - Request body (optional, only if matchBody is true)
74
+ */
75
+
76
+ /**
77
+ * @typedef {Object} SnapshotInfo
78
+ * @property {string} hash - Hash key for the snapshot
79
+ * @property {SnapshotEntryRequest} request - The request object
80
+ * @property {number} responseCount - Number of responses recorded for this request
81
+ * @property {number} callCount - Number of times this snapshot has been called
82
+ * @property {string} timestamp - ISO timestamp of when the snapshot was created
83
+ */
84
+
85
+ /**
86
+ * Normalizes the URL string used for request matching.
87
+ *
88
+ * @param {URL} url - Parsed request URL
89
+ * @param {boolean} matchQuery - Whether to include query parameters in matching
90
+ * @param {((query: URLSearchParams) => string)|undefined} normalizeQuery - Optional normalization function
91
+ * @returns {string} - URL string for hashing
92
+ */
93
+ function normalizeUrlForMatching (url, matchQuery, normalizeQuery) {
94
+ if (matchQuery === false) return `${url.origin}${url.pathname}`
95
+ if (normalizeQuery) {
96
+ const normalized = String(normalizeQuery(url.searchParams) ?? '')
97
+ return normalized ? `${url.origin}${url.pathname}?${normalized}` : `${url.origin}${url.pathname}`
98
+ }
99
+ return url.toString()
100
+ }
101
+
102
+ /**
103
+ * Normalizes the body value used for request matching.
104
+ *
105
+ * @param {string|Buffer|null|undefined} body - Raw request body
106
+ * @param {boolean} matchBody - Whether to include the body in matching
107
+ * @param {((body: string|Buffer|null|undefined) => string)|undefined} normalizeBody - Optional normalization function
108
+ * @returns {string} - Body string for hashing
109
+ */
110
+ function normalizeBodyForMatching (body, matchBody, normalizeBody) {
111
+ if (matchBody === false) return ''
112
+ if (normalizeBody) return String(normalizeBody(body) ?? '')
113
+ return body ? String(body) : ''
114
+ }
115
+
116
+ /**
117
+ * Formats a request for consistent snapshot storage
118
+ * Caches normalized headers to avoid repeated processing
119
+ *
120
+ * @param {SnapshotRequestOptions} opts - Request options
121
+ * @param {import('./snapshot-utils').HeaderFilters} headerFilters - Cached header sets for performance
122
+ * @param {SnapshotRecorderMatchOptions} [matchOptions] - Matching options for headers and body
123
+ * @returns {SnapshotFormattedRequest} - Formatted request object
124
+ */
125
+ function formatRequestKey (opts, headerFilters, matchOptions = {}) {
126
+ const url = new URL(opts.path, opts.origin)
127
+
128
+ // Cache normalized headers if not already done
129
+ const normalized = opts._normalizedHeaders || normalizeHeaders(opts.headers)
130
+ if (!opts._normalizedHeaders) {
131
+ opts._normalizedHeaders = normalized
132
+ }
133
+
134
+ return {
135
+ method: opts.method || 'GET',
136
+ url: normalizeUrlForMatching(url, matchOptions.matchQuery, matchOptions.normalizeQuery),
137
+ headers: filterHeadersForMatching(normalized, headerFilters, matchOptions),
138
+ body: normalizeBodyForMatching(opts.body, matchOptions.matchBody, matchOptions.normalizeBody)
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Filters headers based on matching configuration
144
+ *
145
+ * @param {import('./snapshot-utils').Headers} headers - Headers to filter
146
+ * @param {import('./snapshot-utils').HeaderFilters} headerFilters - Cached sets for ignore, exclude, and match headers
147
+ * @param {SnapshotRecorderMatchOptions} [matchOptions] - Matching options for headers
148
+ */
149
+ function filterHeadersForMatching (headers, headerFilters, matchOptions = {}) {
150
+ if (!headers || typeof headers !== 'object') return {}
151
+
152
+ const {
153
+ caseSensitive = false
154
+ } = matchOptions
155
+
156
+ const filtered = {}
157
+ const { ignore, exclude, match } = headerFilters
158
+
159
+ for (const [key, value] of Object.entries(headers)) {
160
+ const headerKey = caseSensitive ? key : key.toLowerCase()
161
+
162
+ // Skip if in exclude list (for security)
163
+ if (exclude.has(headerKey)) continue
164
+
165
+ // Skip if in ignore list (for matching)
166
+ if (ignore.has(headerKey)) continue
167
+
168
+ // If matchHeaders is specified, only include those headers
169
+ if (match.size !== 0) {
170
+ if (!match.has(headerKey)) continue
171
+ }
172
+
173
+ setHeader(filtered, headerKey, value)
174
+ }
175
+
176
+ return filtered
177
+ }
178
+
179
+ /**
180
+ * Filters headers for storage (only excludes sensitive headers)
181
+ *
182
+ * @param {import('./snapshot-utils').Headers} headers - Headers to filter
183
+ * @param {import('./snapshot-utils').HeaderFilters} headerFilters - Cached sets for ignore, exclude, and match headers
184
+ * @param {SnapshotRecorderMatchOptions} [matchOptions] - Matching options for headers
185
+ */
186
+ function filterHeadersForStorage (headers, headerFilters, matchOptions = {}) {
187
+ if (!headers || typeof headers !== 'object') return {}
188
+
189
+ const {
190
+ caseSensitive = false
191
+ } = matchOptions
192
+
193
+ const filtered = {}
194
+ const { exclude: excludeSet } = headerFilters
195
+
196
+ for (const [key, value] of Object.entries(headers)) {
197
+ const headerKey = caseSensitive ? key : key.toLowerCase()
198
+
199
+ // Skip if in exclude list (for security)
200
+ if (excludeSet.has(headerKey)) continue
201
+
202
+ setHeader(filtered, headerKey, value)
203
+ }
204
+
205
+ return filtered
206
+ }
207
+
208
+ /**
209
+ * Creates a hash key for request matching
210
+ * Properly orders headers to avoid conflicts and uses crypto hashing when available
211
+ *
212
+ * @param {SnapshotFormattedRequest} formattedRequest - Request object
213
+ * @returns {string} - Base64url encoded hash of the request
214
+ */
215
+ function createRequestHash (formattedRequest) {
216
+ const parts = [
217
+ formattedRequest.method,
218
+ formattedRequest.url
219
+ ]
220
+
221
+ // Process headers in a deterministic way to avoid conflicts
222
+ if (formattedRequest.headers && typeof formattedRequest.headers === 'object') {
223
+ const headerKeys = Object.keys(formattedRequest.headers).sort()
224
+ for (const key of headerKeys) {
225
+ const values = Array.isArray(formattedRequest.headers[key])
226
+ ? formattedRequest.headers[key]
227
+ : [formattedRequest.headers[key]]
228
+
229
+ // Add header name
230
+ parts.push(key)
231
+
232
+ // Add all values for this header, sorted for consistency
233
+ for (const value of values.sort()) {
234
+ parts.push(String(value))
235
+ }
236
+ }
237
+ }
238
+
239
+ // Add body
240
+ parts.push(formattedRequest.body)
241
+
242
+ const content = parts.join('|')
243
+
244
+ return hashId(content)
245
+ }
246
+
247
+ class SnapshotRecorder {
248
+ /** @type {NodeJS.Timeout | null} */
249
+ #flushTimeout
250
+
251
+ /** @type {import('./snapshot-utils').IsUrlExcluded} */
252
+ #isUrlExcluded
253
+
254
+ /** @type {Map<string, SnapshotEntry>} */
255
+ #snapshots = new Map()
256
+
257
+ /** @type {string|undefined} */
258
+ #snapshotPath
259
+
260
+ /** @type {number} */
261
+ #maxSnapshots = Infinity
262
+
263
+ /** @type {boolean} */
264
+ #autoFlush = false
265
+
266
+ /** @type {import('./snapshot-utils').HeaderFilters} */
267
+ #headerFilters
268
+
269
+ /**
270
+ * Creates a new SnapshotRecorder instance
271
+ * @param {SnapshotRecorderOptions&SnapshotRecorderMatchOptions} [options={}] - Configuration options for the recorder
272
+ */
273
+ constructor (options = {}) {
274
+ this.#snapshotPath = options.snapshotPath
275
+ this.#maxSnapshots = options.maxSnapshots || Infinity
276
+ this.#autoFlush = options.autoFlush || false
277
+ this.flushInterval = options.flushInterval || 30000 // 30 seconds default
278
+ this._flushTimer = null
279
+
280
+ // Matching configuration
281
+ /** @type {Required<SnapshotRecorderMatchOptions>} */
282
+ this.matchOptions = {
283
+ matchHeaders: options.matchHeaders || [], // empty means match all headers
284
+ ignoreHeaders: options.ignoreHeaders || [],
285
+ excludeHeaders: options.excludeHeaders || [],
286
+ matchBody: options.matchBody !== false, // default: true
287
+ normalizeBody: options.normalizeBody || undefined,
288
+ matchQuery: options.matchQuery !== false, // default: true
289
+ normalizeQuery: options.normalizeQuery || undefined,
290
+ caseSensitive: options.caseSensitive || false
291
+ }
292
+
293
+ // Cache processed header sets to avoid recreating them on every request
294
+ this.#headerFilters = createHeaderFilters(this.matchOptions)
295
+
296
+ // Request filtering callbacks
297
+ this.shouldRecord = options.shouldRecord || (() => true) // function(requestOpts) -> boolean
298
+ this.shouldPlayback = options.shouldPlayback || (() => true) // function(requestOpts) -> boolean
299
+
300
+ // URL pattern filtering
301
+ this.#isUrlExcluded = isUrlExcludedFactory(options.excludeUrls) // Array of regex patterns or strings
302
+
303
+ // Start auto-flush timer if enabled
304
+ if (this.#autoFlush && this.#snapshotPath) {
305
+ this.#startAutoFlush()
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Records a request-response interaction
311
+ * @param {SnapshotRequestOptions} requestOpts - Request options
312
+ * @param {SnapshotEntryResponse} response - Response data to record
313
+ * @return {Promise<void>} - Resolves when the recording is complete
314
+ */
315
+ async record (requestOpts, response) {
316
+ // Check if recording should be filtered out
317
+ if (!this.shouldRecord(requestOpts)) {
318
+ return // Skip recording
319
+ }
320
+
321
+ // Check URL exclusion patterns
322
+ if (this.isUrlExcluded(requestOpts)) {
323
+ return // Skip recording
324
+ }
325
+
326
+ const request = formatRequestKey(requestOpts, this.#headerFilters, this.matchOptions)
327
+ const hash = createRequestHash(request)
328
+
329
+ // Extract response data - always store body as base64
330
+ const normalizedHeaders = normalizeHeaders(response.headers)
331
+
332
+ /** @type {SnapshotEntryResponse} */
333
+ const responseData = {
334
+ statusCode: response.statusCode,
335
+ headers: filterHeadersForStorage(normalizedHeaders, this.#headerFilters, this.matchOptions),
336
+ body: Buffer.isBuffer(response.body)
337
+ ? response.body.toString('base64')
338
+ : Buffer.from(String(response.body || '')).toString('base64'),
339
+ trailers: response.trailers
340
+ }
341
+
342
+ // Remove oldest snapshot if we exceed maxSnapshots limit
343
+ if (this.#snapshots.size >= this.#maxSnapshots && !this.#snapshots.has(hash)) {
344
+ const oldestKey = this.#snapshots.keys().next().value
345
+ this.#snapshots.delete(oldestKey)
346
+ }
347
+
348
+ // Support sequential responses - if snapshot exists, add to responses array
349
+ const existingSnapshot = this.#snapshots.get(hash)
350
+ if (existingSnapshot && existingSnapshot.responses) {
351
+ existingSnapshot.responses.push(responseData)
352
+ existingSnapshot.timestamp = new Date().toISOString()
353
+ } else {
354
+ this.#snapshots.set(hash, {
355
+ request,
356
+ responses: [responseData], // Always store as array for consistency
357
+ callCount: 0,
358
+ timestamp: new Date().toISOString()
359
+ })
360
+ }
361
+
362
+ // Auto-flush if enabled
363
+ if (this.#autoFlush && this.#snapshotPath) {
364
+ this.#scheduleFlush()
365
+ }
366
+ }
367
+
368
+ /**
369
+ * Checks if a URL should be excluded from recording/playback
370
+ * @param {SnapshotRequestOptions} requestOpts - Request options to check
371
+ * @returns {boolean} - True if URL is excluded
372
+ */
373
+ isUrlExcluded (requestOpts) {
374
+ const url = new URL(requestOpts.path, requestOpts.origin).toString()
375
+ return this.#isUrlExcluded(url)
376
+ }
377
+
378
+ /**
379
+ * Finds a matching snapshot for the given request
380
+ * Returns the appropriate response based on call count for sequential responses
381
+ *
382
+ * @param {SnapshotRequestOptions} requestOpts - Request options to match
383
+ * @returns {SnapshotEntry&Record<'response', SnapshotEntryResponse>|undefined} - Matching snapshot response or undefined if not found
384
+ */
385
+ findSnapshot (requestOpts) {
386
+ // Check if playback should be filtered out
387
+ if (!this.shouldPlayback(requestOpts)) {
388
+ return undefined // Skip playback
389
+ }
390
+
391
+ // Check URL exclusion patterns
392
+ if (this.isUrlExcluded(requestOpts)) {
393
+ return undefined // Skip playback
394
+ }
395
+
396
+ const request = formatRequestKey(requestOpts, this.#headerFilters, this.matchOptions)
397
+ const hash = createRequestHash(request)
398
+ const snapshot = this.#snapshots.get(hash)
399
+
400
+ if (!snapshot) return undefined
401
+
402
+ // Handle sequential responses
403
+ const currentCallCount = snapshot.callCount || 0
404
+ const responseIndex = Math.min(currentCallCount, snapshot.responses.length - 1)
405
+ snapshot.callCount = currentCallCount + 1
406
+
407
+ return {
408
+ ...snapshot,
409
+ response: snapshot.responses[responseIndex]
410
+ }
411
+ }
412
+
413
+ /**
414
+ * Loads snapshots from file
415
+ * @param {string} [filePath] - Optional file path to load snapshots from
416
+ * @return {Promise<void>} - Resolves when snapshots are loaded
417
+ */
418
+ async loadSnapshots (filePath) {
419
+ const path = filePath || this.#snapshotPath
420
+ if (!path) {
421
+ throw new InvalidArgumentError('Snapshot path is required')
422
+ }
423
+
424
+ try {
425
+ const data = await readFile(resolve(path), 'utf8')
426
+ const parsed = JSON.parse(data)
427
+
428
+ // Convert array format back to Map
429
+ if (Array.isArray(parsed)) {
430
+ this.#snapshots.clear()
431
+ for (const { hash, snapshot } of parsed) {
432
+ this.#snapshots.set(hash, snapshot)
433
+ }
434
+ } else {
435
+ // Legacy object format
436
+ this.#snapshots = new Map(Object.entries(parsed))
437
+ }
438
+ } catch (error) {
439
+ if (error.code === 'ENOENT') {
440
+ // File doesn't exist yet - that's ok for recording mode
441
+ this.#snapshots.clear()
442
+ } else {
443
+ throw new UndiciError(`Failed to load snapshots from ${path}`, { cause: error })
444
+ }
445
+ }
446
+ }
447
+
448
+ /**
449
+ * Saves snapshots to file
450
+ *
451
+ * @param {string} [filePath] - Optional file path to save snapshots
452
+ * @returns {Promise<void>} - Resolves when snapshots are saved
453
+ */
454
+ async saveSnapshots (filePath) {
455
+ const path = filePath || this.#snapshotPath
456
+ if (!path) {
457
+ throw new InvalidArgumentError('Snapshot path is required')
458
+ }
459
+
460
+ const resolvedPath = resolve(path)
461
+
462
+ // Ensure directory exists
463
+ await mkdir(dirname(resolvedPath), { recursive: true })
464
+
465
+ // Convert Map to serializable format
466
+ const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
467
+ hash,
468
+ snapshot
469
+ }))
470
+
471
+ await writeFile(resolvedPath, JSON.stringify(data, null, 2), { flush: true })
472
+ }
473
+
474
+ /**
475
+ * Clears all recorded snapshots
476
+ * @returns {void}
477
+ */
478
+ clear () {
479
+ this.#snapshots.clear()
480
+ }
481
+
482
+ /**
483
+ * Gets all recorded snapshots
484
+ * @return {Array<SnapshotEntry>} - Array of all recorded snapshots
485
+ */
486
+ getSnapshots () {
487
+ return Array.from(this.#snapshots.values())
488
+ }
489
+
490
+ /**
491
+ * Gets snapshot count
492
+ * @return {number} - Number of recorded snapshots
493
+ */
494
+ size () {
495
+ return this.#snapshots.size
496
+ }
497
+
498
+ /**
499
+ * Resets call counts for all snapshots (useful for test cleanup)
500
+ * @returns {void}
501
+ */
502
+ resetCallCounts () {
503
+ for (const snapshot of this.#snapshots.values()) {
504
+ snapshot.callCount = 0
505
+ }
506
+ }
507
+
508
+ /**
509
+ * Deletes a specific snapshot by request options
510
+ * @param {SnapshotRequestOptions} requestOpts - Request options to match
511
+ * @returns {boolean} - True if snapshot was deleted, false if not found
512
+ */
513
+ deleteSnapshot (requestOpts) {
514
+ const request = formatRequestKey(requestOpts, this.#headerFilters, this.matchOptions)
515
+ const hash = createRequestHash(request)
516
+ return this.#snapshots.delete(hash)
517
+ }
518
+
519
+ /**
520
+ * Gets information about a specific snapshot
521
+ * @param {SnapshotRequestOptions} requestOpts - Request options to match
522
+ * @returns {SnapshotInfo|null} - Snapshot information or null if not found
523
+ */
524
+ getSnapshotInfo (requestOpts) {
525
+ const request = formatRequestKey(requestOpts, this.#headerFilters, this.matchOptions)
526
+ const hash = createRequestHash(request)
527
+ const snapshot = this.#snapshots.get(hash)
528
+
529
+ if (!snapshot) return null
530
+
531
+ return {
532
+ hash,
533
+ request: snapshot.request,
534
+ responseCount: snapshot.responses ? snapshot.responses.length : (snapshot.response ? 1 : 0), // .response for legacy snapshots
535
+ callCount: snapshot.callCount || 0,
536
+ timestamp: snapshot.timestamp
537
+ }
538
+ }
539
+
540
+ /**
541
+ * Replaces all snapshots with new data (full replacement)
542
+ * @param {Array<{hash: string; snapshot: SnapshotEntry}>|Record<string, SnapshotEntry>} snapshotData - New snapshot data to replace existing ones
543
+ * @returns {void}
544
+ */
545
+ replaceSnapshots (snapshotData) {
546
+ this.#snapshots.clear()
547
+
548
+ if (Array.isArray(snapshotData)) {
549
+ for (const { hash, snapshot } of snapshotData) {
550
+ this.#snapshots.set(hash, snapshot)
551
+ }
552
+ } else if (snapshotData && typeof snapshotData === 'object') {
553
+ // Legacy object format
554
+ this.#snapshots = new Map(Object.entries(snapshotData))
555
+ }
556
+ }
557
+
558
+ /**
559
+ * Starts the auto-flush timer
560
+ * @returns {void}
561
+ */
562
+ #startAutoFlush () {
563
+ return this.#scheduleFlush()
564
+ }
565
+
566
+ /**
567
+ * Stops the auto-flush timer
568
+ * @returns {void}
569
+ */
570
+ #stopAutoFlush () {
571
+ if (this.#flushTimeout) {
572
+ clearTimeout(this.#flushTimeout)
573
+ // Ensure any pending flush is completed
574
+ this.saveSnapshots().catch(() => {
575
+ // Ignore flush errors
576
+ })
577
+ this.#flushTimeout = null
578
+ }
579
+ }
580
+
581
+ /**
582
+ * Schedules a flush (debounced to avoid excessive writes)
583
+ */
584
+ #scheduleFlush () {
585
+ this.#flushTimeout = setTimeout(() => {
586
+ this.saveSnapshots().catch(() => {
587
+ // Ignore flush errors
588
+ })
589
+ if (this.#autoFlush) {
590
+ this.#flushTimeout?.refresh()
591
+ } else {
592
+ this.#flushTimeout = null
593
+ }
594
+ }, 1000) // 1 second debounce
595
+ }
596
+
597
+ /**
598
+ * Cleanup method to stop timers
599
+ * @returns {void}
600
+ */
601
+ destroy () {
602
+ this.#stopAutoFlush()
603
+ if (this.#flushTimeout) {
604
+ clearTimeout(this.#flushTimeout)
605
+ this.#flushTimeout = null
606
+ }
607
+ }
608
+
609
+ /**
610
+ * Async close method that saves all recordings and performs cleanup
611
+ * @returns {Promise<void>}
612
+ */
613
+ async close () {
614
+ // Save any pending recordings if we have a snapshot path
615
+ if (this.#snapshotPath && this.#snapshots.size !== 0) {
616
+ await this.saveSnapshots()
617
+ }
618
+
619
+ // Perform cleanup
620
+ this.destroy()
621
+ }
622
+ }
623
+
624
+ module.exports = { SnapshotRecorder, formatRequestKey, createRequestHash, filterHeadersForMatching, filterHeadersForStorage, createHeaderFilters }