From 643dab3b1b5305d002fcefed62755bbe11fc3267 Mon Sep 17 00:00:00 2001 From: Suneet Tipirneni <77477100+suneettipirneni@users.noreply.github.com> Date: Sat, 4 Jun 2022 02:57:19 -0400 Subject: [PATCH] refactor: clean up modal submissions (#7994) Co-authored-by: SpaceEEC Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> --- packages/discord.js/src/index.js | 2 +- ...FieldsResolver.js => ModalSubmitFields.js} | 25 ++++++++------- .../src/structures/ModalSubmitInteraction.js | 22 ++++++++----- packages/discord.js/typings/index.d.ts | 32 +++++++++++++------ 4 files changed, 50 insertions(+), 31 deletions(-) rename packages/discord.js/src/structures/{ModalSubmitFieldsResolver.js => ModalSubmitFields.js} (71%) diff --git a/packages/discord.js/src/index.js b/packages/discord.js/src/index.js index 27c5298ce..1a8c70777 100644 --- a/packages/discord.js/src/index.js +++ b/packages/discord.js/src/index.js @@ -131,7 +131,7 @@ exports.MessageMentions = require('./structures/MessageMentions'); exports.MessagePayload = require('./structures/MessagePayload'); exports.MessageReaction = require('./structures/MessageReaction'); exports.ModalSubmitInteraction = require('./structures/ModalSubmitInteraction'); -exports.ModalSubmitFieldsResolver = require('./structures/ModalSubmitFieldsResolver'); +exports.ModalSubmitFields = require('./structures/ModalSubmitFields'); exports.NewsChannel = require('./structures/NewsChannel'); exports.OAuth2Guild = require('./structures/OAuth2Guild'); exports.PartialGroupDMChannel = require('./structures/PartialGroupDMChannel'); diff --git a/packages/discord.js/src/structures/ModalSubmitFieldsResolver.js b/packages/discord.js/src/structures/ModalSubmitFields.js similarity index 71% rename from packages/discord.js/src/structures/ModalSubmitFieldsResolver.js rename to packages/discord.js/src/structures/ModalSubmitFields.js index 6aa9529aa..8929d54ed 100644 --- a/packages/discord.js/src/structures/ModalSubmitFieldsResolver.js +++ b/packages/discord.js/src/structures/ModalSubmitFields.js @@ -7,17 +7,17 @@ const { TypeError } = require('../errors'); /** * Represents the serialized fields from a modal submit interaction */ -class ModalSubmitFieldsResolver { +class ModalSubmitFields { constructor(components) { /** * The components within the modal - * @type {Array>} The components in the modal + * @type {ActionRowModalData[]} The components in the modal */ this.components = components; /** * The extracted fields from the modal - * @type {Collection} The fields in the modal + * @type {Collection} The fields in the modal */ this.fields = components.reduce((accumulator, next) => { next.components.forEach(c => accumulator.set(c.customId, c)); @@ -28,11 +28,17 @@ class ModalSubmitFieldsResolver { /** * Gets a field given a custom id from a component * @param {string} customId The custom id of the component - * @returns {ModalFieldData} + * @param {ComponentType} [type] The type of the component + * @returns {ModalData} */ - getField(customId) { + getField(customId, type) { const field = this.fields.get(customId); if (!field) throw new TypeError('MODAL_SUBMIT_INTERACTION_FIELD_NOT_FOUND', customId); + + if (type !== undefined && type !== field.type) { + throw new TypeError('MODAL_SUBMIT_INTERACTION_FIELD_TYPE', customId, field.type, type); + } + return field; } @@ -42,13 +48,8 @@ class ModalSubmitFieldsResolver { * @returns {string} */ getTextInputValue(customId) { - const field = this.getField(customId); - const expectedType = ComponentType.TextInput; - if (field.type !== expectedType) { - throw new TypeError('MODAL_SUBMIT_INTERACTION_FIELD_TYPE', customId, field.type, expectedType); - } - return field.value; + return this.getField(customId, ComponentType.TextInput).value; } } -module.exports = ModalSubmitFieldsResolver; +module.exports = ModalSubmitFields; diff --git a/packages/discord.js/src/structures/ModalSubmitInteraction.js b/packages/discord.js/src/structures/ModalSubmitInteraction.js index 6192ff1e1..28a60d9f4 100644 --- a/packages/discord.js/src/structures/ModalSubmitInteraction.js +++ b/packages/discord.js/src/structures/ModalSubmitInteraction.js @@ -2,17 +2,22 @@ const Interaction = require('./Interaction'); const InteractionWebhook = require('./InteractionWebhook'); -const ModalSubmitFieldsResolver = require('./ModalSubmitFieldsResolver'); +const ModalSubmitFields = require('./ModalSubmitFields'); const InteractionResponses = require('./interfaces/InteractionResponses'); -const Components = require('../util/Components'); /** - * @typedef {Object} ModalFieldData + * @typedef {Object} ModalData * @property {string} value The value of the field * @property {ComponentType} type The component type of the field * @property {string} customId The custom id of the field */ +/** + * @typedef {Object} ActionRowModalData + * @property {ModalData[]} components The components of this action row + * @property {ComponentType} type The component type of the action row + */ + /** * Represents a modal interaction * @implements {InteractionResponses} @@ -38,15 +43,15 @@ class ModalSubmitInteraction extends Interaction { /** * The components within the modal - * @type {ActionRow[]} + * @type {ActionRowModalData[]} */ - this.components = data.data.components?.map(c => Components.createComponent(c)) ?? []; + this.components = data.data.components?.map(c => ModalSubmitInteraction.transformComponent(c)); /** * The fields within the modal - * @type {ModalSubmitFieldsResolver} + * @type {ModalSubmitFields} */ - this.fields = new ModalSubmitFieldsResolver(this.components); + this.fields = new ModalSubmitFields(this.components); /** * Whether the reply to this interaction has been deferred @@ -76,13 +81,14 @@ class ModalSubmitInteraction extends Interaction { /** * Transforms component data to discord.js-compatible data * @param {*} rawComponent The data to transform - * @returns {ModalFieldData[]} + * @returns {ModalData[]} */ static transformComponent(rawComponent) { return { value: rawComponent.value, type: rawComponent.type, customId: rawComponent.custom_id, + components: rawComponent.components?.map(c => this.transformComponent(c)), }; } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index eeaf9e0d0..2b565ff62 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -1852,11 +1852,29 @@ export class MessageReaction { public toJSON(): unknown; } -export class ModalSubmitFieldsResolver { +export interface BaseModalData { + customId: string; + type: ComponentType; +} + +export interface TextInputModalData extends BaseModalData { + type: ComponentType.TextInput; + value: string; +} + +export interface ActionRowModalData { + type: ComponentType.ActionRow; + components: ModalData[]; +} + +export type ModalData = TextInputModalData | ActionRowModalData; + +export class ModalSubmitFields { constructor(components: ModalActionRowComponent[][]); public components: ActionRow; public fields: Collection; - public getField(customId: string): ModalActionRowComponent; + public getField(customId: string, type: T): { type: T } & ModalData; + public getField(customId: string, type?: ComponentType): ModalData; public getTextInputValue(customId: string): string; } @@ -1877,8 +1895,8 @@ export interface ModalMessageModalSubmitInteraction extends Interaction { private constructor(client: Client, data: APIModalSubmitInteraction); public readonly customId: string; - public readonly components: ActionRow[]; - public readonly fields: ModalSubmitFieldsResolver; + public readonly components: ActionRowModalData[]; + public readonly fields: ModalSubmitFields; public deferred: boolean; public ephemeral: boolean | null; public message: GuildCacheMessage | null; @@ -4759,12 +4777,6 @@ export interface TextInputComponentData extends BaseComponentData { placeholder?: string; } -export interface ModalData { - customId: string; - title: string; - components: (ActionRow | ActionRowData)[]; -} - export type MessageTarget = | Interaction | InteractionWebhook