@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.
- package/dist/access-B9ujuUtS.js +89 -0
- package/dist/account-inspect-C2UEUhbG.js +81 -0
- package/dist/account-inspect-api.js +10 -0
- package/dist/accounts-BKnkNaoA.js +128 -0
- package/dist/action-runtime-api.js +2 -0
- package/dist/agent-components.runtime-DUhLr9hy.js +4 -0
- package/dist/allow-list-ek-1hMKN.js +336 -0
- package/dist/api-DzNBVTto.js +130 -0
- package/dist/api.js +24 -0
- package/dist/approval-handler.runtime-v8nzQHlT.js +426 -0
- package/dist/approval-native-DqWGp0bM.js +153 -0
- package/dist/approval-shared-DKnwwjZM.js +93 -0
- package/dist/audit-CJ92YD6J.js +102 -0
- package/dist/channel-B3aTtBj1.js +745 -0
- package/dist/channel-access-ewDxhd9q.js +62 -0
- package/dist/channel-actions-TNih7k3w.js +140 -0
- package/dist/channel-actions.runtime-CaPytiY4.js +236 -0
- package/dist/channel-api-CTSWMrnD.js +21 -0
- package/dist/channel-config-api.js +2 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.setup-Dt4tIDrl.js +336 -0
- package/dist/components-BapWDmDM.js +760 -0
- package/dist/config-api-CFZtoMaS.js +2 -0
- package/dist/config-schema-DwFkL904.js +252 -0
- package/dist/configured-state.js +6 -0
- package/dist/contract-api.js +8 -0
- package/dist/conversation-identity-BN9wSmxJ.js +31 -0
- package/dist/directory-cache-D93eSrpB.js +62 -0
- package/dist/directory-config-LyMP0sdv.js +49 -0
- package/dist/directory-contract-api.js +2 -0
- package/dist/directory-live-BQapdpkZ.js +101 -0
- package/dist/discord-D1kDh0X_.js +2751 -0
- package/dist/doctor-B2G7WqO0.js +244 -0
- package/dist/doctor-contract-D3pSutkb.js +383 -0
- package/dist/doctor-contract-api.js +2 -0
- package/dist/doctor-shared-DU8RcnF5.js +4 -0
- package/dist/format-D8TsaXxW.js +24 -0
- package/dist/gateway-registry-BKG4KIVC.js +74 -0
- package/dist/handle-action.guild-admin-BuqsSVXu.js +283 -0
- package/dist/inbound-context-e_oBBJtF.js +51 -0
- package/dist/index.js +26 -0
- package/dist/manager.runtime-M2aAa7qA.js +1019 -0
- package/dist/mentions-BPZUaFk7.js +88 -0
- package/dist/message-handler-D6JfFV3P.js +381 -0
- package/dist/message-handler.preflight-DqaF3vHm.js +1022 -0
- package/dist/message-handler.process-tl3Nwnhr.js +1124 -0
- package/dist/message-utils-Dmgu-7fC.js +512 -0
- package/dist/normalize-B-ktw-T_.js +275 -0
- package/dist/outbound-adapter-DJf9_sfH.js +451 -0
- package/dist/outbound-session-route-uHGLDP-Y.js +43 -0
- package/dist/pluralkit-voQvSN3g.js +22 -0
- package/dist/preflight-audio-BpYtUAT6.js +72 -0
- package/dist/preflight-audio.runtime-BAGmU6uO.js +7 -0
- package/dist/preview-streaming-C0O92Qqz.js +14 -0
- package/dist/probe-DcNEodPI.js +139 -0
- package/dist/probe.runtime-P-e4r1Hl.js +2 -0
- package/dist/provider-CMvXOp-3.js +8440 -0
- package/dist/provider-session.runtime-JFemrDZT.js +6 -0
- package/dist/provider.runtime-BO007oR2.js +2 -0
- package/dist/reply-delivery-D9So77a6.js +131 -0
- package/dist/resolve-allowlist-common-DqqFY_qa.js +34 -0
- package/dist/resolve-channels-CGPntufJ.js +265 -0
- package/dist/resolve-users-CDvSlW0V.js +120 -0
- package/dist/rolldown-runtime-C3SqQTfK.js +28 -0
- package/dist/route-resolution-BYiC-6Cc.js +236 -0
- package/dist/runtime-K9RT6Egn.js +8 -0
- package/dist/runtime-api.actions.js +3 -0
- package/dist/runtime-api.js +31 -0
- package/dist/runtime-api.lookup.js +7 -0
- package/dist/runtime-api.monitor-BC-XN0tY.js +6 -0
- package/dist/runtime-api.monitor.js +9 -0
- package/dist/runtime-api.send.js +6 -0
- package/dist/runtime-api.threads.js +6 -0
- package/dist/runtime-n5xZHW55.js +1001 -0
- package/dist/runtime-setter-api.js +2 -0
- package/dist/secret-config-contract-CoGryS5c.js +115 -0
- package/dist/secret-contract-api.js +2 -0
- package/dist/security-audit-Cdz2iq3m.js +120 -0
- package/dist/security-audit-contract-api.js +2 -0
- package/dist/security-audit.runtime-DBV1T1_N.js +2 -0
- package/dist/security-contract-api.js +2 -0
- package/dist/security-contract-ei3Mz8Sa.js +26 -0
- package/dist/security-doctor-CzTzpXV8.js +18 -0
- package/dist/send-B_frVn_Q.js +845 -0
- package/dist/send.components-B1EgHAds.js +468 -0
- package/dist/send.outbound-DlBAuW7y.js +211 -0
- package/dist/send.shared-Db0opnak.js +708 -0
- package/dist/sender-identity-BiSDAk2P.js +43 -0
- package/dist/session-contract-goJZckp2.js +6 -0
- package/dist/session-key-api.js +2 -0
- package/dist/session-key-normalization-Daag9II6.js +23 -0
- package/dist/setup-entry.js +11 -0
- package/dist/setup-plugin-api.js +2 -0
- package/dist/shared-CqlrJmSs.js +166 -0
- package/dist/shared-interactive-KgJjCqnB.js +79 -0
- package/dist/subagent-hooks-api.js +22 -0
- package/dist/subagent-hooks-mEK5ARfP.js +113 -0
- package/dist/system-events-Bu9jmO4W.js +34 -0
- package/dist/targets-kKlbZ4ai.js +3 -0
- package/dist/test-api.js +45 -0
- package/dist/thread-binding-api.js +4 -0
- package/dist/thread-bindings-Bj1R-6QH.js +256 -0
- package/dist/thread-bindings.discord-api-ClPMuIr8.js +184 -0
- package/dist/thread-bindings.manager-BaN0l4y8.js +535 -0
- package/dist/thread-bindings.session-updates-TTP020qQ.js +54 -0
- package/dist/thread-bindings.state-Dzu1gCE7.js +318 -0
- package/dist/threading-CWhdYHVx.js +475 -0
- package/dist/timeouts-C7jeTtGs.js +52 -0
- package/dist/timeouts.js +2 -0
- package/dist/token-D-w3Rigl.js +42 -0
- package/dist/typing-CJiowRTZ.js +15 -0
- package/package.json +14 -6
- package/account-inspect-api.ts +0 -6
- package/action-runtime-api.ts +0 -1
- package/api.ts +0 -132
- package/channel-config-api.ts +0 -1
- package/channel-plugin-api.ts +0 -3
- package/config-api.ts +0 -4
- package/configured-state.ts +0 -6
- package/contract-api.ts +0 -21
- package/directory-contract-api.ts +0 -4
- package/doctor-contract-api.ts +0 -1
- package/index.test.ts +0 -13
- package/index.ts +0 -24
- package/runtime-api.actions.ts +0 -15
- package/runtime-api.lookup.ts +0 -22
- package/runtime-api.monitor.ts +0 -50
- package/runtime-api.send.ts +0 -79
- package/runtime-api.threads.ts +0 -30
- package/runtime-api.ts +0 -180
- package/runtime-setter-api.ts +0 -3
- package/secret-contract-api.ts +0 -4
- package/security-audit-contract-api.ts +0 -1
- package/security-contract-api.ts +0 -4
- package/session-key-api.ts +0 -1
- package/setup-entry.ts +0 -9
- package/setup-plugin-api.ts +0 -3
- package/src/account-inspect.test.ts +0 -126
- package/src/account-inspect.ts +0 -132
- package/src/accounts.test.ts +0 -247
- package/src/accounts.ts +0 -196
- package/src/actions/handle-action.guild-admin.ts +0 -411
- package/src/actions/handle-action.test.ts +0 -306
- package/src/actions/handle-action.ts +0 -372
- package/src/actions/runtime.guild.ts +0 -446
- package/src/actions/runtime.messaging.messages.ts +0 -205
- package/src/actions/runtime.messaging.reactions.ts +0 -67
- package/src/actions/runtime.messaging.runtime.ts +0 -69
- package/src/actions/runtime.messaging.send.ts +0 -248
- package/src/actions/runtime.messaging.shared.ts +0 -97
- package/src/actions/runtime.messaging.ts +0 -37
- package/src/actions/runtime.moderation-shared.ts +0 -48
- package/src/actions/runtime.moderation.authz.test.ts +0 -151
- package/src/actions/runtime.moderation.ts +0 -116
- package/src/actions/runtime.presence.test.ts +0 -160
- package/src/actions/runtime.presence.ts +0 -117
- package/src/actions/runtime.shared.ts +0 -83
- package/src/actions/runtime.test.ts +0 -1087
- package/src/actions/runtime.ts +0 -87
- package/src/api-barrel.test.ts +0 -80
- package/src/api.test.ts +0 -130
- package/src/api.ts +0 -169
- package/src/approval-handler.runtime.test.ts +0 -41
- package/src/approval-handler.runtime.ts +0 -632
- package/src/approval-native.test.ts +0 -330
- package/src/approval-native.ts +0 -219
- package/src/approval-runtime.ts +0 -14
- package/src/approval-shared.ts +0 -53
- package/src/audit-core.ts +0 -141
- package/src/audit.test.ts +0 -145
- package/src/audit.ts +0 -32
- package/src/channel-actions.contract.test.ts +0 -45
- package/src/channel-actions.runtime.ts +0 -1
- package/src/channel-actions.test.ts +0 -275
- package/src/channel-actions.ts +0 -203
- package/src/channel-api.ts +0 -29
- package/src/channel.conversation.ts +0 -159
- package/src/channel.loaders.ts +0 -47
- package/src/channel.runtime.ts +0 -1
- package/src/channel.setup.ts +0 -12
- package/src/channel.test.ts +0 -571
- package/src/channel.ts +0 -629
- package/src/chunk.test.ts +0 -157
- package/src/chunk.ts +0 -321
- package/src/client.proxy.test.ts +0 -176
- package/src/client.test.ts +0 -76
- package/src/client.ts +0 -132
- package/src/component-custom-id.ts +0 -72
- package/src/components-registry.ts +0 -356
- package/src/components.builders.ts +0 -409
- package/src/components.modal.ts +0 -124
- package/src/components.parse.ts +0 -407
- package/src/components.test.ts +0 -312
- package/src/components.ts +0 -54
- package/src/components.types.ts +0 -187
- package/src/config-schema.test.ts +0 -325
- package/src/config-schema.ts +0 -6
- package/src/config-ui-hints.ts +0 -249
- package/src/conversation-identity.ts +0 -58
- package/src/delivery-retry.ts +0 -56
- package/src/directory-cache.ts +0 -116
- package/src/directory-config.ts +0 -58
- package/src/directory-contract.test.ts +0 -129
- package/src/directory-live.test.ts +0 -126
- package/src/directory-live.ts +0 -135
- package/src/doctor-contract.ts +0 -477
- package/src/doctor-shared.ts +0 -5
- package/src/doctor.test.ts +0 -405
- package/src/doctor.ts +0 -340
- package/src/draft-chunking.test.ts +0 -64
- package/src/draft-chunking.ts +0 -43
- package/src/draft-stream.test.ts +0 -159
- package/src/draft-stream.ts +0 -154
- package/src/error-body.ts +0 -38
- package/src/exec-approvals.test.ts +0 -88
- package/src/exec-approvals.ts +0 -110
- package/src/gateway-logging.test.ts +0 -98
- package/src/gateway-logging.ts +0 -67
- package/src/group-policy.ts +0 -113
- package/src/guilds.ts +0 -29
- package/src/inbound-context.contract.test.ts +0 -11
- package/src/interactive-dispatch.ts +0 -104
- package/src/internal/api.commands.ts +0 -51
- package/src/internal/api.guild.ts +0 -164
- package/src/internal/api.interactions.ts +0 -53
- package/src/internal/api.messages.ts +0 -113
- package/src/internal/api.reactions.ts +0 -38
- package/src/internal/api.test.ts +0 -262
- package/src/internal/api.ts +0 -61
- package/src/internal/api.users.ts +0 -19
- package/src/internal/api.webhooks.ts +0 -13
- package/src/internal/client.test.ts +0 -440
- package/src/internal/client.ts +0 -310
- package/src/internal/command-deploy.ts +0 -297
- package/src/internal/commands.ts +0 -188
- package/src/internal/components.base.ts +0 -65
- package/src/internal/components.message.ts +0 -279
- package/src/internal/components.modal.ts +0 -95
- package/src/internal/components.ts +0 -31
- package/src/internal/discord.ts +0 -11
- package/src/internal/embeds.ts +0 -35
- package/src/internal/entity-cache.ts +0 -98
- package/src/internal/event-queue.ts +0 -162
- package/src/internal/gateway-close-codes.ts +0 -25
- package/src/internal/gateway-dispatch.ts +0 -96
- package/src/internal/gateway-identify-limiter.ts +0 -26
- package/src/internal/gateway-lifecycle.ts +0 -61
- package/src/internal/gateway-rate-limit.ts +0 -104
- package/src/internal/gateway.test.ts +0 -603
- package/src/internal/gateway.ts +0 -476
- package/src/internal/interaction-dispatch.test.ts +0 -148
- package/src/internal/interaction-dispatch.ts +0 -162
- package/src/internal/interaction-options.ts +0 -98
- package/src/internal/interaction-response.ts +0 -53
- package/src/internal/interactions.test.ts +0 -325
- package/src/internal/interactions.ts +0 -378
- package/src/internal/listeners.ts +0 -85
- package/src/internal/live-smoke.live.test.ts +0 -26
- package/src/internal/modal-fields.ts +0 -95
- package/src/internal/payload.ts +0 -69
- package/src/internal/rest-body.ts +0 -115
- package/src/internal/rest-errors.ts +0 -88
- package/src/internal/rest-routes.ts +0 -50
- package/src/internal/rest-scheduler.ts +0 -557
- package/src/internal/rest.test.ts +0 -673
- package/src/internal/rest.ts +0 -322
- package/src/internal/schemas.ts +0 -36
- package/src/internal/structures.test.ts +0 -43
- package/src/internal/structures.ts +0 -280
- package/src/internal/test-builders.test-support.ts +0 -167
- package/src/internal/voice.ts +0 -49
- package/src/media-detection.ts +0 -28
- package/src/mentions.test.ts +0 -111
- package/src/mentions.ts +0 -147
- package/src/monitor/access-groups.ts +0 -55
- package/src/monitor/ack-reactions.ts +0 -70
- package/src/monitor/acp-bind-here.integration.test.ts +0 -211
- package/src/monitor/agent-components-auth.ts +0 -7
- package/src/monitor/agent-components-context.ts +0 -154
- package/src/monitor/agent-components-data.ts +0 -224
- package/src/monitor/agent-components-dm-auth.ts +0 -221
- package/src/monitor/agent-components-guild-auth.ts +0 -322
- package/src/monitor/agent-components-helpers.runtime.ts +0 -5
- package/src/monitor/agent-components-helpers.ts +0 -34
- package/src/monitor/agent-components-reply.ts +0 -10
- package/src/monitor/agent-components.deps.runtime.ts +0 -2
- package/src/monitor/agent-components.dispatch.ts +0 -366
- package/src/monitor/agent-components.handlers.ts +0 -303
- package/src/monitor/agent-components.modal.ts +0 -160
- package/src/monitor/agent-components.plugin-interactive.ts +0 -187
- package/src/monitor/agent-components.runtime.ts +0 -14
- package/src/monitor/agent-components.system-controls.ts +0 -211
- package/src/monitor/agent-components.ts +0 -70
- package/src/monitor/agent-components.types.ts +0 -58
- package/src/monitor/agent-components.wildcard-controls.ts +0 -168
- package/src/monitor/agent-components.wildcard.test.ts +0 -71
- package/src/monitor/allow-list.test.ts +0 -14
- package/src/monitor/allow-list.ts +0 -633
- package/src/monitor/auto-presence.test.ts +0 -156
- package/src/monitor/auto-presence.ts +0 -356
- package/src/monitor/channel-access.test.ts +0 -99
- package/src/monitor/channel-access.ts +0 -102
- package/src/monitor/commands.test.ts +0 -24
- package/src/monitor/commands.ts +0 -9
- package/src/monitor/dm-command-auth.test.ts +0 -197
- package/src/monitor/dm-command-auth.ts +0 -158
- package/src/monitor/dm-command-decision.test.ts +0 -113
- package/src/monitor/dm-command-decision.ts +0 -49
- package/src/monitor/exec-approvals.test.ts +0 -226
- package/src/monitor/exec-approvals.ts +0 -158
- package/src/monitor/format.ts +0 -45
- package/src/monitor/gateway-handle.ts +0 -34
- package/src/monitor/gateway-metadata.test.ts +0 -29
- package/src/monitor/gateway-metadata.ts +0 -298
- package/src/monitor/gateway-plugin.test.ts +0 -297
- package/src/monitor/gateway-plugin.ts +0 -294
- package/src/monitor/gateway-registry.ts +0 -37
- package/src/monitor/gateway-supervisor.test.ts +0 -150
- package/src/monitor/gateway-supervisor.ts +0 -206
- package/src/monitor/inbound-context.test-helpers.ts +0 -37
- package/src/monitor/inbound-context.test.ts +0 -106
- package/src/monitor/inbound-context.ts +0 -103
- package/src/monitor/inbound-dedupe.ts +0 -79
- package/src/monitor/inbound-job.test.ts +0 -203
- package/src/monitor/inbound-job.ts +0 -118
- package/src/monitor/listeners.queue.ts +0 -91
- package/src/monitor/listeners.reactions.ts +0 -610
- package/src/monitor/listeners.test.ts +0 -200
- package/src/monitor/listeners.ts +0 -150
- package/src/monitor/message-channel-info.ts +0 -96
- package/src/monitor/message-forwarded.ts +0 -107
- package/src/monitor/message-handler.batch-gate.test.ts +0 -22
- package/src/monitor/message-handler.batch-gate.ts +0 -19
- package/src/monitor/message-handler.bot-self-filter.test.ts +0 -68
- package/src/monitor/message-handler.context.ts +0 -406
- package/src/monitor/message-handler.dm-preflight.ts +0 -123
- package/src/monitor/message-handler.draft-preview.ts +0 -246
- package/src/monitor/message-handler.hydration.test.ts +0 -80
- package/src/monitor/message-handler.hydration.ts +0 -198
- package/src/monitor/message-handler.inbound-context.test.ts +0 -59
- package/src/monitor/message-handler.module-test-helpers.ts +0 -31
- package/src/monitor/message-handler.preflight-channel-access.ts +0 -86
- package/src/monitor/message-handler.preflight-channel-context.test.ts +0 -18
- package/src/monitor/message-handler.preflight-channel-context.ts +0 -58
- package/src/monitor/message-handler.preflight-context.ts +0 -54
- package/src/monitor/message-handler.preflight-helpers.ts +0 -164
- package/src/monitor/message-handler.preflight-history.ts +0 -23
- package/src/monitor/message-handler.preflight-logging.ts +0 -36
- package/src/monitor/message-handler.preflight-pluralkit.ts +0 -26
- package/src/monitor/message-handler.preflight-runtime.ts +0 -28
- package/src/monitor/message-handler.preflight-thread.ts +0 -49
- package/src/monitor/message-handler.preflight.acp-bindings.test.ts +0 -369
- package/src/monitor/message-handler.preflight.test-helpers.ts +0 -111
- package/src/monitor/message-handler.preflight.test.ts +0 -1623
- package/src/monitor/message-handler.preflight.ts +0 -679
- package/src/monitor/message-handler.preflight.types.ts +0 -110
- package/src/monitor/message-handler.process.test.ts +0 -1369
- package/src/monitor/message-handler.process.ts +0 -686
- package/src/monitor/message-handler.queue.test.ts +0 -496
- package/src/monitor/message-handler.routing-preflight.ts +0 -112
- package/src/monitor/message-handler.test-harness.ts +0 -99
- package/src/monitor/message-handler.test-helpers.ts +0 -75
- package/src/monitor/message-handler.ts +0 -274
- package/src/monitor/message-media.ts +0 -509
- package/src/monitor/message-run-queue.ts +0 -101
- package/src/monitor/message-text.ts +0 -171
- package/src/monitor/message-utils.test.ts +0 -1157
- package/src/monitor/message-utils.ts +0 -32
- package/src/monitor/model-picker-preferences.test.ts +0 -67
- package/src/monitor/model-picker-preferences.ts +0 -184
- package/src/monitor/model-picker.state.ts +0 -364
- package/src/monitor/model-picker.test-utils.ts +0 -26
- package/src/monitor/model-picker.test.ts +0 -794
- package/src/monitor/model-picker.ts +0 -38
- package/src/monitor/model-picker.view.ts +0 -695
- package/src/monitor/monitor.agent-components.test.ts +0 -375
- package/src/monitor/monitor.test.ts +0 -849
- package/src/monitor/monitor.threading-utils.test.ts +0 -598
- package/src/monitor/native-command-agent-reply.ts +0 -125
- package/src/monitor/native-command-arg-ui.ts +0 -233
- package/src/monitor/native-command-auth.ts +0 -308
- package/src/monitor/native-command-bypass.ts +0 -13
- package/src/monitor/native-command-context.test.ts +0 -98
- package/src/monitor/native-command-context.ts +0 -103
- package/src/monitor/native-command-dispatch.ts +0 -35
- package/src/monitor/native-command-model-picker-apply.ts +0 -177
- package/src/monitor/native-command-model-picker-interaction.ts +0 -461
- package/src/monitor/native-command-model-picker-ui.ts +0 -368
- package/src/monitor/native-command-reply.test.ts +0 -68
- package/src/monitor/native-command-reply.ts +0 -185
- package/src/monitor/native-command-route.ts +0 -91
- package/src/monitor/native-command-status.ts +0 -76
- package/src/monitor/native-command-ui.ts +0 -26
- package/src/monitor/native-command-ui.types.ts +0 -20
- package/src/monitor/native-command.args.ts +0 -45
- package/src/monitor/native-command.command-arg.test.ts +0 -99
- package/src/monitor/native-command.commands-allowfrom.test.ts +0 -490
- package/src/monitor/native-command.model-picker.test.ts +0 -767
- package/src/monitor/native-command.options.test.ts +0 -369
- package/src/monitor/native-command.options.ts +0 -153
- package/src/monitor/native-command.plugin-dispatch.test.ts +0 -961
- package/src/monitor/native-command.runtime.ts +0 -50
- package/src/monitor/native-command.status-direct.test.ts +0 -272
- package/src/monitor/native-command.test-helpers.ts +0 -64
- package/src/monitor/native-command.think-autocomplete.test.ts +0 -416
- package/src/monitor/native-command.ts +0 -700
- package/src/monitor/native-command.types.ts +0 -9
- package/src/monitor/native-interaction-channel-context.ts +0 -50
- package/src/monitor/preflight-audio.runtime.ts +0 -9
- package/src/monitor/preflight-audio.test.ts +0 -157
- package/src/monitor/preflight-audio.ts +0 -130
- package/src/monitor/presence-cache.ts +0 -61
- package/src/monitor/presence.test.ts +0 -44
- package/src/monitor/presence.ts +0 -50
- package/src/monitor/provider-session.runtime.ts +0 -12
- package/src/monitor/provider.acp.ts +0 -89
- package/src/monitor/provider.allowlist.test.ts +0 -149
- package/src/monitor/provider.allowlist.ts +0 -394
- package/src/monitor/provider.cleanup.ts +0 -41
- package/src/monitor/provider.commands.ts +0 -129
- package/src/monitor/provider.config-log.ts +0 -45
- package/src/monitor/provider.deploy-errors.ts +0 -362
- package/src/monitor/provider.deploy.ts +0 -221
- package/src/monitor/provider.interactions.ts +0 -160
- package/src/monitor/provider.lifecycle.test.ts +0 -713
- package/src/monitor/provider.lifecycle.ts +0 -552
- package/src/monitor/provider.proxy.test.ts +0 -745
- package/src/monitor/provider.rest-proxy.test.ts +0 -121
- package/src/monitor/provider.runtime.ts +0 -1
- package/src/monitor/provider.skill-dedupe.test.ts +0 -42
- package/src/monitor/provider.startup-log.ts +0 -32
- package/src/monitor/provider.startup.test.ts +0 -426
- package/src/monitor/provider.startup.ts +0 -330
- package/src/monitor/provider.test.ts +0 -1111
- package/src/monitor/provider.ts +0 -713
- package/src/monitor/reply-context.ts +0 -64
- package/src/monitor/reply-delivery.test.ts +0 -244
- package/src/monitor/reply-delivery.ts +0 -203
- package/src/monitor/rest-fetch.ts +0 -43
- package/src/monitor/route-resolution.test.ts +0 -204
- package/src/monitor/route-resolution.ts +0 -140
- package/src/monitor/sender-identity.ts +0 -81
- package/src/monitor/startup-status.test.ts +0 -30
- package/src/monitor/startup-status.ts +0 -10
- package/src/monitor/status.ts +0 -22
- package/src/monitor/system-events.ts +0 -55
- package/src/monitor/thread-bindings.config.ts +0 -35
- package/src/monitor/thread-bindings.discord-api.test.ts +0 -229
- package/src/monitor/thread-bindings.discord-api.ts +0 -310
- package/src/monitor/thread-bindings.lifecycle.test.ts +0 -1871
- package/src/monitor/thread-bindings.lifecycle.ts +0 -354
- package/src/monitor/thread-bindings.manager.ts +0 -553
- package/src/monitor/thread-bindings.messages.ts +0 -6
- package/src/monitor/thread-bindings.persona.test.ts +0 -34
- package/src/monitor/thread-bindings.persona.ts +0 -25
- package/src/monitor/thread-bindings.session-adapter.ts +0 -229
- package/src/monitor/thread-bindings.session-shared.ts +0 -59
- package/src/monitor/thread-bindings.session-updates.ts +0 -35
- package/src/monitor/thread-bindings.shared-state.test.ts +0 -36
- package/src/monitor/thread-bindings.state.ts +0 -540
- package/src/monitor/thread-bindings.ts +0 -48
- package/src/monitor/thread-bindings.types.ts +0 -83
- package/src/monitor/thread-channel-context.ts +0 -112
- package/src/monitor/thread-session-close.test.ts +0 -180
- package/src/monitor/thread-session-close.ts +0 -63
- package/src/monitor/thread-title.generate.test.ts +0 -197
- package/src/monitor/thread-title.test.ts +0 -31
- package/src/monitor/thread-title.ts +0 -181
- package/src/monitor/threading.auto-thread.test.ts +0 -327
- package/src/monitor/threading.auto-thread.ts +0 -287
- package/src/monitor/threading.cache.ts +0 -45
- package/src/monitor/threading.parent-info.test.ts +0 -156
- package/src/monitor/threading.starter.test.ts +0 -260
- package/src/monitor/threading.starter.ts +0 -287
- package/src/monitor/threading.ts +0 -20
- package/src/monitor/threading.types.ts +0 -102
- package/src/monitor/timeouts.ts +0 -84
- package/src/monitor/typing.test.ts +0 -42
- package/src/monitor/typing.ts +0 -17
- package/src/monitor.gateway.test.ts +0 -187
- package/src/monitor.gateway.ts +0 -75
- package/src/monitor.test.ts +0 -1397
- package/src/monitor.ts +0 -28
- package/src/normalize.test.ts +0 -56
- package/src/normalize.ts +0 -86
- package/src/outbound-adapter.interactive-order.test.ts +0 -64
- package/src/outbound-adapter.test-harness.ts +0 -207
- package/src/outbound-adapter.test.ts +0 -696
- package/src/outbound-adapter.ts +0 -291
- package/src/outbound-approval.ts +0 -29
- package/src/outbound-components.ts +0 -81
- package/src/outbound-payload.contract.test.ts +0 -38
- package/src/outbound-payload.ts +0 -134
- package/src/outbound-send-context.ts +0 -92
- package/src/outbound-session-route.test.ts +0 -34
- package/src/outbound-session-route.ts +0 -72
- package/src/pluralkit.test.ts +0 -67
- package/src/pluralkit.ts +0 -58
- package/src/preview-streaming.ts +0 -32
- package/src/probe.intents.test.ts +0 -94
- package/src/probe.parse-token.test.ts +0 -43
- package/src/probe.runtime.ts +0 -1
- package/src/probe.ts +0 -237
- package/src/proxy-fetch.ts +0 -92
- package/src/proxy-request-client.test.ts +0 -78
- package/src/proxy-request-client.ts +0 -21
- package/src/recipient-resolution.ts +0 -39
- package/src/resolve-allowlist-common.test.ts +0 -36
- package/src/resolve-allowlist-common.ts +0 -39
- package/src/resolve-channels.test.ts +0 -340
- package/src/resolve-channels.ts +0 -369
- package/src/resolve-users.test.ts +0 -222
- package/src/resolve-users.ts +0 -184
- package/src/retry.test.ts +0 -83
- package/src/retry.ts +0 -98
- package/src/runtime-api.ts +0 -64
- package/src/runtime.ts +0 -23
- package/src/secret-config-contract.ts +0 -140
- package/src/security-audit.runtime.ts +0 -1
- package/src/security-audit.test.ts +0 -246
- package/src/security-audit.ts +0 -208
- package/src/security-contract.ts +0 -47
- package/src/security-doctor.test.ts +0 -25
- package/src/security-doctor.ts +0 -20
- package/src/security.ts +0 -60
- package/src/send-target-parsing.ts +0 -14
- package/src/send.channels.ts +0 -139
- package/src/send.components.test.ts +0 -275
- package/src/send.components.ts +0 -381
- package/src/send.creates-thread.test.ts +0 -643
- package/src/send.emojis-stickers.ts +0 -57
- package/src/send.guild.ts +0 -170
- package/src/send.message-request.ts +0 -97
- package/src/send.messages.test.ts +0 -53
- package/src/send.messages.ts +0 -225
- package/src/send.outbound.ts +0 -413
- package/src/send.permissions.authz.test.ts +0 -188
- package/src/send.permissions.ts +0 -283
- package/src/send.reactions.ts +0 -155
- package/src/send.sends-basic-channel-messages.test.ts +0 -941
- package/src/send.shared.ts +0 -447
- package/src/send.test-harness.ts +0 -56
- package/src/send.ts +0 -82
- package/src/send.types.ts +0 -188
- package/src/send.typing.test.ts +0 -41
- package/src/send.typing.ts +0 -9
- package/src/send.voice.ts +0 -134
- package/src/send.webhook-activity.test.ts +0 -105
- package/src/send.webhook.proxy.test.ts +0 -191
- package/src/send.webhook.ts +0 -133
- package/src/session-contract.ts +0 -3
- package/src/session-key-normalization.test.ts +0 -44
- package/src/session-key-normalization.ts +0 -47
- package/src/setup-account-state.test.ts +0 -91
- package/src/setup-account-state.ts +0 -144
- package/src/setup-adapter.ts +0 -12
- package/src/setup-core.ts +0 -212
- package/src/setup-runtime-helpers.ts +0 -10
- package/src/setup-surface.test.ts +0 -137
- package/src/setup-surface.ts +0 -129
- package/src/shared-interactive.test.ts +0 -153
- package/src/shared-interactive.ts +0 -124
- package/src/shared.test.ts +0 -165
- package/src/shared.ts +0 -190
- package/src/status-issues.test.ts +0 -70
- package/src/status-issues.ts +0 -169
- package/src/subagent-hooks.test.ts +0 -432
- package/src/subagent-hooks.ts +0 -214
- package/src/target-parsing.ts +0 -53
- package/src/target-resolver.ts +0 -129
- package/src/targets.test.ts +0 -367
- package/src/targets.ts +0 -12
- package/src/test-http-helpers.ts +0 -10
- package/src/test-support/component-runtime.ts +0 -190
- package/src/test-support/config.ts +0 -7
- package/src/test-support/configured-binding-runtime.ts +0 -29
- package/src/test-support/partial-channel.ts +0 -26
- package/src/test-support/provider.test-support.ts +0 -545
- package/src/token.test.ts +0 -107
- package/src/token.ts +0 -60
- package/src/ui-colors.ts +0 -27
- package/src/ui.ts +0 -20
- package/src/voice/access.test.ts +0 -217
- package/src/voice/access.ts +0 -124
- package/src/voice/audio.ts +0 -173
- package/src/voice/capture-state.test.ts +0 -48
- package/src/voice/capture-state.ts +0 -120
- package/src/voice/command.test.ts +0 -164
- package/src/voice/command.ts +0 -283
- package/src/voice/config.ts +0 -8
- package/src/voice/manager.e2e.test.ts +0 -928
- package/src/voice/manager.ready-listener.test.ts +0 -37
- package/src/voice/manager.runtime.ts +0 -11
- package/src/voice/manager.ts +0 -691
- package/src/voice/prompt.test.ts +0 -16
- package/src/voice/prompt.ts +0 -17
- package/src/voice/receive-recovery.test.ts +0 -79
- package/src/voice/receive-recovery.ts +0 -159
- package/src/voice/sanitize.test.ts +0 -34
- package/src/voice/sanitize.ts +0 -32
- package/src/voice/sdk-runtime.ts +0 -14
- package/src/voice/segment.ts +0 -156
- package/src/voice/session.ts +0 -50
- package/src/voice/speaker-context.ts +0 -127
- package/src/voice/tts.ts +0 -125
- package/src/voice-message.test.ts +0 -234
- package/src/voice-message.ts +0 -444
- package/subagent-hooks-api.ts +0 -27
- package/test-api.ts +0 -4
- package/thread-binding-api.ts +0 -1
- package/timeouts.ts +0 -6
- 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 };
|