From a3f8d3884a1deca5eccfb6d990e2a7b42fbbe08a Mon Sep 17 00:00:00 2001 From: IRONM00N <64110067+IRONM00N@users.noreply.github.com> Date: Sun, 23 Jan 2022 18:13:05 -0500 Subject: fix discord.js breaking changes, some other stuff --- src/lib/common/AutoMod.ts | 32 +- src/lib/common/ButtonPaginator.ts | 139 ++++----- src/lib/common/ConfirmationPrompt.ts | 27 +- src/lib/common/DeleteButton.ts | 16 +- src/lib/common/util/Moderation.ts | 8 +- src/lib/extensions/discord-akairo/BushClient.ts | 21 +- .../extensions/discord-akairo/BushClientUtil.ts | 35 ++- src/lib/extensions/discord-akairo/BushCommand.ts | 4 +- .../extensions/discord-akairo/BushSlashMessage.ts | 12 +- .../discord.js/BushApplicationCommandManager.d.ts | 146 --------- .../discord.js/BushApplicationCommandManager.ts | 151 ++++++++++ .../BushApplicationCommandPermissionsManager.d.ts | 184 ------------ .../BushApplicationCommandPermissionsManager.ts | 184 ++++++++++++ .../discord.js/BushBaseGuildEmojiManager.d.ts | 16 - .../discord.js/BushBaseGuildEmojiManager.ts | 19 ++ .../discord.js/BushBaseGuildVoiceChannel.d.ts | 13 - .../discord.js/BushBaseGuildVoiceChannel.ts | 13 + .../extensions/discord.js/BushCategoryChannel.ts | 31 +- src/lib/extensions/discord.js/BushChannel.d.ts | 24 -- src/lib/extensions/discord.js/BushChannel.ts | 41 +++ .../extensions/discord.js/BushChannelManager.d.ts | 22 -- .../extensions/discord.js/BushChannelManager.ts | 25 ++ .../discord.js/BushChatInputCommandInteraction.ts | 46 +++ .../extensions/discord.js/BushClientEvents.d.ts | 326 --------------------- src/lib/extensions/discord.js/BushClientEvents.ts | 281 ++++++++++++++++++ src/lib/extensions/discord.js/BushClientUser.d.ts | 98 ------- src/lib/extensions/discord.js/BushClientUser.ts | 98 +++++++ .../discord.js/BushCommandInteraction.ts | 46 --- src/lib/extensions/discord.js/BushDMChannel.ts | 28 +- src/lib/extensions/discord.js/BushGuild.ts | 42 ++- .../BushGuildApplicationCommandManager.d.ts | 110 ------- .../BushGuildApplicationCommandManager.ts | 114 +++++++ src/lib/extensions/discord.js/BushGuildBan.d.ts | 15 - src/lib/extensions/discord.js/BushGuildBan.ts | 15 + src/lib/extensions/discord.js/BushGuildChannel.ts | 30 +- .../discord.js/BushGuildChannelManager.d.ts | 123 -------- .../discord.js/BushGuildChannelManager.ts | 123 ++++++++ .../discord.js/BushGuildEmojiRoleManager.d.ts | 52 ---- .../discord.js/BushGuildEmojiRoleManager.ts | 55 ++++ .../extensions/discord.js/BushGuildManager.d.ts | 34 --- src/lib/extensions/discord.js/BushGuildManager.ts | 35 +++ src/lib/extensions/discord.js/BushGuildMember.ts | 65 ++-- .../discord.js/BushGuildMemberManager.d.ts | 169 ----------- .../discord.js/BushGuildMemberManager.ts | 173 +++++++++++ src/lib/extensions/discord.js/BushMessage.ts | 4 +- .../extensions/discord.js/BushMessageManager.d.ts | 105 ------- .../extensions/discord.js/BushMessageManager.ts | 109 +++++++ src/lib/extensions/discord.js/BushStoreChannel.ts | 31 +- src/lib/extensions/discord.js/BushTextChannel.ts | 30 +- src/lib/extensions/discord.js/BushThreadChannel.ts | 22 +- .../extensions/discord.js/BushThreadManager.d.ts | 82 ------ src/lib/extensions/discord.js/BushThreadManager.ts | 86 ++++++ .../discord.js/BushThreadMemberManager.d.ts | 43 --- .../discord.js/BushThreadMemberManager.ts | 55 ++++ src/lib/extensions/discord.js/BushUserManager.d.ts | 59 ---- src/lib/extensions/discord.js/BushUserManager.ts | 60 ++++ src/lib/extensions/discord.js/BushVoiceChannel.ts | 30 +- src/lib/extensions/discord.js/other.ts | 54 ++-- src/lib/extensions/global.d.ts | 22 -- src/lib/extensions/global.ts | 22 ++ src/lib/index.ts | 2 +- src/lib/models/Guild.ts | 17 +- src/lib/utils/AllowedMentions.ts | 6 + src/lib/utils/BushConstants.ts | 82 +++--- 64 files changed, 2206 insertions(+), 1956 deletions(-) delete mode 100644 src/lib/extensions/discord.js/BushApplicationCommandManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushApplicationCommandManager.ts delete mode 100644 src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.ts delete mode 100644 src/lib/extensions/discord.js/BushBaseGuildEmojiManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushBaseGuildEmojiManager.ts delete mode 100644 src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.d.ts create mode 100644 src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.ts delete mode 100644 src/lib/extensions/discord.js/BushChannel.d.ts create mode 100644 src/lib/extensions/discord.js/BushChannel.ts delete mode 100644 src/lib/extensions/discord.js/BushChannelManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushChannelManager.ts create mode 100644 src/lib/extensions/discord.js/BushChatInputCommandInteraction.ts delete mode 100644 src/lib/extensions/discord.js/BushClientEvents.d.ts create mode 100644 src/lib/extensions/discord.js/BushClientEvents.ts delete mode 100644 src/lib/extensions/discord.js/BushClientUser.d.ts create mode 100644 src/lib/extensions/discord.js/BushClientUser.ts delete mode 100644 src/lib/extensions/discord.js/BushCommandInteraction.ts delete mode 100644 src/lib/extensions/discord.js/BushGuildApplicationCommandManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushGuildApplicationCommandManager.ts delete mode 100644 src/lib/extensions/discord.js/BushGuildBan.d.ts create mode 100644 src/lib/extensions/discord.js/BushGuildBan.ts delete mode 100644 src/lib/extensions/discord.js/BushGuildChannelManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushGuildChannelManager.ts delete mode 100644 src/lib/extensions/discord.js/BushGuildEmojiRoleManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushGuildEmojiRoleManager.ts delete mode 100644 src/lib/extensions/discord.js/BushGuildManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushGuildManager.ts delete mode 100644 src/lib/extensions/discord.js/BushGuildMemberManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushGuildMemberManager.ts delete mode 100644 src/lib/extensions/discord.js/BushMessageManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushMessageManager.ts delete mode 100644 src/lib/extensions/discord.js/BushThreadManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushThreadManager.ts delete mode 100644 src/lib/extensions/discord.js/BushThreadMemberManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushThreadMemberManager.ts delete mode 100644 src/lib/extensions/discord.js/BushUserManager.d.ts create mode 100644 src/lib/extensions/discord.js/BushUserManager.ts delete mode 100644 src/lib/extensions/global.d.ts create mode 100644 src/lib/extensions/global.ts (limited to 'src/lib') diff --git a/src/lib/common/AutoMod.ts b/src/lib/common/AutoMod.ts index 7a30820..4de242a 100644 --- a/src/lib/common/AutoMod.ts +++ b/src/lib/common/AutoMod.ts @@ -1,5 +1,14 @@ import { banResponse, Moderation, type BushButtonInteraction, type BushMessage } from '#lib'; -import { GuildMember, MessageActionRow, MessageButton, MessageEmbed, type TextChannel } from 'discord.js'; +import { + ActionRow, + ButtonComponent, + ButtonStyle, + ChannelType, + GuildMember, + MessageEmbed, + Permissions, + type TextChannel +} from 'discord.js'; /** * Handles auto moderation functionality. @@ -28,7 +37,7 @@ export class AutoMod { * Handles the auto moderation */ private async handle() { - if (this.message.channel.type === 'DM' || !this.message.guild) return; + if (this.message.channel.type === ChannelType.DM || !this.message.guild) return; if (!(await this.message.guild.hasFeature('automod'))) return; if (this.message.author.bot) return; if (this.message.author.isOwner()) return; @@ -110,7 +119,10 @@ export class AutoMod { const includes = this.message.content.toLocaleLowerCase().includes; if (!includes('@everyone') && !includes('@here')) return; // It would be bad if we deleted a message that actually pinged @everyone or @here - if (this.message.member?.permissionsIn(this.message.channelId).has('MENTION_EVERYONE') || this.message.mentions.everyone) + if ( + this.message.member?.permissionsIn(this.message.channelId).has(Permissions.FLAGS.MENTION_EVERYONE) || + this.message.mentions.everyone + ) return; if ( @@ -142,9 +154,9 @@ export class AutoMod { components: Severity.TEMP_MUTE >= 2 ? [ - new MessageActionRow().addComponents( - new MessageButton() - .setStyle('DANGER') + new ActionRow().addComponents( + new ButtonComponent() + .setStyle(ButtonStyle.Danger) .setLabel('Ban User') .setCustomId(`automod;ban;${this.message.author.id};everyone mention and scam phrase`) ) @@ -263,9 +275,9 @@ export class AutoMod { components: highestOffence.severity >= 2 ? [ - new MessageActionRow().addComponents( - new MessageButton() - .setStyle('DANGER') + new ActionRow().addComponents( + new ButtonComponent() + .setStyle(ButtonStyle.Danger) .setLabel('Ban User') .setCustomId(`automod;ban;${this.message.author.id};${highestOffence.reason}`) ) @@ -279,7 +291,7 @@ export class AutoMod { * @param interaction The button interaction. */ public static async handleInteraction(interaction: BushButtonInteraction) { - if (!interaction.memberPermissions?.has('BAN_MEMBERS')) + if (!interaction.memberPermissions?.has(Permissions.FLAGS.BAN_MEMBERS)) return interaction.reply({ content: `${util.emojis.error} You are missing the **Ban Members** permission.`, ephemeral: true diff --git a/src/lib/common/ButtonPaginator.ts b/src/lib/common/ButtonPaginator.ts index 83f4219..9e72551 100644 --- a/src/lib/common/ButtonPaginator.ts +++ b/src/lib/common/ButtonPaginator.ts @@ -1,13 +1,15 @@ import { DeleteButton, type BushMessage, type BushSlashMessage } from '#lib'; import { CommandUtil } from 'discord-akairo'; import { - MessageActionRow, - MessageButton, + ActionRow, + ActionRowComponent, + ButtonComponent, + ButtonStyle, + ComponentType, MessageEmbed, type MessageComponentInteraction, type MessageEmbedOptions } from 'discord.js'; -import { MessageButtonStyles } from 'discord.js/typings/enums'; /** * Sends multiple embeds with controls to switch between them @@ -94,9 +96,15 @@ export class ButtonPaginator { })) as BushMessage; const collector = this.sentMessage.createMessageComponentCollector({ - filter: (i) => i.customId.startsWith('paginate_') && i.message?.id === this.sentMessage!.id, - time: 300000 + componentType: ComponentType.Button, + filter: (i) => { + const ret = i.customId.startsWith('paginate_') && i.message.id === this.sentMessage!.id; + console.debug(ret); + return ret; + }, + idle: 300000 }); + console.debug('got here'); collector.on('collect', (i) => void this.collect(i)); collector.on('end', () => void this.end()); @@ -107,8 +115,9 @@ export class ButtonPaginator { * @param interaction The interaction received */ protected async collect(interaction: MessageComponentInteraction) { + console.debug(1); if (interaction.user.id !== this.message.author.id && !client.config.owners.includes(interaction.user.id)) - return await interaction?.deferUpdate().catch(() => null); + return await interaction?.deferUpdate(); /* .catch(() => null); */ switch (interaction.customId) { case 'paginate_beginning': @@ -121,17 +130,16 @@ export class ButtonPaginator { break; case 'paginate_stop': if (this.deleteOnExit) { - await interaction.deferUpdate().catch(() => null); - await this.sentMessage!.delete().catch(() => null); + await interaction.deferUpdate(); /* .catch(() => null); */ + await this.sentMessage!.delete(); /* .catch(() => null); */ break; } else { - await interaction - ?.update({ - content: `${this.text ? `${this.text}\n` : ''}Command closed by user.`, - embeds: [], - components: [] - }) - .catch(() => null); + await interaction?.update({ + content: `${this.text ? `${this.text}\n` : ''}Command closed by user.`, + embeds: [], + components: [] + }); + /* .catch(() => null); */ break; } case 'paginate_next': @@ -150,13 +158,12 @@ export class ButtonPaginator { */ protected async end() { if (this.sentMessage && !CommandUtil.deletedMessages.has(this.sentMessage.id)) - await this.sentMessage - .edit({ - content: this.text, - embeds: [this.embeds[this.curPage]], - components: [this.getPaginationRow(true)] - }) - .catch(() => null); + await this.sentMessage.edit({ + content: this.text, + embeds: [this.embeds[this.curPage]], + components: [this.getPaginationRow(true)] + }); + /* .catch(() => null); */ } /** @@ -164,52 +171,46 @@ export class ButtonPaginator { * @param interaction The interaction received */ protected async edit(interaction: MessageComponentInteraction) { - await interaction - ?.update({ - content: this.text, - embeds: [this.embeds[this.curPage]], - components: [this.getPaginationRow()] - }) - .catch(() => null); + await interaction?.update({ + content: this.text, + embeds: [this.embeds[this.curPage]], + components: [this.getPaginationRow()] + }); + /* .catch(() => null); */ } /** * Generates the pagination row based on the class properties * @param disableAll Whether to disable all buttons - * @returns The generated {@link MessageActionRow} + * @returns The generated {@link ActionRow} */ - protected getPaginationRow(disableAll = false): MessageActionRow { - return new MessageActionRow().addComponents( - new MessageButton({ - style: MessageButtonStyles.PRIMARY, - customId: 'paginate_beginning', - emoji: PaginateEmojis.BEGGING, - disabled: disableAll || this.curPage === 0 - }), - new MessageButton({ - style: MessageButtonStyles.PRIMARY, - customId: 'paginate_back', - emoji: PaginateEmojis.BACK, - disabled: disableAll || this.curPage === 0 - }), - new MessageButton({ - style: MessageButtonStyles.PRIMARY, - customId: 'paginate_stop', - emoji: PaginateEmojis.STOP, - disabled: disableAll - }), - new MessageButton({ - style: MessageButtonStyles.PRIMARY, - customId: 'paginate_next', - emoji: PaginateEmojis.FORWARD, - disabled: disableAll || this.curPage === this.numPages - 1 - }), - new MessageButton({ - style: MessageButtonStyles.PRIMARY, - customId: 'paginate_end', - emoji: PaginateEmojis.END, - disabled: disableAll || this.curPage === this.numPages - 1 - }) + protected getPaginationRow(disableAll = false): ActionRow { + return new ActionRow().addComponents( + new ButtonComponent() + .setStyle(ButtonStyle.Primary) + .setCustomId('paginate_beginning') + .setEmoji(PaginateEmojis.BEGINNING) + .setDisabled(disableAll || this.curPage === 0), + new ButtonComponent() + .setStyle(ButtonStyle.Primary) + .setCustomId('paginate_back') + .setEmoji(PaginateEmojis.BACK) + .setDisabled(disableAll || this.curPage === 0), + new ButtonComponent() + .setStyle(ButtonStyle.Primary) + .setCustomId('paginate_stop') + .setEmoji(PaginateEmojis.STOP) + .setDisabled(disableAll), + new ButtonComponent() + .setStyle(ButtonStyle.Primary) + .setCustomId('paginate_next') + .setEmoji(PaginateEmojis.FORWARD) + .setDisabled(disableAll || this.curPage === this.embeds.length - 1), + new ButtonComponent() + .setStyle(ButtonStyle.Primary) + .setCustomId('paginate_end') + .setEmoji(PaginateEmojis.END) + .setDisabled(disableAll || this.curPage === this.embeds.length - 1) ); } @@ -235,10 +236,10 @@ export class ButtonPaginator { } } -export const enum PaginateEmojis { - BEGGING = '853667381335162910', - BACK = '853667410203770881', - STOP = '853667471110570034', - FORWARD = '853667492680564747', - END = '853667514915225640' -} +export const PaginateEmojis = { + BEGINNING: { id: '853667381335162910', name: 'w_paginate_beginning', animated: false } as const, + BACK: { id: '853667410203770881', name: 'w_paginate_back', animated: false } as const, + STOP: { id: '853667471110570034', name: 'w_paginate_stop', animated: false } as const, + FORWARD: { id: '853667492680564747', name: 'w_paginate_next', animated: false } as const, + END: { id: '853667514915225640', name: 'w_paginate_end', animated: false } as const +} as const; diff --git a/src/lib/common/ConfirmationPrompt.ts b/src/lib/common/ConfirmationPrompt.ts index a4acf83..97f18b3 100644 --- a/src/lib/common/ConfirmationPrompt.ts +++ b/src/lib/common/ConfirmationPrompt.ts @@ -1,6 +1,5 @@ import { type BushMessage, type BushSlashMessage } from '#lib'; -import { MessageActionRow, MessageButton, type MessageComponentInteraction, type MessageOptions } from 'discord.js'; -import { MessageButtonStyles } from 'discord.js/typings/enums'; +import { ActionRow, ButtonComponent, ButtonStyle, type MessageComponentInteraction, type MessageOptions } from 'discord.js'; /** * Sends a message with buttons for the user to confirm or cancel the action. @@ -30,19 +29,17 @@ export class ConfirmationPrompt { */ protected async send(): Promise { this.messageOptions.components = [ - new MessageActionRow().addComponents( - new MessageButton({ - style: MessageButtonStyles.SUCCESS, - customId: 'confirmationPrompt_confirm', - emoji: util.emojis.successFull, - label: 'Yes' - }), - new MessageButton({ - style: MessageButtonStyles.DANGER, - customId: 'confirmationPrompt_deny', - emoji: util.emojis.errorFull, - label: 'No' - }) + new ActionRow().addComponents( + new ButtonComponent() + .setStyle(ButtonStyle.Primary) + .setCustomId('confirmationPrompt_confirm') + .setEmoji({ id: util.emojis.successFull, name: 'successFull', animated: false }) + .setLabel('Yes'), + new ButtonComponent() + .setStyle(ButtonStyle.Danger) + .setCustomId('confirmationPrompt_cancel') + .setEmoji({ id: util.emojis.errorFull, name: 'errorFull', animated: false }) + .setLabel('No') ) ]; diff --git a/src/lib/common/DeleteButton.ts b/src/lib/common/DeleteButton.ts index b666a4f..edc40fe 100644 --- a/src/lib/common/DeleteButton.ts +++ b/src/lib/common/DeleteButton.ts @@ -1,7 +1,6 @@ import { PaginateEmojis, type BushMessage, type BushSlashMessage } from '#lib'; import { CommandUtil } from 'discord-akairo'; -import { MessageActionRow, MessageButton, type MessageComponentInteraction, type MessageOptions } from 'discord.js'; -import { MessageButtonStyles } from 'discord.js/typings/enums'; +import { ActionRow, ButtonComponent, ButtonStyle, MessageComponentInteraction, type MessageOptions } from 'discord.js'; /** * Sends a message with a button for the user to delete it. @@ -59,13 +58,12 @@ export class DeleteButton { */ protected updateComponents(edit = false, disable = false): void { this.messageOptions.components = [ - new MessageActionRow().addComponents( - new MessageButton({ - style: MessageButtonStyles.PRIMARY, - customId: 'paginate__stop', - emoji: PaginateEmojis.STOP, - disabled: disable - }) + new ActionRow().addComponents( + new ButtonComponent() + .setStyle(ButtonStyle.Primary) + .setCustomId('paginate__stop') + .setEmoji(PaginateEmojis.STOP) + .setDisabled(disable) ) ]; if (edit) { diff --git a/src/lib/common/util/Moderation.ts b/src/lib/common/util/Moderation.ts index e5cb872..84d9fbf 100644 --- a/src/lib/common/util/Moderation.ts +++ b/src/lib/common/util/Moderation.ts @@ -10,7 +10,7 @@ import { type BushUserResolvable, type ModLogType } from '#lib'; -import { MessageEmbed, type Snowflake } from 'discord.js'; +import { MessageEmbed, Permissions, type Snowflake } from 'discord.js'; /** * A utility class with moderation-related methods. @@ -70,7 +70,11 @@ export class Moderation { ) { return `${util.emojis.error} You cannot ${type} **${victim.user.tag}** because they have higher or equal role hierarchy as I do.`; } - if (checkModerator && victim.permissions.has('MANAGE_MESSAGES') && !(type.startsWith('un') && moderator.id === victim.id)) { + if ( + checkModerator && + victim.permissions.has(Permissions.FLAGS.MANAGE_MESSAGES) && + !(type.startsWith('un') && moderator.id === victim.id) + ) { if (await moderator.guild.hasFeature('modsCanPunishMods')) { return true; } else { diff --git a/src/lib/extensions/discord-akairo/BushClient.ts b/src/lib/extensions/discord-akairo/BushClient.ts index cb1e50b..01620a8 100644 --- a/src/lib/extensions/discord-akairo/BushClient.ts +++ b/src/lib/extensions/discord-akairo/BushClient.ts @@ -24,6 +24,7 @@ import { patch, type PatchedElements } from '@notenoughupdates/events-intercept' import * as Sentry from '@sentry/node'; import { AkairoClient, ContextMenuCommandHandler, version as akairoVersion } from 'discord-akairo'; import { + ActivityType, Intents, Options, Structures, @@ -61,7 +62,7 @@ import { BushConstants } from '../../utils/BushConstants.js'; import { BushLogger } from '../../utils/BushLogger.js'; import { BushButtonInteraction } from '../discord.js/BushButtonInteraction.js'; import { BushCategoryChannel } from '../discord.js/BushCategoryChannel.js'; -import { BushCommandInteraction } from '../discord.js/BushCommandInteraction.js'; +import { BushChatInputCommandInteraction } from '../discord.js/BushChatInputCommandInteraction.js'; import { BushDMChannel } from '../discord.js/BushDMChannel.js'; import { BushGuild } from '../discord.js/BushGuild.js'; import { BushGuildEmoji } from '../discord.js/BushGuildEmoji.js'; @@ -193,7 +194,7 @@ export class BushClient extends AkairoClient extends AkairoClient extends AkairoClient BushVoiceState); Structures.extend('Role', () => BushRole); Structures.extend('User', () => BushUser); - Structures.extend('CommandInteraction', () => BushCommandInteraction); + Structures.extend('ChatInputCommandInteraction', () => BushChatInputCommandInteraction); Structures.extend('ButtonInteraction', () => BushButtonInteraction); Structures.extend('SelectMenuInteraction', () => BushSelectMenuInteraction); } @@ -440,13 +441,17 @@ export class BushClient extends AkairoClient { - await this.guilds.fetch(); - const promises = this.guilds.cache.map((guild) => { - return guild.members.fetch(); - }); + console.debug('ready start'); + console.time('ready'); + const promises = this.guilds.cache + .filter((g) => g.large) + .map((guild) => { + return guild.members.fetch(); + }); await Promise.all(promises); this.customReady = true; this.taskHandler.startAll(); + console.timeEnd('ready'); return done(null, `intercepted ${arg}`); }); diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts index 12becd3..79aa4c1 100644 --- a/src/lib/extensions/discord-akairo/BushClientUtil.ts +++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts @@ -26,13 +26,13 @@ import { GuildMember, Message, MessageEmbed, + Permissions, ThreadMember, User, Util as DiscordUtil, type ColorResolvable, type CommandInteraction, type InteractionReplyOptions, - type PermissionResolvable, type Snowflake, type TextChannel, type UserResolvable @@ -43,6 +43,8 @@ import { inspect, promisify } from 'util'; import CommandErrorListener from '../../../listeners/commands/commandError.js'; import { Format } from '../../common/util/Format.js'; +export type StripPrivate = { [K in keyof T]: T[K] extends Record ? StripPrivate : T[K] }; + export class BushClientUtil extends ClientUtil { /** * The client. @@ -208,7 +210,7 @@ export class BushClientUtil extends ClientUtil { if (author) embed = embed.setAuthor({ name: author.username, - iconURL: author.displayAvatarURL({ dynamic: true }), + iconURL: author.displayAvatarURL(), url: `https://discord.com/users/${author.id}` }); if (color) embed = embed.setColor(color); @@ -425,7 +427,7 @@ export class BushClientUtil extends ClientUtil { * @returns The combined elements or `ifEmpty`. * * @example - * const permissions = oxford(['ADMINISTRATOR', 'SEND_MESSAGES', 'MANAGE_MESSAGES'], 'and', 'none'); + * const permissions = oxford([Permissions.FLAGS.ADMINISTRATOR, Permissions.FLAGS.SEND_MESSAGES, Permissions.FLAGS.MANAGE_MESSAGES], 'and', 'none'); * console.log(permissions); // ADMINISTRATOR, SEND_MESSAGES and MANAGE_MESSAGES */ public oxford(array: string[], conjunction: string, ifEmpty?: string): string | undefined { @@ -785,10 +787,10 @@ export class BushClientUtil extends ClientUtil { * @param permissions The permissions to check for. * @returns The missing permissions or null if none are missing. */ - public userGuildPermCheck(message: BushMessage | BushSlashMessage, permissions: PermissionResolvable) { + public userGuildPermCheck(message: BushMessage | BushSlashMessage, permissions: bigint[]) { const missing = message.member?.permissions.missing(permissions) ?? []; - return missing.length ? missing : null; + return missing.length ? missing.map((p) => Permissions.FLAGS[p]) : null; } /** @@ -797,10 +799,10 @@ export class BushClientUtil extends ClientUtil { * @param permissions The permissions to check for. * @returns The missing permissions or null if none are missing. */ - public clientGuildPermCheck(message: BushMessage | BushSlashMessage, permissions: PermissionResolvable) { + public clientGuildPermCheck(message: BushMessage | BushSlashMessage, permissions: bigint[]) { const missing = message.guild?.me?.permissions.missing(permissions) ?? []; - return missing.length ? missing : null; + return missing.length ? missing.map((p) => Permissions.FLAGS[p]) : null; } /** @@ -811,19 +813,18 @@ export class BushClientUtil extends ClientUtil { * @param checkChannel Whether to check the channel permissions instead of the guild permissions. * @returns The missing permissions or null if none are missing. */ - public clientSendAndPermCheck( - message: BushMessage | BushSlashMessage, - permissions: PermissionResolvable = [], - checkChannel = false - ) { + public clientSendAndPermCheck(message: BushMessage | BushSlashMessage, permissions: bigint[] = [], checkChannel = false) { const missing = []; - const sendPerm = message.channel!.isThread() ? 'SEND_MESSAGES' : 'SEND_MESSAGES_IN_THREADS'; + const sendPerm = message.channel!.isThread() ? Permissions.FLAGS.SEND_MESSAGES : Permissions.FLAGS.SEND_MESSAGES_IN_THREADS; if (!message.guild!.me!.permissionsIn(message.channel!.id!).has(sendPerm)) missing.push(sendPerm); missing.push( ...(checkChannel - ? message.guild!.me!.permissionsIn(message.channel!.id!).missing(permissions) + ? message + .guild!.me!.permissionsIn(message.channel!.id!) + .missing(permissions) + .map((p) => Permissions.FLAGS[p]) : this.clientGuildPermCheck(message, permissions) ?? []) ); @@ -894,6 +895,12 @@ export class BushClientUtil extends ClientUtil { return Object.fromEntries(values); } + public get invite() { + return `https://discord.com/api/oauth2/authorize?client_id=${client.user!.id}&permissions=${ + Permissions.ALL + }&scope=bot%20applications.commands`; + } + /** * A wrapper for the Argument class that adds custom typings. */ diff --git a/src/lib/extensions/discord-akairo/BushCommand.ts b/src/lib/extensions/discord-akairo/BushCommand.ts index fb488be..0456b80 100644 --- a/src/lib/extensions/discord-akairo/BushCommand.ts +++ b/src/lib/extensions/discord-akairo/BushCommand.ts @@ -315,12 +315,12 @@ export interface BaseBushCommandOptions /** * Permissions required by the client to run this command. */ - clientPermissions: PermissionResolvable | PermissionResolvable[] | BushMissingPermissionSupplier; + clientPermissions: bigint | bigint[] | BushMissingPermissionSupplier; /** * Permissions required by the user to run this command. */ - userPermissions: PermissionResolvable | PermissionResolvable[] | BushMissingPermissionSupplier; + userPermissions: bigint | bigint[] | BushMissingPermissionSupplier; /** * Restrict this argument to owners diff --git a/src/lib/extensions/discord-akairo/BushSlashMessage.ts b/src/lib/extensions/discord-akairo/BushSlashMessage.ts index cefd360..d342ea6 100644 --- a/src/lib/extensions/discord-akairo/BushSlashMessage.ts +++ b/src/lib/extensions/discord-akairo/BushSlashMessage.ts @@ -1,4 +1,5 @@ import { + BushGuildTextBasedChannel, type BushClient, type BushCommandUtil, type BushGuild, @@ -7,14 +8,14 @@ import { type BushUser } from '#lib'; import { AkairoMessage } from 'discord-akairo'; -import { type CommandInteraction } from 'discord.js'; +import { type ChatInputCommandInteraction, type ContextMenuCommandInteraction } from 'discord.js'; export class BushSlashMessage extends AkairoMessage { public declare client: BushClient; public declare util: BushCommandUtil; public declare author: BushUser; public declare member: BushGuildMember | null; - public constructor(client: BushClient, interaction: CommandInteraction) { + public constructor(client: BushClient, interaction: ChatInputCommandInteraction | ContextMenuCommandInteraction) { super(client, interaction); } } @@ -22,5 +23,10 @@ export class BushSlashMessage extends AkairoMessage { export interface BushSlashMessage extends AkairoMessage { get channel(): BushTextBasedChannel | null; get guild(): BushGuild | null; - inGuild(): this is this & { guild: BushGuild; member: BushGuildMember }; + inGuild(): this is BushSlashMessageInGuild & this; +} + +interface BushSlashMessageInGuild { + guild: BushGuild; + channel: BushGuildTextBasedChannel; } diff --git a/src/lib/extensions/discord.js/BushApplicationCommandManager.d.ts b/src/lib/extensions/discord.js/BushApplicationCommandManager.d.ts deleted file mode 100644 index 2aa366d..0000000 --- a/src/lib/extensions/discord.js/BushApplicationCommandManager.d.ts +++ /dev/null @@ -1,146 +0,0 @@ -import type { - BushApplicationCommand, - BushApplicationCommandPermissionsManager, - BushApplicationCommandResolvable, - BushClient, - BushGuildResolvable -} from '#lib'; -import type { APIApplicationCommand } from 'discord-api-types'; -import { - CachedManager, - type ApplicationCommandData, - type Collection, - type FetchApplicationCommandOptions, - type Snowflake -} from 'discord.js'; - -/** - * Manages API methods for application commands and stores their cache. - */ -export class BushApplicationCommandManager< - ApplicationCommandScope = BushApplicationCommand<{ guild: BushGuildResolvable }>, - PermissionsOptionsExtras = { guild: BushGuildResolvable }, - PermissionsGuildType = null -> extends CachedManager { - public constructor(client: BushClient, iterable?: Iterable); - - /** - * The manager for permissions of arbitrary commands on arbitrary guilds - */ - public permissions: BushApplicationCommandPermissionsManager< - { command?: BushApplicationCommandResolvable } & PermissionsOptionsExtras, - { command: BushApplicationCommandResolvable } & PermissionsOptionsExtras, - PermissionsOptionsExtras, - PermissionsGuildType, - null - >; - - /** - * The APIRouter path to the commands - * @param id The application command's id - * @param guildId The guild's id to use in the path, - * ignored when using a {@link GuildApplicationCommandManager} - */ - private commandPath({ id, guildId }: { id?: Snowflake; guildId?: Snowflake }): unknown; - - /** - * Creates an application command. - * @param command The command - * @param guildId The guild's id to create this command in, ignored when using a {@link GuildApplicationCommandManager} - * @example - * // Create a new command - * client.application.commands.create({ - * name: 'test', - * description: 'A test command', - * }) - * .then(console.log) - * .catch(console.error); - */ - public create(command: BushApplicationCommandResolvable, guildId?: Snowflake): Promise; - - /** - * Deletes an application command. - * @param command The command to delete - * @param guildId The guild's id where the command is registered, - * ignored when using a {@link GuildApplicationCommandManager} - * @example - * // Delete a command - * guild.commands.delete('123456789012345678') - * .then(console.log) - * .catch(console.error); - */ - public delete(command: BushApplicationCommandResolvable, guildId?: Snowflake): Promise; - - /** - * Edits an application command. - * @param command The command to edit - * @param data The data to update the command with - * @param guildId The guild's id where the command registered, - * ignored when using a {@link GuildApplicationCommandManager} - * @example - * // Edit an existing command - * client.application.commands.edit('123456789012345678', { - * description: 'New description', - * }) - * .then(console.log) - * .catch(console.error); - */ - public edit(command: BushApplicationCommandResolvable, data: ApplicationCommandData): Promise; - public edit( - command: BushApplicationCommandResolvable, - data: ApplicationCommandData, - guildId: Snowflake - ): Promise; - - /** - * Obtains one or multiple application commands from Discord, or the cache if it's already available. - * @param id The application command's id - * @param options Additional options for this fetch - * @example - * // Fetch a single command - * client.application.commands.fetch('123456789012345678') - * .then(command => console.log(`Fetched command ${command.name}`)) - * .catch(console.error); - * @example - * // Fetch all commands - * guild.commands.fetch() - * .then(commands => console.log(`Fetched ${commands.size} commands`)) - * .catch(console.error); - */ - public fetch(id: Snowflake, options: FetchApplicationCommandOptions & { guildId: Snowflake }): Promise; - public fetch(options: FetchApplicationCommandOptions): Promise>; - public fetch(id: Snowflake, options?: FetchApplicationCommandOptions): Promise; - public fetch(id?: Snowflake, options?: FetchApplicationCommandOptions): Promise>; - - /** - * Sets all the commands for this application or guild. - * @param commands The commands - * @param guildId The guild's id to create the commands in, - * ignored when using a {@link GuildApplicationCommandManager} - * @example - * // Set all commands to just this one - * client.application.commands.set([ - * { - * name: 'test', - * description: 'A test command', - * }, - * ]) - * .then(console.log) - * .catch(console.error); - * @example - * // Remove all commands - * guild.commands.set([]) - * .then(console.log) - * .catch(console.error); - */ - public set(commands: ApplicationCommandData[]): Promise>; - public set(commands: ApplicationCommandData[], guildId: Snowflake): Promise>; - - /** - * Transforms an {@link ApplicationCommandData} object into something that can be used with the API. - * @param command The command to transform - */ - private static transformCommand( - command: ApplicationCommandData - ): Omit; -} diff --git a/src/lib/extensions/discord.js/BushApplicationCommandManager.ts b/src/lib/extensions/discord.js/BushApplicationCommandManager.ts new file mode 100644 index 0000000..24a7b22 --- /dev/null +++ b/src/lib/extensions/discord.js/BushApplicationCommandManager.ts @@ -0,0 +1,151 @@ +import type { + BushApplicationCommand, + BushApplicationCommandPermissionsManager, + BushApplicationCommandResolvable, + BushClient, + BushGuildResolvable, + StripPrivate +} from '#lib'; +import type { APIApplicationCommand } from 'discord-api-types'; +import { + ApplicationCommandManager, + CachedManager, + type ApplicationCommandData, + type Collection, + type FetchApplicationCommandOptions, + type Snowflake +} from 'discord.js'; + +/** + * Manages API methods for application commands and stores their cache. + */ +export declare class BushApplicationCommandManager< + ApplicationCommandScope = BushApplicationCommand<{ guild: BushGuildResolvable }>, + PermissionsOptionsExtras = { guild: BushGuildResolvable }, + PermissionsGuildType = null + > + extends CachedManager + implements StripPrivate> +{ + public constructor(client: BushClient, iterable?: Iterable); + + /** + * The manager for permissions of arbitrary commands on arbitrary guilds + */ + public permissions: BushApplicationCommandPermissionsManager< + { command?: BushApplicationCommandResolvable } & PermissionsOptionsExtras, + { command: BushApplicationCommandResolvable } & PermissionsOptionsExtras, + PermissionsOptionsExtras, + PermissionsGuildType, + null + >; + + /** + * The APIRouter path to the commands + * @param id The application command's id + * @param guildId The guild's id to use in the path, + * ignored when using a {@link GuildApplicationCommandManager} + */ + private commandPath({ id, guildId }: { id?: Snowflake; guildId?: Snowflake }): unknown; + + /** + * Creates an application command. + * @param command The command + * @param guildId The guild's id to create this command in, ignored when using a {@link GuildApplicationCommandManager} + * @example + * // Create a new command + * client.application.commands.create({ + * name: 'test', + * description: 'A test command', + * }) + * .then(console.log) + * .catch(console.error); + */ + public create(command: BushApplicationCommandResolvable, guildId?: Snowflake): Promise; + + /** + * Deletes an application command. + * @param command The command to delete + * @param guildId The guild's id where the command is registered, + * ignored when using a {@link GuildApplicationCommandManager} + * @example + * // Delete a command + * guild.commands.delete('123456789012345678') + * .then(console.log) + * .catch(console.error); + */ + public delete(command: BushApplicationCommandResolvable, guildId?: Snowflake): Promise; + + /** + * Edits an application command. + * @param command The command to edit + * @param data The data to update the command with + * @param guildId The guild's id where the command registered, + * ignored when using a {@link GuildApplicationCommandManager} + * @example + * // Edit an existing command + * client.application.commands.edit('123456789012345678', { + * description: 'New description', + * }) + * .then(console.log) + * .catch(console.error); + */ + public edit(command: BushApplicationCommandResolvable, data: ApplicationCommandData): Promise; + public edit( + command: BushApplicationCommandResolvable, + data: ApplicationCommandData, + guildId: Snowflake + ): Promise; + + /** + * Obtains one or multiple application commands from Discord, or the cache if it's already available. + * @param id The application command's id + * @param options Additional options for this fetch + * @example + * // Fetch a single command + * client.application.commands.fetch('123456789012345678') + * .then(command => console.log(`Fetched command ${command.name}`)) + * .catch(console.error); + * @example + * // Fetch all commands + * guild.commands.fetch() + * .then(commands => console.log(`Fetched ${commands.size} commands`)) + * .catch(console.error); + */ + public fetch(id: Snowflake, options: FetchApplicationCommandOptions & { guildId: Snowflake }): Promise; + public fetch(options: FetchApplicationCommandOptions): Promise>; + public fetch(id: Snowflake, options?: FetchApplicationCommandOptions): Promise; + public fetch(id?: Snowflake, options?: FetchApplicationCommandOptions): Promise>; + + /** + * Sets all the commands for this application or guild. + * @param commands The commands + * @param guildId The guild's id to create the commands in, + * ignored when using a {@link GuildApplicationCommandManager} + * @example + * // Set all commands to just this one + * client.application.commands.set([ + * { + * name: 'test', + * description: 'A test command', + * }, + * ]) + * .then(console.log) + * .catch(console.error); + * @example + * // Remove all commands + * guild.commands.set([]) + * .then(console.log) + * .catch(console.error); + */ + public set(commands: ApplicationCommandData[]): Promise>; + public set(commands: ApplicationCommandData[], guildId: Snowflake): Promise>; + + /** + * Transforms an {@link ApplicationCommandData} object into something that can be used with the API. + * @param command The command to transform + */ + private static transformCommand( + command: ApplicationCommandData + ): Omit; +} diff --git a/src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.d.ts b/src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.d.ts deleted file mode 100644 index ff32be4..0000000 --- a/src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.d.ts +++ /dev/null @@ -1,184 +0,0 @@ -import type { BushClient, BushRoleResolvable, BushUserResolvable } from '#lib'; -import type { APIApplicationCommandPermission } from 'discord-api-types'; -import { - BaseManager, - type ApplicationCommand, - type ApplicationCommandManager, - type ApplicationCommandPermissionData, - type ApplicationCommandPermissions, - type Collection, - type GuildApplicationCommandManager, - type GuildApplicationCommandPermissionData, - type Snowflake -} from 'discord.js'; -import type { ApplicationCommandPermissionTypes } from 'discord.js/typings/enums'; - -/** - * Manages API methods for permissions of Application Commands. - */ -export class BushApplicationCommandPermissionsManager< - BaseOptions, - FetchSingleOptions, - FullPermissionsOptions, - GuildType, - CommandIdType -> extends BaseManager { - public constructor(manager: ApplicationCommandManager | GuildApplicationCommandManager | ApplicationCommand); - - /** - * The manager or command that this manager belongs to - */ - private manager: ApplicationCommandManager | GuildApplicationCommandManager | ApplicationCommand; - - /** - * The client that instantiated this Manager - */ - public client: BushClient; - - /** - * The id of the command this manager acts on - */ - public commandId: CommandIdType; - - /** - * The guild that this manager acts on - */ - public guild: GuildType; - - /** - * The id of the guild that this manager acts on - */ - public guildId: Snowflake | null; - - /** - * Add permissions to a command. - * @param options Options used to add permissions - * @example - * // Block a role from the command permissions - * guild.commands.permissions.add({ command: '123456789012345678', permissions: [ - * { - * id: '876543211234567890', - * type: 'ROLE', - * permission: false - * }, - * ]}) - * .then(console.log) - * .catch(console.error); - */ - public add( - options: FetchSingleOptions & { permissions: ApplicationCommandPermissionData[] } - ): Promise; - - /** - * Check whether a permission exists for a user or role - * @param options Options used to check permissions - * @example - * // Check whether a user has permission to use a command - * guild.commands.permissions.has({ command: '123456789012345678', permissionId: '876543210123456789' }) - * .then(console.log) - * .catch(console.error); - */ - public has(options: FetchSingleOptions & { permissionId: BushUserResolvable | BushRoleResolvable }): Promise; - - /** - * Fetches the permissions for one or multiple commands. - * @param options Options used to fetch permissions - * @example - * // Fetch permissions for one command - * guild.commands.permissions.fetch({ command: '123456789012345678' }) - * .then(perms => console.log(`Fetched permissions for ${perms.length} users`)) - * .catch(console.error); - * @example - * // Fetch permissions for all commands in a guild - * client.application.commands.permissions.fetch({ guild: '123456789012345678' }) - * .then(perms => console.log(`Fetched permissions for ${perms.size} commands`)) - * .catch(console.error); - */ - public fetch(options: FetchSingleOptions): Promise; - public fetch(options: BaseOptions): Promise>; - - /** - * Remove permissions from a command. - * @param options Options used to remove permissions - * @example - * // Remove a user permission from this command - * guild.commands.permissions.remove({ command: '123456789012345678', users: '876543210123456789' }) - * .then(console.log) - * .catch(console.error); - * @example - * // Remove multiple roles from this command - * guild.commands.permissions.remove({ - * command: '123456789012345678', roles: ['876543210123456789', '765432101234567890'] - * }) - * .then(console.log) - * .catch(console.error); - */ - public remove( - options: - | (FetchSingleOptions & { - users: BushUserResolvable | BushUserResolvable[]; - roles?: BushRoleResolvable | BushRoleResolvable[]; - }) - | (FetchSingleOptions & { - users?: BushUserResolvable | BushUserResolvable[]; - roles: BushRoleResolvable | BushRoleResolvable[]; - }) - ): Promise; - - /** - * Sets the permissions for one or more commands. - * @param options Options used to set permissions - * @example - * // Set the permissions for one command - * client.application.commands.permissions.set({ guild: '892455839386304532', command: '123456789012345678', - * permissions: [ - * { - * id: '876543210987654321', - * type: 'USER', - * permission: false, - * }, - * ]}) - * .then(console.log) - * .catch(console.error); - * @example - * // Set the permissions for all commands - * guild.commands.permissions.set({ fullPermissions: [ - * { - * id: '123456789012345678', - * permissions: [{ - * id: '876543210987654321', - * type: 'USER', - * permission: false, - * }], - * }, - * ]}) - * .then(console.log) - * .catch(console.error); - */ - public set( - options: FetchSingleOptions & { permissions: ApplicationCommandPermissionData[] } - ): Promise; - public set( - options: FullPermissionsOptions & { - fullPermissions: GuildApplicationCommandPermissionData[]; - } - ): Promise>; - - /** - * The APIRouter path to the commands - * @param guildId The guild's id to use in the path, - * @param commandId The application command's id - */ - private permissionsPath(guildId: Snowflake, commandId?: Snowflake): unknown; - - /** - * Transforms an {@link ApplicationCommandPermissionData} object into something that can be used with the API. - * @param permissions The permissions to transform - * @param received Whether these permissions have been received from Discord - */ - private static transformPermissions( - permissions: ApplicationCommandPermissionData, - received: true - ): Omit & { type: keyof ApplicationCommandPermissionTypes }; - private static transformPermissions(permissions: ApplicationCommandPermissionData): APIApplicationCommandPermission; -} diff --git a/src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.ts b/src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.ts new file mode 100644 index 0000000..f07bde9 --- /dev/null +++ b/src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.ts @@ -0,0 +1,184 @@ +import type { BushClient, BushRoleResolvable, BushUserResolvable } from '#lib'; +import type { APIApplicationCommandPermission } from 'discord-api-types'; +import { + ApplicationCommandPermissionType, + BaseManager, + type ApplicationCommand, + type ApplicationCommandManager, + type ApplicationCommandPermissionData, + type ApplicationCommandPermissions, + type Collection, + type GuildApplicationCommandManager, + type GuildApplicationCommandPermissionData, + type Snowflake +} from 'discord.js'; + +/** + * Manages API methods for permissions of Application Commands. + */ +export declare class BushApplicationCommandPermissionsManager< + BaseOptions, + FetchSingleOptions, + FullPermissionsOptions, + GuildType, + CommandIdType +> extends BaseManager { + public constructor(manager: ApplicationCommandManager | GuildApplicationCommandManager | ApplicationCommand); + + /** + * The manager or command that this manager belongs to + */ + private manager: ApplicationCommandManager | GuildApplicationCommandManager | ApplicationCommand; + + /** + * The client that instantiated this Manager + */ + public client: BushClient; + + /** + * The id of the command this manager acts on + */ + public commandId: CommandIdType; + + /** + * The guild that this manager acts on + */ + public guild: GuildType; + + /** + * The id of the guild that this manager acts on + */ + public guildId: Snowflake | null; + + /** + * Add permissions to a command. + * @param options Options used to add permissions + * @example + * // Block a role from the command permissions + * guild.commands.permissions.add({ command: '123456789012345678', permissions: [ + * { + * id: '876543211234567890', + * type: 'ROLE', + * permission: false + * }, + * ]}) + * .then(console.log) + * .catch(console.error); + */ + public add( + options: FetchSingleOptions & { permissions: ApplicationCommandPermissionData[] } + ): Promise; + + /** + * Check whether a permission exists for a user or role + * @param options Options used to check permissions + * @example + * // Check whether a user has permission to use a command + * guild.commands.permissions.has({ command: '123456789012345678', permissionId: '876543210123456789' }) + * .then(console.log) + * .catch(console.error); + */ + public has(options: FetchSingleOptions & { permissionId: BushUserResolvable | BushRoleResolvable }): Promise; + + /** + * Fetches the permissions for one or multiple commands. + * @param options Options used to fetch permissions + * @example + * // Fetch permissions for one command + * guild.commands.permissions.fetch({ command: '123456789012345678' }) + * .then(perms => console.log(`Fetched permissions for ${perms.length} users`)) + * .catch(console.error); + * @example + * // Fetch permissions for all commands in a guild + * client.application.commands.permissions.fetch({ guild: '123456789012345678' }) + * .then(perms => console.log(`Fetched permissions for ${perms.size} commands`)) + * .catch(console.error); + */ + public fetch(options: FetchSingleOptions): Promise; + public fetch(options: BaseOptions): Promise>; + + /** + * Remove permissions from a command. + * @param options Options used to remove permissions + * @example + * // Remove a user permission from this command + * guild.commands.permissions.remove({ command: '123456789012345678', users: '876543210123456789' }) + * .then(console.log) + * .catch(console.error); + * @example + * // Remove multiple roles from this command + * guild.commands.permissions.remove({ + * command: '123456789012345678', roles: ['876543210123456789', '765432101234567890'] + * }) + * .then(console.log) + * .catch(console.error); + */ + public remove( + options: + | (FetchSingleOptions & { + users: BushUserResolvable | BushUserResolvable[]; + roles?: BushRoleResolvable | BushRoleResolvable[]; + }) + | (FetchSingleOptions & { + users?: BushUserResolvable | BushUserResolvable[]; + roles: BushRoleResolvable | BushRoleResolvable[]; + }) + ): Promise; + + /** + * Sets the permissions for one or more commands. + * @param options Options used to set permissions + * @example + * // Set the permissions for one command + * client.application.commands.permissions.set({ guild: '892455839386304532', command: '123456789012345678', + * permissions: [ + * { + * id: '876543210987654321', + * type: 'USER', + * permission: false, + * }, + * ]}) + * .then(console.log) + * .catch(console.error); + * @example + * // Set the permissions for all commands + * guild.commands.permissions.set({ fullPermissions: [ + * { + * id: '123456789012345678', + * permissions: [{ + * id: '876543210987654321', + * type: 'USER', + * permission: false, + * }], + * }, + * ]}) + * .then(console.log) + * .catch(console.error); + */ + public set( + options: FetchSingleOptions & { permissions: ApplicationCommandPermissionData[] } + ): Promise; + public set( + options: FullPermissionsOptions & { + fullPermissions: GuildApplicationCommandPermissionData[]; + } + ): Promise>; + + /** + * The APIRouter path to the commands + * @param guildId The guild's id to use in the path, + * @param commandId The application command's id + */ + private permissionsPath(guildId: Snowflake, commandId?: Snowflake): unknown; + + /** + * Transforms an {@link ApplicationCommandPermissionData} object into something that can be used with the API. + * @param permissions The permissions to transform + * @param received Whether these permissions have been received from Discord + */ + private static transformPermissions( + permissions: ApplicationCommandPermissionData, + received: true + ): Omit & { type: keyof ApplicationCommandPermissionType }; + private static transformPermissions(permissions: ApplicationCommandPermissionData): APIApplicationCommandPermission; +} diff --git a/src/lib/extensions/discord.js/BushBaseGuildEmojiManager.d.ts b/src/lib/extensions/discord.js/BushBaseGuildEmojiManager.d.ts deleted file mode 100644 index 347ff65..0000000 --- a/src/lib/extensions/discord.js/BushBaseGuildEmojiManager.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { BushClient, BushEmojiIdentifierResolvable, BushEmojiResolvable, BushGuildEmoji } from '#lib'; -import { CachedManager, type Snowflake } from 'discord.js'; -import { type RawGuildEmojiData } from 'discord.js/typings/rawDataTypes'; - -/** - * Holds methods to resolve GuildEmojis and stores their cache. - */ -export class BushBaseGuildEmojiManager extends CachedManager { - public constructor(client: BushClient, iterable?: Iterable); - - /** - * Resolves an EmojiResolvable to an emoji identifier. - * @param emoji The emoji resolvable to resolve - */ - public resolveIdentifier(emoji: BushEmojiIdentifierResolvable): string | null; -} diff --git a/src/lib/extensions/discord.js/BushBaseGuildEmojiManager.ts b/src/lib/extensions/discord.js/BushBaseGuildEmojiManager.ts new file mode 100644 index 0000000..66abbc2 --- /dev/null +++ b/src/lib/extensions/discord.js/BushBaseGuildEmojiManager.ts @@ -0,0 +1,19 @@ +import type { BushClient, BushEmojiIdentifierResolvable, BushEmojiResolvable, BushGuildEmoji } from '#lib'; +import { BaseGuildEmojiManager, CachedManager, type Snowflake } from 'discord.js'; +import { type RawGuildEmojiData } from 'discord.js/typings/rawDataTypes'; + +/** + * Holds methods to resolve GuildEmojis and stores their cache. + */ +export declare class BushBaseGuildEmojiManager + extends CachedManager + implements BaseGuildEmojiManager +{ + public constructor(client: BushClient, iterable?: Iterable); + + /** + * Resolves an EmojiResolvable to an emoji identifier. + * @param emoji The emoji resolvable to resolve + */ + public resolveIdentifier(emoji: BushEmojiIdentifierResolvable): string | null; +} diff --git a/src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.d.ts b/src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.d.ts deleted file mode 100644 index 21be206..0000000 --- a/src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BaseGuildVoiceChannel, Collection, Snowflake } from 'discord.js'; -import { BushCategoryChannel } from './BushCategoryChannel'; -import { BushGuild } from './BushGuild'; -import { BushGuildMember } from './BushGuildMember'; - -/** - * Represents a voice-based guild channel on Discord. - */ -export class BushBaseGuildVoiceChannel extends BaseGuildVoiceChannel { - public readonly members: Collection; - public guild: BushGuild; - public readonly parent: BushCategoryChannel | null; -} diff --git a/src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.ts b/src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.ts new file mode 100644 index 0000000..2ffb2fd --- /dev/null +++ b/src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.ts @@ -0,0 +1,13 @@ +import { BaseGuildVoiceChannel, Collection, Snowflake } from 'discord.js'; +import { BushCategoryChannel } from './BushCategoryChannel'; +import { BushGuild } from './BushGuild'; +import { BushGuildMember } from './BushGuildMember'; + +/** + * Represents a voice-based guild channel on Discord. + */ +export declare class BushBaseGuildVoiceChannel extends BaseGuildVoiceChannel { + public readonly members: Collection; + public guild: BushGuild; + public readonly parent: BushCategoryChannel | null; +} diff --git a/src/lib/extensions/discord.js/BushCategoryChannel.ts b/src/lib/extensions/discord.js/BushCategoryChannel.ts index b711a54..ac82bf0 100644 --- a/src/lib/extensions/discord.js/BushCategoryChannel.ts +++ b/src/lib/extensions/discord.js/BushCategoryChannel.ts @@ -1,4 +1,19 @@ -import { BushNonThreadGuildBasedChannel, type BushClient, type BushGuild, type BushGuildMember } from '#lib'; +import { + BushDMChannel, + BushGuildBasedChannel, + BushNewsChannel, + BushNonThreadGuildBasedChannel, + BushStageChannel, + BushStoreChannel, + BushTextBasedChannel, + BushTextChannel, + BushThreadChannel, + BushVoiceBasedChannel, + BushVoiceChannel, + type BushClient, + type BushGuild, + type BushGuildMember +} from '#lib'; import { CategoryChannel, type Collection, type Snowflake } from 'discord.js'; import { type RawGuildChannelData } from 'discord.js/typings/rawDataTypes'; @@ -16,3 +31,17 @@ export class BushCategoryChannel extends CategoryChannel { super(guild, data, client, immediatePatch); } } + +export interface BushCategoryChannel extends CategoryChannel { + isText(): this is BushTextChannel; + isDM(): this is BushDMChannel; + isVoice(): this is BushVoiceChannel; + isCategory(): this is BushCategoryChannel; + isNews(): this is BushNewsChannel; + // eslint-disable-next-line deprecation/deprecation + isStore(): this is BushStoreChannel; + isThread(): this is BushThreadChannel; + isStage(): this is BushStageChannel; + isTextBased(): this is BushGuildBasedChannel & BushTextBasedChannel; + isVoiceBased(): this is BushVoiceBasedChannel; +} diff --git a/src/lib/extensions/discord.js/BushChannel.d.ts b/src/lib/extensions/discord.js/BushChannel.d.ts deleted file mode 100644 index 42443ba..0000000 --- a/src/lib/extensions/discord.js/BushChannel.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { BushClient, BushTextBasedChannel, BushThreadChannel } from '#lib'; -import { Channel, type ChannelMention, type Snowflake } from 'discord.js'; -import type { ChannelTypes } from 'discord.js/typings/enums'; -import type { RawChannelData } from 'discord.js/typings/rawDataTypes'; -import { BushBaseGuildVoiceChannel } from './BushBaseGuildVoiceChannel'; - -/** - * Represents any channel on Discord. - */ -export class BushChannel extends Channel { - public constructor(client: BushClient, data?: RawChannelData, immediatePatch?: boolean); - public readonly createdAt: Date; - public readonly createdTimestamp: number; - public deleted: boolean; - public id: Snowflake; - public readonly partial: false; - public type: keyof typeof ChannelTypes; - public delete(): Promise; - public fetch(force?: boolean): Promise; - public isText(): this is BushTextBasedChannel; - public isVoice(): this is BushBaseGuildVoiceChannel; - public isThread(): this is BushThreadChannel; - public toString(): ChannelMention; -} diff --git a/src/lib/extensions/discord.js/BushChannel.ts b/src/lib/extensions/discord.js/BushChannel.ts new file mode 100644 index 0000000..50ec723 --- /dev/null +++ b/src/lib/extensions/discord.js/BushChannel.ts @@ -0,0 +1,41 @@ +/* eslint-disable deprecation/deprecation */ +import type { + BushCategoryChannel, + BushClient, + BushDMChannel, + BushNewsChannel, + BushStageChannel, + BushStoreChannel, + BushTextBasedChannel, + BushTextChannel, + BushThreadChannel, + BushVoiceBasedChannel, + BushVoiceChannel +} from '#lib'; +import { Channel, ChannelType, type Snowflake } from 'discord.js'; +import type { RawChannelData } from 'discord.js/typings/rawDataTypes'; + +/** + * Represents any channel on Discord. + */ +export declare class BushChannel extends Channel { + public constructor(client: BushClient, data?: RawChannelData, immediatePatch?: boolean); + public readonly createdAt: Date; + public readonly createdTimestamp: number; + public deleted: boolean; + public id: Snowflake; + public readonly partial: false; + public type: ChannelType; + public delete(): Promise; + public fetch(force?: boolean): Promise; + public isText(): this is BushTextChannel; + public isDM(): this is BushDMChannel; + public isVoice(): this is BushVoiceChannel; + public isCategory(): this is BushCategoryChannel; + public isNews(): this is BushNewsChannel; + public isStore(): this is BushStoreChannel; + public isThread(): this is BushThreadChannel; + public isStage(): this is BushStageChannel; + public isTextBased(): this is BushTextBasedChannel; + public isVoiceBased(): this is BushVoiceBasedChannel; +} diff --git a/src/lib/extensions/discord.js/BushChannelManager.d.ts b/src/lib/extensions/discord.js/BushChannelManager.d.ts deleted file mode 100644 index 514cdd3..0000000 --- a/src/lib/extensions/discord.js/BushChannelManager.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { BushAnyChannel, BushChannelResolvable } from '#lib'; -import { CachedManager, type Client, type FetchChannelOptions, type Snowflake } from 'discord.js'; -import type { RawChannelData } from 'discord.js/typings/