refactor: Better Command Terminology (#7197)

This commit is contained in:
Suneet Tipirneni
2022-01-07 18:47:41 -05:00
committed by GitHub
parent 5022b14da0
commit b7856e7809
11 changed files with 297 additions and 292 deletions

View File

@@ -5,9 +5,9 @@ const Action = require('./Action');
const AutocompleteInteraction = require('../../structures/AutocompleteInteraction');
const ButtonInteraction = require('../../structures/ButtonInteraction');
const CommandInteraction = require('../../structures/CommandInteraction');
const MessageContextMenuInteraction = require('../../structures/MessageContextMenuInteraction');
const MessageContextMenuCommandInteraction = require('../../structures/MessageContextMenuCommandInteraction');
const SelectMenuInteraction = require('../../structures/SelectMenuInteraction');
const UserContextMenuInteraction = require('../../structures/UserContextMenuInteraction');
const UserContextMenuCommandInteraction = require('../../structures/UserContextMenuCommandInteraction');
const { Events, InteractionTypes, MessageComponentTypes, ApplicationCommandTypes } = require('../../util/Constants');
let deprecationEmitted = false;
@@ -27,10 +27,10 @@ class InteractionCreateAction extends Action {
InteractionType = CommandInteraction;
break;
case ApplicationCommandTypes.USER:
InteractionType = UserContextMenuInteraction;
InteractionType = UserContextMenuCommandInteraction;
break;
case ApplicationCommandTypes.MESSAGE:
InteractionType = MessageContextMenuInteraction;
InteractionType = MessageContextMenuCommandInteraction;
break;
default:
client.emit(

View File

@@ -73,7 +73,6 @@ exports.Application = require('./structures/interfaces/Application');
exports.ApplicationCommand = require('./structures/ApplicationCommand');
exports.AutocompleteInteraction = require('./structures/AutocompleteInteraction');
exports.Base = require('./structures/Base');
exports.BaseCommandInteraction = require('./structures/BaseCommandInteraction');
exports.BaseGuild = require('./structures/BaseGuild');
exports.BaseGuildEmoji = require('./structures/BaseGuildEmoji');
exports.BaseGuildTextChannel = require('./structures/BaseGuildTextChannel');
@@ -82,13 +81,14 @@ exports.BaseMessageComponent = require('./structures/BaseMessageComponent');
exports.ButtonInteraction = require('./structures/ButtonInteraction');
exports.CategoryChannel = require('./structures/CategoryChannel');
exports.Channel = require('./structures/Channel').Channel;
exports.ChatInputCommandInteraction = require('./structures/ChatInputCommandInteraction');
exports.ClientApplication = require('./structures/ClientApplication');
exports.ClientPresence = require('./structures/ClientPresence');
exports.ClientUser = require('./structures/ClientUser');
exports.Collector = require('./structures/interfaces/Collector');
exports.CommandInteraction = require('./structures/CommandInteraction');
exports.Collector = require('./structures/interfaces/Collector');
exports.CommandInteractionOptionResolver = require('./structures/CommandInteractionOptionResolver');
exports.ContextMenuInteraction = require('./structures/ContextMenuInteraction');
exports.ContextMenuCommandInteraction = require('./structures/ContextMenuCommandInteraction');
exports.DMChannel = require('./structures/DMChannel');
exports.Emoji = require('./structures/Emoji').Emoji;
exports.Guild = require('./structures/Guild').Guild;
@@ -116,7 +116,7 @@ exports.MessageAttachment = require('./structures/MessageAttachment');
exports.MessageButton = require('./structures/MessageButton');
exports.MessageCollector = require('./structures/MessageCollector');
exports.MessageComponentInteraction = require('./structures/MessageComponentInteraction');
exports.MessageContextMenuInteraction = require('./structures/MessageContextMenuInteraction');
exports.MessageContextMenuCommandInteraction = require('./structures/MessageContextMenuCommandInteraction');
exports.MessageEmbed = require('./structures/MessageEmbed');
exports.MessageMentions = require('./structures/MessageMentions');
exports.MessagePayload = require('./structures/MessagePayload');
@@ -144,7 +144,7 @@ exports.ThreadChannel = require('./structures/ThreadChannel');
exports.ThreadMember = require('./structures/ThreadMember');
exports.Typing = require('./structures/Typing');
exports.User = require('./structures/User');
exports.UserContextMenuInteraction = require('./structures/UserContextMenuInteraction');
exports.UserContextMenuCommandInteraction = require('./structures/UserContextMenuCommandInteraction');
exports.VoiceChannel = require('./structures/VoiceChannel');
exports.VoiceRegion = require('./structures/VoiceRegion');
exports.VoiceState = require('./structures/VoiceState');

View File

@@ -1,195 +0,0 @@
'use strict';
const { Collection } = require('@discordjs/collection');
const Interaction = require('./Interaction');
const InteractionWebhook = require('./InteractionWebhook');
const InteractionResponses = require('./interfaces/InteractionResponses');
const { ApplicationCommandOptionTypes } = require('../util/Constants');
/**
* Represents a command interaction.
* @extends {Interaction}
* @implements {InteractionResponses}
* @abstract
*/
class BaseCommandInteraction extends Interaction {
constructor(client, data) {
super(client, data);
/**
* The id of the channel this interaction was sent in
* @type {Snowflake}
* @name BaseCommandInteraction#channelId
*/
/**
* The invoked application command's id
* @type {Snowflake}
*/
this.commandId = data.data.id;
/**
* The invoked application command's name
* @type {string}
*/
this.commandName = data.data.name;
/**
* Whether the reply to this interaction has been deferred
* @type {boolean}
*/
this.deferred = false;
/**
* Whether this interaction has already been replied to
* @type {boolean}
*/
this.replied = false;
/**
* Whether the reply to this interaction is ephemeral
* @type {?boolean}
*/
this.ephemeral = null;
/**
* An associated interaction webhook, can be used to further interact with this interaction
* @type {InteractionWebhook}
*/
this.webhook = new InteractionWebhook(this.client, this.applicationId, this.token);
}
/**
* The invoked application command, if it was fetched before
* @type {?ApplicationCommand}
*/
get command() {
const id = this.commandId;
return this.guild?.commands.cache.get(id) ?? this.client.application.commands.cache.get(id) ?? null;
}
/**
* Represents the resolved data of a received command interaction.
* @typedef {Object} CommandInteractionResolvedData
* @property {Collection<Snowflake, User>} [users] The resolved users
* @property {Collection<Snowflake, GuildMember|APIGuildMember>} [members] The resolved guild members
* @property {Collection<Snowflake, Role|APIRole>} [roles] The resolved roles
* @property {Collection<Snowflake, Channel|APIChannel>} [channels] The resolved channels
* @property {Collection<Snowflake, Message|APIMessage>} [messages] The resolved messages
*/
/**
* Transforms the resolved received from the API.
* @param {APIInteractionDataResolved} resolved The received resolved objects
* @returns {CommandInteractionResolvedData}
* @private
*/
transformResolved({ members, users, channels, roles, messages }) {
const result = {};
if (members) {
result.members = new Collection();
for (const [id, member] of Object.entries(members)) {
const user = users[id];
result.members.set(id, this.guild?.members._add({ user, ...member }) ?? member);
}
}
if (users) {
result.users = new Collection();
for (const user of Object.values(users)) {
result.users.set(user.id, this.client.users._add(user));
}
}
if (roles) {
result.roles = new Collection();
for (const role of Object.values(roles)) {
result.roles.set(role.id, this.guild?.roles._add(role) ?? role);
}
}
if (channels) {
result.channels = new Collection();
for (const channel of Object.values(channels)) {
result.channels.set(channel.id, this.client.channels._add(channel, this.guild) ?? channel);
}
}
if (messages) {
result.messages = new Collection();
for (const message of Object.values(messages)) {
result.messages.set(message.id, this.channel?.messages?._add(message) ?? message);
}
}
return result;
}
/**
* Represents an option of a received command interaction.
* @typedef {Object} CommandInteractionOption
* @property {string} name The name of the option
* @property {ApplicationCommandOptionType} type The type of the option
* @property {boolean} [autocomplete] Whether the option is an autocomplete option
* @property {string|number|boolean} [value] The value of the option
* @property {CommandInteractionOption[]} [options] Additional options if this option is a
* subcommand (group)
* @property {User} [user] The resolved user
* @property {GuildMember|APIGuildMember} [member] The resolved member
* @property {GuildChannel|ThreadChannel|APIChannel} [channel] The resolved channel
* @property {Role|APIRole} [role] The resolved role
*/
/**
* Transforms an option received from the API.
* @param {APIApplicationCommandOption} option The received option
* @param {APIInteractionDataResolved} resolved The resolved interaction data
* @returns {CommandInteractionOption}
* @private
*/
transformOption(option, resolved) {
const result = {
name: option.name,
type: ApplicationCommandOptionTypes[option.type],
};
if ('value' in option) result.value = option.value;
if ('options' in option) result.options = option.options.map(opt => this.transformOption(opt, resolved));
if (resolved) {
const user = resolved.users?.[option.value];
if (user) result.user = this.client.users._add(user);
const member = resolved.members?.[option.value];
if (member) result.member = this.guild?.members._add({ user, ...member }) ?? member;
const channel = resolved.channels?.[option.value];
if (channel) result.channel = this.client.channels._add(channel, this.guild) ?? channel;
const role = resolved.roles?.[option.value];
if (role) result.role = this.guild?.roles._add(role) ?? role;
}
return result;
}
// These are here only for documentation purposes - they are implemented by InteractionResponses
/* eslint-disable no-empty-function */
deferReply() {}
reply() {}
fetchReply() {}
editReply() {}
deleteReply() {}
followUp() {}
}
InteractionResponses.applyToClass(BaseCommandInteraction, ['deferUpdate', 'update']);
module.exports = BaseCommandInteraction;
/* eslint-disable max-len */
/**
* @external APIInteractionDataResolved
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-resolved-data-structure}
*/

View File

@@ -0,0 +1,41 @@
'use strict';
const CommandInteraction = require('./CommandInteraction');
const CommandInteractionOptionResolver = require('./CommandInteractionOptionResolver');
/**
* Represents a command interaction.
* @extends {BaseCommandInteraction}
*/
class ChatInputCommandInteraction extends CommandInteraction {
constructor(client, data) {
super(client, data);
/**
* The options passed to the command.
* @type {CommandInteractionOptionResolver}
*/
this.options = new CommandInteractionOptionResolver(
this.client,
data.data.options?.map(option => this.transformOption(option, data.data.resolved)) ?? [],
this.transformResolved(data.data.resolved ?? {}),
);
}
/**
* Returns a string representation of the command interaction.
* This can then be copied by a user and executed again in a new command while keeping the option order.
* @returns {string}
*/
toString() {
const properties = [
this.commandName,
this.options._group,
this.options._subcommand,
...this.options._hoistedOptions.map(o => `${o.name}:${o.value}`),
];
return `/${properties.filter(Boolean).join(' ')}`;
}
}
module.exports = ChatInputCommandInteraction;

View File

@@ -1,41 +1,195 @@
'use strict';
const BaseCommandInteraction = require('./BaseCommandInteraction');
const CommandInteractionOptionResolver = require('./CommandInteractionOptionResolver');
const { Collection } = require('@discordjs/collection');
const Interaction = require('./Interaction');
const InteractionWebhook = require('./InteractionWebhook');
const InteractionResponses = require('./interfaces/InteractionResponses');
const { ApplicationCommandOptionTypes } = require('../util/Constants');
/**
* Represents a command interaction.
* @extends {BaseCommandInteraction}
* @extends {Interaction}
* @implements {InteractionResponses}
* @abstract
*/
class CommandInteraction extends BaseCommandInteraction {
class CommandInteraction extends Interaction {
constructor(client, data) {
super(client, data);
/**
* The options passed to the command.
* @type {CommandInteractionOptionResolver}
* The id of the channel this interaction was sent in
* @type {Snowflake}
* @name BaseCommandInteraction#channelId
*/
this.options = new CommandInteractionOptionResolver(
this.client,
data.data.options?.map(option => this.transformOption(option, data.data.resolved)) ?? [],
this.transformResolved(data.data.resolved ?? {}),
);
/**
* The invoked application command's id
* @type {Snowflake}
*/
this.commandId = data.data.id;
/**
* The invoked application command's name
* @type {string}
*/
this.commandName = data.data.name;
/**
* Whether the reply to this interaction has been deferred
* @type {boolean}
*/
this.deferred = false;
/**
* Whether this interaction has already been replied to
* @type {boolean}
*/
this.replied = false;
/**
* Whether the reply to this interaction is ephemeral
* @type {?boolean}
*/
this.ephemeral = null;
/**
* An associated interaction webhook, can be used to further interact with this interaction
* @type {InteractionWebhook}
*/
this.webhook = new InteractionWebhook(this.client, this.applicationId, this.token);
}
/**
* Returns a string representation of the command interaction.
* This can then be copied by a user and executed again in a new command while keeping the option order.
* @returns {string}
* The invoked application command, if it was fetched before
* @type {?ApplicationCommand}
*/
toString() {
const properties = [
this.commandName,
this.options._group,
this.options._subcommand,
...this.options._hoistedOptions.map(o => `${o.name}:${o.value}`),
];
return `/${properties.filter(Boolean).join(' ')}`;
get command() {
const id = this.commandId;
return this.guild?.commands.cache.get(id) ?? this.client.application.commands.cache.get(id) ?? null;
}
/**
* Represents the resolved data of a received command interaction.
* @typedef {Object} CommandInteractionResolvedData
* @property {Collection<Snowflake, User>} [users] The resolved users
* @property {Collection<Snowflake, GuildMember|APIGuildMember>} [members] The resolved guild members
* @property {Collection<Snowflake, Role|APIRole>} [roles] The resolved roles
* @property {Collection<Snowflake, Channel|APIChannel>} [channels] The resolved channels
* @property {Collection<Snowflake, Message|APIMessage>} [messages] The resolved messages
*/
/**
* Transforms the resolved received from the API.
* @param {APIInteractionDataResolved} resolved The received resolved objects
* @returns {CommandInteractionResolvedData}
* @private
*/
transformResolved({ members, users, channels, roles, messages }) {
const result = {};
if (members) {
result.members = new Collection();
for (const [id, member] of Object.entries(members)) {
const user = users[id];
result.members.set(id, this.guild?.members._add({ user, ...member }) ?? member);
}
}
if (users) {
result.users = new Collection();
for (const user of Object.values(users)) {
result.users.set(user.id, this.client.users._add(user));
}
}
if (roles) {
result.roles = new Collection();
for (const role of Object.values(roles)) {
result.roles.set(role.id, this.guild?.roles._add(role) ?? role);
}
}
if (channels) {
result.channels = new Collection();
for (const channel of Object.values(channels)) {
result.channels.set(channel.id, this.client.channels._add(channel, this.guild) ?? channel);
}
}
if (messages) {
result.messages = new Collection();
for (const message of Object.values(messages)) {
result.messages.set(message.id, this.channel?.messages?._add(message) ?? message);
}
}
return result;
}
/**
* Represents an option of a received command interaction.
* @typedef {Object} CommandInteractionOption
* @property {string} name The name of the option
* @property {ApplicationCommandOptionType} type The type of the option
* @property {boolean} [autocomplete] Whether the option is an autocomplete option
* @property {string|number|boolean} [value] The value of the option
* @property {CommandInteractionOption[]} [options] Additional options if this option is a
* subcommand (group)
* @property {User} [user] The resolved user
* @property {GuildMember|APIGuildMember} [member] The resolved member
* @property {GuildChannel|ThreadChannel|APIChannel} [channel] The resolved channel
* @property {Role|APIRole} [role] The resolved role
*/
/**
* Transforms an option received from the API.
* @param {APIApplicationCommandOption} option The received option
* @param {APIInteractionDataResolved} resolved The resolved interaction data
* @returns {CommandInteractionOption}
* @private
*/
transformOption(option, resolved) {
const result = {
name: option.name,
type: ApplicationCommandOptionTypes[option.type],
};
if ('value' in option) result.value = option.value;
if ('options' in option) result.options = option.options.map(opt => this.transformOption(opt, resolved));
if (resolved) {
const user = resolved.users?.[option.value];
if (user) result.user = this.client.users._add(user);
const member = resolved.members?.[option.value];
if (member) result.member = this.guild?.members._add({ user, ...member }) ?? member;
const channel = resolved.channels?.[option.value];
if (channel) result.channel = this.client.channels._add(channel, this.guild) ?? channel;
const role = resolved.roles?.[option.value];
if (role) result.role = this.guild?.roles._add(role) ?? role;
}
return result;
}
// These are here only for documentation purposes - they are implemented by InteractionResponses
/* eslint-disable no-empty-function */
deferReply() {}
reply() {}
fetchReply() {}
editReply() {}
deleteReply() {}
followUp() {}
}
InteractionResponses.applyToClass(CommandInteraction, ['deferUpdate', 'update']);
module.exports = CommandInteraction;
/* eslint-disable max-len */
/**
* @external APIInteractionDataResolved
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-resolved-data-structure}
*/

View File

@@ -1,14 +1,14 @@
'use strict';
const BaseCommandInteraction = require('./BaseCommandInteraction');
const CommandInteraction = require('./CommandInteraction');
const CommandInteractionOptionResolver = require('./CommandInteractionOptionResolver');
const { ApplicationCommandOptionTypes, ApplicationCommandTypes } = require('../util/Constants');
/**
* Represents a context menu interaction.
* @extends {BaseCommandInteraction}
* @extends {CommandInteraction}
*/
class ContextMenuInteraction extends BaseCommandInteraction {
class ContextMenuCommandInteraction extends CommandInteraction {
constructor(client, data) {
super(client, data);
/**
@@ -62,4 +62,4 @@ class ContextMenuInteraction extends BaseCommandInteraction {
}
}
module.exports = ContextMenuInteraction;
module.exports = ContextMenuCommandInteraction;

View File

@@ -136,44 +136,44 @@ class Interaction extends Base {
return Boolean(this.guildId && !this.guild && this.member);
}
/**
* Indicates whether this interaction is a {@link BaseCommandInteraction}.
* @returns {boolean}
*/
isApplicationCommand() {
return InteractionTypes[this.type] === InteractionTypes.APPLICATION_COMMAND;
}
/**
* Indicates whether this interaction is a {@link CommandInteraction}.
* @returns {boolean}
*/
isCommand() {
return InteractionTypes[this.type] === InteractionTypes.APPLICATION_COMMAND;
}
/**
* Indicates whether this interaction is a {@link ChatInputCommandInteraction}.
* @returns {boolean}
*/
isChatInputCommand() {
return InteractionTypes[this.type] === InteractionTypes.APPLICATION_COMMAND && typeof this.targetId === 'undefined';
}
/**
* Indicates whether this interaction is a {@link ContextMenuInteraction}
* Indicates whether this interaction is a {@link ContextMenuCommandInteraction}
* @returns {boolean}
*/
isContextMenu() {
isContextMenuCommand() {
return InteractionTypes[this.type] === InteractionTypes.APPLICATION_COMMAND && typeof this.targetId !== 'undefined';
}
/**
* Indicates whether this interaction is a {@link UserContextMenuInteraction}
* Indicates whether this interaction is a {@link UserContextMenuCommandInteraction}
* @returns {boolean}
*/
isUserContextMenu() {
return this.isContextMenu() && ApplicationCommandTypes[this.targetType] === ApplicationCommandTypes.USER;
isUserContextMenuCommand() {
return this.isContextMenuCommand() && ApplicationCommandTypes[this.targetType] === ApplicationCommandTypes.USER;
}
/**
* Indicates whether this interaction is a {@link MessageContextMenuInteraction}
* Indicates whether this interaction is a {@link MessageContextMenuCommandInteraction}
* @returns {boolean}
*/
isMessageContextMenu() {
return this.isContextMenu() && ApplicationCommandTypes[this.targetType] === ApplicationCommandTypes.MESSAGE;
isMessageContextMenuCommand() {
return this.isContextMenuCommand() && ApplicationCommandTypes[this.targetType] === ApplicationCommandTypes.MESSAGE;
}
/**

View File

@@ -1,12 +1,12 @@
'use strict';
const ContextMenuInteraction = require('./ContextMenuInteraction');
const ContextMenuCommandInteraction = require('./ContextMenuInteraction');
/**
* Represents a message context menu interaction.
* @extends {ContextMenuInteraction}
*/
class MessageContextMenuInteraction extends ContextMenuInteraction {
class MessageContextMenuCommandInteraction extends ContextMenuCommandInteraction {
/**
* The message this interaction was sent from
* @type {Message|APIMessage}
@@ -17,4 +17,4 @@ class MessageContextMenuInteraction extends ContextMenuInteraction {
}
}
module.exports = MessageContextMenuInteraction;
module.exports = MessageContextMenuCommandInteraction;

View File

@@ -1,12 +1,12 @@
'use strict';
const ContextMenuInteraction = require('./ContextMenuInteraction');
const ContextMenuCommandInteraction = require('./ContextMenuInteraction');
/**
* Represents a user context menu interaction.
* @extends {ContextMenuInteraction}
* @extends {ContextMenuCommandInteraction}
*/
class UserContextMenuInteraction extends ContextMenuInteraction {
class UserContextMenuCommandInteraction extends ContextMenuCommandInteraction {
/**
* The user this interaction was sent from
* @type {User}
@@ -26,4 +26,4 @@ class UserContextMenuInteraction extends ContextMenuInteraction {
}
}
module.exports = UserContextMenuInteraction;
module.exports = UserContextMenuCommandInteraction;

View File

@@ -320,7 +320,7 @@ export type GuildCacheMessage<Cached extends CacheType> = CacheTypeReducer<
Message | APIMessage
>;
export abstract class BaseCommandInteraction<Cached extends CacheType = CacheType> extends Interaction<Cached> {
export abstract class CommandInteraction<Cached extends CacheType = CacheType> extends Interaction<Cached> {
public readonly command: ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null;
public options: Omit<
CommandInteractionOptionResolver<Cached>,
@@ -343,9 +343,9 @@ export abstract class BaseCommandInteraction<Cached extends CacheType = CacheTyp
public ephemeral: boolean | null;
public replied: boolean;
public webhook: InteractionWebhook;
public inGuild(): this is BaseCommandInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is BaseCommandInteraction<'cached'>;
public inRawGuild(): this is BaseCommandInteraction<'raw'>;
public inGuild(): this is CommandInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is CommandInteraction<'cached'>;
public inRawGuild(): this is CommandInteraction<'raw'>;
public deferReply(options: InteractionDeferReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
public deferReply(options?: InteractionDeferReplyOptions): Promise<void>;
public deleteReply(): Promise<void>;
@@ -720,11 +720,11 @@ export interface ApplicationCommandInteractionOptionResolver<Cached extends Cach
): NonNullable<CommandInteractionOption<Cached>['member' | 'role' | 'user']> | null;
}
export class CommandInteraction<Cached extends CacheType = CacheType> extends BaseCommandInteraction<Cached> {
export class ChatInputCommandInteraction<Cached extends CacheType = CacheType> extends CommandInteraction<Cached> {
public options: Omit<CommandInteractionOptionResolver<Cached>, 'getMessage' | 'getFocused'>;
public inGuild(): this is CommandInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is CommandInteraction<'cached'>;
public inRawGuild(): this is CommandInteraction<'raw'>;
public inGuild(): this is ChatInputCommandInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is ChatInputCommandInteraction<'cached'>;
public inRawGuild(): this is ChatInputCommandInteraction<'raw'>;
public toString(): string;
}
@@ -800,7 +800,7 @@ export class CommandInteractionOptionResolver<Cached extends CacheType = CacheTy
public getFocused(getFull?: boolean): string | number;
}
export class ContextMenuInteraction<Cached extends CacheType = CacheType> extends BaseCommandInteraction<Cached> {
export class ContextMenuCommandInteraction<Cached extends CacheType = CacheType> extends CommandInteraction<Cached> {
public options: Omit<
CommandInteractionOptionResolver<Cached>,
| 'getFocused'
@@ -816,9 +816,9 @@ export class ContextMenuInteraction<Cached extends CacheType = CacheType> extend
>;
public targetId: Snowflake;
public targetType: Exclude<ApplicationCommandType, 'CHAT_INPUT'>;
public inGuild(): this is ContextMenuInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is ContextMenuInteraction<'cached'>;
public inRawGuild(): this is ContextMenuInteraction<'raw'>;
public inGuild(): this is ContextMenuCommandInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is ContextMenuCommandInteraction<'cached'>;
public inRawGuild(): this is ContextMenuCommandInteraction<'raw'>;
private resolveContextMenuOptions(data: APIApplicationCommandInteractionData): CommandInteractionOption<Cached>[];
}
@@ -1328,13 +1328,16 @@ export class Interaction<Cached extends CacheType = CacheType> extends Base {
public inGuild(): this is Interaction<'raw' | 'cached'>;
public inCachedGuild(): this is Interaction<'cached'>;
public inRawGuild(): this is Interaction<'raw'>;
public isApplicationCommand(): this is BaseCommandInteraction<Cached>;
public isApplicationCommand(): this is CommandInteraction<Cached>;
public isButton(): this is ButtonInteraction<Cached>;
public isCommand(): this is CommandInteraction<Cached>;
public isChatInputCommand(): this is ChatInputCommandInteraction<Cached>;
public isContextMenuCommand(): this is ContextMenuCommandInteraction<Cached>;
public isMessageContextMenuCommand(): this is MessageContextMenuCommandInteraction<Cached>;
public isAutocomplete(): this is AutocompleteInteraction<Cached>;
public isContextMenu(): this is ContextMenuInteraction<Cached>;
public isUserContextMenu(): this is UserContextMenuInteraction<Cached>;
public isMessageContextMenu(): this is MessageContextMenuInteraction<Cached>;
public isContextMenu(): this is ContextMenuCommandInteraction<Cached>;
public isUserContextMenu(): this is UserContextMenuCommandInteraction<Cached>;
public isMessageContextMenu(): this is MessageContextMenuCommandInteraction<Cached>;
public isMessageComponent(): this is MessageComponentInteraction<Cached>;
public isSelectMenu(): this is SelectMenuInteraction<Cached>;
}
@@ -1656,13 +1659,13 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
public static resolveType(type: MessageComponentTypeResolvable): MessageComponentType;
}
export class MessageContextMenuInteraction<
export class MessageContextMenuCommandInteraction<
Cached extends CacheType = CacheType,
> extends ContextMenuInteraction<Cached> {
> extends ContextMenuCommandInteraction<Cached> {
public readonly targetMessage: NonNullable<CommandInteractionOption<Cached>['message']>;
public inGuild(): this is MessageContextMenuInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is MessageContextMenuInteraction<'cached'>;
public inRawGuild(): this is MessageContextMenuInteraction<'raw'>;
public inGuild(): this is MessageContextMenuCommandInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is MessageContextMenuCommandInteraction<'cached'>;
public inRawGuild(): this is MessageContextMenuCommandInteraction<'raw'>;
}
export class MessageEmbed {
@@ -2397,12 +2400,14 @@ export class User extends PartialTextBasedChannel(Base) {
public toString(): UserMention;
}
export class UserContextMenuInteraction<Cached extends CacheType = CacheType> extends ContextMenuInteraction<Cached> {
export class UserContextMenuCommandInteraction<
Cached extends CacheType = CacheType,
> extends ContextMenuCommandInteraction<Cached> {
public readonly targetUser: User;
public readonly targetMember: CacheTypeReducer<Cached, GuildMember, APIInteractionGuildMember>;
public inGuild(): this is UserContextMenuInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is UserContextMenuInteraction<'cached'>;
public inRawGuild(): this is UserContextMenuInteraction<'raw'>;
public inGuild(): this is UserContextMenuCommandInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is UserContextMenuCommandInteraction<'cached'>;
public inRawGuild(): this is UserContextMenuCommandInteraction<'raw'>;
}
export class UserFlags extends BitField<UserFlagsString> {

View File

@@ -19,7 +19,7 @@ import {
ApplicationCommandResolvable,
ApplicationCommandSubCommandData,
ApplicationCommandSubGroupData,
BaseCommandInteraction,
CommandInteraction,
ButtonInteraction,
CacheType,
CategoryChannel,
@@ -28,12 +28,12 @@ import {
ClientUser,
CloseEvent,
Collection,
CommandInteraction,
ChatInputCommandInteraction,
CommandInteractionOption,
CommandInteractionOptionResolver,
CommandOptionNonChoiceResolvableType,
Constants,
ContextMenuInteraction,
ContextMenuCommandInteraction,
DMChannel,
Guild,
GuildApplicationCommandManager,
@@ -980,7 +980,7 @@ client.on('interactionCreate', interaction => {
client.on('interactionCreate', async interaction => {
if (interaction.inCachedGuild()) {
expectAssignable<GuildMember>(interaction.member);
expectNotType<CommandInteraction<'cached'>>(interaction);
expectNotType<ChatInputCommandInteraction<'cached'>>(interaction);
expectAssignable<Interaction>(interaction);
} else if (interaction.inRawGuild()) {
expectAssignable<APIInteractionGuildMember>(interaction.member);
@@ -991,16 +991,16 @@ client.on('interactionCreate', async interaction => {
}
if (interaction.isContextMenu()) {
expectType<ContextMenuInteraction>(interaction);
expectType<ContextMenuCommandInteraction>(interaction);
if (interaction.inCachedGuild()) {
expectAssignable<ContextMenuInteraction>(interaction);
expectAssignable<ContextMenuCommandInteraction>(interaction);
expectAssignable<Guild>(interaction.guild);
expectAssignable<BaseCommandInteraction<'cached'>>(interaction);
expectAssignable<CommandInteraction<'cached'>>(interaction);
} else if (interaction.inRawGuild()) {
expectAssignable<ContextMenuInteraction>(interaction);
expectAssignable<ContextMenuCommandInteraction>(interaction);
expectType<null>(interaction.guild);
} else if (interaction.inGuild()) {
expectAssignable<ContextMenuInteraction>(interaction);
expectAssignable<ContextMenuCommandInteraction>(interaction);
expectType<Guild | null>(interaction.guild);
}
}
@@ -1091,10 +1091,10 @@ client.on('interactionCreate', async interaction => {
}
}
if (interaction.isCommand()) {
if (interaction.isChatInputCommand()) {
if (interaction.inRawGuild()) {
expectNotAssignable<Interaction<'cached'>>(interaction);
expectAssignable<CommandInteraction>(interaction);
expectAssignable<ChatInputCommandInteraction>(interaction);
expectType<Promise<APIMessage>>(interaction.reply({ fetchReply: true }));
expectType<APIInteractionDataResolvedGuildMember | null>(interaction.options.getMember('test'));
expectType<APIInteractionDataResolvedGuildMember>(interaction.options.getMember('test', true));
@@ -1109,7 +1109,7 @@ client.on('interactionCreate', async interaction => {
expectType<ButtonInteraction<'cached'>>(btn);
expectType<GuildMember | null>(interaction.options.getMember('test'));
expectAssignable<CommandInteraction>(interaction);
expectAssignable<ChatInputCommandInteraction>(interaction);
expectType<Promise<Message<true>>>(interaction.reply({ fetchReply: true }));
expectType<GuildBasedChannel>(interaction.options.getChannel('test', true));
@@ -1117,7 +1117,7 @@ client.on('interactionCreate', async interaction => {
} else {
// @ts-expect-error
consumeCachedCommand(interaction);
expectType<CommandInteraction>(interaction);
expectType<ChatInputCommandInteraction>(interaction);
expectType<Promise<Message | APIMessage>>(interaction.reply({ fetchReply: true }));
expectType<APIInteractionDataResolvedGuildMember | GuildMember | null>(interaction.options.getMember('test'));
expectType<APIInteractionDataResolvedGuildMember | GuildMember>(interaction.options.getMember('test', true));
@@ -1126,7 +1126,7 @@ client.on('interactionCreate', async interaction => {
expectType<APIRole | Role>(interaction.options.getRole('test', true));
}
expectType<CommandInteraction>(interaction);
expectType<ChatInputCommandInteraction>(interaction);
expectType<Omit<CommandInteractionOptionResolver<CacheType>, 'getFocused' | 'getMessage'>>(interaction.options);
expectType<readonly CommandInteractionOption[]>(interaction.options.data);