@openclaw/slack 2026.9.6 → 2026.9.7

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 (291) hide show
  1. package/assets/icon.png +0 -0
  2. package/dist/.setup/{account-inspect-DP1Bcwj4.mjs → account-inspect-DWBXpER6.mjs} +1 -1
  3. package/dist/.setup/{accounts-BBHvg0pY.mjs → accounts-D_N9IqNA.mjs} +23 -1
  4. package/dist/.setup/{action-runtime-B01d85zt.mjs → action-runtime-DfWvuiZd.mjs} +26 -41
  5. package/dist/.setup/action-runtime.runtime-Ck4bAWOX.mjs +2 -0
  6. package/dist/.setup/{actions-DKCtBgCI.mjs → actions-Df0CzcDl.mjs} +88 -175
  7. package/dist/.setup/{approval-handler.runtime-DMszKn_7.mjs → approval-handler.runtime-Ed6Sw5VK.mjs} +37 -47
  8. package/dist/.setup/{approval-message-updates-Tb_qRokK.mjs → approval-message-updates-BadvtA7R.mjs} +1 -2
  9. package/dist/.setup/{channel-CErYZ5zw.mjs → channel-C7bgPSTE.mjs} +181 -273
  10. package/dist/.setup/channel-meta-C443t-lI.mjs +27 -0
  11. package/dist/.setup/{channel-type-Dxk8VJUb.mjs → channel-type-ClOttrZ5.mjs} +13 -21
  12. package/dist/.setup/{channel.setup-BVoUtdPn.mjs → channel.setup-Dh2jzAjN.mjs} +35 -42
  13. package/dist/.setup/{config-schema-CyL279e7.mjs → config-schema-BZCxmHKG.mjs} +24 -21
  14. package/dist/.setup/{directory-config-CQTSH45W.mjs → directory-config-BOUWH3hR.mjs} +7 -10
  15. package/dist/.setup/{directory-live-BCcj89QV.mjs → directory-live-B2O4B_Ho.mjs} +9 -21
  16. package/dist/.setup/doctor-contract-CRN1Z_c7.mjs +342 -0
  17. package/dist/.setup/{message-tool-api-C0PTFaNV.mjs → message-tool-api-Cu4lwlGy.mjs} +34 -48
  18. package/dist/.setup/{provider-C-jPaGt2.mjs → monitor-BPVfkumU.mjs} +2181 -2693
  19. package/dist/.setup/{outbound-adapter-A7Wdn8ZT.mjs → outbound-adapter-Bv48XUjq.mjs} +10 -21
  20. package/dist/.setup/{pipeline.runtime-BlPOexmJ.mjs → pipeline.runtime-B1H63Frf.mjs} +311 -457
  21. package/dist/.setup/{plugin-routes-C3X0eVaK.mjs → plugin-routes-B8tooDLj.mjs} +1 -1
  22. package/dist/.setup/{policy-BApW53pI.mjs → policy-D-jfM174.mjs} +5 -5
  23. package/dist/.setup/{probe-DiYIMPJo.mjs → probe-B2Y9qc_z.mjs} +101 -39
  24. package/dist/.setup/{registry-bbjH7IHX.mjs → registry-CIbMfuf8.mjs} +6 -2
  25. package/dist/.setup/{relay-source-DfOnjJTE.mjs → relay-source-BpKdjsll.mjs} +10 -12
  26. package/dist/.setup/{replies-BBAJxUOQ.mjs → replies-BAnUtr2f.mjs} +16 -76
  27. package/dist/.setup/{reply-blocks-Bm8kf6mK.mjs → reply-blocks-SE1kTE3I.mjs} +27 -154
  28. package/dist/.setup/{resolve-channels-BXbMBbJD.mjs → resolve-channels-XXBn8UU_.mjs} +4 -5
  29. package/dist/.setup/{resolve-users-65WqvIqD.mjs → resolve-users-DW0ngD03.mjs} +20 -22
  30. package/dist/.setup/{scopes-h3YB-mMs.mjs → scopes-CasuDvaa.mjs} +6 -17
  31. package/dist/.setup/{secret-contract-DxmvbxBF.mjs → secret-contract-BaZcu6P_.mjs} +15 -20
  32. package/dist/.setup/{secret-contract-api-D9UfYujm.mjs → secret-contract-api-Dp6290Vg.mjs} +1 -1
  33. package/dist/.setup/{security-audit-BypHqcq5.mjs → security-audit-BqDc-6VL.mjs} +1 -1
  34. package/dist/.setup/{send-Cp6omkOg.mjs → send-BOVLQi3n.mjs} +84 -171
  35. package/dist/.setup/{session-status-Cf7AvWOt.mjs → session-status-DscajIsd.mjs} +315 -238
  36. package/dist/.setup/{setup-plugin-api-dLPkL06L.mjs → setup-plugin-api-DTtbTKNk.mjs} +1 -1
  37. package/dist/.setup/{setup-surface-D3DLcCxu.mjs → setup-surface-Dn7QgWRE.mjs} +24 -56
  38. package/dist/.setup/{shared-CJ3arAFL.mjs → shared-qau-uDGl.mjs} +30 -56
  39. package/dist/.setup/{slash-dispatch.runtime-HFy_XvyO.mjs → slash-dispatch.runtime--AEzLVBF.mjs} +1 -1
  40. package/dist/.setup/{streaming-compat-B-e0mqM0.mjs → streaming-compat-C5Wut626.mjs} +31 -8
  41. package/dist/.setup/{target-parsing-DEsPjngB.mjs → target-parsing-FFE26kOV.mjs} +1 -7
  42. package/dist/.setup/{targets-Cku2KCvg.mjs → targets-C6LZQL1Q.mjs} +1 -1
  43. package/dist/.setup/{thread-ts-CukseRVL.mjs → thread-ts-Cvt7WD6B.mjs} +0 -1
  44. package/dist/account-inspect-api.js +1 -1
  45. package/dist/api.js +18 -17
  46. package/dist/channel-config-api.js +1 -1
  47. package/dist/channel-plugin-api.js +1 -1
  48. package/dist/directory-contract-api.js +1 -1
  49. package/dist/doctor-contract-api.js +1 -1
  50. package/dist/http-routes-api.js +1 -1
  51. package/dist/index.js +1 -1
  52. package/dist/message-tool-api.js +1 -1
  53. package/dist/runtime-api.js +11 -12
  54. package/dist/secret-contract-api.js +1 -1
  55. package/dist/security-contract-api.js +1 -1
  56. package/dist/setup-entry.js +2 -2
  57. package/dist/setup-plugin-api.js +1 -1
  58. package/node_modules/@slack/bolt/node_modules/@types/node/README.md +1 -1
  59. package/node_modules/@slack/bolt/node_modules/@types/node/child_process.d.ts +1 -1
  60. package/node_modules/@slack/bolt/node_modules/@types/node/crypto.d.ts +20 -8
  61. package/node_modules/@slack/bolt/node_modules/@types/node/ffi.d.ts +14 -0
  62. package/node_modules/@slack/bolt/node_modules/@types/node/http2.d.ts +3 -2
  63. package/node_modules/@slack/bolt/node_modules/@types/node/net.d.ts +16 -4
  64. package/node_modules/@slack/bolt/node_modules/@types/node/package.json +2 -2
  65. package/node_modules/@slack/bolt/node_modules/@types/node/process.d.ts +1 -0
  66. package/node_modules/@slack/bolt/node_modules/@types/node/quic.d.ts +39 -1
  67. package/node_modules/@slack/bolt/node_modules/@types/node/stream/iter.d.ts +9 -12
  68. package/node_modules/@slack/bolt/node_modules/@types/node/test/reporters.d.ts +1 -0
  69. package/node_modules/@slack/bolt/node_modules/@types/node/test.d.ts +72 -0
  70. package/node_modules/@slack/bolt/node_modules/@types/node/tls.d.ts +14 -10
  71. package/node_modules/@slack/bolt/node_modules/@types/node/vm.d.ts +2 -1
  72. package/node_modules/@slack/bolt/node_modules/@types/node/worker_threads.d.ts +4 -1
  73. package/node_modules/@slack/web-api/node_modules/@types/node/README.md +1 -1
  74. package/node_modules/@slack/web-api/node_modules/@types/node/child_process.d.ts +1 -1
  75. package/node_modules/@slack/web-api/node_modules/@types/node/crypto.d.ts +20 -8
  76. package/node_modules/@slack/web-api/node_modules/@types/node/ffi.d.ts +14 -0
  77. package/node_modules/@slack/web-api/node_modules/@types/node/http2.d.ts +3 -2
  78. package/node_modules/@slack/web-api/node_modules/@types/node/net.d.ts +16 -4
  79. package/node_modules/@slack/web-api/node_modules/@types/node/package.json +2 -2
  80. package/node_modules/@slack/web-api/node_modules/@types/node/process.d.ts +1 -0
  81. package/node_modules/@slack/web-api/node_modules/@types/node/quic.d.ts +39 -1
  82. package/node_modules/@slack/web-api/node_modules/@types/node/stream/iter.d.ts +9 -12
  83. package/node_modules/@slack/web-api/node_modules/@types/node/test/reporters.d.ts +1 -0
  84. package/node_modules/@slack/web-api/node_modules/@types/node/test.d.ts +72 -0
  85. package/node_modules/@slack/web-api/node_modules/@types/node/tls.d.ts +14 -10
  86. package/node_modules/@slack/web-api/node_modules/@types/node/vm.d.ts +2 -1
  87. package/node_modules/@slack/web-api/node_modules/@types/node/worker_threads.d.ts +4 -1
  88. package/node_modules/get-east-asian-width/index.js +8 -3
  89. package/node_modules/get-east-asian-width/lookup-data.js +1 -1
  90. package/node_modules/get-east-asian-width/lookup.js +4 -4
  91. package/node_modules/get-east-asian-width/package.json +1 -1
  92. package/node_modules/typebox/build/compile/code.mjs +1 -2
  93. package/node_modules/typebox/build/compile/validator.mjs +5 -1
  94. package/node_modules/typebox/build/format/iri.mjs +16 -9
  95. package/node_modules/typebox/build/guard/emit.mjs +2 -2
  96. package/node_modules/typebox/build/guard/guard.d.mts +7 -5
  97. package/node_modules/typebox/build/guard/guard.mjs +14 -9
  98. package/node_modules/typebox/build/guard/index.mjs +6 -0
  99. package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
  100. package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
  101. package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
  102. package/node_modules/typebox/build/schema/build.mjs +2 -3
  103. package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
  104. package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
  105. package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
  106. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
  107. package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
  108. package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
  109. package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
  110. package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
  111. package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
  112. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
  113. package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
  114. package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
  115. package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
  116. package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
  117. package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
  118. package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
  119. package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
  120. package/node_modules/typebox/build/schema/parse.mjs +3 -0
  121. package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
  122. package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
  123. package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
  124. package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
  125. package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
  126. package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
  127. package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
  128. package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
  129. package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
  130. package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
  131. package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
  132. package/node_modules/typebox/package.json +1 -1
  133. package/node_modules/typebox/readme.md +3 -1
  134. package/node_modules/undici/README.md +81 -25
  135. package/node_modules/undici/docs/docs/api/Agent.md +249 -42
  136. package/node_modules/undici/docs/docs/api/BalancedPool.md +246 -48
  137. package/node_modules/undici/docs/docs/api/CacheStorage.md +171 -13
  138. package/node_modules/undici/docs/docs/api/CacheStore.md +294 -98
  139. package/node_modules/undici/docs/docs/api/Client.md +407 -162
  140. package/node_modules/undici/docs/docs/api/ClientStats.md +80 -14
  141. package/node_modules/undici/docs/docs/api/Connector.md +118 -35
  142. package/node_modules/undici/docs/docs/api/ContentType.md +65 -25
  143. package/node_modules/undici/docs/docs/api/Cookies.md +122 -71
  144. package/node_modules/undici/docs/docs/api/Debug.md +34 -18
  145. package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +364 -164
  146. package/node_modules/undici/docs/docs/api/Dispatcher.md +490 -1055
  147. package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +105 -93
  148. package/node_modules/undici/docs/docs/api/Errors.md +503 -28
  149. package/node_modules/undici/docs/docs/api/EventSource.md +326 -13
  150. package/node_modules/undici/docs/docs/api/Fetch.md +681 -30
  151. package/node_modules/undici/docs/docs/api/GlobalInstallation.md +78 -96
  152. package/node_modules/undici/docs/docs/api/H2CClient.md +298 -176
  153. package/node_modules/undici/docs/docs/api/Interceptors.md +418 -0
  154. package/node_modules/undici/docs/docs/api/MockAgent.md +333 -314
  155. package/node_modules/undici/docs/docs/api/MockCallHistory.md +272 -98
  156. package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +189 -26
  157. package/node_modules/undici/docs/docs/api/MockClient.md +151 -33
  158. package/node_modules/undici/docs/docs/api/MockErrors.md +56 -5
  159. package/node_modules/undici/docs/docs/api/MockPool.md +321 -258
  160. package/node_modules/undici/docs/docs/api/Pool.md +236 -41
  161. package/node_modules/undici/docs/docs/api/PoolStats.md +119 -13
  162. package/node_modules/undici/docs/docs/api/ProxyAgent.md +179 -160
  163. package/node_modules/undici/docs/docs/api/RedirectHandler.md +238 -55
  164. package/node_modules/undici/docs/docs/api/RetryAgent.md +113 -27
  165. package/node_modules/undici/docs/docs/api/RetryHandler.md +161 -79
  166. package/node_modules/undici/docs/docs/api/RoundRobinPool.md +166 -72
  167. package/node_modules/undici/docs/docs/api/SnapshotAgent.md +262 -517
  168. package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +177 -196
  169. package/node_modules/undici/docs/docs/api/Util.md +68 -11
  170. package/node_modules/undici/docs/docs/api/WebSocket.md +475 -80
  171. package/node_modules/undici/docs/docs/api/api-lifecycle.md +100 -32
  172. package/node_modules/undici/docs/docs/best-practices/client-certificate.md +2 -0
  173. package/node_modules/undici/docs/docs/best-practices/crawling.md +3 -1
  174. package/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +233 -0
  175. package/node_modules/undici/docs/docs/best-practices/mocking-request.md +9 -7
  176. package/node_modules/undici/docs/docs/best-practices/proxy.md +3 -1
  177. package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +10 -8
  178. package/node_modules/undici/docs/docs/best-practices/writing-tests.md +2 -0
  179. package/node_modules/undici/docs/docs/getting-started.md +281 -0
  180. package/node_modules/undici/docs/docs/index.md +784 -0
  181. package/node_modules/undici/docs/docs/site.json +125 -0
  182. package/node_modules/undici/docs/docs/type-map.json +79 -0
  183. package/node_modules/undici/index.js +4 -2
  184. package/node_modules/undici/lib/api/api-connect.js +13 -11
  185. package/node_modules/undici/lib/api/api-pipeline.js +26 -13
  186. package/node_modules/undici/lib/api/api-request.js +51 -21
  187. package/node_modules/undici/lib/api/api-stream.js +81 -20
  188. package/node_modules/undici/lib/api/api-upgrade.js +21 -11
  189. package/node_modules/undici/lib/api/readable.js +45 -9
  190. package/node_modules/undici/lib/cache/memory-cache-store.js +3 -3
  191. package/node_modules/undici/lib/cache/sqlite-cache-store.js +3 -1
  192. package/node_modules/undici/lib/core/connect.js +46 -7
  193. package/node_modules/undici/lib/core/constants.js +1 -24
  194. package/node_modules/undici/lib/core/errors.js +22 -2
  195. package/node_modules/undici/lib/core/request.js +100 -18
  196. package/node_modules/undici/lib/core/symbols.js +4 -0
  197. package/node_modules/undici/lib/core/util.js +105 -48
  198. package/node_modules/undici/lib/dispatcher/agent.js +51 -32
  199. package/node_modules/undici/lib/dispatcher/balanced-pool.js +23 -27
  200. package/node_modules/undici/lib/dispatcher/client-h1.js +86 -24
  201. package/node_modules/undici/lib/dispatcher/client-h2.js +1091 -361
  202. package/node_modules/undici/lib/dispatcher/client.js +109 -36
  203. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +19 -6
  204. package/node_modules/undici/lib/dispatcher/dispatcher.js +15 -5
  205. package/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +110 -0
  206. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +37 -8
  207. package/node_modules/undici/lib/dispatcher/h2c-client.js +4 -4
  208. package/node_modules/undici/lib/dispatcher/pool-base.js +28 -10
  209. package/node_modules/undici/lib/dispatcher/pool.js +30 -5
  210. package/node_modules/undici/lib/dispatcher/proxy-agent.js +95 -19
  211. package/node_modules/undici/lib/dispatcher/retry-agent.js +3 -0
  212. package/node_modules/undici/lib/dispatcher/round-robin-pool.js +32 -10
  213. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +153 -63
  214. package/node_modules/undici/lib/global.js +37 -14
  215. package/node_modules/undici/lib/handler/cache-handler.js +49 -7
  216. package/node_modules/undici/lib/handler/cache-revalidation-handler.js +10 -0
  217. package/node_modules/undici/lib/handler/decorator-handler.js +8 -3
  218. package/node_modules/undici/lib/handler/deduplication-handler.js +12 -6
  219. package/node_modules/undici/lib/handler/redirect-handler.js +66 -66
  220. package/node_modules/undici/lib/handler/retry-handler.js +191 -50
  221. package/node_modules/undici/lib/interceptor/cache.js +75 -25
  222. package/node_modules/undici/lib/interceptor/decompress.js +5 -2
  223. package/node_modules/undici/lib/interceptor/deduplicate.js +5 -4
  224. package/node_modules/undici/lib/interceptor/dns.js +12 -1
  225. package/node_modules/undici/lib/interceptor/redirect.js +3 -3
  226. package/node_modules/undici/lib/llhttp/llhttp-wasm.js +1 -1
  227. package/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +1 -1
  228. package/node_modules/undici/lib/mock/mock-agent.js +21 -9
  229. package/node_modules/undici/lib/mock/mock-call-history.js +1 -1
  230. package/node_modules/undici/lib/mock/mock-interceptor.js +25 -7
  231. package/node_modules/undici/lib/mock/mock-utils.js +281 -47
  232. package/node_modules/undici/lib/mock/snapshot-agent.js +25 -7
  233. package/node_modules/undici/lib/mock/snapshot-recorder.js +38 -3
  234. package/node_modules/undici/lib/util/cache.js +92 -10
  235. package/node_modules/undici/lib/util/runtime-features.js +3 -34
  236. package/node_modules/undici/lib/web/cache/cache.js +6 -8
  237. package/node_modules/undici/lib/web/cookies/parse.js +150 -146
  238. package/node_modules/undici/lib/web/cookies/util.js +1 -1
  239. package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +28 -1
  240. package/node_modules/undici/lib/web/eventsource/eventsource.js +20 -21
  241. package/node_modules/undici/lib/web/eventsource/util.js +32 -1
  242. package/node_modules/undici/lib/web/fetch/body.js +48 -10
  243. package/node_modules/undici/lib/web/fetch/constants.js +1 -1
  244. package/node_modules/undici/lib/web/fetch/formdata.js +21 -2
  245. package/node_modules/undici/lib/web/fetch/index.js +242 -223
  246. package/node_modules/undici/lib/web/fetch/request.js +35 -6
  247. package/node_modules/undici/lib/web/fetch/response.js +1 -3
  248. package/node_modules/undici/lib/web/fetch/util.js +10 -2
  249. package/node_modules/undici/lib/web/webidl/index.js +5 -7
  250. package/node_modules/undici/lib/web/websocket/frame.js +1 -7
  251. package/node_modules/undici/lib/web/websocket/receiver.js +1 -1
  252. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +10 -10
  253. package/node_modules/undici/lib/web/websocket/websocket.js +25 -3
  254. package/node_modules/undici/package.json +10 -10
  255. package/node_modules/undici/types/agent.d.ts +0 -2
  256. package/node_modules/undici/types/client.d.ts +69 -24
  257. package/node_modules/undici/types/connector.d.ts +1 -0
  258. package/node_modules/undici/types/cookies.d.ts +1 -1
  259. package/node_modules/undici/types/dispatcher.d.ts +8 -30
  260. package/node_modules/undici/types/dispatcher1-wrapper.d.ts +7 -0
  261. package/node_modules/undici/types/errors.d.ts +10 -0
  262. package/node_modules/undici/types/fetch.d.ts +5 -1
  263. package/node_modules/undici/types/formdata.d.ts +0 -6
  264. package/node_modules/undici/types/h2c-client.d.ts +6 -6
  265. package/node_modules/undici/types/handlers.d.ts +2 -0
  266. package/node_modules/undici/types/header.d.ts +5 -0
  267. package/node_modules/undici/types/index.d.ts +3 -1
  268. package/node_modules/undici/types/interceptors.d.ts +1 -1
  269. package/node_modules/undici/types/mock-agent.d.ts +11 -10
  270. package/node_modules/undici/types/mock-interceptor.d.ts +5 -1
  271. package/node_modules/undici/types/pool.d.ts +0 -2
  272. package/node_modules/undici/types/proxy-agent.d.ts +9 -2
  273. package/node_modules/undici/types/round-robin-pool.d.ts +0 -2
  274. package/node_modules/undici/types/snapshot-agent.d.ts +4 -0
  275. package/node_modules/undici/types/socks5-proxy-agent.d.ts +4 -2
  276. package/node_modules/undici/types/webidl.d.ts +0 -1
  277. package/openclaw.plugin.json +31 -3
  278. package/package.json +7 -7
  279. package/dist/.setup/accounts.runtime-DN-PPocC.mjs +0 -2
  280. package/dist/.setup/action-runtime.runtime-C8R8CUan.mjs +0 -2
  281. package/dist/.setup/doctor-contract-CtMUqjvk.mjs +0 -186
  282. package/dist/.setup/monitor-_Sht7Dqy.mjs +0 -13
  283. package/dist/.setup/rolldown-runtime-D7D4PA-g.mjs +0 -13
  284. package/dist/.setup/send.runtime-B4caZU6T.mjs +0 -2
  285. package/dist/.setup/slash-commands.runtime-BpSH0b3q.mjs +0 -2
  286. package/dist/.setup/slash-skill-commands.runtime-Bi1JWZHY.mjs +0 -2
  287. package/node_modules/undici/lib/handler/unwrap-handler.js +0 -106
  288. package/node_modules/undici/lib/handler/wrap-handler.js +0 -105
  289. package/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  290. package/node_modules/undici/lib/util/promise.js +0 -28
  291. /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
@@ -1,30 +1,14 @@
1
1
  'use strict'
2
2
 
3
3
  const util = require('../core/util')
4
- const { kBodyUsed } = require('../core/symbols')
5
4
  const assert = require('node:assert')
6
5
  const { InvalidArgumentError } = require('../core/errors')
7
- const EE = require('node:events')
6
+ const { kRequestOrigin } = require('../core/symbols')
8
7
 
9
8
  const redirectableStatusCodes = [300, 301, 302, 303, 307, 308]
10
9
 
11
- const kBody = Symbol('body')
12
-
13
10
  const noop = () => {}
14
11
 
15
- class BodyAsyncIterable {
16
- constructor (body) {
17
- this[kBody] = body
18
- this[kBodyUsed] = false
19
- }
20
-
21
- async * [Symbol.asyncIterator] () {
22
- assert(!this[kBodyUsed], 'disturbed')
23
- this[kBodyUsed] = true
24
- yield * this[kBody]
25
- }
26
- }
27
-
28
12
  class RedirectHandler {
29
13
  static buildDispatch (dispatcher, maxRedirections) {
30
14
  if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
@@ -40,53 +24,34 @@ class RedirectHandler {
40
24
  throw new InvalidArgumentError('maxRedirections must be a positive number')
41
25
  }
42
26
 
27
+ if (opts.throwOnMaxRedirect != null && typeof opts.throwOnMaxRedirect !== 'boolean') {
28
+ throw new InvalidArgumentError('throwOnMaxRedirect must be a boolean')
29
+ }
30
+
43
31
  this.dispatch = dispatch
44
32
  this.location = null
45
- const { maxRedirections: _, ...cleanOpts } = opts
33
+ const { maxRedirections: _, stripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect, ...cleanOpts } = opts
46
34
  this.opts = cleanOpts // opts must be a copy, exclude maxRedirections
35
+ this.opts.body = util.wrapRequestBody(this.opts.body)
36
+ this.stripHeadersOnRedirect = normalizeStripHeaders(stripHeadersOnRedirect, 'stripHeadersOnRedirect')
37
+ this.stripHeadersOnCrossOriginRedirect = normalizeStripHeaders(stripHeadersOnCrossOriginRedirect, 'stripHeadersOnCrossOriginRedirect')
47
38
  this.maxRedirections = maxRedirections
48
39
  this.handler = handler
49
40
  this.history = []
50
-
51
- if (util.isStream(this.opts.body)) {
52
- // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp
53
- // so that it can be dispatched again?
54
- // TODO (fix): Do we need 100-expect support to provide a way to do this properly?
55
- if (util.bodyLength(this.opts.body) === 0) {
56
- this.opts.body
57
- .on('data', function () {
58
- assert(false)
59
- })
60
- }
61
-
62
- if (typeof this.opts.body.readableDidRead !== 'boolean') {
63
- this.opts.body[kBodyUsed] = false
64
- EE.prototype.on.call(this.opts.body, 'data', function () {
65
- this[kBodyUsed] = true
66
- })
67
- }
68
- } else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') {
69
- // TODO (fix): We can't access ReadableStream internal state
70
- // to determine whether or not it has been disturbed. This is just
71
- // a workaround.
72
- this.opts.body = new BodyAsyncIterable(this.opts.body)
73
- } else if (
74
- this.opts.body &&
75
- typeof this.opts.body !== 'string' &&
76
- !ArrayBuffer.isView(this.opts.body) &&
77
- util.isIterable(this.opts.body) &&
78
- !util.isFormDataLike(this.opts.body)
79
- ) {
80
- // TODO: Should we allow re-using iterable if !this.opts.idempotent
81
- // or through some other flag?
82
- this.opts.body = new BodyAsyncIterable(this.opts.body)
83
- }
84
41
  }
85
42
 
86
43
  onRequestStart (controller, context) {
87
44
  this.handler.onRequestStart?.(controller, { ...context, history: this.history })
88
45
  }
89
46
 
47
+ onBodySent (chunk) {
48
+ this.handler.onBodySent?.(chunk)
49
+ }
50
+
51
+ onRequestSent () {
52
+ this.handler.onRequestSent?.()
53
+ }
54
+
90
55
  onRequestUpgrade (controller, statusCode, headers, socket) {
91
56
  this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket)
92
57
  }
@@ -96,15 +61,19 @@ class RedirectHandler {
96
61
  throw new Error('max redirects')
97
62
  }
98
63
 
64
+ let removeContentHeaders = statusCode === 303
65
+
99
66
  // https://tools.ietf.org/html/rfc7231#section-6.4.2
100
67
  // https://fetch.spec.whatwg.org/#http-redirect-fetch
101
68
  // In case of HTTP 301 or 302 with POST, change the method to GET
69
+ // QUERY is safe (RFC 10008) and should not change method like GET.
102
70
  if ((statusCode === 301 || statusCode === 302) && this.opts.method === 'POST') {
103
71
  this.opts.method = 'GET'
104
72
  if (util.isStream(this.opts.body)) {
105
73
  util.destroy(this.opts.body.on('error', noop))
106
74
  }
107
75
  this.opts.body = null
76
+ removeContentHeaders = true
108
77
  }
109
78
 
110
79
  // https://tools.ietf.org/html/rfc7231#section-6.4.4
@@ -121,8 +90,12 @@ class RedirectHandler {
121
90
  ? null
122
91
  : headers.location
123
92
 
124
- if (this.opts.origin) {
125
- this.history.push(new URL(this.opts.path, this.opts.origin))
93
+ const requestOrigin = this.opts[kRequestOrigin] === undefined
94
+ ? this.opts.origin
95
+ : this.opts[kRequestOrigin]
96
+
97
+ if (requestOrigin) {
98
+ this.history.push(new URL(this.opts.path, requestOrigin))
126
99
  }
127
100
 
128
101
  if (!this.location) {
@@ -130,7 +103,10 @@ class RedirectHandler {
130
103
  return
131
104
  }
132
105
 
133
- const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)))
106
+ const baseUrl = requestOrigin
107
+ ? new URL(this.opts.path, requestOrigin)
108
+ : undefined
109
+ const { origin, pathname, search } = util.parseURL(new URL(this.location, baseUrl))
134
110
  const path = search ? `${pathname}${search}` : pathname
135
111
 
136
112
  // Check for redirect loops by seeing if we've already visited this URL in our history
@@ -144,11 +120,12 @@ class RedirectHandler {
144
120
  }
145
121
 
146
122
  // Remove headers referring to the original URL.
147
- // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers.
123
+ // By default it is Host only. A 303 or a 301/302 POST-to-GET redirect also removes all Content-* headers.
148
124
  // https://tools.ietf.org/html/rfc7231#section-6.4
149
- this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin)
125
+ this.opts.headers = cleanRequestHeaders(this.opts.headers, removeContentHeaders, requestOrigin !== origin, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect)
150
126
  this.opts.path = path
151
127
  this.opts.origin = origin
128
+ this.opts[kRequestOrigin] = origin
152
129
  this.opts.query = null
153
130
  }
154
131
 
@@ -198,26 +175,49 @@ class RedirectHandler {
198
175
  }
199
176
 
200
177
  // https://tools.ietf.org/html/rfc7231#section-6.4.4
201
- function shouldRemoveHeader (header, removeContent, unknownOrigin) {
202
- if (header.length === 4) {
203
- return util.headerNameToString(header) === 'host'
178
+ function shouldRemoveHeader (header, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin) {
179
+ const name = util.headerNameToString(header)
180
+ if (name === 'host') {
181
+ return true
204
182
  }
205
- if (removeContent && util.headerNameToString(header).startsWith('content-')) {
183
+ if (stripHeaders?.has(name) || (unknownOrigin && stripHeadersOnCrossOrigin?.has(name))) {
206
184
  return true
207
185
  }
208
- if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) {
209
- const name = util.headerNameToString(header)
186
+ if (removeContent && name.startsWith('content-')) {
187
+ return true
188
+ }
189
+ if (unknownOrigin) {
210
190
  return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
211
191
  }
212
192
  return false
213
193
  }
214
194
 
215
195
  // https://tools.ietf.org/html/rfc7231#section-6.4
216
- function cleanRequestHeaders (headers, removeContent, unknownOrigin) {
196
+ function normalizeStripHeaders (headers, optionName) {
197
+ if (headers == null) {
198
+ return null
199
+ }
200
+
201
+ if (!Array.isArray(headers)) {
202
+ throw new InvalidArgumentError(`${optionName} must be an array`)
203
+ }
204
+
205
+ const normalized = new Set()
206
+ for (const header of headers) {
207
+ if (typeof header !== 'string') {
208
+ throw new InvalidArgumentError(`${optionName} must contain header names`)
209
+ }
210
+
211
+ normalized.add(util.headerNameToString(header))
212
+ }
213
+ return normalized
214
+ }
215
+
216
+ function cleanRequestHeaders (headers, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin) {
217
217
  const ret = []
218
218
  if (Array.isArray(headers)) {
219
219
  for (let i = 0; i < headers.length; i += 2) {
220
- if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) {
220
+ if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin)) {
221
221
  ret.push(headers[i], headers[i + 1])
222
222
  }
223
223
  }
@@ -225,7 +225,7 @@ function cleanRequestHeaders (headers, removeContent, unknownOrigin) {
225
225
  const entries = util.hasSafeIterator(headers) ? headers : Object.entries(headers)
226
226
 
227
227
  for (const [key, value] of entries) {
228
- if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) {
228
+ if (!shouldRemoveHeader(key, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin)) {
229
229
  ret.push(key, value)
230
230
  }
231
231
  }
@@ -2,8 +2,7 @@
2
2
  const assert = require('node:assert')
3
3
 
4
4
  const { kRetryHandlerDefaultRetry } = require('../core/symbols')
5
- const { RequestRetryError } = require('../core/errors')
6
- const WrapHandler = require('./wrap-handler')
5
+ const { RequestRetryError, RequestAbortedError } = require('../core/errors')
7
6
  const {
8
7
  isDisturbed,
9
8
  parseRangeHeader,
@@ -12,7 +11,7 @@ const {
12
11
 
13
12
  function calculateRetryAfterHeader (retryAfter) {
14
13
  const retryTime = new Date(retryAfter).getTime()
15
- return isNaN(retryTime) ? 0 : retryTime - Date.now()
14
+ return isNaN(retryTime) ? null : retryTime - Date.now()
16
15
  }
17
16
 
18
17
  function validatePartialResponseContentLength (headers, range, statusCode, retryCount) {
@@ -35,6 +34,51 @@ function validatePartialResponseContentLength (headers, range, statusCode, retry
35
34
  }
36
35
  }
37
36
 
37
+ // A stable controller handed to the downstream handler for the lifetime of the
38
+ // request. Each transparent retry/resume is a *separate* dispatch with its
39
+ // *own* connection controller. Without a stable proxy the downstream body keeps
40
+ // flow-controlling the original (now-dead) controller while data flows on the
41
+ // new one: backpressure pauses the new connection's controller, but the
42
+ // consumer's resume() targets the old one, so the resumed body stalls forever.
43
+ // The proxy always forwards to the controller of the currently active connection.
44
+ // An abort is additionally reported to the handler so it can cancel a pending
45
+ // retry backoff instead of letting the request hang until the backoff elapses.
46
+ // The notification is a private callback the handler hands over on construction,
47
+ // so nothing outside the handler can trigger it.
48
+ class RetryController {
49
+ #onAbort
50
+
51
+ constructor (onAbort) {
52
+ this.#onAbort = onAbort
53
+ this.target = null
54
+ }
55
+
56
+ pause () { this.target?.pause() }
57
+ resume () { this.target?.resume() }
58
+
59
+ abort (reason) {
60
+ this.target?.abort(reason)
61
+ this.#onAbort(reason)
62
+ }
63
+
64
+ get paused () { return this.target?.paused ?? false }
65
+ get aborted () { return this.target?.aborted ?? false }
66
+ get reason () { return this.target?.reason ?? null }
67
+ get rawHeaders () { return this.target?.rawHeaders ?? null }
68
+ set rawHeaders (value) {
69
+ if (this.target) {
70
+ this.target.rawHeaders = value
71
+ }
72
+ }
73
+
74
+ get rawTrailers () { return this.target?.rawTrailers ?? null }
75
+ set rawTrailers (value) {
76
+ if (this.target) {
77
+ this.target.rawTrailers = value
78
+ }
79
+ }
80
+ }
81
+
38
82
  class RetryHandler {
39
83
  constructor (opts, { dispatch, handler }) {
40
84
  const { retryOptions, ...dispatchOpts } = opts
@@ -55,7 +99,7 @@ class RetryHandler {
55
99
 
56
100
  this.error = null
57
101
  this.dispatch = dispatch
58
- this.handler = WrapHandler.wrap(handler)
102
+ this.handler = handler
59
103
  this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) }
60
104
  this.retryOpts = {
61
105
  throwOnError: throwOnError ?? true,
@@ -66,7 +110,7 @@ class RetryHandler {
66
110
  timeoutFactor: timeoutFactor ?? 2,
67
111
  maxRetries: maxRetries ?? 5,
68
112
  // What errors we should retry
69
- methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'],
113
+ methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE', 'QUERY'],
70
114
  // Indicates which errors to retry
71
115
  statusCodes: statusCodes ?? [500, 502, 503, 504, 429],
72
116
  // List of errors to retry
@@ -89,6 +133,18 @@ class RetryHandler {
89
133
  this.start = 0
90
134
  this.end = null
91
135
  this.etag = null
136
+ this.statusCode = null
137
+ this.headers = null
138
+ this.controllerProxy = new RetryController(reason => this.#onAbort(reason))
139
+ // A retry decision is in flight (the policy may be holding a backoff
140
+ // timer). While pending, a consumer abort cancels the wait.
141
+ this.retryPending = false
142
+ // Backoff timer returned by the retry policy, so #onAbort can cancel it.
143
+ // Null for custom policies that do not return their timer.
144
+ this.retryTimer = null
145
+ // Set once an abort during the backoff delivered the terminal error
146
+ // downstream; late policy callbacks and connection errors are then moot.
147
+ this.aborted = false
92
148
  }
93
149
 
94
150
  onResponseStartWithRetry (controller, statusCode, headers, statusMessage, err) {
@@ -99,11 +155,11 @@ class RetryHandler {
99
155
  // The downstream handler already received the response from an
100
156
  // earlier attempt. Forwarding this response would replace the
101
157
  // downstream body and leave the original body pending forever.
102
- this.handler.onResponseError?.(controller, err)
158
+ this.handler.onResponseError?.(this.controllerProxy, err)
103
159
  } else {
104
160
  this.headersSent = true
105
161
  this.checkpointResponseEnd(headers)
106
- this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage)
162
+ this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage)
107
163
  }
108
164
  } else {
109
165
  this.error = err
@@ -115,21 +171,28 @@ class RetryHandler {
115
171
  if (isDisturbed(this.opts.body)) {
116
172
  this.headersSent = true
117
173
  this.checkpointResponseEnd(headers)
118
- this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage)
174
+ this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage)
119
175
  return
120
176
  }
121
177
 
122
178
  function shouldRetry (passedErr) {
179
+ if (this.aborted) {
180
+ // Aborted while the policy was deciding; the decision is moot.
181
+ return
182
+ }
183
+ this.retryPending = false
184
+ this.retryTimer = null
185
+
123
186
  if (passedErr) {
124
187
  if (this.headersSent) {
125
188
  // The downstream handler already received the response from an
126
189
  // earlier attempt. Forwarding this response would replace the
127
190
  // downstream body and leave the original body pending forever.
128
- this.handler.onResponseError?.(controller, passedErr)
191
+ this.handler.onResponseError?.(this.controllerProxy, passedErr)
129
192
  } else {
130
193
  this.headersSent = true
131
194
  this.checkpointResponseEnd(headers)
132
- this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage)
195
+ this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage)
133
196
  }
134
197
  controller.resume()
135
198
  return
@@ -139,15 +202,25 @@ class RetryHandler {
139
202
  controller.resume()
140
203
  }
141
204
 
205
+ // The pause()/resume() pair (here and in shouldRetry) acts on THIS
206
+ // connection's controller -- never the downstream proxy. We hold this exact
207
+ // connection while the retry policy decides (possibly after a timeout) and
208
+ // must resume the same one. Routing this through controllerProxy would risk
209
+ // resuming a different connection if a later dispatch re-points the proxy in
210
+ // between, leaving this one paused forever -- the very stall the proxy exists
211
+ // to prevent.
142
212
  controller.pause()
143
- this.retryOpts.retry(
213
+ // The default policy returns its backoff timer so an abort can cancel it;
214
+ // a custom policy may return anything (or nothing), which is ignored.
215
+ this.retryPending = true
216
+ this.retryTimer = this.retryOpts.retry(
144
217
  err,
145
218
  {
146
219
  state: { counter: this.retryCount },
147
220
  opts: { retryOptions: this.retryOpts, ...this.opts }
148
221
  },
149
222
  shouldRetry.bind(this)
150
- )
223
+ ) ?? null
151
224
  }
152
225
 
153
226
  checkpointResponseEnd (headers) {
@@ -165,13 +238,27 @@ class RetryHandler {
165
238
  }
166
239
 
167
240
  onRequestStart (controller, context) {
241
+ // request.js creates a fresh RequestController per dispatch and passes that
242
+ // same instance to every later callback of the dispatch. onRequestStart is
243
+ // the first callback (it is where the controller is created), so re-pointing
244
+ // the proxy here is enough to keep it on the active connection across every
245
+ // transparent retry/resume.
246
+ this.controllerProxy.target = controller
168
247
  if (!this.headersSent) {
169
- this.handler.onRequestStart?.(controller, context)
248
+ this.handler.onRequestStart?.(this.controllerProxy, context)
170
249
  }
171
250
  }
172
251
 
173
- onRequestUpgrade (controller, statusCode, headers, socket) {
174
- this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket)
252
+ onBodySent (chunk) {
253
+ this.handler.onBodySent?.(chunk)
254
+ }
255
+
256
+ onRequestSent () {
257
+ this.handler.onRequestSent?.()
258
+ }
259
+
260
+ onRequestUpgrade (_controller, statusCode, headers, socket) {
261
+ this.handler.onRequestUpgrade?.(this.controllerProxy, statusCode, headers, socket)
175
262
  }
176
263
 
177
264
  static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) {
@@ -184,7 +271,8 @@ class RetryHandler {
184
271
  timeoutFactor,
185
272
  statusCodes,
186
273
  errorCodes,
187
- methods
274
+ methods,
275
+ retryAfter
188
276
  } = retryOptions
189
277
  const { counter } = state
190
278
 
@@ -216,7 +304,7 @@ class RetryHandler {
216
304
  return
217
305
  }
218
306
 
219
- let retryAfterHeader = headers?.['retry-after']
307
+ let retryAfterHeader = retryAfter === false ? undefined : headers?.['retry-after']
220
308
  if (retryAfterHeader) {
221
309
  retryAfterHeader = Number(retryAfterHeader)
222
310
  retryAfterHeader = Number.isNaN(retryAfterHeader)
@@ -225,29 +313,28 @@ class RetryHandler {
225
313
  }
226
314
 
227
315
  const retryTimeout =
228
- retryAfterHeader > 0
229
- ? Math.min(retryAfterHeader, maxTimeout)
230
- : Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout)
231
-
232
- setTimeout(() => cb(null), retryTimeout)
316
+ retryAfterHeader === 0
317
+ ? 0
318
+ : retryAfterHeader > 0
319
+ ? Math.min(retryAfterHeader, maxTimeout)
320
+ : Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout)
321
+
322
+ // Return the backoff timer so the handler can cancel it when the
323
+ // consumer aborts while the retry decision is pending.
324
+ return setTimeout(() => cb(null), retryTimeout)
233
325
  }
234
326
 
235
327
  onResponseStart (controller, statusCode, headers, statusMessage) {
236
- this.error = null
237
- this.retryCount += 1
238
-
239
- if (statusCode >= 300) {
240
- const err = new RequestRetryError('Request failed', statusCode, {
241
- headers,
242
- data: {
243
- count: this.retryCount
244
- }
245
- })
246
-
247
- this.onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err)
328
+ if (statusCode < 200) {
329
+ this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage)
248
330
  return
249
331
  }
250
332
 
333
+ this.error = null
334
+ this.retryCount += 1
335
+ this.statusCode = statusCode
336
+ this.headers = headers
337
+
251
338
  // Checkpoint for resume from where we left it
252
339
  if (this.headersSent) {
253
340
  // Only Partial Content 206 supposed to provide Content-Range,
@@ -294,15 +381,27 @@ class RetryHandler {
294
381
  return
295
382
  }
296
383
 
384
+ if (statusCode >= 300) {
385
+ const err = new RequestRetryError('Request failed', statusCode, {
386
+ headers,
387
+ data: {
388
+ count: this.retryCount
389
+ }
390
+ })
391
+
392
+ this.onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err)
393
+ return
394
+ }
395
+
297
396
  if (this.end == null) {
298
397
  if (statusCode === 206) {
299
398
  // First time we receive 206
300
399
  const range = parseRangeHeader(headers['content-range'])
301
400
 
302
- if (range == null) {
401
+ if (range == null || range.end == null) {
303
402
  this.headersSent = true
304
403
  this.handler.onResponseStart?.(
305
- controller,
404
+ this.controllerProxy,
306
405
  statusCode,
307
406
  headers,
308
407
  statusMessage
@@ -324,7 +423,7 @@ class RetryHandler {
324
423
  }
325
424
 
326
425
  // We make our best to checkpoint the body for further range headers
327
- if (this.end == null) {
426
+ if (this.end == null && this.opts.method !== 'HEAD') {
328
427
  const contentLength = headers['content-length']
329
428
  this.end = contentLength != null ? Number(contentLength) - 1 : null
330
429
  }
@@ -351,7 +450,7 @@ class RetryHandler {
351
450
 
352
451
  this.headersSent = true
353
452
  this.handler.onResponseStart?.(
354
- controller,
453
+ this.controllerProxy,
355
454
  statusCode,
356
455
  headers,
357
456
  statusMessage
@@ -364,30 +463,40 @@ class RetryHandler {
364
463
  }
365
464
  }
366
465
 
367
- onResponseData (controller, chunk) {
466
+ onResponseData (_controller, chunk) {
368
467
  if (this.error) {
369
468
  return
370
469
  }
371
470
 
372
471
  this.start += chunk.length
373
472
 
374
- this.handler.onResponseData?.(controller, chunk)
473
+ this.handler.onResponseData?.(this.controllerProxy, chunk)
375
474
  }
376
475
 
377
- onResponseEnd (controller, trailers) {
476
+ onResponseEnd (_controller, trailers) {
378
477
  if (this.error && this.retryOpts.throwOnError) {
379
478
  throw this.error
380
479
  }
381
480
 
382
481
  if (!this.error) {
482
+ // Verify that the received body length matches the expected range
483
+ // when we have a finite end position (from Content-Length or Content-Range)
484
+ if (this.end != null && Number.isFinite(this.end)) {
485
+ if (this.start !== this.end + 1) {
486
+ throw new RequestRetryError('Content-Range mismatch', this.statusCode, {
487
+ headers: this.headers,
488
+ data: { count: this.retryCount }
489
+ })
490
+ }
491
+ }
383
492
  this.retryCount = 0
384
- return this.handler.onResponseEnd?.(controller, trailers)
493
+ return this.handler.onResponseEnd?.(this.controllerProxy, trailers)
385
494
  }
386
495
 
387
- this.retry(controller)
496
+ this.retry()
388
497
  }
389
498
 
390
- retry (controller) {
499
+ retry () {
391
500
  if (this.start !== 0) {
392
501
  const headers = { range: `bytes=${this.start}-${this.end ?? ''}` }
393
502
 
@@ -409,23 +518,38 @@ class RetryHandler {
409
518
  this.retryCountCheckpoint = this.retryCount
410
519
  this.dispatch(this.opts, this)
411
520
  } catch (err) {
412
- this.handler.onResponseError?.(controller, err)
521
+ this.handler.onResponseError?.(this.controllerProxy, err)
413
522
  }
414
523
  }
415
524
 
416
525
  onResponseError (controller, err) {
526
+ if (this.aborted) {
527
+ // #onAbort already delivered the terminal error downstream; the late
528
+ // error of the torn-down connection must not be forwarded twice.
529
+ return
530
+ }
531
+
532
+ // controller is THIS failed connection (not the proxy): we inspect whether
533
+ // the consumer aborted it to decide retry-vs-propagate.
417
534
  if (controller?.aborted || isDisturbed(this.opts.body) || (this.headersSent && !this.resume)) {
418
- this.handler.onResponseError?.(controller, err)
535
+ this.handler.onResponseError?.(this.controllerProxy, err)
419
536
  return
420
537
  }
421
538
 
422
539
  function shouldRetry (returnedErr) {
540
+ if (this.aborted) {
541
+ // Aborted while the policy was deciding; the decision is moot.
542
+ return
543
+ }
544
+ this.retryPending = false
545
+ this.retryTimer = null
546
+
423
547
  if (!returnedErr) {
424
- this.retry(controller)
548
+ this.retry()
425
549
  return
426
550
  }
427
551
 
428
- this.handler?.onResponseError?.(controller, returnedErr)
552
+ this.handler?.onResponseError?.(this.controllerProxy, returnedErr)
429
553
  }
430
554
 
431
555
  // We reconcile in case of a mix between network errors
@@ -439,14 +563,31 @@ class RetryHandler {
439
563
  this.retryCount += 1
440
564
  }
441
565
 
442
- this.retryOpts.retry(
566
+ this.retryPending = true
567
+ this.retryTimer = this.retryOpts.retry(
443
568
  err,
444
569
  {
445
570
  state: { counter: this.retryCount },
446
571
  opts: { retryOptions: this.retryOpts, ...this.opts }
447
572
  },
448
573
  shouldRetry.bind(this)
449
- )
574
+ ) ?? null
575
+ }
576
+
577
+ #onAbort (reason) {
578
+ // A consumer abort lands on the controller proxy. If the retry policy is
579
+ // still deciding (typically holding a backoff timer), cancel the wait and
580
+ // surface the abort immediately instead of letting the request hang until
581
+ // the backoff elapses.
582
+ if (!this.retryPending) {
583
+ return
584
+ }
585
+
586
+ this.aborted = true
587
+ this.retryPending = false
588
+ clearTimeout(this.retryTimer)
589
+ this.retryTimer = null
590
+ this.handler.onResponseError?.(this.controllerProxy, reason ?? new RequestAbortedError())
450
591
  }
451
592
  }
452
593