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.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');

View File

@@ -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<ActionRow<ModalFieldData>>} The components in the modal
* @type {ActionRowModalData[]} The components in the modal
*/
this.components = components;
/**
* 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) => {
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;

View File

@@ -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)),
};
}

View File

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