refactor: clean up modal submissions (#7994)

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
This commit is contained in:
Suneet Tipirneni
2022-06-04 02:57:19 -04:00
committed by GitHub
parent 68d5169f66
commit 643dab3b1b
4 changed files with 50 additions and 31 deletions

View File

@@ -131,7 +131,7 @@ 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.ModalSubmitInteraction = require('./structures/ModalSubmitInteraction'); exports.ModalSubmitInteraction = require('./structures/ModalSubmitInteraction');
exports.ModalSubmitFieldsResolver = require('./structures/ModalSubmitFieldsResolver'); exports.ModalSubmitFields = require('./structures/ModalSubmitFields');
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');

View File

@@ -7,17 +7,17 @@ const { TypeError } = require('../errors');
/** /**
* Represents the serialized fields from a modal submit interaction * Represents the serialized fields from a modal submit interaction
*/ */
class ModalSubmitFieldsResolver { class ModalSubmitFields {
constructor(components) { constructor(components) {
/** /**
* The components within the modal * The components within the modal
* @type {Array<ActionRow<ModalFieldData>>} The components in the modal * @type {ActionRowModalData[]} The components in the modal
*/ */
this.components = components; this.components = components;
/** /**
* The extracted fields from the modal * The extracted fields from the modal
* @type {Collection<string, ModalFieldData>} The fields in the modal * @type {Collection<string, ModalData>} The fields in the modal
*/ */
this.fields = components.reduce((accumulator, next) => { this.fields = components.reduce((accumulator, next) => {
next.components.forEach(c => accumulator.set(c.customId, c)); 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 * Gets a field given a custom id from a component
* @param {string} customId The custom id of the 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); const field = this.fields.get(customId);
if (!field) throw new TypeError('MODAL_SUBMIT_INTERACTION_FIELD_NOT_FOUND', 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; return field;
} }
@@ -42,13 +48,8 @@ class ModalSubmitFieldsResolver {
* @returns {string} * @returns {string}
*/ */
getTextInputValue(customId) { getTextInputValue(customId) {
const field = this.getField(customId); return this.getField(customId, ComponentType.TextInput).value;
const expectedType = ComponentType.TextInput;
if (field.type !== expectedType) {
throw new TypeError('MODAL_SUBMIT_INTERACTION_FIELD_TYPE', customId, field.type, expectedType);
}
return field.value;
} }
} }
module.exports = ModalSubmitFieldsResolver; module.exports = ModalSubmitFields;

View File

@@ -2,17 +2,22 @@
const Interaction = require('./Interaction'); const Interaction = require('./Interaction');
const InteractionWebhook = require('./InteractionWebhook'); const InteractionWebhook = require('./InteractionWebhook');
const ModalSubmitFieldsResolver = require('./ModalSubmitFieldsResolver'); const ModalSubmitFields = require('./ModalSubmitFields');
const InteractionResponses = require('./interfaces/InteractionResponses'); 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 {string} value The value of the field
* @property {ComponentType} type The component type of the field * @property {ComponentType} type The component type of the field
* @property {string} customId The custom id 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 * Represents a modal interaction
* @implements {InteractionResponses} * @implements {InteractionResponses}
@@ -38,15 +43,15 @@ class ModalSubmitInteraction extends Interaction {
/** /**
* The components within the modal * 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 * 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 * 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 * Transforms component data to discord.js-compatible data
* @param {*} rawComponent The data to transform * @param {*} rawComponent The data to transform
* @returns {ModalFieldData[]} * @returns {ModalData[]}
*/ */
static transformComponent(rawComponent) { static transformComponent(rawComponent) {
return { return {
value: rawComponent.value, value: rawComponent.value,
type: rawComponent.type, type: rawComponent.type,
customId: rawComponent.custom_id, customId: rawComponent.custom_id,
components: rawComponent.components?.map(c => this.transformComponent(c)),
}; };
} }

View File

@@ -1852,11 +1852,29 @@ export class MessageReaction {
public toJSON(): unknown; 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[][]); constructor(components: ModalActionRowComponent[][]);
public components: ActionRow<ModalActionRowComponent>; public components: ActionRow<ModalActionRowComponent>;
public fields: Collection<string, ModalActionRowComponent>; public fields: Collection<string, ModalActionRowComponent>;
public getField(customId: string): ModalActionRowComponent; public getField<T extends ComponentType>(customId: string, type: T): { type: T } & ModalData;
public getField(customId: string, type?: ComponentType): ModalData;
public getTextInputValue(customId: string): string; public getTextInputValue(customId: string): string;
} }
@@ -1877,8 +1895,8 @@ export interface ModalMessageModalSubmitInteraction<Cached extends CacheType = C
export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extends Interaction<Cached> { export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extends Interaction<Cached> {
private constructor(client: Client, data: APIModalSubmitInteraction); private constructor(client: Client, data: APIModalSubmitInteraction);
public readonly customId: string; public readonly customId: string;
public readonly components: ActionRow<ModalActionRowComponent>[]; public readonly components: ActionRowModalData[];
public readonly fields: ModalSubmitFieldsResolver; public readonly fields: ModalSubmitFields;
public deferred: boolean; public deferred: boolean;
public ephemeral: boolean | null; public ephemeral: boolean | null;
public message: GuildCacheMessage<Cached> | null; public message: GuildCacheMessage<Cached> | null;
@@ -4759,12 +4777,6 @@ export interface TextInputComponentData extends BaseComponentData {
placeholder?: string; placeholder?: string;
} }
export interface ModalData {
customId: string;
title: string;
components: (ActionRow<ModalActionRowComponent> | ActionRowData<ModalActionRowComponentData>)[];
}
export type MessageTarget = export type MessageTarget =
| Interaction | Interaction
| InteractionWebhook | InteractionWebhook