@openclaw/discord 2026.5.2 → 2026.5.3-beta.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 (612) hide show
  1. package/dist/access-B9ujuUtS.js +89 -0
  2. package/dist/account-inspect-C2UEUhbG.js +81 -0
  3. package/dist/account-inspect-api.js +10 -0
  4. package/dist/accounts-BKnkNaoA.js +128 -0
  5. package/dist/action-runtime-api.js +2 -0
  6. package/dist/agent-components.runtime-DUhLr9hy.js +4 -0
  7. package/dist/allow-list-ek-1hMKN.js +336 -0
  8. package/dist/api-DzNBVTto.js +130 -0
  9. package/dist/api.js +24 -0
  10. package/dist/approval-handler.runtime-v8nzQHlT.js +426 -0
  11. package/dist/approval-native-DqWGp0bM.js +153 -0
  12. package/dist/approval-shared-DKnwwjZM.js +93 -0
  13. package/dist/audit-CJ92YD6J.js +102 -0
  14. package/dist/channel-B3aTtBj1.js +745 -0
  15. package/dist/channel-access-ewDxhd9q.js +62 -0
  16. package/dist/channel-actions-TNih7k3w.js +140 -0
  17. package/dist/channel-actions.runtime-CaPytiY4.js +236 -0
  18. package/dist/channel-api-CTSWMrnD.js +21 -0
  19. package/dist/channel-config-api.js +2 -0
  20. package/dist/channel-plugin-api.js +2 -0
  21. package/dist/channel.setup-Dt4tIDrl.js +336 -0
  22. package/dist/components-BapWDmDM.js +760 -0
  23. package/dist/config-api-CFZtoMaS.js +2 -0
  24. package/dist/config-schema-DwFkL904.js +252 -0
  25. package/dist/configured-state.js +6 -0
  26. package/dist/contract-api.js +8 -0
  27. package/dist/conversation-identity-BN9wSmxJ.js +31 -0
  28. package/dist/directory-cache-D93eSrpB.js +62 -0
  29. package/dist/directory-config-LyMP0sdv.js +49 -0
  30. package/dist/directory-contract-api.js +2 -0
  31. package/dist/directory-live-BQapdpkZ.js +101 -0
  32. package/dist/discord-D1kDh0X_.js +2751 -0
  33. package/dist/doctor-B2G7WqO0.js +244 -0
  34. package/dist/doctor-contract-D3pSutkb.js +383 -0
  35. package/dist/doctor-contract-api.js +2 -0
  36. package/dist/doctor-shared-DU8RcnF5.js +4 -0
  37. package/dist/format-D8TsaXxW.js +24 -0
  38. package/dist/gateway-registry-BKG4KIVC.js +74 -0
  39. package/dist/handle-action.guild-admin-BuqsSVXu.js +283 -0
  40. package/dist/inbound-context-e_oBBJtF.js +51 -0
  41. package/dist/index.js +26 -0
  42. package/dist/manager.runtime-M2aAa7qA.js +1019 -0
  43. package/dist/mentions-BPZUaFk7.js +88 -0
  44. package/dist/message-handler-D6JfFV3P.js +381 -0
  45. package/dist/message-handler.preflight-DqaF3vHm.js +1022 -0
  46. package/dist/message-handler.process-tl3Nwnhr.js +1124 -0
  47. package/dist/message-utils-Dmgu-7fC.js +512 -0
  48. package/dist/normalize-B-ktw-T_.js +275 -0
  49. package/dist/outbound-adapter-DJf9_sfH.js +451 -0
  50. package/dist/outbound-session-route-uHGLDP-Y.js +43 -0
  51. package/dist/pluralkit-voQvSN3g.js +22 -0
  52. package/dist/preflight-audio-BpYtUAT6.js +72 -0
  53. package/dist/preflight-audio.runtime-BAGmU6uO.js +7 -0
  54. package/dist/preview-streaming-C0O92Qqz.js +14 -0
  55. package/dist/probe-DcNEodPI.js +139 -0
  56. package/dist/probe.runtime-P-e4r1Hl.js +2 -0
  57. package/dist/provider-CMvXOp-3.js +8440 -0
  58. package/dist/provider-session.runtime-JFemrDZT.js +6 -0
  59. package/dist/provider.runtime-BO007oR2.js +2 -0
  60. package/dist/reply-delivery-D9So77a6.js +131 -0
  61. package/dist/resolve-allowlist-common-DqqFY_qa.js +34 -0
  62. package/dist/resolve-channels-CGPntufJ.js +265 -0
  63. package/dist/resolve-users-CDvSlW0V.js +120 -0
  64. package/dist/rolldown-runtime-C3SqQTfK.js +28 -0
  65. package/dist/route-resolution-BYiC-6Cc.js +236 -0
  66. package/dist/runtime-K9RT6Egn.js +8 -0
  67. package/dist/runtime-api.actions.js +3 -0
  68. package/dist/runtime-api.js +31 -0
  69. package/dist/runtime-api.lookup.js +7 -0
  70. package/dist/runtime-api.monitor-BC-XN0tY.js +6 -0
  71. package/dist/runtime-api.monitor.js +9 -0
  72. package/dist/runtime-api.send.js +6 -0
  73. package/dist/runtime-api.threads.js +6 -0
  74. package/dist/runtime-n5xZHW55.js +1001 -0
  75. package/dist/runtime-setter-api.js +2 -0
  76. package/dist/secret-config-contract-CoGryS5c.js +115 -0
  77. package/dist/secret-contract-api.js +2 -0
  78. package/dist/security-audit-Cdz2iq3m.js +120 -0
  79. package/dist/security-audit-contract-api.js +2 -0
  80. package/dist/security-audit.runtime-DBV1T1_N.js +2 -0
  81. package/dist/security-contract-api.js +2 -0
  82. package/dist/security-contract-ei3Mz8Sa.js +26 -0
  83. package/dist/security-doctor-CzTzpXV8.js +18 -0
  84. package/dist/send-B_frVn_Q.js +845 -0
  85. package/dist/send.components-B1EgHAds.js +468 -0
  86. package/dist/send.outbound-DlBAuW7y.js +211 -0
  87. package/dist/send.shared-Db0opnak.js +708 -0
  88. package/dist/sender-identity-BiSDAk2P.js +43 -0
  89. package/dist/session-contract-goJZckp2.js +6 -0
  90. package/dist/session-key-api.js +2 -0
  91. package/dist/session-key-normalization-Daag9II6.js +23 -0
  92. package/dist/setup-entry.js +11 -0
  93. package/dist/setup-plugin-api.js +2 -0
  94. package/dist/shared-CqlrJmSs.js +166 -0
  95. package/dist/shared-interactive-KgJjCqnB.js +79 -0
  96. package/dist/subagent-hooks-api.js +22 -0
  97. package/dist/subagent-hooks-mEK5ARfP.js +113 -0
  98. package/dist/system-events-Bu9jmO4W.js +34 -0
  99. package/dist/targets-kKlbZ4ai.js +3 -0
  100. package/dist/test-api.js +45 -0
  101. package/dist/thread-binding-api.js +4 -0
  102. package/dist/thread-bindings-Bj1R-6QH.js +256 -0
  103. package/dist/thread-bindings.discord-api-ClPMuIr8.js +184 -0
  104. package/dist/thread-bindings.manager-BaN0l4y8.js +535 -0
  105. package/dist/thread-bindings.session-updates-TTP020qQ.js +54 -0
  106. package/dist/thread-bindings.state-Dzu1gCE7.js +318 -0
  107. package/dist/threading-CWhdYHVx.js +475 -0
  108. package/dist/timeouts-C7jeTtGs.js +52 -0
  109. package/dist/timeouts.js +2 -0
  110. package/dist/token-D-w3Rigl.js +42 -0
  111. package/dist/typing-CJiowRTZ.js +15 -0
  112. package/package.json +14 -6
  113. package/account-inspect-api.ts +0 -6
  114. package/action-runtime-api.ts +0 -1
  115. package/api.ts +0 -132
  116. package/channel-config-api.ts +0 -1
  117. package/channel-plugin-api.ts +0 -3
  118. package/config-api.ts +0 -4
  119. package/configured-state.ts +0 -6
  120. package/contract-api.ts +0 -21
  121. package/directory-contract-api.ts +0 -4
  122. package/doctor-contract-api.ts +0 -1
  123. package/index.test.ts +0 -13
  124. package/index.ts +0 -24
  125. package/runtime-api.actions.ts +0 -15
  126. package/runtime-api.lookup.ts +0 -22
  127. package/runtime-api.monitor.ts +0 -50
  128. package/runtime-api.send.ts +0 -79
  129. package/runtime-api.threads.ts +0 -30
  130. package/runtime-api.ts +0 -180
  131. package/runtime-setter-api.ts +0 -3
  132. package/secret-contract-api.ts +0 -4
  133. package/security-audit-contract-api.ts +0 -1
  134. package/security-contract-api.ts +0 -4
  135. package/session-key-api.ts +0 -1
  136. package/setup-entry.ts +0 -9
  137. package/setup-plugin-api.ts +0 -3
  138. package/src/account-inspect.test.ts +0 -126
  139. package/src/account-inspect.ts +0 -132
  140. package/src/accounts.test.ts +0 -247
  141. package/src/accounts.ts +0 -196
  142. package/src/actions/handle-action.guild-admin.ts +0 -411
  143. package/src/actions/handle-action.test.ts +0 -306
  144. package/src/actions/handle-action.ts +0 -372
  145. package/src/actions/runtime.guild.ts +0 -446
  146. package/src/actions/runtime.messaging.messages.ts +0 -205
  147. package/src/actions/runtime.messaging.reactions.ts +0 -67
  148. package/src/actions/runtime.messaging.runtime.ts +0 -69
  149. package/src/actions/runtime.messaging.send.ts +0 -248
  150. package/src/actions/runtime.messaging.shared.ts +0 -97
  151. package/src/actions/runtime.messaging.ts +0 -37
  152. package/src/actions/runtime.moderation-shared.ts +0 -48
  153. package/src/actions/runtime.moderation.authz.test.ts +0 -151
  154. package/src/actions/runtime.moderation.ts +0 -116
  155. package/src/actions/runtime.presence.test.ts +0 -160
  156. package/src/actions/runtime.presence.ts +0 -117
  157. package/src/actions/runtime.shared.ts +0 -83
  158. package/src/actions/runtime.test.ts +0 -1087
  159. package/src/actions/runtime.ts +0 -87
  160. package/src/api-barrel.test.ts +0 -80
  161. package/src/api.test.ts +0 -130
  162. package/src/api.ts +0 -169
  163. package/src/approval-handler.runtime.test.ts +0 -41
  164. package/src/approval-handler.runtime.ts +0 -632
  165. package/src/approval-native.test.ts +0 -330
  166. package/src/approval-native.ts +0 -219
  167. package/src/approval-runtime.ts +0 -14
  168. package/src/approval-shared.ts +0 -53
  169. package/src/audit-core.ts +0 -141
  170. package/src/audit.test.ts +0 -145
  171. package/src/audit.ts +0 -32
  172. package/src/channel-actions.contract.test.ts +0 -45
  173. package/src/channel-actions.runtime.ts +0 -1
  174. package/src/channel-actions.test.ts +0 -275
  175. package/src/channel-actions.ts +0 -203
  176. package/src/channel-api.ts +0 -29
  177. package/src/channel.conversation.ts +0 -159
  178. package/src/channel.loaders.ts +0 -47
  179. package/src/channel.runtime.ts +0 -1
  180. package/src/channel.setup.ts +0 -12
  181. package/src/channel.test.ts +0 -571
  182. package/src/channel.ts +0 -629
  183. package/src/chunk.test.ts +0 -157
  184. package/src/chunk.ts +0 -321
  185. package/src/client.proxy.test.ts +0 -176
  186. package/src/client.test.ts +0 -76
  187. package/src/client.ts +0 -132
  188. package/src/component-custom-id.ts +0 -72
  189. package/src/components-registry.ts +0 -356
  190. package/src/components.builders.ts +0 -409
  191. package/src/components.modal.ts +0 -124
  192. package/src/components.parse.ts +0 -407
  193. package/src/components.test.ts +0 -312
  194. package/src/components.ts +0 -54
  195. package/src/components.types.ts +0 -187
  196. package/src/config-schema.test.ts +0 -325
  197. package/src/config-schema.ts +0 -6
  198. package/src/config-ui-hints.ts +0 -249
  199. package/src/conversation-identity.ts +0 -58
  200. package/src/delivery-retry.ts +0 -56
  201. package/src/directory-cache.ts +0 -116
  202. package/src/directory-config.ts +0 -58
  203. package/src/directory-contract.test.ts +0 -129
  204. package/src/directory-live.test.ts +0 -126
  205. package/src/directory-live.ts +0 -135
  206. package/src/doctor-contract.ts +0 -477
  207. package/src/doctor-shared.ts +0 -5
  208. package/src/doctor.test.ts +0 -405
  209. package/src/doctor.ts +0 -340
  210. package/src/draft-chunking.test.ts +0 -64
  211. package/src/draft-chunking.ts +0 -43
  212. package/src/draft-stream.test.ts +0 -159
  213. package/src/draft-stream.ts +0 -154
  214. package/src/error-body.ts +0 -38
  215. package/src/exec-approvals.test.ts +0 -88
  216. package/src/exec-approvals.ts +0 -110
  217. package/src/gateway-logging.test.ts +0 -98
  218. package/src/gateway-logging.ts +0 -67
  219. package/src/group-policy.ts +0 -113
  220. package/src/guilds.ts +0 -29
  221. package/src/inbound-context.contract.test.ts +0 -11
  222. package/src/interactive-dispatch.ts +0 -104
  223. package/src/internal/api.commands.ts +0 -51
  224. package/src/internal/api.guild.ts +0 -164
  225. package/src/internal/api.interactions.ts +0 -53
  226. package/src/internal/api.messages.ts +0 -113
  227. package/src/internal/api.reactions.ts +0 -38
  228. package/src/internal/api.test.ts +0 -262
  229. package/src/internal/api.ts +0 -61
  230. package/src/internal/api.users.ts +0 -19
  231. package/src/internal/api.webhooks.ts +0 -13
  232. package/src/internal/client.test.ts +0 -440
  233. package/src/internal/client.ts +0 -310
  234. package/src/internal/command-deploy.ts +0 -297
  235. package/src/internal/commands.ts +0 -188
  236. package/src/internal/components.base.ts +0 -65
  237. package/src/internal/components.message.ts +0 -279
  238. package/src/internal/components.modal.ts +0 -95
  239. package/src/internal/components.ts +0 -31
  240. package/src/internal/discord.ts +0 -11
  241. package/src/internal/embeds.ts +0 -35
  242. package/src/internal/entity-cache.ts +0 -98
  243. package/src/internal/event-queue.ts +0 -162
  244. package/src/internal/gateway-close-codes.ts +0 -25
  245. package/src/internal/gateway-dispatch.ts +0 -96
  246. package/src/internal/gateway-identify-limiter.ts +0 -26
  247. package/src/internal/gateway-lifecycle.ts +0 -61
  248. package/src/internal/gateway-rate-limit.ts +0 -104
  249. package/src/internal/gateway.test.ts +0 -603
  250. package/src/internal/gateway.ts +0 -476
  251. package/src/internal/interaction-dispatch.test.ts +0 -148
  252. package/src/internal/interaction-dispatch.ts +0 -162
  253. package/src/internal/interaction-options.ts +0 -98
  254. package/src/internal/interaction-response.ts +0 -53
  255. package/src/internal/interactions.test.ts +0 -325
  256. package/src/internal/interactions.ts +0 -378
  257. package/src/internal/listeners.ts +0 -85
  258. package/src/internal/live-smoke.live.test.ts +0 -26
  259. package/src/internal/modal-fields.ts +0 -95
  260. package/src/internal/payload.ts +0 -69
  261. package/src/internal/rest-body.ts +0 -115
  262. package/src/internal/rest-errors.ts +0 -88
  263. package/src/internal/rest-routes.ts +0 -50
  264. package/src/internal/rest-scheduler.ts +0 -557
  265. package/src/internal/rest.test.ts +0 -673
  266. package/src/internal/rest.ts +0 -322
  267. package/src/internal/schemas.ts +0 -36
  268. package/src/internal/structures.test.ts +0 -43
  269. package/src/internal/structures.ts +0 -280
  270. package/src/internal/test-builders.test-support.ts +0 -167
  271. package/src/internal/voice.ts +0 -49
  272. package/src/media-detection.ts +0 -28
  273. package/src/mentions.test.ts +0 -111
  274. package/src/mentions.ts +0 -147
  275. package/src/monitor/access-groups.ts +0 -55
  276. package/src/monitor/ack-reactions.ts +0 -70
  277. package/src/monitor/acp-bind-here.integration.test.ts +0 -211
  278. package/src/monitor/agent-components-auth.ts +0 -7
  279. package/src/monitor/agent-components-context.ts +0 -154
  280. package/src/monitor/agent-components-data.ts +0 -224
  281. package/src/monitor/agent-components-dm-auth.ts +0 -221
  282. package/src/monitor/agent-components-guild-auth.ts +0 -322
  283. package/src/monitor/agent-components-helpers.runtime.ts +0 -5
  284. package/src/monitor/agent-components-helpers.ts +0 -34
  285. package/src/monitor/agent-components-reply.ts +0 -10
  286. package/src/monitor/agent-components.deps.runtime.ts +0 -2
  287. package/src/monitor/agent-components.dispatch.ts +0 -366
  288. package/src/monitor/agent-components.handlers.ts +0 -303
  289. package/src/monitor/agent-components.modal.ts +0 -160
  290. package/src/monitor/agent-components.plugin-interactive.ts +0 -187
  291. package/src/monitor/agent-components.runtime.ts +0 -14
  292. package/src/monitor/agent-components.system-controls.ts +0 -211
  293. package/src/monitor/agent-components.ts +0 -70
  294. package/src/monitor/agent-components.types.ts +0 -58
  295. package/src/monitor/agent-components.wildcard-controls.ts +0 -168
  296. package/src/monitor/agent-components.wildcard.test.ts +0 -71
  297. package/src/monitor/allow-list.test.ts +0 -14
  298. package/src/monitor/allow-list.ts +0 -633
  299. package/src/monitor/auto-presence.test.ts +0 -156
  300. package/src/monitor/auto-presence.ts +0 -356
  301. package/src/monitor/channel-access.test.ts +0 -99
  302. package/src/monitor/channel-access.ts +0 -102
  303. package/src/monitor/commands.test.ts +0 -24
  304. package/src/monitor/commands.ts +0 -9
  305. package/src/monitor/dm-command-auth.test.ts +0 -197
  306. package/src/monitor/dm-command-auth.ts +0 -158
  307. package/src/monitor/dm-command-decision.test.ts +0 -113
  308. package/src/monitor/dm-command-decision.ts +0 -49
  309. package/src/monitor/exec-approvals.test.ts +0 -226
  310. package/src/monitor/exec-approvals.ts +0 -158
  311. package/src/monitor/format.ts +0 -45
  312. package/src/monitor/gateway-handle.ts +0 -34
  313. package/src/monitor/gateway-metadata.test.ts +0 -29
  314. package/src/monitor/gateway-metadata.ts +0 -298
  315. package/src/monitor/gateway-plugin.test.ts +0 -297
  316. package/src/monitor/gateway-plugin.ts +0 -294
  317. package/src/monitor/gateway-registry.ts +0 -37
  318. package/src/monitor/gateway-supervisor.test.ts +0 -150
  319. package/src/monitor/gateway-supervisor.ts +0 -206
  320. package/src/monitor/inbound-context.test-helpers.ts +0 -37
  321. package/src/monitor/inbound-context.test.ts +0 -106
  322. package/src/monitor/inbound-context.ts +0 -103
  323. package/src/monitor/inbound-dedupe.ts +0 -79
  324. package/src/monitor/inbound-job.test.ts +0 -203
  325. package/src/monitor/inbound-job.ts +0 -118
  326. package/src/monitor/listeners.queue.ts +0 -91
  327. package/src/monitor/listeners.reactions.ts +0 -610
  328. package/src/monitor/listeners.test.ts +0 -200
  329. package/src/monitor/listeners.ts +0 -150
  330. package/src/monitor/message-channel-info.ts +0 -96
  331. package/src/monitor/message-forwarded.ts +0 -107
  332. package/src/monitor/message-handler.batch-gate.test.ts +0 -22
  333. package/src/monitor/message-handler.batch-gate.ts +0 -19
  334. package/src/monitor/message-handler.bot-self-filter.test.ts +0 -68
  335. package/src/monitor/message-handler.context.ts +0 -406
  336. package/src/monitor/message-handler.dm-preflight.ts +0 -123
  337. package/src/monitor/message-handler.draft-preview.ts +0 -246
  338. package/src/monitor/message-handler.hydration.test.ts +0 -80
  339. package/src/monitor/message-handler.hydration.ts +0 -198
  340. package/src/monitor/message-handler.inbound-context.test.ts +0 -59
  341. package/src/monitor/message-handler.module-test-helpers.ts +0 -31
  342. package/src/monitor/message-handler.preflight-channel-access.ts +0 -86
  343. package/src/monitor/message-handler.preflight-channel-context.test.ts +0 -18
  344. package/src/monitor/message-handler.preflight-channel-context.ts +0 -58
  345. package/src/monitor/message-handler.preflight-context.ts +0 -54
  346. package/src/monitor/message-handler.preflight-helpers.ts +0 -164
  347. package/src/monitor/message-handler.preflight-history.ts +0 -23
  348. package/src/monitor/message-handler.preflight-logging.ts +0 -36
  349. package/src/monitor/message-handler.preflight-pluralkit.ts +0 -26
  350. package/src/monitor/message-handler.preflight-runtime.ts +0 -28
  351. package/src/monitor/message-handler.preflight-thread.ts +0 -49
  352. package/src/monitor/message-handler.preflight.acp-bindings.test.ts +0 -369
  353. package/src/monitor/message-handler.preflight.test-helpers.ts +0 -111
  354. package/src/monitor/message-handler.preflight.test.ts +0 -1623
  355. package/src/monitor/message-handler.preflight.ts +0 -679
  356. package/src/monitor/message-handler.preflight.types.ts +0 -110
  357. package/src/monitor/message-handler.process.test.ts +0 -1369
  358. package/src/monitor/message-handler.process.ts +0 -686
  359. package/src/monitor/message-handler.queue.test.ts +0 -496
  360. package/src/monitor/message-handler.routing-preflight.ts +0 -112
  361. package/src/monitor/message-handler.test-harness.ts +0 -99
  362. package/src/monitor/message-handler.test-helpers.ts +0 -75
  363. package/src/monitor/message-handler.ts +0 -274
  364. package/src/monitor/message-media.ts +0 -509
  365. package/src/monitor/message-run-queue.ts +0 -101
  366. package/src/monitor/message-text.ts +0 -171
  367. package/src/monitor/message-utils.test.ts +0 -1157
  368. package/src/monitor/message-utils.ts +0 -32
  369. package/src/monitor/model-picker-preferences.test.ts +0 -67
  370. package/src/monitor/model-picker-preferences.ts +0 -184
  371. package/src/monitor/model-picker.state.ts +0 -364
  372. package/src/monitor/model-picker.test-utils.ts +0 -26
  373. package/src/monitor/model-picker.test.ts +0 -794
  374. package/src/monitor/model-picker.ts +0 -38
  375. package/src/monitor/model-picker.view.ts +0 -695
  376. package/src/monitor/monitor.agent-components.test.ts +0 -375
  377. package/src/monitor/monitor.test.ts +0 -849
  378. package/src/monitor/monitor.threading-utils.test.ts +0 -598
  379. package/src/monitor/native-command-agent-reply.ts +0 -125
  380. package/src/monitor/native-command-arg-ui.ts +0 -233
  381. package/src/monitor/native-command-auth.ts +0 -308
  382. package/src/monitor/native-command-bypass.ts +0 -13
  383. package/src/monitor/native-command-context.test.ts +0 -98
  384. package/src/monitor/native-command-context.ts +0 -103
  385. package/src/monitor/native-command-dispatch.ts +0 -35
  386. package/src/monitor/native-command-model-picker-apply.ts +0 -177
  387. package/src/monitor/native-command-model-picker-interaction.ts +0 -461
  388. package/src/monitor/native-command-model-picker-ui.ts +0 -368
  389. package/src/monitor/native-command-reply.test.ts +0 -68
  390. package/src/monitor/native-command-reply.ts +0 -185
  391. package/src/monitor/native-command-route.ts +0 -91
  392. package/src/monitor/native-command-status.ts +0 -76
  393. package/src/monitor/native-command-ui.ts +0 -26
  394. package/src/monitor/native-command-ui.types.ts +0 -20
  395. package/src/monitor/native-command.args.ts +0 -45
  396. package/src/monitor/native-command.command-arg.test.ts +0 -99
  397. package/src/monitor/native-command.commands-allowfrom.test.ts +0 -490
  398. package/src/monitor/native-command.model-picker.test.ts +0 -767
  399. package/src/monitor/native-command.options.test.ts +0 -369
  400. package/src/monitor/native-command.options.ts +0 -153
  401. package/src/monitor/native-command.plugin-dispatch.test.ts +0 -961
  402. package/src/monitor/native-command.runtime.ts +0 -50
  403. package/src/monitor/native-command.status-direct.test.ts +0 -272
  404. package/src/monitor/native-command.test-helpers.ts +0 -64
  405. package/src/monitor/native-command.think-autocomplete.test.ts +0 -416
  406. package/src/monitor/native-command.ts +0 -700
  407. package/src/monitor/native-command.types.ts +0 -9
  408. package/src/monitor/native-interaction-channel-context.ts +0 -50
  409. package/src/monitor/preflight-audio.runtime.ts +0 -9
  410. package/src/monitor/preflight-audio.test.ts +0 -157
  411. package/src/monitor/preflight-audio.ts +0 -130
  412. package/src/monitor/presence-cache.ts +0 -61
  413. package/src/monitor/presence.test.ts +0 -44
  414. package/src/monitor/presence.ts +0 -50
  415. package/src/monitor/provider-session.runtime.ts +0 -12
  416. package/src/monitor/provider.acp.ts +0 -89
  417. package/src/monitor/provider.allowlist.test.ts +0 -149
  418. package/src/monitor/provider.allowlist.ts +0 -394
  419. package/src/monitor/provider.cleanup.ts +0 -41
  420. package/src/monitor/provider.commands.ts +0 -129
  421. package/src/monitor/provider.config-log.ts +0 -45
  422. package/src/monitor/provider.deploy-errors.ts +0 -362
  423. package/src/monitor/provider.deploy.ts +0 -221
  424. package/src/monitor/provider.interactions.ts +0 -160
  425. package/src/monitor/provider.lifecycle.test.ts +0 -713
  426. package/src/monitor/provider.lifecycle.ts +0 -552
  427. package/src/monitor/provider.proxy.test.ts +0 -745
  428. package/src/monitor/provider.rest-proxy.test.ts +0 -121
  429. package/src/monitor/provider.runtime.ts +0 -1
  430. package/src/monitor/provider.skill-dedupe.test.ts +0 -42
  431. package/src/monitor/provider.startup-log.ts +0 -32
  432. package/src/monitor/provider.startup.test.ts +0 -426
  433. package/src/monitor/provider.startup.ts +0 -330
  434. package/src/monitor/provider.test.ts +0 -1111
  435. package/src/monitor/provider.ts +0 -713
  436. package/src/monitor/reply-context.ts +0 -64
  437. package/src/monitor/reply-delivery.test.ts +0 -244
  438. package/src/monitor/reply-delivery.ts +0 -203
  439. package/src/monitor/rest-fetch.ts +0 -43
  440. package/src/monitor/route-resolution.test.ts +0 -204
  441. package/src/monitor/route-resolution.ts +0 -140
  442. package/src/monitor/sender-identity.ts +0 -81
  443. package/src/monitor/startup-status.test.ts +0 -30
  444. package/src/monitor/startup-status.ts +0 -10
  445. package/src/monitor/status.ts +0 -22
  446. package/src/monitor/system-events.ts +0 -55
  447. package/src/monitor/thread-bindings.config.ts +0 -35
  448. package/src/monitor/thread-bindings.discord-api.test.ts +0 -229
  449. package/src/monitor/thread-bindings.discord-api.ts +0 -310
  450. package/src/monitor/thread-bindings.lifecycle.test.ts +0 -1871
  451. package/src/monitor/thread-bindings.lifecycle.ts +0 -354
  452. package/src/monitor/thread-bindings.manager.ts +0 -553
  453. package/src/monitor/thread-bindings.messages.ts +0 -6
  454. package/src/monitor/thread-bindings.persona.test.ts +0 -34
  455. package/src/monitor/thread-bindings.persona.ts +0 -25
  456. package/src/monitor/thread-bindings.session-adapter.ts +0 -229
  457. package/src/monitor/thread-bindings.session-shared.ts +0 -59
  458. package/src/monitor/thread-bindings.session-updates.ts +0 -35
  459. package/src/monitor/thread-bindings.shared-state.test.ts +0 -36
  460. package/src/monitor/thread-bindings.state.ts +0 -540
  461. package/src/monitor/thread-bindings.ts +0 -48
  462. package/src/monitor/thread-bindings.types.ts +0 -83
  463. package/src/monitor/thread-channel-context.ts +0 -112
  464. package/src/monitor/thread-session-close.test.ts +0 -180
  465. package/src/monitor/thread-session-close.ts +0 -63
  466. package/src/monitor/thread-title.generate.test.ts +0 -197
  467. package/src/monitor/thread-title.test.ts +0 -31
  468. package/src/monitor/thread-title.ts +0 -181
  469. package/src/monitor/threading.auto-thread.test.ts +0 -327
  470. package/src/monitor/threading.auto-thread.ts +0 -287
  471. package/src/monitor/threading.cache.ts +0 -45
  472. package/src/monitor/threading.parent-info.test.ts +0 -156
  473. package/src/monitor/threading.starter.test.ts +0 -260
  474. package/src/monitor/threading.starter.ts +0 -287
  475. package/src/monitor/threading.ts +0 -20
  476. package/src/monitor/threading.types.ts +0 -102
  477. package/src/monitor/timeouts.ts +0 -84
  478. package/src/monitor/typing.test.ts +0 -42
  479. package/src/monitor/typing.ts +0 -17
  480. package/src/monitor.gateway.test.ts +0 -187
  481. package/src/monitor.gateway.ts +0 -75
  482. package/src/monitor.test.ts +0 -1397
  483. package/src/monitor.ts +0 -28
  484. package/src/normalize.test.ts +0 -56
  485. package/src/normalize.ts +0 -86
  486. package/src/outbound-adapter.interactive-order.test.ts +0 -64
  487. package/src/outbound-adapter.test-harness.ts +0 -207
  488. package/src/outbound-adapter.test.ts +0 -696
  489. package/src/outbound-adapter.ts +0 -291
  490. package/src/outbound-approval.ts +0 -29
  491. package/src/outbound-components.ts +0 -81
  492. package/src/outbound-payload.contract.test.ts +0 -38
  493. package/src/outbound-payload.ts +0 -134
  494. package/src/outbound-send-context.ts +0 -92
  495. package/src/outbound-session-route.test.ts +0 -34
  496. package/src/outbound-session-route.ts +0 -72
  497. package/src/pluralkit.test.ts +0 -67
  498. package/src/pluralkit.ts +0 -58
  499. package/src/preview-streaming.ts +0 -32
  500. package/src/probe.intents.test.ts +0 -94
  501. package/src/probe.parse-token.test.ts +0 -43
  502. package/src/probe.runtime.ts +0 -1
  503. package/src/probe.ts +0 -237
  504. package/src/proxy-fetch.ts +0 -92
  505. package/src/proxy-request-client.test.ts +0 -78
  506. package/src/proxy-request-client.ts +0 -21
  507. package/src/recipient-resolution.ts +0 -39
  508. package/src/resolve-allowlist-common.test.ts +0 -36
  509. package/src/resolve-allowlist-common.ts +0 -39
  510. package/src/resolve-channels.test.ts +0 -340
  511. package/src/resolve-channels.ts +0 -369
  512. package/src/resolve-users.test.ts +0 -222
  513. package/src/resolve-users.ts +0 -184
  514. package/src/retry.test.ts +0 -83
  515. package/src/retry.ts +0 -98
  516. package/src/runtime-api.ts +0 -64
  517. package/src/runtime.ts +0 -23
  518. package/src/secret-config-contract.ts +0 -140
  519. package/src/security-audit.runtime.ts +0 -1
  520. package/src/security-audit.test.ts +0 -246
  521. package/src/security-audit.ts +0 -208
  522. package/src/security-contract.ts +0 -47
  523. package/src/security-doctor.test.ts +0 -25
  524. package/src/security-doctor.ts +0 -20
  525. package/src/security.ts +0 -60
  526. package/src/send-target-parsing.ts +0 -14
  527. package/src/send.channels.ts +0 -139
  528. package/src/send.components.test.ts +0 -275
  529. package/src/send.components.ts +0 -381
  530. package/src/send.creates-thread.test.ts +0 -643
  531. package/src/send.emojis-stickers.ts +0 -57
  532. package/src/send.guild.ts +0 -170
  533. package/src/send.message-request.ts +0 -97
  534. package/src/send.messages.test.ts +0 -53
  535. package/src/send.messages.ts +0 -225
  536. package/src/send.outbound.ts +0 -413
  537. package/src/send.permissions.authz.test.ts +0 -188
  538. package/src/send.permissions.ts +0 -283
  539. package/src/send.reactions.ts +0 -155
  540. package/src/send.sends-basic-channel-messages.test.ts +0 -941
  541. package/src/send.shared.ts +0 -447
  542. package/src/send.test-harness.ts +0 -56
  543. package/src/send.ts +0 -82
  544. package/src/send.types.ts +0 -188
  545. package/src/send.typing.test.ts +0 -41
  546. package/src/send.typing.ts +0 -9
  547. package/src/send.voice.ts +0 -134
  548. package/src/send.webhook-activity.test.ts +0 -105
  549. package/src/send.webhook.proxy.test.ts +0 -191
  550. package/src/send.webhook.ts +0 -133
  551. package/src/session-contract.ts +0 -3
  552. package/src/session-key-normalization.test.ts +0 -44
  553. package/src/session-key-normalization.ts +0 -47
  554. package/src/setup-account-state.test.ts +0 -91
  555. package/src/setup-account-state.ts +0 -144
  556. package/src/setup-adapter.ts +0 -12
  557. package/src/setup-core.ts +0 -212
  558. package/src/setup-runtime-helpers.ts +0 -10
  559. package/src/setup-surface.test.ts +0 -137
  560. package/src/setup-surface.ts +0 -129
  561. package/src/shared-interactive.test.ts +0 -153
  562. package/src/shared-interactive.ts +0 -124
  563. package/src/shared.test.ts +0 -165
  564. package/src/shared.ts +0 -190
  565. package/src/status-issues.test.ts +0 -70
  566. package/src/status-issues.ts +0 -169
  567. package/src/subagent-hooks.test.ts +0 -432
  568. package/src/subagent-hooks.ts +0 -214
  569. package/src/target-parsing.ts +0 -53
  570. package/src/target-resolver.ts +0 -129
  571. package/src/targets.test.ts +0 -367
  572. package/src/targets.ts +0 -12
  573. package/src/test-http-helpers.ts +0 -10
  574. package/src/test-support/component-runtime.ts +0 -190
  575. package/src/test-support/config.ts +0 -7
  576. package/src/test-support/configured-binding-runtime.ts +0 -29
  577. package/src/test-support/partial-channel.ts +0 -26
  578. package/src/test-support/provider.test-support.ts +0 -545
  579. package/src/token.test.ts +0 -107
  580. package/src/token.ts +0 -60
  581. package/src/ui-colors.ts +0 -27
  582. package/src/ui.ts +0 -20
  583. package/src/voice/access.test.ts +0 -217
  584. package/src/voice/access.ts +0 -124
  585. package/src/voice/audio.ts +0 -173
  586. package/src/voice/capture-state.test.ts +0 -48
  587. package/src/voice/capture-state.ts +0 -120
  588. package/src/voice/command.test.ts +0 -164
  589. package/src/voice/command.ts +0 -283
  590. package/src/voice/config.ts +0 -8
  591. package/src/voice/manager.e2e.test.ts +0 -928
  592. package/src/voice/manager.ready-listener.test.ts +0 -37
  593. package/src/voice/manager.runtime.ts +0 -11
  594. package/src/voice/manager.ts +0 -691
  595. package/src/voice/prompt.test.ts +0 -16
  596. package/src/voice/prompt.ts +0 -17
  597. package/src/voice/receive-recovery.test.ts +0 -79
  598. package/src/voice/receive-recovery.ts +0 -159
  599. package/src/voice/sanitize.test.ts +0 -34
  600. package/src/voice/sanitize.ts +0 -32
  601. package/src/voice/sdk-runtime.ts +0 -14
  602. package/src/voice/segment.ts +0 -156
  603. package/src/voice/session.ts +0 -50
  604. package/src/voice/speaker-context.ts +0 -127
  605. package/src/voice/tts.ts +0 -125
  606. package/src/voice-message.test.ts +0 -234
  607. package/src/voice-message.ts +0 -444
  608. package/subagent-hooks-api.ts +0 -27
  609. package/test-api.ts +0 -4
  610. package/thread-binding-api.ts +0 -1
  611. package/timeouts.ts +0 -6
  612. package/tsconfig.json +0 -16
@@ -0,0 +1,2751 @@
1
+ import { n as __reExport, t as __exportAll } from "./rolldown-runtime-C3SqQTfK.js";
2
+ import { ApplicationCommandOptionType, ApplicationCommandType, ButtonStyle, ComponentType, GatewayDispatchEvents, InteractionContextType, InteractionResponseType, InteractionType, MessageFlags, Routes, TextInputStyle } from "discord-api-types/v10";
3
+ import { createHash, randomBytes } from "node:crypto";
4
+ import fs from "node:fs/promises";
5
+ import path from "node:path";
6
+ import { Type } from "typebox";
7
+ import { Check } from "typebox/value";
8
+ import { inspect } from "node:util";
9
+ //#region extensions/discord/src/internal/api.commands.ts
10
+ async function listApplicationCommands(rest, clientId) {
11
+ return await rest.get(Routes.applicationCommands(clientId));
12
+ }
13
+ async function createApplicationCommand(rest, clientId, body) {
14
+ return await rest.post(Routes.applicationCommands(clientId), { body });
15
+ }
16
+ async function editApplicationCommand(rest, clientId, commandId, body) {
17
+ return await rest.patch(Routes.applicationCommand(clientId, commandId), { body });
18
+ }
19
+ async function deleteApplicationCommand(rest, clientId, commandId) {
20
+ await rest.delete(Routes.applicationCommand(clientId, commandId));
21
+ }
22
+ async function overwriteApplicationCommands(rest, clientId, body) {
23
+ await rest.put(Routes.applicationCommands(clientId), { body });
24
+ }
25
+ async function overwriteGuildApplicationCommands(rest, clientId, guildId, body) {
26
+ await rest.put(Routes.applicationGuildCommands(clientId, guildId), { body });
27
+ }
28
+ //#endregion
29
+ //#region extensions/discord/src/internal/api.guild.ts
30
+ async function getGuild(rest, guildId) {
31
+ return await rest.get(Routes.guild(guildId));
32
+ }
33
+ async function createGuildChannel(rest, guildId, data) {
34
+ return await rest.post(Routes.guildChannels(guildId), data);
35
+ }
36
+ async function moveGuildChannels(rest, guildId, data) {
37
+ await rest.patch(Routes.guildChannels(guildId), data);
38
+ }
39
+ async function getGuildMember(rest, guildId, userId) {
40
+ return await rest.get(Routes.guildMember(guildId, userId));
41
+ }
42
+ async function listGuildRoles(rest, guildId) {
43
+ return await rest.get(Routes.guildRoles(guildId));
44
+ }
45
+ async function listGuildChannels(rest, guildId) {
46
+ return await rest.get(Routes.guildChannels(guildId));
47
+ }
48
+ async function putChannelPermission(rest, channelId, targetId, data) {
49
+ await rest.put(Routes.channelPermission(channelId, targetId), data);
50
+ }
51
+ async function deleteChannelPermission(rest, channelId, targetId) {
52
+ await rest.delete(Routes.channelPermission(channelId, targetId));
53
+ }
54
+ async function listGuildActiveThreads(rest, guildId) {
55
+ return await rest.get(Routes.guildActiveThreads(guildId));
56
+ }
57
+ async function getGuildVoiceState(rest, guildId, userId) {
58
+ return await rest.get(Routes.guildVoiceState(guildId, userId));
59
+ }
60
+ async function listGuildScheduledEvents(rest, guildId) {
61
+ return await rest.get(Routes.guildScheduledEvents(guildId));
62
+ }
63
+ async function createGuildScheduledEvent(rest, guildId, body) {
64
+ return await rest.post(Routes.guildScheduledEvents(guildId), { body });
65
+ }
66
+ async function timeoutGuildMember(rest, guildId, userId, data) {
67
+ return await rest.patch(Routes.guildMember(guildId, userId), data);
68
+ }
69
+ async function addGuildMemberRole(rest, guildId, userId, roleId) {
70
+ await rest.put(Routes.guildMemberRole(guildId, userId, roleId));
71
+ }
72
+ async function removeGuildMemberRole(rest, guildId, userId, roleId) {
73
+ await rest.delete(Routes.guildMemberRole(guildId, userId, roleId));
74
+ }
75
+ async function removeGuildMember(rest, guildId, userId, data) {
76
+ await rest.delete(Routes.guildMember(guildId, userId), data);
77
+ }
78
+ async function createGuildBan(rest, guildId, userId, data) {
79
+ await rest.put(Routes.guildBan(guildId, userId), data);
80
+ }
81
+ async function listGuildEmojis(rest, guildId) {
82
+ return await rest.get(Routes.guildEmojis(guildId));
83
+ }
84
+ async function createGuildEmoji(rest, guildId, data) {
85
+ return await rest.post(Routes.guildEmojis(guildId), data);
86
+ }
87
+ async function createGuildSticker(rest, guildId, data) {
88
+ return await rest.post(Routes.guildStickers(guildId), data);
89
+ }
90
+ //#endregion
91
+ //#region extensions/discord/src/internal/api.interactions.ts
92
+ async function createInteractionCallback(rest, interactionId, token, body) {
93
+ return await rest.post(Routes.interactionCallback(interactionId, token), { body });
94
+ }
95
+ async function editWebhookMessage(rest, applicationId, token, messageId, data, query) {
96
+ return query ? await rest.patch(Routes.webhookMessage(applicationId, token, messageId), data, query) : await rest.patch(Routes.webhookMessage(applicationId, token, messageId), data);
97
+ }
98
+ async function deleteWebhookMessage(rest, applicationId, token, messageId) {
99
+ return await rest.delete(Routes.webhookMessage(applicationId, token, messageId));
100
+ }
101
+ async function getWebhookMessage(rest, applicationId, token, messageId) {
102
+ return await rest.get(Routes.webhookMessage(applicationId, token, messageId));
103
+ }
104
+ async function createWebhookMessage(rest, applicationId, token, data, query) {
105
+ return await rest.post(Routes.webhook(applicationId, token), data, query);
106
+ }
107
+ //#endregion
108
+ //#region extensions/discord/src/internal/api.messages.ts
109
+ async function getChannel(rest, channelId) {
110
+ return await rest.get(Routes.channel(channelId));
111
+ }
112
+ async function editChannel(rest, channelId, data) {
113
+ return await rest.patch(Routes.channel(channelId), data);
114
+ }
115
+ async function deleteChannel(rest, channelId) {
116
+ await rest.delete(Routes.channel(channelId));
117
+ }
118
+ async function listChannelMessages(rest, channelId, query) {
119
+ return await rest.get(Routes.channelMessages(channelId), query);
120
+ }
121
+ async function getChannelMessage(rest, channelId, messageId) {
122
+ return await rest.get(Routes.channelMessage(channelId, messageId));
123
+ }
124
+ async function createChannelMessage(rest, channelId, data) {
125
+ return await rest.post(Routes.channelMessages(channelId), data);
126
+ }
127
+ async function editChannelMessage(rest, channelId, messageId, data) {
128
+ return await rest.patch(Routes.channelMessage(channelId, messageId), data);
129
+ }
130
+ async function deleteChannelMessage(rest, channelId, messageId) {
131
+ await rest.delete(Routes.channelMessage(channelId, messageId));
132
+ }
133
+ async function pinChannelMessage(rest, channelId, messageId) {
134
+ await rest.put(Routes.channelPin(channelId, messageId));
135
+ }
136
+ async function unpinChannelMessage(rest, channelId, messageId) {
137
+ await rest.delete(Routes.channelPin(channelId, messageId));
138
+ }
139
+ async function listChannelPins(rest, channelId) {
140
+ return await rest.get(Routes.channelPins(channelId));
141
+ }
142
+ async function sendChannelTyping(rest, channelId) {
143
+ await rest.post(Routes.channelTyping(channelId));
144
+ }
145
+ async function createThread(rest, channelId, data, messageId) {
146
+ const route = messageId ? Routes.threads(channelId, messageId) : Routes.threads(channelId);
147
+ return await rest.post(route, data);
148
+ }
149
+ async function listChannelArchivedThreads(rest, channelId, query) {
150
+ return await rest.get(Routes.channelThreads(channelId, "public"), query);
151
+ }
152
+ async function searchGuildMessages(rest, guildId, params) {
153
+ return await rest.get(`/guilds/${guildId}/messages/search?${params.toString()}`);
154
+ }
155
+ //#endregion
156
+ //#region extensions/discord/src/internal/api.reactions.ts
157
+ async function createOwnMessageReaction(rest, channelId, messageId, encodedEmoji) {
158
+ await rest.put(Routes.channelMessageOwnReaction(channelId, messageId, encodedEmoji));
159
+ }
160
+ async function deleteOwnMessageReaction(rest, channelId, messageId, encodedEmoji) {
161
+ await rest.delete(Routes.channelMessageOwnReaction(channelId, messageId, encodedEmoji));
162
+ }
163
+ async function listMessageReactionUsers(rest, channelId, messageId, encodedEmoji, query) {
164
+ return await rest.get(Routes.channelMessageReaction(channelId, messageId, encodedEmoji), query);
165
+ }
166
+ //#endregion
167
+ //#region extensions/discord/src/internal/api.users.ts
168
+ async function getCurrentUser(rest) {
169
+ return await rest.get(Routes.user("@me"));
170
+ }
171
+ async function getUser(rest, userId) {
172
+ return await rest.get(Routes.user(userId));
173
+ }
174
+ async function createUserDmChannel(rest, recipientId) {
175
+ return await rest.post(Routes.userChannels(), { body: { recipient_id: recipientId } });
176
+ }
177
+ //#endregion
178
+ //#region extensions/discord/src/internal/api.webhooks.ts
179
+ async function createChannelWebhook(rest, channelId, data) {
180
+ return await rest.post(Routes.channelWebhooks(channelId), data);
181
+ }
182
+ //#endregion
183
+ //#region extensions/discord/src/internal/command-deploy.ts
184
+ var DiscordCommandDeployer = class {
185
+ constructor(params) {
186
+ this.params = params;
187
+ this.hashes = /* @__PURE__ */ new Map();
188
+ this.hashesLoaded = false;
189
+ }
190
+ async getCommands() {
191
+ return await listApplicationCommands(this.rest, this.params.clientId);
192
+ }
193
+ async deploy(options = {}) {
194
+ const commands = this.params.commands.filter((command) => command.name !== "*");
195
+ const serializedGlobal = commands.filter((command) => !command.guildIds).map((command) => command.serialize());
196
+ for (const [guildId, entries] of groupGuildCommands(commands)) await this.putCommandSetIfChanged(`guild:${guildId}`, entries, async () => {
197
+ await overwriteGuildApplicationCommands(this.rest, this.params.clientId, guildId, entries);
198
+ }, options);
199
+ if (this.params.devGuilds?.length) {
200
+ for (const guildId of this.params.devGuilds) {
201
+ const entries = commands.map((command) => command.serialize());
202
+ await this.putCommandSetIfChanged(`dev-guild:${guildId}`, entries, async () => {
203
+ await overwriteGuildApplicationCommands(this.rest, this.params.clientId, guildId, entries);
204
+ }, options);
205
+ }
206
+ return {
207
+ mode: options.mode ?? "reconcile",
208
+ usedDevGuilds: true
209
+ };
210
+ }
211
+ if (options.mode !== "overwrite") {
212
+ await this.putCommandSetIfChanged("global:reconcile", serializedGlobal, async () => {
213
+ await this.reconcileGlobalCommands(serializedGlobal);
214
+ }, options);
215
+ return {
216
+ mode: "reconcile",
217
+ usedDevGuilds: false
218
+ };
219
+ }
220
+ await this.putCommandSetIfChanged("global:overwrite", serializedGlobal, async () => {
221
+ await overwriteApplicationCommands(this.rest, this.params.clientId, serializedGlobal);
222
+ }, options);
223
+ return {
224
+ mode: "overwrite",
225
+ usedDevGuilds: false
226
+ };
227
+ }
228
+ async reconcileGlobalCommands(desired) {
229
+ const existing = await this.getCommands();
230
+ const existingByKey = new Map(existing.map((command) => [stableCommandKey(command), command]));
231
+ const desiredKeys = /* @__PURE__ */ new Set();
232
+ for (const command of desired) {
233
+ const key = stableCommandKey(command);
234
+ desiredKeys.add(key);
235
+ const current = existingByKey.get(key);
236
+ if (!current) {
237
+ await createApplicationCommand(this.rest, this.params.clientId, command);
238
+ continue;
239
+ }
240
+ if (!commandsEqual(current, command)) await editApplicationCommand(this.rest, this.params.clientId, current.id, command);
241
+ }
242
+ for (const command of existing) if (!desiredKeys.has(stableCommandKey(command))) await deleteApplicationCommand(this.rest, this.params.clientId, command.id);
243
+ }
244
+ async putCommandSetIfChanged(key, commands, deploy, options) {
245
+ const hash = stableCommandSetHash(commands);
246
+ await this.loadPersistedHashes();
247
+ if (!options.force && this.hashes.get(key) === hash) return;
248
+ await deploy();
249
+ this.hashes.set(key, hash);
250
+ await this.persistHashes();
251
+ }
252
+ async loadPersistedHashes() {
253
+ if (this.hashesLoaded) return;
254
+ this.hashesLoaded = true;
255
+ const storePath = this.params.hashStorePath;
256
+ if (!storePath) return;
257
+ try {
258
+ const raw = await fs.readFile(storePath, "utf8");
259
+ const parsed = JSON.parse(raw);
260
+ if (!parsed.hashes || typeof parsed.hashes !== "object") return;
261
+ for (const [key, value] of Object.entries(parsed.hashes)) if (typeof value === "string" && key.trim() && value.trim()) this.hashes.set(key, value);
262
+ } catch {}
263
+ }
264
+ async persistHashes() {
265
+ const storePath = this.params.hashStorePath;
266
+ if (!storePath) return;
267
+ try {
268
+ await fs.mkdir(path.dirname(storePath), { recursive: true });
269
+ const tmpPath = `${storePath}.${process.pid}.${Date.now()}.tmp`;
270
+ await fs.writeFile(tmpPath, `${JSON.stringify({
271
+ version: 1,
272
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
273
+ hashes: Object.fromEntries([...this.hashes.entries()].toSorted(([left], [right]) => left.localeCompare(right)))
274
+ }, null, 2)}\n`, "utf8");
275
+ await fs.rename(tmpPath, storePath);
276
+ } catch {}
277
+ }
278
+ get rest() {
279
+ return this.params.rest();
280
+ }
281
+ };
282
+ function groupGuildCommands(commands) {
283
+ const guildCommands = /* @__PURE__ */ new Map();
284
+ for (const command of commands.filter((entry) => entry.guildIds)) for (const guildId of command.guildIds ?? []) {
285
+ const entries = guildCommands.get(guildId) ?? [];
286
+ entries.push(command.serialize());
287
+ guildCommands.set(guildId, entries);
288
+ }
289
+ return guildCommands;
290
+ }
291
+ function stableCommandKey(command) {
292
+ return `${command.type ?? ApplicationCommandType.ChatInput}:${command.name}`;
293
+ }
294
+ function comparableCommand(value) {
295
+ if (!value || typeof value !== "object") return value;
296
+ const omit = new Set([
297
+ "application_id",
298
+ "description_localized",
299
+ "dm_permission",
300
+ "guild_id",
301
+ "id",
302
+ "name_localized",
303
+ "nsfw",
304
+ "version",
305
+ "default_permission"
306
+ ]);
307
+ return stableComparableObject(Object.fromEntries(Object.entries(value).filter(([key, entry]) => !omit.has(key) && entry !== void 0)));
308
+ }
309
+ const unorderedCommandArrayFields = new Set([
310
+ "channel_types",
311
+ "contexts",
312
+ "integration_types"
313
+ ]);
314
+ const optionComparisonOmittedFields = new Set([
315
+ "contexts",
316
+ "default_member_permissions",
317
+ "description_localized",
318
+ "integration_types",
319
+ "name_localized"
320
+ ]);
321
+ const nullableLocalizationFields = new Set(["description_localizations", "name_localizations"]);
322
+ function stableComparableObject(value, path = []) {
323
+ if (Array.isArray(value)) {
324
+ const normalized = value.map((entry) => stableComparableObject(entry, path));
325
+ const key = path.at(-1);
326
+ if (key && unorderedCommandArrayFields.has(key) && normalized.every((entry) => typeof entry === "string" || typeof entry === "number" || typeof entry === "boolean")) return normalized.toSorted((left, right) => String(left).localeCompare(String(right)));
327
+ return normalized;
328
+ }
329
+ if (!value || typeof value !== "object") return value;
330
+ return Object.fromEntries(Object.entries(value).filter(([key, entry]) => {
331
+ if (entry === void 0) return false;
332
+ if (entry === null && nullableLocalizationFields.has(key)) return false;
333
+ if (path.includes("options") && optionComparisonOmittedFields.has(key)) return false;
334
+ if ((key === "required" || key === "autocomplete") && entry === false) return false;
335
+ return true;
336
+ }).toSorted(([a], [b]) => a.localeCompare(b)).map(([key, entry]) => [key, shouldNormalizeDescriptionValue(path, key, entry) ? normalizeDescriptionForComparison(entry) : stableComparableObject(entry, [...path, key])]));
337
+ }
338
+ function shouldNormalizeDescriptionValue(path, key, entry) {
339
+ return typeof entry === "string" && (key === "description" || path.at(-1) === "description_localizations");
340
+ }
341
+ /**
342
+ * Normalize a Discord command description for equality comparison.
343
+ *
344
+ * Discord's server-side storage performs two transformations that our local
345
+ * desired descriptors do not:
346
+ *
347
+ * 1. Consecutive whitespace (including `\n`) is collapsed to a single space.
348
+ * 2. Whitespace between two CJK (Chinese, Japanese, Korean) characters is
349
+ * removed entirely. So a local description `"第一行。\n第二行。"` is stored
350
+ * as `"第一行。第二行。"` on Discord and returned without the `\n`.
351
+ *
352
+ * Without this normalization every startup for any CJK-heavy deployment reads
353
+ * back Discord's collapsed form, computes a diff against the local `\n`-form,
354
+ * decides the command needs updating, and issues a `PATCH`. Under the global
355
+ * per-application rate limit this quickly produces 429 bursts and some
356
+ * commands silently fail to register (see the Discord deploy 429 reports).
357
+ *
358
+ * Applying the same transformation to both sides before comparison makes the
359
+ * equality check match Discord's storage semantics and prevents spurious
360
+ * reconcile writes on every startup.
361
+ */
362
+ function normalizeDescriptionForComparison(description) {
363
+ const collapsed = description.replace(/\s+/g, " ");
364
+ const cjkBoundaryWhitespace = /([\u3000-\u303F\u4E00-\u9FFF\uFF00-\uFFEF])\s+([\u3000-\u303F\u4E00-\u9FFF\uFF00-\uFFEF])/g;
365
+ return collapsed.replace(cjkBoundaryWhitespace, "$1$2").replace(cjkBoundaryWhitespace, "$1$2").trim();
366
+ }
367
+ function commandsEqual(a, b) {
368
+ return JSON.stringify(comparableCommand(a)) === JSON.stringify(comparableCommand(b));
369
+ }
370
+ function stableCommandSetHash(commands) {
371
+ const stable = commands.map((command) => stableComparableObject(command)).toSorted((a, b) => stableCommandKey(a).localeCompare(stableCommandKey(b)));
372
+ return createHash("sha256").update(JSON.stringify(stable)).digest("hex");
373
+ }
374
+ //#endregion
375
+ //#region extensions/discord/src/internal/components.base.ts
376
+ function parseCustomId(id) {
377
+ const [rawKey, ...parts] = id.split(";");
378
+ const [keyPart, firstValue] = rawKey.split("=");
379
+ const key = keyPart.includes(":") ? keyPart.split(":")[0] : keyPart;
380
+ const data = {};
381
+ const entries = firstValue === void 0 ? parts : [rawKey.slice(key.length + 1), ...parts];
382
+ for (const entry of entries) {
383
+ const index = entry.indexOf("=");
384
+ if (index < 0) continue;
385
+ const name = entry.slice(0, index).replace(/^[^:]+:/, "");
386
+ const raw = entry.slice(index + 1);
387
+ data[name] = raw === "true" ? true : raw === "false" ? false : raw;
388
+ }
389
+ return {
390
+ key,
391
+ data
392
+ };
393
+ }
394
+ function clean$3(value) {
395
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
396
+ }
397
+ function colorToNumber(value) {
398
+ if (typeof value === "number") return value;
399
+ if (typeof value === "string" && /^#?[0-9a-f]{6}$/i.test(value)) return Number.parseInt(value.replace(/^#/, ""), 16);
400
+ }
401
+ var BaseComponent = class {
402
+ constructor() {
403
+ this.isV2 = false;
404
+ }
405
+ };
406
+ var BaseMessageInteractiveComponent = class extends BaseComponent {
407
+ constructor(..._args) {
408
+ super(..._args);
409
+ this.isV2 = false;
410
+ this.defer = false;
411
+ this.ephemeral = false;
412
+ this.customIdParser = parseCustomId;
413
+ }
414
+ run(_interaction, _data) {}
415
+ };
416
+ var BaseModalComponent = class extends BaseComponent {};
417
+ //#endregion
418
+ //#region extensions/discord/src/internal/components.message.ts
419
+ var BaseButton = class extends BaseMessageInteractiveComponent {
420
+ constructor(..._args) {
421
+ super(..._args);
422
+ this.type = ComponentType.Button;
423
+ this.style = ButtonStyle.Primary;
424
+ this.disabled = false;
425
+ }
426
+ };
427
+ var Button = class extends BaseButton {
428
+ serialize() {
429
+ return clean$3({
430
+ type: this.type,
431
+ style: this.style,
432
+ custom_id: this.customId,
433
+ label: this.label,
434
+ emoji: this.emoji,
435
+ disabled: this.disabled || void 0
436
+ });
437
+ }
438
+ };
439
+ var LinkButton = class extends BaseButton {
440
+ constructor(..._args2) {
441
+ super(..._args2);
442
+ this.customId = "";
443
+ this.style = ButtonStyle.Link;
444
+ }
445
+ async run() {
446
+ throw new Error("Link buttons do not run handlers");
447
+ }
448
+ serialize() {
449
+ return clean$3({
450
+ type: this.type,
451
+ style: this.style,
452
+ label: this.label,
453
+ emoji: this.emoji,
454
+ disabled: this.disabled || void 0,
455
+ url: this.url
456
+ });
457
+ }
458
+ };
459
+ var AnySelectMenu = class extends BaseMessageInteractiveComponent {
460
+ constructor(..._args3) {
461
+ super(..._args3);
462
+ this.disabled = false;
463
+ }
464
+ serialize() {
465
+ return clean$3({
466
+ ...this.serializeOptions(),
467
+ custom_id: this.customId,
468
+ placeholder: this.placeholder,
469
+ min_values: this.minValues,
470
+ max_values: this.maxValues,
471
+ disabled: this.disabled || void 0,
472
+ required: this.required
473
+ });
474
+ }
475
+ };
476
+ var StringSelectMenu = class extends AnySelectMenu {
477
+ constructor(..._args4) {
478
+ super(..._args4);
479
+ this.type = ComponentType.StringSelect;
480
+ }
481
+ serializeOptions() {
482
+ return {
483
+ type: this.type,
484
+ options: this.options
485
+ };
486
+ }
487
+ };
488
+ var UserSelectMenu = class extends AnySelectMenu {
489
+ constructor(..._args5) {
490
+ super(..._args5);
491
+ this.type = ComponentType.UserSelect;
492
+ }
493
+ serializeOptions() {
494
+ return {
495
+ type: this.type,
496
+ default_values: this.defaultValues
497
+ };
498
+ }
499
+ };
500
+ var RoleSelectMenu = class extends AnySelectMenu {
501
+ constructor(..._args6) {
502
+ super(..._args6);
503
+ this.type = ComponentType.RoleSelect;
504
+ }
505
+ serializeOptions() {
506
+ return {
507
+ type: this.type,
508
+ default_values: this.defaultValues
509
+ };
510
+ }
511
+ };
512
+ var MentionableSelectMenu = class extends AnySelectMenu {
513
+ constructor(..._args7) {
514
+ super(..._args7);
515
+ this.type = ComponentType.MentionableSelect;
516
+ }
517
+ serializeOptions() {
518
+ return {
519
+ type: this.type,
520
+ default_values: this.defaultValues
521
+ };
522
+ }
523
+ };
524
+ var ChannelSelectMenu = class extends AnySelectMenu {
525
+ constructor(..._args8) {
526
+ super(..._args8);
527
+ this.type = ComponentType.ChannelSelect;
528
+ }
529
+ serializeOptions() {
530
+ return {
531
+ type: this.type,
532
+ default_values: this.defaultValues,
533
+ channel_types: this.channelTypes
534
+ };
535
+ }
536
+ };
537
+ var Row = class extends BaseComponent {
538
+ constructor(components = []) {
539
+ super();
540
+ this.type = ComponentType.ActionRow;
541
+ this.isV2 = false;
542
+ this.components = components;
543
+ }
544
+ addComponent(component) {
545
+ this.components.push(component);
546
+ }
547
+ removeComponent(component) {
548
+ this.components = this.components.filter((entry) => entry !== component);
549
+ }
550
+ removeAllComponents() {
551
+ this.components = [];
552
+ }
553
+ serialize() {
554
+ return {
555
+ type: this.type,
556
+ components: this.components.map((entry) => entry.serialize())
557
+ };
558
+ }
559
+ };
560
+ var TextDisplay = class extends BaseComponent {
561
+ constructor(content) {
562
+ super();
563
+ this.content = content;
564
+ this.type = ComponentType.TextDisplay;
565
+ this.isV2 = true;
566
+ }
567
+ serialize() {
568
+ return clean$3({
569
+ type: this.type,
570
+ content: this.content
571
+ });
572
+ }
573
+ };
574
+ var Separator = class extends BaseComponent {
575
+ constructor(options) {
576
+ super();
577
+ this.type = ComponentType.Separator;
578
+ this.isV2 = true;
579
+ this.divider = true;
580
+ this.spacing = "small";
581
+ this.spacing = options?.spacing ?? this.spacing;
582
+ this.divider = options?.divider ?? this.divider;
583
+ }
584
+ serialize() {
585
+ return clean$3({
586
+ type: this.type,
587
+ divider: this.divider,
588
+ spacing: this.spacing === "large" ? 2 : this.spacing === "small" ? 1 : this.spacing
589
+ });
590
+ }
591
+ };
592
+ var Thumbnail = class extends BaseComponent {
593
+ constructor(url) {
594
+ super();
595
+ this.url = url;
596
+ this.type = ComponentType.Thumbnail;
597
+ this.isV2 = true;
598
+ }
599
+ serialize() {
600
+ return clean$3({
601
+ type: this.type,
602
+ media: this.url ? { url: this.url } : void 0
603
+ });
604
+ }
605
+ };
606
+ var Section = class extends BaseComponent {
607
+ constructor(components = [], accessory) {
608
+ super();
609
+ this.components = components;
610
+ this.accessory = accessory;
611
+ this.type = ComponentType.Section;
612
+ this.isV2 = true;
613
+ }
614
+ serialize() {
615
+ return clean$3({
616
+ type: this.type,
617
+ components: this.components.map((entry) => entry.serialize()),
618
+ accessory: this.accessory?.serialize()
619
+ });
620
+ }
621
+ };
622
+ var MediaGallery = class extends BaseComponent {
623
+ constructor(items = []) {
624
+ super();
625
+ this.items = items;
626
+ this.type = ComponentType.MediaGallery;
627
+ this.isV2 = true;
628
+ }
629
+ serialize() {
630
+ return {
631
+ type: this.type,
632
+ items: this.items.map((entry) => ({
633
+ media: { url: entry.url },
634
+ description: entry.description,
635
+ spoiler: entry.spoiler
636
+ }))
637
+ };
638
+ }
639
+ };
640
+ var File = class extends BaseComponent {
641
+ constructor(file, spoiler = false) {
642
+ super();
643
+ this.file = file;
644
+ this.spoiler = spoiler;
645
+ this.type = ComponentType.File;
646
+ this.isV2 = true;
647
+ }
648
+ serialize() {
649
+ return clean$3({
650
+ type: this.type,
651
+ file: this.file ? { url: this.file } : void 0,
652
+ spoiler: this.spoiler || void 0
653
+ });
654
+ }
655
+ };
656
+ var Container = class extends BaseComponent {
657
+ constructor(components = [], options) {
658
+ super();
659
+ this.type = ComponentType.Container;
660
+ this.isV2 = true;
661
+ this.spoiler = false;
662
+ this.components = components;
663
+ this.accentColor = options?.accentColor;
664
+ this.spoiler = options?.spoiler ?? false;
665
+ }
666
+ serialize() {
667
+ return clean$3({
668
+ type: this.type,
669
+ components: this.components.map((entry) => entry.serialize()),
670
+ accent_color: colorToNumber(this.accentColor),
671
+ spoiler: this.spoiler || void 0
672
+ });
673
+ }
674
+ };
675
+ //#endregion
676
+ //#region extensions/discord/src/internal/components.modal.ts
677
+ var TextInput = class extends BaseModalComponent {
678
+ constructor(..._args) {
679
+ super(..._args);
680
+ this.type = ComponentType.TextInput;
681
+ this.customIdParser = parseCustomId;
682
+ this.style = TextInputStyle.Short;
683
+ }
684
+ serialize() {
685
+ return clean$3({
686
+ type: this.type,
687
+ custom_id: this.customId,
688
+ style: this.style,
689
+ min_length: this.minLength,
690
+ max_length: this.maxLength,
691
+ required: this.required,
692
+ value: this.value,
693
+ placeholder: this.placeholder
694
+ });
695
+ }
696
+ };
697
+ var CheckboxGroup = class extends BaseModalComponent {
698
+ constructor(..._args2) {
699
+ super(..._args2);
700
+ this.type = 22;
701
+ this.options = [];
702
+ }
703
+ serialize() {
704
+ return clean$3({
705
+ type: this.type,
706
+ custom_id: this.customId,
707
+ options: this.options,
708
+ required: this.required,
709
+ min_values: this.minValues,
710
+ max_values: this.maxValues
711
+ });
712
+ }
713
+ };
714
+ var RadioGroup = class extends BaseModalComponent {
715
+ constructor(..._args3) {
716
+ super(..._args3);
717
+ this.type = 21;
718
+ this.options = [];
719
+ }
720
+ serialize() {
721
+ return clean$3({
722
+ type: this.type,
723
+ custom_id: this.customId,
724
+ options: this.options,
725
+ required: this.required,
726
+ min_values: this.minValues,
727
+ max_values: this.maxValues
728
+ });
729
+ }
730
+ };
731
+ var Label = class extends BaseModalComponent {
732
+ constructor(component) {
733
+ super();
734
+ this.component = component;
735
+ this.type = ComponentType.Label;
736
+ this.customId = "";
737
+ }
738
+ serialize() {
739
+ return clean$3({
740
+ type: this.type,
741
+ label: this.label,
742
+ description: this.description,
743
+ component: this.component?.serialize()
744
+ });
745
+ }
746
+ };
747
+ var Modal = class {
748
+ constructor() {
749
+ this.components = [];
750
+ this.customIdParser = parseCustomId;
751
+ }
752
+ serialize() {
753
+ return {
754
+ title: this.title,
755
+ custom_id: this.customId,
756
+ components: this.components.map((entry) => entry.serialize())
757
+ };
758
+ }
759
+ };
760
+ //#endregion
761
+ //#region extensions/discord/src/internal/payload.ts
762
+ function clean$2(value) {
763
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
764
+ }
765
+ function serializeAnyComponent(component) {
766
+ return component.serialize();
767
+ }
768
+ function payloadHasV2Components(payload) {
769
+ return Boolean(payload.components?.some((component) => component.isV2));
770
+ }
771
+ function normalizePayloadFlags(payload) {
772
+ const flags = payload.ephemeral ? (payload.flags ?? 0) | MessageFlags.Ephemeral : payload.flags;
773
+ if (!payloadHasV2Components(payload)) return flags;
774
+ if (payload.content || payload.embeds?.length) throw new Error("Discord Components V2 payloads cannot include content or embeds");
775
+ return (flags ?? 0) | MessageFlags.IsComponentsV2;
776
+ }
777
+ function serializePayload(payload) {
778
+ if (typeof payload === "string") return { content: payload };
779
+ const flags = normalizePayloadFlags(payload);
780
+ return clean$2({
781
+ content: payload.content,
782
+ embeds: payload.embeds?.map((entry) => "serialize" in entry ? entry.serialize() : entry),
783
+ components: payload.components?.map((entry) => serializeAnyComponent(entry)),
784
+ allowed_mentions: payload.allowed_mentions ?? payload.allowedMentions,
785
+ flags,
786
+ tts: payload.tts,
787
+ files: payload.files,
788
+ poll: payload.poll,
789
+ sticker_ids: payload.stickers
790
+ });
791
+ }
792
+ //#endregion
793
+ //#region extensions/discord/src/internal/structures.ts
794
+ var Base = class {
795
+ constructor(client) {
796
+ this.client = client;
797
+ }
798
+ };
799
+ var User = class extends Base {
800
+ constructor(client, rawDataOrId) {
801
+ super(client);
802
+ this._rawData = typeof rawDataOrId === "string" ? null : rawDataOrId;
803
+ this.id = typeof rawDataOrId === "string" ? rawDataOrId : rawDataOrId.id;
804
+ }
805
+ get rawData() {
806
+ if (!this._rawData) throw new Error("Partial Discord user has no raw data");
807
+ return this._rawData;
808
+ }
809
+ get partial() {
810
+ return this._rawData === null;
811
+ }
812
+ get username() {
813
+ return this._rawData?.username ?? "";
814
+ }
815
+ get globalName() {
816
+ return this._rawData?.global_name;
817
+ }
818
+ get discriminator() {
819
+ return this._rawData?.discriminator;
820
+ }
821
+ get bot() {
822
+ return this._rawData?.bot;
823
+ }
824
+ get avatar() {
825
+ return this._rawData?.avatar;
826
+ }
827
+ get avatarUrl() {
828
+ return this.avatar ? `https://cdn.discordapp.com/avatars/${this.id}/${this.avatar}.png` : null;
829
+ }
830
+ toString() {
831
+ return `<@${this.id}>`;
832
+ }
833
+ async fetch() {
834
+ return this.client.fetchUser(this.id);
835
+ }
836
+ async createDm() {
837
+ return await createUserDmChannel(this.client.rest, this.id);
838
+ }
839
+ async send(data) {
840
+ const dm = await this.createDm();
841
+ const message = await createChannelMessage(this.client.rest, dm.id, { body: serializePayload(data) });
842
+ return new Message(this.client, message);
843
+ }
844
+ };
845
+ var Role = class extends Base {
846
+ constructor(client, rawDataOrId) {
847
+ super(client);
848
+ this._rawData = typeof rawDataOrId === "string" ? null : rawDataOrId;
849
+ this.id = typeof rawDataOrId === "string" ? rawDataOrId : rawDataOrId.id;
850
+ }
851
+ get name() {
852
+ return this._rawData?.name ?? "";
853
+ }
854
+ };
855
+ var Guild = class extends Base {
856
+ constructor(client, rawDataOrId) {
857
+ super(client);
858
+ this._rawData = typeof rawDataOrId === "string" ? null : rawDataOrId;
859
+ this.id = typeof rawDataOrId === "string" ? rawDataOrId : rawDataOrId.id;
860
+ }
861
+ get name() {
862
+ return this._rawData?.name ?? "";
863
+ }
864
+ };
865
+ var GuildMember = class extends Base {
866
+ constructor(client, rawData) {
867
+ super(client);
868
+ this.rawData = rawData;
869
+ }
870
+ get user() {
871
+ return this.rawData.user ? new User(this.client, this.rawData.user) : null;
872
+ }
873
+ get roles() {
874
+ return this.rawData.roles ?? [];
875
+ }
876
+ get nickname() {
877
+ return this.rawData.nick ?? void 0;
878
+ }
879
+ };
880
+ var Message = class Message extends Base {
881
+ constructor(client, rawDataOrIds) {
882
+ super(client);
883
+ this._rawData = typeof rawDataOrIds === "string" || !("author" in rawDataOrIds) ? null : rawDataOrIds;
884
+ this.id = typeof rawDataOrIds === "string" ? rawDataOrIds : rawDataOrIds.id;
885
+ this.channelId = typeof rawDataOrIds === "string" ? "" : "channel_id" in rawDataOrIds ? rawDataOrIds.channel_id : rawDataOrIds.channelId ?? "";
886
+ }
887
+ get rawData() {
888
+ if (!this._rawData) throw new Error("Partial Discord message has no raw data");
889
+ return this._rawData;
890
+ }
891
+ get partial() {
892
+ return this._rawData === null;
893
+ }
894
+ get message() {
895
+ return this;
896
+ }
897
+ get channel_id() {
898
+ return this.channelId;
899
+ }
900
+ get guild_id() {
901
+ return this._rawData?.guild_id;
902
+ }
903
+ get guild() {
904
+ return this.guild_id ? new Guild(this.client, this.guild_id) : null;
905
+ }
906
+ get webhookId() {
907
+ return this.webhook_id;
908
+ }
909
+ get webhook_id() {
910
+ return this._rawData?.webhook_id ?? null;
911
+ }
912
+ get member() {
913
+ const member = this._rawData?.member;
914
+ return member ? new GuildMember(this.client, member) : null;
915
+ }
916
+ get rawMember() {
917
+ return this._rawData?.member;
918
+ }
919
+ get content() {
920
+ return this._rawData?.content ?? "";
921
+ }
922
+ get author() {
923
+ return this._rawData?.author ? new User(this.client, this._rawData.author) : null;
924
+ }
925
+ get embeds() {
926
+ return this._rawData?.embeds ?? [];
927
+ }
928
+ get attachments() {
929
+ return this._rawData?.attachments ?? [];
930
+ }
931
+ get stickers() {
932
+ return this._rawData?.sticker_items ?? [];
933
+ }
934
+ get mentionedUsers() {
935
+ return (this._rawData?.mentions ?? []).map((user) => new User(this.client, user));
936
+ }
937
+ get mentionedRoles() {
938
+ return this._rawData?.mention_roles ?? [];
939
+ }
940
+ get mentionedEveryone() {
941
+ return this._rawData?.mention_everyone ?? false;
942
+ }
943
+ get timestamp() {
944
+ return this._rawData?.timestamp;
945
+ }
946
+ get type() {
947
+ return this._rawData?.type;
948
+ }
949
+ get messageReference() {
950
+ return this._rawData?.message_reference;
951
+ }
952
+ get referencedMessage() {
953
+ return this._rawData?.referenced_message ? new Message(this.client, this._rawData.referenced_message) : null;
954
+ }
955
+ get thread() {
956
+ return this._rawData?.thread ? channelFactory(this.client, this._rawData.thread) : null;
957
+ }
958
+ async fetch() {
959
+ const raw = await getChannelMessage(this.client.rest, this.channelId, this.id);
960
+ return new Message(this.client, raw);
961
+ }
962
+ async delete() {
963
+ await deleteChannelMessage(this.client.rest, this.channelId, this.id);
964
+ }
965
+ async edit(data) {
966
+ const raw = await editChannelMessage(this.client.rest, this.channelId, this.id, { body: serializePayload(data) });
967
+ return new Message(this.client, raw);
968
+ }
969
+ async reply(data) {
970
+ const raw = await createChannelMessage(this.client.rest, this.channelId, { body: {
971
+ ...serializePayload(data),
972
+ message_reference: {
973
+ message_id: this.id,
974
+ fail_if_not_exists: false
975
+ }
976
+ } });
977
+ return new Message(this.client, raw);
978
+ }
979
+ async pin() {
980
+ await pinChannelMessage(this.client.rest, this.channelId, this.id);
981
+ }
982
+ async unpin() {
983
+ await unpinChannelMessage(this.client.rest, this.channelId, this.id);
984
+ }
985
+ };
986
+ function channelFactory(_client, channelData, _partial) {
987
+ return {
988
+ ...channelData,
989
+ rawData: channelData,
990
+ guildId: "guild_id" in channelData ? channelData.guild_id : void 0,
991
+ guild: "guild_id" in channelData && typeof channelData.guild_id === "string" ? new Guild(_client, channelData.guild_id) : void 0,
992
+ parentId: "parent_id" in channelData ? channelData.parent_id : void 0,
993
+ ownerId: "owner_id" in channelData ? channelData.owner_id : void 0
994
+ };
995
+ }
996
+ //#endregion
997
+ //#region extensions/discord/src/internal/entity-cache.ts
998
+ const DEFAULT_REST_CACHE_TTL_MS = 3e4;
999
+ var DiscordEntityCache = class {
1000
+ constructor(params) {
1001
+ this.params = params;
1002
+ this.entries = /* @__PURE__ */ new Map();
1003
+ }
1004
+ async fetchUser(id) {
1005
+ return await this.fetchCached(`user:${id}`, async () => {
1006
+ const raw = await getUser(this.rest, id);
1007
+ return new User(this.params.client, raw);
1008
+ });
1009
+ }
1010
+ async fetchChannel(id) {
1011
+ return await this.fetchCached(`channel:${id}`, async () => {
1012
+ const raw = await getChannel(this.rest, id);
1013
+ return channelFactory(this.params.client, raw);
1014
+ });
1015
+ }
1016
+ async fetchGuild(id) {
1017
+ return await this.fetchCached(`guild:${id}`, async () => {
1018
+ const raw = await getGuild(this.rest, id);
1019
+ return new Guild(this.params.client, raw);
1020
+ });
1021
+ }
1022
+ async fetchMember(guildId, userId) {
1023
+ return await this.fetchCached(`member:${guildId}:${userId}`, async () => {
1024
+ const raw = await getGuildMember(this.rest, guildId, userId);
1025
+ return new GuildMember(this.params.client, raw);
1026
+ });
1027
+ }
1028
+ invalidateForGatewayEvent(type, data) {
1029
+ const raw = data && typeof data === "object" ? data : {};
1030
+ const channelUpdate = GatewayDispatchEvents.ChannelUpdate;
1031
+ const channelDelete = GatewayDispatchEvents.ChannelDelete;
1032
+ const guildUpdate = GatewayDispatchEvents.GuildUpdate;
1033
+ const guildMemberUpdate = GatewayDispatchEvents.GuildMemberUpdate;
1034
+ if (type === channelUpdate || type === channelDelete) this.deleteId("channel", raw.id);
1035
+ if (type === guildUpdate) this.deleteId("guild", raw.id);
1036
+ if (type === guildMemberUpdate) {
1037
+ const guildId = raw.guild_id;
1038
+ const user = raw.user && typeof raw.user === "object" ? raw.user : {};
1039
+ if (typeof guildId === "string" && typeof user.id === "string") {
1040
+ this.entries.delete(`member:${guildId}:${user.id}`);
1041
+ this.entries.delete(`user:${user.id}`);
1042
+ }
1043
+ }
1044
+ }
1045
+ deleteId(prefix, id) {
1046
+ if (typeof id === "string") this.entries.delete(`${prefix}:${id}`);
1047
+ }
1048
+ async fetchCached(key, fetcher) {
1049
+ const ttl = this.params.ttlMs ?? DEFAULT_REST_CACHE_TTL_MS;
1050
+ if (ttl > 0) {
1051
+ const cached = this.entries.get(key);
1052
+ if (cached && cached.expiresAt > Date.now()) return cached.value;
1053
+ }
1054
+ const value = await fetcher();
1055
+ if (ttl > 0) this.entries.set(key, {
1056
+ expiresAt: Date.now() + ttl,
1057
+ value
1058
+ });
1059
+ return value;
1060
+ }
1061
+ get rest() {
1062
+ return typeof this.params.rest === "function" ? this.params.rest() : this.params.rest;
1063
+ }
1064
+ };
1065
+ //#endregion
1066
+ //#region extensions/discord/src/internal/event-queue.ts
1067
+ const DEFAULT_MAX_QUEUE_SIZE = 1e4;
1068
+ const DEFAULT_MAX_CONCURRENCY = 50;
1069
+ const DEFAULT_LISTENER_TIMEOUT_MS = 12e4;
1070
+ const DEFAULT_SLOW_LISTENER_THRESHOLD_MS = 3e4;
1071
+ var DiscordEventQueue = class {
1072
+ constructor(options = {}) {
1073
+ this.queue = [];
1074
+ this.processing = 0;
1075
+ this.processedCount = 0;
1076
+ this.droppedCount = 0;
1077
+ this.timeoutCount = 0;
1078
+ this.options = {
1079
+ maxQueueSize: normalizePositiveInteger(options.maxQueueSize, DEFAULT_MAX_QUEUE_SIZE),
1080
+ maxConcurrency: normalizePositiveInteger(options.maxConcurrency, DEFAULT_MAX_CONCURRENCY),
1081
+ listenerTimeout: normalizePositiveInteger(options.listenerTimeout, DEFAULT_LISTENER_TIMEOUT_MS),
1082
+ slowListenerThreshold: normalizePositiveInteger(options.slowListenerThreshold, DEFAULT_SLOW_LISTENER_THRESHOLD_MS)
1083
+ };
1084
+ }
1085
+ enqueue(params) {
1086
+ if (this.queue.length >= this.options.maxQueueSize) {
1087
+ this.droppedCount += 1;
1088
+ return Promise.reject(/* @__PURE__ */ new Error(`Discord event queue is full for ${params.eventType}; maxQueueSize=${this.options.maxQueueSize}`));
1089
+ }
1090
+ return new Promise((resolve, reject) => {
1091
+ this.queue.push({
1092
+ ...params,
1093
+ resolve,
1094
+ reject
1095
+ });
1096
+ this.processNext();
1097
+ });
1098
+ }
1099
+ getMetrics() {
1100
+ return {
1101
+ queueSize: this.queue.length,
1102
+ processing: this.processing,
1103
+ processed: this.processedCount,
1104
+ dropped: this.droppedCount,
1105
+ timeouts: this.timeoutCount,
1106
+ maxQueueSize: this.options.maxQueueSize,
1107
+ maxConcurrency: this.options.maxConcurrency
1108
+ };
1109
+ }
1110
+ processNext() {
1111
+ while (this.processing < this.options.maxConcurrency && this.queue.length > 0) {
1112
+ const job = this.queue.shift();
1113
+ if (!job) return;
1114
+ this.processing += 1;
1115
+ this.runJob(job).then(job.resolve, job.reject).finally(() => {
1116
+ this.processing -= 1;
1117
+ this.processedCount += 1;
1118
+ this.processNext();
1119
+ });
1120
+ }
1121
+ }
1122
+ async runJob(job) {
1123
+ const startedAt = Date.now();
1124
+ try {
1125
+ await this.runWithTimeout(job);
1126
+ this.logSlowListener(job, Date.now() - startedAt);
1127
+ } catch (error) {
1128
+ if (isListenerTimeoutError(error)) {
1129
+ this.timeoutCount += 1;
1130
+ console.error(`[EventQueue] Listener ${job.listenerName} timed out after ${this.options.listenerTimeout}ms for event ${job.eventType}`);
1131
+ return;
1132
+ }
1133
+ console.error(`[EventQueue] Listener ${job.listenerName} failed for event ${job.eventType}:`, error);
1134
+ }
1135
+ }
1136
+ async runWithTimeout(job) {
1137
+ let timeout;
1138
+ try {
1139
+ await Promise.race([job.run(), new Promise((_, reject) => {
1140
+ timeout = setTimeout(() => {
1141
+ reject(createListenerTimeoutError(this.options.listenerTimeout));
1142
+ }, this.options.listenerTimeout);
1143
+ timeout.unref?.();
1144
+ })]);
1145
+ } finally {
1146
+ if (timeout) clearTimeout(timeout);
1147
+ }
1148
+ }
1149
+ logSlowListener(job, durationMs) {
1150
+ if (durationMs < this.options.slowListenerThreshold) return;
1151
+ console.warn(`[EventQueue] Slow listener detected: ${job.listenerName} took ${durationMs}ms for event ${job.eventType}`);
1152
+ }
1153
+ };
1154
+ function normalizePositiveInteger(value, fallback) {
1155
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return fallback;
1156
+ return Math.max(1, Math.floor(value));
1157
+ }
1158
+ function createListenerTimeoutError(timeoutMs) {
1159
+ const error = /* @__PURE__ */ new Error(`Listener timeout after ${timeoutMs}ms`);
1160
+ error.name = "DiscordEventQueueListenerTimeoutError";
1161
+ return error;
1162
+ }
1163
+ function isListenerTimeoutError(error) {
1164
+ return error instanceof Error && error.name === "DiscordEventQueueListenerTimeoutError";
1165
+ }
1166
+ //#endregion
1167
+ //#region extensions/discord/src/internal/commands.ts
1168
+ function clean$1(value) {
1169
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
1170
+ }
1171
+ function resolveConditionalCommandOption(value, interaction) {
1172
+ return typeof value === "function" ? value(interaction) : value;
1173
+ }
1174
+ async function deferCommandInteractionIfNeeded(command, interaction) {
1175
+ if (!resolveConditionalCommandOption(command.defer, interaction)) return;
1176
+ await interaction.defer({ ephemeral: resolveConditionalCommandOption(command.ephemeral, interaction) });
1177
+ }
1178
+ function readRawCommandOptions(interaction) {
1179
+ const options = interaction.rawData.data?.options;
1180
+ return Array.isArray(options) ? options : [];
1181
+ }
1182
+ function findSelectedSubcommand(subcommands, interaction) {
1183
+ const subcommandName = readRawCommandOptions(interaction).find((option) => option.type === ApplicationCommandOptionType.Subcommand)?.name;
1184
+ return typeof subcommandName === "string" ? subcommands.find((command) => command.name === subcommandName) : void 0;
1185
+ }
1186
+ function findCommandOption(options, name) {
1187
+ if (!name) return;
1188
+ return options?.find((option) => option.name === name);
1189
+ }
1190
+ function hasCommandOptions(command) {
1191
+ return "options" in command;
1192
+ }
1193
+ function resolveFocusedCommandOptionAutocompleteHandler(command, interaction) {
1194
+ const focusedName = interaction.options.getFocused()?.name;
1195
+ const autocomplete = findCommandOption("subcommands" in command && Array.isArray(command.subcommands) ? findSelectedSubcommand(command.subcommands, interaction)?.options : hasCommandOptions(command) ? command.options : void 0, focusedName)?.autocomplete;
1196
+ return typeof autocomplete === "function" ? autocomplete : void 0;
1197
+ }
1198
+ var BaseCommand = class {
1199
+ constructor() {
1200
+ this.defer = false;
1201
+ this.ephemeral = false;
1202
+ this.integrationTypes = [0, 1];
1203
+ this.contexts = [
1204
+ InteractionContextType.Guild,
1205
+ InteractionContextType.BotDM,
1206
+ InteractionContextType.PrivateChannel
1207
+ ];
1208
+ }
1209
+ serialize() {
1210
+ return clean$1({
1211
+ name: this.name,
1212
+ name_localizations: this.nameLocalizations,
1213
+ description: this.type === ApplicationCommandType.ChatInput ? this.description ?? "" : void 0,
1214
+ description_localizations: this.descriptionLocalizations,
1215
+ type: this.type,
1216
+ options: this.serializeOptions(),
1217
+ integration_types: this.integrationTypes,
1218
+ contexts: this.contexts,
1219
+ default_member_permissions: Array.isArray(this.permission) ? this.permission.reduce((sum, entry) => sum | entry, 0n).toString() : this.permission ? this.permission.toString() : null
1220
+ });
1221
+ }
1222
+ };
1223
+ var Command = class extends BaseCommand {
1224
+ constructor(..._args) {
1225
+ super(..._args);
1226
+ this.type = ApplicationCommandType.ChatInput;
1227
+ }
1228
+ async autocomplete(interaction) {
1229
+ throw new Error(`The ${interaction.rawData?.data?.name ?? this.name} command does not support autocomplete`);
1230
+ }
1231
+ async preCheck(interaction) {
1232
+ return Boolean(interaction) || true;
1233
+ }
1234
+ serializeOptions() {
1235
+ return this.options?.map((option) => {
1236
+ if (typeof option.autocomplete === "function") {
1237
+ const { autocomplete: _autocomplete, ...rest } = option;
1238
+ return {
1239
+ ...rest,
1240
+ autocomplete: true
1241
+ };
1242
+ }
1243
+ return option;
1244
+ });
1245
+ }
1246
+ };
1247
+ var CommandWithSubcommands = class extends BaseCommand {
1248
+ constructor(..._args2) {
1249
+ super(..._args2);
1250
+ this.type = ApplicationCommandType.ChatInput;
1251
+ }
1252
+ async run(interaction) {
1253
+ const subcommand = findSelectedSubcommand(this.subcommands, interaction);
1254
+ if (!subcommand) {
1255
+ const subcommandName = readRawCommandOptions(interaction).find((option) => option.type === ApplicationCommandOptionType.Subcommand)?.name;
1256
+ throw new Error(`Unknown Discord subcommand: ${typeof subcommandName === "string" ? subcommandName : "<missing>"}`);
1257
+ }
1258
+ await deferCommandInteractionIfNeeded(subcommand, interaction);
1259
+ return await subcommand.run(interaction);
1260
+ }
1261
+ serializeOptions() {
1262
+ return this.subcommands.map((command) => clean$1({
1263
+ name: command.name,
1264
+ name_localizations: command.nameLocalizations,
1265
+ description: command.description ?? "",
1266
+ description_localizations: command.descriptionLocalizations,
1267
+ type: ApplicationCommandOptionType.Subcommand,
1268
+ options: command.serializeOptions()
1269
+ }));
1270
+ }
1271
+ };
1272
+ //#endregion
1273
+ //#region extensions/discord/src/internal/interaction-options.ts
1274
+ function readFocusedOption(options) {
1275
+ for (const option of options ?? []) {
1276
+ if ("focused" in option && option.focused) return option;
1277
+ const child = readFocusedOption(readChildOptions(option));
1278
+ if (child) return child;
1279
+ }
1280
+ }
1281
+ function findOption(options, name) {
1282
+ for (const option of options ?? []) {
1283
+ if (option.name === name) return option;
1284
+ const child = findOption(readChildOptions(option), name);
1285
+ if (child) return child;
1286
+ }
1287
+ }
1288
+ function readChildOptions(option) {
1289
+ if (!("options" in option) || !Array.isArray(option.options)) return;
1290
+ return option.options;
1291
+ }
1292
+ var OptionsHandler = class {
1293
+ constructor(rawOptions, client, resolvedChannels) {
1294
+ this.rawOptions = rawOptions;
1295
+ this.client = client;
1296
+ this.resolvedChannels = resolvedChannels;
1297
+ }
1298
+ getString(name) {
1299
+ const option = findOption(this.rawOptions, name);
1300
+ const value = option && "value" in option ? option.value : void 0;
1301
+ return typeof value === "string" ? value : null;
1302
+ }
1303
+ getNumber(name) {
1304
+ const option = findOption(this.rawOptions, name);
1305
+ const value = option && "value" in option ? option.value : void 0;
1306
+ return typeof value === "number" ? value : null;
1307
+ }
1308
+ getBoolean(name) {
1309
+ const option = findOption(this.rawOptions, name);
1310
+ const value = option && "value" in option ? option.value : void 0;
1311
+ return typeof value === "boolean" ? value : null;
1312
+ }
1313
+ async getChannel(name, required = false) {
1314
+ const option = findOption(this.rawOptions, name);
1315
+ const value = option && "value" in option ? option.value : void 0;
1316
+ const id = typeof value === "string" ? value : void 0;
1317
+ const resolved = id ? this.resolvedChannels?.[id] : void 0;
1318
+ if (resolved) return channelFactory(this.client, resolved);
1319
+ if (id) return await this.client.fetchChannel(id);
1320
+ if (required) throw new Error(`Missing required channel option ${name}`);
1321
+ return null;
1322
+ }
1323
+ getFocused() {
1324
+ return readFocusedOption(this.rawOptions);
1325
+ }
1326
+ };
1327
+ //#endregion
1328
+ //#region extensions/discord/src/internal/interaction-response.ts
1329
+ var InteractionResponseController = class {
1330
+ constructor() {
1331
+ this.state = "unacknowledged";
1332
+ }
1333
+ get acknowledged() {
1334
+ return this.state !== "unacknowledged";
1335
+ }
1336
+ recordCallback(type) {
1337
+ if (type === InteractionResponseType.DeferredChannelMessageWithSource) {
1338
+ this.state = "deferred";
1339
+ return;
1340
+ }
1341
+ if (type === InteractionResponseType.DeferredMessageUpdate) {
1342
+ this.state = "deferred-update";
1343
+ return;
1344
+ }
1345
+ this.state = "replied";
1346
+ }
1347
+ nextReplyAction() {
1348
+ if (this.state === "deferred" || this.state === "deferred-update") return "edit";
1349
+ if (this.state === "unacknowledged") return "initial";
1350
+ return "follow-up";
1351
+ }
1352
+ recordReplyEdit() {
1353
+ this.state = "replied";
1354
+ }
1355
+ };
1356
+ function needsComponentsV2Query(body) {
1357
+ return body !== null && typeof body === "object" && "flags" in body && typeof body.flags === "number" && (body.flags & MessageFlags.IsComponentsV2) !== 0;
1358
+ }
1359
+ //#endregion
1360
+ //#region extensions/discord/src/internal/modal-fields.ts
1361
+ function extractModalFields(components) {
1362
+ const out = {};
1363
+ for (const component of flattenModalComponents(components)) {
1364
+ const raw = component;
1365
+ if (typeof raw.custom_id !== "string") continue;
1366
+ if (Array.isArray(raw.values)) out[raw.custom_id] = raw.values.map(String);
1367
+ else if (typeof raw.value === "string" || typeof raw.value === "number" || typeof raw.value === "boolean") out[raw.custom_id] = String(raw.value);
1368
+ }
1369
+ return out;
1370
+ }
1371
+ function flattenModalComponents(components) {
1372
+ const out = [];
1373
+ for (const entry of components) {
1374
+ if (!entry || typeof entry !== "object") continue;
1375
+ const component = entry;
1376
+ if (component.component && typeof component.component === "object") out.push(component.component);
1377
+ if (Array.isArray(component.components)) out.push(...flattenModalComponents(component.components));
1378
+ out.push(entry);
1379
+ }
1380
+ return out;
1381
+ }
1382
+ var ModalFields = class {
1383
+ constructor(values, resolved, client) {
1384
+ this.values = values;
1385
+ this.resolved = resolved;
1386
+ this.client = client;
1387
+ }
1388
+ value(id, required) {
1389
+ const value = this.values[id];
1390
+ if (required && (value === void 0 || Array.isArray(value) && value.length === 0)) throw new Error(`Missing required modal field ${id}`);
1391
+ return value;
1392
+ }
1393
+ getText(id, required = false) {
1394
+ const value = this.value(id, required);
1395
+ return typeof value === "string" ? value : null;
1396
+ }
1397
+ getStringSelect(id, required = false) {
1398
+ const value = this.value(id, required);
1399
+ if (Array.isArray(value)) return value;
1400
+ return typeof value === "string" ? [value] : [];
1401
+ }
1402
+ getRoleSelect(id, required = false) {
1403
+ return this.getStringSelect(id, required).map((roleId) => {
1404
+ const raw = this.resolved?.roles?.[roleId];
1405
+ return raw ? new Role(this.client, {
1406
+ id: roleId,
1407
+ name: raw.name ?? ""
1408
+ }) : new Role(this.client, roleId);
1409
+ });
1410
+ }
1411
+ getUserSelect(id, required = false) {
1412
+ return this.getStringSelect(id, required).map((userId) => {
1413
+ const raw = this.resolved?.users?.[userId];
1414
+ return new User(this.client, {
1415
+ id: userId,
1416
+ username: raw?.username ?? ""
1417
+ });
1418
+ });
1419
+ }
1420
+ };
1421
+ //#endregion
1422
+ //#region extensions/discord/src/internal/schemas.ts
1423
+ const discordInteractionPayloadSchema = Type.Object({
1424
+ id: Type.String({ minLength: 1 }),
1425
+ token: Type.String({ minLength: 1 }),
1426
+ type: Type.Number()
1427
+ }, { additionalProperties: true });
1428
+ const discordRateLimitBodySchema = Type.Object({
1429
+ message: Type.Optional(Type.String()),
1430
+ retry_after: Type.Optional(Type.Union([Type.Number(), Type.String()])),
1431
+ global: Type.Optional(Type.Boolean()),
1432
+ code: Type.Optional(Type.Union([Type.Number(), Type.String()]))
1433
+ }, { additionalProperties: true });
1434
+ function assertDiscordInteractionPayload(value) {
1435
+ if (!Check(discordInteractionPayloadSchema, value)) throw new Error("Invalid Discord interaction payload");
1436
+ }
1437
+ function isDiscordRateLimitBody(value) {
1438
+ return Check(discordRateLimitBodySchema, value);
1439
+ }
1440
+ //#endregion
1441
+ //#region extensions/discord/src/internal/interactions.ts
1442
+ function toCommandRawInteraction(rawData) {
1443
+ return rawData;
1444
+ }
1445
+ function toMessageComponentRawInteraction(rawData) {
1446
+ return rawData;
1447
+ }
1448
+ function toModalSubmitRawInteraction(rawData) {
1449
+ return rawData;
1450
+ }
1451
+ function readInteractionUser(rawData, client) {
1452
+ const directUser = "user" in rawData ? rawData.user : void 0;
1453
+ if (directUser && typeof directUser === "object" && "id" in directUser) return new User(client, directUser);
1454
+ const memberUser = rawData.member?.user;
1455
+ if (memberUser && typeof memberUser === "object" && typeof memberUser.id === "string") {
1456
+ const user = { ...memberUser };
1457
+ if (typeof user.username !== "string") user.username = "";
1458
+ return new User(client, user);
1459
+ }
1460
+ return null;
1461
+ }
1462
+ var BaseInteraction = class {
1463
+ constructor(client, rawData) {
1464
+ this.client = client;
1465
+ this.rawData = rawData;
1466
+ this.message = null;
1467
+ this.response = new InteractionResponseController();
1468
+ this.id = rawData.id;
1469
+ this.token = rawData.token;
1470
+ this.user = readInteractionUser(rawData, client);
1471
+ this.userId = this.user?.id ?? "";
1472
+ this.guild = rawData.guild_id ? new Guild(client, rawData.guild_id) : null;
1473
+ this.channel = "channel" in rawData && rawData.channel ? channelFactory(client, rawData.channel) : null;
1474
+ }
1475
+ get acknowledged() {
1476
+ return this.response.acknowledged;
1477
+ }
1478
+ get responseState() {
1479
+ return this.response.state;
1480
+ }
1481
+ set responseState(nextState) {
1482
+ this.response.state = nextState;
1483
+ }
1484
+ async callback(type, data) {
1485
+ this.response.recordCallback(type);
1486
+ return await createInteractionCallback(this.client.rest, this.id, this.token, data === void 0 ? { type } : {
1487
+ type,
1488
+ data
1489
+ });
1490
+ }
1491
+ async reply(payload) {
1492
+ const action = this.response.nextReplyAction();
1493
+ if (action === "edit") return await this.editReply(payload);
1494
+ if (action === "follow-up") return await this.followUp(payload);
1495
+ return await this.callback(InteractionResponseType.ChannelMessageWithSource, serializePayload(payload));
1496
+ }
1497
+ async defer(options) {
1498
+ return await this.callback(InteractionResponseType.DeferredChannelMessageWithSource, options?.ephemeral ? { flags: 64 } : void 0);
1499
+ }
1500
+ async acknowledge() {
1501
+ return await this.defer();
1502
+ }
1503
+ async editReply(payload) {
1504
+ const body = serializePayload(payload);
1505
+ const query = needsComponentsV2Query(body) ? { with_components: true } : void 0;
1506
+ const result = query ? await editWebhookMessage(this.client.rest, this.client.options.clientId, this.token, "@original", { body }, query) : await editWebhookMessage(this.client.rest, this.client.options.clientId, this.token, "@original", { body });
1507
+ this.response.recordReplyEdit();
1508
+ return result;
1509
+ }
1510
+ async deleteReply() {
1511
+ return await deleteWebhookMessage(this.client.rest, this.client.options.clientId, this.token, "@original");
1512
+ }
1513
+ async fetchReply() {
1514
+ return await getWebhookMessage(this.client.rest, this.client.options.clientId, this.token, "@original");
1515
+ }
1516
+ async replyAndWaitForComponent(payload, timeoutMs = 3e5) {
1517
+ const result = await this.reply(payload);
1518
+ const rawMessage = isRawMessage(result) ? result : await this.fetchReply();
1519
+ if (!isRawMessage(rawMessage)) throw new Error("Discord interaction reply did not return a message");
1520
+ const message = new Message(this.client, rawMessage);
1521
+ return await this.client.componentHandler.waitForMessageComponent(message, timeoutMs);
1522
+ }
1523
+ async followUp(payload) {
1524
+ const body = serializePayload(payload);
1525
+ return await createWebhookMessage(this.client.rest, this.client.options.clientId, this.token, { body }, needsComponentsV2Query(body) ? { with_components: true } : void 0);
1526
+ }
1527
+ };
1528
+ var CommandInteraction = class extends BaseInteraction {
1529
+ constructor(client, rawData) {
1530
+ super(client, rawData);
1531
+ this.options = new OptionsHandler(rawData.data.options, client, rawData.data.resolved?.channels);
1532
+ }
1533
+ };
1534
+ var AutocompleteInteraction = class extends CommandInteraction {
1535
+ async respond(choices) {
1536
+ return await this.callback(InteractionResponseType.ApplicationCommandAutocompleteResult, { choices });
1537
+ }
1538
+ };
1539
+ var BaseComponentInteraction = class extends BaseInteraction {
1540
+ constructor(client, rawData) {
1541
+ super(client, rawData);
1542
+ this.message = rawData.message && typeof rawData.message === "object" ? new Message(client, rawData.message) : null;
1543
+ this.values = Array.isArray(rawData.data.values) ? rawData.data.values.map(String) : [];
1544
+ }
1545
+ async update(payload) {
1546
+ return await this.callback(InteractionResponseType.UpdateMessage, serializePayload(payload));
1547
+ }
1548
+ async acknowledge() {
1549
+ return await this.callback(InteractionResponseType.DeferredMessageUpdate);
1550
+ }
1551
+ async showModal(modal) {
1552
+ return await this.callback(InteractionResponseType.Modal, modal.serialize());
1553
+ }
1554
+ async editAndWaitForComponent(payload, message = this.message, timeoutMs = 3e5) {
1555
+ if (!message) return null;
1556
+ const editedMessage = await message.edit(payload);
1557
+ return await this.client.componentHandler.waitForMessageComponent(editedMessage, timeoutMs);
1558
+ }
1559
+ };
1560
+ var ButtonInteraction = class extends BaseComponentInteraction {};
1561
+ var StringSelectMenuInteraction = class extends BaseComponentInteraction {};
1562
+ var UserSelectMenuInteraction = class extends BaseComponentInteraction {};
1563
+ var RoleSelectMenuInteraction = class extends BaseComponentInteraction {};
1564
+ var MentionableSelectMenuInteraction = class extends BaseComponentInteraction {};
1565
+ var ChannelSelectMenuInteraction = class extends BaseComponentInteraction {};
1566
+ var ModalInteraction = class extends BaseInteraction {
1567
+ constructor(client, rawData) {
1568
+ super(client, rawData);
1569
+ this.fields = new ModalFields(extractModalFields(rawData.data.components ?? []), rawData.data.resolved, client);
1570
+ }
1571
+ async acknowledge() {
1572
+ return await this.callback(InteractionResponseType.DeferredMessageUpdate);
1573
+ }
1574
+ };
1575
+ function createInteraction(client, rawData) {
1576
+ assertDiscordInteractionPayload(rawData);
1577
+ if (rawData.type === InteractionType.ApplicationCommandAutocomplete) return new AutocompleteInteraction(client, toCommandRawInteraction(rawData));
1578
+ if (rawData.type === InteractionType.ApplicationCommand) return new CommandInteraction(client, toCommandRawInteraction(rawData));
1579
+ if (rawData.type === InteractionType.ModalSubmit) return new ModalInteraction(client, toModalSubmitRawInteraction(rawData));
1580
+ if (rawData.type === InteractionType.MessageComponent) {
1581
+ const componentRawData = toMessageComponentRawInteraction(rawData);
1582
+ switch (rawData.data?.component_type) {
1583
+ case ComponentType.Button: return new ButtonInteraction(client, componentRawData);
1584
+ case ComponentType.StringSelect: return new StringSelectMenuInteraction(client, componentRawData);
1585
+ case ComponentType.UserSelect: return new UserSelectMenuInteraction(client, componentRawData);
1586
+ case ComponentType.RoleSelect: return new RoleSelectMenuInteraction(client, componentRawData);
1587
+ case ComponentType.MentionableSelect: return new MentionableSelectMenuInteraction(client, componentRawData);
1588
+ case ComponentType.ChannelSelect: return new ChannelSelectMenuInteraction(client, componentRawData);
1589
+ default: return new BaseComponentInteraction(client, componentRawData);
1590
+ }
1591
+ }
1592
+ return new BaseInteraction(client, rawData);
1593
+ }
1594
+ function parseComponentInteractionData(component, customId) {
1595
+ return component.customIdParser(customId).data;
1596
+ }
1597
+ function isRawMessage(value) {
1598
+ return Boolean(value) && typeof value === "object" && typeof value.id === "string" && typeof value.channel_id === "string";
1599
+ }
1600
+ //#endregion
1601
+ //#region extensions/discord/src/internal/interaction-dispatch.ts
1602
+ async function dispatchInteraction(client, rawData) {
1603
+ const interaction = createInteraction(client, rawData);
1604
+ if (rawData.type === InteractionType.ApplicationCommandAutocomplete) {
1605
+ const command = client.commands.find((entry) => entry.name === readInteractionName(rawData));
1606
+ if (!command) return;
1607
+ const autocompleteInteraction = interaction;
1608
+ const optionAutocomplete = resolveFocusedCommandOptionAutocompleteHandler(command, autocompleteInteraction);
1609
+ if (optionAutocomplete) {
1610
+ await optionAutocomplete(autocompleteInteraction);
1611
+ return;
1612
+ }
1613
+ if ("autocomplete" in command) await command.autocomplete(autocompleteInteraction);
1614
+ return;
1615
+ }
1616
+ if (rawData.type === InteractionType.ApplicationCommand) {
1617
+ const command = client.commands.find((entry) => entry.name === readInteractionName(rawData));
1618
+ if (command && "run" in command) {
1619
+ await deferCommandInteractionIfNeeded(command, interaction);
1620
+ await command.run(interaction);
1621
+ }
1622
+ return;
1623
+ }
1624
+ if (rawData.type === InteractionType.MessageComponent) {
1625
+ const customId = readCustomId(rawData);
1626
+ if (!customId) return;
1627
+ const componentInteraction = interaction;
1628
+ if (client.componentHandler.resolveOneOffComponent({
1629
+ channelId: readMessageChannelId(rawData),
1630
+ customId,
1631
+ messageId: readMessageId(rawData),
1632
+ values: readComponentValues(rawData)
1633
+ })) {
1634
+ await componentInteraction.acknowledge();
1635
+ return;
1636
+ }
1637
+ const component = client.componentHandler.resolve(customId, { componentType: rawData.data?.component_type });
1638
+ if (component) {
1639
+ await deferComponentInteractionIfNeeded(component, componentInteraction);
1640
+ await component.run(componentInteraction, parseComponentInteractionData(component, customId));
1641
+ }
1642
+ return;
1643
+ }
1644
+ if (rawData.type === InteractionType.ModalSubmit) {
1645
+ const customId = readCustomId(rawData);
1646
+ if (!customId) return;
1647
+ const modal = client.modalHandler.resolve(customId);
1648
+ if (modal) await modal.run(interaction, modal.customIdParser(customId).data);
1649
+ }
1650
+ }
1651
+ function resolveConditionalComponentOption(value, interaction) {
1652
+ return typeof value === "function" ? value(interaction) : value;
1653
+ }
1654
+ async function deferComponentInteractionIfNeeded(component, interaction) {
1655
+ if (!resolveConditionalComponentOption(component.defer, interaction)) return;
1656
+ if (resolveConditionalComponentOption(component.ephemeral, interaction)) {
1657
+ await interaction.defer({ ephemeral: true });
1658
+ return;
1659
+ }
1660
+ await interaction.acknowledge();
1661
+ }
1662
+ function readInteractionName(rawData) {
1663
+ return rawData.data?.name;
1664
+ }
1665
+ function readCustomId(rawData) {
1666
+ return rawData.data?.custom_id;
1667
+ }
1668
+ function readComponentValues(rawData) {
1669
+ const values = rawData.data?.values;
1670
+ return Array.isArray(values) ? values.map(String) : void 0;
1671
+ }
1672
+ function readMessageId(rawData) {
1673
+ const messageId = rawData.message?.id;
1674
+ return typeof messageId === "string" ? messageId : void 0;
1675
+ }
1676
+ function readMessageChannelId(rawData) {
1677
+ const channelId = rawData.message?.channel_id;
1678
+ return typeof channelId === "string" ? channelId : void 0;
1679
+ }
1680
+ //#endregion
1681
+ //#region extensions/discord/src/internal/rest-body.ts
1682
+ function serializeRequestBody(data, headers) {
1683
+ if (data?.headers) for (const [key, value] of Object.entries(data.headers)) headers.set(key, value);
1684
+ if (data?.body == null) return;
1685
+ if (typeof data.body === "object") {
1686
+ const bodyObject = data.body;
1687
+ const topLevelFiles = Array.isArray(bodyObject.files) ? bodyObject.files : void 0;
1688
+ const nestedData = bodyObject.data && typeof bodyObject.data === "object" ? bodyObject.data : void 0;
1689
+ const nestedFiles = nestedData && Array.isArray(nestedData.files) ? nestedData.files : void 0;
1690
+ const files = topLevelFiles ?? nestedFiles;
1691
+ const filesContainer = topLevelFiles ? bodyObject : nestedFiles ? nestedData : void 0;
1692
+ if (files?.length && filesContainer) {
1693
+ if (data.multipartStyle === "form") {
1694
+ const formData = new FormData();
1695
+ for (const [key, value] of Object.entries(filesContainer)) {
1696
+ if (key === "files" || value === void 0 || value === null) continue;
1697
+ formData.append(key, typeof value === "string" ? value : JSON.stringify(value));
1698
+ }
1699
+ for (const file of files) {
1700
+ const item = file;
1701
+ const name = typeof item.name === "string" && item.name ? item.name : "file";
1702
+ const blob = item.data instanceof Blob ? item.data : new Blob([item.data], { type: typeof item.contentType === "string" ? item.contentType : void 0 });
1703
+ formData.append(typeof item.fieldName === "string" && item.fieldName ? item.fieldName : "file", blob, name);
1704
+ }
1705
+ return formData;
1706
+ }
1707
+ const payloadJson = topLevelFiles ? { ...bodyObject } : {
1708
+ ...bodyObject,
1709
+ data: { ...nestedData }
1710
+ };
1711
+ const payloadFilesContainer = topLevelFiles ? payloadJson : payloadJson.data ?? {};
1712
+ const formData = new FormData();
1713
+ const existingAttachments = Array.isArray(payloadFilesContainer.attachments) ? [...payloadFilesContainer.attachments] : [];
1714
+ const uploaded = files.map((file, index) => {
1715
+ const item = file;
1716
+ const name = typeof item.name === "string" && item.name ? item.name : `file-${index}`;
1717
+ const blob = item.data instanceof Blob ? item.data : new Blob([item.data], { type: typeof item.contentType === "string" ? item.contentType : void 0 });
1718
+ const id = existingAttachments.length + index;
1719
+ formData.append(`files[${id}]`, blob, name);
1720
+ const attachment = {
1721
+ id,
1722
+ filename: name
1723
+ };
1724
+ if (typeof item.description === "string") attachment.description = item.description;
1725
+ if (typeof item.duration_secs === "number") attachment.duration_secs = item.duration_secs;
1726
+ if (typeof item.waveform === "string") attachment.waveform = item.waveform;
1727
+ return attachment;
1728
+ });
1729
+ payloadFilesContainer.attachments = [...existingAttachments, ...uploaded];
1730
+ delete payloadFilesContainer.files;
1731
+ formData.append("payload_json", JSON.stringify(payloadJson));
1732
+ return formData;
1733
+ }
1734
+ }
1735
+ if (!data.rawBody) headers.set("Content-Type", "application/json");
1736
+ return data.rawBody ? data.body : JSON.stringify(data.body);
1737
+ }
1738
+ //#endregion
1739
+ //#region extensions/discord/src/internal/rest-errors.ts
1740
+ function readDiscordCode(body) {
1741
+ const value = body && typeof body === "object" && "code" in body ? body.code : void 0;
1742
+ if (typeof value === "number" && Number.isFinite(value)) return value;
1743
+ if (typeof value === "string" && /^\d+$/.test(value)) return Number(value);
1744
+ }
1745
+ function readDiscordMessage(body, fallback) {
1746
+ const value = body && typeof body === "object" && "message" in body ? body.message : void 0;
1747
+ return typeof value === "string" && value.trim() ? value : fallback;
1748
+ }
1749
+ function readRetryAfterHeader(value, now = Date.now()) {
1750
+ if (!value) return;
1751
+ const seconds = Number(value);
1752
+ if (Number.isFinite(seconds)) return seconds;
1753
+ const retryAt = Date.parse(value);
1754
+ return Number.isFinite(retryAt) ? (retryAt - now) / 1e3 : void 0;
1755
+ }
1756
+ function coerceRetryAfterSeconds(value) {
1757
+ if (typeof value !== "number" && typeof value !== "string") return;
1758
+ const seconds = typeof value === "number" ? value : Number(value);
1759
+ return Number.isFinite(seconds) && seconds >= 0 ? Math.max(0, seconds) : void 0;
1760
+ }
1761
+ function readRetryAfter(body, response, fallbackSeconds = 0) {
1762
+ return coerceRetryAfterSeconds(body && typeof body === "object" && "retry_after" in body ? body.retry_after : void 0) ?? coerceRetryAfterSeconds(readRetryAfterHeader(response.headers.get("Retry-After"))) ?? fallbackSeconds;
1763
+ }
1764
+ var DiscordError = class extends Error {
1765
+ constructor(response, body) {
1766
+ super(readDiscordMessage(body, `Discord API request failed (${response.status})`));
1767
+ this.name = "DiscordError";
1768
+ this.status = response.status;
1769
+ this.statusCode = response.status;
1770
+ this.rawBody = body;
1771
+ this.rawError = body;
1772
+ this.discordCode = readDiscordCode(body);
1773
+ }
1774
+ };
1775
+ var RateLimitError = class extends DiscordError {
1776
+ constructor(response, body) {
1777
+ super(response, body);
1778
+ this.name = "RateLimitError";
1779
+ this.retryAfter = readRetryAfter(body, response, 1);
1780
+ this.scope = body.global ? "global" : response.headers.get("X-RateLimit-Scope");
1781
+ this.bucket = response.headers.get("X-RateLimit-Bucket");
1782
+ }
1783
+ };
1784
+ //#endregion
1785
+ //#region extensions/discord/src/internal/rest-routes.ts
1786
+ function createRouteKey(method, path) {
1787
+ return `${method.toUpperCase()} ${path.split("?")[0] ?? path}`;
1788
+ }
1789
+ function readTopLevelRouteKey(path) {
1790
+ const [pathname = path] = path.split("?");
1791
+ const [first, id, token] = pathname.replace(/^\/+/, "").split("/");
1792
+ if (!first || !id) return pathname;
1793
+ if (first === "channels" || first === "guilds" || first === "webhooks") return first === "webhooks" && token ? `${first}/${id}/${token}` : `${first}/${id}`;
1794
+ return first;
1795
+ }
1796
+ function createBucketKey(bucket, path) {
1797
+ return `${bucket}:${readTopLevelRouteKey(path)}`;
1798
+ }
1799
+ function readHeaderNumber(headers, name) {
1800
+ const value = headers.get(name);
1801
+ if (!value) return;
1802
+ const parsed = Number(value);
1803
+ return Number.isFinite(parsed) ? parsed : void 0;
1804
+ }
1805
+ function readResetAt(response) {
1806
+ const resetAfter = readHeaderNumber(response.headers, "X-RateLimit-Reset-After");
1807
+ if (resetAfter !== void 0) return Date.now() + Math.max(0, resetAfter * 1e3);
1808
+ const reset = readHeaderNumber(response.headers, "X-RateLimit-Reset");
1809
+ return reset !== void 0 ? reset * 1e3 : void 0;
1810
+ }
1811
+ function appendQuery(path, query) {
1812
+ if (!query || Object.keys(query).length === 0) return path;
1813
+ const search = new URLSearchParams();
1814
+ for (const [key, value] of Object.entries(query)) search.set(key, String(value));
1815
+ return `${path}?${search.toString()}`;
1816
+ }
1817
+ //#endregion
1818
+ //#region extensions/discord/src/internal/rest-scheduler.ts
1819
+ const INVALID_REQUEST_WINDOW_MS = 10 * 6e4;
1820
+ const requestPriorities = [
1821
+ "critical",
1822
+ "standard",
1823
+ "background"
1824
+ ];
1825
+ function createLaneQueues() {
1826
+ return {
1827
+ critical: [],
1828
+ standard: [],
1829
+ background: []
1830
+ };
1831
+ }
1832
+ function countPending(bucket) {
1833
+ return requestPriorities.reduce((count, lane) => count + bucket.pending[lane].length, 0);
1834
+ }
1835
+ var RestScheduler = class {
1836
+ constructor(options, executor) {
1837
+ this.options = options;
1838
+ this.executor = executor;
1839
+ this.activeWorkers = 0;
1840
+ this.buckets = /* @__PURE__ */ new Map();
1841
+ this.globalRateLimitUntil = 0;
1842
+ this.invalidRequestTimestamps = [];
1843
+ this.laneCursor = 0;
1844
+ this.laneDropped = {
1845
+ critical: 0,
1846
+ standard: 0,
1847
+ background: 0
1848
+ };
1849
+ this.queuedByLane = {
1850
+ critical: 0,
1851
+ standard: 0,
1852
+ background: 0
1853
+ };
1854
+ this.queueGeneration = 0;
1855
+ this.queuedRequests = 0;
1856
+ this.routeBuckets = /* @__PURE__ */ new Map();
1857
+ this.laneSchedule = this.buildLaneSchedule(options.lanes);
1858
+ }
1859
+ enqueue(params) {
1860
+ if (this.queuedRequests >= this.options.maxQueueSize) throw new Error("Discord request queue is full");
1861
+ const laneOptions = this.options.lanes[params.priority];
1862
+ if (this.queuedByLane[params.priority] >= laneOptions.maxQueueSize) {
1863
+ this.laneDropped[params.priority] += 1;
1864
+ throw new Error(`Discord ${params.priority} request queue is full (${this.queuedByLane[params.priority]} / ${laneOptions.maxQueueSize})`);
1865
+ }
1866
+ const routeKey = createRouteKey(params.method, params.path);
1867
+ const bucket = this.getBucket(this.routeBuckets.get(routeKey) ?? routeKey);
1868
+ return new Promise((resolve, reject) => {
1869
+ this.queuedRequests += 1;
1870
+ this.queuedByLane[params.priority] += 1;
1871
+ bucket.pending[params.priority].push({
1872
+ ...params,
1873
+ enqueuedAt: Date.now(),
1874
+ generation: this.queueGeneration,
1875
+ routeKey,
1876
+ retryCount: 0,
1877
+ resolve,
1878
+ reject
1879
+ });
1880
+ this.drainQueues();
1881
+ });
1882
+ }
1883
+ recordResponse(routeKey, path, response, parsed) {
1884
+ this.updateRateLimitState(routeKey, path, response, parsed);
1885
+ this.recordInvalidRequest(routeKey, path, response);
1886
+ }
1887
+ clearQueue() {
1888
+ this.queueGeneration += 1;
1889
+ if (this.drainTimer) {
1890
+ clearTimeout(this.drainTimer);
1891
+ this.drainTimer = void 0;
1892
+ }
1893
+ this.rejectPending(/* @__PURE__ */ new Error("Discord request queue cleared"));
1894
+ }
1895
+ abortPending() {
1896
+ this.queueGeneration += 1;
1897
+ this.rejectPending(new DOMException("Aborted", "AbortError"));
1898
+ }
1899
+ get queueSize() {
1900
+ return this.queuedRequests;
1901
+ }
1902
+ getMetrics() {
1903
+ this.pruneInvalidRequests();
1904
+ return {
1905
+ globalRateLimitUntil: this.globalRateLimitUntil,
1906
+ activeBuckets: this.buckets.size,
1907
+ routeBucketMappings: this.routeBuckets.size,
1908
+ buckets: Array.from(this.buckets.entries()).map(([key, bucket]) => ({
1909
+ key,
1910
+ active: bucket.active,
1911
+ bucket: bucket.bucket,
1912
+ invalidRequests: bucket.invalidRequests,
1913
+ pending: countPending(bucket),
1914
+ pendingByLane: Object.fromEntries(requestPriorities.map((lane) => [lane, bucket.pending[lane].length])),
1915
+ rateLimitHits: bucket.rateLimitHits,
1916
+ remaining: bucket.remaining,
1917
+ resetAt: bucket.resetAt,
1918
+ routeKeyCount: bucket.routeKeys.size
1919
+ })),
1920
+ invalidRequestCount: this.invalidRequestTimestamps.length,
1921
+ invalidRequestCountByStatus: this.invalidRequestTimestamps.reduce((counts, entry) => {
1922
+ counts[entry.status] = (counts[entry.status] ?? 0) + 1;
1923
+ return counts;
1924
+ }, {}),
1925
+ queueSize: this.queueSize,
1926
+ queueSizeByLane: { ...this.queuedByLane },
1927
+ droppedByLane: { ...this.laneDropped },
1928
+ oldestQueuedByLane: Object.fromEntries(requestPriorities.map((lane) => [lane, this.getOldestQueuedAge(lane)])),
1929
+ activeWorkers: this.activeWorkers,
1930
+ maxConcurrentWorkers: this.maxConcurrentWorkers
1931
+ };
1932
+ }
1933
+ get maxConcurrentWorkers() {
1934
+ return Math.max(1, Math.floor(this.options.maxConcurrency));
1935
+ }
1936
+ get maxRateLimitRetries() {
1937
+ return Math.max(0, Math.floor(this.options.maxRateLimitRetries));
1938
+ }
1939
+ getBucket(key) {
1940
+ const existing = this.buckets.get(key);
1941
+ if (existing) return existing;
1942
+ const bucket = {
1943
+ active: 0,
1944
+ invalidRequests: 0,
1945
+ pending: createLaneQueues(),
1946
+ rateLimitHits: 0,
1947
+ resetAt: 0,
1948
+ routeKeys: new Set([key])
1949
+ };
1950
+ this.buckets.set(key, bucket);
1951
+ return bucket;
1952
+ }
1953
+ hasBucketReference(key) {
1954
+ for (const bucketKey of this.routeBuckets.values()) if (bucketKey === key) return true;
1955
+ return false;
1956
+ }
1957
+ isBucketRateLimited(bucket, now = Date.now()) {
1958
+ return bucket.remaining === 0 && bucket.resetAt > now;
1959
+ }
1960
+ pruneRouteMapping(routeKey) {
1961
+ const bucketKey = this.routeBuckets.get(routeKey);
1962
+ if (!bucketKey) return;
1963
+ this.routeBuckets.delete(routeKey);
1964
+ this.buckets.get(bucketKey)?.routeKeys.delete(routeKey);
1965
+ }
1966
+ pruneIdleRouteMappings(bucketKey, bucket, now = Date.now()) {
1967
+ if (bucket.active > 0 || countPending(bucket) > 0 || this.isBucketRateLimited(bucket, now)) return;
1968
+ for (const routeKey of Array.from(bucket.routeKeys)) if (this.routeBuckets.get(routeKey) === bucketKey) this.pruneRouteMapping(routeKey);
1969
+ }
1970
+ shouldPruneIdleBucket(key) {
1971
+ return this.routeBuckets.get(key) !== key && !this.hasBucketReference(key);
1972
+ }
1973
+ bindRouteToBucket(routeKey, bucketKey) {
1974
+ const target = this.getBucket(bucketKey);
1975
+ target.routeKeys.add(routeKey);
1976
+ this.routeBuckets.set(routeKey, bucketKey);
1977
+ const routeBucket = this.buckets.get(routeKey);
1978
+ if (routeBucket && routeBucket !== target) {
1979
+ for (const lane of requestPriorities) {
1980
+ target.pending[lane].push(...routeBucket.pending[lane]);
1981
+ routeBucket.pending[lane] = [];
1982
+ }
1983
+ if (routeBucket.active === 0) this.buckets.delete(routeKey);
1984
+ }
1985
+ return target;
1986
+ }
1987
+ updateRateLimitState(routeKey, path, response, parsed) {
1988
+ const bucketHeader = response.headers.get("X-RateLimit-Bucket");
1989
+ const bucket = bucketHeader ? this.bindRouteToBucket(routeKey, createBucketKey(bucketHeader, path)) : this.getBucket(this.routeBuckets.get(routeKey) ?? routeKey);
1990
+ bucket.bucket = bucketHeader ?? bucket.bucket;
1991
+ const limit = readHeaderNumber(response.headers, "X-RateLimit-Limit");
1992
+ if (limit !== void 0) bucket.limit = limit;
1993
+ const remaining = readHeaderNumber(response.headers, "X-RateLimit-Remaining");
1994
+ if (remaining !== void 0) bucket.remaining = remaining;
1995
+ const resetAt = readResetAt(response);
1996
+ if (resetAt !== void 0) bucket.resetAt = resetAt;
1997
+ if (response.status !== 429) return;
1998
+ bucket.rateLimitHits += 1;
1999
+ const retryAfterMs = Math.max(0, readRetryAfter(parsed, response, 1) * 1e3);
2000
+ const retryAt = Date.now() + retryAfterMs;
2001
+ if (response.headers.get("X-RateLimit-Global") === "true" || isGlobalRateLimit(parsed)) {
2002
+ this.globalRateLimitUntil = Math.max(this.globalRateLimitUntil, retryAt);
2003
+ return;
2004
+ }
2005
+ bucket.remaining = 0;
2006
+ bucket.resetAt = Math.max(bucket.resetAt, retryAt);
2007
+ }
2008
+ recordInvalidRequest(routeKey, path, response) {
2009
+ if (response.status !== 401 && response.status !== 403 && response.status !== 429) return;
2010
+ if (response.status === 429 && response.headers.get("X-RateLimit-Scope") === "shared") return;
2011
+ const now = Date.now();
2012
+ this.invalidRequestTimestamps.push({
2013
+ at: now,
2014
+ status: response.status
2015
+ });
2016
+ this.pruneInvalidRequests(now);
2017
+ const bucketHeader = response.headers.get("X-RateLimit-Bucket");
2018
+ const bucketKey = bucketHeader ? createBucketKey(bucketHeader, path) : this.routeBuckets.get(routeKey) ?? routeKey;
2019
+ const bucket = this.buckets.get(bucketKey);
2020
+ if (bucket) bucket.invalidRequests += 1;
2021
+ }
2022
+ pruneInvalidRequests(now = Date.now()) {
2023
+ const cutoff = now - INVALID_REQUEST_WINDOW_MS;
2024
+ while (this.invalidRequestTimestamps.length > 0 && (this.invalidRequestTimestamps[0]?.at ?? 0) <= cutoff) this.invalidRequestTimestamps.shift();
2025
+ }
2026
+ getBucketWaitMs(bucket, now) {
2027
+ if (bucket.remaining === 0 && bucket.resetAt > now) return bucket.resetAt - now;
2028
+ if (bucket.remaining === 0 && bucket.resetAt <= now) bucket.remaining = bucket.limit;
2029
+ return 0;
2030
+ }
2031
+ scheduleDrain(delayMs = 0) {
2032
+ if (this.drainTimer) return;
2033
+ this.drainTimer = setTimeout(() => {
2034
+ this.drainTimer = void 0;
2035
+ this.drainQueues();
2036
+ }, Math.max(0, delayMs));
2037
+ this.drainTimer.unref?.();
2038
+ }
2039
+ drainQueues() {
2040
+ let nextDelayMs = Number.POSITIVE_INFINITY;
2041
+ while (this.activeWorkers < this.maxConcurrentWorkers) {
2042
+ const next = this.takeNextQueuedRequest();
2043
+ if (!next.queued) {
2044
+ if (next.waitMs !== void 0) nextDelayMs = Math.min(nextDelayMs, next.waitMs);
2045
+ break;
2046
+ }
2047
+ const { bucket, queued } = next;
2048
+ if (bucket.remaining !== void 0 && bucket.remaining > 0) bucket.remaining -= 1;
2049
+ bucket.active += 1;
2050
+ this.activeWorkers += 1;
2051
+ this.runQueuedRequest(queued, bucket);
2052
+ }
2053
+ if (Number.isFinite(nextDelayMs)) this.scheduleDrain(nextDelayMs);
2054
+ }
2055
+ takeNextQueuedRequest() {
2056
+ const now = Date.now();
2057
+ if (this.globalRateLimitUntil > now) return { waitMs: this.globalRateLimitUntil - now };
2058
+ this.pruneIdleBuckets(now);
2059
+ let nextDelayMs;
2060
+ const buckets = Array.from(this.buckets.values()).filter((bucket) => countPending(bucket) > 0);
2061
+ if (buckets.length === 0) return {};
2062
+ for (let laneOffset = 0; laneOffset < this.laneSchedule.length; laneOffset += 1) {
2063
+ const lane = this.laneSchedule[(this.laneCursor + laneOffset) % this.laneSchedule.length];
2064
+ if (!lane || this.queuedByLane[lane] <= 0) continue;
2065
+ for (const bucket of buckets) {
2066
+ const queue = bucket.pending[lane];
2067
+ this.dropStaleHeadRequests(queue, lane, now);
2068
+ if (queue.length === 0) continue;
2069
+ if (bucket.active > 0) continue;
2070
+ const waitMs = this.getBucketWaitMs(bucket, now);
2071
+ if (waitMs > 0) {
2072
+ nextDelayMs = Math.min(nextDelayMs ?? waitMs, waitMs);
2073
+ continue;
2074
+ }
2075
+ const queued = queue.shift();
2076
+ if (!queued) continue;
2077
+ this.queuedByLane[lane] = Math.max(0, this.queuedByLane[lane] - 1);
2078
+ this.laneCursor = (this.laneCursor + laneOffset + 1) % this.laneSchedule.length;
2079
+ return {
2080
+ bucket,
2081
+ queued
2082
+ };
2083
+ }
2084
+ }
2085
+ return { waitMs: nextDelayMs };
2086
+ }
2087
+ dropStaleHeadRequests(queue, lane, now) {
2088
+ if (lane !== "background") return;
2089
+ const staleAfterMs = this.options.lanes[lane].staleAfterMs;
2090
+ if (!staleAfterMs || staleAfterMs <= 0) return;
2091
+ while (queue.length > 0 && now - (queue[0]?.enqueuedAt ?? now) > staleAfterMs) {
2092
+ const stale = queue.shift();
2093
+ if (!stale) continue;
2094
+ this.queuedRequests = Math.max(0, this.queuedRequests - 1);
2095
+ this.queuedByLane[lane] = Math.max(0, this.queuedByLane[lane] - 1);
2096
+ this.laneDropped[lane] += 1;
2097
+ stale.reject(/* @__PURE__ */ new Error(`Dropped stale ${lane} request after ${now - stale.enqueuedAt}ms`));
2098
+ }
2099
+ }
2100
+ pruneIdleBuckets(now = Date.now()) {
2101
+ for (const [key, bucket] of this.buckets) {
2102
+ if (bucket.active !== 0 || countPending(bucket) > 0) continue;
2103
+ if (this.isBucketRateLimited(bucket, now)) continue;
2104
+ this.pruneIdleRouteMappings(key, bucket, now);
2105
+ if (this.shouldPruneIdleBucket(key)) this.buckets.delete(key);
2106
+ }
2107
+ }
2108
+ async runQueuedRequest(queued, bucket) {
2109
+ let requeued = false;
2110
+ try {
2111
+ queued.resolve(await this.executor(queued));
2112
+ } catch (error) {
2113
+ if (error instanceof RateLimitError && this.requeueRateLimitedRequest(queued)) {
2114
+ requeued = true;
2115
+ return;
2116
+ }
2117
+ queued.reject(error);
2118
+ } finally {
2119
+ bucket.active = Math.max(0, bucket.active - 1);
2120
+ this.activeWorkers = Math.max(0, this.activeWorkers - 1);
2121
+ if (!requeued) this.queuedRequests = Math.max(0, this.queuedRequests - 1);
2122
+ if (bucket.active === 0 && countPending(bucket) === 0) {
2123
+ for (const routeKey of bucket.routeKeys) if (this.routeBuckets.get(routeKey) === routeKey) this.routeBuckets.delete(routeKey);
2124
+ }
2125
+ this.drainQueues();
2126
+ }
2127
+ }
2128
+ requeueRateLimitedRequest(queued) {
2129
+ if (queued.generation !== this.queueGeneration || queued.retryCount >= this.maxRateLimitRetries) return false;
2130
+ const bucketKey = this.routeBuckets.get(queued.routeKey) ?? queued.routeKey;
2131
+ this.getBucket(bucketKey).pending[queued.priority].push({
2132
+ ...queued,
2133
+ enqueuedAt: Date.now(),
2134
+ retryCount: queued.retryCount + 1
2135
+ });
2136
+ this.queuedByLane[queued.priority] += 1;
2137
+ return true;
2138
+ }
2139
+ rejectPending(error) {
2140
+ for (const bucket of this.buckets.values()) for (const lane of requestPriorities) for (const queued of bucket.pending[lane].splice(0)) {
2141
+ queued.reject(error);
2142
+ this.queuedRequests = Math.max(0, this.queuedRequests - 1);
2143
+ this.queuedByLane[lane] = Math.max(0, this.queuedByLane[lane] - 1);
2144
+ }
2145
+ }
2146
+ buildLaneSchedule(lanes) {
2147
+ const schedule = [];
2148
+ for (const lane of requestPriorities) {
2149
+ const weight = Math.max(1, Math.floor(lanes[lane].weight));
2150
+ for (let i = 0; i < weight; i += 1) schedule.push(lane);
2151
+ }
2152
+ return schedule.length > 0 ? schedule : [...requestPriorities];
2153
+ }
2154
+ getOldestQueuedAge(lane) {
2155
+ const now = Date.now();
2156
+ let oldest = 0;
2157
+ for (const bucket of this.buckets.values()) {
2158
+ const queued = bucket.pending[lane][0];
2159
+ if (!queued) continue;
2160
+ oldest = Math.max(oldest, now - queued.enqueuedAt);
2161
+ }
2162
+ return oldest;
2163
+ }
2164
+ };
2165
+ function isGlobalRateLimit(parsed) {
2166
+ return parsed && typeof parsed === "object" && "global" in parsed ? Boolean(parsed.global) : false;
2167
+ }
2168
+ //#endregion
2169
+ //#region extensions/discord/src/internal/rest.ts
2170
+ const defaultOptions = {
2171
+ tokenHeader: "Bot",
2172
+ baseUrl: "https://discord.com/api",
2173
+ apiVersion: 10,
2174
+ userAgent: "OpenClaw Discord",
2175
+ timeout: 15e3,
2176
+ queueRequests: true,
2177
+ maxQueueSize: 1e3,
2178
+ runtimeProfile: "persistent"
2179
+ };
2180
+ const DEFAULT_MAX_CONCURRENT_WORKERS = 4;
2181
+ const defaultLaneOptions = {
2182
+ critical: { weight: 6 },
2183
+ standard: { weight: 3 },
2184
+ background: {
2185
+ staleAfterMs: 2e4,
2186
+ weight: 1
2187
+ }
2188
+ };
2189
+ function coerceResponseBody(raw) {
2190
+ if (!raw) return;
2191
+ try {
2192
+ return JSON.parse(raw);
2193
+ } catch {
2194
+ return raw;
2195
+ }
2196
+ }
2197
+ function escapeMultipartQuotedValue(value) {
2198
+ return value.replace(/["\r\n]/g, (ch) => ch === "\"" ? "%22" : ch === "\r" ? "%0D" : "%0A");
2199
+ }
2200
+ async function formDataToMultipartBody(body, headers) {
2201
+ const boundary = `----openclaw-discord-${randomBytes(12).toString("hex")}`;
2202
+ headers.set("Content-Type", `multipart/form-data; boundary=${boundary}`);
2203
+ const chunks = [];
2204
+ const push = (value) => {
2205
+ chunks.push(typeof value === "string" ? Buffer.from(value) : value);
2206
+ };
2207
+ for (const [key, value] of body.entries()) {
2208
+ push(`--${boundary}\r\n`);
2209
+ const escapedKey = escapeMultipartQuotedValue(key);
2210
+ if (typeof value === "string") {
2211
+ push(`Content-Disposition: form-data; name="${escapedKey}"\r\n\r\n`);
2212
+ push(value);
2213
+ push("\r\n");
2214
+ continue;
2215
+ }
2216
+ const filename = value.name;
2217
+ push(`Content-Disposition: form-data; name="${escapedKey}"; filename="${escapeMultipartQuotedValue(typeof filename === "string" && filename.length > 0 ? filename : "blob")}"\r\n`);
2218
+ if (value.type) push(`Content-Type: ${value.type}\r\n`);
2219
+ push("\r\n");
2220
+ push(Buffer.from(await value.arrayBuffer()));
2221
+ push("\r\n");
2222
+ }
2223
+ push(`--${boundary}--\r\n`);
2224
+ return Buffer.concat(chunks);
2225
+ }
2226
+ async function normalizeFetchBody(body, headers) {
2227
+ if (body instanceof FormData) return await formDataToMultipartBody(body, headers);
2228
+ return body;
2229
+ }
2230
+ var RequestClient = class {
2231
+ constructor(token, options) {
2232
+ this.requestControllers = /* @__PURE__ */ new Set();
2233
+ this.token = token.replace(/^Bot\s+/i, "");
2234
+ this.customFetch = options?.fetch;
2235
+ this.options = {
2236
+ ...defaultOptions,
2237
+ ...options
2238
+ };
2239
+ this.scheduler = new RestScheduler({
2240
+ lanes: normalizeSchedulerLanes(this.options.maxQueueSize ?? defaultOptions.maxQueueSize, this.options.scheduler?.lanes),
2241
+ maxConcurrency: this.options.scheduler?.maxConcurrency ?? DEFAULT_MAX_CONCURRENT_WORKERS,
2242
+ maxQueueSize: this.options.maxQueueSize ?? defaultOptions.maxQueueSize,
2243
+ maxRateLimitRetries: this.options.scheduler?.maxRateLimitRetries ?? 3
2244
+ }, async (request) => await this.executeRequest(request.method, request.path, {
2245
+ data: request.data,
2246
+ query: request.query
2247
+ }, request.routeKey));
2248
+ }
2249
+ async get(path, query) {
2250
+ return await this.request("GET", path, { query });
2251
+ }
2252
+ async post(path, data, query) {
2253
+ return await this.request("POST", path, {
2254
+ data,
2255
+ query
2256
+ });
2257
+ }
2258
+ async patch(path, data, query) {
2259
+ return await this.request("PATCH", path, {
2260
+ data,
2261
+ query
2262
+ });
2263
+ }
2264
+ async put(path, data, query) {
2265
+ return await this.request("PUT", path, {
2266
+ data,
2267
+ query
2268
+ });
2269
+ }
2270
+ async delete(path, data, query) {
2271
+ return await this.request("DELETE", path, {
2272
+ data,
2273
+ query
2274
+ });
2275
+ }
2276
+ async request(method, path, params) {
2277
+ const routeKey = createRouteKey(method, path);
2278
+ if (!this.options.queueRequests) return await this.executeRequest(method, path, params, routeKey);
2279
+ return await this.scheduler.enqueue({
2280
+ method,
2281
+ path,
2282
+ priority: getRequestPriority(method, path),
2283
+ ...params
2284
+ });
2285
+ }
2286
+ async executeRequest(method, path, params, routeKey = createRouteKey(method, path)) {
2287
+ const url = `${this.options.baseUrl}/v${this.options.apiVersion}${appendQuery(path, params.query)}`;
2288
+ const headers = new Headers({ "User-Agent": this.options.userAgent ?? defaultOptions.userAgent });
2289
+ if (this.token !== "webhook") headers.set("Authorization", `${this.options.tokenHeader ?? "Bot"} ${this.token}`);
2290
+ const body = serializeRequestBody(params.data, headers);
2291
+ const controller = new AbortController();
2292
+ const timeout = setTimeout(() => controller.abort(), this.options.timeout ?? 15e3);
2293
+ timeout.unref?.();
2294
+ this.requestControllers.add(controller);
2295
+ try {
2296
+ const response = await (this.customFetch ?? fetch)(url, {
2297
+ method,
2298
+ headers,
2299
+ body: await normalizeFetchBody(body, headers),
2300
+ signal: controller.signal
2301
+ });
2302
+ const parsed = coerceResponseBody(await response.text());
2303
+ this.scheduler.recordResponse(routeKey, path, response, parsed);
2304
+ if (response.status === 204) return;
2305
+ if (response.status === 429) {
2306
+ const rateLimitBody = isDiscordRateLimitBody(parsed) ? parsed : void 0;
2307
+ throw new RateLimitError(response, {
2308
+ message: readDiscordMessage(rateLimitBody, "Rate limited"),
2309
+ retry_after: readRetryAfter(rateLimitBody, response, 1),
2310
+ code: readDiscordCode(rateLimitBody),
2311
+ global: Boolean(rateLimitBody?.global)
2312
+ });
2313
+ }
2314
+ if (!response.ok) throw new DiscordError(response, parsed);
2315
+ return parsed;
2316
+ } catch (error) {
2317
+ if (error instanceof DOMException && error.name === "AbortError") throw error;
2318
+ if (error instanceof Error) throw error;
2319
+ throw new Error(`Discord request failed: ${inspect(error)}`, { cause: error });
2320
+ } finally {
2321
+ clearTimeout(timeout);
2322
+ this.requestControllers.delete(controller);
2323
+ }
2324
+ }
2325
+ clearQueue() {
2326
+ this.scheduler.clearQueue();
2327
+ }
2328
+ get queueSize() {
2329
+ return this.scheduler.queueSize;
2330
+ }
2331
+ getSchedulerMetrics() {
2332
+ return this.scheduler.getMetrics();
2333
+ }
2334
+ abortAllRequests() {
2335
+ this.scheduler.abortPending();
2336
+ for (const controller of this.requestControllers) controller.abort();
2337
+ this.requestControllers.clear();
2338
+ }
2339
+ };
2340
+ function normalizeSchedulerLanes(maxQueueSize, lanes) {
2341
+ const fallbackMaxQueueSize = Math.max(1, Math.floor(maxQueueSize));
2342
+ return {
2343
+ critical: normalizeSchedulerLane("critical", fallbackMaxQueueSize, lanes?.critical),
2344
+ standard: normalizeSchedulerLane("standard", fallbackMaxQueueSize, lanes?.standard),
2345
+ background: normalizeSchedulerLane("background", fallbackMaxQueueSize, lanes?.background)
2346
+ };
2347
+ }
2348
+ function normalizeSchedulerLane(lane, maxQueueSize, options) {
2349
+ const defaults = defaultLaneOptions[lane];
2350
+ return {
2351
+ maxQueueSize: options?.maxQueueSize !== void 0 ? Math.max(1, Math.floor(options.maxQueueSize)) : maxQueueSize,
2352
+ staleAfterMs: options?.staleAfterMs !== void 0 ? Math.max(0, Math.floor(options.staleAfterMs)) : defaults.staleAfterMs,
2353
+ weight: options?.weight !== void 0 ? Math.max(1, Math.floor(options.weight)) : defaults.weight
2354
+ };
2355
+ }
2356
+ function getRequestPriority(method, path) {
2357
+ const normalizedMethod = method.toUpperCase();
2358
+ const normalizedPath = path.toLowerCase();
2359
+ if (/^\/interactions\/\d+\/[^/]+\/callback$/.test(normalizedPath)) return "critical";
2360
+ return normalizedMethod === "GET" ? "background" : "standard";
2361
+ }
2362
+ //#endregion
2363
+ //#region extensions/discord/src/internal/client.ts
2364
+ var Plugin = class {};
2365
+ var ComponentRegistry = class {
2366
+ constructor() {
2367
+ this.entries = /* @__PURE__ */ new Map();
2368
+ this.oneOffComponents = /* @__PURE__ */ new Map();
2369
+ this.wildcardEntries = [];
2370
+ }
2371
+ register(entry) {
2372
+ const key = parseRegistryKey(entry.customId, entry.customIdParser);
2373
+ if (key === "*") {
2374
+ if (!this.wildcardEntries.includes(entry)) this.wildcardEntries.push(entry);
2375
+ return;
2376
+ }
2377
+ const entries = this.entries.get(key) ?? [];
2378
+ if (!entries.includes(entry)) {
2379
+ entries.push(entry);
2380
+ this.entries.set(key, entries);
2381
+ }
2382
+ }
2383
+ resolve(customId, options) {
2384
+ for (const entries of this.entries.values()) {
2385
+ const match = entries.find((entry) => {
2386
+ if (options?.componentType !== void 0 && entry.type !== options.componentType) return false;
2387
+ const parser = entry.customIdParser ?? parseCustomId;
2388
+ return parseRegistryKey(entry.customId, parser) === parseRegistryKey(customId, parser);
2389
+ });
2390
+ if (match) return match;
2391
+ }
2392
+ return this.wildcardEntries.find((entry) => {
2393
+ if (options?.componentType !== void 0 && entry.type !== options.componentType) return false;
2394
+ return true;
2395
+ });
2396
+ }
2397
+ waitForMessageComponent(message, timeoutMs) {
2398
+ const key = createOneOffComponentKey(message.id, message.channelId);
2399
+ return new Promise((resolve) => {
2400
+ const existing = this.oneOffComponents.get(key);
2401
+ if (existing) {
2402
+ clearTimeout(existing.timer);
2403
+ existing.resolve({
2404
+ success: false,
2405
+ message,
2406
+ reason: "timed out"
2407
+ });
2408
+ }
2409
+ const timer = setTimeout(() => {
2410
+ this.oneOffComponents.delete(key);
2411
+ resolve({
2412
+ success: false,
2413
+ message,
2414
+ reason: "timed out"
2415
+ });
2416
+ }, Math.max(0, timeoutMs));
2417
+ timer.unref?.();
2418
+ this.oneOffComponents.set(key, {
2419
+ message,
2420
+ timer,
2421
+ resolve
2422
+ });
2423
+ });
2424
+ }
2425
+ resolveOneOffComponent(params) {
2426
+ if (!params.messageId || !params.channelId) return false;
2427
+ const entry = this.oneOffComponents.get(createOneOffComponentKey(params.messageId, params.channelId));
2428
+ if (!entry) return false;
2429
+ clearTimeout(entry.timer);
2430
+ this.oneOffComponents.delete(createOneOffComponentKey(params.messageId, params.channelId));
2431
+ entry.resolve({
2432
+ success: true,
2433
+ customId: params.customId,
2434
+ message: entry.message,
2435
+ values: params.values
2436
+ });
2437
+ return true;
2438
+ }
2439
+ };
2440
+ function parseRegistryKey(customId, parser = parseCustomId) {
2441
+ return parser(customId).key;
2442
+ }
2443
+ function createOneOffComponentKey(messageId, channelId) {
2444
+ return `${messageId}:${channelId}`;
2445
+ }
2446
+ var Client = class {
2447
+ constructor(options, handlers, plugins = []) {
2448
+ this.routes = [];
2449
+ this.plugins = [];
2450
+ this.componentHandler = new ComponentRegistry();
2451
+ this.modalHandler = new ComponentRegistry();
2452
+ if (!options.clientId) throw new Error("Missing Discord application ID");
2453
+ if (!options.token) throw new Error("Missing Discord bot token");
2454
+ this.options = {
2455
+ ...options,
2456
+ baseUrl: options.baseUrl.replace(/\/+$/, "")
2457
+ };
2458
+ this.commands = handlers.commands ?? [];
2459
+ this.listeners = handlers.listeners ?? [];
2460
+ this.rest = new RequestClient(options.token, options.requestOptions);
2461
+ this.eventQueue = this.options.eventQueue ? new DiscordEventQueue(this.options.eventQueue) : void 0;
2462
+ this.entityCache = new DiscordEntityCache({
2463
+ client: this,
2464
+ rest: () => this.rest,
2465
+ ttlMs: this.options.restCacheTtlMs
2466
+ });
2467
+ this.commandDeployer = new DiscordCommandDeployer({
2468
+ clientId: this.options.clientId,
2469
+ commands: this.commands,
2470
+ devGuilds: this.options.devGuilds,
2471
+ hashStorePath: this.options.commandDeployHashStorePath,
2472
+ rest: () => this.rest
2473
+ });
2474
+ for (const component of handlers.components ?? []) this.componentHandler.register(component);
2475
+ for (const command of this.commands) for (const component of command.components ?? []) this.componentHandler.register(component);
2476
+ for (const modal of handlers.modals ?? []) this.modalHandler.register(modal);
2477
+ for (const plugin of plugins) {
2478
+ plugin.registerClient?.(this);
2479
+ plugin.registerRoutes?.(this);
2480
+ this.plugins.push({
2481
+ id: plugin.id,
2482
+ plugin
2483
+ });
2484
+ }
2485
+ }
2486
+ getPlugin(id) {
2487
+ return this.plugins.find((entry) => entry.id === id)?.plugin;
2488
+ }
2489
+ registerListener(listener) {
2490
+ if (!this.listeners.includes(listener)) this.listeners.push(listener);
2491
+ return listener;
2492
+ }
2493
+ unregisterListener(listener) {
2494
+ const index = this.listeners.indexOf(listener);
2495
+ if (index < 0) return false;
2496
+ this.listeners.splice(index, 1);
2497
+ return true;
2498
+ }
2499
+ getRuntimeMetrics() {
2500
+ return {
2501
+ request: this.rest.getSchedulerMetrics(),
2502
+ eventQueue: this.eventQueue?.getMetrics()
2503
+ };
2504
+ }
2505
+ async fetchUser(id) {
2506
+ return await this.entityCache.fetchUser(id);
2507
+ }
2508
+ async fetchChannel(id) {
2509
+ return await this.entityCache.fetchChannel(id);
2510
+ }
2511
+ async fetchGuild(id) {
2512
+ return await this.entityCache.fetchGuild(id);
2513
+ }
2514
+ async fetchMember(guildId, userId) {
2515
+ return await this.entityCache.fetchMember(guildId, userId);
2516
+ }
2517
+ async getDiscordCommands() {
2518
+ return await this.commandDeployer.getCommands();
2519
+ }
2520
+ async deployCommands(options = {}) {
2521
+ return await this.commandDeployer.deploy(options);
2522
+ }
2523
+ async reconcileCommands() {
2524
+ return await this.deployCommands({ mode: "reconcile" });
2525
+ }
2526
+ async handleInteraction(rawData, _ctx) {
2527
+ await dispatchInteraction(this, rawData);
2528
+ }
2529
+ async dispatchGatewayEvent(type, data) {
2530
+ this.entityCache.invalidateForGatewayEvent(type, data);
2531
+ const listeners = this.listeners.filter((entry) => entry.type === type);
2532
+ if (!this.eventQueue) {
2533
+ for (const listener of listeners) await listener.handle(data, this);
2534
+ return;
2535
+ }
2536
+ await Promise.all(listeners.map((listener) => this.eventQueue.enqueue({
2537
+ eventType: type,
2538
+ listenerName: listener.constructor.name || "AnonymousListener",
2539
+ run: async () => {
2540
+ await listener.handle(data, this);
2541
+ }
2542
+ })));
2543
+ }
2544
+ };
2545
+ //#endregion
2546
+ //#region extensions/discord/src/internal/embeds.ts
2547
+ function clean(value) {
2548
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
2549
+ }
2550
+ var Embed = class {
2551
+ constructor(embed) {
2552
+ Object.assign(this, embed);
2553
+ }
2554
+ serialize() {
2555
+ return clean({
2556
+ title: this.title,
2557
+ description: this.description,
2558
+ url: this.url,
2559
+ timestamp: this.timestamp,
2560
+ color: this.color,
2561
+ footer: this.footer,
2562
+ image: typeof this.image === "string" ? { url: this.image } : this.image,
2563
+ thumbnail: typeof this.thumbnail === "string" ? { url: this.thumbnail } : this.thumbnail,
2564
+ author: this.author,
2565
+ fields: this.fields
2566
+ });
2567
+ }
2568
+ };
2569
+ //#endregion
2570
+ //#region extensions/discord/src/internal/listeners.ts
2571
+ var BaseListener = class {};
2572
+ var ReadyListener = class extends BaseListener {
2573
+ constructor(..._args) {
2574
+ super(..._args);
2575
+ this.type = GatewayDispatchEvents.Ready;
2576
+ }
2577
+ };
2578
+ var ResumedListener = class extends BaseListener {
2579
+ constructor(..._args2) {
2580
+ super(..._args2);
2581
+ this.type = GatewayDispatchEvents.Resumed;
2582
+ }
2583
+ };
2584
+ var MessageCreateListener = class extends BaseListener {
2585
+ constructor(..._args3) {
2586
+ super(..._args3);
2587
+ this.type = GatewayDispatchEvents.MessageCreate;
2588
+ }
2589
+ };
2590
+ var InteractionCreateListener = class extends BaseListener {
2591
+ constructor(..._args4) {
2592
+ super(..._args4);
2593
+ this.type = GatewayDispatchEvents.InteractionCreate;
2594
+ }
2595
+ };
2596
+ var MessageReactionAddListener = class extends BaseListener {
2597
+ constructor(..._args5) {
2598
+ super(..._args5);
2599
+ this.type = GatewayDispatchEvents.MessageReactionAdd;
2600
+ }
2601
+ };
2602
+ var MessageReactionRemoveListener = class extends BaseListener {
2603
+ constructor(..._args6) {
2604
+ super(..._args6);
2605
+ this.type = GatewayDispatchEvents.MessageReactionRemove;
2606
+ }
2607
+ };
2608
+ var PresenceUpdateListener = class extends BaseListener {
2609
+ constructor(..._args7) {
2610
+ super(..._args7);
2611
+ this.type = GatewayDispatchEvents.PresenceUpdate;
2612
+ }
2613
+ };
2614
+ var ThreadUpdateListener = class extends BaseListener {
2615
+ constructor(..._args8) {
2616
+ super(..._args8);
2617
+ this.type = GatewayDispatchEvents.ThreadUpdate;
2618
+ }
2619
+ };
2620
+ //#endregion
2621
+ //#region extensions/discord/src/internal/discord.ts
2622
+ var discord_exports = /* @__PURE__ */ __exportAll({
2623
+ AnySelectMenu: () => AnySelectMenu,
2624
+ AutocompleteInteraction: () => AutocompleteInteraction,
2625
+ Base: () => Base,
2626
+ BaseCommand: () => BaseCommand,
2627
+ BaseComponent: () => BaseComponent,
2628
+ BaseComponentInteraction: () => BaseComponentInteraction,
2629
+ BaseInteraction: () => BaseInteraction,
2630
+ BaseListener: () => BaseListener,
2631
+ BaseMessageInteractiveComponent: () => BaseMessageInteractiveComponent,
2632
+ BaseModalComponent: () => BaseModalComponent,
2633
+ Button: () => Button,
2634
+ ButtonInteraction: () => ButtonInteraction,
2635
+ ChannelSelectMenu: () => ChannelSelectMenu,
2636
+ ChannelSelectMenuInteraction: () => ChannelSelectMenuInteraction,
2637
+ CheckboxGroup: () => CheckboxGroup,
2638
+ Client: () => Client,
2639
+ Command: () => Command,
2640
+ CommandInteraction: () => CommandInteraction,
2641
+ CommandWithSubcommands: () => CommandWithSubcommands,
2642
+ ComponentRegistry: () => ComponentRegistry,
2643
+ Container: () => Container,
2644
+ DiscordError: () => DiscordError,
2645
+ Embed: () => Embed,
2646
+ File: () => File,
2647
+ Guild: () => Guild,
2648
+ GuildMember: () => GuildMember,
2649
+ InteractionCreateListener: () => InteractionCreateListener,
2650
+ Label: () => Label,
2651
+ LinkButton: () => LinkButton,
2652
+ MediaGallery: () => MediaGallery,
2653
+ MentionableSelectMenu: () => MentionableSelectMenu,
2654
+ MentionableSelectMenuInteraction: () => MentionableSelectMenuInteraction,
2655
+ Message: () => Message,
2656
+ MessageCreateListener: () => MessageCreateListener,
2657
+ MessageReactionAddListener: () => MessageReactionAddListener,
2658
+ MessageReactionRemoveListener: () => MessageReactionRemoveListener,
2659
+ Modal: () => Modal,
2660
+ ModalFields: () => ModalFields,
2661
+ ModalInteraction: () => ModalInteraction,
2662
+ OptionsHandler: () => OptionsHandler,
2663
+ Plugin: () => Plugin,
2664
+ PresenceUpdateListener: () => PresenceUpdateListener,
2665
+ RadioGroup: () => RadioGroup,
2666
+ RateLimitError: () => RateLimitError,
2667
+ ReadyListener: () => ReadyListener,
2668
+ RequestClient: () => RequestClient,
2669
+ ResumedListener: () => ResumedListener,
2670
+ Role: () => Role,
2671
+ RoleSelectMenu: () => RoleSelectMenu,
2672
+ RoleSelectMenuInteraction: () => RoleSelectMenuInteraction,
2673
+ Row: () => Row,
2674
+ Section: () => Section,
2675
+ Separator: () => Separator,
2676
+ StringSelectMenu: () => StringSelectMenu,
2677
+ StringSelectMenuInteraction: () => StringSelectMenuInteraction,
2678
+ TextDisplay: () => TextDisplay,
2679
+ TextInput: () => TextInput,
2680
+ ThreadUpdateListener: () => ThreadUpdateListener,
2681
+ Thumbnail: () => Thumbnail,
2682
+ User: () => User,
2683
+ UserSelectMenu: () => UserSelectMenu,
2684
+ UserSelectMenuInteraction: () => UserSelectMenuInteraction,
2685
+ addGuildMemberRole: () => addGuildMemberRole,
2686
+ channelFactory: () => channelFactory,
2687
+ clean: () => clean$3,
2688
+ colorToNumber: () => colorToNumber,
2689
+ createApplicationCommand: () => createApplicationCommand,
2690
+ createChannelMessage: () => createChannelMessage,
2691
+ createChannelWebhook: () => createChannelWebhook,
2692
+ createGuildBan: () => createGuildBan,
2693
+ createGuildChannel: () => createGuildChannel,
2694
+ createGuildEmoji: () => createGuildEmoji,
2695
+ createGuildScheduledEvent: () => createGuildScheduledEvent,
2696
+ createGuildSticker: () => createGuildSticker,
2697
+ createInteraction: () => createInteraction,
2698
+ createInteractionCallback: () => createInteractionCallback,
2699
+ createOwnMessageReaction: () => createOwnMessageReaction,
2700
+ createThread: () => createThread,
2701
+ createUserDmChannel: () => createUserDmChannel,
2702
+ createWebhookMessage: () => createWebhookMessage,
2703
+ deferCommandInteractionIfNeeded: () => deferCommandInteractionIfNeeded,
2704
+ deleteApplicationCommand: () => deleteApplicationCommand,
2705
+ deleteChannel: () => deleteChannel,
2706
+ deleteChannelMessage: () => deleteChannelMessage,
2707
+ deleteChannelPermission: () => deleteChannelPermission,
2708
+ deleteOwnMessageReaction: () => deleteOwnMessageReaction,
2709
+ deleteWebhookMessage: () => deleteWebhookMessage,
2710
+ editApplicationCommand: () => editApplicationCommand,
2711
+ editChannel: () => editChannel,
2712
+ editChannelMessage: () => editChannelMessage,
2713
+ editWebhookMessage: () => editWebhookMessage,
2714
+ getChannel: () => getChannel,
2715
+ getChannelMessage: () => getChannelMessage,
2716
+ getCurrentUser: () => getCurrentUser,
2717
+ getGuild: () => getGuild,
2718
+ getGuildMember: () => getGuildMember,
2719
+ getGuildVoiceState: () => getGuildVoiceState,
2720
+ getUser: () => getUser,
2721
+ getWebhookMessage: () => getWebhookMessage,
2722
+ listApplicationCommands: () => listApplicationCommands,
2723
+ listChannelArchivedThreads: () => listChannelArchivedThreads,
2724
+ listChannelMessages: () => listChannelMessages,
2725
+ listChannelPins: () => listChannelPins,
2726
+ listGuildActiveThreads: () => listGuildActiveThreads,
2727
+ listGuildChannels: () => listGuildChannels,
2728
+ listGuildEmojis: () => listGuildEmojis,
2729
+ listGuildRoles: () => listGuildRoles,
2730
+ listGuildScheduledEvents: () => listGuildScheduledEvents,
2731
+ listMessageReactionUsers: () => listMessageReactionUsers,
2732
+ moveGuildChannels: () => moveGuildChannels,
2733
+ overwriteApplicationCommands: () => overwriteApplicationCommands,
2734
+ overwriteGuildApplicationCommands: () => overwriteGuildApplicationCommands,
2735
+ parseComponentInteractionData: () => parseComponentInteractionData,
2736
+ parseCustomId: () => parseCustomId,
2737
+ pinChannelMessage: () => pinChannelMessage,
2738
+ putChannelPermission: () => putChannelPermission,
2739
+ removeGuildMember: () => removeGuildMember,
2740
+ removeGuildMemberRole: () => removeGuildMemberRole,
2741
+ resolveFocusedCommandOptionAutocompleteHandler: () => resolveFocusedCommandOptionAutocompleteHandler,
2742
+ searchGuildMessages: () => searchGuildMessages,
2743
+ sendChannelTyping: () => sendChannelTyping,
2744
+ serializePayload: () => serializePayload,
2745
+ timeoutGuildMember: () => timeoutGuildMember,
2746
+ unpinChannelMessage: () => unpinChannelMessage
2747
+ });
2748
+ import * as import_discord_api_types_v10 from "discord-api-types/v10";
2749
+ __reExport(discord_exports, import_discord_api_types_v10);
2750
+ //#endregion
2751
+ export { createChannelMessage as $, Button as A, putChannelPermission as At, Separator as B, User as C, getGuildVoiceState as Ct, Modal as D, listGuildRoles as Dt, Label as E, listGuildEmojis as Et, MediaGallery as F, BaseMessageInteractiveComponent as G, TextDisplay as H, MentionableSelectMenu as I, createUserDmChannel as J, parseCustomId as K, RoleSelectMenu as L, Container as M, removeGuildMemberRole as Mt, File as N, timeoutGuildMember as Nt, RadioGroup as O, listGuildScheduledEvents as Ot, LinkButton as P, overwriteApplicationCommands as Pt, listMessageReactionUsers as Q, Row as R, Message as S, getGuildMember as St, CheckboxGroup as T, listGuildChannels as Tt, Thumbnail as U, StringSelectMenu as V, UserSelectMenu as W, createOwnMessageReaction as X, getCurrentUser as Y, deleteOwnMessageReaction as Z, readDiscordMessage as _, createGuildEmoji as _t, MessageReactionRemoveListener as a, getChannel as at, CommandWithSubcommands as b, deleteChannelPermission as bt, ResumedListener as c, listChannelMessages as ct, Client as d, searchGuildMessages as dt, createThread as et, Plugin as f, sendChannelTyping as ft, readDiscordCode as g, createGuildChannel as gt, RateLimitError as h, createGuildBan as ht, MessageReactionAddListener as i, editChannelMessage as it, ChannelSelectMenu as j, removeGuildMember as jt, TextInput as k, moveGuildChannels as kt, ThreadUpdateListener as l, listChannelPins as lt, DiscordError as m, addGuildMemberRole as mt, InteractionCreateListener as n, deleteChannelMessage as nt, PresenceUpdateListener as o, getChannelMessage as ot, RequestClient as p, unpinChannelMessage as pt, createChannelWebhook as q, MessageCreateListener as r, editChannel as rt, ReadyListener as s, listChannelArchivedThreads as st, discord_exports as t, deleteChannel as tt, Embed as u, pinChannelMessage as ut, readRetryAfter as v, createGuildScheduledEvent as vt, serializePayload as w, listGuildActiveThreads as wt, Guild as x, getGuild as xt, Command as y, createGuildSticker as yt, Section as z };