Skip to content

Commit

Permalink
feat(ApplicationCommand): add support for channel_types (#6640)
Browse files Browse the repository at this point in the history
Co-authored-by: Tiemen <ThaTiemsz@users.noreply.github.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
  • Loading branch information
3 people committed Sep 27, 2021
1 parent 8426770 commit 3b14883
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 7 deletions.
28 changes: 26 additions & 2 deletions src/structures/ApplicationCommand.js
Expand Up @@ -2,7 +2,7 @@

const Base = require('./Base');
const ApplicationCommandPermissionsManager = require('../managers/ApplicationCommandPermissionsManager');
const { ApplicationCommandOptionTypes, ApplicationCommandTypes } = require('../util/Constants');
const { ApplicationCommandOptionTypes, ApplicationCommandTypes, ChannelTypes } = require('../util/Constants');
const SnowflakeUtil = require('../util/SnowflakeUtil');

/**
Expand Down Expand Up @@ -131,6 +131,12 @@ class ApplicationCommand extends Base {
* @property {boolean} [required] Whether the option is required
* @property {ApplicationCommandOptionChoice[]} [choices] The choices of the option for the user to pick from
* @property {ApplicationCommandOptionData[]} [options] Additional options if this option is a subcommand (group)
* @property {ChannelType[]|number[]} [channelTypes] When the option type is channel,
* the allowed types of channels that can be selected
* @property {number[]} [channel_types] When the option type is channel,
* the API data for allowed types of channels that can be selected
* <warn>This is provided for compatibility with something like `@discordjs/builders`
* and will be discarded when `channelTypes` is present</warn>
*/

/**
Expand Down Expand Up @@ -239,7 +245,8 @@ class ApplicationCommand extends Base {
(option.required ?? (['SUB_COMMAND', 'SUB_COMMAND_GROUP'].includes(optionType) ? undefined : false)) !==
existing.required ||
option.choices?.length !== existing.choices?.length ||
option.options?.length !== existing.options?.length
option.options?.length !== existing.options?.length ||
(option.channelTypes ?? option.channel_types)?.length !== existing.channelTypes?.length
) {
return false;
}
Expand All @@ -262,6 +269,15 @@ class ApplicationCommand extends Base {
}
}

if (existing.channelTypes) {
const newTypes = (option.channelTypes ?? option.channel_types).map(type =>
typeof type === 'number' ? ChannelTypes[type] : type,
);
for (const type of existing.channelTypes) {
if (!newTypes.includes(type)) return false;
}
}

if (existing.options) {
return this.optionsEqual(existing.options, option.options, enforceOptionOrder);
}
Expand All @@ -277,6 +293,8 @@ class ApplicationCommand extends Base {
* @property {boolean} [required] Whether the option is required
* @property {ApplicationCommandOptionChoice[]} [choices] The choices of the option for the user to pick from
* @property {ApplicationCommandOption[]} [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
*/

/**
Expand All @@ -295,6 +313,7 @@ class ApplicationCommand extends Base {
*/
static transformOption(option, received) {
const stringType = typeof option.type === 'string' ? option.type : ApplicationCommandOptionTypes[option.type];
const channelTypesKey = received ? 'channelTypes' : 'channel_types';
return {
type: typeof option.type === 'number' && !received ? option.type : ApplicationCommandOptionTypes[option.type],
name: option.name,
Expand All @@ -303,6 +322,11 @@ class ApplicationCommand extends Base {
option.required ?? (stringType === 'SUB_COMMAND' || stringType === 'SUB_COMMAND_GROUP' ? undefined : false),
choices: option.choices,
options: option.options?.map(o => this.transformOption(o, received)),
[channelTypesKey]: received
? option.channel_types?.map(type => ChannelTypes[type])
: option.channelTypes?.map(type => (typeof type === 'string' ? ChannelTypes[type] : type)) ??
// When transforming to API data, accept API data
option.channel_types,
};
}
}
Expand Down
45 changes: 40 additions & 5 deletions typings/index.d.ts
Expand Up @@ -3032,6 +3032,8 @@ export interface BaseApplicationCommandData {

export type CommandOptionDataTypeResolvable = ApplicationCommandOptionType | ApplicationCommandOptionTypes;

export type CommandOptionChannelResolvableType = ApplicationCommandOptionTypes.CHANNEL | 'CHANNEL';

export type CommandOptionChoiceResolvableType =
| ApplicationCommandOptionTypes.NUMBER
| 'NUMBER'
Expand All @@ -3048,7 +3050,7 @@ export type CommandOptionSubOptionResolvableType =

export type CommandOptionNonChoiceResolvableType = Exclude<
CommandOptionDataTypeResolvable,
CommandOptionChoiceResolvableType | CommandOptionSubOptionResolvableType
CommandOptionChoiceResolvableType | CommandOptionSubOptionResolvableType | CommandOptionChannelResolvableType
>;

export interface BaseApplicationCommandOptionsData {
Expand Down Expand Up @@ -3076,35 +3078,68 @@ export type ApplicationCommandData =
| MessageApplicationCommandData
| ChatInputApplicationCommandData;

export interface ApplicationCommandChannelOptionData extends BaseApplicationCommandOptionsData {
type: CommandOptionChannelResolvableType;
channelTypes?: (keyof typeof ChannelTypes | ChannelTypes)[];
channel_types?: ChannelTypes[];
}

export interface ApplicationCommandChannelOption extends BaseApplicationCommandOptionsData {
type: 'CHANNEL';
channelTypes?: (keyof typeof ChannelTypes)[];
}

export interface ApplicationCommandChoicesData extends BaseApplicationCommandOptionsData {
type: CommandOptionChoiceResolvableType;
choices?: ApplicationCommandOptionChoice[];
}

export interface ApplicationCommandChoicesOption extends BaseApplicationCommandOptionsData {
type: Exclude<CommandOptionChoiceResolvableType, ApplicationCommandOptionTypes>;
choices?: ApplicationCommandOptionChoice[];
}

export interface ApplicationCommandSubGroupData extends BaseApplicationCommandOptionsData {
type: 'SUB_COMMAND_GROUP' | ApplicationCommandOptionTypes.SUB_COMMAND_GROUP;
options?: ApplicationCommandSubCommandData[];
}

export interface ApplicationCommandSubGroup extends BaseApplicationCommandOptionsData {
type: 'SUB_COMMAND_GROUP';
options?: ApplicationCommandSubCommand[];
}

export interface ApplicationCommandSubCommandData extends BaseApplicationCommandOptionsData {
type: 'SUB_COMMAND' | ApplicationCommandOptionTypes.SUB_COMMAND;
options?: (ApplicationCommandChoicesData | ApplicationCommandNonOptionsData)[];
}

export interface ApplicationCommandSubCommand extends BaseApplicationCommandOptionsData {
type: 'SUB_COMMAND';
options?: (ApplicationCommandChoicesOption | ApplicationCommandNonOptions)[];
}

export interface ApplicationCommandNonOptionsData extends BaseApplicationCommandOptionsData {
type: CommandOptionNonChoiceResolvableType;
}

export interface ApplicationCommandNonOptions extends BaseApplicationCommandOptionsData {
type: Exclude<CommandOptionNonChoiceResolvableType, ApplicationCommandOptionTypes>;
}

export type ApplicationCommandOptionData =
| ApplicationCommandSubGroupData
| ApplicationCommandNonOptionsData
| ApplicationCommandChannelOptionData
| ApplicationCommandChoicesData
| ApplicationCommandSubCommandData;

export type ApplicationCommandOption = ApplicationCommandOptionData & {
type: ApplicationCommandOptionType;
options?: ApplicationCommandOption[];
};
export type ApplicationCommandOption =
| ApplicationCommandSubGroup
| ApplicationCommandNonOptions
| ApplicationCommandChannelOption
| ApplicationCommandChoicesOption
| ApplicationCommandSubCommand;

export interface ApplicationCommandOptionChoice {
name: string;
Expand Down

0 comments on commit 3b14883

Please sign in to comment.