@azurioh/discord-kernel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/authz/authorizer.d.ts +45 -0
- package/dist/authz/authorizer.d.ts.map +1 -0
- package/dist/authz/authorizer.js +31 -0
- package/dist/authz/authorizer.js.map +1 -0
- package/dist/authz/require-level-guard.d.ts +23 -0
- package/dist/authz/require-level-guard.d.ts.map +1 -0
- package/dist/authz/require-level-guard.js +37 -0
- package/dist/authz/require-level-guard.js.map +1 -0
- package/dist/clock.d.ts +13 -0
- package/dist/clock.d.ts.map +1 -0
- package/dist/clock.js +13 -0
- package/dist/clock.js.map +1 -0
- package/dist/concurrency/keyed-queue.d.ts +18 -0
- package/dist/concurrency/keyed-queue.d.ts.map +1 -0
- package/dist/concurrency/keyed-queue.js +37 -0
- package/dist/concurrency/keyed-queue.js.map +1 -0
- package/dist/concurrency/run-with-concurrency.d.ts +15 -0
- package/dist/concurrency/run-with-concurrency.d.ts.map +1 -0
- package/dist/concurrency/run-with-concurrency.js +40 -0
- package/dist/concurrency/run-with-concurrency.js.map +1 -0
- package/dist/config/env.d.ts +17 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +49 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/errors.d.ts +14 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +25 -0
- package/dist/config/errors.js.map +1 -0
- package/dist/datetime.d.ts +34 -0
- package/dist/datetime.d.ts.map +1 -0
- package/dist/datetime.js +188 -0
- package/dist/datetime.js.map +1 -0
- package/dist/discord/api-errors.d.ts +20 -0
- package/dist/discord/api-errors.d.ts.map +1 -0
- package/dist/discord/api-errors.js +90 -0
- package/dist/discord/api-errors.js.map +1 -0
- package/dist/discord/channel-exporter.d.ts +42 -0
- package/dist/discord/channel-exporter.d.ts.map +1 -0
- package/dist/discord/channel-exporter.js +3 -0
- package/dist/discord/channel-exporter.js.map +1 -0
- package/dist/discord/command/autocomplete-dispatcher.d.ts +26 -0
- package/dist/discord/command/autocomplete-dispatcher.d.ts.map +1 -0
- package/dist/discord/command/autocomplete-dispatcher.js +41 -0
- package/dist/discord/command/autocomplete-dispatcher.js.map +1 -0
- package/dist/discord/command/autocomplete.d.ts +18 -0
- package/dist/discord/command/autocomplete.d.ts.map +1 -0
- package/dist/discord/command/autocomplete.js +65 -0
- package/dist/discord/command/autocomplete.js.map +1 -0
- package/dist/discord/command/context.d.ts +33 -0
- package/dist/discord/command/context.d.ts.map +1 -0
- package/dist/discord/command/context.js +48 -0
- package/dist/discord/command/context.js.map +1 -0
- package/dist/discord/command/cooldown-guard.d.ts +25 -0
- package/dist/discord/command/cooldown-guard.d.ts.map +1 -0
- package/dist/discord/command/cooldown-guard.js +60 -0
- package/dist/discord/command/cooldown-guard.js.map +1 -0
- package/dist/discord/command/create-command.d.ts +100 -0
- package/dist/discord/command/create-command.d.ts.map +1 -0
- package/dist/discord/command/create-command.js +245 -0
- package/dist/discord/command/create-command.js.map +1 -0
- package/dist/discord/command/create-context-menu-command.d.ts +51 -0
- package/dist/discord/command/create-context-menu-command.d.ts.map +1 -0
- package/dist/discord/command/create-context-menu-command.js +128 -0
- package/dist/discord/command/create-context-menu-command.js.map +1 -0
- package/dist/discord/command/errors.d.ts +19 -0
- package/dist/discord/command/errors.d.ts.map +1 -0
- package/dist/discord/command/errors.js +27 -0
- package/dist/discord/command/errors.js.map +1 -0
- package/dist/discord/command/guard.d.ts +30 -0
- package/dist/discord/command/guard.d.ts.map +1 -0
- package/dist/discord/command/guard.js +34 -0
- package/dist/discord/command/guard.js.map +1 -0
- package/dist/discord/command/localization.d.ts +9 -0
- package/dist/discord/command/localization.d.ts.map +1 -0
- package/dist/discord/command/localization.js +13 -0
- package/dist/discord/command/localization.js.map +1 -0
- package/dist/discord/command/options.d.ts +113 -0
- package/dist/discord/command/options.d.ts.map +1 -0
- package/dist/discord/command/options.js +509 -0
- package/dist/discord/command/options.js.map +1 -0
- package/dist/discord/command/permission-guard.d.ts +21 -0
- package/dist/discord/command/permission-guard.d.ts.map +1 -0
- package/dist/discord/command/permission-guard.js +69 -0
- package/dist/discord/command/permission-guard.js.map +1 -0
- package/dist/discord/command/router.d.ts +48 -0
- package/dist/discord/command/router.d.ts.map +1 -0
- package/dist/discord/command/router.js +118 -0
- package/dist/discord/command/router.js.map +1 -0
- package/dist/discord/command/types.d.ts +51 -0
- package/dist/discord/command/types.d.ts.map +1 -0
- package/dist/discord/command/types.js +3 -0
- package/dist/discord/command/types.js.map +1 -0
- package/dist/discord/components/component-router.d.ts +116 -0
- package/dist/discord/components/component-router.d.ts.map +1 -0
- package/dist/discord/components/component-router.js +123 -0
- package/dist/discord/components/component-router.js.map +1 -0
- package/dist/discord/components/interactive-message/index.d.ts +3 -0
- package/dist/discord/components/interactive-message/index.d.ts.map +1 -0
- package/dist/discord/components/interactive-message/index.js +11 -0
- package/dist/discord/components/interactive-message/index.js.map +1 -0
- package/dist/discord/components/interactive-message/interactive-message-collector.d.ts +195 -0
- package/dist/discord/components/interactive-message/interactive-message-collector.d.ts.map +1 -0
- package/dist/discord/components/interactive-message/interactive-message-collector.js +151 -0
- package/dist/discord/components/interactive-message/interactive-message-collector.js.map +1 -0
- package/dist/discord/components/interactive-message/mount-interactive-message.d.ts +30 -0
- package/dist/discord/components/interactive-message/mount-interactive-message.d.ts.map +1 -0
- package/dist/discord/components/interactive-message/mount-interactive-message.js +44 -0
- package/dist/discord/components/interactive-message/mount-interactive-message.js.map +1 -0
- package/dist/discord/components/paginator/index.d.ts +5 -0
- package/dist/discord/components/paginator/index.d.ts.map +1 -0
- package/dist/discord/components/paginator/index.js +15 -0
- package/dist/discord/components/paginator/index.js.map +1 -0
- package/dist/discord/components/paginator/mount-paginator.d.ts +25 -0
- package/dist/discord/components/paginator/mount-paginator.d.ts.map +1 -0
- package/dist/discord/components/paginator/mount-paginator.js +41 -0
- package/dist/discord/components/paginator/mount-paginator.js.map +1 -0
- package/dist/discord/components/paginator/page-state.d.ts +21 -0
- package/dist/discord/components/paginator/page-state.d.ts.map +1 -0
- package/dist/discord/components/paginator/page-state.js +44 -0
- package/dist/discord/components/paginator/page-state.js.map +1 -0
- package/dist/discord/components/paginator/paginator-buttons.d.ts +17 -0
- package/dist/discord/components/paginator/paginator-buttons.d.ts.map +1 -0
- package/dist/discord/components/paginator/paginator-buttons.js +45 -0
- package/dist/discord/components/paginator/paginator-buttons.js.map +1 -0
- package/dist/discord/components/paginator/paginator-view.d.ts +26 -0
- package/dist/discord/components/paginator/paginator-view.d.ts.map +1 -0
- package/dist/discord/components/paginator/paginator-view.js +28 -0
- package/dist/discord/components/paginator/paginator-view.js.map +1 -0
- package/dist/discord/components/persistent-paginator.d.ts +47 -0
- package/dist/discord/components/persistent-paginator.d.ts.map +1 -0
- package/dist/discord/components/persistent-paginator.js +137 -0
- package/dist/discord/components/persistent-paginator.js.map +1 -0
- package/dist/discord/components/settings-editor/index.d.ts +7 -0
- package/dist/discord/components/settings-editor/index.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/index.js +22 -0
- package/dist/discord/components/settings-editor/index.js.map +1 -0
- package/dist/discord/components/settings-editor/mount-settings-editor.d.ts +140 -0
- package/dist/discord/components/settings-editor/mount-settings-editor.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/mount-settings-editor.js +344 -0
- package/dist/discord/components/settings-editor/mount-settings-editor.js.map +1 -0
- package/dist/discord/components/settings-editor/navigation.d.ts +49 -0
- package/dist/discord/components/settings-editor/navigation.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/navigation.js +39 -0
- package/dist/discord/components/settings-editor/navigation.js.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-card.view.d.ts +56 -0
- package/dist/discord/components/settings-editor/settings-editor-card.view.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-card.view.js +284 -0
- package/dist/discord/components/settings-editor/settings-editor-card.view.js.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-field-modal.d.ts +69 -0
- package/dist/discord/components/settings-editor/settings-editor-field-modal.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-field-modal.js +353 -0
- package/dist/discord/components/settings-editor/settings-editor-field-modal.js.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-fields.d.ts +216 -0
- package/dist/discord/components/settings-editor/settings-editor-fields.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-fields.js +66 -0
- package/dist/discord/components/settings-editor/settings-editor-fields.js.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor.view.d.ts +303 -0
- package/dist/discord/components/settings-editor/settings-editor.view.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor.view.js +316 -0
- package/dist/discord/components/settings-editor/settings-editor.view.js.map +1 -0
- package/dist/discord/events/create-event.d.ts +5 -0
- package/dist/discord/events/create-event.d.ts.map +1 -0
- package/dist/discord/events/create-event.js +8 -0
- package/dist/discord/events/create-event.js.map +1 -0
- package/dist/discord/events/event-router.d.ts +16 -0
- package/dist/discord/events/event-router.d.ts.map +1 -0
- package/dist/discord/events/event-router.js +51 -0
- package/dist/discord/events/event-router.js.map +1 -0
- package/dist/discord/events/types.d.ts +16 -0
- package/dist/discord/events/types.d.ts.map +1 -0
- package/dist/discord/events/types.js +3 -0
- package/dist/discord/events/types.js.map +1 -0
- package/dist/discord/i18n.d.ts +58 -0
- package/dist/discord/i18n.d.ts.map +1 -0
- package/dist/discord/i18n.js +173 -0
- package/dist/discord/i18n.js.map +1 -0
- package/dist/discord/interaction/button.d.ts +39 -0
- package/dist/discord/interaction/button.d.ts.map +1 -0
- package/dist/discord/interaction/button.js +36 -0
- package/dist/discord/interaction/button.js.map +1 -0
- package/dist/discord/interaction/interaction-router.d.ts +21 -0
- package/dist/discord/interaction/interaction-router.d.ts.map +1 -0
- package/dist/discord/interaction/interaction-router.js +24 -0
- package/dist/discord/interaction/interaction-router.js.map +1 -0
- package/dist/discord/interaction/modal.d.ts +171 -0
- package/dist/discord/interaction/modal.d.ts.map +1 -0
- package/dist/discord/interaction/modal.js +264 -0
- package/dist/discord/interaction/modal.js.map +1 -0
- package/dist/discord/interaction/select-menu.d.ts +104 -0
- package/dist/discord/interaction/select-menu.d.ts.map +1 -0
- package/dist/discord/interaction/select-menu.js +126 -0
- package/dist/discord/interaction/select-menu.js.map +1 -0
- package/dist/discord/permissions.d.ts +32 -0
- package/dist/discord/permissions.d.ts.map +1 -0
- package/dist/discord/permissions.js +40 -0
- package/dist/discord/permissions.js.map +1 -0
- package/dist/discord/placeholder-registry-errors.d.ts +10 -0
- package/dist/discord/placeholder-registry-errors.d.ts.map +1 -0
- package/dist/discord/placeholder-registry-errors.js +18 -0
- package/dist/discord/placeholder-registry-errors.js.map +1 -0
- package/dist/discord/placeholder-registry.d.ts +53 -0
- package/dist/discord/placeholder-registry.d.ts.map +1 -0
- package/dist/discord/placeholder-registry.js +52 -0
- package/dist/discord/placeholder-registry.js.map +1 -0
- package/dist/discord/presenter.d.ts +26 -0
- package/dist/discord/presenter.d.ts.map +1 -0
- package/dist/discord/presenter.js +3 -0
- package/dist/discord/presenter.js.map +1 -0
- package/dist/discord/ui/card.d.ts +114 -0
- package/dist/discord/ui/card.d.ts.map +1 -0
- package/dist/discord/ui/card.js +162 -0
- package/dist/discord/ui/card.js.map +1 -0
- package/dist/discord/ui/color-input-errors.d.ts +12 -0
- package/dist/discord/ui/color-input-errors.d.ts.map +1 -0
- package/dist/discord/ui/color-input-errors.js +21 -0
- package/dist/discord/ui/color-input-errors.js.map +1 -0
- package/dist/discord/ui/color-input.d.ts +37 -0
- package/dist/discord/ui/color-input.d.ts.map +1 -0
- package/dist/discord/ui/color-input.js +166 -0
- package/dist/discord/ui/color-input.js.map +1 -0
- package/dist/discord/ui/colors.d.ts +44 -0
- package/dist/discord/ui/colors.d.ts.map +1 -0
- package/dist/discord/ui/colors.js +45 -0
- package/dist/discord/ui/colors.js.map +1 -0
- package/dist/discord/ui/embed.d.ts +16 -0
- package/dist/discord/ui/embed.d.ts.map +1 -0
- package/dist/discord/ui/embed.js +53 -0
- package/dist/discord/ui/embed.js.map +1 -0
- package/dist/discord/ui/message-attachments.d.ts +40 -0
- package/dist/discord/ui/message-attachments.d.ts.map +1 -0
- package/dist/discord/ui/message-attachments.js +27 -0
- package/dist/discord/ui/message-attachments.js.map +1 -0
- package/dist/errors/business-error.d.ts +41 -0
- package/dist/errors/business-error.d.ts.map +1 -0
- package/dist/errors/business-error.js +39 -0
- package/dist/errors/business-error.js.map +1 -0
- package/dist/errors/describe-error.d.ts +29 -0
- package/dist/errors/describe-error.d.ts.map +1 -0
- package/dist/errors/describe-error.js +49 -0
- package/dist/errors/describe-error.js.map +1 -0
- package/dist/errors/incident-ref.d.ts +7 -0
- package/dist/errors/incident-ref.d.ts.map +1 -0
- package/dist/errors/incident-ref.js +13 -0
- package/dist/errors/incident-ref.js.map +1 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +15 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/i18n/business-message.d.ts +14 -0
- package/dist/i18n/business-message.d.ts.map +1 -0
- package/dist/i18n/business-message.js +19 -0
- package/dist/i18n/business-message.js.map +1 -0
- package/dist/i18n/catalog.d.ts +27 -0
- package/dist/i18n/catalog.d.ts.map +1 -0
- package/dist/i18n/catalog.js +25 -0
- package/dist/i18n/catalog.js.map +1 -0
- package/dist/i18n/errors.d.ts +10 -0
- package/dist/i18n/errors.d.ts.map +1 -0
- package/dist/i18n/errors.js +18 -0
- package/dist/i18n/errors.js.map +1 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +16 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/locale.d.ts +22 -0
- package/dist/i18n/locale.d.ts.map +1 -0
- package/dist/i18n/locale.js +40 -0
- package/dist/i18n/locale.js.map +1 -0
- package/dist/i18n/translator.d.ts +35 -0
- package/dist/i18n/translator.d.ts.map +1 -0
- package/dist/i18n/translator.js +40 -0
- package/dist/i18n/translator.js.map +1 -0
- package/dist/logger.d.ts +28 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +3 -0
- package/dist/logger.js.map +1 -0
- package/dist/module/module.d.ts +42 -0
- package/dist/module/module.d.ts.map +1 -0
- package/dist/module/module.js +3 -0
- package/dist/module/module.js.map +1 -0
- package/dist/persistence/database.d.ts +24 -0
- package/dist/persistence/database.d.ts.map +1 -0
- package/dist/persistence/database.js +3 -0
- package/dist/persistence/database.js.map +1 -0
- package/dist/resilience/retry.d.ts +36 -0
- package/dist/resilience/retry.d.ts.map +1 -0
- package/dist/resilience/retry.js +78 -0
- package/dist/resilience/retry.js.map +1 -0
- package/dist/scheduler/errors.d.ts +25 -0
- package/dist/scheduler/errors.d.ts.map +1 -0
- package/dist/scheduler/errors.js +45 -0
- package/dist/scheduler/errors.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +68 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -0
- package/dist/scheduler/scheduler.js +162 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/package.json +89 -0
- package/src/authz/authorizer.ts +76 -0
- package/src/authz/require-level-guard.ts +42 -0
- package/src/clock.ts +18 -0
- package/src/concurrency/keyed-queue.ts +50 -0
- package/src/concurrency/run-with-concurrency.ts +44 -0
- package/src/config/env.ts +58 -0
- package/src/config/errors.ts +21 -0
- package/src/datetime.ts +221 -0
- package/src/discord/api-errors.ts +91 -0
- package/src/discord/channel-exporter.ts +48 -0
- package/src/discord/command/autocomplete-dispatcher.ts +54 -0
- package/src/discord/command/autocomplete.ts +76 -0
- package/src/discord/command/context.ts +85 -0
- package/src/discord/command/cooldown-guard.ts +81 -0
- package/src/discord/command/create-command.ts +431 -0
- package/src/discord/command/create-context-menu-command.ts +227 -0
- package/src/discord/command/errors.ts +22 -0
- package/src/discord/command/guard.ts +54 -0
- package/src/discord/command/localization.ts +11 -0
- package/src/discord/command/options.ts +847 -0
- package/src/discord/command/permission-guard.ts +74 -0
- package/src/discord/command/router.ts +142 -0
- package/src/discord/command/types.ts +52 -0
- package/src/discord/components/component-router.ts +213 -0
- package/src/discord/components/interactive-message/index.ts +18 -0
- package/src/discord/components/interactive-message/interactive-message-collector.ts +374 -0
- package/src/discord/components/interactive-message/mount-interactive-message.ts +71 -0
- package/src/discord/components/paginator/index.ts +17 -0
- package/src/discord/components/paginator/mount-paginator.ts +69 -0
- package/src/discord/components/paginator/page-state.ts +45 -0
- package/src/discord/components/paginator/paginator-buttons.ts +60 -0
- package/src/discord/components/paginator/paginator-view.ts +61 -0
- package/src/discord/components/persistent-paginator.ts +197 -0
- package/src/discord/components/settings-editor/index.ts +41 -0
- package/src/discord/components/settings-editor/mount-settings-editor.ts +646 -0
- package/src/discord/components/settings-editor/navigation.ts +67 -0
- package/src/discord/components/settings-editor/settings-editor-card.view.ts +344 -0
- package/src/discord/components/settings-editor/settings-editor-field-modal.ts +538 -0
- package/src/discord/components/settings-editor/settings-editor-fields.ts +290 -0
- package/src/discord/components/settings-editor/settings-editor.view.ts +654 -0
- package/src/discord/events/create-event.ts +7 -0
- package/src/discord/events/event-router.ts +53 -0
- package/src/discord/events/types.ts +17 -0
- package/src/discord/i18n.ts +173 -0
- package/src/discord/interaction/button.ts +75 -0
- package/src/discord/interaction/interaction-router.ts +28 -0
- package/src/discord/interaction/modal.ts +505 -0
- package/src/discord/interaction/select-menu.ts +246 -0
- package/src/discord/permissions.ts +57 -0
- package/src/discord/placeholder-registry-errors.ts +11 -0
- package/src/discord/placeholder-registry.ts +77 -0
- package/src/discord/presenter.ts +26 -0
- package/src/discord/ui/card.ts +303 -0
- package/src/discord/ui/color-input-errors.ts +17 -0
- package/src/discord/ui/color-input.ts +179 -0
- package/src/discord/ui/colors.ts +58 -0
- package/src/discord/ui/embed.ts +64 -0
- package/src/discord/ui/message-attachments.ts +57 -0
- package/src/errors/business-error.ts +49 -0
- package/src/errors/describe-error.ts +73 -0
- package/src/errors/incident-ref.ts +10 -0
- package/src/errors/index.ts +12 -0
- package/src/i18n/business-message.ts +23 -0
- package/src/i18n/catalog.ts +41 -0
- package/src/i18n/errors.ts +11 -0
- package/src/i18n/index.ts +11 -0
- package/src/i18n/locale.ts +41 -0
- package/src/i18n/translator.ts +78 -0
- package/src/logger.ts +28 -0
- package/src/module/module.ts +42 -0
- package/src/persistence/database.ts +23 -0
- package/src/resilience/retry.ts +102 -0
- package/src/scheduler/errors.ts +40 -0
- package/src/scheduler/scheduler.ts +248 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { type Attachment, type ChannelType, ModalBuilder, type ModalSubmitInteraction } from "discord.js";
|
|
2
|
+
export type TextFieldStyleName = "short" | "paragraph";
|
|
3
|
+
/**
|
|
4
|
+
* A single text field. `required` defaults to Discord's own default (`true`); set
|
|
5
|
+
* it to `false` to make {@link Modal.read} return `null` when left empty.
|
|
6
|
+
*/
|
|
7
|
+
export interface TextFieldDef {
|
|
8
|
+
kind?: "text";
|
|
9
|
+
label: string;
|
|
10
|
+
/** Helper text rendered under the label. */
|
|
11
|
+
description?: string;
|
|
12
|
+
style?: TextFieldStyleName;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
minLength?: number;
|
|
15
|
+
maxLength?: number;
|
|
16
|
+
placeholder?: string;
|
|
17
|
+
/** Prefilled content, e.g. when editing an existing value. */
|
|
18
|
+
value?: string;
|
|
19
|
+
}
|
|
20
|
+
/** A single checkbox field — always optional from Discord's own perspective. */
|
|
21
|
+
export interface CheckboxFieldDef {
|
|
22
|
+
kind: "checkbox";
|
|
23
|
+
label: string;
|
|
24
|
+
/** Helper text rendered under the label. */
|
|
25
|
+
description?: string;
|
|
26
|
+
/** Pre-ticked state. Defaults to unticked. */
|
|
27
|
+
default?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A single file upload. `required` defaults to Discord's own default (`true`);
|
|
31
|
+
* set it to `false` to make {@link Modal.read} return `null` when nothing was
|
|
32
|
+
* uploaded.
|
|
33
|
+
*/
|
|
34
|
+
export interface FileFieldDef {
|
|
35
|
+
kind: "file";
|
|
36
|
+
label: string;
|
|
37
|
+
/** Helper text rendered under the label. */
|
|
38
|
+
description?: string;
|
|
39
|
+
required?: boolean;
|
|
40
|
+
/** How many files may be uploaded at once. Discord's own default is one of each. */
|
|
41
|
+
minValues?: number;
|
|
42
|
+
maxValues?: number;
|
|
43
|
+
}
|
|
44
|
+
/** One choice offered by a {@link SelectFieldDef}. */
|
|
45
|
+
export interface SelectFieldOption {
|
|
46
|
+
label: string;
|
|
47
|
+
value: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
default?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A single string select menu. `required` defaults to Discord's own default
|
|
53
|
+
* (`true`); set it to `false` to make {@link Modal.read} return `null` when
|
|
54
|
+
* nothing was picked.
|
|
55
|
+
*/
|
|
56
|
+
export interface SelectFieldDef {
|
|
57
|
+
kind: "select";
|
|
58
|
+
label: string;
|
|
59
|
+
/** Helper text rendered under the label. */
|
|
60
|
+
description?: string;
|
|
61
|
+
options: readonly SelectFieldOption[];
|
|
62
|
+
placeholder?: string;
|
|
63
|
+
required?: boolean;
|
|
64
|
+
minValues?: number;
|
|
65
|
+
maxValues?: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A single role select menu. `required` defaults to Discord's own default
|
|
69
|
+
* (`true`); set it to `false` to make {@link Modal.read} return `null` when
|
|
70
|
+
* nothing was picked.
|
|
71
|
+
*/
|
|
72
|
+
export interface RoleFieldDef {
|
|
73
|
+
kind: "role";
|
|
74
|
+
label: string;
|
|
75
|
+
/** Helper text rendered under the label. */
|
|
76
|
+
description?: string;
|
|
77
|
+
defaultRoleIds?: readonly string[];
|
|
78
|
+
placeholder?: string;
|
|
79
|
+
required?: boolean;
|
|
80
|
+
minValues?: number;
|
|
81
|
+
maxValues?: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* A single user select menu. `required` defaults to Discord's own default
|
|
85
|
+
* (`true`); set it to `false` to make {@link Modal.read} return `null` when
|
|
86
|
+
* nothing was picked.
|
|
87
|
+
*/
|
|
88
|
+
export interface UserFieldDef {
|
|
89
|
+
kind: "user";
|
|
90
|
+
label: string;
|
|
91
|
+
/** Helper text rendered under the label. */
|
|
92
|
+
description?: string;
|
|
93
|
+
defaultUserIds?: readonly string[];
|
|
94
|
+
placeholder?: string;
|
|
95
|
+
required?: boolean;
|
|
96
|
+
minValues?: number;
|
|
97
|
+
maxValues?: number;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A single channel select menu. `required` defaults to Discord's own default
|
|
101
|
+
* (`true`); set it to `false` to make {@link Modal.read} return `null` when
|
|
102
|
+
* nothing was picked.
|
|
103
|
+
*/
|
|
104
|
+
export interface ChannelFieldDef {
|
|
105
|
+
kind: "channel";
|
|
106
|
+
label: string;
|
|
107
|
+
/** Helper text rendered under the label. */
|
|
108
|
+
description?: string;
|
|
109
|
+
defaultChannelIds?: readonly string[];
|
|
110
|
+
/** Restricts which channel kinds may be picked, e.g. to categories only. */
|
|
111
|
+
channelTypes?: readonly ChannelType[];
|
|
112
|
+
placeholder?: string;
|
|
113
|
+
required?: boolean;
|
|
114
|
+
minValues?: number;
|
|
115
|
+
maxValues?: number;
|
|
116
|
+
}
|
|
117
|
+
export type FieldDef = TextFieldDef | CheckboxFieldDef | FileFieldDef | SelectFieldDef | RoleFieldDef | UserFieldDef | ChannelFieldDef;
|
|
118
|
+
/** Field declarations keyed by custom id — the same key `read` returns values under. */
|
|
119
|
+
export type ModalFields = Record<string, FieldDef>;
|
|
120
|
+
/**
|
|
121
|
+
* Submitted values, keyed like the declaration. A checkbox field always resolves
|
|
122
|
+
* to a `boolean`; an optional text, file, select, role, user or channel field
|
|
123
|
+
* widens to `| null` so a caller cannot forget the empty case. A file field's
|
|
124
|
+
* uploads come back as a list because the field itself may allow several, and
|
|
125
|
+
* so do a select/role/user/channel field's picks, as the identifiers chosen.
|
|
126
|
+
* This only resolves correctly because `createModal` infers its fields as
|
|
127
|
+
* `const`.
|
|
128
|
+
*/
|
|
129
|
+
export type ModalValues<F extends ModalFields> = {
|
|
130
|
+
[K in keyof F]: F[K] extends CheckboxFieldDef ? boolean : F[K] extends FileFieldDef ? F[K]["required"] extends false ? readonly Attachment[] | null : readonly Attachment[] : F[K] extends SelectFieldDef | RoleFieldDef | UserFieldDef | ChannelFieldDef ? F[K]["required"] extends false ? readonly string[] | null : readonly string[] : F[K] extends TextFieldDef ? F[K]["required"] extends false ? string | null : string : never;
|
|
131
|
+
};
|
|
132
|
+
export interface ModalDef<F extends ModalFields> {
|
|
133
|
+
id: string;
|
|
134
|
+
title: string;
|
|
135
|
+
/**
|
|
136
|
+
* Text shown above the fields, via a Text Display component — a legend whose
|
|
137
|
+
* content is not one of the fields themselves. Counts toward the same
|
|
138
|
+
* five-component budget `fields` does: Discord's own modal object carries
|
|
139
|
+
* "between 1 and 5 (inclusive) components", label and text display alike.
|
|
140
|
+
*/
|
|
141
|
+
legend?: string;
|
|
142
|
+
fields: F;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Compiled modal: it knows how to render itself (`build`) and how to decode what
|
|
146
|
+
* came back (`read`) — the same construction/behaviour pairing as a compiled
|
|
147
|
+
* {@link import("../../discord/interaction/button").Button}. Without it a module
|
|
148
|
+
* has to hand-roll raw discord.js builders, which the template forbids everywhere
|
|
149
|
+
* else in the DSL.
|
|
150
|
+
*/
|
|
151
|
+
export interface Modal<F extends ModalFields> {
|
|
152
|
+
readonly id: string;
|
|
153
|
+
/**
|
|
154
|
+
* Build the modal to show. `state` is appended after a colon so the persistent
|
|
155
|
+
* {@link import("../../discord/components/component-router").ComponentRouter}
|
|
156
|
+
* still routes it to the handler registered under `id`.
|
|
157
|
+
*/
|
|
158
|
+
build(state?: string): ModalBuilder;
|
|
159
|
+
read(interaction: ModalSubmitInteraction): ModalValues<F>;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Declare a modal: a title, a custom id and typed fields (text, checkbox,
|
|
163
|
+
* file, select, role, user or channel).
|
|
164
|
+
*
|
|
165
|
+
* Discord caps a modal at five components, so keep `fields` — plus one more if
|
|
166
|
+
* `legend` is set — within that budget. The `const` type parameter is what
|
|
167
|
+
* preserves each field's literal `kind`/`required`, and therefore the shape of
|
|
168
|
+
* the values `read` returns.
|
|
169
|
+
*/
|
|
170
|
+
export declare function createModal<const F extends ModalFields>(def: ModalDef<F>): Modal<F>;
|
|
171
|
+
//# sourceMappingURL=modal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../../src/discord/interaction/modal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createModal = createModal;
|
|
4
|
+
const discord_js_1 = require("discord.js");
|
|
5
|
+
const TEXT_FIELD_STYLES = {
|
|
6
|
+
short: discord_js_1.TextInputStyle.Short,
|
|
7
|
+
paragraph: discord_js_1.TextInputStyle.Paragraph,
|
|
8
|
+
};
|
|
9
|
+
/** Separates a modal's static id from the dynamic state appended for routing. */
|
|
10
|
+
const CUSTOM_ID_SEPARATOR = ":";
|
|
11
|
+
function createTextInput(name, field) {
|
|
12
|
+
const input = new discord_js_1.TextInputBuilder()
|
|
13
|
+
.setCustomId(name)
|
|
14
|
+
.setStyle(TEXT_FIELD_STYLES[field.style ?? "short"])
|
|
15
|
+
.setRequired(field.required ?? true);
|
|
16
|
+
if (field.minLength !== undefined) {
|
|
17
|
+
input.setMinLength(field.minLength);
|
|
18
|
+
}
|
|
19
|
+
if (field.maxLength !== undefined) {
|
|
20
|
+
input.setMaxLength(field.maxLength);
|
|
21
|
+
}
|
|
22
|
+
if (field.placeholder !== undefined) {
|
|
23
|
+
input.setPlaceholder(field.placeholder);
|
|
24
|
+
}
|
|
25
|
+
if (field.value !== undefined) {
|
|
26
|
+
input.setValue(field.value);
|
|
27
|
+
}
|
|
28
|
+
return input;
|
|
29
|
+
}
|
|
30
|
+
function createFileUpload(name, field) {
|
|
31
|
+
const upload = new discord_js_1.FileUploadBuilder().setCustomId(name).setRequired(field.required ?? true);
|
|
32
|
+
if (field.minValues !== undefined) {
|
|
33
|
+
upload.setMinValues(field.minValues);
|
|
34
|
+
}
|
|
35
|
+
if (field.maxValues !== undefined) {
|
|
36
|
+
upload.setMaxValues(field.maxValues);
|
|
37
|
+
}
|
|
38
|
+
return upload;
|
|
39
|
+
}
|
|
40
|
+
function createSelectOption(option) {
|
|
41
|
+
const built = new discord_js_1.StringSelectMenuOptionBuilder()
|
|
42
|
+
.setLabel(option.label)
|
|
43
|
+
.setValue(option.value)
|
|
44
|
+
.setDefault(option.default ?? false);
|
|
45
|
+
if (option.description !== undefined) {
|
|
46
|
+
built.setDescription(option.description);
|
|
47
|
+
}
|
|
48
|
+
return built;
|
|
49
|
+
}
|
|
50
|
+
function createStringSelect(name, field) {
|
|
51
|
+
const select = new discord_js_1.StringSelectMenuBuilder()
|
|
52
|
+
.setCustomId(name)
|
|
53
|
+
.setRequired(field.required ?? true)
|
|
54
|
+
.addOptions(field.options.map(createSelectOption));
|
|
55
|
+
if (field.placeholder !== undefined) {
|
|
56
|
+
select.setPlaceholder(field.placeholder);
|
|
57
|
+
}
|
|
58
|
+
if (field.minValues !== undefined) {
|
|
59
|
+
select.setMinValues(field.minValues);
|
|
60
|
+
}
|
|
61
|
+
if (field.maxValues !== undefined) {
|
|
62
|
+
select.setMaxValues(field.maxValues);
|
|
63
|
+
}
|
|
64
|
+
return select;
|
|
65
|
+
}
|
|
66
|
+
function createRoleSelect(name, field) {
|
|
67
|
+
const select = new discord_js_1.RoleSelectMenuBuilder().setCustomId(name).setRequired(field.required ?? true);
|
|
68
|
+
if (field.defaultRoleIds !== undefined) {
|
|
69
|
+
select.setDefaultRoles(...field.defaultRoleIds);
|
|
70
|
+
}
|
|
71
|
+
if (field.placeholder !== undefined) {
|
|
72
|
+
select.setPlaceholder(field.placeholder);
|
|
73
|
+
}
|
|
74
|
+
if (field.minValues !== undefined) {
|
|
75
|
+
select.setMinValues(field.minValues);
|
|
76
|
+
}
|
|
77
|
+
if (field.maxValues !== undefined) {
|
|
78
|
+
select.setMaxValues(field.maxValues);
|
|
79
|
+
}
|
|
80
|
+
return select;
|
|
81
|
+
}
|
|
82
|
+
function createUserSelect(name, field) {
|
|
83
|
+
const select = new discord_js_1.UserSelectMenuBuilder().setCustomId(name).setRequired(field.required ?? true);
|
|
84
|
+
if (field.defaultUserIds !== undefined) {
|
|
85
|
+
select.setDefaultUsers(...field.defaultUserIds);
|
|
86
|
+
}
|
|
87
|
+
if (field.placeholder !== undefined) {
|
|
88
|
+
select.setPlaceholder(field.placeholder);
|
|
89
|
+
}
|
|
90
|
+
if (field.minValues !== undefined) {
|
|
91
|
+
select.setMinValues(field.minValues);
|
|
92
|
+
}
|
|
93
|
+
if (field.maxValues !== undefined) {
|
|
94
|
+
select.setMaxValues(field.maxValues);
|
|
95
|
+
}
|
|
96
|
+
return select;
|
|
97
|
+
}
|
|
98
|
+
function createChannelSelect(name, field) {
|
|
99
|
+
const select = new discord_js_1.ChannelSelectMenuBuilder()
|
|
100
|
+
.setCustomId(name)
|
|
101
|
+
.setRequired(field.required ?? true);
|
|
102
|
+
if (field.channelTypes !== undefined) {
|
|
103
|
+
select.setChannelTypes(...field.channelTypes);
|
|
104
|
+
}
|
|
105
|
+
if (field.defaultChannelIds !== undefined) {
|
|
106
|
+
select.setDefaultChannels(...field.defaultChannelIds);
|
|
107
|
+
}
|
|
108
|
+
if (field.placeholder !== undefined) {
|
|
109
|
+
select.setPlaceholder(field.placeholder);
|
|
110
|
+
}
|
|
111
|
+
if (field.minValues !== undefined) {
|
|
112
|
+
select.setMinValues(field.minValues);
|
|
113
|
+
}
|
|
114
|
+
if (field.maxValues !== undefined) {
|
|
115
|
+
select.setMaxValues(field.maxValues);
|
|
116
|
+
}
|
|
117
|
+
return select;
|
|
118
|
+
}
|
|
119
|
+
function createLabel(name, field) {
|
|
120
|
+
const label = new discord_js_1.LabelBuilder().setLabel(field.label);
|
|
121
|
+
if (field.description !== undefined) {
|
|
122
|
+
label.setDescription(field.description);
|
|
123
|
+
}
|
|
124
|
+
if (field.kind === "checkbox") {
|
|
125
|
+
return label.setCheckboxComponent(new discord_js_1.CheckboxBuilder().setCustomId(name).setDefault(field.default ?? false));
|
|
126
|
+
}
|
|
127
|
+
if (field.kind === "file") {
|
|
128
|
+
return label.setFileUploadComponent(createFileUpload(name, field));
|
|
129
|
+
}
|
|
130
|
+
if (field.kind === "select") {
|
|
131
|
+
return label.setStringSelectMenuComponent(createStringSelect(name, field));
|
|
132
|
+
}
|
|
133
|
+
if (field.kind === "role") {
|
|
134
|
+
return label.setRoleSelectMenuComponent(createRoleSelect(name, field));
|
|
135
|
+
}
|
|
136
|
+
if (field.kind === "user") {
|
|
137
|
+
return label.setUserSelectMenuComponent(createUserSelect(name, field));
|
|
138
|
+
}
|
|
139
|
+
if (field.kind === "channel") {
|
|
140
|
+
return label.setChannelSelectMenuComponent(createChannelSelect(name, field));
|
|
141
|
+
}
|
|
142
|
+
return label.setTextInputComponent(createTextInput(name, field));
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* An optional field left blank comes back as an empty string (or not at all when
|
|
146
|
+
* Discord omits it), two shapes for the same "nothing entered" outcome — collapse
|
|
147
|
+
* both to `null` so callers branch once.
|
|
148
|
+
*/
|
|
149
|
+
function readOptionalField(interaction, name) {
|
|
150
|
+
if (!interaction.fields.fields.has(name)) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const value = interaction.fields.getTextInputValue(name);
|
|
154
|
+
return value.length > 0 ? value : null;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* The same "nothing entered" collapsing for an upload: an optional file field
|
|
158
|
+
* left alone comes back absent, or present with no attachment at all.
|
|
159
|
+
*/
|
|
160
|
+
function readOptionalFiles(interaction, name) {
|
|
161
|
+
if (!interaction.fields.fields.has(name)) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
const uploaded = interaction.fields.getUploadedFiles(name);
|
|
165
|
+
if (uploaded === null || uploaded.size === 0) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
return [...uploaded.values()];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The same "nothing entered" collapsing for a string select: an optional select
|
|
172
|
+
* field left alone comes back absent, or present with no option chosen.
|
|
173
|
+
*/
|
|
174
|
+
function readOptionalSelectValues(interaction, name) {
|
|
175
|
+
if (!interaction.fields.fields.has(name)) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
const values = interaction.fields.getStringSelectValues(name);
|
|
179
|
+
return values.length > 0 ? values : null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* The same "nothing entered" collapsing for a role/user/channel select: an
|
|
183
|
+
* optional field left alone comes back absent, or present with an empty (or
|
|
184
|
+
* `null`) selection. The identifiers are returned as the keys of the
|
|
185
|
+
* `Collection` the underlying getter resolves.
|
|
186
|
+
*/
|
|
187
|
+
function readOptionalIds(interaction, name, getSelected) {
|
|
188
|
+
if (!interaction.fields.fields.has(name)) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
const selected = getSelected(interaction, name);
|
|
192
|
+
if (selected === null || selected.size === 0) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
return [...selected.keys()];
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Declare a modal: a title, a custom id and typed fields (text, checkbox,
|
|
199
|
+
* file, select, role, user or channel).
|
|
200
|
+
*
|
|
201
|
+
* Discord caps a modal at five components, so keep `fields` — plus one more if
|
|
202
|
+
* `legend` is set — within that budget. The `const` type parameter is what
|
|
203
|
+
* preserves each field's literal `kind`/`required`, and therefore the shape of
|
|
204
|
+
* the values `read` returns.
|
|
205
|
+
*/
|
|
206
|
+
function createModal(def) {
|
|
207
|
+
const entries = Object.entries(def.fields);
|
|
208
|
+
return {
|
|
209
|
+
id: def.id,
|
|
210
|
+
build(state) {
|
|
211
|
+
const customId = state === undefined ? def.id : `${def.id}${CUSTOM_ID_SEPARATOR}${state}`;
|
|
212
|
+
const modal = new discord_js_1.ModalBuilder().setCustomId(customId).setTitle(def.title);
|
|
213
|
+
if (def.legend !== undefined) {
|
|
214
|
+
modal.addTextDisplayComponents((textDisplay) => textDisplay.setContent(def.legend));
|
|
215
|
+
}
|
|
216
|
+
return modal.addLabelComponents(...entries.map(([name, field]) => createLabel(name, field)));
|
|
217
|
+
},
|
|
218
|
+
read(interaction) {
|
|
219
|
+
const values = {};
|
|
220
|
+
for (const [name, field] of entries) {
|
|
221
|
+
if (field.kind === "checkbox") {
|
|
222
|
+
values[name] = interaction.fields.getCheckbox(name);
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const isRequired = field.required ?? true;
|
|
226
|
+
if (field.kind === "file") {
|
|
227
|
+
values[name] = isRequired
|
|
228
|
+
? [...interaction.fields.getUploadedFiles(name, true).values()]
|
|
229
|
+
: readOptionalFiles(interaction, name);
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (field.kind === "select") {
|
|
233
|
+
values[name] = isRequired
|
|
234
|
+
? interaction.fields.getStringSelectValues(name)
|
|
235
|
+
: readOptionalSelectValues(interaction, name);
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
if (field.kind === "role") {
|
|
239
|
+
values[name] = isRequired
|
|
240
|
+
? [...interaction.fields.getSelectedRoles(name, true).keys()]
|
|
241
|
+
: readOptionalIds(interaction, name, (i, n) => i.fields.getSelectedRoles(n, false));
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (field.kind === "user") {
|
|
245
|
+
values[name] = isRequired
|
|
246
|
+
? [...interaction.fields.getSelectedUsers(name, true).keys()]
|
|
247
|
+
: readOptionalIds(interaction, name, (i, n) => i.fields.getSelectedUsers(n, false));
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (field.kind === "channel") {
|
|
251
|
+
values[name] = isRequired
|
|
252
|
+
? [...interaction.fields.getSelectedChannels(name, true).keys()]
|
|
253
|
+
: readOptionalIds(interaction, name, (i, n) => i.fields.getSelectedChannels(n, false));
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
values[name] = isRequired
|
|
257
|
+
? interaction.fields.getTextInputValue(name)
|
|
258
|
+
: readOptionalField(interaction, name);
|
|
259
|
+
}
|
|
260
|
+
return values;
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modal.js","sourceRoot":"","sources":["../../../src/discord/interaction/modal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ActionRowBuilder, type AnySelectMenuInteraction, ChannelSelectMenuBuilder, type ChannelSelectMenuInteraction, type ChannelType, RoleSelectMenuBuilder, type RoleSelectMenuInteraction, StringSelectMenuBuilder, type StringSelectMenuInteraction, UserSelectMenuBuilder, type UserSelectMenuInteraction } from "discord.js";
|
|
2
|
+
import type { ComponentAuthorization, ComponentHandler } from "../../discord/components/component-router";
|
|
3
|
+
/** The builders this DSL can produce; the union an action row accepts. */
|
|
4
|
+
export type AnySelectMenuBuilder = StringSelectMenuBuilder | ChannelSelectMenuBuilder | RoleSelectMenuBuilder | UserSelectMenuBuilder;
|
|
5
|
+
/**
|
|
6
|
+
* Context handed to `onSelect`, mirroring
|
|
7
|
+
* {@link import("../../discord/interaction/button").ComponentContext}: the
|
|
8
|
+
* triggering interaction plus the picked values, already unwrapped so a handler
|
|
9
|
+
* does not have to know where discord.js keeps them.
|
|
10
|
+
*/
|
|
11
|
+
export interface SelectContext<I extends AnySelectMenuInteraction> {
|
|
12
|
+
readonly interaction: I;
|
|
13
|
+
readonly values: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Presentation options shared by every select flavour. Split from the handler so
|
|
17
|
+
* the shared `applyBaseOptions` never sees `onSelect`: a callback is
|
|
18
|
+
* contravariant in its interaction type, so a common supertype for the
|
|
19
|
+
* *definitions* cannot exist.
|
|
20
|
+
*/
|
|
21
|
+
export interface SelectLayout {
|
|
22
|
+
id: string;
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
minValues?: number;
|
|
25
|
+
maxValues?: number;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/** A select declaration: its layout plus the behaviour it carries. */
|
|
29
|
+
export interface BaseSelectDef<I extends AnySelectMenuInteraction> extends SelectLayout {
|
|
30
|
+
onSelect?: (ctx: SelectContext<I>) => Promise<void> | void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Compiled select menu: renders itself (`apply`) and owns its behaviour
|
|
34
|
+
* (`onSelect`), exactly like a compiled
|
|
35
|
+
* {@link import("../../discord/interaction/button").Button}. It lives in the
|
|
36
|
+
* interaction layer for the same reason — it carries behaviour, it is not a
|
|
37
|
+
* passive widget.
|
|
38
|
+
*/
|
|
39
|
+
export interface SelectMenu<B, I extends AnySelectMenuInteraction> {
|
|
40
|
+
readonly id: string;
|
|
41
|
+
readonly onSelect?: (ctx: SelectContext<I>) => Promise<void> | void;
|
|
42
|
+
apply(forceDisabled?: boolean): B;
|
|
43
|
+
}
|
|
44
|
+
export interface StringSelectOption {
|
|
45
|
+
label: string;
|
|
46
|
+
value: string;
|
|
47
|
+
description?: string;
|
|
48
|
+
emoji?: string;
|
|
49
|
+
default?: boolean;
|
|
50
|
+
}
|
|
51
|
+
export interface StringSelectDef extends BaseSelectDef<StringSelectMenuInteraction> {
|
|
52
|
+
options: readonly StringSelectOption[];
|
|
53
|
+
}
|
|
54
|
+
export interface ChannelSelectDef extends BaseSelectDef<ChannelSelectMenuInteraction> {
|
|
55
|
+
/** Restricts what the picker offers, e.g. text channels only. */
|
|
56
|
+
channelTypes?: readonly ChannelType[];
|
|
57
|
+
/**
|
|
58
|
+
* What the picker opens already holding.
|
|
59
|
+
*
|
|
60
|
+
* A picker returns its whole selection, never a delta, so one that opens
|
|
61
|
+
* empty over a setting that already has a value turns "change this" into
|
|
62
|
+
* "type the list again" — and anything the administrator forgets to re-pick
|
|
63
|
+
* is silently dropped.
|
|
64
|
+
*/
|
|
65
|
+
defaultChannelIds?: readonly string[];
|
|
66
|
+
}
|
|
67
|
+
export interface RoleSelectDef extends BaseSelectDef<RoleSelectMenuInteraction> {
|
|
68
|
+
/** What the picker opens already holding. See {@link ChannelSelectDef.defaultChannelIds}. */
|
|
69
|
+
defaultRoleIds?: readonly string[];
|
|
70
|
+
}
|
|
71
|
+
export interface UserSelectDef extends BaseSelectDef<UserSelectMenuInteraction> {
|
|
72
|
+
/** What the picker opens already holding. See {@link ChannelSelectDef.defaultChannelIds}. */
|
|
73
|
+
defaultUserIds?: readonly string[];
|
|
74
|
+
}
|
|
75
|
+
/** A menu of caller-defined string values. */
|
|
76
|
+
export declare function createStringSelect(def: StringSelectDef): SelectMenu<StringSelectMenuBuilder, StringSelectMenuInteraction>;
|
|
77
|
+
/** A menu populated by Discord with the guild's channels. */
|
|
78
|
+
export declare function createChannelSelect(def: ChannelSelectDef): SelectMenu<ChannelSelectMenuBuilder, ChannelSelectMenuInteraction>;
|
|
79
|
+
/** A menu populated by Discord with the guild's roles. */
|
|
80
|
+
export declare function createRoleSelect(def: RoleSelectDef): SelectMenu<RoleSelectMenuBuilder, RoleSelectMenuInteraction>;
|
|
81
|
+
/**
|
|
82
|
+
* A menu populated by Discord with the guild's members.
|
|
83
|
+
*
|
|
84
|
+
* A distinct flavour from the mentionable one on purpose: naming a person is not
|
|
85
|
+
* the same act as naming a role, and the calls behind it — adding someone to the
|
|
86
|
+
* recap's ping list, granting a user a level — take a user id, not either.
|
|
87
|
+
*/
|
|
88
|
+
export declare function createUserSelect(def: UserSelectDef): SelectMenu<UserSelectMenuBuilder, UserSelectMenuInteraction>;
|
|
89
|
+
/**
|
|
90
|
+
* Wrap a select menu in its own action row. Unlike buttons, Discord gives a
|
|
91
|
+
* select menu a whole row, so there is nothing to group — hence a distinct
|
|
92
|
+
* helper from `createActionRow`.
|
|
93
|
+
*/
|
|
94
|
+
export declare function createSelectRow<B extends AnySelectMenuBuilder, I extends AnySelectMenuInteraction>(menu: SelectMenu<B, I>, forceDisabled?: boolean): ActionRowBuilder<B>;
|
|
95
|
+
/**
|
|
96
|
+
* Bridge a select menu's `onSelect` to the persistent
|
|
97
|
+
* {@link import("../../discord/components/component-router").ComponentRouter}.
|
|
98
|
+
*
|
|
99
|
+
* Without this a declared `onSelect` would never run: the router dispatches to a
|
|
100
|
+
* `ComponentHandler`, and nothing else turns an interaction back into the menu
|
|
101
|
+
* that produced it. Register the result through a module's `components`.
|
|
102
|
+
*/
|
|
103
|
+
export declare function createSelectHandler<B extends AnySelectMenuBuilder, I extends AnySelectMenuInteraction>(menu: SelectMenu<B, I>, authorize: ComponentAuthorization): ComponentHandler;
|
|
104
|
+
//# sourceMappingURL=select-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-menu.d.ts","sourceRoot":"","sources":["../../../src/discord/interaction/select-menu.ts"],"names":[],"mappings":"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"}
|