feat: file types for discord.js (#11580)

* feat: file types

* fix(ApplicationCommandNonOptions): make it actually work
This commit is contained in:
Jiralite
2026-07-19 22:35:39 +00:00
committed by GitHub
parent c21f0af7db
commit c35a06663e
5 changed files with 77 additions and 2 deletions
@@ -276,6 +276,9 @@ class ApplicationCommand extends Base {
* @property {ApplicationCommandOptionData[]} [options] Additional options if this option is a subcommand (group)
* @property {ChannelType[]} [channelTypes] When the option type is channel,
* the allowed types of channels that can be selected
* @property {FileUploadType[]} [fileTypes] When the option type is attachment,
* the allowed types of files that can be uploaded. When only using extensions, include `.jpg`
* for images and both `.mp4` and `.mov` for videos for mobile compatibility
* @property {number} [minValue] The minimum value for an {@link ApplicationCommandOptionType.Integer} or
* {@link ApplicationCommandOptionType.Number} option
* @property {number} [maxValue] The maximum value for an {@link ApplicationCommandOptionType.Integer} or
@@ -509,6 +512,7 @@ class ApplicationCommand extends Base {
option.choices?.length !== existing.choices?.length ||
option.options?.length !== existing.options?.length ||
(option.channelTypes ?? option.channel_types)?.length !== existing.channelTypes?.length ||
(option.fileTypes ?? option.file_types)?.length !== existing.fileTypes?.length ||
(option.minValue ?? option.min_value) !== existing.minValue ||
(option.maxValue ?? option.max_value) !== existing.maxValue ||
(option.minLength ?? option.min_length) !== existing.minLength ||
@@ -554,6 +558,13 @@ class ApplicationCommand extends Base {
}
}
if (existing.fileTypes) {
const newTypes = option.fileTypes ?? option.file_types;
for (const type of existing.fileTypes) {
if (!newTypes.includes(type)) return false;
}
}
if (existing.options) {
return this.optionsEqual(existing.options, option.options, enforceOptionOrder);
}
@@ -580,6 +591,9 @@ class ApplicationCommand extends Base {
* @property {ApplicationCommandOption[]} [options] Additional options if this option is a subcommand (group)
* @property {ApplicationCommandOptionAllowedChannelType[]} [channelTypes] When the option type is channel,
* the allowed types of channels that can be selected
* @property {FileUploadType[]} [fileTypes] When the option type is attachment,
* the allowed types of files that can be uploaded. When only using extensions, include `.jpg`
* for images and both `.mp4` and `.mov` for videos for mobile compatibility
* @property {number} [minValue] The minimum value for an {@link ApplicationCommandOptionType.Integer} or
* {@link ApplicationCommandOptionType.Number} option
* @property {number} [maxValue] The maximum value for an {@link ApplicationCommandOptionType.Integer} or
@@ -610,6 +624,7 @@ class ApplicationCommand extends Base {
*/
static transformOption(option, received) {
const channelTypesKey = received ? 'channelTypes' : 'channel_types';
const fileTypesKey = received ? 'fileTypes' : 'file_types';
const minValueKey = received ? 'minValue' : 'min_value';
const maxValueKey = received ? 'maxValue' : 'max_value';
const minLengthKey = received ? 'minLength' : 'min_length';
@@ -641,6 +656,7 @@ class ApplicationCommand extends Base {
})),
options: option.options?.map(opt => this.transformOption(opt, received)),
[channelTypesKey]: option.channelTypes ?? option.channel_types,
[fileTypesKey]: option.fileTypes ?? option.file_types,
[minValueKey]: option.minValue ?? option.min_value,
[maxValueKey]: option.maxValue ?? option.max_value,
[minLengthKey]: option.minLength ?? option.min_length,
+5
View File
@@ -380,6 +380,11 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/EntryPointCommandHandlerType}
*/
/**
* @external FileUploadType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#FileUploadType}
*/
/**
* @external ForumLayoutType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ForumLayoutType}
@@ -78,6 +78,8 @@ const getUserSelectMenuComponent = lazy(
* @property {string} customId The custom id of the file upload
* @property {number} [minValues] The minimum number of files that must be uploaded (0-10)
* @property {number} [maxValues] The maximum number of files that can be uploaded (1-10)
* @property {FileUploadType[]} [fileTypes] The allowed types of files that can be uploaded (maximum of 10).
* When only using extensions, include `.jpg` for images and both `.mp4` and `.mov` for videos for mobile compatibility
* @property {boolean} [required] Whether this component is required in modals
*/
+12 -2
View File
@@ -127,6 +127,7 @@ import {
EmbedType,
EntitlementType,
EntryPointCommandHandlerType,
FileUploadType,
FormattingPatterns,
ForumLayoutType,
GatewayActivity,
@@ -5120,7 +5121,14 @@ export interface ApplicationCommandMentionableOption extends BaseApplicationComm
type: ApplicationCommandOptionType.Mentionable;
}
export interface ApplicationCommandAttachmentOptionData extends BaseApplicationCommandOptionsData {
fileTypes?: readonly FileUploadType[];
file_types?: readonly FileUploadType[];
type: ApplicationCommandOptionType.Attachment;
}
export interface ApplicationCommandAttachmentOption extends BaseApplicationCommandOptionsData {
fileTypes?: readonly FileUploadType[];
type: ApplicationCommandOptionType.Attachment;
}
@@ -5232,14 +5240,15 @@ export interface ApplicationCommandSubCommand extends CommonBaseApplicationComma
}
export interface ApplicationCommandNonOptionsData extends BaseApplicationCommandOptionsData {
type: CommandOptionNonChoiceResolvableType;
type: Exclude<CommandOptionNonChoiceResolvableType, ApplicationCommandOptionType.Attachment>;
}
export interface ApplicationCommandNonOptions extends BaseApplicationCommandOptionsData {
type: Exclude<CommandOptionNonChoiceResolvableType, ApplicationCommandOptionType>;
type: Exclude<CommandOptionNonChoiceResolvableType, ApplicationCommandOptionType.Attachment>;
}
export type ApplicationCommandOptionData =
| ApplicationCommandAttachmentOptionData
| ApplicationCommandAutocompleteNumericOptionData
| ApplicationCommandAutocompleteStringOptionData
| ApplicationCommandBooleanOptionData
@@ -6943,6 +6952,7 @@ export interface TextInputComponentData extends BaseComponentData {
export interface FileUploadComponentData extends BaseComponentData {
customId: string;
fileTypes?: readonly FileUploadType[];
maxValues?: number;
minValues?: number;
required?: boolean;
@@ -62,6 +62,8 @@ import type {
AnnouncementChannel,
AnyThreadChannel,
ApplicationCommand,
ApplicationCommandAttachmentOption,
ApplicationCommandAttachmentOptionData,
ApplicationCommandChannelOption,
ApplicationCommandChannelOptionData,
ApplicationCommandChoicesData,
@@ -116,6 +118,7 @@ import type {
FetchedThreadsMore,
FetchPinnedMessagesResponse,
FileComponentData,
FileUploadComponentData,
ForumChannel,
Guild,
GuildApplicationCommandManager,
@@ -1668,6 +1671,21 @@ declare const applicationCommandChannelOption: ApplicationCommandChannelOption;
applicationCommandChannelOption.channelTypes = [] as const;
}
declare const applicationCommandAttachmentOptionData: ApplicationCommandAttachmentOptionData;
declare const applicationCommandAttachmentOption: ApplicationCommandAttachmentOption;
{
applicationCommandAttachmentOptionData.fileTypes = ['image', '.pdf'] as const;
applicationCommandAttachmentOptionData.file_types = ['video', '.mov'] as const;
applicationCommandAttachmentOption.fileTypes = ['audio', '.flac'] as const;
expectNotAssignable<ApplicationCommandOptionData>({
description: 'Upload a file',
fileTypes: ['pdf'],
name: 'file',
type: ApplicationCommandOptionType.Attachment,
});
}
declare const applicationNonChoiceOptionData: ApplicationCommandOptionData & {
type: CommandOptionNonChoiceResolvableType;
};
@@ -2601,6 +2619,15 @@ await chatInputInteraction.showModal({
type: ComponentType.Label,
label: 'yo',
},
{
component: {
type: ComponentType.FileUpload,
custom_id: 'upload',
file_types: ['image', '.pdf'],
},
type: ComponentType.Label,
label: 'upload',
},
],
});
@@ -2642,9 +2669,24 @@ await chatInputInteraction.showModal({
},
label: 'cc',
},
{
type: ComponentType.Label,
component: {
type: ComponentType.FileUpload,
customId: 'upload',
fileTypes: ['video', '.mp4', '.mov'],
},
label: 'upload',
},
],
});
expectNotAssignable<FileUploadComponentData>({
customId: 'upload',
fileTypes: ['pdf'],
type: ComponentType.FileUpload,
});
declare const stringSelectMenuComp: StringSelectMenuComponent;
new StringSelectMenuBuilder(stringSelectMenuComp.toJSON());