Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/discord.js/src/structures/CommandInteraction.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ class CommandInteraction extends BaseInteraction {
* @property {Collection<Snowflake, GuildMember|APIGuildMember>} [members] The resolved guild members
* @property {Collection<Snowflake, Role|APIRole>} [roles] The resolved roles
* @property {Collection<Snowflake, BaseChannel|APIChannel>} [channels] The resolved channels
* @property {Collection<Snowflake, Attachment>} [attachments] The resolved attachments
*/

/**
* Represents the resolved data of a received command interaction.
*
* @typedef {BaseInteractionResolvedData} CommandInteractionResolvedData
* @property {Collection<Snowflake, Message|APIMessage>} [messages] The resolved messages
* @property {Collection<Snowflake, Attachment>} [attachments] The resolved attachments
*/

/**
Expand Down
11 changes: 11 additions & 0 deletions packages/discord.js/src/structures/ModalComponentResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,17 @@ class ModalComponentResolver {

return null;
}

/**
* Gets file upload component
*
* @param {string} customId The custom id of the component
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
* @returns {?Collection<string, Attachment>} The uploaded files, or null if none were uploaded and not required
*/
getUploadedFiles(customId, required = false) {
return this._getTypedComponent(customId, [ComponentType.FileUpload], ['attachments'], required).attachments ?? null;
}
}

exports.ModalComponentResolver = ModalComponentResolver;
21 changes: 19 additions & 2 deletions packages/discord.js/src/structures/ModalSubmitInteraction.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { ModalComponentResolver } = require('./ModalComponentResolver.js');
const { InteractionResponses } = require('./interfaces/InteractionResponses.js');

const getMessage = lazy(() => require('./Message.js').Message);
const getAttachment = lazy(() => require('./Attachment.js').Attachment);

/**
* @typedef {Object} BaseModalData
Expand All @@ -26,6 +27,13 @@ const getMessage = lazy(() => require('./Message.js').Message);
* @property {Collection<string, BaseChannel|APIChannel>} [channels] The resolved channels
*/

/**
* @typedef {BaseModalData} FileUploadModalData
* @property {string} customId The custom id of the file upload
* @property {string[]} values The values of the file upload
* @property {Collection<string, Attachment>} [attachments] The resolved attachments
*/

/**
* @typedef {BaseModalData} TextInputModalData
* @property {string} customId The custom id of the component
Expand All @@ -37,7 +45,7 @@ const getMessage = lazy(() => require('./Message.js').Message);
*/

/**
* @typedef {SelectMenuModalData|TextInputModalData} ModalData
* @typedef {SelectMenuModalData|TextInputModalData|FileUploadModalData} ModalData
*/

/**
Expand Down Expand Up @@ -155,7 +163,7 @@ class ModalSubmitInteraction extends BaseInteraction {
if (rawComponent.values) {
data.values = rawComponent.values;
if (resolved) {
const { members, users, channels, roles } = resolved;
const { members, users, channels, roles, attachments } = resolved;
const valueSet = new Set(rawComponent.values);

if (users) {
Expand Down Expand Up @@ -198,6 +206,15 @@ class ModalSubmitInteraction extends BaseInteraction {
}
}
}

if (attachments) {
data.attachments = new Collection();
for (const [id, attachment] of Object.entries(attachments)) {
if (valueSet.has(id)) {
data.attachments.set(id, new (getAttachment())(attachment));
}
}
}
}
}

Expand Down
10 changes: 9 additions & 1 deletion packages/discord.js/src/util/Components.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const { ComponentType } = require('discord-api-types/v10');

/**
* @typedef {StringSelectMenuComponentData|TextInputComponentData|UserSelectMenuComponentData|
* RoleSelectMenuComponentData|MentionableSelectMenuComponentData|ChannelSelectMenuComponentData} ComponentInLabelData
* RoleSelectMenuComponentData|MentionableSelectMenuComponentData|ChannelSelectMenuComponentData|FileUploadComponentData} ComponentInLabelData
*/

/**
Expand All @@ -44,6 +44,14 @@ const { ComponentType } = require('discord-api-types/v10');
* @property {string} [url] The URL of the button
*/

/**
* @typedef {BaseComponentData} FileUploadComponentData
* @property {string} customId The custom id of the file upload
* @property {number} [minValues] The minimum number of files that can be uploaded (0-10)
* @property {number} [maxValues] The maximum number of files that can be uploaded (1-10)
* @property {boolean} [required] Whether this component is required in modals
*/

/**
* @typedef {BaseComponentData} BaseSelectMenuComponentData
* @property {string} customId The custom id of the select menu
Expand Down
19 changes: 17 additions & 2 deletions packages/discord.js/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2580,7 +2580,12 @@ export interface SelectMenuModalData<Cached extends CacheType = CacheType>
values: readonly string[];
}

export type ModalData = SelectMenuModalData | TextInputModalData;
export interface FileUploadModalData extends BaseModalData<ComponentType.FileUpload> {
customId: string;
files: readonly Attachment[];
}

export type ModalData = FileUploadModalData | SelectMenuModalData | TextInputModalData;

export interface LabelModalData extends BaseModalData<ComponentType.Label> {
component: readonly ModalData[];
Expand Down Expand Up @@ -2653,6 +2658,8 @@ export class ModalComponentResolver<Cached extends CacheType = CacheType> {

public getSelectedMentionables(customId: string, required: true): ModalSelectedMentionables<Cached>;
public getSelectedMentionables(customId: string, required?: boolean): ModalSelectedMentionables<Cached> | null;
public getUploadedFiles(customId: string, required: true): ReadonlyCollection<string, Attachment>;
public getUploadedFiles(customId: string, required?: boolean): ReadonlyCollection<string, Attachment> | null;
}

export interface ModalMessageModalSubmitInteraction<Cached extends CacheType = CacheType>
Expand Down Expand Up @@ -5621,6 +5628,7 @@ export interface CommandInteractionOption<Cached extends CacheType = CacheType>
}

export interface BaseInteractionResolvedData<Cached extends CacheType = CacheType> {
attachments?: ReadonlyCollection<Snowflake, Attachment>;
channels?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Channel, APIInteractionDataResolvedChannel>>;
members?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIInteractionDataResolvedGuildMember>>;
roles?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
Expand All @@ -5629,7 +5637,6 @@ export interface BaseInteractionResolvedData<Cached extends CacheType = CacheTyp

export interface CommandInteractionResolvedData<Cached extends CacheType = CacheType>
extends BaseInteractionResolvedData<Cached> {
attachments?: ReadonlyCollection<Snowflake, Attachment>;
messages?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Message, APIMessage>>;
}

Expand Down Expand Up @@ -6838,6 +6845,14 @@ export interface TextInputComponentData extends BaseComponentData {
value?: string;
}

export interface FileUploadComponentData extends BaseComponentData {
customId: string;
maxValues?: number;
minValues?: number;
required?: number;
type: ComponentType.FileUpload;
}

export type MessageTarget =
| ChannelManager
| Interaction
Expand Down