mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-16 03:23:29 +01:00
feat(modals): modals, input text components and modal submits, v13 style (#7431)
This commit is contained in:
31
package-lock.json
generated
31
package-lock.json
generated
@@ -14,7 +14,7 @@
|
|||||||
"@sapphire/async-queue": "^1.1.9",
|
"@sapphire/async-queue": "^1.1.9",
|
||||||
"@types/node-fetch": "^2.5.12",
|
"@types/node-fetch": "^2.5.12",
|
||||||
"@types/ws": "^8.2.2",
|
"@types/ws": "^8.2.2",
|
||||||
"discord-api-types": "^0.26.0",
|
"discord-api-types": "^0.27.1",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"ws": "^8.4.0"
|
"ws": "^8.4.0"
|
||||||
@@ -1009,6 +1009,15 @@
|
|||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@discordjs/builders/node_modules/discord-api-types": {
|
||||||
|
"version": "0.26.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.26.1.tgz",
|
||||||
|
"integrity": "sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ==",
|
||||||
|
"deprecated": "No longer supported. Install the latest release!",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@discordjs/builders/node_modules/tslib": {
|
"node_modules/@discordjs/builders/node_modules/tslib": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||||
@@ -4291,12 +4300,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/discord-api-types": {
|
"node_modules/discord-api-types": {
|
||||||
"version": "0.26.0",
|
"version": "0.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.26.0.tgz",
|
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.27.1.tgz",
|
||||||
"integrity": "sha512-bnUltSHpQLzTVZTMjm+iNgVhAbtm5oAKHrhtiPaZoxprbm1UtuCZCsG0yXM61NamWfeSz7xnLvgFc50YzVJ5cQ==",
|
"integrity": "sha512-NhOrRs3TDx/p/e7+VCzcvtVz/Wkqa/olS82HJb2aM/oI0CLcnB+lJMXWa8wjn57XviFBcMMR0poqUMXx0IqTkQ=="
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/dmd": {
|
"node_modules/dmd": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.6",
|
||||||
@@ -13474,6 +13480,11 @@
|
|||||||
"zod": "^3.11.6"
|
"zod": "^3.11.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"discord-api-types": {
|
||||||
|
"version": "0.26.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.26.1.tgz",
|
||||||
|
"integrity": "sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ=="
|
||||||
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||||
@@ -16053,9 +16064,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"discord-api-types": {
|
"discord-api-types": {
|
||||||
"version": "0.26.0",
|
"version": "0.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.26.0.tgz",
|
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.27.1.tgz",
|
||||||
"integrity": "sha512-bnUltSHpQLzTVZTMjm+iNgVhAbtm5oAKHrhtiPaZoxprbm1UtuCZCsG0yXM61NamWfeSz7xnLvgFc50YzVJ5cQ=="
|
"integrity": "sha512-NhOrRs3TDx/p/e7+VCzcvtVz/Wkqa/olS82HJb2aM/oI0CLcnB+lJMXWa8wjn57XviFBcMMR0poqUMXx0IqTkQ=="
|
||||||
},
|
},
|
||||||
"dmd": {
|
"dmd": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.6",
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
"@sapphire/async-queue": "^1.1.9",
|
"@sapphire/async-queue": "^1.1.9",
|
||||||
"@types/node-fetch": "^2.5.12",
|
"@types/node-fetch": "^2.5.12",
|
||||||
"@types/ws": "^8.2.2",
|
"@types/ws": "^8.2.2",
|
||||||
"discord-api-types": "^0.26.0",
|
"discord-api-types": "^0.27.1",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"ws": "^8.4.0"
|
"ws": "^8.4.0"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const AutocompleteInteraction = require('../../structures/AutocompleteInteractio
|
|||||||
const ButtonInteraction = require('../../structures/ButtonInteraction');
|
const ButtonInteraction = require('../../structures/ButtonInteraction');
|
||||||
const CommandInteraction = require('../../structures/CommandInteraction');
|
const CommandInteraction = require('../../structures/CommandInteraction');
|
||||||
const MessageContextMenuInteraction = require('../../structures/MessageContextMenuInteraction');
|
const MessageContextMenuInteraction = require('../../structures/MessageContextMenuInteraction');
|
||||||
|
const ModalSubmitInteraction = require('../../structures/ModalSubmitInteraction');
|
||||||
const SelectMenuInteraction = require('../../structures/SelectMenuInteraction');
|
const SelectMenuInteraction = require('../../structures/SelectMenuInteraction');
|
||||||
const UserContextMenuInteraction = require('../../structures/UserContextMenuInteraction');
|
const UserContextMenuInteraction = require('../../structures/UserContextMenuInteraction');
|
||||||
const { Events, InteractionTypes, MessageComponentTypes, ApplicationCommandTypes } = require('../../util/Constants');
|
const { Events, InteractionTypes, MessageComponentTypes, ApplicationCommandTypes } = require('../../util/Constants');
|
||||||
@@ -59,6 +60,9 @@ class InteractionCreateAction extends Action {
|
|||||||
case InteractionTypes.APPLICATION_COMMAND_AUTOCOMPLETE:
|
case InteractionTypes.APPLICATION_COMMAND_AUTOCOMPLETE:
|
||||||
InteractionType = AutocompleteInteraction;
|
InteractionType = AutocompleteInteraction;
|
||||||
break;
|
break;
|
||||||
|
case InteractionTypes.MODAL_SUBMIT:
|
||||||
|
InteractionType = ModalSubmitInteraction;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
client.emit(Events.DEBUG, `[INTERACTION] Received interaction with unknown type: ${data.type}`);
|
client.emit(Events.DEBUG, `[INTERACTION] Received interaction with unknown type: ${data.type}`);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -58,6 +58,14 @@ const Messages = {
|
|||||||
SELECT_OPTION_VALUE: 'MessageSelectOption value must be a string',
|
SELECT_OPTION_VALUE: 'MessageSelectOption value must be a string',
|
||||||
SELECT_OPTION_DESCRIPTION: 'MessageSelectOption description must be a string',
|
SELECT_OPTION_DESCRIPTION: 'MessageSelectOption description must be a string',
|
||||||
|
|
||||||
|
TEXT_INPUT_CUSTOM_ID: 'TextInputComponent customId must be a string',
|
||||||
|
TEXT_INPUT_LABEL: 'TextInputComponent label must be a string',
|
||||||
|
TEXT_INPUT_PLACEHOLDER: 'TextInputComponent placeholder must be a string',
|
||||||
|
TEXT_INPUT_VALUE: 'TextInputComponent value must be a string',
|
||||||
|
|
||||||
|
MODAL_CUSTOM_ID: 'Modal customId must be a string',
|
||||||
|
MODAL_TITLE: 'Modal title must be a string',
|
||||||
|
|
||||||
INTERACTION_COLLECTOR_ERROR: reason => `Collector received no interactions before ending with reason: ${reason}`,
|
INTERACTION_COLLECTOR_ERROR: reason => `Collector received no interactions before ending with reason: ${reason}`,
|
||||||
|
|
||||||
FILE_NOT_FOUND: file => `File could not be found: ${file}`,
|
FILE_NOT_FOUND: file => `File could not be found: ${file}`,
|
||||||
@@ -148,6 +156,10 @@ const Messages = {
|
|||||||
COMMAND_INTERACTION_OPTION_NO_SUB_COMMAND_GROUP: 'No subcommand group specified for interaction.',
|
COMMAND_INTERACTION_OPTION_NO_SUB_COMMAND_GROUP: 'No subcommand group specified for interaction.',
|
||||||
AUTOCOMPLETE_INTERACTION_OPTION_NO_FOCUSED_OPTION: 'No focused option for autocomplete interaction.',
|
AUTOCOMPLETE_INTERACTION_OPTION_NO_FOCUSED_OPTION: 'No focused option for autocomplete interaction.',
|
||||||
|
|
||||||
|
MODAL_SUBMIT_INTERACTION_FIELD_NOT_FOUND: customId => `Required field with custom id "${customId}" not found.`,
|
||||||
|
MODAL_SUBMIT_INTERACTION_FIELD_TYPE: (customId, type, expected) =>
|
||||||
|
`Field with custom id "${customId}" is of type: ${type}; expected ${expected}.`,
|
||||||
|
|
||||||
INVITE_MISSING_SCOPES: 'At least one valid scope must be provided for the invite',
|
INVITE_MISSING_SCOPES: 'At least one valid scope must be provided for the invite',
|
||||||
|
|
||||||
NOT_IMPLEMENTED: (what, name) => `Method ${what} not implemented on ${name}.`,
|
NOT_IMPLEMENTED: (what, name) => `Method ${what} not implemented on ${name}.`,
|
||||||
|
|||||||
@@ -122,6 +122,8 @@ exports.MessageMentions = require('./structures/MessageMentions');
|
|||||||
exports.MessagePayload = require('./structures/MessagePayload');
|
exports.MessagePayload = require('./structures/MessagePayload');
|
||||||
exports.MessageReaction = require('./structures/MessageReaction');
|
exports.MessageReaction = require('./structures/MessageReaction');
|
||||||
exports.MessageSelectMenu = require('./structures/MessageSelectMenu');
|
exports.MessageSelectMenu = require('./structures/MessageSelectMenu');
|
||||||
|
exports.Modal = require('./structures/Modal');
|
||||||
|
exports.ModalSubmitInteraction = require('./structures/ModalSubmitInteraction');
|
||||||
exports.NewsChannel = require('./structures/NewsChannel');
|
exports.NewsChannel = require('./structures/NewsChannel');
|
||||||
exports.OAuth2Guild = require('./structures/OAuth2Guild');
|
exports.OAuth2Guild = require('./structures/OAuth2Guild');
|
||||||
exports.PartialGroupDMChannel = require('./structures/PartialGroupDMChannel');
|
exports.PartialGroupDMChannel = require('./structures/PartialGroupDMChannel');
|
||||||
@@ -140,6 +142,7 @@ exports.StoreChannel = require('./structures/StoreChannel');
|
|||||||
exports.Team = require('./structures/Team');
|
exports.Team = require('./structures/Team');
|
||||||
exports.TeamMember = require('./structures/TeamMember');
|
exports.TeamMember = require('./structures/TeamMember');
|
||||||
exports.TextChannel = require('./structures/TextChannel');
|
exports.TextChannel = require('./structures/TextChannel');
|
||||||
|
exports.TextInputComponent = require('./structures/TextInputComponent');
|
||||||
exports.ThreadChannel = require('./structures/ThreadChannel');
|
exports.ThreadChannel = require('./structures/ThreadChannel');
|
||||||
exports.ThreadMember = require('./structures/ThreadMember');
|
exports.ThreadMember = require('./structures/ThreadMember');
|
||||||
exports.Typing = require('./structures/Typing');
|
exports.Typing = require('./structures/Typing');
|
||||||
|
|||||||
@@ -196,6 +196,8 @@ class BaseCommandInteraction extends Interaction {
|
|||||||
editReply() {}
|
editReply() {}
|
||||||
deleteReply() {}
|
deleteReply() {}
|
||||||
followUp() {}
|
followUp() {}
|
||||||
|
showModal() {}
|
||||||
|
awaitModalSubmit() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
InteractionResponses.applyToClass(BaseCommandInteraction, ['deferUpdate', 'update']);
|
InteractionResponses.applyToClass(BaseCommandInteraction, ['deferUpdate', 'update']);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const { TypeError } = require('../errors');
|
|||||||
const { MessageComponentTypes, Events } = require('../util/Constants');
|
const { MessageComponentTypes, Events } = require('../util/Constants');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an interactive component of a Message. It should not be necessary to construct this directly.
|
* Represents an interactive component of a Message or Modal. It should not be necessary to construct this directly.
|
||||||
* See {@link MessageComponent}
|
* See {@link MessageComponent}
|
||||||
*/
|
*/
|
||||||
class BaseMessageComponent {
|
class BaseMessageComponent {
|
||||||
@@ -15,18 +15,20 @@ class BaseMessageComponent {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data that can be resolved into options for a MessageComponent. This can be:
|
* Data that can be resolved into options for a component. This can be:
|
||||||
* * MessageActionRowOptions
|
* * MessageActionRowOptions
|
||||||
* * MessageButtonOptions
|
* * MessageButtonOptions
|
||||||
* * MessageSelectMenuOptions
|
* * MessageSelectMenuOptions
|
||||||
|
* * TextInputComponentOptions
|
||||||
* @typedef {MessageActionRowOptions|MessageButtonOptions|MessageSelectMenuOptions} MessageComponentOptions
|
* @typedef {MessageActionRowOptions|MessageButtonOptions|MessageSelectMenuOptions} MessageComponentOptions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Components that can be sent in a message. These can be:
|
* Components that can be sent in a payload. These can be:
|
||||||
* * MessageActionRow
|
* * MessageActionRow
|
||||||
* * MessageButton
|
* * MessageButton
|
||||||
* * MessageSelectMenu
|
* * MessageSelectMenu
|
||||||
|
* * TextInputComponent
|
||||||
* @typedef {MessageActionRow|MessageButton|MessageSelectMenu} MessageComponent
|
* @typedef {MessageActionRow|MessageButton|MessageSelectMenu} MessageComponent
|
||||||
* @see {@link https://discord.com/developers/docs/interactions/message-components#component-object-component-types}
|
* @see {@link https://discord.com/developers/docs/interactions/message-components#component-object-component-types}
|
||||||
*/
|
*/
|
||||||
@@ -51,10 +53,10 @@ class BaseMessageComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a MessageComponent based on the type of the incoming data
|
* Constructs a component based on the type of the incoming data
|
||||||
* @param {MessageComponentOptions} data Data for a MessageComponent
|
* @param {MessageComponentOptions} data Data for a MessageComponent
|
||||||
* @param {Client|WebhookClient} [client] Client constructing this component
|
* @param {Client|WebhookClient} [client] Client constructing this component
|
||||||
* @returns {?MessageComponent}
|
* @returns {?(MessageComponent|ModalComponent)}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
static create(data, client) {
|
static create(data, client) {
|
||||||
@@ -79,6 +81,11 @@ class BaseMessageComponent {
|
|||||||
component = data instanceof MessageSelectMenu ? data : new MessageSelectMenu(data);
|
component = data instanceof MessageSelectMenu ? data : new MessageSelectMenu(data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MessageComponentTypes.TEXT_INPUT: {
|
||||||
|
const TextInputComponent = require('./TextInputComponent');
|
||||||
|
component = data instanceof TextInputComponent ? data : new TextInputComponent(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if (client) {
|
if (client) {
|
||||||
client.emit(Events.DEBUG, `[BaseMessageComponent] Received component with unknown type: ${data.type}`);
|
client.emit(Events.DEBUG, `[BaseMessageComponent] Received component with unknown type: ${data.type}`);
|
||||||
@@ -90,7 +97,7 @@ class BaseMessageComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the type of a MessageComponent
|
* Resolves the type of a component
|
||||||
* @param {MessageComponentTypeResolvable} type The type to resolve
|
* @param {MessageComponentTypeResolvable} type The type to resolve
|
||||||
* @returns {MessageComponentType}
|
* @returns {MessageComponentType}
|
||||||
* @private
|
* @private
|
||||||
|
|||||||
@@ -173,6 +173,14 @@ class Interaction extends Base {
|
|||||||
return InteractionTypes[this.type] === InteractionTypes.APPLICATION_COMMAND && typeof this.targetId !== 'undefined';
|
return InteractionTypes[this.type] === InteractionTypes.APPLICATION_COMMAND && typeof this.targetId !== 'undefined';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this interaction is a {@link ModalSubmitInteraction}
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isModalSubmit() {
|
||||||
|
return InteractionTypes[this.type] === InteractionTypes.MODAL_SUBMIT;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether this interaction is a {@link UserContextMenuInteraction}
|
* Indicates whether this interaction is a {@link UserContextMenuInteraction}
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
|
|||||||
@@ -12,14 +12,16 @@ class MessageActionRow extends BaseMessageComponent {
|
|||||||
* Components that can be placed in an action row
|
* Components that can be placed in an action row
|
||||||
* * MessageButton
|
* * MessageButton
|
||||||
* * MessageSelectMenu
|
* * MessageSelectMenu
|
||||||
* @typedef {MessageButton|MessageSelectMenu} MessageActionRowComponent
|
* * TextInputComponent
|
||||||
|
* @typedef {MessageButton|MessageSelectMenu|TextInputComponent} MessageActionRowComponent
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options for components that can be placed in an action row
|
* Options for components that can be placed in an action row
|
||||||
* * MessageButtonOptions
|
* * MessageButtonOptions
|
||||||
* * MessageSelectMenuOptions
|
* * MessageSelectMenuOptions
|
||||||
* @typedef {MessageButtonOptions|MessageSelectMenuOptions} MessageActionRowComponentOptions
|
* * TextInputComponentOptions
|
||||||
|
* @typedef {MessageButtonOptions|MessageSelectMenuOptions|TextInputComponentOptions} MessageActionRowComponentOptions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ class MessageComponentInteraction extends Interaction {
|
|||||||
followUp() {}
|
followUp() {}
|
||||||
deferUpdate() {}
|
deferUpdate() {}
|
||||||
update() {}
|
update() {}
|
||||||
|
showModal() {}
|
||||||
|
awaitModalSubmit() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
InteractionResponses.applyToClass(MessageComponentInteraction);
|
InteractionResponses.applyToClass(MessageComponentInteraction);
|
||||||
|
|||||||
103
src/structures/Modal.js
Normal file
103
src/structures/Modal.js
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BaseMessageComponent = require('./BaseMessageComponent');
|
||||||
|
const Util = require('../util/Util');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a modal (form) to be shown in response to an interaction
|
||||||
|
*/
|
||||||
|
class Modal {
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ModalOptions
|
||||||
|
* @property {string} [customId] A unique string to be sent in the interaction when clicked
|
||||||
|
* @property {string} [title] The title to be displayed on this modal
|
||||||
|
* @property {MessageActionRow[]|MessageActionRowOptions[]} [components]
|
||||||
|
* Action rows containing interactive components for the modal (text input components)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Modal|ModalOptions} data Modal to clone or raw data
|
||||||
|
* @param {Client} client The client constructing this Modal, if provided
|
||||||
|
*/
|
||||||
|
constructor(data = {}, client = null) {
|
||||||
|
/**
|
||||||
|
* A list of MessageActionRows in the modal
|
||||||
|
* @type {MessageActionRow[]}
|
||||||
|
*/
|
||||||
|
this.components = data.components?.map(c => BaseMessageComponent.create(c, client)) ?? [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A unique string to be sent in the interaction when submitted
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.customId = data.custom_id ?? data.customId ?? null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The title to be displayed on this modal
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.title = data.title ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds components to the modal.
|
||||||
|
* @param {...MessageActionRowResolvable[]} components The components to add
|
||||||
|
* @returns {Modal}
|
||||||
|
*/
|
||||||
|
addComponents(...components) {
|
||||||
|
this.components.push(...components.flat(Infinity).map(c => BaseMessageComponent.create(c)));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the components of the modal.
|
||||||
|
* @param {...MessageActionRowResolvable[]} components The components to set
|
||||||
|
* @returns {Modal}
|
||||||
|
*/
|
||||||
|
setComponents(...components) {
|
||||||
|
this.spliceComponents(0, this.components.length, components);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the custom id for this modal
|
||||||
|
* @param {string} customId A unique string to be sent in the interaction when submitted
|
||||||
|
* @returns {Modal}
|
||||||
|
*/
|
||||||
|
setCustomId(customId) {
|
||||||
|
this.customId = Util.verifyString(customId, RangeError, 'MODAL_CUSTOM_ID');
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes, replaces, and inserts components in the modal.
|
||||||
|
* @param {number} index The index to start at
|
||||||
|
* @param {number} deleteCount The number of components to remove
|
||||||
|
* @param {...MessageActionRowResolvable[]} [components] The replacing components
|
||||||
|
* @returns {Modal}
|
||||||
|
*/
|
||||||
|
spliceComponents(index, deleteCount, ...components) {
|
||||||
|
this.components.splice(index, deleteCount, ...components.flat(Infinity).map(c => BaseMessageComponent.create(c)));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the title of this modal
|
||||||
|
* @param {string} title The title to be displayed on this modal
|
||||||
|
* @returns {Modal}
|
||||||
|
*/
|
||||||
|
setTitle(title) {
|
||||||
|
this.title = Util.verifyString(title, RangeError, 'MODAL_TITLE');
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON() {
|
||||||
|
return {
|
||||||
|
components: this.components.map(c => c.toJSON()),
|
||||||
|
custom_id: this.customId,
|
||||||
|
title: this.title,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Modal;
|
||||||
53
src/structures/ModalSubmitFieldsResolver.js
Normal file
53
src/structures/ModalSubmitFieldsResolver.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { TypeError } = require('../errors');
|
||||||
|
const { MessageComponentTypes } = require('../util/Constants');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A resolver for modal submit interaction text inputs.
|
||||||
|
*/
|
||||||
|
class ModalSubmitFieldsResolver {
|
||||||
|
constructor(components) {
|
||||||
|
/**
|
||||||
|
* The components within the modal
|
||||||
|
* @type {PartialModalActionRow[]} The components in the modal
|
||||||
|
*/
|
||||||
|
this.components = components;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The extracted fields from the modal
|
||||||
|
* @type {PartialInputTextData[]} The fields in the modal
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
get _fields() {
|
||||||
|
return this.components.reduce((previous, next) => previous.concat(next.components), []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a field given a custom id from a component
|
||||||
|
* @param {string} customId The custom id of the component
|
||||||
|
* @returns {?PartialInputTextData}
|
||||||
|
*/
|
||||||
|
getField(customId) {
|
||||||
|
const field = this._fields.find(f => f.customId === customId);
|
||||||
|
if (!field) throw new TypeError('MODAL_SUBMIT_INTERACTION_FIELD_NOT_FOUND', customId);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of a text input component given a custom id
|
||||||
|
* @param {string} customId The custom id of the text input component
|
||||||
|
* @returns {?string}
|
||||||
|
*/
|
||||||
|
getTextInputValue(customId) {
|
||||||
|
const field = this.getField(customId);
|
||||||
|
const expectedType = MessageComponentTypes[MessageComponentTypes.TEXT_INPUT];
|
||||||
|
if (field.type !== expectedType) {
|
||||||
|
throw new TypeError('MODAL_SUBMIT_INTERACTION_FIELD_TYPE', customId, field.type, expectedType);
|
||||||
|
}
|
||||||
|
return field.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ModalSubmitFieldsResolver;
|
||||||
111
src/structures/ModalSubmitInteraction.js
Normal file
111
src/structures/ModalSubmitInteraction.js
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Interaction = require('./Interaction');
|
||||||
|
const InteractionWebhook = require('./InteractionWebhook');
|
||||||
|
const ModalSubmitFieldsResolver = require('./ModalSubmitFieldsResolver');
|
||||||
|
const InteractionResponses = require('./interfaces/InteractionResponses');
|
||||||
|
const { MessageComponentTypes } = require('../util/Constants');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a modal submit interaction.
|
||||||
|
* @extends {Interaction}
|
||||||
|
* @implements {InteractionResponses}
|
||||||
|
*/
|
||||||
|
class ModalSubmitInteraction extends Interaction {
|
||||||
|
constructor(client, data) {
|
||||||
|
super(client, data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The custom id of the modal.
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this.customId = data.data.custom_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} PartialTextInputData
|
||||||
|
* @property {string} [customId] A unique string to be sent in the interaction when submitted
|
||||||
|
* @property {MessageComponentType} [type] The type of this component
|
||||||
|
* @property {string} [value] Value of this text input component
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} PartialModalActionRow
|
||||||
|
* @property {MessageComponentType} [type] The type of this component
|
||||||
|
* @property {PartialTextInputData[]} [components] Partial text input components
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The inputs within the modal
|
||||||
|
* @type {PartialModalActionRow[]}
|
||||||
|
*/
|
||||||
|
this.components =
|
||||||
|
data.data.components?.map(c => ({
|
||||||
|
type: MessageComponentTypes[c.type],
|
||||||
|
components: ModalSubmitInteraction.transformComponent(c),
|
||||||
|
})) ?? [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message associated with this interaction
|
||||||
|
* @type {Message|APIMessage|null}
|
||||||
|
*/
|
||||||
|
this.message = data.message ? this.channel?.messages._add(data.message) ?? data.message : null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fields within the modal
|
||||||
|
* @type {ModalSubmitFieldsResolver}
|
||||||
|
*/
|
||||||
|
this.fields = new ModalSubmitFieldsResolver(this.components);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the reply to this interaction has been deferred
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
this.deferred = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the reply to this interaction is ephemeral
|
||||||
|
* @type {?boolean}
|
||||||
|
*/
|
||||||
|
this.ephemeral = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this interaction has already been replied to
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
this.replied = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An associated interaction webhook, can be used to further interact with this interaction
|
||||||
|
* @type {InteractionWebhook}
|
||||||
|
*/
|
||||||
|
this.webhook = new InteractionWebhook(this.client, this.applicationId, this.token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms component data to discord.js-compatible data
|
||||||
|
* @param {*} rawComponent The data to transform
|
||||||
|
* @returns {PartialTextInputData[]}
|
||||||
|
*/
|
||||||
|
static transformComponent(rawComponent) {
|
||||||
|
return rawComponent.components.map(c => ({
|
||||||
|
value: c.value,
|
||||||
|
type: MessageComponentTypes[c.type],
|
||||||
|
customId: c.custom_id,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are here only for documentation purposes - they are implemented by InteractionResponses
|
||||||
|
/* eslint-disable no-empty-function */
|
||||||
|
deferReply() {}
|
||||||
|
reply() {}
|
||||||
|
fetchReply() {}
|
||||||
|
editReply() {}
|
||||||
|
deleteReply() {}
|
||||||
|
followUp() {}
|
||||||
|
update() {}
|
||||||
|
deferUpdate() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
InteractionResponses.applyToClass(ModalSubmitInteraction, ['showModal', 'awaitModalSubmit']);
|
||||||
|
|
||||||
|
module.exports = ModalSubmitInteraction;
|
||||||
201
src/structures/TextInputComponent.js
Normal file
201
src/structures/TextInputComponent.js
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BaseMessageComponent = require('./BaseMessageComponent');
|
||||||
|
const { RangeError } = require('../errors');
|
||||||
|
const { TextInputStyles, MessageComponentTypes } = require('../util/Constants');
|
||||||
|
const Util = require('../util/Util');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a text input component in a modal
|
||||||
|
* @extends {BaseMessageComponent}
|
||||||
|
*/
|
||||||
|
|
||||||
|
class TextInputComponent extends BaseMessageComponent {
|
||||||
|
/**
|
||||||
|
* @typedef {BaseMessageComponentOptions} TextInputComponentOptions
|
||||||
|
* @property {string} [customId] A unique string to be sent in the interaction when submitted
|
||||||
|
* @property {string} [label] The text to be displayed above this text input component
|
||||||
|
* @property {number} [maxLength] Maximum length of text that can be entered
|
||||||
|
* @property {number} [minLength] Minimum length of text required to be entered
|
||||||
|
* @property {string} [placeholder] Custom placeholder text to display when no text is entered
|
||||||
|
* @property {boolean} [required] Whether or not this text input component is required
|
||||||
|
* @property {TextInputStyleResolvable} [style] The style of this text input component
|
||||||
|
* @property {string} [value] Value of this text input component
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {TextInputComponent|TextInputComponentOptions} [data={}] TextInputComponent to clone or raw data
|
||||||
|
*/
|
||||||
|
constructor(data = {}) {
|
||||||
|
super({ type: 'TEXT_INPUT' });
|
||||||
|
|
||||||
|
this.setup(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
setup(data) {
|
||||||
|
/**
|
||||||
|
* A unique string to be sent in the interaction when submitted
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.customId = data.custom_id ?? data.customId ?? null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The text to be displayed above this text input component
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.label = data.label ?? null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum length of text that can be entered
|
||||||
|
* @type {?number}
|
||||||
|
*/
|
||||||
|
this.maxLength = data.max_length ?? data.maxLength ?? null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum length of text required to be entered
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.minLength = data.min_length ?? data.minLength ?? null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom placeholder text to display when no text is entered
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.placeholder = data.placeholder ?? null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not this text input component is required
|
||||||
|
* @type {?boolean}
|
||||||
|
*/
|
||||||
|
this.required = data.required ?? false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The style of this text input component
|
||||||
|
* @type {?TextInputStyle}
|
||||||
|
*/
|
||||||
|
this.style = data.style ? TextInputComponent.resolveStyle(data.style) : null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value of this text input component
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.value = data.value ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the custom id of this text input component
|
||||||
|
* @param {string} customId A unique string to be sent in the interaction when submitted
|
||||||
|
* @returns {TextInputComponent}
|
||||||
|
*/
|
||||||
|
setCustomId(customId) {
|
||||||
|
this.customId = Util.verifyString(customId, RangeError, 'TEXT_INPUT_CUSTOM_ID');
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the label of this text input component
|
||||||
|
* @param {string} label The text to be displayed above this text input component
|
||||||
|
* @returns {TextInputComponent}
|
||||||
|
*/
|
||||||
|
setLabel(label) {
|
||||||
|
this.label = Util.verifyString(label, RangeError, 'TEXT_INPUT_LABEL');
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text input component to be required for modal submission
|
||||||
|
* @param {boolean} [required=true] Whether this text input component is required
|
||||||
|
* @returns {TextInputComponent}
|
||||||
|
*/
|
||||||
|
setRequired(required = true) {
|
||||||
|
this.required = required;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximum length of text input required in this text input component
|
||||||
|
* @param {number} maxLength Maximum length of text to be required
|
||||||
|
* @returns {TextInputComponent}
|
||||||
|
*/
|
||||||
|
setMaxLength(maxLength) {
|
||||||
|
this.maxLength = maxLength;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the minimum length of text input required in this text input component
|
||||||
|
* @param {number} minLength Minimum length of text to be required
|
||||||
|
* @returns {TextInputComponent}
|
||||||
|
*/
|
||||||
|
setMinLength(minLength) {
|
||||||
|
this.minLength = minLength;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the placeholder of this text input component
|
||||||
|
* @param {string} placeholder Custom placeholder text to display when no text is entered
|
||||||
|
* @returns {TextInputComponent}
|
||||||
|
*/
|
||||||
|
setPlaceholder(placeholder) {
|
||||||
|
this.placeholder = Util.verifyString(placeholder, RangeError, 'TEXT_INPUT_PLACEHOLDER');
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the style of this text input component
|
||||||
|
* @param {TextInputStyleResolvable} style The style of this text input component
|
||||||
|
* @returns {TextInputComponent}
|
||||||
|
*/
|
||||||
|
setStyle(style) {
|
||||||
|
this.style = TextInputComponent.resolveStyle(style);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of this text input component
|
||||||
|
* @param {string} value Value of this text input component
|
||||||
|
* @returns {TextInputComponent}
|
||||||
|
*/
|
||||||
|
setValue(value) {
|
||||||
|
this.value = Util.verifyString(value, RangeError, 'TEXT_INPUT_VALUE');
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms the text input component into a plain object
|
||||||
|
* @returns {APITextInput} The raw data of this text input component
|
||||||
|
*/
|
||||||
|
toJSON() {
|
||||||
|
return {
|
||||||
|
custom_id: this.customId,
|
||||||
|
label: this.label,
|
||||||
|
max_length: this.maxLength,
|
||||||
|
min_length: this.minLength,
|
||||||
|
placeholder: this.placeholder,
|
||||||
|
required: this.required,
|
||||||
|
style: TextInputStyles[this.style],
|
||||||
|
type: MessageComponentTypes[this.type],
|
||||||
|
value: this.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data that can be resolved to a TextInputStyle. This can be
|
||||||
|
* * TextInputStyle
|
||||||
|
* * number
|
||||||
|
* @typedef {number|TextInputStyle} TextInputStyleResolvable
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the style of a text input component
|
||||||
|
* @param {TextInputStyleResolvable} style The style to resolve
|
||||||
|
* @returns {TextInputStyle}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static resolveStyle(style) {
|
||||||
|
return typeof style === 'string' ? style : TextInputStyles[style];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = TextInputComponent;
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { Error } = require('../../errors');
|
const { Error } = require('../../errors');
|
||||||
const { InteractionResponseTypes } = require('../../util/Constants');
|
const { InteractionResponseTypes, InteractionTypes } = require('../../util/Constants');
|
||||||
const MessageFlags = require('../../util/MessageFlags');
|
const MessageFlags = require('../../util/MessageFlags');
|
||||||
|
const InteractionCollector = require('../InteractionCollector');
|
||||||
const MessagePayload = require('../MessagePayload');
|
const MessagePayload = require('../MessagePayload');
|
||||||
|
const Modal = require('../Modal');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for classes that support shared interaction response types.
|
* Interface for classes that support shared interaction response types.
|
||||||
@@ -226,6 +228,56 @@ class InteractionResponses {
|
|||||||
return options.fetchReply ? this.fetchReply() : undefined;
|
return options.fetchReply ? this.fetchReply() : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a modal component
|
||||||
|
* @param {Modal|ModalOptions} modal The modal to show
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async showModal(modal) {
|
||||||
|
if (this.deferred || this.replied) throw new Error('INTERACTION_ALREADY_REPLIED');
|
||||||
|
|
||||||
|
const _modal = modal instanceof Modal ? modal : new Modal(modal);
|
||||||
|
await this.client.api.interactions(this.id, this.token).callback.post({
|
||||||
|
data: {
|
||||||
|
type: InteractionResponseTypes.MODAL,
|
||||||
|
data: _modal.toJSON(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.replied = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object containing the same properties as CollectorOptions, but a few more:
|
||||||
|
* @typedef {Object} AwaitModalSubmitOptions
|
||||||
|
* @property {CollectorFilter} [filter] The filter applied to this collector
|
||||||
|
* @property {number} time Time to wait for an interaction before rejecting
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collects a single modal submit interaction that passes the filter.
|
||||||
|
* The Promise will reject if the time expires.
|
||||||
|
* @param {AwaitModalSubmitOptions} options Options to pass to the internal collector
|
||||||
|
* @returns {Promise<ModalSubmitInteraction>}
|
||||||
|
* @example
|
||||||
|
* // Collect a modal submit interaction
|
||||||
|
* const filter = (interaction) => interaction.customId === 'modal';
|
||||||
|
* interaction.awaitModalSubmit({ filter, time: 15_000 })
|
||||||
|
* .then(interaction => console.log(`${interaction.customId} was submitted!`))
|
||||||
|
* .catch(console.error);
|
||||||
|
*/
|
||||||
|
awaitModalSubmit(options) {
|
||||||
|
if (typeof options.time !== 'number') throw new Error('INVALID_TYPE', 'time', 'number');
|
||||||
|
const _options = { ...options, max: 1, interactionType: InteractionTypes.MODAL_SUBMIT };
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const collector = new InteractionCollector(this.client, _options);
|
||||||
|
collector.once('end', (interactions, reason) => {
|
||||||
|
const interaction = interactions.first();
|
||||||
|
if (interaction) resolve(interaction);
|
||||||
|
else reject(new Error('INTERACTION_COLLECTOR_ERROR', reason));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static applyToClass(structure, ignore = []) {
|
static applyToClass(structure, ignore = []) {
|
||||||
const props = [
|
const props = [
|
||||||
'deferReply',
|
'deferReply',
|
||||||
@@ -236,6 +288,8 @@ class InteractionResponses {
|
|||||||
'followUp',
|
'followUp',
|
||||||
'deferUpdate',
|
'deferUpdate',
|
||||||
'update',
|
'update',
|
||||||
|
'showModal',
|
||||||
|
'awaitModalSubmit',
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const prop of props) {
|
for (const prop of props) {
|
||||||
|
|||||||
@@ -1076,6 +1076,7 @@ exports.InteractionTypes = createEnum([
|
|||||||
'APPLICATION_COMMAND',
|
'APPLICATION_COMMAND',
|
||||||
'MESSAGE_COMPONENT',
|
'MESSAGE_COMPONENT',
|
||||||
'APPLICATION_COMMAND_AUTOCOMPLETE',
|
'APPLICATION_COMMAND_AUTOCOMPLETE',
|
||||||
|
'MODAL_SUBMIT',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1099,6 +1100,7 @@ exports.InteractionResponseTypes = createEnum([
|
|||||||
'DEFERRED_MESSAGE_UPDATE',
|
'DEFERRED_MESSAGE_UPDATE',
|
||||||
'UPDATE_MESSAGE',
|
'UPDATE_MESSAGE',
|
||||||
'APPLICATION_COMMAND_AUTOCOMPLETE_RESULT',
|
'APPLICATION_COMMAND_AUTOCOMPLETE_RESULT',
|
||||||
|
'MODAL',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1109,7 +1111,7 @@ exports.InteractionResponseTypes = createEnum([
|
|||||||
* @typedef {string} MessageComponentType
|
* @typedef {string} MessageComponentType
|
||||||
* @see {@link https://discord.com/developers/docs/interactions/message-components#component-object-component-types}
|
* @see {@link https://discord.com/developers/docs/interactions/message-components#component-object-component-types}
|
||||||
*/
|
*/
|
||||||
exports.MessageComponentTypes = createEnum([null, 'ACTION_ROW', 'BUTTON', 'SELECT_MENU']);
|
exports.MessageComponentTypes = createEnum([null, 'ACTION_ROW', 'BUTTON', 'SELECT_MENU', 'TEXT_INPUT']);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The style of a message button
|
* The style of a message button
|
||||||
@@ -1152,6 +1154,15 @@ exports.NSFWLevels = createEnum(['DEFAULT', 'EXPLICIT', 'SAFE', 'AGE_RESTRICTED'
|
|||||||
*/
|
*/
|
||||||
exports.PrivacyLevels = createEnum([null, 'PUBLIC', 'GUILD_ONLY']);
|
exports.PrivacyLevels = createEnum([null, 'PUBLIC', 'GUILD_ONLY']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The style of a text input component
|
||||||
|
* * SHORT
|
||||||
|
* * PARAGRAPH
|
||||||
|
* @typedef {string} TextInputStyle
|
||||||
|
* @see {@link https://discord.com/developers/docs/interactions/message-components#text-inputs-text-input-styles}
|
||||||
|
*/
|
||||||
|
exports.TextInputStyles = createEnum([null, 'SHORT', 'PARAGRAPH']);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Privacy level of a {@link GuildScheduledEvent} object:
|
* Privacy level of a {@link GuildScheduledEvent} object:
|
||||||
* * GUILD_ONLY
|
* * GUILD_ONLY
|
||||||
|
|||||||
13
typings/enums.d.ts
vendored
13
typings/enums.d.ts
vendored
@@ -111,6 +111,7 @@ export const enum InteractionResponseTypes {
|
|||||||
DEFERRED_MESSAGE_UPDATE = 6,
|
DEFERRED_MESSAGE_UPDATE = 6,
|
||||||
UPDATE_MESSAGE = 7,
|
UPDATE_MESSAGE = 7,
|
||||||
APPLICATION_COMMAND_AUTOCOMPLETE_RESULT = 8,
|
APPLICATION_COMMAND_AUTOCOMPLETE_RESULT = 8,
|
||||||
|
MODAL = 9,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum InteractionTypes {
|
export const enum InteractionTypes {
|
||||||
@@ -118,6 +119,7 @@ export const enum InteractionTypes {
|
|||||||
APPLICATION_COMMAND = 2,
|
APPLICATION_COMMAND = 2,
|
||||||
MESSAGE_COMPONENT = 3,
|
MESSAGE_COMPONENT = 3,
|
||||||
APPLICATION_COMMAND_AUTOCOMPLETE = 4,
|
APPLICATION_COMMAND_AUTOCOMPLETE = 4,
|
||||||
|
MODAL_SUBMIT = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum InviteTargetType {
|
export const enum InviteTargetType {
|
||||||
@@ -142,6 +144,12 @@ export const enum MessageComponentTypes {
|
|||||||
ACTION_ROW = 1,
|
ACTION_ROW = 1,
|
||||||
BUTTON = 2,
|
BUTTON = 2,
|
||||||
SELECT_MENU = 3,
|
SELECT_MENU = 3,
|
||||||
|
TEXT_INPUT = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const enum ModalComponentTypes {
|
||||||
|
ACTION_ROW = 1,
|
||||||
|
TEXT_INPUT = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum MFALevels {
|
export const enum MFALevels {
|
||||||
@@ -184,6 +192,11 @@ export const enum StickerTypes {
|
|||||||
GUILD = 2,
|
GUILD = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const enum TextInputStyles {
|
||||||
|
SHORT = 1,
|
||||||
|
PARAGRAPH = 2,
|
||||||
|
}
|
||||||
|
|
||||||
export const enum VerificationLevels {
|
export const enum VerificationLevels {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
LOW = 1,
|
LOW = 1,
|
||||||
|
|||||||
238
typings/index.d.ts
vendored
238
typings/index.d.ts
vendored
@@ -22,6 +22,7 @@ import {
|
|||||||
import { Collection } from '@discordjs/collection';
|
import { Collection } from '@discordjs/collection';
|
||||||
import {
|
import {
|
||||||
APIActionRowComponent,
|
APIActionRowComponent,
|
||||||
|
APIActionRowComponentTypes,
|
||||||
APIApplicationCommand,
|
APIApplicationCommand,
|
||||||
APIApplicationCommandInteractionData,
|
APIApplicationCommandInteractionData,
|
||||||
APIApplicationCommandOption,
|
APIApplicationCommandOption,
|
||||||
@@ -35,7 +36,9 @@ import {
|
|||||||
APIInteractionDataResolvedGuildMember,
|
APIInteractionDataResolvedGuildMember,
|
||||||
APIInteractionGuildMember,
|
APIInteractionGuildMember,
|
||||||
APIMessage,
|
APIMessage,
|
||||||
|
APIMessageActionRowComponent,
|
||||||
APIMessageComponent,
|
APIMessageComponent,
|
||||||
|
APIModalActionRowComponent,
|
||||||
APIOverwrite,
|
APIOverwrite,
|
||||||
APIPartialChannel,
|
APIPartialChannel,
|
||||||
APIPartialEmoji,
|
APIPartialEmoji,
|
||||||
@@ -43,6 +46,7 @@ import {
|
|||||||
APIRole,
|
APIRole,
|
||||||
APISelectMenuComponent,
|
APISelectMenuComponent,
|
||||||
APITemplateSerializedSourceGuild,
|
APITemplateSerializedSourceGuild,
|
||||||
|
APITextInputComponent,
|
||||||
APIUser,
|
APIUser,
|
||||||
GatewayVoiceServerUpdateDispatchData,
|
GatewayVoiceServerUpdateDispatchData,
|
||||||
GatewayVoiceStateUpdateDispatchData,
|
GatewayVoiceStateUpdateDispatchData,
|
||||||
@@ -71,6 +75,7 @@ import {
|
|||||||
MessageButtonStyles,
|
MessageButtonStyles,
|
||||||
MessageComponentTypes,
|
MessageComponentTypes,
|
||||||
MessageTypes,
|
MessageTypes,
|
||||||
|
ModalComponentTypes,
|
||||||
MFALevels,
|
MFALevels,
|
||||||
NSFWLevels,
|
NSFWLevels,
|
||||||
OverwriteTypes,
|
OverwriteTypes,
|
||||||
@@ -78,6 +83,7 @@ import {
|
|||||||
PrivacyLevels,
|
PrivacyLevels,
|
||||||
StickerFormatTypes,
|
StickerFormatTypes,
|
||||||
StickerTypes,
|
StickerTypes,
|
||||||
|
TextInputStyles,
|
||||||
VerificationLevels,
|
VerificationLevels,
|
||||||
WebhookTypes,
|
WebhookTypes,
|
||||||
GuildScheduledEventEntityTypes,
|
GuildScheduledEventEntityTypes,
|
||||||
@@ -117,6 +123,7 @@ import {
|
|||||||
RawMessagePayloadData,
|
RawMessagePayloadData,
|
||||||
RawMessageReactionData,
|
RawMessageReactionData,
|
||||||
RawMessageSelectMenuInteractionData,
|
RawMessageSelectMenuInteractionData,
|
||||||
|
RawModalSubmitInteractionData,
|
||||||
RawOAuth2GuildData,
|
RawOAuth2GuildData,
|
||||||
RawPartialGroupDMChannelData,
|
RawPartialGroupDMChannelData,
|
||||||
RawPartialMessageData,
|
RawPartialMessageData,
|
||||||
@@ -130,6 +137,7 @@ import {
|
|||||||
RawStickerPackData,
|
RawStickerPackData,
|
||||||
RawTeamData,
|
RawTeamData,
|
||||||
RawTeamMemberData,
|
RawTeamMemberData,
|
||||||
|
RawTextInputComponentData,
|
||||||
RawThreadChannelData,
|
RawThreadChannelData,
|
||||||
RawThreadMemberData,
|
RawThreadMemberData,
|
||||||
RawTypingData,
|
RawTypingData,
|
||||||
@@ -360,6 +368,9 @@ export abstract class BaseCommandInteraction<Cached extends CacheType = CacheTyp
|
|||||||
public ephemeral: boolean | null;
|
public ephemeral: boolean | null;
|
||||||
public replied: boolean;
|
public replied: boolean;
|
||||||
public webhook: InteractionWebhook;
|
public webhook: InteractionWebhook;
|
||||||
|
public awaitModalSubmit(
|
||||||
|
options: AwaitModalSubmitOptions<ModalSubmitInteraction>,
|
||||||
|
): Promise<ModalSubmitInteraction<Cached>>;
|
||||||
public inGuild(): this is BaseCommandInteraction<'raw' | 'cached'>;
|
public inGuild(): this is BaseCommandInteraction<'raw' | 'cached'>;
|
||||||
public inCachedGuild(): this is BaseCommandInteraction<'cached'>;
|
public inCachedGuild(): this is BaseCommandInteraction<'cached'>;
|
||||||
public inRawGuild(): this is BaseCommandInteraction<'raw'>;
|
public inRawGuild(): this is BaseCommandInteraction<'raw'>;
|
||||||
@@ -371,6 +382,7 @@ export abstract class BaseCommandInteraction<Cached extends CacheType = CacheTyp
|
|||||||
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<GuildCacheMessage<Cached>>;
|
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<GuildCacheMessage<Cached>>;
|
||||||
public reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
public reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||||
public reply(options: string | MessagePayload | InteractionReplyOptions): Promise<void>;
|
public reply(options: string | MessagePayload | InteractionReplyOptions): Promise<void>;
|
||||||
|
public showModal(modal: Modal | ModalOptions): Promise<void>;
|
||||||
private transformOption(
|
private transformOption(
|
||||||
option: APIApplicationCommandOption,
|
option: APIApplicationCommandOption,
|
||||||
resolved: APIApplicationCommandInteractionData['resolved'],
|
resolved: APIApplicationCommandInteractionData['resolved'],
|
||||||
@@ -1366,6 +1378,7 @@ export class Interaction<Cached extends CacheType = CacheType> extends Base {
|
|||||||
public isUserContextMenu(): this is UserContextMenuInteraction<Cached>;
|
public isUserContextMenu(): this is UserContextMenuInteraction<Cached>;
|
||||||
public isMessageContextMenu(): this is MessageContextMenuInteraction<Cached>;
|
public isMessageContextMenu(): this is MessageContextMenuInteraction<Cached>;
|
||||||
public isMessageComponent(): this is MessageComponentInteraction<Cached>;
|
public isMessageComponent(): this is MessageComponentInteraction<Cached>;
|
||||||
|
public isModalSubmit(): this is ModalSubmitInteraction<Cached>;
|
||||||
public isSelectMenu(): this is SelectMenuInteraction<Cached>;
|
public isSelectMenu(): this is SelectMenuInteraction<Cached>;
|
||||||
public isRepliable(): this is this & InteractionResponseFields<Cached>;
|
public isRepliable(): this is this & InteractionResponseFields<Cached>;
|
||||||
}
|
}
|
||||||
@@ -1501,6 +1514,7 @@ export type MappedInteractionTypes<Cached extends boolean = boolean> = EnumValue
|
|||||||
BUTTON: ButtonInteraction<WrapBooleanCache<Cached>>;
|
BUTTON: ButtonInteraction<WrapBooleanCache<Cached>>;
|
||||||
SELECT_MENU: SelectMenuInteraction<WrapBooleanCache<Cached>>;
|
SELECT_MENU: SelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||||
ACTION_ROW: MessageComponentInteraction<WrapBooleanCache<Cached>>;
|
ACTION_ROW: MessageComponentInteraction<WrapBooleanCache<Cached>>;
|
||||||
|
TEXT_INPUT: ModalSubmitInteraction<WrapBooleanCache<Cached>>;
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
@@ -1578,22 +1592,20 @@ export class Message<Cached extends boolean = boolean> extends Base {
|
|||||||
public inGuild(): this is Message<true> & this;
|
public inGuild(): this is Message<true> & this;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MessageActionRow extends BaseMessageComponent {
|
export class MessageActionRow<
|
||||||
public constructor(data?: MessageActionRow | MessageActionRowOptions | APIActionRowComponent);
|
T extends MessageActionRowComponent | ModalActionRowComponent = MessageActionRowComponent,
|
||||||
|
U = T extends ModalActionRowComponent ? ModalActionRowComponentResolvable : MessageActionRowComponentResolvable,
|
||||||
|
V = T extends ModalActionRowComponent
|
||||||
|
? APIActionRowComponent<APIModalActionRowComponent>
|
||||||
|
: APIActionRowComponent<APIMessageActionRowComponent>,
|
||||||
|
> extends BaseMessageComponent {
|
||||||
|
public constructor(data?: MessageActionRow<T> | MessageActionRowOptions<U> | V);
|
||||||
public type: 'ACTION_ROW';
|
public type: 'ACTION_ROW';
|
||||||
public components: MessageActionRowComponent[];
|
public components: T[];
|
||||||
public addComponents(
|
public addComponents(...components: U[] | U[][]): this;
|
||||||
...components: MessageActionRowComponentResolvable[] | MessageActionRowComponentResolvable[][]
|
public setComponents(...components: U[] | U[][]): this;
|
||||||
): this;
|
public spliceComponents(index: number, deleteCount: number, ...components: U[] | U[][]): this;
|
||||||
public setComponents(
|
public toJSON(): V;
|
||||||
...components: MessageActionRowComponentResolvable[] | MessageActionRowComponentResolvable[][]
|
|
||||||
): this;
|
|
||||||
public spliceComponents(
|
|
||||||
index: number,
|
|
||||||
deleteCount: number,
|
|
||||||
...components: MessageActionRowComponentResolvable[] | MessageActionRowComponentResolvable[][]
|
|
||||||
): this;
|
|
||||||
public toJSON(): APIActionRowComponent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MessageAttachment {
|
export class MessageAttachment {
|
||||||
@@ -1656,9 +1668,9 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
|
|||||||
public readonly component: CacheTypeReducer<
|
public readonly component: CacheTypeReducer<
|
||||||
Cached,
|
Cached,
|
||||||
MessageActionRowComponent,
|
MessageActionRowComponent,
|
||||||
Exclude<APIMessageComponent, APIActionRowComponent>,
|
Exclude<APIMessageComponent, APIActionRowComponent<APIMessageActionRowComponent>>,
|
||||||
MessageActionRowComponent | Exclude<APIMessageComponent, APIActionRowComponent>,
|
MessageActionRowComponent | Exclude<APIMessageComponent, APIActionRowComponent<APIMessageActionRowComponent>>,
|
||||||
MessageActionRowComponent | Exclude<APIMessageComponent, APIActionRowComponent>
|
MessageActionRowComponent | Exclude<APIMessageComponent, APIActionRowComponent<APIMessageActionRowComponent>>
|
||||||
>;
|
>;
|
||||||
public componentType: Exclude<MessageComponentType, 'ACTION_ROW'>;
|
public componentType: Exclude<MessageComponentType, 'ACTION_ROW'>;
|
||||||
public customId: string;
|
public customId: string;
|
||||||
@@ -1668,6 +1680,9 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
|
|||||||
public message: GuildCacheMessage<Cached>;
|
public message: GuildCacheMessage<Cached>;
|
||||||
public replied: boolean;
|
public replied: boolean;
|
||||||
public webhook: InteractionWebhook;
|
public webhook: InteractionWebhook;
|
||||||
|
public awaitModalSubmit(
|
||||||
|
options: AwaitModalSubmitOptions<ModalSubmitInteraction>,
|
||||||
|
): Promise<ModalSubmitInteraction<Cached>>;
|
||||||
public inGuild(): this is MessageComponentInteraction<'raw' | 'cached'>;
|
public inGuild(): this is MessageComponentInteraction<'raw' | 'cached'>;
|
||||||
public inCachedGuild(): this is MessageComponentInteraction<'cached'>;
|
public inCachedGuild(): this is MessageComponentInteraction<'cached'>;
|
||||||
public inRawGuild(): this is MessageComponentInteraction<'raw'>;
|
public inRawGuild(): this is MessageComponentInteraction<'raw'>;
|
||||||
@@ -1681,6 +1696,7 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
|
|||||||
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<GuildCacheMessage<Cached>>;
|
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<GuildCacheMessage<Cached>>;
|
||||||
public reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
public reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||||
public reply(options: string | MessagePayload | InteractionReplyOptions): Promise<void>;
|
public reply(options: string | MessagePayload | InteractionReplyOptions): Promise<void>;
|
||||||
|
public showModal(modal: Modal | ModalOptions): Promise<void>;
|
||||||
public update(options: InteractionUpdateOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
public update(options: InteractionUpdateOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||||
public update(options: string | MessagePayload | InteractionUpdateOptions): Promise<void>;
|
public update(options: string | MessagePayload | InteractionUpdateOptions): Promise<void>;
|
||||||
|
|
||||||
@@ -1842,6 +1858,82 @@ export class MessageSelectMenu extends BaseMessageComponent {
|
|||||||
public toJSON(): APISelectMenuComponent;
|
public toJSON(): APISelectMenuComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class Modal {
|
||||||
|
public constructor(data?: Modal | ModalOptions);
|
||||||
|
public components: MessageActionRow<ModalActionRowComponent>[];
|
||||||
|
public customId: string | null;
|
||||||
|
public title: string | null;
|
||||||
|
public addComponents(
|
||||||
|
...components: (
|
||||||
|
| MessageActionRow<ModalActionRowComponent>
|
||||||
|
| (Required<BaseMessageComponentOptions> & MessageActionRowOptions<ModalActionRowComponentResolvable>)
|
||||||
|
)[]
|
||||||
|
): this;
|
||||||
|
public setComponents(
|
||||||
|
...components: (
|
||||||
|
| MessageActionRow<ModalActionRowComponent>
|
||||||
|
| (Required<BaseMessageComponentOptions> & MessageActionRowOptions<ModalActionRowComponentResolvable>)
|
||||||
|
)[]
|
||||||
|
): this;
|
||||||
|
public setCustomId(customId: string): this;
|
||||||
|
public spliceComponents(
|
||||||
|
index: number,
|
||||||
|
deleteCount: number,
|
||||||
|
...components: (
|
||||||
|
| MessageActionRow<ModalActionRowComponent>
|
||||||
|
| (Required<BaseMessageComponentOptions> & MessageActionRowOptions<ModalActionRowComponentResolvable>)
|
||||||
|
)[]
|
||||||
|
): this;
|
||||||
|
public setTitle(title: string): this;
|
||||||
|
public toJSON(): RawModalSubmitInteractionData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ModalSubmitFieldsResolver {
|
||||||
|
constructor(components: PartialModalActionRow[]);
|
||||||
|
private readonly _fields: PartialTextInputData[];
|
||||||
|
public getField(customId: string): PartialTextInputData;
|
||||||
|
public getTextInputValue(customId: string): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ModalMessageModalSubmitInteraction<Cached extends CacheType = CacheType>
|
||||||
|
extends ModalSubmitInteraction<Cached> {
|
||||||
|
message: GuildCacheMessage<Cached> | null;
|
||||||
|
update(options: InteractionUpdateOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||||
|
update(options: string | MessagePayload | InteractionUpdateOptions): Promise<void>;
|
||||||
|
deferUpdate(options: InteractionDeferUpdateOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||||
|
deferUpdate(options?: InteractionDeferUpdateOptions): Promise<void>;
|
||||||
|
inGuild(): this is ModalMessageModalSubmitInteraction<'raw' | 'cached'>;
|
||||||
|
inCachedGuild(): this is ModalMessageModalSubmitInteraction<'cached'>;
|
||||||
|
inRawGuild(): this is ModalMessageModalSubmitInteraction<'raw'>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extends Interaction<Cached> {
|
||||||
|
protected constructor(client: Client, data: RawModalSubmitInteractionData);
|
||||||
|
public customId: string;
|
||||||
|
public components: PartialModalActionRow[];
|
||||||
|
public deferred: boolean;
|
||||||
|
public ephemeral: boolean | null;
|
||||||
|
public fields: ModalSubmitFieldsResolver;
|
||||||
|
public replied: false;
|
||||||
|
public webhook: InteractionWebhook;
|
||||||
|
public reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||||
|
public reply(options: string | MessagePayload | InteractionReplyOptions): Promise<void>;
|
||||||
|
public deleteReply(): Promise<void>;
|
||||||
|
public editReply(options: string | MessagePayload | WebhookEditMessageOptions): Promise<GuildCacheMessage<Cached>>;
|
||||||
|
public deferReply(options: InteractionDeferReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||||
|
public deferReply(options?: InteractionDeferReplyOptions): Promise<void>;
|
||||||
|
public deferUpdate(options: InteractionDeferUpdateOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||||
|
public deferUpdate(options?: InteractionDeferUpdateOptions): Promise<void>;
|
||||||
|
public fetchReply(): Promise<GuildCacheMessage<Cached>>;
|
||||||
|
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<GuildCacheMessage<Cached>>;
|
||||||
|
public inGuild(): this is ModalSubmitInteraction<'raw' | 'cached'>;
|
||||||
|
public inCachedGuild(): this is ModalSubmitInteraction<'cached'>;
|
||||||
|
public inRawGuild(): this is ModalSubmitInteraction<'raw'>;
|
||||||
|
public isFromMessage(): this is ModalMessageModalSubmitInteraction<Cached>;
|
||||||
|
public update(options: InteractionUpdateOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||||
|
public update(options: string | MessagePayload | InteractionUpdateOptions): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
export class NewsChannel extends BaseGuildTextChannel {
|
export class NewsChannel extends BaseGuildTextChannel {
|
||||||
public threads: ThreadManager<AllowedThreadTypeForNewsChannel>;
|
public threads: ThreadManager<AllowedThreadTypeForNewsChannel>;
|
||||||
public type: 'GUILD_NEWS';
|
public type: 'GUILD_NEWS';
|
||||||
@@ -2319,6 +2411,28 @@ export class TextChannel extends BaseGuildTextChannel {
|
|||||||
public setRateLimitPerUser(rateLimitPerUser: number, reason?: string): Promise<TextChannel>;
|
public setRateLimitPerUser(rateLimitPerUser: number, reason?: string): Promise<TextChannel>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class TextInputComponent extends BaseMessageComponent {
|
||||||
|
public constructor(data?: TextInputComponent | TextInputComponentOptions);
|
||||||
|
public customId: string | null;
|
||||||
|
public label: string | null;
|
||||||
|
public required: boolean;
|
||||||
|
public maxLength: number | null;
|
||||||
|
public minLength: number | null;
|
||||||
|
public placeholder: string | null;
|
||||||
|
public style: TextInputStyle;
|
||||||
|
public value: string | null;
|
||||||
|
public setCustomId(customId: string): this;
|
||||||
|
public setLabel(label: string): this;
|
||||||
|
public setRequired(required?: boolean): this;
|
||||||
|
public setMaxLength(maxLength: number): this;
|
||||||
|
public setMinLength(minLength: number): this;
|
||||||
|
public setPlaceholder(placeholder: string): this;
|
||||||
|
public setStyle(style: TextInputStyleResolvable): this;
|
||||||
|
public setValue(value: string): this;
|
||||||
|
public toJSON(): RawTextInputComponentData;
|
||||||
|
public static resolveStyle(style: TextInputStyleResolvable): TextInputStyle;
|
||||||
|
}
|
||||||
|
|
||||||
export class ThreadChannel extends TextBasedChannelMixin(Channel) {
|
export class ThreadChannel extends TextBasedChannelMixin(Channel) {
|
||||||
private constructor(guild: Guild, data?: RawThreadChannelData, client?: Client, fromInteraction?: boolean);
|
private constructor(guild: Guild, data?: RawThreadChannelData, client?: Client, fromInteraction?: boolean);
|
||||||
public archived: boolean | null;
|
public archived: boolean | null;
|
||||||
@@ -2865,6 +2979,8 @@ export const Constants: {
|
|||||||
InteractionResponseTypes: EnumHolder<typeof InteractionResponseTypes>;
|
InteractionResponseTypes: EnumHolder<typeof InteractionResponseTypes>;
|
||||||
MessageComponentTypes: EnumHolder<typeof MessageComponentTypes>;
|
MessageComponentTypes: EnumHolder<typeof MessageComponentTypes>;
|
||||||
MessageButtonStyles: EnumHolder<typeof MessageButtonStyles>;
|
MessageButtonStyles: EnumHolder<typeof MessageButtonStyles>;
|
||||||
|
ModalComponentTypes: EnumHolder<typeof ModalComponentTypes>;
|
||||||
|
TextInputStyles: EnumHolder<typeof TextInputStyles>;
|
||||||
MFALevels: EnumHolder<typeof MFALevels>;
|
MFALevels: EnumHolder<typeof MFALevels>;
|
||||||
NSFWLevels: EnumHolder<typeof NSFWLevels>;
|
NSFWLevels: EnumHolder<typeof NSFWLevels>;
|
||||||
PrivacyLevels: EnumHolder<typeof PrivacyLevels>;
|
PrivacyLevels: EnumHolder<typeof PrivacyLevels>;
|
||||||
@@ -3808,6 +3924,13 @@ export interface AwaitMessagesOptions extends MessageCollectorOptions {
|
|||||||
errors?: string[];
|
errors?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type AwaitModalSubmitOptions<T extends ModalSubmitInteraction> = Omit<
|
||||||
|
ModalSubmitInteractionCollectorOptions<T>,
|
||||||
|
'max' | 'maxComponents' | 'maxUsers'
|
||||||
|
> & {
|
||||||
|
time: number;
|
||||||
|
};
|
||||||
|
|
||||||
export interface AwaitReactionsOptions extends ReactionCollectorOptions {
|
export interface AwaitReactionsOptions extends ReactionCollectorOptions {
|
||||||
errors?: string[];
|
errors?: string[];
|
||||||
}
|
}
|
||||||
@@ -4920,11 +5043,6 @@ export interface ImageURLOptions extends Omit<StaticImageURLOptions, 'format'> {
|
|||||||
format?: DynamicImageFormat;
|
format?: DynamicImageFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IntegrationAccount {
|
|
||||||
id: string | Snowflake;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type IntegrationType = 'twitch' | 'youtube' | 'discord';
|
export type IntegrationType = 'twitch' | 'youtube' | 'discord';
|
||||||
|
|
||||||
export interface InteractionCollectorOptions<T extends Interaction, Cached extends CacheType = CacheType>
|
export interface InteractionCollectorOptions<T extends Interaction, Cached extends CacheType = CacheType>
|
||||||
@@ -5044,10 +5162,26 @@ export type MessageActionRowComponentOptions =
|
|||||||
| (Required<BaseMessageComponentOptions> & MessageButtonOptions)
|
| (Required<BaseMessageComponentOptions> & MessageButtonOptions)
|
||||||
| (Required<BaseMessageComponentOptions> & MessageSelectMenuOptions);
|
| (Required<BaseMessageComponentOptions> & MessageSelectMenuOptions);
|
||||||
|
|
||||||
export type MessageActionRowComponentResolvable = MessageActionRowComponent | MessageActionRowComponentOptions;
|
export type MessageActionRowComponentResolvable =
|
||||||
|
| MessageActionRowComponent
|
||||||
|
| MessageActionRowComponentOptions
|
||||||
|
| APIMessageActionRowComponent;
|
||||||
|
|
||||||
export interface MessageActionRowOptions extends BaseMessageComponentOptions {
|
export type ModalActionRowComponent = TextInputComponent;
|
||||||
components: MessageActionRowComponentResolvable[];
|
|
||||||
|
export type ModalActionRowComponentOptions = TextInputComponentOptions;
|
||||||
|
|
||||||
|
export type ModalActionRowComponentResolvable =
|
||||||
|
| ModalActionRowComponent
|
||||||
|
| ModalActionRowComponentOptions
|
||||||
|
| APIModalActionRowComponent;
|
||||||
|
|
||||||
|
export interface MessageActionRowOptions<
|
||||||
|
T extends
|
||||||
|
| MessageActionRowComponentResolvable
|
||||||
|
| ModalActionRowComponentResolvable = MessageActionRowComponentResolvable,
|
||||||
|
> extends BaseMessageComponentOptions {
|
||||||
|
components: T[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MessageActivity {
|
export interface MessageActivity {
|
||||||
@@ -5084,15 +5218,13 @@ export interface MessageCollectorOptions extends CollectorOptions<[Message]> {
|
|||||||
|
|
||||||
export type MessageComponent = BaseMessageComponent | MessageActionRow | MessageButton | MessageSelectMenu;
|
export type MessageComponent = BaseMessageComponent | MessageActionRow | MessageButton | MessageSelectMenu;
|
||||||
|
|
||||||
export type MessageComponentCollectorOptions<T extends MessageComponentInteraction> = Omit<
|
export type MessageComponentCollectorOptions<T extends MessageComponentInteraction | ModalSubmitInteraction> = Omit<
|
||||||
InteractionCollectorOptions<T>,
|
InteractionCollectorOptions<T>,
|
||||||
'channel' | 'message' | 'guild' | 'interactionType'
|
'channel' | 'message' | 'guild' | 'interactionType'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type MessageChannelComponentCollectorOptions<T extends MessageComponentInteraction> = Omit<
|
export type MessageChannelComponentCollectorOptions<T extends MessageComponentInteraction | ModalSubmitInteraction> =
|
||||||
InteractionCollectorOptions<T>,
|
Omit<InteractionCollectorOptions<T>, 'channel' | 'guild' | 'interactionType'>;
|
||||||
'channel' | 'guild' | 'interactionType'
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type MessageComponentOptions =
|
export type MessageComponentOptions =
|
||||||
| BaseMessageComponentOptions
|
| BaseMessageComponentOptions
|
||||||
@@ -5276,6 +5408,19 @@ export type MessageType = keyof typeof MessageTypes;
|
|||||||
|
|
||||||
export type MFALevel = keyof typeof MFALevels;
|
export type MFALevel = keyof typeof MFALevels;
|
||||||
|
|
||||||
|
export interface ModalOptions {
|
||||||
|
components:
|
||||||
|
| MessageActionRow<ModalActionRowComponent>[]
|
||||||
|
| MessageActionRowOptions<ModalActionRowComponentResolvable>[];
|
||||||
|
customId: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ModalSubmitInteractionCollectorOptions<T extends ModalSubmitInteraction> = Omit<
|
||||||
|
InteractionCollectorOptions<T>,
|
||||||
|
'channel' | 'message' | 'guild' | 'interactionType'
|
||||||
|
>;
|
||||||
|
|
||||||
export interface MultipleShardRespawnOptions {
|
export interface MultipleShardRespawnOptions {
|
||||||
shardDelay?: number;
|
shardDelay?: number;
|
||||||
respawnDelay?: number;
|
respawnDelay?: number;
|
||||||
@@ -5301,6 +5446,18 @@ export type OverwriteResolvable = PermissionOverwrites | OverwriteData;
|
|||||||
|
|
||||||
export type OverwriteType = 'member' | 'role';
|
export type OverwriteType = 'member' | 'role';
|
||||||
|
|
||||||
|
export interface PartialModalActionRow {
|
||||||
|
type: MessageComponentType;
|
||||||
|
components: PartialTextInputData[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PartialTextInputData {
|
||||||
|
value: string;
|
||||||
|
// TODO: use dapi types
|
||||||
|
type: MessageComponentType;
|
||||||
|
customId: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type PermissionFlags = Record<PermissionString, bigint>;
|
export type PermissionFlags = Record<PermissionString, bigint>;
|
||||||
|
|
||||||
export type PermissionOverwriteOptions = Partial<Record<PermissionString, boolean | null>>;
|
export type PermissionOverwriteOptions = Partial<Record<PermissionString, boolean | null>>;
|
||||||
@@ -5647,6 +5804,25 @@ export type TextBasedChannel = Extract<AnyChannel, { messages: MessageManager }>
|
|||||||
|
|
||||||
export type TextBasedChannelTypes = TextBasedChannel['type'];
|
export type TextBasedChannelTypes = TextBasedChannel['type'];
|
||||||
|
|
||||||
|
export interface TextInputComponentOptions extends BaseMessageComponentOptions {
|
||||||
|
customId?: string;
|
||||||
|
label?: string;
|
||||||
|
minLength?: number;
|
||||||
|
maxLength?: number;
|
||||||
|
placeholder?: string;
|
||||||
|
required?: boolean;
|
||||||
|
style?: TextInputStyleResolvable;
|
||||||
|
value?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TextInputStyle = keyof typeof TextInputStyles;
|
||||||
|
|
||||||
|
export type TextInputStyleResolvable = TextInputStyle | TextInputStyles;
|
||||||
|
export interface IntegrationAccount {
|
||||||
|
id: string | Snowflake;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type VoiceBasedChannel = Extract<AnyChannel, { bitrate: number }>;
|
export type VoiceBasedChannel = Extract<AnyChannel, { bitrate: number }>;
|
||||||
|
|
||||||
export type GuildBasedChannel = Extract<AnyChannel, { guild: Guild }>;
|
export type GuildBasedChannel = Extract<AnyChannel, { guild: Guild }>;
|
||||||
|
|||||||
@@ -679,6 +679,8 @@ client.on('interaction', async interaction => {
|
|||||||
|
|
||||||
void new MessageActionRow();
|
void new MessageActionRow();
|
||||||
|
|
||||||
|
void new MessageActionRow({});
|
||||||
|
|
||||||
const button = new MessageButton();
|
const button = new MessageButton();
|
||||||
|
|
||||||
const actionRow = new MessageActionRow({ components: [button] });
|
const actionRow = new MessageActionRow({ components: [button] });
|
||||||
@@ -688,9 +690,6 @@ client.on('interaction', async interaction => {
|
|||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
interaction.reply({ content: 'Hi!', components: [[button]] });
|
interaction.reply({ content: 'Hi!', components: [[button]] });
|
||||||
|
|
||||||
// @ts-expect-error
|
|
||||||
void new MessageActionRow({});
|
|
||||||
|
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
await interaction.reply({ content: 'Hi!', components: [button] });
|
await interaction.reply({ content: 'Hi!', components: [button] });
|
||||||
|
|
||||||
|
|||||||
10
typings/rawDataTypes.d.ts
vendored
10
typings/rawDataTypes.d.ts
vendored
@@ -76,8 +76,13 @@ import {
|
|||||||
RESTPostAPIWebhookWithTokenJSONBody,
|
RESTPostAPIWebhookWithTokenJSONBody,
|
||||||
Snowflake,
|
Snowflake,
|
||||||
APIGuildScheduledEvent,
|
APIGuildScheduledEvent,
|
||||||
|
APIActionRowComponent,
|
||||||
|
APITextInputComponent,
|
||||||
|
APIModalActionRowComponent,
|
||||||
|
APIModalSubmitInteraction,
|
||||||
} from 'discord-api-types/v9';
|
} from 'discord-api-types/v9';
|
||||||
import { GuildChannel, Guild, PermissionOverwrites } from '.';
|
import { GuildChannel, Guild, PermissionOverwrites, InteractionType } from '.';
|
||||||
|
import type { InteractionTypes, MessageComponentTypes } from './enums';
|
||||||
|
|
||||||
export type RawActivityData = GatewayActivity;
|
export type RawActivityData = GatewayActivity;
|
||||||
|
|
||||||
@@ -141,6 +146,9 @@ export type RawMessageComponentInteractionData = APIMessageComponentInteraction;
|
|||||||
export type RawMessageButtonInteractionData = APIMessageButtonInteractionData;
|
export type RawMessageButtonInteractionData = APIMessageButtonInteractionData;
|
||||||
export type RawMessageSelectMenuInteractionData = APIMessageSelectMenuInteractionData;
|
export type RawMessageSelectMenuInteractionData = APIMessageSelectMenuInteractionData;
|
||||||
|
|
||||||
|
export type RawTextInputComponentData = APITextInputComponent;
|
||||||
|
export type RawModalSubmitInteractionData = APIModalSubmitInteraction;
|
||||||
|
|
||||||
export type RawInviteData =
|
export type RawInviteData =
|
||||||
| APIExtendedInvite
|
| APIExtendedInvite
|
||||||
| APIInvite
|
| APIInvite
|
||||||
|
|||||||
Reference in New Issue
Block a user