diff options
author | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2022-06-14 12:47:57 -0400 |
---|---|---|
committer | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2022-06-14 12:47:57 -0400 |
commit | 661e4c9935aeb8760dafc7ced4bbec6cc356a033 (patch) | |
tree | bb4c12bdef067d203f100e13e05ccb705b299834 | |
parent | eaf592b72eb5b1d66aa2bde5151a8947570a506c (diff) | |
download | tanzanite-661e4c9935aeb8760dafc7ced4bbec6cc356a033.tar.gz tanzanite-661e4c9935aeb8760dafc7ced4bbec6cc356a033.tar.bz2 tanzanite-661e4c9935aeb8760dafc7ced4bbec6cc356a033.zip |
remove the war crimes that I previously committed
- Remove custom typings and replace with declaration merging
- Fix the typings for args
- Replace all discord-api-types imports with discord.js imports
- Fix discord.js breaking changes
222 files changed, 1674 insertions, 4224 deletions
diff --git a/package.json b/package.json index 61ecb5c..ea08576 100644 --- a/package.json +++ b/package.json @@ -72,20 +72,20 @@ "chalk": "^5.0.1", "deep-lock": "^1.0.0", "discord-akairo": "npm:@notenoughupdates/discord-akairo@dev", - "discord-api-types": "0.33.5", + "discord-api-types": "0.34.0", "discord.js": "npm:@notenoughupdates/discord.js@dev", "fuse.js": "^6.6.2", "gif-to-apng": "^0.1.2", - "googleapis": "^101.0.0", + "googleapis": "^102.0.0", "got": "^12.1.0", "lodash": "^4.17.21", "mathjs": "^10.6.1", "nanoid": "^4.0.0", - "node-os-utils": "^1.3.6", + "node-os-utils": "^1.3.7", "numeral": "^2.0.6", "pg": "^8.7.3", "pg-hstore": "^2.3.4", - "prettier": "^2.6.2", + "prettier": "^2.7.0", "pretty-bytes": "^6.0.0", "rimraf": "^3.0.2", "sequelize": "6.20.1", @@ -107,8 +107,8 @@ "@types/rimraf": "^3.0.2", "@types/tinycolor2": "^1.4.3", "@types/validator": "^13.7.3", - "@typescript-eslint/eslint-plugin": "^5.27.1", - "@typescript-eslint/parser": "^5.27.1", + "@typescript-eslint/eslint-plugin": "^5.28.0", + "@typescript-eslint/parser": "^5.28.0", "eslint": "^8.17.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-deprecation": "^1.3.2", diff --git a/src/arguments/abbreviatedNumber.ts b/src/arguments/abbreviatedNumber.ts index 43d2938..eba9214 100644 --- a/src/arguments/abbreviatedNumber.ts +++ b/src/arguments/abbreviatedNumber.ts @@ -1,4 +1,4 @@ -import { type BushArgumentTypeCaster } from '#lib'; +import type { BushArgumentTypeCaster } from '#lib'; import assert from 'assert'; import numeral from 'numeral'; assert(typeof numeral === 'function'); diff --git a/src/arguments/contentWithDuration.ts b/src/arguments/contentWithDuration.ts index cd8549b..e92997a 100644 --- a/src/arguments/contentWithDuration.ts +++ b/src/arguments/contentWithDuration.ts @@ -1,4 +1,4 @@ -import { type BushArgumentTypeCaster, type ParsedDuration } from '#lib'; +import type { BushArgumentTypeCaster, ParsedDuration } from '#lib'; export const contentWithDuration: BushArgumentTypeCaster<Promise<ParsedDuration>> = async (_, phrase) => { return client.util.parseDuration(phrase); diff --git a/src/arguments/discordEmoji.ts b/src/arguments/discordEmoji.ts index 3edf123..57710e4 100644 --- a/src/arguments/discordEmoji.ts +++ b/src/arguments/discordEmoji.ts @@ -1,5 +1,5 @@ import type { BushArgumentTypeCaster } from '#lib'; -import type { Snowflake } from 'discord-api-types/v10'; +import type { Snowflake } from 'discord.js'; export const discordEmoji: BushArgumentTypeCaster<DiscordEmojiInfo | null> = (_, phrase) => { if (!phrase) return null; diff --git a/src/arguments/duration.ts b/src/arguments/duration.ts index 58593ef..ffd9159 100644 --- a/src/arguments/duration.ts +++ b/src/arguments/duration.ts @@ -1,4 +1,4 @@ -import { type BushArgumentTypeCaster } from '#lib'; +import type { BushArgumentTypeCaster } from '#lib'; export const duration: BushArgumentTypeCaster<number | null> = (_, phrase) => { return client.util.parseDuration(phrase).duration; diff --git a/src/arguments/durationSeconds.ts b/src/arguments/durationSeconds.ts index 74d136f..432fd8c 100644 --- a/src/arguments/durationSeconds.ts +++ b/src/arguments/durationSeconds.ts @@ -1,4 +1,4 @@ -import { type BushArgumentTypeCaster } from '#lib'; +import type { BushArgumentTypeCaster } from '#lib'; export const durationSeconds: BushArgumentTypeCaster<number | null> = (_, phrase) => { phrase += 's'; diff --git a/src/arguments/globalUser.ts b/src/arguments/globalUser.ts index 08350d2..df4f5d9 100644 --- a/src/arguments/globalUser.ts +++ b/src/arguments/globalUser.ts @@ -1,6 +1,7 @@ -import { type BushArgumentTypeCaster, type BushUser } from '#lib'; +import type { BushArgumentTypeCaster } from '#lib'; +import type { User } from 'discord.js'; // resolve non-cached users -export const globalUser: BushArgumentTypeCaster<Promise<BushUser | null>> = async (_, phrase) => { +export const globalUser: BushArgumentTypeCaster<Promise<User | null>> = async (_, phrase) => { return client.users.resolve(phrase) ?? (await client.users.fetch(`${phrase}`).catch(() => null)); }; diff --git a/src/arguments/messageLink.ts b/src/arguments/messageLink.ts index 5c91a4b..457410e 100644 --- a/src/arguments/messageLink.ts +++ b/src/arguments/messageLink.ts @@ -1,5 +1,5 @@ -import { type BushArgumentTypeCaster } from '#lib'; -import { type Message } from 'discord.js'; +import type { BushArgumentTypeCaster } from '#lib'; +import type { Message } from 'discord.js'; export const messageLink: BushArgumentTypeCaster<Promise<Message | null>> = async (_, phrase) => { const match = new RegExp(client.consts.regex.messageLink).exec(phrase); diff --git a/src/arguments/permission.ts b/src/arguments/permission.ts index cf4c42c..98bfe74 100644 --- a/src/arguments/permission.ts +++ b/src/arguments/permission.ts @@ -1,4 +1,4 @@ -import { type BushArgumentTypeCaster } from '#lib'; +import type { BushArgumentTypeCaster } from '#lib'; import { PermissionFlagsBits, type PermissionsString } from 'discord.js'; export const permission: BushArgumentTypeCaster<PermissionsString | null> = (_, phrase) => { diff --git a/src/arguments/roleWithDuration.ts b/src/arguments/roleWithDuration.ts index 5f1da98..e338b79 100644 --- a/src/arguments/roleWithDuration.ts +++ b/src/arguments/roleWithDuration.ts @@ -1,5 +1,5 @@ -import { type BushArgumentTypeCaster } from '#lib'; -import { type Role } from 'discord.js'; +import type { BushArgumentTypeCaster } from '#lib'; +import type { Role } from 'discord.js'; export const roleWithDuration: BushArgumentTypeCaster<Promise<RoleWithDuration | null>> = async (message, phrase) => { // eslint-disable-next-line prefer-const diff --git a/src/arguments/snowflake.ts b/src/arguments/snowflake.ts index 15896ae..dc83909 100644 --- a/src/arguments/snowflake.ts +++ b/src/arguments/snowflake.ts @@ -1,5 +1,5 @@ -import { type BushArgumentTypeCaster } from '#lib'; -import { type Snowflake } from 'discord.js'; +import type { BushArgumentTypeCaster } from '#lib'; +import type { Snowflake } from 'discord.js'; export const snowflake: BushArgumentTypeCaster<Snowflake | null> = (_, phrase) => { if (!phrase) return null; diff --git a/src/arguments/tinyColor.ts b/src/arguments/tinyColor.ts new file mode 100644 index 0000000..8d01928 --- /dev/null +++ b/src/arguments/tinyColor.ts @@ -0,0 +1,10 @@ +import type { BushArgumentTypeCaster } from '#lib'; +import assert from 'assert'; +import tinycolorModule from 'tinycolor2'; +assert(tinycolorModule); + +export const tinyColor: BushArgumentTypeCaster<string | null> = (_message, phrase) => { + // if the phase is a number it converts it to hex incase it could be representing a color in decimal + const newPhase = isNaN(phrase as any) ? phrase : `#${Number(phrase).toString(16)}`; + return tinycolorModule(newPhase).isValid() ? newPhase : null; +}; diff --git a/src/commands/_fake-command/ironmoon.ts b/src/commands/_fake-command/ironmoon.ts index 1f63c06..cb50c7e 100644 --- a/src/commands/_fake-command/ironmoon.ts +++ b/src/commands/_fake-command/ironmoon.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class IronmoonCommand extends BushCommand { public constructor() { @@ -13,13 +13,13 @@ export default class IronmoonCommand extends BushCommand { }); } - public override condition(message: BushMessage): boolean { + public override condition(message: CommandMessage): boolean { return false; if (message.content.toLowerCase().includes('ironmoon')) return true; else return false; } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { return await message.util.reply('Your message included the word ironmoon.'); } } diff --git a/src/commands/admin/channelPermissions.ts b/src/commands/admin/channelPermissions.ts index d58a7da..f6240a5 100644 --- a/src/commands/admin/channelPermissions.ts +++ b/src/commands/admin/channelPermissions.ts @@ -1,4 +1,4 @@ -import { BushCommand, ButtonPaginator, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, ButtonPaginator, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; @@ -57,12 +57,8 @@ export default class ChannelPermissionsCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - args: { - target: ArgType<'member'> | ArgType<'role'>; - permission: ArgType<'permission'>; - state: 'true' | 'false' | 'neutral'; - } + message: CommandMessage | SlashMessage, + args: { target: ArgType<'member' | 'role'>; permission: ArgType<'permission'>; state: 'true' | 'false' | 'neutral' } ) { assert(message.inGuild()); if (message.util.isSlashMessage(message)) await message.interaction.deferReply(); diff --git a/src/commands/admin/roleAll.ts b/src/commands/admin/roleAll.ts index 7cb7346..80952cc 100644 --- a/src/commands/admin/roleAll.ts +++ b/src/commands/admin/roleAll.ts @@ -1,4 +1,5 @@ -import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; + import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits, type GuildMember } from 'discord.js'; @@ -39,7 +40,7 @@ export default class RoleAllCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { role: ArgType<'role'>; bots: ArgType<'boolean'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { role: ArgType<'role'>; bots: ArgType<'flag'> }) { assert(message.inGuild()); if (!message.member!.permissions.has(PermissionFlagsBits.Administrator) && !message.member!.user.isOwner()) return await message.util.reply(`${util.emojis.error} You must have admin perms to use this command.`); diff --git a/src/commands/config/_customAutomodPhrases.ts b/src/commands/config/_customAutomodPhrases.ts index bd9bab5..13887ae 100644 --- a/src/commands/config/_customAutomodPhrases.ts +++ b/src/commands/config/_customAutomodPhrases.ts @@ -1,5 +1,5 @@ -// import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; -// import { PermissionFlagsBits } from 'discord.js'; +// import { BushCommand, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; +// import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; // export default class CustomAutomodPhrasesCommand extends BushCommand { // public constructor() { @@ -36,7 +36,7 @@ // } // public override async exec( -// message: BushMessage | BushSlashMessage, -// args: { required_argument: string; optional_argument: string } +// message: CommandMessage | SlashMessage, +// args: { required_argument: ArgType<'string'>; optional_argument: OptArgType<'string'> } // ) {} // } diff --git a/src/commands/config/blacklist.ts b/src/commands/config/blacklist.ts index ba2d24a..de457c0 100644 --- a/src/commands/config/blacklist.ts +++ b/src/commands/config/blacklist.ts @@ -1,6 +1,6 @@ -import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; -import { ApplicationCommandOptionType, PermissionFlagsBits, User } from 'discord.js'; +import { ApplicationCommandOptionType, GuildMember, PermissionFlagsBits, User } from 'discord.js'; export default class BlacklistCommand extends BushCommand { public constructor() { @@ -47,11 +47,11 @@ export default class BlacklistCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { action?: 'blacklist' | 'unblacklist'; - target: ArgType<'channel'> | ArgType<'user'> | string; // there is no way to combine channel and user in slash commands without making subcommands - global: ArgType<'boolean'>; + target: ArgType<'channel' | 'user'> | string; // there is no way to combine channel and user in slash commands without making subcommands + global: ArgType<'flag'>; } ) { let action: 'blacklist' | 'unblacklist' | 'toggle' = @@ -88,7 +88,7 @@ export default class BlacklistCommand extends BushCommand { const success = await (global ? util.setGlobal(key, newValue) - : message.guild!.setSetting(key, newValue, message.member!) + : message.guild!.setSetting(key, newValue, message.member as GuildMember) ).catch(() => false); if (!success) diff --git a/src/commands/config/config.ts b/src/commands/config/config.ts index e203d12..689a3af 100644 --- a/src/commands/config/config.ts +++ b/src/commands/config/config.ts @@ -4,12 +4,13 @@ import { guildSettingsObj, settingsArr, type ArgType, - type BushMessage, - type BushSlashMessage, + type CommandMessage, type GuildSettings, - type GuildSettingType + type GuildSettingType, + type SlashMessage } from '#lib'; import assert from 'assert'; + import { type ArgumentGeneratorReturn, type SlashOption } from 'discord-akairo'; import { ActionRowBuilder, @@ -149,7 +150,7 @@ export default class ConfigCommand extends BushCommand { }); } - public override *args(message: BushMessage): ArgumentGeneratorReturn { + public override *args(message: CommandMessage): ArgumentGeneratorReturn { const optional = message.util.parsed!.alias === 'settings'; const setting: GuildSettings = yield { id: 'setting', @@ -205,13 +206,13 @@ export default class ConfigCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { setting?: GuildSettings; subcommandGroup?: GuildSettings; action?: Action; subcommand?: Action; - value: ArgType<'channel'> | ArgType<'role'> | string; + value: ArgType<'channel' | 'role'> | string; } ) { assert(message.inGuild()); @@ -305,7 +306,7 @@ export default class ConfigCommand extends BushCommand { } public async generateMessageOptions( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, setting?: undefined | keyof typeof guildSettingsObj ): Promise<MessageOptions & InteractionUpdateOptions> { assert(message.inGuild()); diff --git a/src/commands/config/disable.ts b/src/commands/config/disable.ts index dea7b0f..373b5f6 100644 --- a/src/commands/config/disable.ts +++ b/src/commands/config/disable.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, AutocompleteInteraction, PermissionFlagsBits } from 'discord.js'; import Fuse from 'fuse.js'; @@ -54,8 +54,8 @@ export default class DisableCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - args: { action?: 'enable' | 'disable'; command: ArgType<'commandAlias'> | string; global: boolean } + message: CommandMessage | SlashMessage, + args: { action?: 'enable' | 'disable'; command: ArgType<'commandAlias'> | string; global: ArgType<'flag'> } ) { assert(message.inGuild()); diff --git a/src/commands/config/features.ts b/src/commands/config/features.ts index 2eee0fe..95ae544 100644 --- a/src/commands/config/features.ts +++ b/src/commands/config/features.ts @@ -2,9 +2,9 @@ import { BushCommand, guildFeaturesArr, guildFeaturesObj, - type BushMessage, - type BushSlashMessage, - type GuildFeatures + type CommandMessage, + type GuildFeatures, + type SlashMessage } from '#lib'; import assert from 'assert'; import { @@ -32,7 +32,7 @@ export default class FeaturesCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { assert(message.inGuild()); const featureEmbed = new EmbedBuilder().setTitle(`${message.guild.name}'s Features`).setColor(util.colors.default); diff --git a/src/commands/config/log.ts b/src/commands/config/log.ts index f99f007..7c76bdf 100644 --- a/src/commands/config/log.ts +++ b/src/commands/config/log.ts @@ -1,4 +1,4 @@ -import { BushCommand, guildLogsArr, type ArgType, type BushMessage, type BushSlashMessage, type GuildLogType } from '#lib'; +import { BushCommand, guildLogsArr, type ArgType, type CommandMessage, type GuildLogType, type SlashMessage } from '#lib'; import assert from 'assert'; import { ArgumentGeneratorReturn } from 'discord-akairo'; import { ApplicationCommandOptionType, ChannelType, PermissionFlagsBits } from 'discord.js'; @@ -70,7 +70,7 @@ export default class LogCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { log_type: GuildLogType; channel: ArgType<'textChannel'> } ) { assert(message.inGuild()); diff --git a/src/commands/dev/__template.ts b/src/commands/dev/__template.ts index ace8802..7bcce32 100644 --- a/src/commands/dev/__template.ts +++ b/src/commands/dev/__template.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib'; +import { BushCommand, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType } from 'discord.js'; export default class TemplateCommand extends BushCommand { @@ -39,7 +39,7 @@ export default class TemplateCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { required_argument: ArgType<'string'>; optional_argument: OptArgType<'string'> } ) { return await message.util.reply(`${util.emojis.error} Do not use the template command.`); diff --git a/src/commands/dev/debug.ts b/src/commands/dev/debug.ts index f8c614d..682a93d 100644 --- a/src/commands/dev/debug.ts +++ b/src/commands/dev/debug.ts @@ -1,4 +1,4 @@ -// import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +// import { BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; // import { ApplicationCommandOptionType, AutocompleteInteraction, ChatInputCommandInteraction } from 'discord.js'; // import Fuse from 'fuse.js'; @@ -29,7 +29,7 @@ // }); // } -// public override async exec(message: BushMessage | BushSlashMessage, args: { action: ArgType<'string'> }) { +// public override async exec(message: CommandMessage | SlashMessage, args: { action: ArgType<'string'> }) { // if (args.action === 'util.reply') { // return await message.util.reply(`This is a util.reply`); // } else if (args.action === 'util.reply-object') { diff --git a/src/commands/dev/dm.ts b/src/commands/dev/dm.ts index 0646f59..468fb20 100644 --- a/src/commands/dev/dm.ts +++ b/src/commands/dev/dm.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType } from 'discord.js'; export default class DMCommand extends BushCommand { @@ -37,7 +37,7 @@ export default class DMCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { user: ArgType<'user'>; content: ArgType<'string'> } ) { try { diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts index 8af280d..b8ee9e4 100644 --- a/src/commands/dev/eval.ts +++ b/src/commands/dev/eval.ts @@ -3,8 +3,6 @@ import { ActivePunishment, BushCommand, BushInspectOptions, - BushMessage, - BushSlashMessage, CodeBlockLang, Global, Guild, @@ -12,7 +10,9 @@ import { ModLog, Shared, StickyRole, - type ArgType + type ArgType, + type CommandMessage, + type SlashMessage } from '#lib'; import { Snowflake as Snowflake_ } from '@sapphire/snowflake'; import assert from 'assert'; @@ -57,7 +57,7 @@ const { transpile } = ts, /* eslint-enable @typescript-eslint/no-unused-vars */ // prettier-ignore -util.assertAll(ActivePunishment, BushCommand, BushMessage, BushSlashMessage, Global, Guild, Level, ModLog, Shared, StickyRole, Snowflake_, Canvas, exec, ActionRow, ButtonComponent, ButtonInteraction, Collection, Collector, CommandInteraction, ContextMenuCommandInteraction, DMChannel, Embed, Emoji, Interaction, InteractionCollector, Message, Attachment, MessageCollector, OAuth2Scopes, PermissionFlagsBits, PermissionsBitField, ReactionCollector, SelectMenuComponent, Util, path, ts, fileURLToPath, promisify, assert, got, transpile, emojis, colors, sh, SnowflakeUtil, __dirname); +util.assertAll(ActivePunishment, BushCommand, Global, Guild, Level, ModLog, Shared, StickyRole, Snowflake_, Canvas, exec, ActionRow, ButtonComponent, ButtonInteraction, Collection, Collector, CommandInteraction, ContextMenuCommandInteraction, DMChannel, Embed, Emoji, Interaction, InteractionCollector, Message, Attachment, MessageCollector, OAuth2Scopes, PermissionFlagsBits, PermissionsBitField, ReactionCollector, SelectMenuComponent, Util, path, ts, fileURLToPath, promisify, assert, got, transpile, emojis, colors, sh, SnowflakeUtil, __dirname); export default class EvalCommand extends BushCommand { public constructor() { @@ -180,7 +180,7 @@ export default class EvalCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, { code: argCode, sel_depth: selDepth, @@ -196,15 +196,15 @@ export default class EvalCommand extends BushCommand { }: { code: ArgType<'string'>; sel_depth: ArgType<'integer'>; - sudo: ArgType<'boolean'>; - silent: ArgType<'boolean'>; - delete_msg: ArgType<'boolean'>; - typescript: ArgType<'boolean'>; - hidden: ArgType<'boolean'>; - show_proto: ArgType<'boolean'>; - show_methods: ArgType<'boolean'>; - async: ArgType<'boolean'>; - no_inspect_strings: ArgType<'boolean'>; + sudo: ArgType<'flag'>; + silent: ArgType<'flag'>; + delete_msg: ArgType<'flag'>; + typescript: ArgType<'flag'>; + hidden: ArgType<'flag'>; + show_proto: ArgType<'flag'>; + show_methods: ArgType<'flag'>; + async: ArgType<'flag'>; + no_inspect_strings: ArgType<'flag'>; } ) { if (!message.author.isOwner()) @@ -322,5 +322,3 @@ interface CodeBlockCustomOptions extends CodeBlockOptions { prototype?: boolean; methods?: boolean; } - -/** @typedef {ActivePunishment|Global|Guild|Level|ModLog|StickyRole|ButtonInteraction|Collection|Collector|CommandInteraction|ContextMenuCommandInteraction|DMChannel|Emoji|Interaction|InteractionCollector|Message|ActionRow|Attachment|ButtonComponent|MessageCollector|SelectMenuComponent|ReactionCollector|Util|Canvas|Shared|PermissionsBitField|got} VSCodePleaseDontRemove */ diff --git a/src/commands/dev/javascript.ts b/src/commands/dev/javascript.ts index be8fdce..fd1894b 100644 --- a/src/commands/dev/javascript.ts +++ b/src/commands/dev/javascript.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, EmbedBuilder } from 'discord.js'; import { VM } from 'vm2'; @@ -41,11 +41,8 @@ export default class JavascriptCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - args: { - sel_depth: ArgType<'integer'>; - code: string; - } + message: CommandMessage | SlashMessage, + args: { code: ArgType<'string'>; sel_depth: OptArgType<'integer'> } ) { if (!message.author.isSuperUser()) return await message.util.reply(`${util.emojis.error} Only super users can run this command.`); diff --git a/src/commands/dev/reload.ts b/src/commands/dev/reload.ts index 17802b0..96c395f 100644 --- a/src/commands/dev/reload.ts +++ b/src/commands/dev/reload.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class ReloadCommand extends BushCommand { public constructor() { @@ -13,7 +13,7 @@ export default class ReloadCommand extends BushCommand { // id: 'fast', // description: 'Whether or not to use esbuild for fast compiling.', // match: 'flag', - // flag: '--fast', + // flag: ['--fast'], // prompt: 'Would you like to use esbuild for fast compiling?', // optional: true, // slashType: ApplicationCommandOptionType.Boolean @@ -27,14 +27,14 @@ export default class ReloadCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage /* { fast }: { fast: boolean } */) { + public override async exec(message: CommandMessage | SlashMessage /* args: { fast: ArgType<'flag'> } */) { if (!message.author.isOwner()) return await message.util.reply(`${util.emojis.error} Only my developers can run this command.`); let output: { stdout: string; stderr: string }; try { const s = new Date(); - output = await util.shell(`yarn build:${/* fast ? 'esbuild' : */ 'tsc'}`); + output = await util.shell(`yarn build:${/* args.fast ? 'esbuild' : */ 'tsc'}`); await Promise.all([ client.commandHandler.reloadAll(), client.listenerHandler.reloadAll(), diff --git a/src/commands/dev/say.ts b/src/commands/dev/say.ts index bbada0c..a452126 100644 --- a/src/commands/dev/say.ts +++ b/src/commands/dev/say.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType } from 'discord.js'; export default class SayCommand extends BushCommand { @@ -27,7 +27,7 @@ export default class SayCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { content: string }) { + public override async exec(message: CommandMessage | SlashMessage, args: { content: ArgType<'string'> }) { if (!message.author.isOwner()) return await message.util.reply(`${util.emojis.error} Only my developers can run this command.`); @@ -35,7 +35,7 @@ export default class SayCommand extends BushCommand { await message.util.send({ content: args.content, allowedMentions: AllowedMentions.none() }).catch(() => null); } - public override async execSlash(message: BushSlashMessage, args: { content: string }) { + public override async execSlash(message: SlashMessage, args: { content: string }) { if (!client.config.owners.includes(message.author.id)) { return await message.interaction.reply({ content: `${util.emojis.error} Only my developers can run this command.`, diff --git a/src/commands/dev/servers.ts b/src/commands/dev/servers.ts index 0701158..e99bcda 100644 --- a/src/commands/dev/servers.ts +++ b/src/commands/dev/servers.ts @@ -1,7 +1,6 @@ -import { BushCommand, ButtonPaginator, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, ButtonPaginator, type CommandMessage, type SlashMessage } from '#lib'; import { stripIndent } from '#tags'; -import type { APIEmbed } from 'discord-api-types/v10'; -import type { Guild } from 'discord.js'; +import { type APIEmbed, type Guild } from 'discord.js'; export default class ServersCommand extends BushCommand { public constructor() { @@ -17,7 +16,7 @@ export default class ServersCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { const guilds = [...client.guilds.cache.sort((a, b) => (a.memberCount < b.memberCount ? 1 : -1)).values()]; const chunkedGuilds: Guild[][] = util.chunk(guilds, 10); const embeds: APIEmbed[] = chunkedGuilds.map((chunk) => { diff --git a/src/commands/dev/sh.ts b/src/commands/dev/sh.ts index d47ecd2..8c62f5d 100644 --- a/src/commands/dev/sh.ts +++ b/src/commands/dev/sh.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { ArgType, BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import chalk from 'chalk'; import { exec } from 'child_process'; @@ -40,10 +40,10 @@ export default class ShCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, { command }: { command: string }) { + public override async exec(message: CommandMessage | SlashMessage, args: { command: ArgType<'string'> }) { if (!client.config.owners.includes(message.author.id)) return await message.util.reply(`${util.emojis.error} Only my developers can run this command.`); - const input = clean(command); + const input = clean(args.command); const embed = new EmbedBuilder() .setColor(util.colors.gray) @@ -65,7 +65,7 @@ export default class ShCommand extends BushCommand { return abc.replace(new RegExp(pattern, 'g'), ''); } */ try { - const output = await sh(command, { env: { ...process.env, FORCE_COLOR: 'true' } }); + const output = await sh(args.command, { env: { ...process.env, FORCE_COLOR: 'true' } }); const stdout = /* strip( */ clean(output.stdout); /* ) */ const stderr = /* strip( */ clean(output.stderr); /* ) */ diff --git a/src/commands/dev/superUser.ts b/src/commands/dev/superUser.ts index d62ac8e..6a2b745 100644 --- a/src/commands/dev/superUser.ts +++ b/src/commands/dev/superUser.ts @@ -1,6 +1,5 @@ -import { BushCommand, type ArgType, type BushMessage } from '#lib'; -import { ArgumentGeneratorReturn } from 'discord-akairo'; -import { ArgumentTypeCasterReturn } from 'discord-akairo/dist/src/struct/commands/arguments/Argument.js'; +import { BushCommand, type ArgType, type CommandMessage } from '#lib'; +import { type ArgumentGeneratorReturn, type ArgumentTypeCasterReturn } from 'discord-akairo'; export default class SuperUserCommand extends BushCommand { public constructor() { @@ -54,30 +53,30 @@ export default class SuperUserCommand extends BushCommand { return { action, user }; } - public override async exec(message: BushMessage, { action, user }: { action: 'add' | 'remove'; user: ArgType<'user'> }) { + public override async exec(message: CommandMessage, args: { action: 'add' | 'remove'; user: ArgType<'user'> }) { if (!message.author.isOwner()) return await message.util.reply(`${util.emojis.error} Only my developers can run this command.`); const superUsers: string[] = util.getShared('superUsers'); - if (action === 'add' ? superUsers.includes(user.id) : !superUsers.includes(user.id)) + if (args.action === 'add' ? superUsers.includes(args.user.id) : !superUsers.includes(args.user.id)) return message.util.reply( - `${util.emojis.warn} ${util.format.input(user.tag)} is ${action === 'add' ? 'already' : 'not'} a superuser.` + `${util.emojis.warn} ${util.format.input(args.user.tag)} is ${args.action === 'add' ? 'already' : 'not'} a superuser.` ); - const success = await util.insertOrRemoveFromShared(action, 'superUsers', user.id).catch(() => false); + const success = await util.insertOrRemoveFromShared(args.action, 'superUsers', args.user.id).catch(() => false); if (success) { return await message.util.reply( - `${util.emojis.success} ${action == 'remove' ? '' : 'made'} ${util.format.input(user.tag)} ${ - action == 'remove' ? 'is no longer ' : '' + `${util.emojis.success} ${args.action == 'remove' ? '' : 'made'} ${util.format.input(args.user.tag)} ${ + args.action == 'remove' ? 'is no longer ' : '' }a superuser.` ); } else { return await message.util.reply( - `${util.emojis.error} There was an error ${action == 'remove' ? `removing` : 'making'} ${util.format.input(user.tag)} ${ - action == 'remove' ? `from` : 'to' - } the superuser list.` + `${util.emojis.error} There was an error ${args.action == 'remove' ? `removing` : 'making'} ${util.format.input( + args.user.tag + )} ${args.action == 'remove' ? `from` : 'to'} the superuser list.` ); } } diff --git a/src/commands/dev/syncAutomod.ts b/src/commands/dev/syncAutomod.ts index 4d4a6d7..9954e70 100644 --- a/src/commands/dev/syncAutomod.ts +++ b/src/commands/dev/syncAutomod.ts @@ -1,4 +1,4 @@ -import { BushCommand, Shared, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, Shared, type CommandMessage, type SlashMessage } from '#lib'; import got from 'got'; import typescript from 'typescript'; import { NodeVM } from 'vm2'; @@ -18,7 +18,7 @@ export default class SyncAutomodCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { if (!message.author.isOwner() && message.author.id !== '497789163555389441') return await message.util.reply(`${util.emojis.error} Only a very select few may use this command.`); diff --git a/src/commands/dev/test.ts b/src/commands/dev/test.ts index 2d7b1f8..d54d544 100644 --- a/src/commands/dev/test.ts +++ b/src/commands/dev/test.ts @@ -1,11 +1,11 @@ -import { BushCommand, ButtonPaginator, Shared, type BushMessage } from '#lib'; -import { Routes } from 'discord-api-types/rest/v9'; +import { BushCommand, ButtonPaginator, OptArgType, Shared, type CommandMessage } from '#lib'; import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, GatewayDispatchEvents, + Routes, type ApplicationCommand, type Collection } from 'discord.js'; @@ -38,7 +38,7 @@ export default class TestCommand extends BushCommand { }); } - public override async exec(message: BushMessage, args: { feature: string }) { + public override async exec(message: CommandMessage, args: { feature: OptArgType<'string'> }) { const responses = [ 'Yes master.', 'Test it your self bitch, I am hungry.', @@ -51,166 +51,168 @@ export default class TestCommand extends BushCommand { return await message.util.reply(responses[Math.floor(Math.random() * responses.length)]); } - if (['button', 'buttons'].includes(args.feature?.toLowerCase())) { - const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents([ - new ButtonBuilder({ style: ButtonStyle.Primary, customId: 'primaryButton', label: 'Primary' }), - new ButtonBuilder({ style: ButtonStyle.Secondary, customId: 'secondaryButton', label: 'Secondary' }), - new ButtonBuilder({ style: ButtonStyle.Success, customId: 'successButton', label: 'Success' }), - new ButtonBuilder({ style: ButtonStyle.Danger, customId: 'dangerButton', label: 'Danger' }), - new ButtonBuilder({ style: ButtonStyle.Link, label: 'Link', url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' }) - ]); - return await message.util.reply({ content: 'buttons', components: [buttonRow] }); - } else if (['embed', 'button embed'].includes(args.feature?.toLowerCase())) { - const embed = new EmbedBuilder() - .addFields([{ name: 'Field Name', value: 'Field Content' }]) - .setAuthor({ name: 'Author', iconURL: 'https://www.w3schools.com/w3css/img_snowtops.jpg', url: 'https://google.com/' }) - .setColor(message.member?.displayColor ?? util.colors.default) - .setDescription('Description') - .setFooter({ text: 'Footer', iconURL: message.author.avatarURL() ?? undefined }) - .setURL('https://duckduckgo.com/') - .setTimestamp() - .setImage('https://media.sproutsocial.com/uploads/2017/02/10x-featured-social-media-image-size.png') - .setThumbnail( - 'https://images.unsplash.com/photo-1501183007986-d0d080b147f9?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2134&q=80' - ) - .setTitle('Title'); + if (args.feature) { + if (['button', 'buttons'].includes(args.feature?.toLowerCase())) { + const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents([ + new ButtonBuilder({ style: ButtonStyle.Primary, customId: 'primaryButton', label: 'Primary' }), + new ButtonBuilder({ style: ButtonStyle.Secondary, customId: 'secondaryButton', label: 'Secondary' }), + new ButtonBuilder({ style: ButtonStyle.Success, customId: 'successButton', label: 'Success' }), + new ButtonBuilder({ style: ButtonStyle.Danger, customId: 'dangerButton', label: 'Danger' }), + new ButtonBuilder({ style: ButtonStyle.Link, label: 'Link', url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' }) + ]); + return await message.util.reply({ content: 'buttons', components: [buttonRow] }); + } else if (['embed', 'button embed'].includes(args.feature?.toLowerCase())) { + const embed = new EmbedBuilder() + .addFields([{ name: 'Field Name', value: 'Field Content' }]) + .setAuthor({ name: 'Author', iconURL: 'https://www.w3schools.com/w3css/img_snowtops.jpg', url: 'https://google.com/' }) + .setColor(message.member?.displayColor ?? util.colors.default) + .setDescription('Description') + .setFooter({ text: 'Footer', iconURL: message.author.avatarURL() ?? undefined }) + .setURL('https://duckduckgo.com/') + .setTimestamp() + .setImage('https://media.sproutsocial.com/uploads/2017/02/10x-featured-social-media-image-size.png') + .setThumbnail( + 'https://images.unsplash.com/photo-1501183007986-d0d080b147f9?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2134&q=80' + ) + .setTitle('Title'); - const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents([ - new ButtonBuilder({ style: ButtonStyle.Link, label: 'Link', url: 'https://google.com/' }) - ]); - return await message.util.reply({ content: 'Test', embeds: [embed], components: [buttonRow] }); - } else if (['lots of buttons'].includes(args.feature?.toLowerCase())) { - const buttonRows: ActionRowBuilder<ButtonBuilder>[] = []; - for (let a = 1; a <= 5; a++) { - const row = new ActionRowBuilder<ButtonBuilder>(); - for (let b = 1; b <= 5; b++) { - const id = (a + 5 * (b - 1)).toString(); - const button = new ButtonBuilder({ style: ButtonStyle.Primary, customId: id, label: id }); - row.addComponents([button]); + const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents([ + new ButtonBuilder({ style: ButtonStyle.Link, label: 'Link', url: 'https://google.com/' }) + ]); + return await message.util.reply({ content: 'Test', embeds: [embed], components: [buttonRow] }); + } else if (['lots of buttons'].includes(args.feature?.toLowerCase())) { + const buttonRows: ActionRowBuilder<ButtonBuilder>[] = []; + for (let a = 1; a <= 5; a++) { + const row = new ActionRowBuilder<ButtonBuilder>(); + for (let b = 1; b <= 5; b++) { + const id = (a + 5 * (b - 1)).toString(); + const button = new ButtonBuilder({ style: ButtonStyle.Primary, customId: id, label: id }); + row.addComponents([button]); + } + buttonRows.push(row); } - buttonRows.push(row); - } - return await message.util.reply({ content: 'buttons', components: buttonRows }); - } else if (['paginate'].includes(args.feature?.toLowerCase())) { - const embeds = []; - for (let i = 1; i <= 5; i++) { - embeds.push(new EmbedBuilder().setDescription(i.toString())); - } - return await ButtonPaginator.send(message, embeds); - } else if (['lots of embeds'].includes(args.feature?.toLowerCase())) { - const description = 'This is a description.'; - const _avatar = message.author.avatarURL() ?? undefined; - const author = { name: 'This is a author', iconURL: _avatar }; - const footer = { text: 'This is a footer', iconURL: _avatar }; - const fields = Array(25) - .fill(0) - .map((_, i) => ({ name: `Field ${i}`, value: 'Field Value' })); - const c = util.colors; - const o = { description, author, footer, fields, time: Date.now() }; + return await message.util.reply({ content: 'buttons', components: buttonRows }); + } else if (['paginate'].includes(args.feature?.toLowerCase())) { + const embeds = []; + for (let i = 1; i <= 5; i++) { + embeds.push(new EmbedBuilder().setDescription(i.toString())); + } + return await ButtonPaginator.send(message, embeds); + } else if (['lots of embeds'].includes(args.feature?.toLowerCase())) { + const description = 'This is a description.'; + const _avatar = message.author.avatarURL() ?? undefined; + const author = { name: 'This is a author', iconURL: _avatar }; + const footer = { text: 'This is a footer', iconURL: _avatar }; + const fields = Array(25) + .fill(0) + .map((_, i) => ({ name: `Field ${i}`, value: 'Field Value' })); + const c = util.colors; + const o = { description, author, footer, fields, time: Date.now() }; - const colors = [c.red, c.orange, c.gold, c.yellow, c.green, c.darkGreen, c.aqua, c.blue, c.purple, c.pink]; + const colors = [c.red, c.orange, c.gold, c.yellow, c.green, c.darkGreen, c.aqua, c.blue, c.purple, c.pink]; - const embeds = colors.map((c, i) => ({ ...o, title: `Embed Title ${i}`, color: c })); + const embeds = colors.map((c, i) => ({ ...o, title: `Embed Title ${i}`, color: c })); - const ButtonRows: ActionRowBuilder<ButtonBuilder>[] = []; - for (let a = 1; a <= 5; a++) { - const row = new ActionRowBuilder<ButtonBuilder>(); - for (let b = 1; b <= 5; b++) { - const id = (a + 5 * (b - 1)).toString(); - const button = new ButtonBuilder({ style: ButtonStyle.Secondary, customId: id, label: id }); - row.addComponents([button]); + const ButtonRows: ActionRowBuilder<ButtonBuilder>[] = []; + for (let a = 1; a <= 5; a++) { + const row = new ActionRowBuilder<ButtonBuilder>(); + for (let b = 1; b <= 5; b++) { + const id = (a + 5 * (b - 1)).toString(); + const button = new ButtonBuilder({ style: ButtonStyle.Secondary, customId: id, label: id }); + row.addComponents([button]); + } + ButtonRows.push(row); } - ButtonRows.push(row); - } - return await message.util.reply({ content: 'this is content', components: ButtonRows, embeds }); - } else if (['delete slash commands'].includes(args.feature?.toLowerCase())) { - if (!message.guild) return await message.util.reply(`${util.emojis.error} This test can only be run in a guild.`); - await client.guilds.fetch(); - const promises: Promise<Collection<string, ApplicationCommand>>[] = []; - client.guilds.cache.each((guild) => { - promises.push(guild.commands.set([])); - }); - await Promise.all(promises); + return await message.util.reply({ content: 'this is content', components: ButtonRows, embeds }); + } else if (['delete slash commands'].includes(args.feature?.toLowerCase())) { + if (!message.guild) return await message.util.reply(`${util.emojis.error} This test can only be run in a guild.`); + await client.guilds.fetch(); + const promises: Promise<Collection<string, ApplicationCommand>>[] = []; + client.guilds.cache.each((guild) => { + promises.push(guild.commands.set([])); + }); + await Promise.all(promises); - await client.application!.commands.fetch(); - await client.application!.commands.set([]); + await client.application!.commands.fetch(); + await client.application!.commands.set([]); - return await message.util.reply(`${util.emojis.success} Removed guild commands and global commands.`); - } else if (['drop down', 'drop downs', 'select menu', 'select menus'].includes(args.feature?.toLowerCase())) { - return message.util.reply(`${util.emojis.error} no`); - } else if (['sync automod'].includes(args.feature?.toLowerCase())) { - const row = (await Shared.findByPk(0))!; - row.badLinks = badLinksArray; - row.badLinksSecret = badLinksSecretArray; - row.badWords = badWords; - await row.save(); - return await message.util.reply(`${util.emojis.success} Synced automod.`); - } else if (['modal'].includes(args.feature?.toLowerCase())) { - const m = await message.util.reply({ - content: 'Click for modal', - components: [ - new ActionRowBuilder<ButtonBuilder>().addComponents([ - new ButtonBuilder({ style: ButtonStyle.Primary, label: 'Modal', customId: 'test;modal' }) - ]) - ] - }); + return await message.util.reply(`${util.emojis.success} Removed guild commands and global commands.`); + } else if (['drop down', 'drop downs', 'select menu', 'select menus'].includes(args.feature?.toLowerCase())) { + return message.util.reply(`${util.emojis.error} no`); + } else if (['sync automod'].includes(args.feature?.toLowerCase())) { + const row = (await Shared.findByPk(0))!; + row.badLinks = badLinksArray; + row.badLinksSecret = badLinksSecretArray; + row.badWords = badWords; + await row.save(); + return await message.util.reply(`${util.emojis.success} Synced automod.`); + } else if (['modal'].includes(args.feature?.toLowerCase())) { + const m = await message.util.reply({ + content: 'Click for modal', + components: [ + new ActionRowBuilder<ButtonBuilder>().addComponents([ + new ButtonBuilder({ style: ButtonStyle.Primary, label: 'Modal', customId: 'test;modal' }) + ]) + ] + }); - // eslint-disable-next-line @typescript-eslint/no-misused-promises - client.ws.on(GatewayDispatchEvents.InteractionCreate, async (i: any) => { - if (i?.data?.custom_id !== 'test;modal' || i?.data?.component_type !== 2) return; - if (i?.message?.id !== m.id) return; + // eslint-disable-next-line @typescript-eslint/no-misused-promises + client.ws.on(GatewayDispatchEvents.InteractionCreate, async (i: any) => { + if (i?.data?.custom_id !== 'test;modal' || i?.data?.component_type !== 2) return; + if (i?.message?.id !== m.id) return; - const text = { type: 4, style: 1, min_length: 1, max_length: 4000, required: true }; + const text = { type: 4, style: 1, min_length: 1, max_length: 4000, required: true }; - await this.client.rest.post(Routes.interactionCallback(i.id, i.token), { - body: { - type: 9, - data: { - custom_id: 'test;login', - title: 'Login (real)', - components: [ - { - type: 1, - components: [ - { - ...text, - custom_id: 'test;login;email', - label: 'Email', - placeholder: 'Email' - } - ] - }, - { - type: 1, - components: [ - { - ...text, - custom_id: 'test;login;password', - label: 'Password', - placeholder: 'Password' - } - ] - }, - { - type: 1, - components: [ - { - ...text, - custom_id: 'test;login;2fa', - label: 'Enter Discord Auth Code', - min_length: 6, - max_length: 6, - placeholder: '6-digit authentication code' - } - ] - } - ] + await this.client.rest.post(Routes.interactionCallback(i.id, i.token), { + body: { + type: 9, + data: { + custom_id: 'test;login', + title: 'Login (real)', + components: [ + { + type: 1, + components: [ + { + ...text, + custom_id: 'test;login;email', + label: 'Email', + placeholder: 'Email' + } + ] + }, + { + type: 1, + components: [ + { + ...text, + custom_id: 'test;login;password', + label: 'Password', + placeholder: 'Password' + } + ] + }, + { + type: 1, + components: [ + { + ...text, + custom_id: 'test;login;2fa', + label: 'Enter Discord Auth Code', + min_length: 6, + max_length: 6, + placeholder: '6-digit authentication code' + } + ] + } + ] + } } - } + }); }); - }); - return; + return; + } } return await message.util.reply(responses[Math.floor(Math.random() * responses.length)]); } diff --git a/src/commands/fun/coinFlip.ts b/src/commands/fun/coinFlip.ts index b0805cd..fea5cb5 100644 --- a/src/commands/fun/coinFlip.ts +++ b/src/commands/fun/coinFlip.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class CoinFlipCommand extends BushCommand { public constructor() { @@ -14,7 +14,7 @@ export default class CoinFlipCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { const random = Math.random(); let result: string; const fall = message.author.id === '322862723090219008' ? 0.1 : 0.001; //dw about it diff --git a/src/commands/fun/dice.ts b/src/commands/fun/dice.ts index 53fc9e2..b2bc7e4 100644 --- a/src/commands/fun/dice.ts +++ b/src/commands/fun/dice.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class DiceCommand extends BushCommand { public constructor() { @@ -14,7 +14,7 @@ export default class DiceCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { const responses = ['1', '2', '3', '4', '5', '6']; const answer = responses[Math.floor(Math.random() * responses.length)]; return await message.util.reply(`You rolled a **${answer}**.`); diff --git a/src/commands/fun/eightBall.ts b/src/commands/fun/eightBall.ts index ff06fe5..66fcc45 100644 --- a/src/commands/fun/eightBall.ts +++ b/src/commands/fun/eightBall.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType } from 'discord.js'; export default class EightBallCommand extends BushCommand { @@ -26,7 +26,7 @@ export default class EightBallCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { const responses = [ 'It is certain', 'Without a doubt', diff --git a/src/commands/fun/minesweeper.ts b/src/commands/fun/minesweeper.ts index 72551e9..d25cb5d 100644 --- a/src/commands/fun/minesweeper.ts +++ b/src/commands/fun/minesweeper.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, OptArgType, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import { Minesweeper } from '@notenoughupdates/discord.js-minesweeper'; import assert from 'assert'; import { ApplicationCommandOptionType } from 'discord.js'; @@ -53,10 +53,10 @@ export default class MinesweeperCommand extends BushCommand { optional: true }, { - id: 'do_not_reveal_first_cell', + id: 'no_reveal', description: 'Whether to not reveal the first cell automatically.', match: 'flag', - flag: ['--doNotRevealFirstCell', 'do_not_reveal_first_cell'], + flag: ['--noReveal', '--no_reveal', '--doNotRevealFirstCell', 'do_not_reveal_first_cell'], prompt: 'Would you like to not automatically reveal the first cell?', slashType: ApplicationCommandOptionType.Boolean, optional: true @@ -69,20 +69,24 @@ export default class MinesweeperCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { - rows: ArgType<'integer'>; - columns: ArgType<'integer'>; - mines: ArgType<'integer'>; - spaces: boolean; - do_not_reveal_first_cell: boolean; + rows: OptArgType<'integer'>; + columns: OptArgType<'integer'>; + mines: OptArgType<'integer'>; + spaces: ArgType<'flag'>; + no_reveal: ArgType<'flag'>; } ) { + args.rows ??= 9; + args.columns ??= 9; + args.mines ??= 10; + const minesweeper = new Minesweeper({ rows: args.rows, columns: args.columns, mines: args.mines, - revealFirstCell: args.do_not_reveal_first_cell ? false : true, + revealFirstCell: args.no_reveal ? false : true, spaces: args.spaces ?? false, zeroFirstCell: false }); diff --git a/src/commands/info/avatar.ts b/src/commands/info/avatar.ts index 870908d..544c30a 100644 --- a/src/commands/info/avatar.ts +++ b/src/commands/info/avatar.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType, EmbedBuilder, GuildMember, PermissionFlagsBits } from 'discord.js'; export default class AvatarCommand extends BushCommand { @@ -27,11 +27,12 @@ export default class AvatarCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { user: ArgType<'member'> | ArgType<'globalUser'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { user: OptArgType<'member' | 'globalUser'> }) { const params: { size: 2048; extension: 'png'; dynamic: true } = { size: 2048, extension: 'png', dynamic: true }; const defaultAvatar = `https://cdn.discordapp.com/embed/avatars/${Math.ceil(Math.random() * 6) - 1}.png`; - const member = (args.user ?? message.member) instanceof GuildMember ? args.user ?? message.member : undefined; + const member = + (args.user ?? message.member) instanceof GuildMember ? args.user ?? (message.member as GuildMember | null) : null; const user = args.user instanceof GuildMember ? args.user.user : args.user ?? message.author; const guildAvatar = member?.avatarURL(params); diff --git a/src/commands/info/botInfo.ts b/src/commands/info/botInfo.ts index e67ae5a..4a8a36a 100644 --- a/src/commands/info/botInfo.ts +++ b/src/commands/info/botInfo.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { EmbedBuilder, PermissionFlagsBits, version as discordJSVersion } from 'discord.js'; import * as os from 'os'; @@ -20,7 +20,7 @@ export default class BotInfoCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { enum Platform { aix = 'AIX', android = 'Android', diff --git a/src/commands/info/color.ts b/src/commands/info/color.ts index a74c3f3..f60e28a 100644 --- a/src/commands/info/color.ts +++ b/src/commands/info/color.ts @@ -1,25 +1,9 @@ -import { - AllowedMentions, - BushCommand, - type ArgType, - type BushArgumentTypeCaster, - type BushGuildMember, - type BushMessage, - type BushRole, - type BushSlashMessage -} from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; -import { ApplicationCommandOptionType, EmbedBuilder, PermissionFlagsBits, Role } from 'discord.js'; +import { ApplicationCommandOptionType, EmbedBuilder, GuildMember, PermissionFlagsBits, Role } from 'discord.js'; import tinycolor from 'tinycolor2'; - assert(tinycolor); -const isValidTinyColor: BushArgumentTypeCaster<string | null> = (_message, phase) => { - // if the phase is a number it converts it to hex incase it could be representing a color in decimal - const newPhase = isNaN(phase as any) ? phase : `#${Number(phase).toString(16)}`; - return tinycolor(newPhase).isValid() ? newPhase : null; -}; - export default class ColorCommand extends BushCommand { public constructor() { super('color', { @@ -32,7 +16,7 @@ export default class ColorCommand extends BushCommand { { id: 'color', description: 'The color string, role, or member to find the color of.', - type: util.arg.union(isValidTinyColor as any, 'role', 'member'), + type: util.arg.union('tinyColor', 'role', 'member'), readableType: 'color|role|member', match: 'restContent', prompt: 'What color code, role, or user would you like to find the color of?', @@ -50,15 +34,12 @@ export default class ColorCommand extends BushCommand { return color.substring(4, color.length - 5); } - public override async exec( - message: BushMessage | BushSlashMessage, - args: { color: string | ArgType<'role'> | ArgType<'member'> } - ) { + public override async exec(message: CommandMessage | SlashMessage, args: { color: ArgType<'tinyColor' | 'role' | 'member'> }) { const _color = message.util.isSlashMessage(message) - ? ((await util.arg.cast(util.arg.union(isValidTinyColor, 'role', 'member'), message, args.color as string)) as + ? ((await util.arg.cast(util.arg.union('tinyColor', 'role', 'member'), message, args.color as string)) as | string - | BushRole - | BushGuildMember) + | Role + | GuildMember) : args.color; const color = diff --git a/src/commands/info/guildInfo.ts b/src/commands/info/guildInfo.ts index 4872497..572cf06 100644 --- a/src/commands/info/guildInfo.ts +++ b/src/commands/info/guildInfo.ts @@ -1,10 +1,12 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib'; +import { BushCommand, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import assert from 'assert'; -import { GuildDefaultMessageNotifications, GuildExplicitContentFilter } from 'discord-api-types/v10'; import { ApplicationCommandOptionType, + ChannelType, EmbedBuilder, Guild, + GuildDefaultMessageNotifications, + GuildExplicitContentFilter, GuildMFALevel, GuildPremiumTier, GuildVerificationLevel, @@ -41,17 +43,14 @@ export default class GuildInfoCommand extends BushCommand { }); } - public override async exec( - message: BushMessage | BushSlashMessage, - args: { guild: OptArgType<'guild'> | OptArgType<'snowflake'> } - ) { + public override async exec(message: CommandMessage | SlashMessage, args: { guild: OptArgType<'guild' | 'snowflake'> }) { if (!args.guild && !message.inGuild()) { return await message.util.reply( `${util.emojis.error} You must either provide an server to provide info about or run this command in a server.` ); } - let guild: ArgType<'guild'> | ArgType<'snowflake'> | GuildPreview = args.guild ?? message.guild!; + let guild: ArgType<'guild' | 'snowflake'> | GuildPreview = args.guild ?? message.guild!; if (typeof guild === 'string') { const preview = await client.fetchGuildPreview(`${args.guild}` as Snowflake).catch(() => undefined); if (preview) guild = preview; @@ -163,10 +162,19 @@ export default class GuildInfoCommand extends BushCommand { const guildStats: string[] = []; - const channelTypes = (['Text', 'Voice', 'News', 'Stage', 'Category', 'Thread'] as const).map( + const channelTypes = ( + [ + ['Text', [ChannelType.GuildText]], + ['Voice', [ChannelType.GuildVoice]], + ['News', [ChannelType.GuildNews]], + ['Stage', [ChannelType.GuildStageVoice]], + ['Category', [ChannelType.GuildCategory]], + ['Thread', [ChannelType.GuildNewsThread, ChannelType.GuildPrivateThread, ChannelType.GuildPublicThread]] + ] as const + ).map( (type) => - `${client.consts.mappings.otherEmojis[`Channel${type}`]} ${guild.channels.cache - .filter((channel) => channel[`is${type}`]()) + `${client.consts.mappings.otherEmojis[`Channel${type[0]}`]} ${guild.channels.cache + .filter((channel) => type[1].some((type) => channel.type === type)) .size.toLocaleString()}` ); diff --git a/src/commands/info/help.ts b/src/commands/info/help.ts index ea1e965..af44980 100644 --- a/src/commands/info/help.ts +++ b/src/commands/info/help.ts @@ -1,10 +1,10 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; -import { ButtonBuilder } from '@discordjs/builders'; +import { BushCommand, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import assert from 'assert'; import { ActionRowBuilder, ApplicationCommandOptionType, AutocompleteInteraction, + ButtonBuilder, ButtonStyle, EmbedBuilder, PermissionFlagsBits @@ -53,7 +53,7 @@ export default class HelpCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: HelpArgs) { + public override async exec(message: CommandMessage | SlashMessage, args: HelpArgs) { const row = this.addLinks(message); const command = args.command ? typeof args.command === 'string' @@ -70,7 +70,7 @@ export default class HelpCommand extends BushCommand { } } - private helpAll(message: BushMessage | BushSlashMessage, args: HelpArgs, row: ActionRowBuilder<ButtonBuilder>) { + private helpAll(message: CommandMessage | SlashMessage, args: HelpArgs, row: ActionRowBuilder<ButtonBuilder>) { const prefix = util.prefix(message); const embed = new EmbedBuilder() .setColor(util.colors.default) @@ -99,7 +99,7 @@ export default class HelpCommand extends BushCommand { return message.util.reply({ embeds: [embed], components: row.components.length ? [row] : undefined }); } - private helpIndividual(message: BushMessage | BushSlashMessage, row: ActionRowBuilder<ButtonBuilder>, command: BushCommand) { + private helpIndividual(message: CommandMessage | SlashMessage, row: ActionRowBuilder<ButtonBuilder>, command: BushCommand) { const embed = new EmbedBuilder().setColor(util.colors.default).setTitle(`${command.id} Command`); let description = `${command.description ?? '*This command does not have a description.*'}`; @@ -207,7 +207,7 @@ export default class HelpCommand extends BushCommand { } } - private addLinks(message: BushMessage | BushSlashMessage) { + private addLinks(message: CommandMessage | SlashMessage) { const row = new ActionRowBuilder<ButtonBuilder>(); if (!client.config.isDevelopment && !client.guilds.cache.some((guild) => guild.ownerId === message.author.id)) { @@ -246,4 +246,4 @@ export default class HelpCommand extends BushCommand { } } -type HelpArgs = { command: ArgType<'commandAlias'> | string; showHidden?: boolean }; +type HelpArgs = { command: OptArgType<'commandAlias'> | string; showHidden: ArgType<'flag'> }; diff --git a/src/commands/info/icon.ts b/src/commands/info/icon.ts index db390a5..9c9556b 100644 --- a/src/commands/info/icon.ts +++ b/src/commands/info/icon.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { EmbedBuilder, PermissionFlagsBits } from 'discord.js'; @@ -17,7 +17,7 @@ export default class IconCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { assert(message.inGuild()); const embed = new EmbedBuilder() diff --git a/src/commands/info/links.ts b/src/commands/info/links.ts index 91b62ca..0d5bd15 100644 --- a/src/commands/info/links.ts +++ b/src/commands/info/links.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js'; import packageDotJSON from '../../../package.json' assert { type: 'json' }; @@ -19,7 +19,7 @@ export default class LinksCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { const buttonRow = new ActionRowBuilder<ButtonBuilder>(); if (!client.config.isDevelopment || message.author.isOwner()) { buttonRow.addComponents([new ButtonBuilder({ style: ButtonStyle.Link, label: 'Invite Me', url: util.invite })]); diff --git a/src/commands/info/ping.ts b/src/commands/info/ping.ts index af0fa98..ad7fdcc 100644 --- a/src/commands/info/ping.ts +++ b/src/commands/info/ping.ts @@ -1,5 +1,5 @@ -import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; -import { EmbedBuilder, PermissionFlagsBits } from 'discord.js'; +import { BushCommand, type CommandMessage, type SlashMessage } from '#lib'; +import { EmbedBuilder, PermissionFlagsBits, type Message } from 'discord.js'; export default class PingCommand extends BushCommand { public constructor() { @@ -15,21 +15,21 @@ export default class PingCommand extends BushCommand { }); } - public override async exec(message: BushMessage) { + public override async exec(message: CommandMessage) { const timestamp1 = message.editedTimestamp ? message.editedTimestamp : message.createdTimestamp; const msg = await message.util.reply('Pong!'); const timestamp2 = msg.editedTimestamp ? msg.editedTimestamp : msg.createdTimestamp; void this.command(message, timestamp2 - timestamp1); } - public override async execSlash(message: BushSlashMessage) { + public override async execSlash(message: SlashMessage) { const timestamp1 = message.createdTimestamp; - const msg = (await message.util.reply({ content: 'Pong!', fetchReply: true })) as BushMessage; + const msg = (await message.util.reply({ content: 'Pong!', fetchReply: true })) as Message; const timestamp2 = msg.editedTimestamp ? msg.editedTimestamp : msg.createdTimestamp; void this.command(message, timestamp2 - timestamp1); } - private command(message: BushMessage | BushSlashMessage, msgLatency: number) { + private command(message: CommandMessage | SlashMessage, msgLatency: number) { const botLatency = util.format.codeBlock(`${Math.round(msgLatency)}ms`); const apiLatency = util.format.codeBlock(`${Math.round(message.client.ws.ping)}ms`); const embed = new EmbedBuilder() diff --git a/src/commands/info/pronouns.ts b/src/commands/info/pronouns.ts index b45f9b3..f916687 100644 --- a/src/commands/info/pronouns.ts +++ b/src/commands/info/pronouns.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; export default class PronounsCommand extends BushCommand { @@ -26,7 +26,7 @@ export default class PronounsCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { user?: ArgType<'globalUser'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { user: OptArgType<'globalUser'> }) { const user = args.user ?? message.author; const author = user.id === message.author.id; diff --git a/src/commands/info/snowflake.ts b/src/commands/info/snowflake.ts index 07544c9..e74756f 100644 --- a/src/commands/info/snowflake.ts +++ b/src/commands/info/snowflake.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import { stripIndent } from '#tags'; import { ApplicationCommandOptionType, @@ -37,7 +37,7 @@ export default class SnowflakeCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { snowflake: ArgType<'snowflake'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { snowflake: ArgType<'snowflake'> }) { const snowflake = `${args.snowflake}` as Snowflake; const snowflakeEmbed = new EmbedBuilder().setTitle('Unknown :snowflake:').setColor(util.colors.default); @@ -45,7 +45,7 @@ export default class SnowflakeCommand extends BushCommand { if (client.channels.cache.has(snowflake)) { const channel = client.channels.resolve(snowflake)!; const channelInfo = [`**Type:** ${BushChannelType[channel.type] ?? ChannelType[channel.type]}`]; - if (channel.isDM()) { + if (channel.type === ChannelType.DM) { channelInfo.push( `**Recipient:** ${util.discord.escapeMarkdown(channel.recipient?.tag ?? '¯\\_(ツ)_/¯')} (${ channel.recipient?.id ?? '¯\\_(ツ)_/¯' @@ -55,11 +55,11 @@ export default class SnowflakeCommand extends BushCommand { `:snowflake: DM with ${util.discord.escapeMarkdown(channel.recipient?.tag ?? '¯\\_(ツ)_/¯')} \`[Channel]\`` ); } else if ( - channel.isCategory() || - channel.isNews() || - channel.isText() || - channel.isVoice() || - channel.isStage() || + channel.type === ChannelType.GuildCategory || + channel.type === ChannelType.GuildNews || + channel.type === ChannelType.GuildText || + channel.type === ChannelType.GuildVoice || + channel.type === ChannelType.GuildStageVoice || channel.isThread() ) { channelInfo.push( diff --git a/src/commands/info/userInfo.ts b/src/commands/info/userInfo.ts index cb2fc5f..d617756 100644 --- a/src/commands/info/userInfo.ts +++ b/src/commands/info/userInfo.ts @@ -1,22 +1,17 @@ -import { - BushCommand, - Time, - type ArgType, - type BushGuild, - type BushGuildMember, - type BushMessage, - type BushSlashMessage, - type BushUser -} from '#lib'; -import { TeamMemberMembershipState, type APIApplication } from 'discord-api-types/v10'; +import { BushCommand, Time, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import { ActivityType, ApplicationCommandOptionType, ApplicationFlagsBitField, - ApplicationFlagsString, EmbedBuilder, PermissionFlagsBits, - UserFlags + TeamMemberMembershipState, + UserFlags, + type APIApplication, + type ApplicationFlagsString, + type Guild, + type GuildMember, + type User } from 'discord.js'; export default class UserInfoCommand extends BushCommand { @@ -45,7 +40,7 @@ export default class UserInfoCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { user: ArgType<'user'> | ArgType<'snowflake'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { user: OptArgType<'user' | 'snowflake'> }) { const user = args.user === null ? message.author @@ -61,7 +56,7 @@ export default class UserInfoCommand extends BushCommand { return await message.util.reply({ embeds: [userEmbed] }); } - public static async makeUserInfoEmbed(user: BushUser, member?: BushGuildMember, guild?: BushGuild | null) { + public static async makeUserInfoEmbed(user: User, member?: GuildMember, guild?: Guild | null) { const emojis = []; const superUsers = util.getShared('superUsers'); @@ -121,7 +116,7 @@ export default class UserInfoCommand extends BushCommand { return userEmbed; } - public static async generateGeneralInfoField(embed: EmbedBuilder, user: BushUser, title = '» General Information') { + public static async generateGeneralInfoField(embed: EmbedBuilder, user: User, title = '» General Information') { // General Info const generalInfo = [ `**Mention:** <@${user.id}>`, @@ -138,11 +133,7 @@ export default class UserInfoCommand extends BushCommand { embed.addFields([{ name: title, value: generalInfo.join('\n') }]); } - public static generateServerInfoField( - embed: EmbedBuilder, - member?: BushGuildMember | undefined, - title = '» Server Information' - ) { + public static generateServerInfoField(embed: EmbedBuilder, member?: GuildMember | undefined, title = '» Server Information') { if (!member) return; // Server User Info @@ -167,7 +158,7 @@ export default class UserInfoCommand extends BushCommand { if (serverUserInfo.length) embed.addFields([{ name: title, value: serverUserInfo.join('\n') }]); } - public static generatePresenceField(embed: EmbedBuilder, member?: BushGuildMember | undefined, title = '» Presence') { + public static generatePresenceField(embed: EmbedBuilder, member?: GuildMember | undefined, title = '» Presence') { if (!member || !member.presence) return; if (!member.presence.status && !member.presence.clientStatus && !member.presence.activities) return; @@ -207,7 +198,7 @@ export default class UserInfoCommand extends BushCommand { }); } - public static generateRolesField(embed: EmbedBuilder, member?: BushGuildMember | undefined) { + public static generateRolesField(embed: EmbedBuilder, member?: GuildMember | undefined) { if (!member || member.roles.cache.size <= 1) return; // roles @@ -227,7 +218,7 @@ export default class UserInfoCommand extends BushCommand { public static generatePermissionsField( embed: EmbedBuilder, - member: BushGuildMember | undefined, + member: GuildMember | undefined, title = '» Important Permissions' ) { if (!member) return; @@ -247,7 +238,7 @@ export default class UserInfoCommand extends BushCommand { if (perms.length) embed.addFields([{ name: title, value: perms.join(' ') }]); } - public static async generateBotField(embed: EmbedBuilder, user: BushUser, title = '» Bot Information') { + public static async generateBotField(embed: EmbedBuilder, user: User, title = '» Bot Information') { if (!user.bot) return; const applicationInfo = (await client.rest.get(`/applications/${user.id}/rpc`).catch(() => null)) as APIApplication | null; diff --git a/src/commands/leveling/leaderboard.ts b/src/commands/leveling/leaderboard.ts index f476ac1..040ed4a 100644 --- a/src/commands/leveling/leaderboard.ts +++ b/src/commands/leveling/leaderboard.ts @@ -1,4 +1,4 @@ -import { BushCommand, ButtonPaginator, Level, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, ButtonPaginator, Level, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; @@ -28,7 +28,7 @@ export default class LeaderboardCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { page: ArgType<'integer'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { page: OptArgType<'integer'> }) { assert(message.inGuild()); if (!(await message.guild.hasFeature('leveling'))) diff --git a/src/commands/leveling/level.ts b/src/commands/leveling/level.ts index 3a9a916..34a839a 100644 --- a/src/commands/leveling/level.ts +++ b/src/commands/leveling/level.ts @@ -3,16 +3,14 @@ import { BushCommand, CanvasProgressBar, Level, - type BushGuild, - type BushMessage, - type BushSlashMessage, - type BushUser, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import { SimplifyNumber } from '@notenoughupdates/simplify-number'; import assert from 'assert'; import canvas from 'canvas'; -import { ApplicationCommandOptionType, Attachment, PermissionFlagsBits } from 'discord.js'; +import { ApplicationCommandOptionType, AttachmentBuilder, Guild, PermissionFlagsBits, User } from 'discord.js'; import got from 'got'; import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; @@ -46,7 +44,7 @@ export default class LevelCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { user: OptArgType<'user'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { user: OptArgType<'user'> }) { assert(message.inGuild()); if (!(await message.guild.hasFeature('leveling'))) @@ -60,7 +58,7 @@ export default class LevelCommand extends BushCommand { const user = args.user ?? message.author; try { return await message.util.reply({ - files: [new Attachment(await this.getImage(user, message.guild), 'level.png')] + files: [new AttachmentBuilder(await this.getImage(user, message.guild), { name: 'level.png' })] }); } catch (e) { if (e instanceof Error && e.message === 'User does not have a level') { @@ -72,7 +70,7 @@ export default class LevelCommand extends BushCommand { } } - private async getImage(user: BushUser, guild: BushGuild): Promise<Buffer> { + private async getImage(user: User, guild: Guild): Promise<Buffer> { const guildRows = await Level.findAll({ where: { guild: guild.id } }); const rank = guildRows.sort((a, b) => b.xp - a.xp); const userLevelRow = guildRows.find((a) => a.user === user.id); diff --git a/src/commands/leveling/levelRoles.ts b/src/commands/leveling/levelRoles.ts index 9fe7dd0..afa4ab6 100644 --- a/src/commands/leveling/levelRoles.ts +++ b/src/commands/leveling/levelRoles.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -39,7 +39,7 @@ export default class LevelRolesCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { level: ArgType<'integer'>; role: OptArgType<'role'> } ) { assert(message.inGuild()); diff --git a/src/commands/leveling/setLevel.ts b/src/commands/leveling/setLevel.ts index ac7df57..8abdb57 100644 --- a/src/commands/leveling/setLevel.ts +++ b/src/commands/leveling/setLevel.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, Level, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, Level, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -36,7 +36,7 @@ export default class SetLevelCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, { user, level }: { user: ArgType<'user'>; level: ArgType<'integer'> } ) { assert(message.inGuild()); diff --git a/src/commands/leveling/setXp.ts b/src/commands/leveling/setXp.ts index 1f7c981..60e0b94 100644 --- a/src/commands/leveling/setXp.ts +++ b/src/commands/leveling/setXp.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, Level, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, Level, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -37,7 +37,7 @@ export default class SetXpCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, { user, xp }: { user: ArgType<'user'>; xp: ArgType<'abbreviatedNumber'> } ) { assert(message.inGuild()); diff --git a/src/commands/moderation/_activePunishments.ts b/src/commands/moderation/_activePunishments.ts index e751493..92b4242 100644 --- a/src/commands/moderation/_activePunishments.ts +++ b/src/commands/moderation/_activePunishments.ts @@ -1,79 +1,78 @@ -/* import { BushCommand, ModLog, ModLogModel, type BushGuildMember, type BushMessage, type BushSlashMessage } from '#lib'; -import { FindOptions, Op } from 'sequelize'; -import { Permissions } from 'discord.js'; +// import { BushCommand, ModLog, ModLogModel, OptArgType, type CommandMessage, type SlashMessage } from '#lib'; +// import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; +// import { FindOptions, Op } from 'sequelize'; -const punishmentTypes = ['ban', 'kick', 'mute', 'warn', 'role'] as const; +// const punishmentTypes = ['ban', 'kick', 'mute', 'warn', 'role'] as const; -export default class ActivePunishmentsCommand extends BushCommand { - public constructor() { - super('activePunishments', { - aliases: ['active-punishments', 'ap'], - category: 'moderation', - description: 'Gets a list of all the active punishment in the server.', - usage: [`active-punishments [--moderator <user>] [--type <${punishmentTypes.map((v) => `'${v}'`).join('|')}>]`], - examples: ['active-punishments'], - args: [ - { - id: 'moderator', - description: 'Only show active punishments by this moderator.', - type: 'user', - match: 'option', - prompt: 'Only show active punishments from what user?', - optional: true, - slashType: ApplicationCommandOptionType.User, - slashResolve: 'Member' - }, - { - id: 'type', - description: 'Only show active punishments of this type.', - customType: [...punishmentTypes], - readableType: punishmentTypes.map((v) => `'${v}'`).join('|'), - match: 'option', - optional: true, - slashType: ApplicationCommandOptionType.String, - choices: punishmentTypes.map((v) => ({ name: v, value: v })) - } - ], - slash: true, - channel: 'guild', - hidden: true, - clientPermissions: (m) => util.clientSendAndPermCheck(m), - userPermissions: (m) => util.userGuildPermCheck(m, [PermissionFlagsBits.ManageMessages]) - }); - } +// export default class ActivePunishmentsCommand extends BushCommand { +// public constructor() { +// super('activePunishments', { +// aliases: ['active-punishments', 'ap'], +// category: 'moderation', +// description: 'Gets a list of all the active punishment in the server.', +// usage: [`active-punishments [--moderator <user>] [--type <${punishmentTypes.map((v) => `'${v}'`).join('|')}>]`], +// examples: ['active-punishments'], +// args: [ +// { +// id: 'moderator', +// description: 'Only show active punishments by this moderator.', +// type: 'user', +// match: 'option', +// prompt: 'Only show active punishments from what user?', +// optional: true, +// slashType: ApplicationCommandOptionType.User, +// slashResolve: 'Member' +// }, +// { +// id: 'type', +// description: 'Only show active punishments of this type.', +// customType: [...punishmentTypes], +// readableType: punishmentTypes.map((v) => `'${v}'`).join('|'), +// match: 'option', +// optional: true, +// slashType: ApplicationCommandOptionType.String, +// choices: punishmentTypes.map((v) => ({ name: v, value: v })) +// } +// ], +// slash: true, +// channel: 'guild', +// hidden: true, +// clientPermissions: (m) => util.clientSendAndPermCheck(m), +// userPermissions: (m) => util.userGuildPermCheck(m, [PermissionFlagsBits.ManageMessages]) +// }); +// } - public override async exec( - message: BushMessage | BushSlashMessage, - args: { moderator?: BushGuildMember; type: typeof punishmentTypes[number] } - ) { - const where: FindOptions<ModLogModel>['where'] = { guild: message.guild!.id }; - if (args.moderator?.id) where.user = args.moderator.id; - if (args.type) { - switch (args.type) { - case 'ban': - where.type = { [Op.or]: ['PERM_BAN', 'TEMP_BAN', 'UNBAN'] }; - break; - case 'kick': - where.type = { [Op.or]: ['KICK'] }; - break; - case 'mute': - where.type = { [Op.or]: ['PERM_MUTE', 'TEMP_MUTE', 'UNMUTE'] }; - break; - case 'warn': - where.type = { [Op.or]: ['WARN'] }; - break; - case 'role': - where.type = { [Op.or]: ['PERM_PUNISHMENT_ROLE', 'TEMP_PUNISHMENT_ROLE', 'REMOVE_PUNISHMENT_ROLE'] }; - break; - default: - return message.util.reply(`${util.emojis.error} You supplied an invalid case type to filter by.`); - } - } +// public override async exec( +// message: CommandMessage | SlashMessage, +// args: { moderator: OptArgType<'user' | 'member'>; type: typeof punishmentTypes[number] } +// ) { +// const where: FindOptions<ModLogModel>['where'] = { guild: message.guild!.id }; +// if (args.moderator?.id) where.user = args.moderator.id; +// if (args.type) { +// switch (args.type) { +// case 'ban': +// where.type = { [Op.or]: ['PERM_BAN', 'TEMP_BAN', 'UNBAN'] }; +// break; +// case 'kick': +// where.type = { [Op.or]: ['KICK'] }; +// break; +// case 'mute': +// where.type = { [Op.or]: ['PERM_MUTE', 'TEMP_MUTE', 'UNMUTE'] }; +// break; +// case 'warn': +// where.type = { [Op.or]: ['WARN'] }; +// break; +// case 'role': +// where.type = { [Op.or]: ['PERM_PUNISHMENT_ROLE', 'TEMP_PUNISHMENT_ROLE', 'REMOVE_PUNISHMENT_ROLE'] }; +// break; +// default: +// return message.util.reply(`${util.emojis.error} You supplied an invalid case type to filter by.`); +// } +// } - const logs = await ModLog.findAll({ - where, - order: [['createdAt', 'ASC']] - }); - } -} - */ +// const logs = await ModLog.findAll({ +// where, +// order: [['createdAt', 'ASC']] +// }); +// } +// } diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts index 77951c3..f4bd52b 100644 --- a/src/commands/moderation/ban.ts +++ b/src/commands/moderation/ban.ts @@ -4,9 +4,9 @@ import { BushCommand, Moderation, type ArgType, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -71,12 +71,12 @@ export default class BanCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { - user: ArgType<'user'> | ArgType<'snowflake'>; + user: ArgType<'user' | 'snowflake'>; reason_and_duration: OptArgType<'contentWithDuration'> | string; days: OptArgType<'integer'>; - force: boolean; + force: ArgType<'flag'>; } ) { assert(message.inGuild()); diff --git a/src/commands/moderation/block.ts b/src/commands/moderation/block.ts index 722f08b..16beb6f 100644 --- a/src/commands/moderation/block.ts +++ b/src/commands/moderation/block.ts @@ -4,9 +4,9 @@ import { BushCommand, Moderation, type ArgType, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -58,15 +58,16 @@ export default class BlockCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { user: ArgType<'user'>; reason_and_duration: OptArgType<'contentWithDuration'> | string; - force?: ArgType<'boolean'>; + force: ArgType<'flag'>; } ) { assert(message.inGuild()); assert(message.member); + assert(message.channel); if (!message.channel.isTextBased()) return message.util.send(`${util.emojis.error} This command can only be used in text based channels.`); diff --git a/src/commands/moderation/evidence.ts b/src/commands/moderation/evidence.ts index 9b63189..f1fac0d 100644 --- a/src/commands/moderation/evidence.ts +++ b/src/commands/moderation/evidence.ts @@ -1,8 +1,7 @@ -import { BushCommand, ModLog, OptArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, ModLog, OptArgType, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; -import { ArgumentGeneratorReturn } from 'discord-akairo'; -import { Argument, ArgumentTypeCasterReturn } from 'discord-akairo/dist/src/struct/commands/arguments/Argument.js'; -import { ApplicationCommandOptionType, PermissionFlagsBits, User } from 'discord.js'; +import { Argument, ArgumentGeneratorReturn } from 'discord-akairo'; +import { ApplicationCommandOptionType, PermissionFlagsBits, type Message } from 'discord.js'; export default class EvidenceCommand extends BushCommand { public constructor() { @@ -48,8 +47,8 @@ export default class EvidenceCommand extends BushCommand { }); } - public override *args(message: BushMessage): ArgumentGeneratorReturn { - const target: ArgumentTypeCasterReturn<'string'> | ArgumentTypeCasterReturn<'snowflake'> = yield { + public override *args(message: CommandMessage): ArgumentGeneratorReturn { + const target: ArgType<'string' | 'snowflake'> = yield { id: 'target', type: Argument.union('snowflake', 'string'), prompt: { @@ -59,7 +58,7 @@ export default class EvidenceCommand extends BushCommand { } }; - const evidence: ArgumentTypeCasterReturn<'string'> = yield { + const evidence: OptArgType<'string'> = yield { id: 'evidence', type: 'string', match: 'restContent', @@ -74,13 +73,18 @@ export default class EvidenceCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, { case_id: caseID, user, target: messageCommandTarget, evidence - }: { case_id?: string; user?: User; target: string | User; evidence: OptArgType<'string'> } + }: { + case_id: OptArgType<'string'>; + user: OptArgType<'user'>; + target: ArgType<'string' | 'snowflake'>; + evidence: OptArgType<'string'>; + } ) { assert(message.inGuild()); @@ -88,22 +92,13 @@ export default class EvidenceCommand extends BushCommand { return message.util.send(`${util.emojis.error} You must provide either a user or a case ID.`); const entry = messageCommandTarget - ? typeof messageCommandTarget == 'string' - ? await ModLog.findByPk(messageCommandTarget) - : await ModLog.findOne({ - where: { - user: messageCommandTarget.id - }, - order: [['createdAt', 'DESC']] - }) + ? util.consts.regex.snowflake.test(messageCommandTarget) + ? await ModLog.findOne({ where: { user: messageCommandTarget }, order: [['createdAt', 'DESC']] }) + : await ModLog.findByPk(messageCommandTarget) : caseID ? await ModLog.findByPk(caseID) - : await ModLog.findOne({ - where: { - user: user!.id - }, - order: [['createdAt', 'DESC']] - }); + : await ModLog.findOne({ where: { user: user!.id }, order: [['createdAt', 'DESC']] }); + if (!entry || entry.pseudo) return message.util.send(`${util.emojis.error} Invalid modlog entry.`); if (entry.guild !== message.guild.id) return message.util.reply(`${util.emojis.error} This modlog is from another server.`); @@ -122,8 +117,8 @@ export default class EvidenceCommand extends BushCommand { ); } - public static getEvidence(message: BushMessage | BushSlashMessage, evidenceArg: OptArgType<'string'>): null | string { - if (evidenceArg && (message as BushMessage).attachments?.size) { + public static getEvidence(message: CommandMessage | SlashMessage, evidenceArg: OptArgType<'string'>): null | string { + if (evidenceArg && (message as Message).attachments?.size) { void message.util.reply(`${util.emojis.error} Please either attach an image or a reason not both.`); return null; } @@ -131,7 +126,7 @@ export default class EvidenceCommand extends BushCommand { const _evidence = evidenceArg ? evidenceArg : !message.util.isSlash - ? (message as BushMessage).attachments.first()?.url + ? (message as Message).attachments.first()?.url : undefined; if (!_evidence) { void message.util.reply(`${util.emojis.error} You must provide evidence for this modlog.`); diff --git a/src/commands/moderation/hideCase.ts b/src/commands/moderation/hideCase.ts index 8cec66e..fc5baf4 100644 --- a/src/commands/moderation/hideCase.ts +++ b/src/commands/moderation/hideCase.ts @@ -1,4 +1,4 @@ -import { BushCommand, ModLog, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, ModLog, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -27,7 +27,7 @@ export default class HideCaseCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, { case_id: caseID }: { case_id: string }) { + public override async exec(message: CommandMessage | SlashMessage, { case_id: caseID }: { case_id: string }) { assert(message.inGuild()); const entry = await ModLog.findByPk(caseID); diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts index 26098b5..a9a0336 100644 --- a/src/commands/moderation/kick.ts +++ b/src/commands/moderation/kick.ts @@ -4,8 +4,9 @@ import { kickResponse, Moderation, type ArgType, - type BushMessage, - type BushSlashMessage + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -55,8 +56,8 @@ export default class KickCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - { user, reason, force }: { user: ArgType<'user'>; reason: ArgType<'string'>; force: boolean } + message: CommandMessage | SlashMessage, + { user, reason, force }: { user: ArgType<'user'>; reason: OptArgType<'string'>; force: ArgType<'flag'> } ) { assert(message.inGuild()); assert(message.member); diff --git a/src/commands/moderation/lockdown.ts b/src/commands/moderation/lockdown.ts index d10a5d4..7d8211c 100644 --- a/src/commands/moderation/lockdown.ts +++ b/src/commands/moderation/lockdown.ts @@ -3,9 +3,9 @@ import { BushCommand, ConfirmationPrompt, type ArgType, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { @@ -72,22 +72,22 @@ export default class LockdownCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { - channel: OptArgType<'textChannel'> | OptArgType<'newsChannel'> | OptArgType<'threadChannel'>; + channel: OptArgType<'textChannel' | 'newsChannel' | 'threadChannel' | 'voiceChannel'>; reason: OptArgType<'string'>; - all: ArgType<'boolean'>; + all: ArgType<'flag'>; } ) { return await LockdownCommand.lockdownOrUnlockdown(message, args, 'lockdown'); } public static async lockdownOrUnlockdown( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { - channel: OptArgType<'textChannel'> | OptArgType<'newsChannel'> | OptArgType<'threadChannel'> | OptArgType<'voiceChannel'>; + channel: OptArgType<'textChannel' | 'newsChannel' | 'threadChannel' | 'voiceChannel'>; reason: OptArgType<'string'>; - all: ArgType<'boolean'>; + all: ArgType<'flag'>; }, action: 'lockdown' | 'unlockdown' ) { diff --git a/src/commands/moderation/massBan.ts b/src/commands/moderation/massBan.ts index f1d85ed..a25c64f 100644 --- a/src/commands/moderation/massBan.ts +++ b/src/commands/moderation/massBan.ts @@ -3,9 +3,9 @@ import { banResponse, BushCommand, type ArgType, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, Collection, PermissionFlagsBits } from 'discord.js'; @@ -61,7 +61,7 @@ export default class MassBanCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { users: ArgType<'string'>; reason: OptArgType<'string'>; days: OptArgType<'integer'> } ) { assert(message.inGuild()); diff --git a/src/commands/moderation/massEvidence.ts b/src/commands/moderation/massEvidence.ts index 67f5a25..468d43c 100644 --- a/src/commands/moderation/massEvidence.ts +++ b/src/commands/moderation/massEvidence.ts @@ -1,4 +1,4 @@ -import { BushCommand, ModLog, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib'; +import { BushCommand, ModLog, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; import { EvidenceCommand } from '../index.js'; @@ -44,7 +44,7 @@ export default class MassEvidenceCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { users: ArgType<'string'>; evidence: OptArgType<'string'> } ) { assert(message.inGuild()); diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts index 66368f9..71ed975 100644 --- a/src/commands/moderation/modlog.ts +++ b/src/commands/moderation/modlog.ts @@ -1,4 +1,4 @@ -import { BushCommand, ButtonPaginator, ModLog, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, ButtonPaginator, ModLog, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits, User } from 'discord.js'; @@ -40,8 +40,8 @@ export default class ModlogCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - { search, hidden }: { search: ArgType<'user'> | string; hidden: boolean } + message: CommandMessage | SlashMessage, + { search, hidden }: { search: ArgType<'user'> | string; hidden: ArgType<'flag'> } ) { assert(message.inGuild()); diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts index d846817..a665670 100644 --- a/src/commands/moderation/mute.ts +++ b/src/commands/moderation/mute.ts @@ -4,9 +4,9 @@ import { Moderation, muteResponse, type ArgType, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -57,11 +57,11 @@ export default class MuteCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { user: ArgType<'user'>; reason_and_duration: OptArgType<'contentWithDuration'> | string; - force?: ArgType<'boolean'>; + force: ArgType<'flag'>; } ) { assert(message.inGuild()); diff --git a/src/commands/moderation/purge.ts b/src/commands/moderation/purge.ts index 799cf36..1652f6f 100644 --- a/src/commands/moderation/purge.ts +++ b/src/commands/moderation/purge.ts @@ -1,6 +1,6 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, OptArgType, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; -import { ApplicationCommandOptionType, Collection, PermissionFlagsBits } from 'discord.js'; +import { ApplicationCommandOptionType, Collection, PermissionFlagsBits, type Message } from 'discord.js'; export default class PurgeCommand extends BushCommand { public constructor() { @@ -50,14 +50,14 @@ export default class PurgeCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - args: { amount: number; bot: boolean; user: ArgType<'user'> } + message: CommandMessage | SlashMessage, + args: { amount: ArgType<'integer'>; bot: ArgType<'flag'>; user: OptArgType<'user'> } ) { assert(message.inGuild()); if (args.amount > 100 || args.amount < 1) return message.util.reply(`${util.emojis.error} `); - const messageFilter = (filterMessage: BushMessage): boolean => { + const messageFilter = (filterMessage: Message): boolean => { const shouldFilter: boolean[] = []; if (args.bot) shouldFilter.push(filterMessage.author.bot); if (args.user) shouldFilter.push(filterMessage.author.id === args.user.id); @@ -65,16 +65,16 @@ export default class PurgeCommand extends BushCommand { return shouldFilter.filter((bool) => bool === false).length === 0 && filterMessage.id !== message.id; }; const messages = new Collection( - (await message.channel.messages.fetch({ limit: 100, before: message.id })) + (await message.channel!.messages.fetch({ limit: 100, before: message.id })) .filter((message) => messageFilter(message)) .first(args.amount) .map((m) => [m.id, m] as const) ); - const purged = await message.channel.bulkDelete(messages, true).catch(() => null); + const purged = await message.channel!.bulkDelete(messages, true).catch(() => null); if (!purged) return message.util.reply(`${util.emojis.error} Failed to purge messages.`).catch(() => null); else { - client.emit('bushPurge', message.author, message.guild, message.channel, messages); + client.emit('bushPurge', message.author, message.guild, message.channel!, messages); await message.util.send(`${util.emojis.success} Successfully purged **${purged.size}** messages.`); /* .then(async (purgeMessage) => { if (!message.util.isSlashMessage(message)) { diff --git a/src/commands/moderation/removeReactionEmoji.ts b/src/commands/moderation/removeReactionEmoji.ts index bc24db0..4359c5b 100644 --- a/src/commands/moderation/removeReactionEmoji.ts +++ b/src/commands/moderation/removeReactionEmoji.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, Message, PermissionFlagsBits } from 'discord.js'; @@ -40,8 +40,8 @@ export default class RemoveReactionEmojiCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - args: { message: ArgType<'guildMessage'> | string; emoji: ArgType<'emoji'> | ArgType<'snowflake'> } + message: CommandMessage | SlashMessage, + args: { message: ArgType<'guildMessage'> | string; emoji: ArgType<'emoji' | 'snowflake'> } ) { assert(message.channel); const resolvedMessage = args.message instanceof Message ? args.message : await message.channel.messages.fetch(args.message); diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts index a87b2bf..b9e1490 100644 --- a/src/commands/moderation/role.ts +++ b/src/commands/moderation/role.ts @@ -4,10 +4,11 @@ import { BushCommand, removeRoleResponse, type ArgType, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; +import assert from 'assert'; import { type ArgumentGeneratorReturn } from 'discord-akairo'; import { ApplicationCommandOptionType, PermissionFlagsBits, type Snowflake } from 'discord.js'; @@ -59,6 +60,7 @@ export default class RoleCommand extends BushCommand { ], slash: true, channel: 'guild', + flags: ['--force'], typing: true, clientPermissions: (m) => util.clientSendAndPermCheck(m, [PermissionFlagsBits.ManageRoles, PermissionFlagsBits.EmbedLinks], true), @@ -66,7 +68,7 @@ export default class RoleCommand extends BushCommand { }); } - public override *args(message: BushMessage): ArgumentGeneratorReturn { + public override *args(message: CommandMessage): ArgumentGeneratorReturn { const action = (['rr'] as const).includes(message.util.parsed?.alias ?? '') ? 'remove' : (['ar', 'ra'] as const).includes(message.util.parsed?.alias ?? '') @@ -118,15 +120,16 @@ export default class RoleCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { action: 'add' | 'remove'; member: ArgType<'member'>; role: ArgType<'role'>; - duration?: OptArgType<'duration'>; - force?: boolean; + duration: OptArgType<'duration'>; + force?: ArgType<'flag'>; } ) { + assert(message.inGuild()); if (!args.role) return await message.util.reply(`${util.emojis.error} You must specify a role.`); args.duration ??= 0; if ( diff --git a/src/commands/moderation/slowmode.ts b/src/commands/moderation/slowmode.ts index 6d93ede..e657b76 100644 --- a/src/commands/moderation/slowmode.ts +++ b/src/commands/moderation/slowmode.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import assert from 'assert'; import { Argument } from 'discord-akairo'; import { ApplicationCommandOptionType, ChannelType, PermissionFlagsBits } from 'discord.js'; @@ -42,17 +42,22 @@ export default class SlowmodeCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { - length: ArgType<'duration'> | ArgType<'durationSeconds'> | 'off' | 'none' | 'disable' | null; - channel: ArgType<'channel'>; + length: OptArgType<'duration' | 'durationSeconds'> | 'off' | 'none' | 'disable'; + channel: OptArgType<'channel'>; } ) { assert(message.inGuild()); - args.channel ??= message.channel; + args.channel ??= message.channel!; - if (!args.channel.isTextBased() || args.channel.isNews()) + if ( + args.channel.type !== ChannelType.GuildText && + args.channel.type !== ChannelType.GuildNews && + args.channel.type !== ChannelType.GuildVoice && + !args.channel.isThread() + ) return await message.util.reply(`${util.emojis.error} <#${args.channel.id}> is not a text or thread channel.`); args.length = diff --git a/src/commands/moderation/timeout.ts b/src/commands/moderation/timeout.ts index b8fb78f..ed3562d 100644 --- a/src/commands/moderation/timeout.ts +++ b/src/commands/moderation/timeout.ts @@ -4,8 +4,8 @@ import { Moderation, timeoutResponse, type ArgType, - type BushMessage, - type BushSlashMessage + type CommandMessage, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -55,8 +55,8 @@ export default class TimeoutCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - args: { user: ArgType<'user'>; reason_and_duration: ArgType<'contentWithDuration'> | string; force?: ArgType<'boolean'> } + message: CommandMessage | SlashMessage, + args: { user: ArgType<'user'>; reason_and_duration: ArgType<'contentWithDuration'> | string; force?: ArgType<'flag'> } ) { assert(message.inGuild()); assert(message.member); diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts index e6ac6d0..d7549ab 100644 --- a/src/commands/moderation/unban.ts +++ b/src/commands/moderation/unban.ts @@ -3,9 +3,9 @@ import { BushCommand, unbanResponse, type ArgType, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -46,8 +46,8 @@ export default class UnbanCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - { user, reason }: { user: ArgType<'user'>; reason: OptArgType<'string'> } + message: CommandMessage | SlashMessage, + { user, reason }: { user: ArgType<'user' | 'globalUser'>; reason: OptArgType<'string'> } ) { assert(message.inGuild()); diff --git a/src/commands/moderation/unblock.ts b/src/commands/moderation/unblock.ts index 22c9949..886d546 100644 --- a/src/commands/moderation/unblock.ts +++ b/src/commands/moderation/unblock.ts @@ -4,9 +4,9 @@ import { Moderation, unblockResponse, type ArgType, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -57,11 +57,12 @@ export default class UnblockCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - args: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: ArgType<'boolean'> } + message: CommandMessage | SlashMessage, + args: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: ArgType<'flag'> } ) { assert(message.inGuild()); assert(message.member); + assert(message.channel); if (!message.channel.isTextBased()) return message.util.send(`${util.emojis.error} This command can only be used in text based channels.`); diff --git a/src/commands/moderation/unlockdown.ts b/src/commands/moderation/unlockdown.ts index 253ce37..dbcd429 100644 --- a/src/commands/moderation/unlockdown.ts +++ b/src/commands/moderation/unlockdown.ts @@ -1,5 +1,5 @@ import { LockdownCommand } from '#commands'; -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib'; +import { BushCommand, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType, ChannelType, PermissionFlagsBits } from 'discord.js'; export default class UnlockdownCommand extends BushCommand { @@ -14,7 +14,7 @@ export default class UnlockdownCommand extends BushCommand { { id: 'channel', description: 'Specify a different channel to unlockdown instead of the one you trigger the command in.', - type: util.arg.union('textChannel', 'newsChannel', 'threadChannel'), + type: util.arg.union('textChannel', 'newsChannel', 'threadChannel', 'voiceChannel'), prompt: 'What channel would you like to unlockdown?', slashType: ApplicationCommandOptionType.Channel, channelTypes: [ @@ -22,7 +22,8 @@ export default class UnlockdownCommand extends BushCommand { ChannelType.GuildNews, ChannelType.GuildNewsThread, ChannelType.GuildPublicThread, - ChannelType.GuildPrivateThread + ChannelType.GuildPrivateThread, + ChannelType.GuildVoice ], optional: true }, @@ -53,11 +54,11 @@ export default class UnlockdownCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { - channel: OptArgType<'textChannel'> | OptArgType<'newsChannel'> | OptArgType<'threadChannel'>; + channel: OptArgType<'textChannel' | 'newsChannel' | 'threadChannel' | 'voiceChannel'>; reason: OptArgType<'string'>; - all: ArgType<'boolean'>; + all: ArgType<'flag'>; } ) { return await LockdownCommand.lockdownOrUnlockdown(message, args, 'unlockdown'); diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts index 094cadd..202e341 100644 --- a/src/commands/moderation/unmute.ts +++ b/src/commands/moderation/unmute.ts @@ -4,10 +4,9 @@ import { Moderation, unmuteResponse, type ArgType, - type BushGuildMember, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -58,14 +57,14 @@ export default class UnmuteCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - { user, reason, force = false }: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: boolean } + message: CommandMessage | SlashMessage, + { user, reason, force = false }: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: ArgType<'flag'> } ) { assert(message.inGuild()); assert(message.member); const error = util.emojis.error; - const member = message.guild.members.cache.get(user.id) as BushGuildMember; + const member = message.guild.members.cache.get(user.id)!; const useForce = force && message.author.isOwner(); const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'unmute', true, useForce); diff --git a/src/commands/moderation/untimeout.ts b/src/commands/moderation/untimeout.ts index cbaf7d1..7622f29 100644 --- a/src/commands/moderation/untimeout.ts +++ b/src/commands/moderation/untimeout.ts @@ -4,9 +4,9 @@ import { Moderation, removeTimeoutResponse, type ArgType, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -57,8 +57,8 @@ export default class UntimeoutCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - args: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: ArgType<'boolean'> } + message: CommandMessage | SlashMessage, + args: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: ArgType<'flag'> } ) { assert(message.inGuild()); assert(message.member); diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts index 87baf4a..b3bf965 100644 --- a/src/commands/moderation/warn.ts +++ b/src/commands/moderation/warn.ts @@ -4,9 +4,9 @@ import { Moderation, warnResponse, type ArgType, - type BushMessage, - type BushSlashMessage, - type OptArgType + type CommandMessage, + type OptArgType, + type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -56,8 +56,8 @@ export default class WarnCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - { user, reason, force = false }: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: boolean } + message: CommandMessage | SlashMessage, + { user, reason, force = false }: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: ArgType<'flag'> } ) { assert(message.inGuild()); assert(message.member); diff --git a/src/commands/moulberry-bush/capePermissions.ts b/src/commands/moulberry-bush/capePermissions.ts index dd210e2..5f15d9e 100644 --- a/src/commands/moulberry-bush/capePermissions.ts +++ b/src/commands/moulberry-bush/capePermissions.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; import got from 'got'; @@ -27,7 +27,7 @@ export default class CapePermissionsCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { ign: ArgType<'string'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { ign: ArgType<'string'> }) { let capePerms: CapePerms | null, uuid: string; try { uuid = await util.mcUUID(args.ign); diff --git a/src/commands/moulberry-bush/capes.ts b/src/commands/moulberry-bush/capes.ts index 3f273c1..6bf7854 100644 --- a/src/commands/moulberry-bush/capes.ts +++ b/src/commands/moulberry-bush/capes.ts @@ -1,7 +1,14 @@ -import { AllowedMentions, BushCommand, ButtonPaginator, DeleteButton, type BushMessage, type OptArgType } from '#lib'; +import { + AllowedMentions, + BushCommand, + ButtonPaginator, + DeleteButton, + type CommandMessage, + type OptArgType, + type SlashMessage +} from '#lib'; import assert from 'assert'; -import { APIEmbed } from 'discord-api-types/v10'; -import { ApplicationCommandOptionType, AutocompleteInteraction, PermissionFlagsBits } from 'discord.js'; +import { ApplicationCommandOptionType, PermissionFlagsBits, type APIEmbed, type AutocompleteInteraction } from 'discord.js'; import Fuse from 'fuse.js'; import got from 'got'; @@ -34,7 +41,7 @@ export default class CapesCommand extends BushCommand { }); } - public override async exec(message: BushMessage, args: { cape: OptArgType<'string'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { cape: OptArgType<'string'> }) { const { tree: neuFileTree }: GithubTreeApi = await got .get('https://api.github.com/repos/Moulberry/NotEnoughUpdates/git/trees/master?recursive=1') .json(); diff --git a/src/commands/moulberry-bush/giveawayPing.ts b/src/commands/moulberry-bush/giveawayPing.ts index dd305c6..23a6a20 100644 --- a/src/commands/moulberry-bush/giveawayPing.ts +++ b/src/commands/moulberry-bush/giveawayPing.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type BushMessage } from '#lib'; +import { AllowedMentions, BushCommand, type CommandMessage } from '#lib'; import { PermissionFlagsBits } from 'discord.js'; export default class GiveawayPingCommand extends BushCommand { @@ -28,7 +28,7 @@ export default class GiveawayPingCommand extends BushCommand { }); } - public override async exec(message: BushMessage) { + public override async exec(message: CommandMessage) { if (!message.member!.permissions.has(PermissionFlagsBits.ManageGuild) && !message.member!.user.isOwner()) await message.util.reply(`${util.emojis.error} You are missing the **ManageGuild** permission.`); diff --git a/src/commands/moulberry-bush/moulHammer.ts b/src/commands/moulberry-bush/moulHammer.ts index a5d2c27..f07511a 100644 --- a/src/commands/moulberry-bush/moulHammer.ts +++ b/src/commands/moulberry-bush/moulHammer.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; @@ -29,10 +29,10 @@ export default class MoulHammerCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, { user }: { user: ArgType<'user'> }) { + public override async exec(message: CommandMessage | SlashMessage, { user }: { user: ArgType<'user'> }) { assert(message.inGuild()); - if (message.channel.permissionsFor(message.guild.members.me!).has('ManageMessages')) await message.delete().catch(() => {}); + if (message.channel?.permissionsFor(message.guild.members.me!).has('ManageMessages')) await message.delete().catch(() => {}); const embed = new EmbedBuilder() .setTitle('L') diff --git a/src/commands/moulberry-bush/report.ts b/src/commands/moulberry-bush/report.ts index 0561e13..29eee76 100644 --- a/src/commands/moulberry-bush/report.ts +++ b/src/commands/moulberry-bush/report.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type ArgType, type BushMessage } from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage } from '#lib'; import { stripIndent } from '#tags'; import assert from 'assert'; import { ApplicationCommandOptionType, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; @@ -38,7 +38,7 @@ export default class ReportCommand extends BushCommand { }); } - public override async exec(message: BushMessage, { member, evidence }: { member: ArgType<'member'>; evidence: string }) { + public override async exec(message: CommandMessage, { member, evidence }: { member: ArgType<'member'>; evidence: string }) { assert(message.inGuild()); if (!(await message.guild.hasFeature('reporting'))) diff --git a/src/commands/moulberry-bush/rule.ts b/src/commands/moulberry-bush/rule.ts index cd9994f..17f1bd8 100644 --- a/src/commands/moulberry-bush/rule.ts +++ b/src/commands/moulberry-bush/rule.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, BushSlashMessage, type BushMessage, type OptArgType } from '#lib'; +import { AllowedMentions, BushCommand, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; import { stripIndent } from '../../lib/common/tags.js'; @@ -99,7 +99,7 @@ export default class RuleCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, { rule, user }: { rule: OptArgType<'integer'>; user: OptArgType<'user'> } ) { const rulesEmbed = new EmbedBuilder() diff --git a/src/commands/moulberry-bush/serverStatus.ts b/src/commands/moulberry-bush/serverStatus.ts index c0df828..ad3903a 100644 --- a/src/commands/moulberry-bush/serverStatus.ts +++ b/src/commands/moulberry-bush/serverStatus.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage } from '#lib'; +import { BushCommand, type CommandMessage } from '#lib'; import assert from 'assert'; import { EmbedBuilder, PermissionFlagsBits } from 'discord.js'; import got from 'got'; @@ -19,7 +19,7 @@ export default class ServerStatusCommand extends BushCommand { }); } - public override async exec(message: BushMessage) { + public override async exec(message: CommandMessage) { const msgEmbed = new EmbedBuilder() .setTitle('Server status') .setDescription(`Checking server:\n${util.emojis.loading}`) diff --git a/src/commands/utilities/_poll.ts b/src/commands/utilities/_poll.ts index 81bb5fc..a843561 100644 --- a/src/commands/utilities/_poll.ts +++ b/src/commands/utilities/_poll.ts @@ -1,81 +1,80 @@ -/* import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; -import { ApplicationCommandOptionType, ComponentType } from 'discord.js'; +// import { BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; +// import { ApplicationCommandOptionType, ComponentType } from 'discord.js'; -export default class PollCommand extends BushCommand { - public constructor() { - super('poll', { - aliases: ['poll', 'quick-poll'], - category: 'utilities', - description: 'Allows you to create a poll that other users can vote on. Separate options with "," or "|".', - usage: ['poll options'], - examples: ['poll 1 2'], - args: [ - { - id: 'question', - description: 'The question to be answered by a poll.', - type: 'string', - prompt: 'What question would you like to ask?', - retry: '{error} Choose a question.', - slashType: ApplicationCommandOptionType.String, - only: 'slash' - }, - { - id: 'options', - description: 'The options to include in the poll. Separate options with "," or "|".', - type: 'string', - prompt: 'What options you want to include in the poll? Separate options with "," or "|".', - retry: '{error} Choose options for the poll. Separate options with "," or "|".', - slashType: ApplicationCommandOptionType.String - } - ], - slash: true, - clientPermissions: (m) => util.clientSendAndPermCheck(m), - userPermissions: [] - }); - } +// export default class PollCommand extends BushCommand { +// public constructor() { +// super('poll', { +// aliases: ['poll', 'quick-poll'], +// category: 'utilities', +// description: 'Allows you to create a poll that other users can vote on. Separate options with "," or "|".', +// usage: ['poll options'], +// examples: ['poll 1 2'], +// args: [ +// { +// id: 'question', +// description: 'The question to be answered by a poll.', +// type: 'string', +// prompt: 'What question would you like to ask?', +// retry: '{error} Choose a question.', +// slashType: ApplicationCommandOptionType.String, +// only: 'slash' +// }, +// { +// id: 'options', +// description: 'The options to include in the poll. Separate options with "," or "|".', +// type: 'string', +// prompt: 'What options you want to include in the poll? Separate options with "," or "|".', +// retry: '{error} Choose options for the poll. Separate options with "," or "|".', +// slashType: ApplicationCommandOptionType.String +// } +// ], +// slash: true, +// clientPermissions: (m) => util.clientSendAndPermCheck(m), +// userPermissions: [] +// }); +// } - public override async exec(message: BushMessage | BushSlashMessage, args: { question?: string; options: ArgType<'string'> }) { - const { question, options } = this.parseArgs(message, args); - if (!question || !options.length) return; +// public override async exec(message: CommandMessage | SlashMessage, args: { question?: string; options: ArgType<'string'> }) { +// const { question, options } = this.parseArgs(message, args); +// if (!question || !options.length) return; - if (question.length > 256) return await message.util.reply(`${util.emojis.error} Question must be 256 characters or less.`); - if (options.length > 10) return await message.util.reply(`${util.emojis.error} You can only have upto 10 options.`); +// if (question.length > 256) return await message.util.reply(`${util.emojis.error} Question must be 256 characters or less.`); +// if (options.length > 10) return await message.util.reply(`${util.emojis.error} You can only have upto 10 options.`); - return message.util.send({ - embeds: [ - { - author: { name: `asked by: ${message.author.tag}`, icon_url: message.author.displayAvatarURL() || undefined }, - title: question - } - ], - components: [ - { - type: ComponentType.ActionRow, - components: [] - } - ] - }); - } +// return message.util.send({ +// embeds: [ +// { +// author: { name: `asked by: ${message.author.tag}`, icon_url: message.author.displayAvatarURL() || undefined }, +// title: question +// } +// ], +// components: [ +// { +// type: ComponentType.ActionRow, +// components: [] +// } +// ] +// }); +// } - private parseArgs( - message: BushMessage | BushSlashMessage, - args: { question?: string; options: ArgType<'string'> } - ): { question: string; options: string[] } { - const split = args.options.split(/[,|]/).filter((s) => s.trim().length > 0); - if (message.util.isSlash) { - if (split.length < 2) { - void message.util.reply(`${util.emojis.error} You must provide at least two options.`); - return { question: '', options: [] }; - } - return { question: args.question!, options: split }; - } else { - if (split.length < 3) { - void message.util.reply(`${util.emojis.error} You must provide a question and at least two options.`); - return { question: '', options: [] }; - } +// private parseArgs( +// message: CommandMessage | SlashMessage, +// args: { question?: string; options: ArgType<'string'> } +// ): { question: string; options: string[] } { +// const split = args.options.split(/[,|]/).filter((s) => s.trim().length > 0); +// if (message.util.isSlash) { +// if (split.length < 2) { +// void message.util.reply(`${util.emojis.error} You must provide at least two options.`); +// return { question: '', options: [] }; +// } +// return { question: args.question!, options: split }; +// } else { +// if (split.length < 3) { +// void message.util.reply(`${util.emojis.error} You must provide a question and at least two options.`); +// return { question: '', options: [] }; +// } - return { question: split[0], options: split.slice(1) }; - } - } -} - */ +// return { question: split[0], options: split.slice(1) }; +// } +// } +// } diff --git a/src/commands/utilities/activity.ts b/src/commands/utilities/activity.ts index 230cc81..14cc5a0 100644 --- a/src/commands/utilities/activity.ts +++ b/src/commands/utilities/activity.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushArgumentTypeCaster, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type ArgType, type BushArgumentTypeCaster, type CommandMessage, type SlashMessage } from '#lib'; import { type ArgumentGeneratorReturn, type ArgumentTypeCaster } from 'discord-akairo'; import { ApplicationCommandOptionType, ChannelType, type DiscordAPIError, type Snowflake } from 'discord.js'; @@ -66,7 +66,7 @@ function map(phase: string): Activity | null { return null; } -const activityTypeCaster: BushArgumentTypeCaster<Snowflake | null> = (message: BushMessage, phrase: string) => { +const activityTypeCaster: BushArgumentTypeCaster<Snowflake | null> = (message: CommandMessage, phrase: string) => { const parsedPhrase = phrase ?? message.util.parsed?.alias !== 'activity' ? message.util.parsed?.alias : undefined; if (!parsedPhrase) return null; const mappedPhrase = map(parsedPhrase)?.id; @@ -120,7 +120,7 @@ export default class ActivityCommand extends BushCommand { }); } - public override *args(message: BushMessage): ArgumentGeneratorReturn { + public override *args(message: CommandMessage): ArgumentGeneratorReturn { const channel: ArgType<'voiceChannel'> = yield { id: 'channel', description: 'The channel to create the activity in.', @@ -151,11 +151,12 @@ export default class ActivityCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { channel: ArgType<'voiceChannel'>; activity: string } ) { const channel = typeof args.channel === 'string' ? message.guild?.channels.cache.get(args.channel) : args.channel; - if (!channel || !channel.isVoice()) return await message.util.reply(`${util.emojis.error} Choose a valid voice channel`); + if (channel?.type !== ChannelType.GuildVoice) + return await message.util.reply(`${util.emojis.error} Choose a valid voice channel`); const target_application_id = message.util.isSlashMessage(message) ? args.activity diff --git a/src/commands/utilities/calculator.ts b/src/commands/utilities/calculator.ts index e17ef76..a318a79 100644 --- a/src/commands/utilities/calculator.ts +++ b/src/commands/utilities/calculator.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, EmbedBuilder } from 'discord.js'; import { evaluate } from 'mathjs'; @@ -30,7 +30,7 @@ export default class CalculatorCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { expression: string }) { + public override async exec(message: CommandMessage | SlashMessage, args: { expression: string }) { const decodedEmbed = new EmbedBuilder().addFields([ { name: '📥 Input', diff --git a/src/commands/utilities/decode.ts b/src/commands/utilities/decode.ts index 7cb0e83..8c82fcc 100644 --- a/src/commands/utilities/decode.ts +++ b/src/commands/utilities/decode.ts @@ -1,5 +1,4 @@ -import { AllowedMentions, BushCommand, type BushMessage } from '#lib'; -import { type AkairoMessage } from 'discord-akairo'; +import { AllowedMentions, BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType, EmbedBuilder } from 'discord.js'; const encodingTypesArray = ['ascii', 'utf8', 'utf-8', 'utf16le', 'ucs2', 'ucs-2', 'base64', 'latin1', 'binary', 'hex']; @@ -49,7 +48,7 @@ export default class DecodeCommand extends BushCommand { } public override async exec( - message: BushMessage | AkairoMessage, + message: CommandMessage | SlashMessage, { from, to, data }: { from: BufferEncoding; to: BufferEncoding; data: string } ) { const encodeOrDecode = util.capitalizeFirstLetter(message?.util?.parsed?.alias ?? 'decoded'); diff --git a/src/commands/utilities/hash.ts b/src/commands/utilities/hash.ts index 7cc59f3..f47c388 100644 --- a/src/commands/utilities/hash.ts +++ b/src/commands/utilities/hash.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage } from '#lib'; +import { BushCommand, type CommandMessage } from '#lib'; import assert from 'assert'; import crypto from 'crypto'; import { ApplicationCommandOptionType } from 'discord.js'; @@ -30,7 +30,7 @@ export default class HashCommand extends BushCommand { }); } - public override async exec(message: BushMessage, { url }: { url: string }) { + public override async exec(message: CommandMessage, { url }: { url: string }) { try { const req = await got.get(url); const rawHash = crypto.createHash('md5'); diff --git a/src/commands/utilities/highlight-!.ts b/src/commands/utilities/highlight-!.ts index 9aeb9ec..6dca545 100644 --- a/src/commands/utilities/highlight-!.ts +++ b/src/commands/utilities/highlight-!.ts @@ -1,7 +1,11 @@ -import { BushCommand, Highlight, HighlightWord, type BushSlashMessage } from '#lib'; +import { BushCommand, Highlight, HighlightWord, type SlashMessage } from '#lib'; import { Flag, type ArgumentGeneratorReturn, type SlashOption } from 'discord-akairo'; -import { ApplicationCommandOptionType } from 'discord-api-types/v10'; -import { ApplicationCommandSubCommandData, AutocompleteInteraction, CacheType } from 'discord.js'; +import { + ApplicationCommandOptionType, + ApplicationCommandSubCommandData, + type AutocompleteInteraction, + type CacheType +} from 'discord.js'; type Unpacked<T> = T extends (infer U)[] ? U : T; @@ -139,7 +143,7 @@ export default class HighlightCommand extends BushCommand { return Flag.continue(`highlight-${subcommand}`); } - public override async execSlash(message: BushSlashMessage, args: { subcommand: keyof typeof highlightSubcommands }) { + public override async execSlash(message: SlashMessage, args: { subcommand: keyof typeof highlightSubcommands }) { // manual `Flag.continue` const subcommand = this.handler.modules.get(`highlight-${args.subcommand}`)!; return subcommand.exec(message, args); diff --git a/src/commands/utilities/highlight-add.ts b/src/commands/utilities/highlight-add.ts index 73c61d2..726b887 100644 --- a/src/commands/utilities/highlight-add.ts +++ b/src/commands/utilities/highlight-add.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { highlightCommandArgs, highlightSubcommands } from './highlight-!.js'; @@ -37,10 +37,7 @@ export default class HighlightAddCommand extends BushCommand { }); } - public override async exec( - message: BushMessage | BushSlashMessage, - args: { word: ArgType<'string'>; regex: ArgType<'boolean'> } - ) { + public override async exec(message: CommandMessage | SlashMessage, args: { word: ArgType<'string'>; regex: ArgType<'flag'> }) { assert(message.inGuild()); args.regex = false; diff --git a/src/commands/utilities/highlight-block.ts b/src/commands/utilities/highlight-block.ts index 4ad1a86..61e1254 100644 --- a/src/commands/utilities/highlight-block.ts +++ b/src/commands/utilities/highlight-block.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, Highlight, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, Highlight, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { Argument, ArgumentGeneratorReturn } from 'discord-akairo'; import { Channel, GuildMember } from 'discord.js'; @@ -18,7 +18,7 @@ export default class HighlightBlockCommand extends BushCommand { } public override *args(): ArgumentGeneratorReturn { - const target: ArgType<'member'> | ArgType<'channel'> = yield { + const target: ArgType<'member' | 'channel'> = yield { type: Argument.union('member', 'channel'), match: 'rest', prompt: { @@ -31,10 +31,7 @@ export default class HighlightBlockCommand extends BushCommand { return { target }; } - public override async exec( - message: BushMessage | BushSlashMessage, - args: { target: string | ArgType<'member'> | ArgType<'channel'> } - ) { + public override async exec(message: CommandMessage | SlashMessage, args: { target: string | ArgType<'member' | 'channel'> }) { assert(message.inGuild()); args.target = diff --git a/src/commands/utilities/highlight-clear.ts b/src/commands/utilities/highlight-clear.ts index 274c6fb..b905f3b 100644 --- a/src/commands/utilities/highlight-clear.ts +++ b/src/commands/utilities/highlight-clear.ts @@ -1,4 +1,4 @@ -import { BushCommand, ConfirmationPrompt, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, ConfirmationPrompt, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { highlightSubcommands } from './highlight-!.js'; @@ -15,7 +15,7 @@ export default class HighlightClearCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { assert(message.inGuild()); if (message.util.isSlashMessage(message)) await message.interaction.deferReply(); diff --git a/src/commands/utilities/highlight-matches.ts b/src/commands/utilities/highlight-matches.ts index 0e98c8d..40020cd 100644 --- a/src/commands/utilities/highlight-matches.ts +++ b/src/commands/utilities/highlight-matches.ts @@ -1,7 +1,7 @@ -import { BushCommand, ButtonPaginator, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, ButtonPaginator, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; -import { ArgumentGeneratorReturn } from 'discord-akairo'; -import { APIEmbed } from 'discord-api-types/v10'; +import { type ArgumentGeneratorReturn } from 'discord-akairo'; +import { type APIEmbed } from 'discord.js'; import { highlightCommandArgs, highlightSubcommands } from './highlight-!.js'; export default class HighlightMatchesCommand extends BushCommand { @@ -31,7 +31,7 @@ export default class HighlightMatchesCommand extends BushCommand { return { phrase }; } - public override async exec(message: BushMessage | BushSlashMessage, args: { phrase: ArgType<'string'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { phrase: ArgType<'string'> }) { assert(message.inGuild()); const res = await client.highlightManager.checkPhrase(message.guild.id, message.author.id, args.phrase); diff --git a/src/commands/utilities/highlight-remove.ts b/src/commands/utilities/highlight-remove.ts index 7e8c416..a2f2367 100644 --- a/src/commands/utilities/highlight-remove.ts +++ b/src/commands/utilities/highlight-remove.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { highlightCommandArgs, highlightSubcommands } from './highlight-!.js'; @@ -28,7 +28,7 @@ export default class HighlightRemoveCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { word: ArgType<'string'> }) { + public override async exec(message: CommandMessage | SlashMessage, args: { word: ArgType<'string'> }) { assert(message.inGuild()); const res = await client.highlightManager.removeHighlight(message.guild.id, message.author.id, args.word); diff --git a/src/commands/utilities/highlight-show.ts b/src/commands/utilities/highlight-show.ts index d0a91e6..80ba4ca 100644 --- a/src/commands/utilities/highlight-show.ts +++ b/src/commands/utilities/highlight-show.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, Highlight, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, Highlight, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { EmbedBuilder } from 'discord.js'; import { highlightSubcommands } from './highlight-!.js'; @@ -16,7 +16,7 @@ export default class HighlightShowCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { assert(message.inGuild()); const [highlight] = await Highlight.findOrCreate({ diff --git a/src/commands/utilities/highlight-unblock.ts b/src/commands/utilities/highlight-unblock.ts index c437e6f..b738ee9 100644 --- a/src/commands/utilities/highlight-unblock.ts +++ b/src/commands/utilities/highlight-unblock.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, Highlight, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, Highlight, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { Argument, ArgumentGeneratorReturn } from 'discord-akairo'; import { Channel, GuildMember } from 'discord.js'; @@ -18,7 +18,7 @@ export default class HighlightUnblockCommand extends BushCommand { } public override *args(): ArgumentGeneratorReturn { - const target: ArgType<'member'> | ArgType<'channel'> = yield { + const target: ArgType<'member' | 'channel'> = yield { type: Argument.union('member', 'channel'), match: 'rest', prompt: { @@ -31,10 +31,7 @@ export default class HighlightUnblockCommand extends BushCommand { return { target }; } - public override async exec( - message: BushMessage | BushSlashMessage, - args: { target: ArgType<'user'> | ArgType<'role'> | ArgType<'member'> } - ) { + public override async exec(message: CommandMessage | SlashMessage, args: { target: ArgType<'user' | 'role' | 'member'> }) { assert(message.inGuild()); if (!(args.target instanceof GuildMember || args.target instanceof Channel)) diff --git a/src/commands/utilities/price.ts b/src/commands/utilities/price.ts index e4e4f50..a4f4c03 100644 --- a/src/commands/utilities/price.ts +++ b/src/commands/utilities/price.ts @@ -1,4 +1,4 @@ -import { BushCommand, type BushMessage } from '#lib'; +import { ArgType, BushCommand, type CommandMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, AutocompleteInteraction, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; import Fuse from 'fuse.js'; @@ -45,7 +45,7 @@ export default class PriceCommand extends BushCommand { }); } - public override async exec(message: BushMessage, { item, strict }: { item: string; strict: boolean }) { + public override async exec(message: CommandMessage, args: { item: ArgType<'string'>; strict: ArgType<'flag'> }) { if (message.util.isSlashMessage(message)) await message.interaction.deferReply(); const errors: string[] = []; @@ -57,7 +57,7 @@ export default class PriceCommand extends BushCommand { got.get('https://moulberry.codes/auction_averages/3day.json').json().catch(() => { errors.push('auction average') }) ])) as [Bazaar | undefined, LowestBIN | undefined, LowestBIN | undefined, AuctionAverages | undefined]; - let parsedItem = item.toString().toUpperCase().replace(/ /g, '_').replace(/'S/g, ''); + let parsedItem = args.item.toString().toUpperCase().replace(/ /g, '_').replace(/'S/g, ''); const priceEmbed = new EmbedBuilder().setColor(errors?.length ? util.colors.warn : util.colors.success).setTimestamp(); if (bazaar?.success === false) errors.push('bazaar'); @@ -75,7 +75,7 @@ export default class PriceCommand extends BushCommand { ]); // fuzzy search - if (!strict) { + if (!args.strict) { parsedItem = new Fuse([...itemNames], { isCaseSensitive: false, findAllMatches: true, diff --git a/src/commands/utilities/remind.ts b/src/commands/utilities/remind.ts index 044d4fc..8727879 100644 --- a/src/commands/utilities/remind.ts +++ b/src/commands/utilities/remind.ts @@ -1,4 +1,4 @@ -import { BushCommand, Reminder, Time, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, Reminder, Time, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType } from 'discord.js'; export default class RemindCommand extends BushCommand { @@ -28,8 +28,8 @@ export default class RemindCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - args: { reminder: ArgType<'contentWithDuration'> | string } + message: CommandMessage | SlashMessage, + args: { reminder: OptArgType<'contentWithDuration'> | string } ) { const { duration, content } = await util.castDurationContent(args.reminder, message); diff --git a/src/commands/utilities/reminders.ts b/src/commands/utilities/reminders.ts index 653274a..79284ac 100644 --- a/src/commands/utilities/reminders.ts +++ b/src/commands/utilities/reminders.ts @@ -1,7 +1,6 @@ -import { BushCommand, ButtonPaginator, Reminder, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, ButtonPaginator, Reminder, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; -import { APIEmbed } from 'discord-api-types/v10'; -import { PermissionFlagsBits } from 'discord.js'; +import { PermissionFlagsBits, type APIEmbed } from 'discord.js'; import { Op } from 'sequelize'; assert(Op); @@ -20,7 +19,7 @@ export default class RemindersCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { const reminders = await Reminder.findAll({ where: { user: message.author.id, expires: { [Op.gt]: new Date() } } }); if (!reminders.length) return message.util.send(`${util.emojis.error} You don't have any reminders set.`); diff --git a/src/commands/utilities/steal.ts b/src/commands/utilities/steal.ts index e4f08f1..69d3054 100644 --- a/src/commands/utilities/steal.ts +++ b/src/commands/utilities/steal.ts @@ -1,7 +1,7 @@ -import { BushCommand, OptArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, OptArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; import { type ArgumentGeneratorReturn, type ArgumentType, type ArgumentTypeCaster } from 'discord-akairo'; -import { ApplicationCommandOptionType, PermissionFlagsBits, type Attachment } from 'discord.js'; +import { ApplicationCommandOptionType, Attachment, PermissionFlagsBits } from 'discord.js'; import _ from 'lodash'; import { Stream } from 'stream'; import { URL } from 'url'; @@ -41,7 +41,7 @@ export default class StealCommand extends BushCommand { }); } - public override *args(message: BushMessage): ArgumentGeneratorReturn { + public override *args(message: CommandMessage): ArgumentGeneratorReturn { const hasImage = message.attachments.size && message.attachments.first()?.contentType?.includes('image/'); const emoji = hasImage @@ -60,8 +60,8 @@ export default class StealCommand extends BushCommand { } public override async exec( - message: BushMessage, - args: { emoji: OptArgType<'discordEmoji'> | OptArgType<'snowflake'> | OptArgType<'url'> | string; name: string } + message: CommandMessage, + args: { emoji: OptArgType<'discordEmoji' | 'snowflake' | 'url'>; name: OptArgType<'string'> } ) { assert(message.inGuild()); @@ -88,7 +88,9 @@ export default class StealCommand extends BushCommand { : 'stolen_emoji'; const creationSuccess = await message.guild.emojis - .create(image, emojiName, { + .create({ + attachment: image, + name: emojiName, reason: `Stolen by ${message.author.tag} (${message.author.id})` }) .catch((e: Error) => e); @@ -102,7 +104,7 @@ export default class StealCommand extends BushCommand { } } - public override async execSlash(message: BushSlashMessage, args: { emoji: Attachment; name?: string }) { + public override async execSlash(message: SlashMessage, args: { emoji: Attachment; name: string | null }) { assert(message.inGuild()); const name = args.name ?? args.emoji.name ?? 'stolen_emoji'; @@ -119,7 +121,9 @@ export default class StealCommand extends BushCommand { : args.emoji.attachment; const creationSuccess = await message.guild.emojis - .create(data, name, { + .create({ + attachment: data, + name: name, reason: `Stolen by ${message.author.tag} (${message.author.id})` }) .catch((e: Error) => e); diff --git a/src/commands/utilities/suicide.ts b/src/commands/utilities/suicide.ts index e4609f2..c4151e8 100644 --- a/src/commands/utilities/suicide.ts +++ b/src/commands/utilities/suicide.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import { stripIndent } from '#tags'; import { EmbedBuilder } from 'discord.js'; @@ -17,7 +17,7 @@ export default class SuicideCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage) { + public override async exec(message: CommandMessage | SlashMessage) { // stolen from https://github.com/dexbiobot/Zeppelin const suicideEmbed = new EmbedBuilder() .setTitle('Mental Health Resources') diff --git a/src/commands/utilities/uuid.ts b/src/commands/utilities/uuid.ts index 448baf3..1e70e91 100644 --- a/src/commands/utilities/uuid.ts +++ b/src/commands/utilities/uuid.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, ArgType, BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import { ApplicationCommandOptionType } from 'discord.js'; export default class UuidCommand extends BushCommand { @@ -14,7 +14,7 @@ export default class UuidCommand extends BushCommand { id: 'ign', description: 'The ign to find the ign of.', customType: /\w{1,16}/im, - readableType: 'ign', + readableType: 'string[1,16]', prompt: 'What ign would you like to find the uuid of?', retry: '{error} Choose a valid ign.', slashType: ApplicationCommandOptionType.String @@ -23,7 +23,7 @@ export default class UuidCommand extends BushCommand { id: 'dashed', description: 'Include dashes in the uuid.', match: 'flag', - flag: '--dashed', + flag: ['--dashed', '-d'], prompt: 'Would you like to include dashes in the uuid?', slashType: ApplicationCommandOptionType.Boolean, optional: true @@ -36,15 +36,15 @@ export default class UuidCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, - { ign, dashed }: { ign: { match: RegExpMatchArray; matches?: any[] } | string; dashed: boolean } + message: CommandMessage | SlashMessage, + args: { ign: ArgType<'regex'> | string; dashed: ArgType<'flag'> } ) { - if (typeof ign === 'string') ign = { match: /\w{1,16}/im.exec(ign)! }; + if (typeof args.ign === 'string') args.ign = { match: /\w{1,16}/im.exec(args.ign)!, matches: [] }; - if (!ign || !ign.match) return await message.util.reply(`${util.emojis.error} Please enter a valid ign.`); - const readableIGN = ign.match[0]; + if (!args.ign.match) return await message.util.reply(`${util.emojis.error} Please enter a valid ign.`); + const readableIGN = args.ign.match[0]; try { - const uuid = await util.mcUUID(readableIGN, dashed); + const uuid = await util.mcUUID(readableIGN, args.dashed); return await message.util.reply({ content: `The uuid for ${util.format.input(readableIGN)} is ${util.format.input(uuid)}`, allowedMentions: AllowedMentions.none() diff --git a/src/commands/utilities/viewRaw.ts b/src/commands/utilities/viewRaw.ts index cb106dd..5c2c146 100644 --- a/src/commands/utilities/viewRaw.ts +++ b/src/commands/utilities/viewRaw.ts @@ -1,4 +1,4 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib'; +import { BushCommand, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib'; import assert from 'assert'; import { ApplicationCommandOptionType, ChannelType, EmbedBuilder, Message, PermissionFlagsBits } from 'discord.js'; @@ -23,7 +23,7 @@ export default class ViewRawCommand extends BushCommand { { id: 'channel', description: 'The channel that the message is in.', - type: util.arg.union('textChannel', 'newsChannel', 'threadChannel'), + type: util.arg.union('textChannel', 'newsChannel', 'threadChannel', 'voiceChannel'), prompt: 'What channel is the message in?', retry: '{error} Choose a valid channel.', optional: true, @@ -34,7 +34,8 @@ export default class ViewRawCommand extends BushCommand { ChannelType.GuildNews, ChannelType.GuildNewsThread, ChannelType.GuildPublicThread, - ChannelType.GuildPrivateThread + ChannelType.GuildPrivateThread, + ChannelType.GuildVoice ] }, { @@ -64,12 +65,12 @@ export default class ViewRawCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { - message: ArgType<'message'> | ArgType<'messageLink'>; - channel: OptArgType<'textChannel'> | OptArgType<'newsChannel'> | OptArgType<'threadChannel'>; - json: boolean; - js: boolean; + message: ArgType<'message' | 'messageLink'>; + channel: OptArgType<'textChannel' | 'newsChannel' | 'threadChannel' | 'voiceChannel'>; + json: ArgType<'flag'>; + js: ArgType<'flag'>; } ) { assert(message.inGuild()); @@ -88,7 +89,7 @@ export default class ViewRawCommand extends BushCommand { return await message.util.reply({ embeds: [Embed] }); } - public static async getRawData(message: BushMessage, options: { json?: boolean; js: boolean }): Promise<EmbedBuilder> { + public static async getRawData(message: Message, options: { json?: boolean; js: boolean }): Promise<EmbedBuilder> { const content = options.json || options.js ? options.json diff --git a/src/commands/utilities/whoHasRole.ts b/src/commands/utilities/whoHasRole.ts index 5f13c02..ae96a65 100644 --- a/src/commands/utilities/whoHasRole.ts +++ b/src/commands/utilities/whoHasRole.ts @@ -1,6 +1,6 @@ -import { BushCommand, BushRole, ButtonPaginator, OptArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, ButtonPaginator, OptArgType, type CommandMessage, type SlashMessage } from '#lib'; import assert from 'assert'; -import { ApplicationCommandOptionType, Util, type CommandInteraction } from 'discord.js'; +import { ApplicationCommandOptionType, Util, type CommandInteraction, type Role } from 'discord.js'; export default class WhoHasRoleCommand extends BushCommand { public constructor() { @@ -31,7 +31,7 @@ export default class WhoHasRoleCommand extends BushCommand { } public override async exec( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, args: { [K in `role${NumberRange}`]: OptArgType<'role'>; } @@ -39,7 +39,7 @@ export default class WhoHasRoleCommand extends BushCommand { assert(message.inGuild()); if (message.util.isSlash) await (message.interaction as CommandInteraction).deferReply(); - const rawRoles = Object.values(args).filter((v) => v !== null) as BushRole[]; + const rawRoles = Object.values(args).filter((v) => v !== null) as Role[]; const roles = rawRoles.map((v) => v.id); const members = message.guild.members.cache.filter((m) => roles.every((r) => m.roles.cache.has(r))); diff --git a/src/commands/utilities/wolframAlpha.ts b/src/commands/utilities/wolframAlpha.ts index 0e1cb14..98cac69 100644 --- a/src/commands/utilities/wolframAlpha.ts +++ b/src/commands/utilities/wolframAlpha.ts @@ -1,4 +1,4 @@ -import { AllowedMentions, BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { AllowedMentions, BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; import { initializeClass as WolframAlphaAPI } from '@notenoughupdates/wolfram-alpha-api'; import assert from 'assert'; import { ApplicationCommandOptionType, EmbedBuilder, type MessageOptions } from 'discord.js'; @@ -39,7 +39,10 @@ export default class WolframAlphaCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { expression: string; image: boolean }) { + public override async exec( + message: CommandMessage | SlashMessage, + args: { expression: ArgType<'string'>; image: ArgType<'flag'> } + ) { if (message.util.isSlashMessage(message)) await message.interaction.deferReply(); args.image && void message.util.reply({ content: `${util.emojis.loading} Loading...`, embeds: [] }); diff --git a/src/context-menu-commands/message/viewRaw.ts b/src/context-menu-commands/message/viewRaw.ts index c283635..6cfe552 100644 --- a/src/context-menu-commands/message/viewRaw.ts +++ b/src/context-menu-commands/message/viewRaw.ts @@ -1,7 +1,6 @@ import { ViewRawCommand } from '#commands'; -import { type BushMessage } from '#lib'; import { ContextMenuCommand } from 'discord-akairo'; -import { ApplicationCommandType, type ContextMenuCommandInteraction } from 'discord.js'; +import { ApplicationCommandType, type ContextMenuCommandInteraction, type Message } from 'discord.js'; export default class ViewRawContextMenuCommand extends ContextMenuCommand { public constructor() { @@ -14,7 +13,7 @@ export default class ViewRawContextMenuCommand extends ContextMenuCommand { public override async exec(interaction: ContextMenuCommandInteraction) { await interaction.deferReply({ ephemeral: true }); - const embed = await ViewRawCommand.getRawData(interaction.options.getMessage('message') as BushMessage, { + const embed = await ViewRawCommand.getRawData(interaction.options.getMessage('message') as Message, { json: false, js: false }); diff --git a/src/context-menu-commands/user/modlog.ts b/src/context-menu-commands/user/modlog.ts index ac156cd..bdb311f 100644 --- a/src/context-menu-commands/user/modlog.ts +++ b/src/context-menu-commands/user/modlog.ts @@ -1,6 +1,6 @@ import { ModlogCommand } from '#commands'; -import { BushCommandUtil, BushSlashMessage } from '#lib'; -import { ContextMenuCommand } from 'discord-akairo'; +import { SlashMessage } from '#lib'; +import { CommandUtil, ContextMenuCommand } from 'discord-akairo'; import { ApplicationCommandType, type ContextMenuCommandInteraction } from 'discord.js'; export default class ModlogContextMenuCommand extends ContextMenuCommand { @@ -25,8 +25,8 @@ export default class ModlogContextMenuCommand extends ContextMenuCommand { }); await interaction.deferReply({ ephemeral: true }); - const pseudoMessage = new BushSlashMessage(client, interaction as any); - pseudoMessage.util = new BushCommandUtil(client.commandHandler, pseudoMessage); + const pseudoMessage = new SlashMessage(client, interaction as any); + pseudoMessage.util = new CommandUtil(client.commandHandler, pseudoMessage); void new ModlogCommand().exec(pseudoMessage, { search: interaction.targetId, hidden: false }); } diff --git a/src/context-menu-commands/user/userInfo.ts b/src/context-menu-commands/user/userInfo.ts index 8ecde92..80e9883 100644 --- a/src/context-menu-commands/user/userInfo.ts +++ b/src/context-menu-commands/user/userInfo.ts @@ -1,7 +1,6 @@ import { UserInfoCommand } from '#commands'; -import { type BushGuild } from '#lib'; import { ContextMenuCommand } from 'discord-akairo'; -import { ApplicationCommandType, type ContextMenuCommandInteraction } from 'discord.js'; +import { ApplicationCommandType, type ContextMenuCommandInteraction, type Guild } from 'discord.js'; export default class UserInfoContextMenuCommand extends ContextMenuCommand { public constructor() { @@ -18,7 +17,7 @@ export default class UserInfoContextMenuCommand extends ContextMenuCommand { const user = await client.users.fetch(interaction.targetId).catch(() => null); if (!user) return interaction.reply(`⁉ I couldn't find that user`); - const guild = interaction.guild as BushGuild; + const guild = interaction.guild as Guild; const member = await guild.members.fetch(interaction.targetId).catch(() => null); if (!member) return interaction.reply(`${util.format.input(user.tag)} doesn't appear to be a member of this server anymore.`); diff --git a/src/inhibitors/blacklist/channelGlobalBlacklist.ts b/src/inhibitors/blacklist/channelGlobalBlacklist.ts index 34c23af..1ac26f1 100644 --- a/src/inhibitors/blacklist/channelGlobalBlacklist.ts +++ b/src/inhibitors/blacklist/channelGlobalBlacklist.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class UserGlobalBlacklistInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class UserGlobalBlacklistInhibitor extends BushInhibitor { }); } - public override exec(message: BushMessage | BushSlashMessage, command: BushCommand): boolean { + public override exec(message: CommandMessage | SlashMessage, command: BushCommand): boolean { if (!message.author || !message.inGuild()) return false; // do not change to message.author.isOwner() if (client.isOwner(message.author) || client.user!.id === message.author.id) return false; diff --git a/src/inhibitors/blacklist/channelGuildBlacklist.ts b/src/inhibitors/blacklist/channelGuildBlacklist.ts index 09f58d0..a634015 100644 --- a/src/inhibitors/blacklist/channelGuildBlacklist.ts +++ b/src/inhibitors/blacklist/channelGuildBlacklist.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class ChannelGuildBlacklistInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class ChannelGuildBlacklistInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage, command: BushCommand): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> { if (!message.author || !message.inGuild()) return false; // do not change to message.author.isOwner() if (client.isOwner(message.author) || client.user!.id === message.author.id) return false; diff --git a/src/inhibitors/blacklist/guildBlacklist.ts b/src/inhibitors/blacklist/guildBlacklist.ts index d540af7..087bdb7 100644 --- a/src/inhibitors/blacklist/guildBlacklist.ts +++ b/src/inhibitors/blacklist/guildBlacklist.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type CommandMessage, type SlashMessage } from '#lib'; export default class GuildBlacklistInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class GuildBlacklistInhibitor extends BushInhibitor { }); } - public override exec(message: BushMessage | BushSlashMessage): boolean { + public override exec(message: CommandMessage | SlashMessage): boolean { if (!message.author || !message.inGuild()) return false; // do not change to message.author.isOwner() if (client.isOwner(message.author) || client.isSuperUser(message.author) || client.user!.id === message.author.id) diff --git a/src/inhibitors/blacklist/userGlobalBlacklist.ts b/src/inhibitors/blacklist/userGlobalBlacklist.ts index a3b0cdc..ae488c8 100644 --- a/src/inhibitors/blacklist/userGlobalBlacklist.ts +++ b/src/inhibitors/blacklist/userGlobalBlacklist.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type CommandMessage, type SlashMessage } from '#lib'; export default class UserGlobalBlacklistInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class UserGlobalBlacklistInhibitor extends BushInhibitor { }); } - public override exec(message: BushMessage | BushSlashMessage): boolean { + public override exec(message: CommandMessage | SlashMessage): boolean { if (!message.author) return false; // do not change to message.author.isOwner() if (client.isOwner(message.author) || client.user!.id === message.author.id) return false; diff --git a/src/inhibitors/blacklist/userGuildBlacklist.ts b/src/inhibitors/blacklist/userGuildBlacklist.ts index b6c707a..c4fa527 100644 --- a/src/inhibitors/blacklist/userGuildBlacklist.ts +++ b/src/inhibitors/blacklist/userGuildBlacklist.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type CommandMessage, type SlashMessage } from '#lib'; export default class UserGuildBlacklistInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class UserGuildBlacklistInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage): Promise<boolean> { if (!message.author || !message.inGuild()) return false; // do not change to message.author.isOwner() if (client.isOwner(message.author) || client.isSuperUser(message.author) || client.user!.id === message.author.id) diff --git a/src/inhibitors/checks/fatal.ts b/src/inhibitors/checks/fatal.ts index 2521b2f..520754a 100644 --- a/src/inhibitors/checks/fatal.ts +++ b/src/inhibitors/checks/fatal.ts @@ -1,4 +1,5 @@ -import { BushInhibitor, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type SlashMessage } from '#lib'; +import { type Message } from 'discord.js'; export default class FatalInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +11,7 @@ export default class FatalInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage): Promise<boolean> { + public override async exec(message: Message | SlashMessage): Promise<boolean> { if (client.isOwner(message.author)) return false; for (const property in client.cache.global) { if (!client.cache.global[property as keyof typeof client.cache.global]) { diff --git a/src/inhibitors/checks/guildUnavailable.ts b/src/inhibitors/checks/guildUnavailable.ts index a13944d..45ec0da 100644 --- a/src/inhibitors/checks/guildUnavailable.ts +++ b/src/inhibitors/checks/guildUnavailable.ts @@ -1,4 +1,5 @@ -import { BushInhibitor, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type SlashMessage } from '#lib'; +import { type Message } from 'discord.js'; export default class GuildUnavailableInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +11,7 @@ export default class GuildUnavailableInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage): Promise<boolean> { + public override async exec(message: Message | SlashMessage): Promise<boolean> { if (message.inGuild() && !message.guild.available) { void client.console.verbose( 'guildUnavailable', diff --git a/src/inhibitors/command/dm.ts b/src/inhibitors/command/dm.ts index ebcd647..d6c13a9 100644 --- a/src/inhibitors/command/dm.ts +++ b/src/inhibitors/command/dm.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class DMInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class DMInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage, command: BushCommand): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> { if (command.channel === 'dm' && message.guild) { void client.console.verbose( 'dm', diff --git a/src/inhibitors/command/globalDisabledCommand.ts b/src/inhibitors/command/globalDisabledCommand.ts index 0ec1305..ada9716 100644 --- a/src/inhibitors/command/globalDisabledCommand.ts +++ b/src/inhibitors/command/globalDisabledCommand.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class DisabledGuildCommandInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class DisabledGuildCommandInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage, command: BushCommand): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> { if (message.author.isOwner()) return false; if (client.cache.global.disabledCommands.includes(command?.id)) { void client.console.verbose( diff --git a/src/inhibitors/command/guild.ts b/src/inhibitors/command/guild.ts index 69b5df9..8b249ff 100644 --- a/src/inhibitors/command/guild.ts +++ b/src/inhibitors/command/guild.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class GuildInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class GuildInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage, command: BushCommand): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> { if (command.channel === 'guild' && !message.guild) { void client.console.verbose( 'guild', diff --git a/src/inhibitors/command/guildDisabledCommand.ts b/src/inhibitors/command/guildDisabledCommand.ts index a04984d..a97f5cc 100644 --- a/src/inhibitors/command/guildDisabledCommand.ts +++ b/src/inhibitors/command/guildDisabledCommand.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class DisabledGuildCommandInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class DisabledGuildCommandInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage, command: BushCommand): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> { if (!message.guild || !message.guild) return false; if (message.author.isOwner() || message.author.isSuperUser()) return false; // super users bypass guild disabled commands diff --git a/src/inhibitors/command/nsfw.ts b/src/inhibitors/command/nsfw.ts index fb4e51f..6eb2878 100644 --- a/src/inhibitors/command/nsfw.ts +++ b/src/inhibitors/command/nsfw.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import { type TextChannel } from 'discord.js'; export default class NsfwInhibitor extends BushInhibitor { @@ -11,7 +11,7 @@ export default class NsfwInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage, command: BushCommand): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> { if (command.onlyNsfw && !(message.channel as TextChannel).nsfw) { void client.console.verbose( 'notNsfw', diff --git a/src/inhibitors/command/owner.ts b/src/inhibitors/command/owner.ts index 8eee1e0..2331e04 100644 --- a/src/inhibitors/command/owner.ts +++ b/src/inhibitors/command/owner.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class OwnerInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class OwnerInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage, command: BushCommand): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> { if (command.ownerOnly) { if (!client.isOwner(message.author)) { void client.console.verbose( diff --git a/src/inhibitors/command/restrictedChannel.ts b/src/inhibitors/command/restrictedChannel.ts index c8f2e1e..6b06f95 100644 --- a/src/inhibitors/command/restrictedChannel.ts +++ b/src/inhibitors/command/restrictedChannel.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class RestrictedChannelInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class RestrictedChannelInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage, command: BushCommand): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> { if (command.restrictedChannels?.length && message.channel) { if (!command.restrictedChannels.includes(message.channel.id)) { void client.console.verbose( diff --git a/src/inhibitors/command/restrictedGuild.ts b/src/inhibitors/command/restrictedGuild.ts index a8a5097..47c61ce 100644 --- a/src/inhibitors/command/restrictedGuild.ts +++ b/src/inhibitors/command/restrictedGuild.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class RestrictedGuildInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class RestrictedGuildInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage, command: BushCommand): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> { if (command.restrictedChannels?.length && message.channel) { if (!command.restrictedChannels.includes(message.channel.id)) { void client.console.verbose( diff --git a/src/inhibitors/command/superUser.ts b/src/inhibitors/command/superUser.ts index a7c1f47..23b1c64 100644 --- a/src/inhibitors/command/superUser.ts +++ b/src/inhibitors/command/superUser.ts @@ -1,4 +1,4 @@ -import { BushInhibitor, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushInhibitor, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; export default class SuperUserInhibitor extends BushInhibitor { public constructor() { @@ -10,7 +10,7 @@ export default class SuperUserInhibitor extends BushInhibitor { }); } - public override async exec(message: BushMessage | BushSlashMessage, command: BushCommand): Promise<boolean> { + public override async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> { if (command.superUserOnly) { if (!client.isSuperUser(message.author)) { void client.console.verbose( diff --git a/src/lib/common/AutoMod.ts b/src/lib/common/AutoMod.ts index f30eab7..982e0e8 100644 --- a/src/lib/common/AutoMod.ts +++ b/src/lib/common/AutoMod.ts @@ -1,4 +1,4 @@ -import { banResponse, Moderation, type BushButtonInteraction, type BushMessage } from '#lib'; +import { banResponse, Moderation } from '#lib'; import assert from 'assert'; import chalk from 'chalk'; import { @@ -8,6 +8,8 @@ import { EmbedBuilder, GuildMember, PermissionFlagsBits, + type ButtonInteraction, + type Message, type TextChannel } from 'discord.js'; @@ -18,7 +20,7 @@ export class AutoMod { /** * The message to check for blacklisted phrases on */ - private message: BushMessage; + private message: Message; /** * Whether or not a punishment has already been given to the user @@ -28,7 +30,7 @@ export class AutoMod { /** * @param message The message to check and potentially perform automod actions to */ - public constructor(message: BushMessage) { + public constructor(message: Message) { this.message = message; if (message.author.id === client.user?.id) return; void this.handle(); @@ -355,7 +357,7 @@ export class AutoMod { * Handles the ban button in the automod log. * @param interaction The button interaction. */ - public static async handleInteraction(interaction: BushButtonInteraction) { + public static async handleInteraction(interaction: ButtonInteraction) { if (!interaction.memberPermissions?.has(PermissionFlagsBits.BanMembers)) return interaction.reply({ content: `${util.emojis.error} You are missing the **Ban Members** permission.`, @@ -382,7 +384,7 @@ export class AutoMod { user: userId, reason, moderator: interaction.user.id, - evidence: (interaction.message as BushMessage).url ?? undefined + evidence: (interaction.message as Message).url ?? undefined }); const victimUserFormatted = (await util.resolveNonCachedUser(userId))?.tag ?? userId; diff --git a/src/lib/common/ButtonPaginator.ts b/src/lib/common/ButtonPaginator.ts index cc95601..64870cf 100644 --- a/src/lib/common/ButtonPaginator.ts +++ b/src/lib/common/ButtonPaginator.ts @@ -1,7 +1,14 @@ -import { DeleteButton, type BushMessage, type BushSlashMessage } from '#lib'; +import { DeleteButton, type CommandMessage, type SlashMessage } from '#lib'; import { CommandUtil } from 'discord-akairo'; -import { APIEmbed } from 'discord-api-types/v10'; -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, type MessageComponentInteraction } from 'discord.js'; +import { + ActionRowBuilder, + ButtonBuilder, + ButtonStyle, + EmbedBuilder, + type APIEmbed, + type Message, + type MessageComponentInteraction +} from 'discord.js'; /** * Sends multiple embeds with controls to switch between them @@ -10,7 +17,7 @@ export class ButtonPaginator { /** * The message that triggered the command */ - protected message: BushMessage | BushSlashMessage; + protected message: CommandMessage | SlashMessage; /** * The embeds to paginate @@ -35,7 +42,7 @@ export class ButtonPaginator { /** * The paginator message */ - protected sentMessage: BushMessage | undefined; + protected sentMessage: Message | undefined; /** * @param message The message to respond to @@ -45,7 +52,7 @@ export class ButtonPaginator { * @param startOn The page to start from (**not** the index) */ protected constructor( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, embeds: EmbedBuilder[] | APIEmbed[], text: string | null, deleteOnExit: boolean, @@ -80,11 +87,11 @@ export class ButtonPaginator { * Sends the paginator message */ protected async send() { - this.sentMessage = (await this.message.util.reply({ + this.sentMessage = await this.message.util.reply({ content: this.text, embeds: [this.embeds[this.curPage]], components: [this.getPaginationRow()] - })) as BushMessage; + }); const collector = this.sentMessage.createMessageComponentCollector({ filter: (i) => i.customId.startsWith('paginate_'), @@ -214,7 +221,7 @@ export class ButtonPaginator { * @param startOn The page to start from (**not** the index) */ public static async send( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, embeds: EmbedBuilder[] | APIEmbed[], text: string | null = null, deleteOnExit = true, diff --git a/src/lib/common/ConfirmationPrompt.ts b/src/lib/common/ConfirmationPrompt.ts index c611fd3..c95dbbc 100644 --- a/src/lib/common/ConfirmationPrompt.ts +++ b/src/lib/common/ConfirmationPrompt.ts @@ -1,4 +1,4 @@ -import { type BushMessage, type BushSlashMessage } from '#lib'; +import { type CommandMessage, type SlashMessage } from '#lib'; import { ActionRowBuilder, ButtonBuilder, ButtonStyle, type MessageComponentInteraction, type MessageOptions } from 'discord.js'; /** @@ -13,13 +13,13 @@ export class ConfirmationPrompt { /** * The message that triggered the command */ - protected message: BushMessage | BushSlashMessage; + protected message: CommandMessage | SlashMessage; /** * @param message The message to respond to * @param options The send message options */ - protected constructor(message: BushMessage | BushSlashMessage, messageOptions: MessageOptions) { + protected constructor(message: CommandMessage | SlashMessage, messageOptions: MessageOptions) { this.message = message; this.messageOptions = messageOptions; } @@ -71,7 +71,7 @@ export class ConfirmationPrompt { * @param message The message to respond to * @param options The send message options */ - public static async send(message: BushMessage | BushSlashMessage, sendOptions: MessageOptions): Promise<boolean> { + public static async send(message: CommandMessage | SlashMessage, sendOptions: MessageOptions): Promise<boolean> { return new ConfirmationPrompt(message, sendOptions).send(); } } diff --git a/src/lib/common/DeleteButton.ts b/src/lib/common/DeleteButton.ts index 03e2639..91f4bfa 100644 --- a/src/lib/common/DeleteButton.ts +++ b/src/lib/common/DeleteButton.ts @@ -1,4 +1,4 @@ -import { PaginateEmojis, type BushMessage, type BushSlashMessage } from '#lib'; +import { PaginateEmojis, type CommandMessage, type SlashMessage } from '#lib'; import { CommandUtil } from 'discord-akairo'; import { ActionRowBuilder, @@ -22,13 +22,13 @@ export class DeleteButton { /** * The message that triggered the command */ - protected message: BushMessage | BushSlashMessage; + protected message: CommandMessage | SlashMessage; /** * @param message The message to respond to * @param options The send message options */ - protected constructor(message: BushMessage | BushSlashMessage, options: MessageOptions) { + protected constructor(message: CommandMessage | SlashMessage, options: MessageOptions) { this.message = message; this.messageOptions = options; } @@ -39,7 +39,7 @@ export class DeleteButton { protected async send() { this.updateComponents(); - const msg = (await this.message.util.reply(this.messageOptions)) as BushMessage; + const msg = await this.message.util.reply(this.messageOptions); const collector = msg.createMessageComponentCollector({ filter: (interaction) => interaction.customId == 'paginate__stop' && interaction.message?.id == msg.id, @@ -85,7 +85,7 @@ export class DeleteButton { * @param message The message to respond to * @param options The send message options */ - public static async send(message: BushMessage | BushSlashMessage, options: Omit<MessageOptions, 'components'>) { + public static async send(message: CommandMessage | SlashMessage, options: Omit<MessageOptions, 'components'>) { return new DeleteButton(message, options).send(); } } diff --git a/src/lib/common/HighlightManager.ts b/src/lib/common/HighlightManager.ts index fffb266..fdec322 100644 --- a/src/lib/common/HighlightManager.ts +++ b/src/lib/common/HighlightManager.ts @@ -1,6 +1,6 @@ -import { Highlight, type BushMessage, type HighlightWord } from '#lib'; +import { Highlight, type HighlightWord } from '#lib'; import assert from 'assert'; -import { Collection, type Snowflake } from 'discord.js'; +import { Collection, type Message, type Snowflake } from 'discord.js'; import { Time } from '../utils/BushConstants.js'; const NOTIFY_COOLDOWN = 5 * Time.Minute; @@ -75,7 +75,7 @@ export class HighlightManager { * @param message The message to check. * @returns A collection users mapped to the highlight matched */ - public checkMessage(message: BushMessage): Collection<Snowflake, HighlightWord> { + public checkMessage(message: Message): Collection<Snowflake, HighlightWord> { // even if there are multiple matches, only the first one is returned const ret = new Collection<Snowflake, HighlightWord>(); if (!message.content || !message.inGuild()) return ret; @@ -225,7 +225,7 @@ export class HighlightManager { * @param hl The highlight that was matched. * @returns Whether or a dm was sent. */ - public async notify(message: BushMessage, user: Snowflake, hl: HighlightWord): Promise<boolean> { + public async notify(message: Message, user: Snowflake, hl: HighlightWord): Promise<boolean> { assert(message.inGuild()); dmCooldown: { @@ -301,7 +301,7 @@ export class HighlightManager { * Updates the time that a user last talked in a particular guild. * @param message The message the user sent. */ - public updateLastTalked(message: BushMessage): void { + public updateLastTalked(message: Message): void { if (!message.inGuild()) return; const lastTalked = ( this.userLastTalkedCooldown.has(message.guildId) diff --git a/src/lib/common/util/Arg.ts b/src/lib/common/util/Arg.ts index 01d3b0b..51d8065 100644 --- a/src/lib/common/util/Arg.ts +++ b/src/lib/common/util/Arg.ts @@ -1,4 +1,10 @@ -import { type BaseBushArgumentType, type BushArgumentType, type BushArgumentTypeCaster, type BushSlashMessage } from '#lib'; +import { + type BaseBushArgumentType, + type BushArgumentType, + type BushArgumentTypeCaster, + type CommandMessage, + type SlashMessage +} from '#lib'; import { Argument, type Flag, type ParsedValuePredicate } from 'discord-akairo'; import { type Message } from 'discord.js'; @@ -12,10 +18,10 @@ export class Arg { * @param message - Message that called the command. * @param phrase - Phrase to process. */ - public static async cast<T extends ATC>(type: T, message: Message | BushSlashMessage, phrase: string): Promise<ATCR<T>>; - public static async cast<T extends KBAT>(type: T, message: Message | BushSlashMessage, phrase: string): Promise<BAT[T]>; - public static async cast(type: AT | ATC, message: Message | BushSlashMessage, phrase: string): Promise<any>; - public static async cast(type: ATC | AT, message: Message | BushSlashMessage, phrase: string): Promise<any> { + public static async cast<T extends ATC>(type: T, message: CommandMessage | SlashMessage, phrase: string): Promise<ATCR<T>>; + public static async cast<T extends KBAT>(type: T, message: CommandMessage | SlashMessage, phrase: string): Promise<BAT[T]>; + public static async cast(type: AT | ATC, message: CommandMessage | SlashMessage, phrase: string): Promise<any>; + public static async cast(type: ATC | AT, message: CommandMessage | SlashMessage, phrase: string): Promise<any> { return Argument.cast(type as any, client.commandHandler.resolver, message as Message, phrase); } diff --git a/src/lib/common/util/Moderation.ts b/src/lib/common/util/Moderation.ts index 9f93375..6cdc141 100644 --- a/src/lib/common/util/Moderation.ts +++ b/src/lib/common/util/Moderation.ts @@ -1,17 +1,18 @@ -import { - ActivePunishment, - ActivePunishmentType, - Guild, - ModLog, - type BushGuild, - type BushGuildMember, - type BushGuildMemberResolvable, - type BushGuildResolvable, - type BushUserResolvable, - type ModLogType -} from '#lib'; +import { ActivePunishment, ActivePunishmentType, Guild as GuildDB, ModLog, type ModLogType } from '#lib'; import assert from 'assert'; -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, PermissionFlagsBits, type Snowflake } from 'discord.js'; +import { + ActionRowBuilder, + ButtonBuilder, + ButtonStyle, + EmbedBuilder, + PermissionFlagsBits, + type Guild, + type GuildMember, + type GuildMemberResolvable, + type GuildResolvable, + type Snowflake, + type UserResolvable +} from 'discord.js'; enum punishMap { 'warned' = 'warn', @@ -52,8 +53,8 @@ export class Moderation { * @returns `true` if the moderator can perform the action otherwise a reason why they can't. */ public static async permissionCheck( - moderator: BushGuildMember, - victim: BushGuildMember, + moderator: GuildMember, + victim: GuildMember, type: | 'mute' | 'unmute' @@ -146,7 +147,7 @@ export class Moderation { getCaseNumber = false ): Promise<{ log: ModLog | null; caseNum: number | null }> { // If guild does not exist create it so the modlog can reference a guild. - await Guild.findOrCreate({ + await GuildDB.findOrCreate({ where: { id: options.guild }, defaults: { id: options.guild } }); @@ -349,17 +350,17 @@ export interface CreateModLogEntryOptions extends BaseCreateModLogEntryOptions { /** * The user that a modlog entry is created for. */ - user: BushGuildMemberResolvable; + user: GuildMemberResolvable; /** * The moderator that created the modlog entry. */ - moderator: BushGuildMemberResolvable; + moderator: GuildMemberResolvable; /** * The guild that the punishment is created for. */ - guild: BushGuildResolvable; + guild: GuildResolvable; } /** @@ -394,7 +395,7 @@ export interface CreatePunishmentEntryOptions { /** * The user that the punishment is created for. */ - user: BushGuildMemberResolvable; + user: GuildMemberResolvable; /** * The length of time the punishment lasts for. @@ -404,7 +405,7 @@ export interface CreatePunishmentEntryOptions { /** * The guild that the punishment is created for. */ - guild: BushGuildResolvable; + guild: GuildResolvable; /** * The id of the modlog that is linked to the punishment entry. @@ -429,12 +430,12 @@ export interface RemovePunishmentEntryOptions { /** * The user that the punishment is destroyed for. */ - user: BushGuildMemberResolvable; + user: GuildMemberResolvable; /** * The guild that the punishment was in. */ - guild: BushGuildResolvable; + guild: GuildResolvable; /** * Extra information for the punishment. The role for role punishments and the channel for blocks. @@ -454,12 +455,12 @@ export interface PunishDMOptions { /** * The guild that the punishment is taking place in. */ - guild: BushGuild; + guild: Guild; /** * The user that is being punished. */ - user: BushUserResolvable; + user: UserResolvable; /** * The punishment that the user has received. diff --git a/src/lib/extensions/discord-akairo/BushArgumentTypeCaster.ts b/src/lib/extensions/discord-akairo/BushArgumentTypeCaster.ts index 7a9a3db..def7ad6 100644 --- a/src/lib/extensions/discord-akairo/BushArgumentTypeCaster.ts +++ b/src/lib/extensions/discord-akairo/BushArgumentTypeCaster.ts @@ -1,3 +1,3 @@ -import { type BushMessage } from '#lib'; +import { type CommandMessage } from '#lib'; -export type BushArgumentTypeCaster<R = unknown> = (message: BushMessage, phrase: string) => R; +export type BushArgumentTypeCaster<R = unknown> = (message: CommandMessage, phrase: string) => R; diff --git a/src/lib/extensions/discord-akairo/BushClient.ts b/src/lib/extensions/discord-akairo/BushClient.ts index db0ad91..2644231 100644 --- a/src/lib/extensions/discord-akairo/BushClient.ts +++ b/src/lib/extensions/discord-akairo/BushClient.ts @@ -10,28 +10,20 @@ import { roleWithDuration, snowflake } from '#args'; -import type { - BushBaseGuildEmojiManager, - BushChannelManager, - BushClientEvents, - BushClientUser, - BushGuildManager, - BushUserManager, - BushUserResolvable, - Config -} from '#lib'; +import type { BushClientEvents, Config } from '#lib'; import { patch, type PatchedElements } from '@notenoughupdates/events-intercept'; import * as Sentry from '@sentry/node'; import { AkairoClient, - ArgumentPromptData, ContextMenuCommandHandler, - OtherwiseContentSupplier, - version as akairoVersion + version as akairoVersion, + type ArgumentPromptData, + type ClientUtil, + type OtherwiseContentSupplier } from 'discord-akairo'; -import { GatewayIntentBits } from 'discord-api-types/v10'; import { ActivityType, + GatewayIntentBits, MessagePayload, Options, Partials, @@ -45,19 +37,21 @@ import { type MessageOptions, type ReplyMessageOptions, type Snowflake, + type UserResolvable, type WebhookEditMessageOptions } from 'discord.js'; -import EventEmitter from 'events'; +import type EventEmitter from 'events'; import { google } from 'googleapis'; import path from 'path'; import readline from 'readline'; import type { Options as SequelizeOptions, Sequelize as SequelizeType } from 'sequelize'; import { fileURLToPath } from 'url'; +import { tinyColor } from '../../../arguments/tinyColor.js'; import UpdateCacheTask from '../../../tasks/updateCache.js'; import UpdateStatsTask from '../../../tasks/updateStats.js'; import { HighlightManager } from '../../common/HighlightManager.js'; import { ActivePunishment } from '../../models/instance/ActivePunishment.js'; -import { Guild as GuildModel } from '../../models/instance/Guild.js'; +import { Guild as GuildDB } from '../../models/instance/Guild.js'; import { Highlight } from '../../models/instance/Highlight.js'; import { Level } from '../../models/instance/Level.js'; import { ModLog } from '../../models/instance/ModLog.js'; @@ -71,26 +65,10 @@ import { AllowedMentions } from '../../utils/AllowedMentions.js'; import { BushCache } from '../../utils/BushCache.js'; 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 { 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'; -import { BushGuildMember } from '../discord.js/BushGuildMember.js'; -import { BushMessage } from '../discord.js/BushMessage.js'; -import { BushMessageReaction } from '../discord.js/BushMessageReaction.js'; -import { BushModalSubmitInteraction } from '../discord.js/BushModalSubmitInteraction.js'; -import { BushNewsChannel } from '../discord.js/BushNewsChannel.js'; -import { BushPresence } from '../discord.js/BushPresence.js'; -import { BushRole } from '../discord.js/BushRole.js'; -import { BushSelectMenuInteraction } from '../discord.js/BushSelectMenuInteraction.js'; -import { BushTextChannel } from '../discord.js/BushTextChannel.js'; -import { BushThreadChannel } from '../discord.js/BushThreadChannel.js'; -import { BushThreadMember } from '../discord.js/BushThreadMember.js'; -import { BushUser } from '../discord.js/BushUser.js'; -import { BushVoiceChannel } from '../discord.js/BushVoiceChannel.js'; -import { BushVoiceState } from '../discord.js/BushVoiceState.js'; +import { ExtendedGuild } from '../discord.js/ExtendedGuild.js'; +import { ExtendedGuildMember } from '../discord.js/ExtendedGuildMember.js'; +import { ExtendedMessage } from '../discord.js/ExtendedMessage.js'; +import { ExtendedUser } from '../discord.js/ExtendedUser.js'; import { BushClientUtil } from './BushClientUtil.js'; import { BushCommandHandler } from './BushCommandHandler.js'; import { BushInhibitorHandler } from './BushInhibitorHandler.js'; @@ -98,11 +76,43 @@ import { BushListenerHandler } from './BushListenerHandler.js'; import { BushTaskHandler } from './BushTaskHandler.js'; const { Sequelize } = (await import('sequelize')).default; -export type BushReplyMessageType = string | MessagePayload | ReplyMessageOptions; -export type BushEditMessageType = string | MessageEditOptions | MessagePayload; -export type BushSlashSendMessageType = string | MessagePayload | InteractionReplyOptions; -export type BushSlashEditMessageType = string | MessagePayload | WebhookEditMessageOptions; -export type BushSendMessageType = string | MessagePayload | MessageOptions; +declare module 'discord.js' { + export interface Client extends EventEmitter { + /** + * The ID of the owner(s). + */ + ownerID: Snowflake | Snowflake[]; + /** + * The ID of the superUser(s). + */ + superUserID: Snowflake | Snowflake[]; + /** + * Utility methods. + */ + util: ClientUtil | BushClientUtil; + on<K extends keyof BushClientEvents>(event: K, listener: (...args: BushClientEvents[K]) => Awaitable<void>): this; + once<K extends keyof BushClientEvents>(event: K, listener: (...args: BushClientEvents[K]) => Awaitable<void>): this; + emit<K extends keyof BushClientEvents>(event: K, ...args: BushClientEvents[K]): boolean; + off<K extends keyof BushClientEvents>(event: K, listener: (...args: BushClientEvents[K]) => Awaitable<void>): this; + removeAllListeners<K extends keyof BushClientEvents>(event?: K): this; + /** + * Checks if a user is the owner of this bot. + * @param user - User to check. + */ + isOwner(user: UserResolvable): boolean; + /** + * Checks if a user is a super user of this bot. + * @param user - User to check. + */ + isSuperUser(user: UserResolvable): boolean; + } +} + +export type ReplyMessageType = string | MessagePayload | ReplyMessageOptions; +export type EditMessageType = string | MessageEditOptions | MessagePayload; +export type SlashSendMessageType = string | MessagePayload | InteractionReplyOptions; +export type SlashEditMessageType = string | MessagePayload | WebhookEditMessageOptions; +export type SendMessageType = string | MessagePayload | MessageOptions; const rl = readline.createInterface({ input: process.stdin, @@ -116,12 +126,9 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); * The main hub for interacting with the Discord API. */ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Ready> { - public declare channels: BushChannelManager; - public declare guilds: BushGuildManager; - public declare user: If<Ready, BushClientUser>; - public declare users: BushUserManager; - public declare util: BushClientUtil; public declare ownerID: Snowflake[]; + public declare superUserID: Snowflake[]; + public declare util: BushClientUtil; /** * Whether or not the client is ready. @@ -272,7 +279,7 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re prefix: async ({ guild }: Message) => { if (this.config.isDevelopment) return 'dev '; if (!guild) return this.config.prefix; - const prefix = await (guild as BushGuild).getSetting('prefix'); + const prefix = await guild.getSetting('prefix'); return (prefix ?? this.config.prefix) as string; }, allowMention: true, @@ -296,7 +303,6 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re automateCategories: false, autoRegisterSlashCommands: true, skipBuiltInPostInhibitors: true, - useSlashPermissions: false, aliasReplacement: /-/g }); this.contextMenuCommandHandler = new ContextMenuCommandHandler(this, { @@ -342,26 +348,10 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re * Extends discord.js structures before the client is instantiated. */ public static extendStructures(): void { - Structures.extend('GuildEmoji', () => BushGuildEmoji); - Structures.extend('DMChannel', () => BushDMChannel); - Structures.extend('TextChannel', () => BushTextChannel); - Structures.extend('VoiceChannel', () => BushVoiceChannel); - Structures.extend('CategoryChannel', () => BushCategoryChannel); - Structures.extend('NewsChannel', () => BushNewsChannel); - Structures.extend('ThreadChannel', () => BushThreadChannel); - Structures.extend('GuildMember', () => BushGuildMember); - Structures.extend('ThreadMember', () => BushThreadMember); - Structures.extend('Guild', () => BushGuild); - Structures.extend('Message', () => BushMessage); - Structures.extend('MessageReaction', () => BushMessageReaction); - Structures.extend('Presence', () => BushPresence); - Structures.extend('VoiceState', () => BushVoiceState); - Structures.extend('Role', () => BushRole); - Structures.extend('User', () => BushUser); - Structures.extend('ChatInputCommandInteraction', () => BushChatInputCommandInteraction); - Structures.extend('ButtonInteraction', () => BushButtonInteraction); - Structures.extend('SelectMenuInteraction', () => BushSelectMenuInteraction); - Structures.extend('ModalSubmitInteraction', () => BushModalSubmitInteraction); + Structures.extend('GuildMember', () => ExtendedGuildMember); + Structures.extend('Guild', () => ExtendedGuild); + Structures.extend('Message', () => ExtendedMessage); + Structures.extend('User', () => ExtendedUser); } /** @@ -407,7 +397,8 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re abbreviatedNumber, durationSeconds, globalUser, - messageLink + messageLink, + tinyColor }); this.sentry = Sentry; @@ -448,7 +439,7 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re public async dbPreInit() { try { await this.instanceDB.authenticate(); - GuildModel.initModel(this.instanceDB, this); + GuildDB.initModel(this.instanceDB, this); ModLog.initModel(this.instanceDB); ActivePunishment.initModel(this.instanceDB); Level.initModel(this.instanceDB); @@ -527,33 +518,22 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re } } - public override isOwner(user: BushUserResolvable): boolean { + public override isOwner(user: UserResolvable): boolean { return this.config.owners.includes(this.users.resolveId(user!)!); } - public override isSuperUser(user: BushUserResolvable): boolean { + public override isSuperUser(user: UserResolvable): boolean { const userID = this.users.resolveId(user)!; return client.cache.shared.superUsers.includes(userID) || this.config.owners.includes(userID); } } export interface BushClient<Ready extends boolean = boolean> extends EventEmitter, PatchedElements, AkairoClient<Ready> { - get emojis(): BushBaseGuildEmojiManager; - on<K extends keyof BushClientEvents>(event: K, listener: (...args: BushClientEvents[K]) => Awaitable<void>): this; - // on<S extends string | symbol>(event: Exclude<S, keyof BushClientEvents>, listener: (...args: any[]) => Awaitable<void>): this; - once<K extends keyof BushClientEvents>(event: K, listener: (...args: BushClientEvents[K]) => Awaitable<void>): this; - // once<S extends string | symbol>(event: Exclude<S, keyof BushClientEvents>, listener: (...args: any[]) => Awaitable<void>): this; - emit<K extends keyof BushClientEvents>(event: K, ...args: BushClientEvents[K]): boolean; - // emit<S extends string | symbol>(event: Exclude<S, keyof BushClientEvents>, ...args: unknown[]): boolean; - off<K extends keyof BushClientEvents>(event: K, listener: (...args: BushClientEvents[K]) => Awaitable<void>): this; - // off<S extends string | symbol>(event: Exclude<S, keyof BushClientEvents>, listener: (...args: any[]) => Awaitable<void>): this; - removeAllListeners<K extends keyof BushClientEvents>(event?: K): this; - // removeAllListeners<S extends string | symbol>(event?: Exclude<S, keyof BushClientEvents>): this; } export interface BushStats { diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts index 9fe70fa..19810bd 100644 --- a/src/lib/extensions/discord-akairo/BushClientUtil.ts +++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts @@ -1,41 +1,43 @@ import { Arg, - BaseBushArgumentType, BushConstants, + CommandMessage, Global, Shared, - SharedCache, + type BaseBushArgumentType, type BushClient, type BushInspectOptions, - type BushMessage, - type BushSlashEditMessageType, - type BushSlashMessage, - type BushSlashSendMessageType, - type BushUser, type CodeBlockLang, type GlobalCache, type Pronoun, - type PronounCode + type PronounCode, + type SharedCache, + type SlashEditMessageType, + type SlashMessage, + type SlashSendMessageType } from '#lib'; import { humanizeDuration } from '@notenoughupdates/humanize-duration'; import assert from 'assert'; import { exec } from 'child_process'; import deepLock from 'deep-lock'; import { ClientUtil, Util as AkairoUtil } from 'discord-akairo'; -import { APIEmbed, APIMessage, OAuth2Scopes, Routes } from 'discord-api-types/v10'; import { Constants as DiscordConstants, EmbedBuilder, GuildMember, Message, + OAuth2Scopes, PermissionFlagsBits, PermissionsBitField, - PermissionsString, + Routes, ThreadMember, User, Util as DiscordUtil, + type APIEmbed, + type APIMessage, type CommandInteraction, type InteractionReplyOptions, + type PermissionsString, type Snowflake, type TextChannel, type UserResolvable @@ -377,7 +379,7 @@ export class BushClientUtil extends ClientUtil { */ public async slashRespond( interaction: CommandInteraction, - responseOptions: BushSlashSendMessageType | BushSlashEditMessageType + responseOptions: SlashSendMessageType | SlashEditMessageType ): Promise<Message | APIMessage | undefined> { const newResponseOptions = typeof responseOptions === 'string' ? { content: responseOptions } : responseOptions; if (interaction.replied || interaction.deferred) { @@ -696,17 +698,17 @@ export class BushClientUtil extends ClientUtil { * @param user The user to fetch * @returns Undefined if the user is not found, otherwise the user. */ - public async resolveNonCachedUser(user: UserResolvable | undefined | null): Promise<BushUser | undefined> { + public async resolveNonCachedUser(user: UserResolvable | undefined | null): Promise<User | undefined> { if (user == null) return undefined; const resolvedUser = user instanceof User - ? <BushUser>user + ? user : user instanceof GuildMember - ? <BushUser>user.user + ? user.user : user instanceof ThreadMember - ? <BushUser>user.user + ? user.user : user instanceof Message - ? <BushUser>user.author + ? user.author : undefined; return resolvedUser ?? (await client.users.fetch(user as Snowflake).catch(() => undefined)); @@ -831,9 +833,10 @@ export class BushClientUtil extends ClientUtil { * @returns The missing permissions or null if none are missing. */ public userGuildPermCheck( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, permissions: typeof PermissionFlagsBits[keyof typeof PermissionFlagsBits][] ): PermissionsString[] | null { + if (!message.inGuild()) return null; const missing = message.member?.permissions.missing(permissions) ?? []; return missing.length ? missing : null; @@ -845,7 +848,7 @@ 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: bigint[]): PermissionsString[] | null { + public clientGuildPermCheck(message: CommandMessage | SlashMessage, permissions: bigint[]): PermissionsString[] | null { const missing = message.guild?.members.me?.permissions.missing(permissions) ?? []; return missing.length ? missing : null; @@ -860,7 +863,7 @@ export class BushClientUtil extends ClientUtil { * @returns The missing permissions or null if none are missing. */ public clientSendAndPermCheck( - message: BushMessage | BushSlashMessage, + message: CommandMessage | SlashMessage, permissions: bigint[] = [], checkChannel = false ): PermissionsString[] | null { @@ -868,7 +871,7 @@ export class BushClientUtil extends ClientUtil { const sendPerm = message.channel!.isThread() ? 'SendMessages' : 'SendMessagesInThreads'; if (!message.inGuild()) return null; - if (!message.guild.members.me!.permissionsIn(message.channel.id).has(sendPerm)) missing.push(sendPerm); + if (!message.guild.members.me!.permissionsIn(message.channel!.id).has(sendPerm)) missing.push(sendPerm); missing.push( ...(checkChannel @@ -884,7 +887,7 @@ export class BushClientUtil extends ClientUtil { * @param message The message to get the prefix from. * @returns The prefix. */ - public prefix(message: BushMessage | BushSlashMessage): string { + public prefix(message: CommandMessage | SlashMessage): string { return message.util.isSlash ? '/' : client.config.isDevelopment @@ -970,7 +973,7 @@ export class BushClientUtil extends ClientUtil { */ public async castDurationContent( arg: string | ParsedDuration | null, - message: BushMessage | BushSlashMessage + message: CommandMessage | SlashMessage ): Promise<ParsedDurationRes> { const res = typeof arg === 'string' ? await util.arg.cast('contentWithDuration', message, arg) : arg; @@ -987,7 +990,7 @@ export class BushClientUtil extends ClientUtil { public async cast<T extends keyof BaseBushArgumentType>( type: T, arg: BaseBushArgumentType[T] | string, - message: BushMessage | BushSlashMessage + message: CommandMessage | SlashMessage ) { return typeof arg === 'string' ? await util.arg.cast(type, message, arg) : arg; } diff --git a/src/lib/extensions/discord-akairo/BushCommand.ts b/src/lib/extensions/discord-akairo/BushCommand.ts index c727e98..5fb4e06 100644 --- a/src/lib/extensions/discord-akairo/BushCommand.ts +++ b/src/lib/extensions/discord-akairo/BushCommand.ts @@ -1,33 +1,17 @@ import { type DiscordEmojiInfo, type RoleWithDuration } from '#args'; import { type BushArgumentTypeCaster, - type BushBaseGuildVoiceChannel, - type BushCategoryChannel, type BushClient, type BushCommandHandler, - type BushEmoji, - type BushGuild, - type BushGuildBasedChannel, - type BushGuildChannel, - type BushGuildEmoji, - type BushGuildMember, type BushInhibitor, type BushListener, - type BushMessage, - type BushNewsChannel, - type BushRole, - type BushSlashMessage, - type BushStageChannel, type BushTask, - type BushTextChannel, - type BushThreadChannel, - type BushUser, - type BushVoiceChannel, type ParsedDuration } from '#lib'; import { ArgumentMatch, Command, + CommandUtil, type AkairoApplicationCommandAutocompleteOption, type AkairoApplicationCommandChannelOptionData, type AkairoApplicationCommandChoicesData, @@ -47,51 +31,17 @@ import { type SlashResolveType } from 'discord-akairo'; import { + Message, + User, type ApplicationCommandOptionChoiceData, - type Collection, - type Invite, type PermissionResolvable, type PermissionsString, type Snowflake } from 'discord.js'; import _ from 'lodash'; +import { SlashMessage } from './SlashMessage.js'; export interface OverriddenBaseArgumentType extends BaseArgumentType { - user: BushUser | null; - users: Collection<string, BushUser> | null; - member: BushGuildMember | null; - members: Collection<string, BushGuildMember> | null; - relevant: BushUser | BushGuildMember | null; - relevants: Collection<string, BushUser> | Collection<string, BushGuildMember> | null; - channel: BushGuildBasedChannel | BushBaseGuildVoiceChannel | null; - channels: Collection<string, BushGuildBasedChannel | BushBaseGuildVoiceChannel> | null; - textChannel: BushTextChannel | null; - textChannels: Collection<string, BushTextChannel> | null; - voiceChannel: BushVoiceChannel | null; - voiceChannels: Collection<string, BushVoiceChannel> | null; - categoryChannel: BushCategoryChannel | null; - categoryChannels: Collection<string, BushCategoryChannel> | null; - newsChannel: BushNewsChannel | null; - newsChannels: Collection<string, BushNewsChannel> | null; - stageChannel: BushStageChannel | null; - stageChannels: Collection<string, BushStageChannel> | null; - threadChannel: BushThreadChannel | null; - threadChannels: Collection<string, BushThreadChannel> | null; - role: BushRole | null; - roles: Collection<string, BushRole> | null; - emoji: BushEmoji | null; - emojis: Collection<string, BushEmoji> | null; - guild: BushGuild | null; - guilds: Collection<string, BushGuild> | null; - message: BushMessage | null; - guildMessage: BushMessage | null; - relevantMessage: BushMessage | null; - invite: Invite | null; - userMention: BushUser | null; - memberMention: BushGuildMember | null; - channelMention: BushThreadChannel | BushGuildChannel | null; - roleMention: BushRole | null; - emojiMention: BushGuildEmoji | null; commandAlias: BushCommand | null; command: BushCommand | null; inhibitor: BushInhibitor | null; @@ -108,9 +58,10 @@ export interface BaseBushArgumentType extends OverriddenBaseArgumentType { discordEmoji: DiscordEmojiInfo | null; roleWithDuration: RoleWithDuration | null; abbreviatedNumber: number | null; - globalUser: BushUser | null; - messageLink: BushMessage | null; + globalUser: User | null; + messageLink: Message | null; durationSeconds: number | null; + tinyColor: string | null; } export type BushArgumentType = keyof BaseBushArgumentType | RegExp; @@ -247,6 +198,7 @@ export interface BushArgumentOptions extends BaseBushArgumentOptions { */ type?: BushArgumentType | (keyof BaseBushArgumentType)[] | BushArgumentTypeCaster; } + export interface CustomBushArgumentOptions extends BaseBushArgumentOptions { /** * An array of strings can be used to restrict input to only those strings, case insensitive. @@ -259,7 +211,7 @@ export interface CustomBushArgumentOptions extends BaseBushArgumentOptions { customType?: (string | string[])[] | RegExp | string | null; } -export type BushMissingPermissionSupplier = (message: BushMessage | BushSlashMessage) => Promise<any> | any; +export type BushMissingPermissionSupplier = (message: CommandMessage | SlashMessage) => Promise<any> | any; interface ExtendedCommandOptions { /** @@ -407,9 +359,7 @@ export interface ArgsInfo { export class BushCommand extends Command { public declare client: BushClient; - public declare handler: BushCommandHandler; - public declare description: string; /** @@ -595,13 +545,13 @@ export interface BushCommand extends Command { * @param message - Message that triggered the command. * @param args - Evaluated arguments. */ - exec(message: BushMessage, args: any): any; + exec(message: CommandMessage, args: any): any; /** * Executes the command. * @param message - Message that triggered the command. * @param args - Evaluated arguments. */ - exec(message: BushMessage | BushSlashMessage, args: any): any; + exec(message: CommandMessage | SlashMessage, args: any): any; } type SlashOptionKeys = @@ -615,7 +565,22 @@ type SlashOptionKeys = interface PseudoArguments extends BaseBushArgumentType { boolean: boolean; + flag: boolean; + regex: { match: RegExpMatchArray; matches: RegExpExecArray[] }; } export type ArgType<T extends keyof PseudoArguments> = NonNullable<PseudoArguments[T]>; export type OptArgType<T extends keyof PseudoArguments> = PseudoArguments[T]; + +/** + * `util` is always defined for messages after `'all'` inhibitors + */ +export type CommandMessage = Message & { + /** + * Extra properties applied to the Discord.js message object. + * Utilities for command responding. + * Available on all messages after 'all' inhibitors and built-in inhibitors (bot, client). + * Not all properties of the util are available, depending on the input. + * */ + util: CommandUtil<Message>; +}; diff --git a/src/lib/extensions/discord-akairo/BushCommandHandler.ts b/src/lib/extensions/discord-akairo/BushCommandHandler.ts index 2c1903f..f095356 100644 --- a/src/lib/extensions/discord-akairo/BushCommandHandler.ts +++ b/src/lib/extensions/discord-akairo/BushCommandHandler.ts @@ -1,35 +1,30 @@ -import { type BushClient, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { type BushClient, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import { CommandHandler, type Category, type CommandHandlerEvents, type CommandHandlerOptions } from 'discord-akairo'; -import { type Collection, type PermissionsString } from 'discord.js'; +import { type Collection, type Message, type PermissionsString } from 'discord.js'; export type BushCommandHandlerOptions = CommandHandlerOptions; export interface BushCommandHandlerEvents extends CommandHandlerEvents { - commandBlocked: [message: BushMessage, command: BushCommand, reason: string]; - commandBreakout: [message: BushMessage, command: BushCommand, breakMessage: BushMessage]; - commandCancelled: [message: BushMessage, command: BushCommand, retryMessage?: BushMessage]; - commandFinished: [message: BushMessage, command: BushCommand, args: any, returnValue: any]; - commandInvalid: [message: BushMessage, command: BushCommand]; - commandLocked: [message: BushMessage, command: BushCommand]; - commandStarted: [message: BushMessage, command: BushCommand, args: any]; - cooldown: [message: BushMessage | BushSlashMessage, command: BushCommand, remaining: number]; - error: [error: Error, message: BushMessage, command?: BushCommand]; - inPrompt: [message: BushMessage]; + commandBlocked: [message: CommandMessage, command: BushCommand, reason: string]; + commandBreakout: [message: CommandMessage, command: BushCommand, /* no util */ breakMessage: Message]; + commandCancelled: [message: CommandMessage, command: BushCommand, /* no util */ retryMessage?: Message]; + commandFinished: [message: CommandMessage, command: BushCommand, args: any, returnValue: any]; + commandInvalid: [message: CommandMessage, command: BushCommand]; + commandLocked: [message: CommandMessage, command: BushCommand]; + commandStarted: [message: CommandMessage, command: BushCommand, args: any]; + cooldown: [message: CommandMessage | SlashMessage, command: BushCommand, remaining: number]; + error: [error: Error, message: /* no util */ Message, command?: BushCommand]; + inPrompt: [message: /* no util */ Message]; load: [command: BushCommand, isReload: boolean]; - messageBlocked: [message: BushMessage | BushSlashMessage, reason: string]; - messageInvalid: [message: BushMessage]; - missingPermissions: [message: BushMessage, command: BushCommand, type: 'client' | 'user', missing: PermissionsString[]]; + messageBlocked: [message: /* no util */ Message | CommandMessage | SlashMessage, reason: string]; + messageInvalid: [message: CommandMessage]; + missingPermissions: [message: CommandMessage, command: BushCommand, type: 'client' | 'user', missing: PermissionsString[]]; remove: [command: BushCommand]; - slashBlocked: [message: BushSlashMessage, command: BushCommand, reason: string]; - slashError: [error: Error, message: BushSlashMessage, command: BushCommand]; - slashFinished: [message: BushSlashMessage, command: BushCommand, args: any, returnValue: any]; - slashMissingPermissions: [ - message: BushSlashMessage, - command: BushCommand, - type: 'client' | 'user', - missing: PermissionsString[] - ]; - slashStarted: [message: BushSlashMessage, command: BushCommand, args: any]; + slashBlocked: [message: SlashMessage, command: BushCommand, reason: string]; + slashError: [error: Error, message: SlashMessage, command: BushCommand]; + slashFinished: [message: SlashMessage, command: BushCommand, args: any, returnValue: any]; + slashMissingPermissions: [message: SlashMessage, command: BushCommand, type: 'client' | 'user', missing: PermissionsString[]]; + slashStarted: [message: SlashMessage, command: BushCommand, args: any]; } export class BushCommandHandler extends CommandHandler { diff --git a/src/lib/extensions/discord-akairo/BushCommandUtil.ts b/src/lib/extensions/discord-akairo/BushCommandUtil.ts deleted file mode 100644 index 7a06b35..0000000 --- a/src/lib/extensions/discord-akairo/BushCommandUtil.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { type BushCommand, type BushCommandHandler, type BushMessage, type BushSlashMessage } from '#lib'; -import { CommandUtil, type ParsedComponentData } from 'discord-akairo'; -import { type Collection, type Snowflake } from 'discord.js'; - -export interface BushParsedComponentData extends ParsedComponentData { - command?: BushCommand; -} - -export class BushCommandUtil<BushMessageType extends BushMessage | BushSlashMessage> extends CommandUtil<BushMessageType> { - public declare parsed: BushParsedComponentData | null; - public declare handler: BushCommandHandler; - public declare message: BushMessageType; - public declare messages: Collection<Snowflake, BushMessage> | null; - - public constructor(handler: BushCommandHandler, message: BushMessageType) { - super(handler, message); - } -} - -export interface BushCommandUtil<BushMessageType extends BushMessage | BushSlashMessage> extends CommandUtil<BushMessageType> { - isSlashMessage(message: BushMessage | BushSlashMessage): message is BushSlashMessage; -} diff --git a/src/lib/extensions/discord-akairo/BushInhibitor.ts b/src/lib/extensions/discord-akairo/BushInhibitor.ts index 7f13594..12b2baf 100644 --- a/src/lib/extensions/discord-akairo/BushInhibitor.ts +++ b/src/lib/extensions/discord-akairo/BushInhibitor.ts @@ -1,4 +1,4 @@ -import { type BushClient, type BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; +import { type BushClient, type BushCommand, type CommandMessage, type SlashMessage } from '#lib'; import { Inhibitor } from 'discord-akairo'; export class BushInhibitor extends Inhibitor { @@ -10,9 +10,12 @@ export interface BushInhibitor { * Checks if message should be blocked. * A return value of true will block the message. * If returning a Promise, a resolved value of true will block the message. + * + * **Note:** `all` type inhibitors do not have `message.util` defined. + * * @param message - Message being handled. * @param command - Command to check. */ - exec(message: BushMessage, command: BushCommand): any; - exec(message: BushMessage | BushSlashMessage, command: BushCommand): any; + exec(message: CommandMessage, command: BushCommand): any; + exec(message: CommandMessage | SlashMessage, command: BushCommand): any; } diff --git a/src/lib/extensions/discord-akairo/BushInhibitorHandler.ts b/src/lib/extensions/discord-akairo/BushInhibitorHandler.ts index a607bf7..5e4fb6c 100644 --- a/src/lib/extensions/discord-akairo/BushInhibitorHandler.ts +++ b/src/lib/extensions/discord-akairo/BushInhibitorHandler.ts @@ -1,6 +1,3 @@ -import { type BushClient } from '#lib'; import { InhibitorHandler } from 'discord-akairo'; -export class BushInhibitorHandler extends InhibitorHandler { - public declare client: BushClient; -} +export class BushInhibitorHandler extends InhibitorHandler {} diff --git a/src/lib/extensions/discord-akairo/BushListener.ts b/src/lib/extensions/discord-akairo/BushListener.ts index f6247ec..3efe527 100644 --- a/src/lib/extensions/discord-akairo/BushListener.ts +++ b/src/lib/extensions/discord-akairo/BushListener.ts @@ -1,10 +1,7 @@ -import { type BushClient } from '#lib'; import { Listener } from 'discord-akairo'; import type EventEmitter from 'events'; export class BushListener extends Listener { - public declare client: BushClient; - public constructor( id: string, options: { diff --git a/src/lib/extensions/discord-akairo/BushListenerHandler.ts b/src/lib/extensions/discord-akairo/BushListenerHandler.ts index 517fb55..9c3e4af 100644 --- a/src/lib/extensions/discord-akairo/BushListenerHandler.ts +++ b/src/lib/extensions/discord-akairo/BushListenerHandler.ts @@ -1,6 +1,3 @@ -import { type BushClient } from '#lib'; import { ListenerHandler } from 'discord-akairo'; -export class BushListenerHandler extends ListenerHandler { - public declare client: BushClient; -} +export class BushListenerHandler extends ListenerHandler {} diff --git a/src/lib/extensions/discord-akairo/BushSlashMessage.ts b/src/lib/extensions/discord-akairo/BushSlashMessage.ts deleted file mode 100644 index 0860964..0000000 --- a/src/lib/extensions/discord-akairo/BushSlashMessage.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - BushCommandHandler, - BushGuildTextBasedChannel, - type BushClient, - type BushCommandUtil, - type BushGuild, - type BushGuildMember, - type BushTextBasedChannel, - type BushUser -} from '#lib'; -import { AkairoMessage } from 'discord-akairo'; -import { type ChatInputCommandInteraction } from 'discord.js'; - -export class BushSlashMessage extends AkairoMessage { - public declare client: BushClient; - public declare util: BushCommandUtil<BushSlashMessage> & { handler: BushCommandHandler }; - public declare author: BushUser; - public declare member: BushGuildMember | null; - public declare interaction: ChatInputCommandInteraction; - public constructor(client: BushClient, interaction: ChatInputCommandInteraction) { - super(client, interaction); - } -} - -export interface BushSlashMessage extends AkairoMessage { - get channel(): BushTextBasedChannel | null; - get guild(): BushGuild | null; - inGuild(): this is BushSlashMessageInGuild & this; -} - -interface BushSlashMessageInGuild { - guild: BushGuild; - channel: BushGuildTextBasedChannel; -} diff --git a/src/lib/extensions/discord-akairo/BushTask.ts b/src/lib/extensions/discord-akairo/BushTask.ts index b4359ce..9f5c0cd 100644 --- a/src/lib/extensions/discord-akairo/BushTask.ts +++ b/src/lib/extensions/discord-akairo/BushTask.ts @@ -1,10 +1,3 @@ -import { type BushClient } from '#lib'; -import { Task, type TaskOptions } from 'discord-akairo'; +import { Task } from 'discord-akairo'; -export class BushTask extends Task { - public declare client: BushClient; - - public constructor(id: string, options: TaskOptions) { - super(id, options); - } -} +export class BushTask extends Task {} diff --git a/src/lib/extensions/discord-akairo/BushTaskHandler.ts b/src/lib/extensions/discord-akairo/BushTaskHandler.ts index ed6b91d..f667ead 100644 --- a/src/lib/extensions/discord-akairo/BushTaskHandler.ts +++ b/src/lib/extensions/discord-akairo/BushTaskHandler.ts @@ -1,12 +1,5 @@ -import { type BushClient } from '#lib'; import { TaskHandler, type AkairoHandlerOptions } from 'discord-akairo'; export type BushTaskHandlerOptions = AkairoHandlerOptions; -export class BushTaskHandler extends TaskHandler { - public declare client: BushClient; - - public constructor(client: BushClient, options: BushTaskHandlerOptions) { - super(client, options); - } -} +export class BushTaskHandler extends TaskHandler {} diff --git a/src/lib/extensions/discord-akairo/SlashMessage.ts b/src/lib/extensions/discord-akairo/SlashMessage.ts new file mode 100644 index 0000000..0a6669b --- /dev/null +++ b/src/lib/extensions/discord-akairo/SlashMessage.ts @@ -0,0 +1,3 @@ +import { AkairoMessage } from 'discord-akairo'; + +export class SlashMessage extends AkairoMessage {} diff --git a/src/lib/extensions/discord.js/BushActivity.ts b/src/lib/extensions/discord.js/BushActivity.ts deleted file mode 100644 index 3f19232..0000000 --- a/src/lib/extensions/discord.js/BushActivity.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { BushEmoji, BushPresence } from '#lib'; -import { Activity } from 'discord.js'; -import type { RawActivityData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents an activity that is part of a user's presence. - */ -export class BushActivity extends Activity { - public declare emoji: BushEmoji | null; - - public constructor(presence: BushPresence, data?: RawActivityData) { - super(presence, data); - } -} diff --git a/src/lib/extensions/discord.js/BushApplicationCommand.ts b/src/lib/extensions/discord.js/BushApplicationCommand.ts deleted file mode 100644 index 8298830..0000000 --- a/src/lib/extensions/discord.js/BushApplicationCommand.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-types */ -import type { BushClient, BushGuild } from '#lib'; -import { ApplicationCommand, type Snowflake } from 'discord.js'; -import type { RawApplicationCommandData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents an application command. - */ -export class BushApplicationCommand<PermissionsFetchType = {}> extends ApplicationCommand<PermissionsFetchType> { - public declare readonly client: BushClient; - public declare guild: BushGuild | null; - - public constructor(client: BushClient, data: RawApplicationCommandData, guild?: BushGuild, guildID?: Snowflake) { - super(client, data, guild, guildID); - } -} diff --git a/src/lib/extensions/discord.js/BushApplicationCommandManager.ts b/src/lib/extensions/discord.js/BushApplicationCommandManager.ts deleted file mode 100644 index dc27dbf..0000000 --- a/src/lib/extensions/discord.js/BushApplicationCommandManager.ts +++ /dev/null @@ -1,151 +0,0 @@ -import type { - BushApplicationCommand, - BushApplicationCommandPermissionsManager, - BushApplicationCommandResolvable, - BushClient, - BushGuildResolvable, - StripPrivate -} from '#lib'; -import type { APIApplicationCommand } from 'discord-api-types/v10'; -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<Snowflake, ApplicationCommandScope, BushApplicationCommandResolvable> - implements StripPrivate<ApplicationCommandManager<ApplicationCommandScope, PermissionsOptionsExtras, PermissionsGuildType>> -{ - public constructor(client: BushClient, iterable?: Iterable<unknown>); - - /** - * 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<ApplicationCommandScope>; - - /** - * 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<ApplicationCommandScope | null>; - - /** - * 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<ApplicationCommandScope>; - public edit( - command: BushApplicationCommandResolvable, - data: ApplicationCommandData, - guildId: Snowflake - ): Promise<BushApplicationCommand>; - - /** - * 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<BushApplicationCommand>; - public fetch(options: FetchApplicationCommandOptions): Promise<Collection<string, ApplicationCommandScope>>; - public fetch(id: Snowflake, options?: FetchApplicationCommandOptions): Promise<ApplicationCommandScope>; - public fetch(id?: Snowflake, options?: FetchApplicationCommandOptions): Promise<Collection<Snowflake, ApplicationCommandScope>>; - - /** - * 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<Collection<Snowflake, ApplicationCommandScope>>; - public set(commands: ApplicationCommandData[], guildId: Snowflake): Promise<Collection<Snowflake, BushApplicationCommand>>; - - /** - * 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<APIApplicationCommand, 'id' | 'application_id' | 'guild_id'>; -} diff --git a/src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.ts b/src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.ts deleted file mode 100644 index 401f3e2..0000000 --- a/src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.ts +++ /dev/null @@ -1,184 +0,0 @@ -import type { BushClient, BushRoleResolvable, BushUserResolvable } from '#lib'; -import type { APIApplicationCommandPermission } from 'discord-api-types/v10'; -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<ApplicationCommandPermissions[]>; - - /** - * 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<boolean>; - - /** - * 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<ApplicationCommandPermissions[]>; - public fetch(options: BaseOptions): Promise<Collection<Snowflake, ApplicationCommandPermissions[]>>; - - /** - * 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<ApplicationCommandPermissions[]>; - - /** - * 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<ApplicationCommandPermissions[]>; - public set( - options: FullPermissionsOptions & { - fullPermissions: GuildApplicationCommandPermissionData[]; - } - ): Promise<Collection<Snowflake, ApplicationCommandPermissions[]>>; - - /** - * 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<APIApplicationCommandPermission, 'type'> & { type: keyof ApplicationCommandPermissionType }; - private static transformPermissions(permissions: ApplicationCommandPermissionData): APIApplicationCommandPermission; -} diff --git a/src/lib/extensions/discord.js/BushBaseGuildEmojiManager.ts b/src/lib/extensions/discord.js/BushBaseGuildEmojiManager.ts deleted file mode 100644 index 66abbc2..0000000 --- a/src/lib/extensions/discord.js/BushBaseGuildEmojiManager.ts +++ /dev/null @@ -1,19 +0,0 @@ -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<Snowflake, BushGuildEmoji, BushEmojiResolvable> - implements BaseGuildEmojiManager -{ - public constructor(client: BushClient, iterable?: Iterable<RawGuildEmojiData>); - - /** - * 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/BushBaseGuildTextChannel.ts b/src/lib/extensions/discord.js/BushBaseGuildTextChannel.ts deleted file mode 100644 index 5cc74c4..0000000 --- a/src/lib/extensions/discord.js/BushBaseGuildTextChannel.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { BushCategoryChannel, BushClient, BushGuild, BushGuildMember, BushMessageManager, BushThreadManager } from '#lib'; -import { - BaseGuildTextChannel, - type AllowedThreadTypeForNewsChannel, - type AllowedThreadTypeForTextChannel, - type Collection, - type Snowflake -} from 'discord.js'; -import type { RawGuildChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a text-based guild channel on Discord. - */ -export class BushBaseGuildTextChannel extends BaseGuildTextChannel { - public declare messages: BushMessageManager; - public declare threads: BushThreadManager<AllowedThreadTypeForTextChannel | AllowedThreadTypeForNewsChannel>; - public declare readonly client: BushClient; - public declare guild: BushGuild; - - public constructor(guild: BushGuild, data?: RawGuildChannelData, client?: BushClient, immediatePatch?: boolean) { - super(guild, data, client, immediatePatch); - } -} - -export interface BushBaseGuildTextChannel extends BaseGuildTextChannel { - get members(): Collection<Snowflake, BushGuildMember>; - get parent(): BushCategoryChannel | null; -} diff --git a/src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.ts b/src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.ts deleted file mode 100644 index ba41cfe..0000000 --- a/src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BaseGuildVoiceChannel, Collection, Snowflake } from 'discord.js'; -import { BushCategoryChannel } from './BushCategoryChannel.js'; -import { BushGuild } from './BushGuild.js'; -import { BushGuildMember } from './BushGuildMember.js'; - -/** - * Represents a voice-based guild channel on Discord. - */ -export declare class BushBaseGuildVoiceChannel extends BaseGuildVoiceChannel { - public get members(): Collection<Snowflake, BushGuildMember>; - public guild: BushGuild; - public get parent(): BushCategoryChannel | null; -} diff --git a/src/lib/extensions/discord.js/BushButtonInteraction.ts b/src/lib/extensions/discord.js/BushButtonInteraction.ts deleted file mode 100644 index 368d19d..0000000 --- a/src/lib/extensions/discord.js/BushButtonInteraction.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { BushClient, BushGuild, BushGuildMember, BushGuildTextBasedChannel, BushTextBasedChannel, BushUser } from '#lib'; -import type { APIInteractionGuildMember } from 'discord-api-types/v10'; -import { ButtonInteraction, type CacheType, type CacheTypeReducer } from 'discord.js'; -import type { RawMessageButtonInteractionData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a button interaction. - */ -export class BushButtonInteraction<Cached extends CacheType = CacheType> extends ButtonInteraction<Cached> { - public declare member: CacheTypeReducer<Cached, BushGuildMember, APIInteractionGuildMember>; - public declare user: BushUser; - - public constructor(client: BushClient, data: RawMessageButtonInteractionData) { - super(client, data); - } -} - -export interface BushButtonInteraction<Cached extends CacheType = CacheType> extends ButtonInteraction<Cached> { - get channel(): CacheTypeReducer< - Cached, - BushGuildTextBasedChannel | null, - BushGuildTextBasedChannel | null, - BushGuildTextBasedChannel | null, - BushTextBasedChannel | null - >; - get guild(): CacheTypeReducer<Cached, BushGuild, null>; - inGuild(): this is BushButtonInteraction<'raw' | 'cached'>; - inCachedGuild(): this is BushButtonInteraction<'cached'>; - inRawGuild(): this is BushButtonInteraction<'raw'>; -} diff --git a/src/lib/extensions/discord.js/BushCategoryChannel.ts b/src/lib/extensions/discord.js/BushCategoryChannel.ts deleted file mode 100644 index a2e1e1c..0000000 --- a/src/lib/extensions/discord.js/BushCategoryChannel.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - BushDMChannel, - BushGuildBasedChannel, - BushNewsChannel, - BushStageChannel, - BushTextBasedChannel, - BushTextChannel, - BushThreadChannel, - BushVoiceBasedChannel, - BushVoiceChannel, - type BushCategoryChannelChildManager, - type BushClient, - type BushGuild -} from '#lib'; -import { CategoryChannel } from 'discord.js'; -import { type RawGuildChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a guild category channel on Discord. - */ -export class BushCategoryChannel extends CategoryChannel { - public declare readonly client: BushClient; - public declare guild: BushGuild; - - public constructor(guild: BushGuild, data?: RawGuildChannelData, client?: BushClient, immediatePatch?: boolean) { - super(guild, data, client, immediatePatch); - } -} - -export interface BushCategoryChannel extends CategoryChannel { - get children(): BushCategoryChannelChildManager; - isText(): this is BushTextChannel; - isDM(): this is BushDMChannel; - isVoice(): this is BushVoiceChannel; - isCategory(): this is BushCategoryChannel; - isNews(): this is BushNewsChannel; - 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/BushCategoryChannelChildManager.ts b/src/lib/extensions/discord.js/BushCategoryChannelChildManager.ts deleted file mode 100644 index 2b0d56b..0000000 --- a/src/lib/extensions/discord.js/BushCategoryChannelChildManager.ts +++ /dev/null @@ -1,44 +0,0 @@ -import type { - BushCategoryChannel, - BushGuild, - BushGuildChannelResolvable, - BushMappedChannelCategoryTypes, - BushNonCategoryGuildBasedChannel, - BushTextChannel -} from '#lib'; -import type { - CategoryChannelChildManager, - CategoryChannelType, - CategoryCreateChannelOptions, - DataManager, - Snowflake -} from 'discord.js'; - -export declare class BushCategoryChannelChildManager - extends DataManager<Snowflake, BushNonCategoryGuildBasedChannel, BushGuildChannelResolvable> - implements CategoryChannelChildManager -{ - private constructor(channel: BushCategoryChannel); - - /** - * The category channel this manager belongs to - */ - public channel: BushCategoryChannel; - - /** - * The guild this manager belongs to - */ - public readonly guild: BushGuild; - - /** - * Creates a new channel within this category. - * <info>You cannot create a channel of type {@link ChannelType.GuildCategory} inside a CategoryChannel.</info> - * @param name The name of the new channel - * @param options Options for creating the new channel - */ - public create<T extends CategoryChannelType>( - name: string, - options: CategoryCreateChannelOptions & { type: T } - ): Promise<BushMappedChannelCategoryTypes[T]>; - public create(name: string, options?: CategoryCreateChannelOptions): Promise<BushTextChannel>; -} diff --git a/src/lib/extensions/discord.js/BushChannel.ts b/src/lib/extensions/discord.js/BushChannel.ts deleted file mode 100644 index e66135c..0000000 --- a/src/lib/extensions/discord.js/BushChannel.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { - BushCategoryChannel, - BushClient, - BushDMChannel, - BushNewsChannel, - BushStageChannel, - BushTextBasedChannel, - BushTextChannel, - BushThreadChannel, - BushVoiceBasedChannel, - BushVoiceChannel -} from '#lib'; -import { Channel, ChannelType, PartialGroupDMChannel, 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 get createdAt(): Date | null; - public get createdTimestamp(): number | null; - public deleted: boolean; - public id: Snowflake; - public get partial(): false; - public type: ChannelType; - public delete(): Promise<this>; - public fetch(force?: boolean): Promise<this>; - public isText(): this is BushTextChannel; - public isDM(): this is BushDMChannel; - public isDMBased(): this is PartialGroupDMChannel | BushDMChannel; - public isVoice(): this is BushVoiceChannel; - public isCategory(): this is BushCategoryChannel; - public isNews(): this is BushNewsChannel; - 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.ts b/src/lib/extensions/discord.js/BushChannelManager.ts deleted file mode 100644 index ff93209..0000000 --- a/src/lib/extensions/discord.js/BushChannelManager.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { BushAnyChannel, BushChannelResolvable } from '#lib'; -import { CachedManager, ChannelManager, type Client, type FetchChannelOptions, type Snowflake } from 'discord.js'; -import type { RawChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * A manager of channels belonging to a client - */ -export declare class BushChannelManager - extends CachedManager<Snowflake, BushAnyChannel, BushChannelResolvable> - implements ChannelManager -{ - public constructor(client: Client, iterable: Iterable<RawChannelData>); - - /** - * Obtains a channel from Discord, or the channel cache if it's already available. - * @param id The channel's id - * @param options Additional options for this fetch - * @example - * // Fetch a channel by its id - * client.channels.fetch('222109930545610754') - * .then(channel => console.log(channel.name)) - * .catch(console.error); - */ - public fetch(id: Snowflake, options?: FetchChannelOptions): Promise<BushAnyChannel | null>; -} diff --git a/src/lib/extensions/discord.js/BushChatInputCommandInteraction.ts b/src/lib/extensions/discord.js/BushChatInputCommandInteraction.ts deleted file mode 100644 index 2491a68..0000000 --- a/src/lib/extensions/discord.js/BushChatInputCommandInteraction.ts +++ /dev/null @@ -1,49 +0,0 @@ -import type { - BushApplicationCommand, - BushClient, - BushGuild, - BushGuildEmoji, - BushGuildMember, - BushGuildTextBasedChannel, - BushNonThreadGuildBasedChannel, - BushRole, - BushTextBasedChannel, - BushUser -} from '#lib'; -import type { APIInteractionGuildMember } from 'discord-api-types/v10'; -import { ChatInputCommandInteraction, type CacheType, type CacheTypeReducer, type Invite, type Snowflake } from 'discord.js'; -import type { RawCommandInteractionData } from 'discord.js/typings/rawDataTypes'; - -export type BushGuildResolvable = - | BushGuild - | BushNonThreadGuildBasedChannel - | BushGuildMember - | BushGuildEmoji - | Invite - | BushRole - | Snowflake; - -/** - * Represents a command interaction. - */ -export class BushChatInputCommandInteraction<Cached extends CacheType = CacheType> extends ChatInputCommandInteraction<Cached> { - public declare readonly client: BushClient; - public declare member: CacheTypeReducer<Cached, BushGuildMember, APIInteractionGuildMember>; - public declare user: BushUser; - - public constructor(client: BushClient, data: RawCommandInteractionData) { - super(client, data); - } -} - -export interface BushChatInputCommandInteraction<Cached extends CacheType = CacheType> { - get command(): BushApplicationCommand | BushApplicationCommand<{ guild: BushGuildResolvable }> | null; - get channel(): CacheTypeReducer< - Cached, - BushGuildTextBasedChannel | null, - BushGuildTextBasedChannel | null, - BushGuildTextBasedChannel | null, - BushTextBasedChannel | null - >; - get guild(): CacheTypeReducer<Cached, BushGuild, null>; -} diff --git a/src/lib/extensions/discord.js/BushClientEvents.ts b/src/lib/extensions/discord.js/BushClientEvents.ts index e1a9954..22bae65 100644 --- a/src/lib/extensions/discord.js/BushClientEvents.ts +++ b/src/lib/extensions/discord.js/BushClientEvents.ts @@ -1,176 +1,29 @@ import type { BanResponse, - BushApplicationCommand, - BushButtonInteraction, - BushClient, - BushDMChannel, - BushGuild, - BushGuildBan, - BushGuildEmoji, - BushGuildMember, - BushGuildTextBasedChannel, - BushMessage, - BushMessageReaction, - BushModalSubmitInteraction, - BushNewsChannel, - BushNonThreadGuildBasedChannel, - BushPresence, - BushRole, - BushSelectMenuInteraction, - BushStageInstance, - BushTextBasedChannel, - BushTextChannel, - BushThreadChannel, - BushThreadMember, - BushUser, - BushVoiceState, - Guild, - GuildSettings, - PartialBushGuildMember, - PartialBushMessage, - PartialBushMessageReaction, - PartialBushUser + CommandMessage, + Guild as GuildDB, + GuildSettings } from '#lib'; import type { AkairoClientEvents } from 'discord-akairo'; import type { + ButtonInteraction, Collection, - GuildScheduledEvent, - Interaction, - Invite, + Guild, + GuildMember, + GuildTextBasedChannel, + Message, + ModalSubmitInteraction, + Role, + SelectMenuInteraction, Snowflake, - Sticker, - Typing + User } from 'discord.js'; export interface BushClientEvents extends AkairoClientEvents { - applicationCommandCreate: [command: BushApplicationCommand]; - applicationCommandDelete: [command: BushApplicationCommand]; - applicationCommandUpdate: [ - oldCommand: BushApplicationCommand | null, - newCommand: BushApplicationCommand - ]; - channelCreate: [channel: BushNonThreadGuildBasedChannel]; - channelDelete: [channel: BushDMChannel | BushNonThreadGuildBasedChannel]; - channelPinsUpdate: [channel: BushTextBasedChannel, date: Date]; - channelUpdate: [ - oldChannel: BushDMChannel | BushNonThreadGuildBasedChannel, - newChannel: BushDMChannel | BushNonThreadGuildBasedChannel - ]; - debug: [message: string]; - warn: [message: string]; - emojiCreate: [emoji: BushGuildEmoji]; - emojiDelete: [emoji: BushGuildEmoji]; - emojiUpdate: [oldEmoji: BushGuildEmoji, newEmoji: BushGuildEmoji]; - error: [error: Error]; - guildBanAdd: [ban: BushGuildBan]; - guildBanRemove: [ban: BushGuildBan]; - guildCreate: [guild: BushGuild]; - guildDelete: [guild: BushGuild]; - guildUnavailable: [guild: BushGuild]; - guildIntegrationsUpdate: [guild: BushGuild]; - guildMemberAdd: [member: BushGuildMember]; - guildMemberAvailable: [member: BushGuildMember | PartialBushGuildMember]; - guildMemberRemove: [member: BushGuildMember | PartialBushGuildMember]; - guildMembersChunk: [ - members: Collection<Snowflake, BushGuildMember>, - guild: BushGuild, - data: { - count: number; - index: number; - nonce: string | undefined; - } - ]; - guildMemberUpdate: [ - oldMember: BushGuildMember | PartialBushGuildMember, - newMember: BushGuildMember - ]; - guildUpdate: [oldGuild: BushGuild, newGuild: BushGuild]; - inviteCreate: [invite: Invite]; - inviteDelete: [invite: Invite]; - messageCreate: [message: BushMessage]; - messageDelete: [message: BushMessage | PartialBushMessage]; - messageReactionRemoveAll: [ - message: BushMessage | PartialBushMessage, - reactions: Collection<string, BushMessageReaction> - ]; - messageReactionRemoveEmoji: [ - reaction: BushMessageReaction | PartialBushMessageReaction - ]; - messageDeleteBulk: [ - messages: Collection<Snowflake, BushMessage | PartialBushMessage>, - channel: BushTextBasedChannel - ]; - messageReactionAdd: [ - reaction: BushMessageReaction | PartialBushMessageReaction, - user: BushUser | PartialBushUser - ]; - messageReactionRemove: [ - reaction: BushMessageReaction | PartialBushMessageReaction, - user: BushUser | PartialBushUser - ]; - messageUpdate: [ - oldMessage: BushMessage | PartialBushMessage, - newMessage: BushMessage | PartialBushMessage - ]; - presenceUpdate: [oldPresence: BushPresence | null, newPresence: BushPresence]; - ready: [client: BushClient<true>]; - invalidated: []; - roleCreate: [role: BushRole]; - roleDelete: [role: BushRole]; - roleUpdate: [oldRole: BushRole, newRole: BushRole]; - threadCreate: [thread: BushThreadChannel, newlyCreated: boolean]; - threadDelete: [thread: BushThreadChannel]; - threadListSync: [ - threads: Collection<Snowflake, BushThreadChannel>, - guild: BushGuild - ]; - threadMemberUpdate: [ - oldMember: BushThreadMember, - newMember: BushThreadMember - ]; - threadMembersUpdate: [ - oldMembers: Collection<Snowflake, BushThreadMember>, - newMembers: Collection<Snowflake, BushThreadMember>, - thread: BushThreadChannel - ]; - threadUpdate: [oldThread: BushThreadChannel, newThread: BushThreadChannel]; - typingStart: [typing: Typing]; - userUpdate: [oldUser: BushUser | PartialBushUser, newUser: BushUser]; - voiceStateUpdate: [oldState: BushVoiceState, newState: BushVoiceState]; - webhookUpdate: [channel: BushTextChannel]; - interactionCreate: [interaction: Interaction]; - shardError: [error: Error, shardId: number]; - shardReady: [shardId: number, unavailableGuilds: Set<Snowflake> | undefined]; - shardReconnecting: [shardId: number]; - shardResume: [shardId: number, replayedEvents: number]; - stageInstanceCreate: [stageInstance: BushStageInstance]; - stageInstanceUpdate: [ - oldStageInstance: BushStageInstance | null, - newStageInstance: BushStageInstance - ]; - stageInstanceDelete: [stageInstance: BushStageInstance]; - stickerCreate: [sticker: Sticker]; - stickerDelete: [sticker: Sticker]; - stickerUpdate: [oldSticker: Sticker, newSticker: Sticker]; - guildScheduledEventCreate: [guildScheduledEvent: GuildScheduledEvent]; - guildScheduledEventUpdate: [ - oldGuildScheduledEvent: GuildScheduledEvent, - newGuildScheduledEvent: GuildScheduledEvent - ]; - guildScheduledEventDelete: [guildScheduledEvent: GuildScheduledEvent]; - guildScheduledEventUserAdd: [ - guildScheduledEvent: GuildScheduledEvent, - user: BushUser - ]; - guildScheduledEventUserRemove: [ - guildScheduledEvent: GuildScheduledEvent, - user: BushUser - ]; - /* Custom */ bushBan: [ - victim: BushGuildMember | BushUser, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember | User, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, duration: number, @@ -178,29 +31,29 @@ export interface BushClientEvents extends AkairoClientEvents { evidence?: string ]; bushBlock: [ - victim: BushGuildMember, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, duration: number, dmSuccess: boolean, - channel: BushGuildTextBasedChannel, + channel: GuildTextBasedChannel, evidence?: string ]; bushKick: [ - victim: BushGuildMember, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, dmSuccess: boolean, evidence?: string ]; bushMute: [ - victim: BushGuildMember, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, duration: number, @@ -208,43 +61,43 @@ export interface BushClientEvents extends AkairoClientEvents { evidence?: string ]; bushPunishRole: [ - victim: BushGuildMember, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, duration: number, - role: BushRole, + role: Role, evidence?: string ]; bushPunishRoleRemove: [ - victim: BushGuildMember, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, - role: BushRole, + role: Role, evidence?: string ]; bushPurge: [ - moderator: BushUser, - guild: BushGuild, - channel: BushTextChannel | BushNewsChannel | BushThreadChannel, - messages: Collection<Snowflake, BushMessage> + moderator: User, + guild: Guild, + channel: GuildTextBasedChannel, + messages: Collection<Snowflake, Message> ]; bushRemoveTimeout: [ - victim: BushGuildMember, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, dmSuccess: boolean, evidence?: string ]; bushTimeout: [ - victim: BushGuildMember, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, duration: number, @@ -252,35 +105,35 @@ export interface BushClientEvents extends AkairoClientEvents { evidence?: string ]; bushUnban: [ - victim: BushUser, - moderator: BushUser, - guild: BushGuild, + victim: User, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, dmSuccess: boolean, evidence?: string ]; bushUnblock: [ - victim: BushGuildMember | BushUser, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember | User, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, dmSuccess: boolean, - channel: BushGuildTextBasedChannel, + channel: GuildTextBasedChannel, evidence?: string ]; bushUnmute: [ - victim: BushGuildMember, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, dmSuccess: boolean, evidence?: string ]; bushUpdateModlog: [ - moderator: BushGuildMember, + moderator: GuildMember, modlogID: string, key: 'evidence' | 'hidden', oldModlog: string | boolean, @@ -288,55 +141,55 @@ export interface BushClientEvents extends AkairoClientEvents { ]; bushUpdateSettings: [ setting: Setting, - guild: BushGuild, - oldValue: Guild[Setting], - newValue: Guild[Setting], - moderator?: BushGuildMember + guild: Guild, + oldValue: GuildDB[Setting], + newValue: GuildDB[Setting], + moderator?: GuildMember ]; bushWarn: [ - victim: BushGuildMember, - moderator: BushUser, - guild: BushGuild, + victim: GuildMember, + moderator: User, + guild: Guild, reason: string | undefined, caseID: string, dmSuccess: boolean, evidence?: string ]; bushLevelUpdate: [ - member: BushGuildMember, + member: GuildMember, oldLevel: number, newLevel: number, currentXp: number, - message: BushMessage & { guild: BushGuild } + message: CommandMessage ]; bushLockdown: [ - moderator: BushGuildMember, + moderator: GuildMember, reason: string | undefined, channelsSuccessMap: Collection<Snowflake, boolean>, all?: boolean ]; bushUnlockdown: [ - moderator: BushGuildMember, + moderator: GuildMember, reason: string | undefined, channelsSuccessMap: Collection<Snowflake, boolean>, all?: boolean ]; massBan: [ - moderator: BushGuildMember, - guild: BushGuild, + moderator: GuildMember, + guild: Guild, reason: string | undefined, results: Collection<Snowflake, BanResponse> ]; massEvidence: [ - moderator: BushGuildMember, - guild: BushGuild, + moderator: GuildMember, + guild: Guild, evidence: string, lines: string[] ]; /* components */ - button: [button: BushButtonInteraction]; - selectMenu: [selectMenu: BushSelectMenuInteraction]; - modal: [modal: BushModalSubmitInteraction]; + button: [button: ButtonInteraction]; + selectMenu: [selectMenu: SelectMenuInteraction]; + modal: [modal: ModalSubmitInteraction]; } type Setting = diff --git a/src/lib/extensions/discord.js/BushClientUser.ts b/src/lib/extensions/discord.js/BushClientUser.ts deleted file mode 100644 index cee9808..0000000 --- a/src/lib/extensions/discord.js/BushClientUser.ts +++ /dev/null @@ -1,98 +0,0 @@ -import type { - ActivityOptions, - Base64Resolvable, - BufferResolvable, - ClientPresence, - ClientUser, - ClientUserEditData, - PresenceData, - PresenceStatusData -} from 'discord.js'; -import { BushUser } from './BushUser.js'; - -/** - * Represents the logged in client's Discord user. - */ -export declare class BushClientUser extends BushUser implements ClientUser { - /** - * If the bot's {@link ClientApplication.owner Owner} has MFA enabled on their account - */ - public mfaEnabled: boolean; - - /** - * Represents the client user's presence - */ - public readonly presence: ClientPresence; - - /** - * Whether or not this account has been verified - */ - public verified: boolean; - - /** - * Edits the logged in client. - * @param data The new data - */ - public edit(data: ClientUserEditData): Promise<this>; - - /** - * Sets the activity the client user is playing. - * @param name Activity being played, or options for setting the activity - * @param options Options for setting the activity - * @example - * // Set the client user's activity - * client.user.setActivity('discord.js', { type: 'WATCHING' }); - */ - public setActivity(options?: ActivityOptions): ClientPresence; - public setActivity(name: string, options?: ActivityOptions): ClientPresence; - - /** - * Sets/removes the AFK flag for the client user. - * @param afk Whether or not the user is AFK - * @param shardId Shard Id(s) to have the AFK flag set on - */ - public setAFK(afk: boolean, shardId?: number | number[]): ClientPresence; - - /** - * Sets the avatar of the logged in client. - * @param avatar The new avatar - * @example - * // Set avatar - * client.user.setAvatar('./avatar.png') - * .then(user => console.log(`New avatar set!`)) - * .catch(console.error); - */ - public setAvatar(avatar: BufferResolvable | Base64Resolvable | null): Promise<this>; - - /** - * Sets the full presence of the client user. - * @param data Data for the presence - * @example - * // Set the client user's presence - * client.user.setPresence({ activities: [{ name: 'with discord.js' }], status: 'idle' }); - */ - public setPresence(data: PresenceData): ClientPresence; - - /** - * Sets the status of the client user. - * @param status Status to change to - * @param shardId Shard id(s) to have the activity set on - * @example - * // Set the client user's status - * client.user.setStatus('idle'); - */ - public setStatus(status: PresenceStatusData, shardId?: number | number[]): ClientPresence; - - /** - * Sets the username of the logged in client. - * <info>Changing usernames in Discord is heavily rate limited, with only 2 requests - * every hour. Use this sparingly!</info> - * @param username The new username - * @example - * // Set username - * client.user.setUsername('discordjs') - * .then(user => console.log(`My new username is ${user.username}`)) - * .catch(console.error); - */ - public setUsername(username: string): Promise<this>; -} diff --git a/src/lib/extensions/discord.js/BushDMChannel.ts b/src/lib/extensions/discord.js/BushDMChannel.ts deleted file mode 100644 index 87382ec..0000000 --- a/src/lib/extensions/discord.js/BushDMChannel.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { - BushCategoryChannel, - BushClient, - BushMessageManager, - BushNewsChannel, - BushStageChannel, - BushTextBasedChannel, - BushTextChannel, - BushThreadChannel, - BushUser, - BushVoiceBasedChannel, - BushVoiceChannel -} from '#lib'; -import { DMChannel, PartialGroupDMChannel, type Partialize } from 'discord.js'; -import type { RawDMChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a direct message channel between two users. - */ -export class BushDMChannel extends DMChannel { - public declare readonly client: BushClient; - public declare messages: BushMessageManager; - - public constructor(client: BushClient, data?: RawDMChannelData) { - super(client, data); - } -} - -export interface BushDMChannel extends DMChannel { - get recipient(): BushUser | null; - isText(): this is BushTextChannel; - isDM(): this is BushDMChannel; - isDMBased(): this is PartialGroupDMChannel | BushDMChannel; - isVoice(): this is BushVoiceChannel; - isCategory(): this is BushCategoryChannel; - isNews(): this is BushNewsChannel; - isThread(): this is BushThreadChannel; - isStage(): this is BushStageChannel; - isTextBased(): this is BushTextBasedChannel; - isVoiceBased(): this is BushVoiceBasedChannel; -} - -export interface PartialBushDMChannel extends Partialize<BushDMChannel, null, null, 'lastMessageId'> { - lastMessageId: undefined; -} diff --git a/src/lib/extensions/discord.js/BushEmoji.ts b/src/lib/extensions/discord.js/BushEmoji.ts deleted file mode 100644 index 9e42e5d..0000000 --- a/src/lib/extensions/discord.js/BushEmoji.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { BushClient } from '#lib'; -import { Emoji } from 'discord.js'; -import type { RawEmojiData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents an emoji, see {@link GuildEmoji} and {@link ReactionEmoji}. - */ -export class BushEmoji extends Emoji { - public declare readonly client: BushClient; - - public constructor(client: BushClient, emoji: RawEmojiData) { - super(client, emoji); - } -} diff --git a/src/lib/extensions/discord.js/BushGuildApplicationCommandManager.ts b/src/lib/extensions/discord.js/BushGuildApplicationCommandManager.ts deleted file mode 100644 index ba9db66..0000000 --- a/src/lib/extensions/discord.js/BushGuildApplicationCommandManager.ts +++ /dev/null @@ -1,114 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-types */ -import { - BushApplicationCommandManager, - type BushApplicationCommand, - type BushApplicationCommandResolvable, - type BushClient, - type BushGuild -} from '#lib'; -import type { ApplicationCommandData, BaseFetchOptions, Collection, Snowflake } from 'discord.js'; -import type { RawApplicationCommandData } from 'discord.js/typings/rawDataTypes'; - -/** - * An extension for guild-specific application commands. - */ -export declare class BushGuildApplicationCommandManager extends BushApplicationCommandManager< - BushApplicationCommand, - {}, - BushGuild -> { - public constructor(guild: BushGuild, iterable?: Iterable<RawApplicationCommandData>); - public declare readonly client: BushClient; - - /** - * The guild that this manager belongs to - */ - public guild: BushGuild; - - /** - * 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): Promise<BushApplicationCommand>; - - /** - * 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): Promise<BushApplicationCommand | null>; - - /** - * 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<BushApplicationCommand>; - - /** - * 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?: BaseFetchOptions): Promise<BushApplicationCommand>; - public fetch(options: BaseFetchOptions): Promise<Collection<Snowflake, BushApplicationCommand>>; - public fetch(id?: undefined, options?: BaseFetchOptions): Promise<Collection<Snowflake, BushApplicationCommand>>; - - /** - * 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<Collection<Snowflake, BushApplicationCommand>>; -} diff --git a/src/lib/extensions/discord.js/BushGuildBan.ts b/src/lib/extensions/discord.js/BushGuildBan.ts deleted file mode 100644 index d56c531..0000000 --- a/src/lib/extensions/discord.js/BushGuildBan.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { BushClient, BushGuild, BushUser } from '#lib'; -import { GuildBan } from 'discord.js'; -import type { RawGuildBanData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a ban in a guild on Discord. - */ -export declare class BushGuildBan extends GuildBan { - public constructor(client: BushClient, data: RawGuildBanData, guild: BushGuild); - public guild: BushGuild; - public user: BushUser; - public get partial(): boolean; - public reason?: string | null; - public fetch(force?: boolean): Promise<BushGuildBan>; -} diff --git a/src/lib/extensions/discord.js/BushGuildChannel.ts b/src/lib/extensions/discord.js/BushGuildChannel.ts deleted file mode 100644 index 62bf05a..0000000 --- a/src/lib/extensions/discord.js/BushGuildChannel.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { - BushCategoryChannel, - BushClient, - BushDMChannel, - BushGuild, - BushGuildBasedChannel, - BushNewsChannel, - BushStageChannel, - BushTextBasedChannel, - BushTextChannel, - BushThreadChannel, - BushVoiceBasedChannel, - BushVoiceChannel -} from '#lib'; -import { GuildChannel, PartialGroupDMChannel } from 'discord.js'; -import type { RawGuildChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a guild channel from any of the following: - * - {@link BushTextChannel} - * - {@link BushVoiceChannel} - * - {@link BushCategoryChannel} - * - {@link BushNewsChannel} - * - {@link BushStoreChannel} - * - {@link BushStageChannel} - */ -export class BushGuildChannel extends GuildChannel { - public declare readonly client: BushClient; - public declare guild: BushGuild; - - public constructor(guild: BushGuild, data?: RawGuildChannelData, client?: BushClient, immediatePatch?: boolean) { - super(guild, data, client, immediatePatch); - } -} - -export interface BushGuildChannel extends GuildChannel { - isText(): this is BushTextChannel; - isDMBased(): this is PartialGroupDMChannel | BushDMChannel; - isDM(): this is BushDMChannel; - isVoice(): this is BushVoiceChannel; - isCategory(): this is BushCategoryChannel; - isNews(): this is BushNewsChannel; - 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/BushGuildChannelManager.ts b/src/lib/extensions/discord.js/BushGuildChannelManager.ts deleted file mode 100644 index 4048b98..0000000 --- a/src/lib/extensions/discord.js/BushGuildChannelManager.ts +++ /dev/null @@ -1,183 +0,0 @@ -import type { - BushFetchedThreads, - BushGuild, - BushGuildBasedChannel, - BushGuildChannel, - BushMappedGuildChannelTypes, - BushNonThreadGuildBasedChannel, - BushTextChannel -} from '#lib'; -import { - CachedManager, - ChannelData, - ChannelWebhookCreateOptions, - SetChannelPositionOptions, - Webhook, - type BaseFetchOptions, - type ChannelPosition, - type Collection, - type GuildChannelCreateOptions, - type GuildChannelManager, - type GuildChannelResolvable, - type GuildChannelTypes, - type Snowflake -} from 'discord.js'; -import type { RawGuildChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * Manages API methods for GuildChannels and stores their cache. - */ -export declare class BushGuildChannelManager - extends CachedManager<Snowflake, BushGuildBasedChannel, GuildChannelResolvable> - implements GuildChannelManager -{ - public constructor(guild: BushGuild, iterable?: Iterable<RawGuildChannelData>); - - /** - * The number of channels in this managers cache excluding thread channels - * that do not count towards a guild's maximum channels restriction. - */ - public readonly channelCountWithoutThreads: number; - - /** - * The guild this Manager belongs to - */ - public guild: BushGuild; - - /** - * Creates a new channel in the guild. - * @param name The name of the new channel - * @param options Options for creating the new channel - * @example - * // Create a new text channel - * guild.channels.create('new-general', { reason: 'Needed a cool new channel' }) - * .then(console.log) - * .catch(console.error); - * @example - * // Create a new channel with permission overwrites - * guild.channels.create('new-voice', { - * type: 'GuildVoice', - * permissionOverwrites: [ - * { - * id: message.author.id, - * deny: [PermissionFlagsBits.ViewChannel], - * }, - * ], - * }) - */ - public create<T extends GuildChannelTypes>( - name: string, - options: GuildChannelCreateOptions & { type: T } - ): Promise<BushMappedGuildChannelTypes[T]>; - public create(name: string, options?: GuildChannelCreateOptions): Promise<BushTextChannel>; - - /** - * Creates a webhook for the channel. - * @param channel The channel to create the webhook for - * @param name The name of the webhook - * @param options Options for creating the webhook - * @returns Returns the created Webhook - * @example - * // Create a webhook for the current channel - * guild.channels.createWebhook('222197033908436994', 'Snek', { - * avatar: 'https://i.imgur.com/mI8XcpG.jpg', - * reason: 'Needed a cool new Webhook' - * }) - * .then(console.log) - * .catch(console.error) - */ - public createWebhook(channel: GuildChannelResolvable, name: string, options?: ChannelWebhookCreateOptions): Promise<Webhook>; - - /** - * Edits the channel. - * @param channel The channel to edit - * @param data The new data for the channel - * @param reason Reason for editing this channel - * @example - * // Edit a channel - * guild.channels.edit('222197033908436994', { name: 'new-channel' }) - * .then(console.log) - * .catch(console.error); - */ - public edit(channel: GuildChannelResolvable, data: ChannelData, reason?: string): Promise<BushGuildChannel>; - - /** - * Obtains one or more guild channels from Discord, or the channel cache if they're already available. - * @param id The channel's id - * @param options Additional options for this fetch - * @example - * // Fetch all channels from the guild (excluding threads) - * message.guild.channels.fetch() - * .then(channels => console.log(`There are ${channels.size} channels.`)) - * .catch(console.error); - * @example - * // Fetch a single channel - * message.guild.channels.fetch('222197033908436994') - * .then(channel => console.log(`The channel name is: ${channel.name}`)) - * .catch(console.error); - */ - public fetch(id: Snowflake, options?: BaseFetchOptions): Promise<BushNonThreadGuildBasedChannel | null>; - public fetch(id?: undefined, options?: BaseFetchOptions): Promise<Collection<Snowflake, BushNonThreadGuildBasedChannel>>; - - /** - * Fetches all webhooks for the channel. - * @param channel The channel to fetch webhooks for - * @example - * // Fetch webhooks - * guild.channels.fetchWebhooks('769862166131245066') - * .then(hooks => console.log(`This channel has ${hooks.size} hooks`)) - * .catch(console.error); - */ - public fetchWebhooks(channel: GuildChannelResolvable): Promise<Collection<Snowflake, Webhook>>; - - /** - * Sets a new position for the guild channel. - * @param channel The channel to set the position for - * @param position The new position for the guild channel - * @param options Options for setting position - * @example - * // Set a new channel position - * guild.channels.setPosition('222078374472843266', 2) - * .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`)) - * .catch(console.error); - */ - public setPosition( - channel: GuildChannelResolvable, - position: number, - options?: SetChannelPositionOptions - ): Promise<BushGuildChannel>; - - /** - * Batch-updates the guild's channels' positions. - * <info>Only one channel's parent can be changed at a time</info> - * @param channelPositions Channel positions to update - * @example - * guild.channels.setPositions([{ channel: channelId, position: newChannelIndex }]) - * .then(guild => console.log(`Updated channel positions for ${guild}`)) - * .catch(console.error); - */ - public setPositions(channelPositions: readonly ChannelPosition[]): Promise<BushGuild>; - - /** - * Obtains all active thread channels in the guild from Discord - * @param {} [cache=true] Whether to cache the fetched data - * @example - * // Fetch all threads from the guild - * message.guild.channels.fetchActiveThreads() - * .then(fetched => console.log(`There are ${fetched.threads.size} threads.`)) - * .catch(console.error); - */ - public fetchActiveThreads(cache?: boolean): Promise<BushFetchedThreads>; - - /** - * Deletes the channel. - * @param channel The channel to delete - * @param reason Reason for deleting this channel - * @example - * // Delete the channel - * guild.channels.delete('858850993013260338', 'making room for new channels') - * .then(console.log) - * .catch(console.error); - */ - public delete(channel: GuildChannelResolvable, reason?: string): Promise<void>; -} diff --git a/src/lib/extensions/discord.js/BushGuildEmoji.ts b/src/lib/extensions/discord.js/BushGuildEmoji.ts deleted file mode 100644 index 9b931bb..0000000 --- a/src/lib/extensions/discord.js/BushGuildEmoji.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { BushClient, BushGuild, BushGuildEmojiRoleManager, BushUser } from '#lib'; -import { GuildEmoji } from 'discord.js'; -import type { RawGuildEmojiData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a custom emoji. - */ -export class BushGuildEmoji extends GuildEmoji { - public declare readonly client: BushClient; - public declare guild: BushGuild; - public declare author: BushUser | null; - - public constructor(client: BushClient, data: RawGuildEmojiData, guild: BushGuild) { - super(client, data, guild); - } -} - -export interface BushGuildEmoji extends GuildEmoji { - get roles(): BushGuildEmojiRoleManager; -} diff --git a/src/lib/extensions/discord.js/BushGuildEmojiRoleManager.ts b/src/lib/extensions/discord.js/BushGuildEmojiRoleManager.ts deleted file mode 100644 index 8b069ae..0000000 --- a/src/lib/extensions/discord.js/BushGuildEmojiRoleManager.ts +++ /dev/null @@ -1,55 +0,0 @@ -import type { BushClient, BushGuild, BushGuildEmoji, BushRole, BushRoleResolvable } from '#lib'; -import { DataManager, GuildEmojiRoleManager, type Collection, type Snowflake } from 'discord.js'; - -/** - * Manages API methods for roles belonging to emojis and stores their cache. - */ -export declare class BushGuildEmojiRoleManager - extends DataManager<Snowflake, BushRole, BushRoleResolvable> - implements GuildEmojiRoleManager -{ - public constructor(emoji: BushGuildEmoji); - public declare readonly client: BushClient; - - /** - * The emoji belonging to this manager - */ - public emoji: BushGuildEmoji; - - /** - * The guild belonging to this manager - */ - public guild: BushGuild; - - /** - * Adds a role (or multiple roles) to the list of roles that can use this emoji. - * @param roleOrRoles The role or roles to add - */ - public add( - roleOrRoles: BushRoleResolvable | readonly BushRoleResolvable[] | Collection<Snowflake, BushRole> - ): Promise<BushGuildEmoji>; - - /** - * Sets the role(s) that can use this emoji. - * @param roles The roles or role ids to apply - * @example - * // Set the emoji's roles to a single role - * guildEmoji.roles.set(['391156570408615936']) - * .then(console.log) - * .catch(console.error); - * @example - * // Remove all roles from an emoji - * guildEmoji.roles.set([]) - * .then(console.log) - * .catch(console.error); - */ - public set(roles: readonly BushRoleResolvable[] | Collection<Snowflake, BushRole>): Promise<BushGuildEmoji>; - - /** - * Removes a role (or multiple roles) from the list of roles that can use this emoji. - * @param roleOrRoles The role or roles to remove - */ - public remove( - roleOrRoles: BushRoleResolvable | readonly BushRoleResolvable[] | Collection<Snowflake, BushRole> - ): Promise<BushGuildEmoji>; -} diff --git a/src/lib/extensions/discord.js/BushGuildManager.ts b/src/lib/extensions/discord.js/BushGuildManager.ts deleted file mode 100644 index 41618e3..0000000 --- a/src/lib/extensions/discord.js/BushGuildManager.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { BushClient, BushGuild, BushGuildResolvable } from '#lib'; -import { - CachedManager, - GuildManager, - type Collection, - type FetchGuildOptions, - type FetchGuildsOptions, - type GuildCreateOptions, - type OAuth2Guild, - type Snowflake -} from 'discord.js'; -import { type RawGuildData } from 'discord.js/typings/rawDataTypes'; - -/** - * Manages API methods for Guilds and stores their cache. - */ -export declare class BushGuildManager extends CachedManager<Snowflake, BushGuild, BushGuildResolvable> implements GuildManager { - public constructor(client: BushClient, iterable?: Iterable<RawGuildData>); - - /** - * Creates a guild. - * <warn>This is only available to bots in fewer than 10 guilds.</warn> - * @param name The name of the guild - * @param options Options for creating the guild - * @returns The guild that was created - */ - public create(name: string, options?: GuildCreateOptions): Promise<BushGuild>; - - /** - * Obtains one or multiple guilds from Discord, or the guild cache if it's already available. - * @param options The guild's id or options - */ - public fetch(options: Snowflake | FetchGuildOptions): Promise<BushGuild>; - public fetch(options?: FetchGuildsOptions): Promise<Collection<Snowflake, OAuth2Guild>>; -} diff --git a/src/lib/extensions/discord.js/BushGuildMemberManager.ts b/src/lib/extensions/discord.js/BushGuildMemberManager.ts deleted file mode 100644 index b0368b5..0000000 --- a/src/lib/extensions/discord.js/BushGuildMemberManager.ts +++ /dev/null @@ -1,177 +0,0 @@ -import type { BushClient, BushGuild, BushGuildMember, BushGuildMemberResolvable, BushUser, BushUserResolvable } from '#lib'; -import { - CachedManager, - GuildMemberManager, - type AddGuildMemberOptions, - type BanOptions, - type Collection, - type FetchMemberOptions, - type FetchMembersOptions, - type GuildListMembersOptions, - type GuildMemberEditData, - type GuildPruneMembersOptions, - type GuildSearchMembersOptions, - type Snowflake -} from 'discord.js'; -import type { RawGuildMemberData } from 'discord.js/typings/rawDataTypes'; - -/** - * Manages API methods for GuildMembers and stores their cache. - */ -export declare class BushGuildMemberManager - extends CachedManager<Snowflake, BushGuildMember, BushGuildMemberResolvable> - implements GuildMemberManager -{ - public constructor(guild: BushGuild, iterable?: Iterable<RawGuildMemberData>); - public declare readonly client: BushClient; - - /** - * The guild this manager belongs to - */ - public guild: BushGuild; - - /** - * Adds a user to the guild using OAuth2. Requires the `PermissionFlagsBits.CreateInstantInvite` permission. - * @param user The user to add to the guild - * @param options Options for adding the user to the guild - */ - public add( - user: BushUserResolvable, - options: AddGuildMemberOptions & { fetchWhenExisting: false } - ): Promise<BushGuildMember | null>; - public add(user: BushUserResolvable, options: AddGuildMemberOptions): Promise<BushGuildMember>; - - /** - * Bans a user from the guild. - * @param user The user to ban - * @param options Options for the ban - * @returns Result object will be resolved as specifically as possible. - * If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot - * be resolved, the user id will be the result. - * Internally calls the GuildBanManager#create method. - * @example - * // Ban a user by id (or with a user/guild member object) - * guild.members.ban('84484653687267328') - * .then(banInfo => console.log(`Banned ${banInfo.user?.tag ?? banInfo.tag ?? banInfo}`)) - * .catch(console.error); - */ - public ban(user: BushUserResolvable, options?: BanOptions): Promise<BushGuildMember | BushUser | Snowflake>; - - /** - * Edits a member of the guild. - * <info>The user must be a member of the guild</info> - * @param user The member to edit - * @param data The data to edit the member with - * @param reason Reason for editing this user - */ - public edit(user: BushUserResolvable, data: GuildMemberEditData, reason?: string): Promise<void>; - - /** - * Fetches member(s) from Discord, even if they're offline. - * @param options If a UserResolvable, the user to fetch. - * If undefined, fetches all members. - * If a query, it limits the results to users with similar usernames. - * @example - * // Fetch all members from a guild - * guild.members.fetch() - * .then(console.log) - * .catch(console.error); - * @example - * // Fetch a single member - * guild.members.fetch('66564597481480192') - * .then(console.log) - * .catch(console.error); - * @example - * // Fetch a single member without checking cache - * guild.members.fetch({ user, force: true }) - * .then(console.log) - * .catch(console.error) - * @example - * // Fetch a single member without caching - * guild.members.fetch({ user, cache: false }) - * .then(console.log) - * .catch(console.error); - * @example - * // Fetch by an array of users including their presences - * guild.members.fetch({ user: ['66564597481480192', '191615925336670208'], withPresences: true }) - * .then(console.log) - * .catch(console.error); - * @example - * // Fetch by query - * guild.members.fetch({ query: 'hydra', limit: 1 }) - * .then(console.log) - * .catch(console.error); - */ - public fetch( - options: BushUserResolvable | FetchMemberOptions | (FetchMembersOptions & { user: BushUserResolvable }) - ): Promise<BushGuildMember>; - public fetch(options?: FetchMembersOptions): Promise<Collection<Snowflake, BushGuildMember>>; - - /** - * Kicks a user from the guild. - * <info>The user must be a member of the guild</info> - * @param user The member to kick - * @param reason Reason for kicking - * @returns Result object will be resolved as specifically as possible. - * If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot - * be resolved, the user's id will be the result. - * @example - * // Kick a user by id (or with a user/guild member object) - * guild.members.kick('84484653687267328') - * .then(banInfo => console.log(`Kicked ${banInfo.user?.tag ?? banInfo.tag ?? banInfo}`)) - * .catch(console.error); - */ - public kick(user: BushUserResolvable, reason?: string): Promise<BushGuildMember | BushUser | Snowflake>; - - /** - * Lists up to 1000 members of the guild. - * @param options Options for listing members - */ - public list(options?: GuildListMembersOptions): Promise<Collection<Snowflake, BushGuildMember>>; - - /** - * Prunes members from the guild based on how long they have been inactive. - * @param options Options for pruning - * @returns The number of members that were/will be kicked - * @example - * // See how many members will be pruned - * guild.members.prune({ dry: true }) - * .then(pruned => console.log(`This will prune ${pruned} people!`)) - * .catch(console.error); - * @example - * // Actually prune the members - * guild.members.prune({ days: 1, reason: 'too many people!' }) - * .then(pruned => console.log(`I just pruned ${pruned} people!`)) - * .catch(console.error); - * @example - * // Include members with a specified role - * guild.members.prune({ days: 7, roles: ['657259391652855808'] }) - * .then(pruned => console.log(`I just pruned ${pruned} people!`)) - * .catch(console.error); - */ - public prune(options: GuildPruneMembersOptions & { dry?: false; count: false }): Promise<null>; - public prune(options?: GuildPruneMembersOptions): Promise<number>; - - /** - * Searches for members in the guild based on a query. - * @param options Options for searching members - */ - public search(options: GuildSearchMembersOptions): Promise<Collection<Snowflake, BushGuildMember>>; - - /** - * Unbans a user from the guild. Internally calls the {@link GuildBanManager.remove} method. - * @param user The user to unban - * @param reason Reason for unbanning user - * @returns The user that was unbanned - * @example - * // Unban a user by id (or with a user/guild member object) - * guild.members.unban('84484653687267328') - * .then(user => console.log(`Unbanned ${user.username} from ${guild.name}`)) - * .catch(console.error); - */ - public unban(user: BushUserResolvable, reason?: string): Promise<BushUser | null>; -} - -export interface BushGuildMemberManager extends CachedManager<Snowflake, BushGuildMember, BushGuildMemberResolvable> { - get me(): BushGuildMember | null; -} diff --git a/src/lib/extensions/discord.js/BushMessage.ts b/src/lib/extensions/discord.js/BushMessage.ts deleted file mode 100644 index 48e1792..0000000 --- a/src/lib/extensions/discord.js/BushMessage.ts +++ /dev/null @@ -1,63 +0,0 @@ -import type { - BushClient, - BushCommandUtil, - BushGuild, - BushGuildMember, - BushGuildTextBasedChannel, - BushMessageReaction, - BushTextBasedChannel, - BushThreadChannel, - BushUser -} from '#lib'; -import { - Message, - MessageActionRowComponent, - type EmojiIdentifierResolvable, - type If, - type MessageEditOptions, - type MessagePayload, - type Partialize, - type ReplyMessageOptions, - type StartThreadOptions -} from 'discord.js'; -import type { RawMessageData } from 'discord.js/typings/rawDataTypes'; - -export type PartialBushMessage = Partialize< - BushMessage, - 'type' | 'system' | 'pinned' | 'tts', - 'content' | 'cleanContent' | 'author' ->; - -/** - * Represents a message on Discord. - */ -export class BushMessage<Cached extends boolean = boolean> extends Message<Cached> { - public declare readonly client: BushClient; - public declare util: BushCommandUtil<BushMessage<true>>; - public declare author: BushUser; - - public constructor(client: BushClient, data: RawMessageData) { - super(client, data); - } -} - -export interface BushMessage<Cached extends boolean = boolean> extends Message<Cached> { - get guild(): If<Cached, BushGuild>; - get member(): BushGuildMember | null; - get channel(): If<Cached, BushGuildTextBasedChannel, BushTextBasedChannel>; - delete(): Promise<BushMessage>; - edit(content: string | MessageEditOptions | MessagePayload): Promise<BushMessage>; - equals(message: BushMessage, rawData: unknown): boolean; - fetchReference(): Promise<BushMessage>; - crosspost(): Promise<BushMessage>; - fetch(force?: boolean): Promise<BushMessage>; - pin(): Promise<BushMessage>; - react(emoji: EmojiIdentifierResolvable): Promise<BushMessageReaction>; - removeAttachments(): Promise<BushMessage>; - reply(options: string | MessagePayload | ReplyMessageOptions): Promise<BushMessage>; - resolveComponent(customId: string): MessageActionRowComponent | null; - startThread(options: StartThreadOptions): Promise<BushThreadChannel>; - suppressEmbeds(suppress?: boolean): Promise<BushMessage>; - unpin(): Promise<BushMessage>; - inGuild(): this is BushMessage<true> & this; -} diff --git a/src/lib/extensions/discord.js/BushMessageManager.ts b/src/lib/extensions/discord.js/BushMessageManager.ts deleted file mode 100644 index edb7982..0000000 --- a/src/lib/extensions/discord.js/BushMessageManager.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { BushMessageResolvable, BushTextBasedChannel, type BushMessage } from '#lib'; -import { - CachedManager, - FetchMessageOptions, - FetchMessagesOptions, - MessageManager, - type Collection, - type EmojiIdentifierResolvable, - type MessageEditOptions, - type MessagePayload, - type Snowflake -} from 'discord.js'; -import type { RawMessageData } from 'discord.js/typings/rawDataTypes'; - -/** - * Manages API methods for Messages and holds their cache. - */ -export declare class BushMessageManager - extends CachedManager<Snowflake, BushMessage, BushMessageResolvable> - implements MessageManager -{ - public constructor(channel: BushTextBasedChannel, iterable?: Iterable<RawMessageData>); - - /** - * The channel that the messages belong to - */ - public channel: BushTextBasedChannel; - - /** - * The cache of Messages - */ - public get cache(): Collection<Snowflake, BushMessage>; - - /** - * Publishes a message in an announcement channel to all channels following it, even if it's not cached. - * @param message The message to publish - */ - public crosspost(message: BushMessageResolvable): Promise<BushMessage>; - - /** - * Deletes a message, even if it's not cached. - * @param message The message to delete - */ - public delete(message: BushMessageResolvable): Promise<void>; - - /** - * Edits a message, even if it's not cached. - * @param message The message to edit - * @param options The options to edit the message - */ - public edit(message: BushMessageResolvable, options: string | MessagePayload | MessageEditOptions): Promise<BushMessage>; - - /** - * Gets a message, or messages, from this channel. - * <info>The returned Collection does not contain reaction users of the messages if they were not cached. - * Those need to be fetched separately in such a case.</info> - * @param message The id of the message to fetch, or query parameters. - * @param options Additional options for this fetch - * @example - * // Get message - * channel.messages.fetch('99539446449315840') - * .then(message => console.log(message.content)) - * .catch(console.error); - * @example - * // Get messages - * channel.messages.fetch({ limit: 10 }) - * .then(messages => console.log(`Received ${messages.size} messages`)) - * .catch(console.error); - * @example - * // Get messages and filter by user id - * channel.messages.fetch() - * .then(messages => console.log(`${messages.filter(m => m.author.id === '84484653687267328').size} messages`)) - * .catch(console.error); - */ - public fetch(options: BushMessageResolvable | FetchMessageOptions): Promise<BushMessage>; - public fetch(options?: FetchMessagesOptions): Promise<Collection<Snowflake, BushMessage>>; - - /** - * Fetches the pinned messages of this channel and returns a collection of them. - * <info>The returned Collection does not contain any reaction data of the messages. - * Those need to be fetched separately.</info> - * @param {} [cache=true] Whether to cache the message(s) - * @example - * // Get pinned messages - * channel.messages.fetchPinned() - * .then(messages => console.log(`Received ${messages.size} messages`)) - * .catch(console.error); - */ - public fetchPinned(cache?: boolean): Promise<Collection<Snowflake, BushMessage>>; - - /** - * Adds a reaction to a message, even if it's not cached. - * @param message The message to react to - * @param emoji The emoji to react with - */ - public react(message: BushMessageResolvable, emoji: EmojiIdentifierResolvable): Promise<void>; - - /** - * Pins a message to the channel's pinned messages, even if it's not cached. - * @param message The message to pin - */ - public pin(message: BushMessageResolvable): Promise<void>; - - /** - * Unpins a message from the channel's pinned messages, even if it's not cached. - * @param message The message to unpin - */ - public unpin(message: BushMessageResolvable): Promise<void>; -} - -export interface BushFetchMessageOptions extends FetchMessageOptions { - message: BushMessageResolvable; -} diff --git a/src/lib/extensions/discord.js/BushMessageReaction.ts b/src/lib/extensions/discord.js/BushMessageReaction.ts deleted file mode 100644 index 7fe110d..0000000 --- a/src/lib/extensions/discord.js/BushMessageReaction.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { BushClient, BushGuildEmoji, BushMessage, BushReactionEmoji } from '#lib'; -import { MessageReaction, type Partialize } from 'discord.js'; -import type { RawMessageReactionData } from 'discord.js/typings/rawDataTypes'; - -export type PartialBushMessageReaction = Partialize<BushMessageReaction, 'count'>; - -/** - * Represents a reaction to a message. - */ -export class BushMessageReaction extends MessageReaction { - public declare readonly client: BushClient; - - public constructor(client: BushClient, data: RawMessageReactionData, message: BushMessage) { - super(client, data, message); - } -} - -export interface BushMessageReaction extends MessageReaction { - get emoji(): BushGuildEmoji | BushReactionEmoji; -} diff --git a/src/lib/extensions/discord.js/BushModalSubmitInteraction.ts b/src/lib/extensions/discord.js/BushModalSubmitInteraction.ts deleted file mode 100644 index 9bdc9e5..0000000 --- a/src/lib/extensions/discord.js/BushModalSubmitInteraction.ts +++ /dev/null @@ -1,96 +0,0 @@ -import type { - BushClient, - BushGuild, - BushGuildCacheMessage, - BushGuildMember, - BushGuildTextBasedChannel, - BushTextBasedChannel, - BushUser -} from '#lib'; -import type { APIInteractionGuildMember, APIModalSubmitInteraction } from 'discord-api-types/v10'; -import { - InteractionDeferUpdateOptions, - InteractionResponse, - InteractionUpdateOptions, - MessagePayload, - ModalSubmitInteraction, - type CacheType, - type CacheTypeReducer -} from 'discord.js'; - -/** - * Represents a button interaction. - */ -export class BushModalSubmitInteraction<Cached extends CacheType = CacheType> extends ModalSubmitInteraction<Cached> { - public declare member: CacheTypeReducer<Cached, BushGuildMember, APIInteractionGuildMember>; - public declare user: BushUser; - - public constructor(client: BushClient, data: APIModalSubmitInteraction) { - super(client, data); - } -} - -export interface BushModalSubmitInteraction<Cached extends CacheType = CacheType> extends ModalSubmitInteraction<Cached> { - get channel(): CacheTypeReducer< - Cached, - BushGuildTextBasedChannel | null, - BushGuildTextBasedChannel | null, - BushGuildTextBasedChannel | null, - BushTextBasedChannel | null - >; - get guild(): CacheTypeReducer<Cached, BushGuild, null>; - inGuild(): this is BushModalSubmitInteraction<'raw' | 'cached'>; - inCachedGuild(): this is BushModalSubmitInteraction<'cached'>; - inRawGuild(): this is BushModalSubmitInteraction<'raw'>; - isFromMessage(): this is BushModalMessageModalSubmitInteraction<Cached>; -} - -export interface BushModalMessageModalSubmitInteraction<Cached extends CacheType = CacheType> - extends ModalSubmitInteraction<Cached> { - /** - * The message associated with this interaction - */ - message: BushGuildCacheMessage<Cached>; - - /** - * Updates the original message of the component on which the interaction was received on. - * @param options The options for the updated message - * @example - * // Remove the components from the message - * interaction.update({ - * content: "A component interaction was received", - * components: [] - * }) - * .then(console.log) - * .catch(console.error); - */ - update(options: InteractionUpdateOptions & { fetchReply: true }): Promise<BushGuildCacheMessage<Cached>>; - update(options: string | MessagePayload | InteractionUpdateOptions): Promise<InteractionResponse>; - - /** - * Defers an update to the message to which the component was attached. - * @param options Options for deferring the update to this interaction - * @example - * // Defer updating and reset the component's loading state - * interaction.deferUpdate() - * .then(console.log) - * .catch(console.error); - */ - deferUpdate(options: InteractionDeferUpdateOptions & { fetchReply: true }): Promise<BushGuildCacheMessage<Cached>>; - deferUpdate(options?: InteractionDeferUpdateOptions): Promise<InteractionResponse>; - - /** - * Indicates whether this interaction is received from a guild. - */ - inGuild(): this is BushModalMessageModalSubmitInteraction<'raw' | 'cached'>; - - /** - * Indicates whether or not this interaction is both cached and received from a guild. - */ - inCachedGuild(): this is BushModalMessageModalSubmitInteraction<'cached'>; - - /** - * Indicates whether or not this interaction is received from an uncached guild. - */ - inRawGuild(): this is BushModalMessageModalSubmitInteraction<'raw'>; -} diff --git a/src/lib/extensions/discord.js/BushNewsChannel.ts b/src/lib/extensions/discord.js/BushNewsChannel.ts deleted file mode 100644 index e262188..0000000 --- a/src/lib/extensions/discord.js/BushNewsChannel.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { BushGuild, BushGuildMember, BushMessageManager, BushThreadManager } from '#lib'; -import { NewsChannel, type AllowedThreadTypeForNewsChannel, type Collection, type Snowflake } from 'discord.js'; - -/** - * Represents a guild news channel on Discord. - */ -export class BushNewsChannel extends NewsChannel { - public declare threads: BushThreadManager<AllowedThreadTypeForNewsChannel>; - public declare guild: BushGuild; - public declare messages: BushMessageManager; -} - -export interface BushNewsChannel extends NewsChannel { - get members(): Collection<Snowflake, BushGuildMember>; -} diff --git a/src/lib/extensions/discord.js/BushPresence.ts b/src/lib/extensions/discord.js/BushPresence.ts deleted file mode 100644 index 40873ac..0000000 --- a/src/lib/extensions/discord.js/BushPresence.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { BushClient, BushGuild, BushGuildMember, BushUser } from '#lib'; -import { Presence } from 'discord.js'; -import type { RawPresenceData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a user's presence. - */ -export class BushPresence extends Presence { - public declare guild: BushGuild | null; - - public constructor(client: BushClient, data?: RawPresenceData) { - super(client, data); - } -} - -export interface BushPresence extends Presence { - get member(): BushGuildMember | null; - get user(): BushUser | null; -} diff --git a/src/lib/extensions/discord.js/BushReactionEmoji.ts b/src/lib/extensions/discord.js/BushReactionEmoji.ts deleted file mode 100644 index b2a7eb0..0000000 --- a/src/lib/extensions/discord.js/BushReactionEmoji.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { BushMessageReaction } from '#lib'; -import { ReactionEmoji } from 'discord.js'; -import type { RawReactionEmojiData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a limited emoji set used for both custom and unicode emojis. Custom emojis - * will use this class opposed to the Emoji class when the client doesn't know enough - * information about them. - */ -export class BushReactionEmoji extends ReactionEmoji { - public declare reaction: BushMessageReaction; - - public constructor(reaction: BushMessageReaction, emoji: RawReactionEmojiData) { - super(reaction, emoji); - } -} diff --git a/src/lib/extensions/discord.js/BushRole.ts b/src/lib/extensions/discord.js/BushRole.ts deleted file mode 100644 index a9575bd..0000000 --- a/src/lib/extensions/discord.js/BushRole.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { BushClient, BushGuild, BushGuildMember } from '#lib'; -import { Role, type Collection, type Snowflake } from 'discord.js'; -import type { RawRoleData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a role on Discord. - */ -export class BushRole extends Role { - public declare guild: BushGuild; - - public constructor(client: BushClient, data: RawRoleData, guild: BushGuild) { - super(client, data, guild); - } -} - -export interface BushRole extends Role { - get members(): Collection<Snowflake, BushGuildMember>; -} diff --git a/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts b/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts deleted file mode 100644 index 66a5ea9..0000000 --- a/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { BushClient, BushGuild, BushGuildMember, BushGuildTextBasedChannel, BushTextBasedChannel, BushUser } from '#lib'; -import type { APIInteractionGuildMember } from 'discord-api-types/v10'; -import { SelectMenuInteraction, type CacheType, type CacheTypeReducer } from 'discord.js'; -import type { RawMessageSelectMenuInteractionData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a select menu interaction. - */ -export class BushSelectMenuInteraction<Cached extends CacheType = CacheType> extends SelectMenuInteraction<Cached> { - public declare member: CacheTypeReducer<Cached, BushGuildMember, APIInteractionGuildMember>; - public declare user: BushUser; - - public constructor(client: BushClient, data: RawMessageSelectMenuInteractionData) { - super(client, data); - } -} - -export interface BushSelectMenuInteraction<Cached extends CacheType = CacheType> extends SelectMenuInteraction<Cached> { - get channel(): CacheTypeReducer< - Cached, - BushGuildTextBasedChannel | null, - BushGuildTextBasedChannel | null, - BushGuildTextBasedChannel | null, - BushTextBasedChannel | null - >; - get guild(): CacheTypeReducer<Cached, BushGuild, null>; - inGuild(): this is BushSelectMenuInteraction<'raw' | 'cached'>; - inCachedGuild(): this is BushSelectMenuInteraction<'cached'>; - inRawGuild(): this is BushSelectMenuInteraction<'raw'>; -} diff --git a/src/lib/extensions/discord.js/BushStageChannel.ts b/src/lib/extensions/discord.js/BushStageChannel.ts deleted file mode 100644 index 983bd56..0000000 --- a/src/lib/extensions/discord.js/BushStageChannel.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { BushCategoryChannel, BushGuild, BushGuildMember, BushStageInstance } from '#lib'; -import { StageChannel, type Collection, type Snowflake } from 'discord.js'; -import type { RawGuildChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a guild stage channel on Discord. - */ -export class BushStageChannel extends StageChannel { - public declare guild: BushGuild; - - public constructor(guild: BushGuild, data?: RawGuildChannelData) { - super(guild, data); - } -} - -export interface BushStageChannel extends StageChannel { - get members(): Collection<Snowflake, BushGuildMember>; - get parent(): BushCategoryChannel | null; - get stageInstance(): BushStageInstance | null; -} diff --git a/src/lib/extensions/discord.js/BushStageInstance.ts b/src/lib/extensions/discord.js/BushStageInstance.ts deleted file mode 100644 index 96453a7..0000000 --- a/src/lib/extensions/discord.js/BushStageInstance.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { BushClient, BushGuild, BushStageChannel } from '#lib'; -import { StageInstance } from 'discord.js'; -import type { RawStageInstanceData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a stage instance. - */ -export class BushStageInstance extends StageInstance { - public constructor(client: BushClient, data: RawStageInstanceData, channel: BushStageChannel) { - super(client, data, channel); - } -} - -export interface BushStageInstance extends StageInstance { - get channel(): BushStageChannel | null; - get guild(): BushGuild | null; -} diff --git a/src/lib/extensions/discord.js/BushTextChannel.ts b/src/lib/extensions/discord.js/BushTextChannel.ts deleted file mode 100644 index 575de20..0000000 --- a/src/lib/extensions/discord.js/BushTextChannel.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { - BushCategoryChannel, - BushDMChannel, - BushGuild, - BushGuildBasedChannel, - BushMessageManager, - BushNewsChannel, - BushStageChannel, - BushTextBasedChannel, - BushThreadChannel, - BushThreadManager, - BushVoiceBasedChannel, - BushVoiceChannel -} from '#lib'; -import { PartialGroupDMChannel, TextChannel, type AllowedThreadTypeForTextChannel } from 'discord.js'; -import type { RawGuildChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a guild text channel on Discord. - */ -export class BushTextChannel extends TextChannel { - public declare guild: BushGuild; - public declare messages: BushMessageManager; - public declare threads: BushThreadManager<AllowedThreadTypeForTextChannel>; - - public constructor(guild: BushGuild, data?: RawGuildChannelData) { - super(guild, data); - } -} - -export interface BushTextChannel extends TextChannel { - isText(): this is BushTextChannel; - isDM(): this is BushDMChannel; - isDMBased(): this is PartialGroupDMChannel | BushDMChannel; - isVoice(): this is BushVoiceChannel; - isCategory(): this is BushCategoryChannel; - isNews(): this is BushNewsChannel; - 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/BushThreadChannel.ts b/src/lib/extensions/discord.js/BushThreadChannel.ts deleted file mode 100644 index 8b941f9..0000000 --- a/src/lib/extensions/discord.js/BushThreadChannel.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { - BushCategoryChannel, - BushClient, - BushDMChannel, - BushGuild, - BushGuildBasedChannel, - BushGuildMember, - BushMessageManager, - BushNewsChannel, - BushStageChannel, - BushTextBasedChannel, - BushTextChannel, - BushThreadMemberManager, - BushVoiceBasedChannel, - BushVoiceChannel -} from '#lib'; -import { PartialGroupDMChannel, ThreadChannel, type Collection, type Snowflake } from 'discord.js'; -import type { RawThreadChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a thread channel on Discord. - */ -export class BushThreadChannel extends ThreadChannel { - public declare guild: BushGuild; - public declare messages: BushMessageManager; - public declare members: BushThreadMemberManager; - public declare readonly client: BushClient; - - public constructor(guild: BushGuild, data?: RawThreadChannelData, client?: BushClient, fromInteraction?: boolean) { - super(guild, data, client, fromInteraction); - } -} - -export interface BushThreadChannel extends ThreadChannel { - get guildMembers(): Collection<Snowflake, BushGuildMember>; - get parent(): BushTextChannel | BushNewsChannel | null; - isText(): this is BushTextChannel; - isDM(): this is BushDMChannel; - isDMBased(): this is PartialGroupDMChannel | BushDMChannel; - isVoice(): this is BushVoiceChannel; - isCategory(): this is BushCategoryChannel; - isNews(): this is BushNewsChannel; - 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/BushThreadManager.ts b/src/lib/extensions/discord.js/BushThreadManager.ts deleted file mode 100644 index 0748a4d..0000000 --- a/src/lib/extensions/discord.js/BushThreadManager.ts +++ /dev/null @@ -1,84 +0,0 @@ -import type { BushFetchedThreads, BushThreadChannel } from '#lib'; -import { - CachedManager, - NewsChannel, - TextChannel, - ThreadManager, - type BaseFetchOptions, - type FetchArchivedThreadOptions, - type FetchThreadsOptions, - type Snowflake, - type ThreadChannelResolvable, - type ThreadCreateOptions -} from 'discord.js'; -import type { RawThreadChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * Manages API methods for {@link BushThreadChannel} objects and stores their cache. - */ -export declare class BushThreadManager<AllowedThreadType> - extends CachedManager<Snowflake, BushThreadChannel, ThreadChannelResolvable> - implements ThreadManager<AllowedThreadType> -{ - public constructor(channel: TextChannel | NewsChannel, iterable?: Iterable<RawThreadChannelData>); - - /** - * The channel this Manager belongs to - */ - public channel: TextChannel | NewsChannel; - - /** - * Creates a new thread in the channel. - * @param options Options to create a new thread - * @example - * // Create a new public thread - * channel.threads - * .create({ - * name: 'food-talk', - * autoArchiveDuration: 60, - * reason: 'Needed a separate thread for food', - * }) - * .then(threadChannel => console.log(threadChannel)) - * .catch(console.error); - * @example - * // Create a new private thread - * channel.threads - * .create({ - * name: 'mod-talk', - * autoArchiveDuration: 60, - * type: 'GuildPrivateThread', - * reason: 'Needed a separate thread for moderation', - * }) - * .then(threadChannel => console.log(threadChannel)) - * .catch(console.error); - */ - public create(options: ThreadCreateOptions<AllowedThreadType>): Promise<BushThreadChannel>; - - /** - * Obtains a thread from Discord, or the channel cache if it's already available. - * @param options The options to fetch threads. If it is a - * ThreadChannelResolvable then the specified thread will be fetched. Fetches all active threads if `undefined` - * @param cacheOptions Additional options for this fetch. <warn>The `force` field gets ignored - * if `options` is not a {@link ThreadChannelResolvable}</warn> - * @example - * // Fetch a thread by its id - * channel.threads.fetch('831955138126104859') - * .then(channel => console.log(channel.name)) - * .catch(console.error); - */ - public fetch(options: ThreadChannelResolvable, cacheOptions?: BaseFetchOptions): Promise<BushThreadChannel | null>; - public fetch(options?: FetchThreadsOptions, cacheOptions?: { cache?: boolean }): Promise<BushFetchedThreads>; - - /** - * Obtains a set of archived threads from Discord, requires `READ_MESSAGE_HISTORY` in the parent channel. - * @param options The options to fetch archived threads - * @param cache Whether to cache the new thread objects if they aren't already - */ - public fetchArchived(options?: FetchArchivedThreadOptions, cache?: boolean): Promise<BushFetchedThreads>; - - /** - * Obtains the accessible active threads from Discord, requires `READ_MESSAGE_HISTORY` in the parent channel. - * @param cache Whether to cache the new thread objects if they aren't already - */ - public fetchActive(cache?: boolean): Promise<BushFetchedThreads>; -} diff --git a/src/lib/extensions/discord.js/BushThreadMember.ts b/src/lib/extensions/discord.js/BushThreadMember.ts deleted file mode 100644 index 90c9c9b..0000000 --- a/src/lib/extensions/discord.js/BushThreadMember.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { BushGuildMember, BushThreadChannel, BushUser } from '#lib'; -import { ThreadMember } from 'discord.js'; -import type { RawThreadMemberData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a Member for a Thread. - */ -export class BushThreadMember extends ThreadMember { - public declare thread: BushThreadChannel; - - public constructor(thread: BushThreadChannel, data?: RawThreadMemberData) { - super(thread, data); - } -} - -export interface BushThreadMember extends ThreadMember { - get guildMember(): BushGuildMember | null; - get user(): BushUser | null; -} diff --git a/src/lib/extensions/discord.js/BushThreadMemberManager.ts b/src/lib/extensions/discord.js/BushThreadMemberManager.ts deleted file mode 100644 index d183b30..0000000 --- a/src/lib/extensions/discord.js/BushThreadMemberManager.ts +++ /dev/null @@ -1,62 +0,0 @@ -import type { BushClient, BushThreadChannel, BushThreadMember, BushThreadMemberResolvable, BushUserResolvable } from '#lib'; -import { - CachedManager, - ThreadMemberManager, - type BaseFetchOptions, - type Collection, - type Snowflake, - type UserResolvable -} from 'discord.js'; -import type { RawThreadMemberData } from 'discord.js/typings/rawDataTypes'; - -/** - * Manages API methods for GuildMembers and stores their cache. - */ -export declare class BushThreadMemberManager - extends CachedManager<Snowflake, BushThreadMember, BushThreadMemberResolvable> - implements ThreadMemberManager -{ - public constructor(thread: BushThreadChannel, iterable?: Iterable<RawThreadMemberData>); - public declare readonly client: BushClient; - - /** - * The thread this manager belongs to - */ - public thread: BushThreadChannel; - - /** - * Adds a member to the thread. - * @param member The member to add - * @param reason The reason for adding this member - */ - public add(member: UserResolvable | '@me', reason?: string): Promise<Snowflake>; - - /** - * Fetches member(s) for the thread from Discord, requires access to the `GatewayIntentBits.GuildMembers` gateway intent. - * @param options Additional options for this fetch, when a `boolean` is provided - * all members are fetched with `options.cache` set to the boolean value - */ - public fetch(options?: BushThreadMemberFetchOptions): Promise<BushThreadMember>; - public fetch(cache?: boolean): Promise<Collection<Snowflake, BushThreadMember>>; - - /** - * Remove a user from the thread. - * @param id The id of the member to remove - * @param reason The reason for removing this member from the thread - */ - public remove(id: Snowflake | '@me', reason?: string): Promise<Snowflake>; -} - -export interface BushThreadMemberManager extends CachedManager<Snowflake, BushThreadMember, BushThreadMemberResolvable> { - /** - * The client user as a ThreadMember of this ThreadChannel - */ - get me(): BushThreadMember | null; -} - -export interface BushThreadMemberFetchOptions extends BaseFetchOptions { - /** - * The specific user to fetch from the thread - */ - member?: BushUserResolvable; -} diff --git a/src/lib/extensions/discord.js/BushUser.ts b/src/lib/extensions/discord.js/BushUser.ts deleted file mode 100644 index 27ef2b2..0000000 --- a/src/lib/extensions/discord.js/BushUser.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { BushClient, BushDMChannel } from '#lib'; -import { User, type Partialize } from 'discord.js'; -import type { RawUserData } from 'discord.js/typings/rawDataTypes'; - -export type PartialBushUser = Partialize<BushUser, 'username' | 'tag' | 'discriminator' | 'isOwner' | 'isSuperUser'>; - -/** - * Represents a user on Discord. - */ -export class BushUser extends User { - public declare readonly client: BushClient; - - public constructor(client: BushClient, data: RawUserData) { - super(client, data); - } - - /** - * Indicates whether the user is an owner of the bot. - */ - public isOwner(): boolean { - return client.isOwner(this); - } - - /** - * Indicates whether the user is a superuser of the bot. - */ - public isSuperUser(): boolean { - return client.isSuperUser(this); - } -} - -export interface BushUser extends User { - get dmChannel(): BushDMChannel | null; -} diff --git a/src/lib/extensions/discord.js/BushUserManager.ts b/src/lib/extensions/discord.js/BushUserManager.ts deleted file mode 100644 index c26dbde..0000000 --- a/src/lib/extensions/discord.js/BushUserManager.ts +++ /dev/null @@ -1,60 +0,0 @@ -import type { BushClient, BushDMChannel, BushUser, BushUserResolvable } from '#lib'; -import { - CachedManager, - Message, - MessageOptions, - MessagePayload, - UserFlagsBitField, - UserManager, - type BaseFetchOptions, - type Snowflake -} from 'discord.js'; -import type { RawUserData } from 'discord.js/typings/rawDataTypes'; - -/** - * Manages API methods for users and stores their cache. - */ -export declare class BushUserManager extends CachedManager<Snowflake, BushUser, BushUserResolvable> implements UserManager { - private constructor(client: BushClient, iterable?: Iterable<RawUserData>); - - /** - * The DM between the client's user and a user - * @param userId The user id - * @private - */ - public dmChannel(userId: Snowflake): BushDMChannel | null; - - /** - * Creates a {@link BushDMChannel} between the client and a user. - * @param user The UserResolvable to identify - * @param options Additional options for this fetch - */ - public createDM(user: BushUserResolvable, options?: BaseFetchOptions): Promise<BushDMChannel>; - - /** - * Deletes a {@link BushDMChannel} (if one exists) between the client and a user. Resolves with the channel if successful. - * @param user The UserResolvable to identify - */ - public deleteDM(user: BushUserResolvable): Promise<BushDMChannel>; - - /** - * Obtains a user from Discord, or the user cache if it's already available. - * @param user The user to fetch - * @param options Additional options for this fetch - */ - public fetch(user: BushUserResolvable, options?: BaseFetchOptions): Promise<BushUser>; - - /** - * Fetches a user's flags. - * @param user The UserResolvable to identify - * @param options Additional options for this fetch - */ - public fetchFlags(user: BushUserResolvable, options?: BaseFetchOptions): Promise<UserFlagsBitField>; - - /** - * Sends a message to a user. - * @param user The UserResolvable to identify - * @param options The options to provide - */ - public send(user: BushUserResolvable, options: string | MessagePayload | MessageOptions): Promise<Message>; -} diff --git a/src/lib/extensions/discord.js/BushVoiceChannel.ts b/src/lib/extensions/discord.js/BushVoiceChannel.ts deleted file mode 100644 index 6966727..0000000 --- a/src/lib/extensions/discord.js/BushVoiceChannel.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { - BushCategoryChannel, - BushClient, - BushDMChannel, - BushGuild, - BushGuildBasedChannel, - BushGuildMember, - BushNewsChannel, - BushStageChannel, - BushTextBasedChannel, - BushTextChannel, - BushThreadChannel, - BushVoiceBasedChannel -} from '#lib'; -import { VoiceChannel, type Collection, type Snowflake } from 'discord.js'; -import type { RawGuildChannelData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents a guild voice channel on Discord. - */ -export class BushVoiceChannel extends VoiceChannel { - public declare readonly client: BushClient; - - public constructor(guild: BushGuild, data?: RawGuildChannelData) { - super(guild, data); - } -} - -export interface BushVoiceChannel extends VoiceChannel { - get members(): Collection<Snowflake, BushGuildMember>; - isText(): this is BushTextChannel; - isDM(): this is BushDMChannel; - isVoice(): this is BushVoiceChannel; - isCategory(): this is BushCategoryChannel; - isNews(): this is BushNewsChannel; - 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/BushVoiceState.ts b/src/lib/extensions/discord.js/BushVoiceState.ts deleted file mode 100644 index bbcdfa8..0000000 --- a/src/lib/extensions/discord.js/BushVoiceState.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { BushClient, BushGuild, BushGuildMember, BushVoiceBasedChannel } from '#lib'; -import { VoiceState } from 'discord.js'; -import type { RawVoiceStateData } from 'discord.js/typings/rawDataTypes'; - -/** - * Represents the voice state for a Guild Member. - */ -export class BushVoiceState extends VoiceState { - public declare readonly client: BushClient; - public declare guild: BushGuild; - - public constructor(guild: BushGuild, data: RawVoiceStateData) { - super(guild, data); - } -} - -export interface BushVoiceState extends VoiceState { - get channel(): BushVoiceBasedChannel | null; - get getmember(): BushGuildMember | null; -} diff --git a/src/lib/extensions/discord.js/BushGuild.ts b/src/lib/extensions/discord.js/ExtendedGuild.ts index a93e35f..b8b7b22 100644 --- a/src/lib/extensions/discord.js/BushGuild.ts +++ b/src/lib/extensions/discord.js/ExtendedGuild.ts @@ -1,65 +1,146 @@ import { AllowedMentions, banResponse, - BushGuildChannelManager, - BushGuildMemberManager, - BushMessage, - BushVoiceChannel, dmResponse, permissionsResponse, punishmentEntryRemove, type BanResponse, - type BushClient, - type BushGuildMember, - type BushGuildMemberResolvable, - type BushNewsChannel, - type BushTextChannel, - type BushThreadChannel, - type BushUser, - type BushUserResolvable, type GuildFeatures, type GuildLogType, type GuildModel } from '#lib'; -import { APIMessage } from 'discord-api-types/v10'; import { + AttachmentBuilder, + AttachmentPayload, Collection, Guild, + JSONEncodable, + Message, MessageType, PermissionFlagsBits, SnowflakeUtil, ThreadChannel, - Webhook, - WebhookMessageOptions, + type APIMessage, + type GuildMember, + type GuildMemberResolvable, + type GuildTextBasedChannel, type MessageOptions, type MessagePayload, - type Snowflake + type NewsChannel, + type Snowflake, + type TextChannel, + type User, + type UserResolvable, + type VoiceChannel, + type Webhook, + type WebhookMessageOptions } from 'discord.js'; -import type { RawGuildData } from 'discord.js/typings/rawDataTypes'; import _ from 'lodash'; import { Moderation } from '../../common/util/Moderation.js'; import { Guild as GuildDB } from '../../models/instance/Guild.js'; import { ModLogType } from '../../models/instance/ModLog.js'; +declare module 'discord.js' { + export interface Guild { + /** + * Checks if the guild has a certain custom feature. + * @param feature The feature to check for + */ + hasFeature(feature: GuildFeatures): Promise<boolean>; + /** + * Adds a custom feature to the guild. + * @param feature The feature to add + * @param moderator The moderator responsible for adding a feature + */ + addFeature(feature: GuildFeatures, moderator?: GuildMember): Promise<GuildDB['enabledFeatures']>; + /** + * Removes a custom feature from the guild. + * @param feature The feature to remove + * @param moderator The moderator responsible for removing a feature + */ + removeFeature(feature: GuildFeatures, moderator?: GuildMember): Promise<GuildDB['enabledFeatures']>; + /** + * Makes a custom feature the opposite of what it was before + * @param feature The feature to toggle + * @param moderator The moderator responsible for toggling a feature + */ + toggleFeature(feature: GuildFeatures, moderator?: GuildMember): Promise<GuildDB['enabledFeatures']>; + /** + * Fetches a custom setting for the guild + * @param setting The setting to get + */ + getSetting<K extends keyof GuildModel>(setting: K): Promise<GuildModel[K]>; + /** + * Sets a custom setting for the guild + * @param setting The setting to change + * @param value The value to change the setting to + * @param moderator The moderator to responsible for changing the setting + */ + setSetting<K extends Exclude<keyof GuildModel, 'id'>>( + setting: K, + value: GuildModel[K], + moderator?: GuildMember + ): Promise<GuildModel>; + /** + * Get a the log channel configured for a certain log type. + * @param logType The type of log channel to get. + * @returns Either the log channel or undefined if not configured. + */ + getLogChannel(logType: GuildLogType): Promise<TextChannel | undefined>; + /** + * Sends a message to the guild's specified logging channel + * @param logType The corresponding channel that the message will be sent to + * @param message The parameters for {@link BushTextChannel.send} + */ + sendLogChannel(logType: GuildLogType, message: string | MessagePayload | MessageOptions): Promise<Message | null | undefined>; + /** + * Sends a formatted error message in a guild's error log channel + * @param title The title of the error embed + * @param message The description of the error embed + */ + error(title: string, message: string): Promise<void>; + /** + * Bans a user, dms them, creates a mod log entry, and creates a punishment entry. + * @param options Options for banning the user. + * @returns A string status message of the ban. + */ + bushBan(options: GuildBushBanOptions): Promise<BanResponse>; + /** + * {@link bushBan} with less resolving and checks + * @param options Options for banning the user. + * @returns A string status message of the ban. + * **Preconditions:** + * - {@link me} has the `BanMembers` permission + * **Warning:** + * - Doesn't emit bushBan Event + */ + massBanOne(options: GuildMassBanOneOptions): Promise<BanResponse>; + /** + * Unbans a user, dms them, creates a mod log entry, and destroys the punishment entry. + * @param options Options for unbanning the user. + * @returns A status message of the unban. + */ + bushUnban(options: GuildBushUnbanOptions): Promise<UnbanResponse>; + /** + * Denies send permissions in specified channels + * @param options The options for locking down the guild + */ + lockdown(options: LockdownOptions): Promise<LockdownResponse>; + quote(rawQuote: APIMessage, channel: GuildTextBasedChannel): Promise<Message | null>; + } +} + /** * Represents a guild (or a server) on Discord. * <info>It's recommended to see if a guild is available before performing operations or reading data from it. You can - * check this with {@link BushGuild.available}.</info> + * check this with {@link ExtendedGuild.available}.</info> */ -export class BushGuild extends Guild { - public declare readonly client: BushClient; - public declare members: BushGuildMemberManager; - public declare channels: BushGuildChannelManager; - - public constructor(client: BushClient, data: RawGuildData) { - super(client, data); - } - +export class ExtendedGuild extends Guild { /** * Checks if the guild has a certain custom feature. * @param feature The feature to check for */ - public async hasFeature(feature: GuildFeatures): Promise<boolean> { + public override async hasFeature(feature: GuildFeatures): Promise<boolean> { const features = await this.getSetting('enabledFeatures'); return features.includes(feature); } @@ -69,7 +150,7 @@ export class BushGuild extends Guild { * @param feature The feature to add * @param moderator The moderator responsible for adding a feature */ - public async addFeature(feature: GuildFeatures, moderator?: BushGuildMember): Promise<GuildModel['enabledFeatures']> { + public override async addFeature(feature: GuildFeatures, moderator?: GuildMember): Promise<GuildModel['enabledFeatures']> { const features = await this.getSetting('enabledFeatures'); const newFeatures = util.addOrRemoveFromArray('add', features, feature); return (await this.setSetting('enabledFeatures', newFeatures, moderator)).enabledFeatures; @@ -80,7 +161,7 @@ export class BushGuild extends Guild { * @param feature The feature to remove * @param moderator The moderator responsible for removing a feature */ - public async removeFeature(feature: GuildFeatures, moderator?: BushGuildMember): Promise<GuildModel['enabledFeatures']> { + public override async removeFeature(feature: GuildFeatures, moderator?: GuildMember): Promise<GuildModel['enabledFeatures']> { const features = await this.getSetting('enabledFeatures'); const newFeatures = util.addOrRemoveFromArray('remove', features, feature); return (await this.setSetting('enabledFeatures', newFeatures, moderator)).enabledFeatures; @@ -91,7 +172,7 @@ export class BushGuild extends Guild { * @param feature The feature to toggle * @param moderator The moderator responsible for toggling a feature */ - public async toggleFeature(feature: GuildFeatures, moderator?: BushGuildMember): Promise<GuildModel['enabledFeatures']> { + public override async toggleFeature(feature: GuildFeatures, moderator?: GuildMember): Promise<GuildModel['enabledFeatures']> { return (await this.hasFeature(feature)) ? await this.removeFeature(feature, moderator) : await this.addFeature(feature, moderator); @@ -101,7 +182,7 @@ export class BushGuild extends Guild { * Fetches a custom setting for the guild * @param setting The setting to get */ - public async getSetting<K extends keyof GuildModel>(setting: K): Promise<GuildModel[K]> { + public override async getSetting<K extends keyof GuildModel>(setting: K): Promise<GuildModel[K]> { return ( client.cache.guilds.get(this.id)?.[setting] ?? ((await GuildDB.findByPk(this.id)) ?? GuildDB.build({ id: this.id }))[setting] @@ -114,10 +195,10 @@ export class BushGuild extends Guild { * @param value The value to change the setting to * @param moderator The moderator to responsible for changing the setting */ - public async setSetting<K extends Exclude<keyof GuildModel, 'id'>>( + public override async setSetting<K extends Exclude<keyof GuildModel, 'id'>>( setting: K, value: GuildDB[K], - moderator?: BushGuildMember + moderator?: GuildMember ): Promise<GuildDB> { const row = (await GuildDB.findByPk(this.id)) ?? GuildDB.build({ id: this.id }); const oldValue = row[setting] as GuildDB[K]; @@ -132,12 +213,12 @@ export class BushGuild extends Guild { * @param logType The type of log channel to get. * @returns Either the log channel or undefined if not configured. */ - public async getLogChannel(logType: GuildLogType): Promise<BushTextChannel | undefined> { + public override async getLogChannel(logType: GuildLogType): Promise<TextChannel | undefined> { const channelId = (await this.getSetting('logChannels'))[logType]; if (!channelId) return undefined; return ( - (this.channels.cache.get(channelId) as BushTextChannel | undefined) ?? - ((await this.channels.fetch(channelId)) as BushTextChannel | null) ?? + (this.channels.cache.get(channelId) as TextChannel | undefined) ?? + ((await this.channels.fetch(channelId)) as TextChannel | null) ?? undefined ); } @@ -147,7 +228,10 @@ export class BushGuild extends Guild { * @param logType The corresponding channel that the message will be sent to * @param message The parameters for {@link BushTextChannel.send} */ - public async sendLogChannel(logType: GuildLogType, message: string | MessagePayload | MessageOptions) { + public override async sendLogChannel( + logType: GuildLogType, + message: string | MessagePayload | MessageOptions + ): Promise<Message | null | undefined> { const logChannel = await this.getLogChannel(logType); if (!logChannel || !logChannel.isTextBased()) return; if ( @@ -165,7 +249,7 @@ export class BushGuild extends Guild { * @param title The title of the error embed * @param message The description of the error embed */ - public async error(title: string, message: string) { + public override async error(title: string, message: string): Promise<void> { void client.console.info(_.camelCase(title), message.replace(/\*\*(.*?)\*\*/g, '<<$1>>')); void this.sendLogChannel('error', { embeds: [{ title: title, description: message, color: util.colors.error }] }); } @@ -175,7 +259,7 @@ export class BushGuild extends Guild { * @param options Options for banning the user. * @returns A string status message of the ban. */ - public async bushBan(options: GuildBushBanOptions): Promise<BanResponse> { + public override async bushBan(options: GuildBushBanOptions): Promise<BanResponse> { // checks if (!this.members.me!.permissions.has(PermissionFlagsBits.BanMembers)) return banResponse.MISSING_PERMISSIONS; @@ -259,7 +343,7 @@ export class BushGuild extends Guild { * **Warning:** * - Doesn't emit bushBan Event */ - public async massBanOne(options: GuildMassBanOneOptions): Promise<BanResponse> { + public override async massBanOne(options: GuildMassBanOneOptions): Promise<BanResponse> { if (this.bans.cache.has(options.user)) return banResponse.ALREADY_BANNED; const ret = await (async () => { @@ -318,7 +402,7 @@ export class BushGuild extends Guild { * @param options Options for unbanning the user. * @returns A status message of the unban. */ - public async bushUnban(options: GuildBushUnbanOptions): Promise<UnbanResponse> { + public override async bushUnban(options: GuildBushUnbanOptions): Promise<UnbanResponse> { // checks if (!this.members.me!.permissions.has(PermissionFlagsBits.BanMembers)) return unbanResponse.MISSING_PERMISSIONS; @@ -391,7 +475,7 @@ export class BushGuild extends Guild { * Denies send permissions in specified channels * @param options The options for locking down the guild */ - public async lockdown(options: LockdownOptions): Promise<LockdownResponse> { + public override async lockdown(options: LockdownOptions): Promise<LockdownResponse> { if (!options.all && !options.channel) return 'all not chosen and no channel specified'; const channelIds = options.all ? await this.getSetting('lockdownChannels') : [options.channel!.id]; @@ -466,11 +550,11 @@ export class BushGuild extends Guild { return ret; } - public async quote(rawQuote: APIMessage, channel: BushTextChannel | BushNewsChannel | BushThreadChannel) { + public override async quote(rawQuote: APIMessage, channel: GuildTextBasedChannel): Promise<Message | null> { if (!channel.isTextBased() || channel.isDMBased() || channel.guildId !== this.id || !this.members.me) return null; if (!channel.permissionsFor(this.members.me).has('ManageWebhooks')) return null; - const quote = new BushMessage(client, rawQuote); + const quote = new Message(client, rawQuote); const target = channel instanceof ThreadChannel ? channel.parent : channel; if (!target) return null; @@ -482,7 +566,8 @@ export class BushGuild extends Guild { let webhook = webhooks.find((w) => !!w.token) ?? null; if (!webhook) webhook = await target - .createWebhook(`${client.user!.username} Quotes #${target.name}`, { + .createWebhook({ + name: `${client.user!.username} Quotes #${target.name}`, avatar: client.user!.displayAvatarURL({ size: 2048 }), reason: 'Creating a webhook for quoting' }) @@ -503,7 +588,10 @@ export class BushGuild extends Guild { sendOptions.content = quote.content || undefined; sendOptions.threadId = channel instanceof ThreadChannel ? channel.id : undefined; sendOptions.embeds = quote.embeds.length ? quote.embeds : undefined; - sendOptions.attachments = quote.attachments.size ? [...quote.attachments.values()] : undefined; + //@ts-expect-error: jank + sendOptions.attachments = quote.attachments.size + ? [...quote.attachments.values()].map((a) => AttachmentBuilder.from(a as JSONEncodable<AttachmentPayload>)) + : undefined; if (quote.stickers.size && !(quote.content || quote.embeds.length || quote.attachments.size)) sendOptions.content = '[[This message has a sticker but not content]]'; @@ -651,7 +739,7 @@ export interface GuildBushUnbanOptions { /** * The user to unban */ - user: BushUserResolvable | BushUser; + user: UserResolvable | User; /** * The reason for unbanning the user @@ -661,7 +749,7 @@ export interface GuildBushUnbanOptions { /** * The moderator who unbanned the user */ - moderator?: BushUserResolvable; + moderator?: UserResolvable; /** * The evidence for the unban @@ -698,7 +786,7 @@ export interface GuildBushBanOptions { /** * The user to ban */ - user: BushUserResolvable; + user: UserResolvable; /** * The reason to ban the user @@ -708,7 +796,7 @@ export interface GuildBushBanOptions { /** * The moderator who banned the user */ - moderator?: BushUserResolvable; + moderator?: UserResolvable; /** * The duration of the ban @@ -747,7 +835,7 @@ export interface LockdownOptions { /** * The moderator responsible for the lockdown */ - moderator: BushGuildMemberResolvable; + moderator: GuildMemberResolvable; /** * Whether to lock down all (specified) channels @@ -762,7 +850,7 @@ export interface LockdownOptions { /** * A specific channel to lockdown */ - channel?: BushThreadChannel | BushNewsChannel | BushTextChannel | BushVoiceChannel; + channel?: ThreadChannel | NewsChannel | TextChannel | VoiceChannel; /** * Whether or not to unlock the channel(s) instead of locking them diff --git a/src/lib/extensions/discord.js/BushGuildMember.ts b/src/lib/extensions/discord.js/ExtendedGuildMember.ts index 20a1f60..28acc1a 100644 --- a/src/lib/extensions/discord.js/BushGuildMember.ts +++ b/src/lib/extensions/discord.js/ExtendedGuildMember.ts @@ -1,44 +1,127 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ +import { BushClientEvents, Moderation, ModLogType, PunishmentTypeDM, Time } from '#lib'; import { - BushClientEvents, - Moderation, - ModLogType, - PunishmentTypeDM, - Time, - type BushClient, - type BushGuild, - type BushGuildTextBasedChannel, - type BushGuildTextChannelResolvable, - type BushRole, - type BushThreadChannelResolvable, - type BushUser -} from '#lib'; -import { GuildMember, PermissionFlagsBits, type Partialize, type Role } from 'discord.js'; -import type { RawGuildMemberData } from 'discord.js/typings/rawDataTypes'; + ChannelType, + GuildChannelResolvable, + GuildMember, + GuildTextBasedChannel, + PermissionFlagsBits, + type Role +} from 'discord.js'; /* eslint-enable @typescript-eslint/no-unused-vars */ +declare module 'discord.js' { + export interface GuildMember { + /** + * Send a punishment dm to the user. + * @param punishment The punishment that the user has received. + * @param reason The reason for the user's punishment. + * @param duration The duration of the punishment. + * @param modlog The modlog case id so the user can make an appeal. + * @param sendFooter Whether or not to send the guild's punishment footer with the dm. + * @returns Whether or not the dm was sent successfully. + */ + bushPunishDM( + punishment: PunishmentTypeDM, + reason?: string | null, + duration?: number, + modlog?: string, + sendFooter?: boolean + ): Promise<boolean>; + /** + * Warn the user, create a modlog entry, and send a dm to the user. + * @param options Options for warning the user. + * @returns An object with the result of the warning, and the case number of the warn. + * @emits {@link BushClientEvents.bushWarn} + */ + bushWarn(options: BushPunishmentOptions): Promise<{ result: WarnResponse; caseNum: number | null }>; + /** + * Add a role to the user, if it is a punishment create a modlog entry, and create a punishment entry if it is temporary or a punishment. + * @param options Options for adding a role to the user. + * @returns A status message for adding the add. + * @emits {@link BushClientEvents.bushPunishRole} + */ + bushAddRole(options: AddRoleOptions): Promise<AddRoleResponse>; + /** + * Remove a role from the user, if it is a punishment create a modlog entry, and destroy a punishment entry if it was temporary or a punishment. + * @param options Options for removing a role from the user. + * @returns A status message for removing the role. + * @emits {@link BushClientEvents.bushPunishRoleRemove} + */ + bushRemoveRole(options: RemoveRoleOptions): Promise<RemoveRoleResponse>; + /** + * Mute the user, create a modlog entry, creates a punishment entry, and dms the user. + * @param options Options for muting the user. + * @returns A status message for muting the user. + * @emits {@link BushClientEvents.bushMute} + */ + bushMute(options: BushTimedPunishmentOptions): Promise<MuteResponse>; + /** + * Unmute the user, create a modlog entry, remove the punishment entry, and dm the user. + * @param options Options for unmuting the user. + * @returns A status message for unmuting the user. + * @emits {@link BushClientEvents.bushUnmute} + */ + bushUnmute(options: BushPunishmentOptions): Promise<UnmuteResponse>; + /** + * Kick the user, create a modlog entry, and dm the user. + * @param options Options for kicking the user. + * @returns A status message for kicking the user. + * @emits {@link BushClientEvents.bushKick} + */ + bushKick(options: BushPunishmentOptions): Promise<KickResponse>; + /** + * Ban the user, create a modlog entry, create a punishment entry, and dm the user. + * @param options Options for banning the user. + * @returns A status message for banning the user. + * @emits {@link BushClientEvents.bushBan} + */ + bushBan(options: BushBanOptions): Promise<Exclude<BanResponse, typeof banResponse['ALREADY_BANNED']>>; + /** + * Prevents a user from speaking in a channel. + * @param options Options for blocking the user. + */ + bushBlock(options: BlockOptions): Promise<BlockResponse>; + /** + * Allows a user to speak in a channel. + * @param options Options for unblocking the user. + */ + bushUnblock(options: UnblockOptions): Promise<UnblockResponse>; + /** + * Mutes a user using discord's timeout feature. + * @param options Options for timing out the user. + */ + bushTimeout(options: BushTimeoutOptions): Promise<TimeoutResponse>; + /** + * Removes a timeout from a user. + * @param options Options for removing the timeout. + */ + bushRemoveTimeout(options: BushPunishmentOptions): Promise<RemoveTimeoutResponse>; + /** + * Whether or not the user is an owner of the bot. + */ + isOwner(): boolean; + /** + * Whether or not the user is a super user of the bot. + */ + isSuperUser(): boolean; + } +} + /** * Represents a member of a guild on Discord. */ -export class BushGuildMember extends GuildMember { - public declare readonly client: BushClient; - public declare guild: BushGuild; - public declare user: BushUser; - - public constructor(client: BushClient, data: RawGuildMemberData, guild: BushGuild) { - super(client, data, guild); - } - +export class ExtendedGuildMember extends GuildMember { /** * Send a punishment dm to the user. - * @param modlog The modlog case id so the user can make an appeal. * @param punishment The punishment that the user has received. * @param reason The reason for the user's punishment. * @param duration The duration of the punishment. + * @param modlog The modlog case id so the user can make an appeal. * @param sendFooter Whether or not to send the guild's punishment footer with the dm. * @returns Whether or not the dm was sent successfully. */ - public async bushPunishDM( + public override async bushPunishDM( punishment: PunishmentTypeDM, reason?: string | null, duration?: number, @@ -62,7 +145,7 @@ export class BushGuildMember extends GuildMember { * @returns An object with the result of the warning, and the case number of the warn. * @emits {@link BushClientEvents.bushWarn} */ - public async bushWarn(options: BushPunishmentOptions): Promise<{ result: WarnResponse; caseNum: number | null }> { + public override async bushWarn(options: BushPunishmentOptions): Promise<{ result: WarnResponse; caseNum: number | null }> { let caseID: string | undefined = undefined; let dmSuccessEvent: boolean | undefined = undefined; const moderator = await util.resolveNonCachedUser(options.moderator ?? this.guild.members.me); @@ -105,7 +188,7 @@ export class BushGuildMember extends GuildMember { * @returns A status message for adding the add. * @emits {@link BushClientEvents.bushPunishRole} */ - public async bushAddRole(options: AddRoleOptions): Promise<AddRoleResponse> { + public override async bushAddRole(options: AddRoleOptions): Promise<AddRoleResponse> { // checks if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ManageRoles)) return addRoleResponse.MISSING_PERMISSIONS; const ifShouldAddRole = this.#checkIfShouldAddRole(options.role, options.moderator); @@ -164,7 +247,7 @@ export class BushGuildMember extends GuildMember { options.reason ?? undefined, caseID!, options.duration ?? 0, - options.role as BushRole, + options.role, options.evidence ); return ret; @@ -176,7 +259,7 @@ export class BushGuildMember extends GuildMember { * @returns A status message for removing the role. * @emits {@link BushClientEvents.bushPunishRoleRemove} */ - public async bushRemoveRole(options: RemoveRoleOptions): Promise<RemoveRoleResponse> { + public override async bushRemoveRole(options: RemoveRoleOptions): Promise<RemoveRoleResponse> { // checks if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ManageRoles)) return removeRoleResponse.MISSING_PERMISSIONS; const ifShouldAddRole = this.#checkIfShouldAddRole(options.role, options.moderator); @@ -235,7 +318,7 @@ export class BushGuildMember extends GuildMember { this.guild, options.reason ?? undefined, caseID!, - options.role as BushRole, + options.role, options.evidence ); return ret; @@ -248,8 +331,8 @@ export class BushGuildMember extends GuildMember { * @returns `true` if the role should be added/removed or a string for the reason why it shouldn't. */ #checkIfShouldAddRole( - role: BushRole | Role, - moderator?: BushGuildMember + role: Role | Role, + moderator?: GuildMember ): true | 'user hierarchy' | 'role managed' | 'client hierarchy' { if (moderator && moderator.roles.highest.position <= role.position && this.guild.ownerId !== this.user.id) { return shouldAddRoleResponse.USER_HIERARCHY; @@ -267,7 +350,7 @@ export class BushGuildMember extends GuildMember { * @returns A status message for muting the user. * @emits {@link BushClientEvents.bushMute} */ - public async bushMute(options: BushTimedPunishmentOptions): Promise<MuteResponse> { + public override async bushMute(options: BushTimedPunishmentOptions): Promise<MuteResponse> { // checks if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ManageRoles)) return muteResponse.MISSING_PERMISSIONS; const muteRoleID = await this.guild.getSetting('muteRole'); @@ -353,7 +436,7 @@ export class BushGuildMember extends GuildMember { * @returns A status message for unmuting the user. * @emits {@link BushClientEvents.bushUnmute} */ - public async bushUnmute(options: BushPunishmentOptions): Promise<UnmuteResponse> { + public override async bushUnmute(options: BushPunishmentOptions): Promise<UnmuteResponse> { // checks if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ManageRoles)) return unmuteResponse.MISSING_PERMISSIONS; const muteRoleID = await this.guild.getSetting('muteRole'); @@ -436,7 +519,7 @@ export class BushGuildMember extends GuildMember { * @returns A status message for kicking the user. * @emits {@link BushClientEvents.bushKick} */ - public async bushKick(options: BushPunishmentOptions): Promise<KickResponse> { + public override async bushKick(options: BushPunishmentOptions): Promise<KickResponse> { // checks if (!this.guild.members.me?.permissions.has(PermissionFlagsBits.KickMembers) || !this.kickable) return kickResponse.MISSING_PERMISSIONS; @@ -490,7 +573,7 @@ export class BushGuildMember extends GuildMember { * @returns A status message for banning the user. * @emits {@link BushClientEvents.bushBan} */ - public async bushBan(options: BushBanOptions): Promise<Exclude<BanResponse, typeof banResponse['ALREADY_BANNED']>> { + public override async bushBan(options: BushBanOptions): Promise<Exclude<BanResponse, typeof banResponse['ALREADY_BANNED']>> { // checks if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.BanMembers) || !this.bannable) return banResponse.MISSING_PERMISSIONS; @@ -570,7 +653,7 @@ export class BushGuildMember extends GuildMember { * Prevents a user from speaking in a channel. * @param options Options for blocking the user. */ - public async bushBlock(options: BlockOptions): Promise<BlockResponse> { + public override async bushBlock(options: BlockOptions): Promise<BlockResponse> { const channel = this.guild.channels.resolve(options.channel); if (!channel || (!channel.isTextBased() && !channel.isThread())) return blockResponse.INVALID_CHANNEL; @@ -660,10 +743,10 @@ export class BushGuildMember extends GuildMember { * Allows a user to speak in a channel. * @param options Options for unblocking the user. */ - public async bushUnblock(options: UnblockOptions): Promise<UnblockResponse> { + public override async bushUnblock(options: UnblockOptions): Promise<UnblockResponse> { const _channel = this.guild.channels.resolve(options.channel); - if (!_channel || (!_channel.isText() && !_channel.isThread())) return unblockResponse.INVALID_CHANNEL; - const channel = _channel as BushGuildTextBasedChannel; + if (!_channel || (_channel.type !== ChannelType.GuildText && !_channel.isThread())) return unblockResponse.INVALID_CHANNEL; + const channel = _channel as GuildTextBasedChannel; // checks if (!channel.permissionsFor(this.guild.members.me!)!.has(PermissionFlagsBits.ManageChannels)) @@ -747,7 +830,7 @@ export class BushGuildMember extends GuildMember { * Mutes a user using discord's timeout feature. * @param options Options for timing out the user. */ - public async bushTimeout(options: BushTimeoutOptions): Promise<TimeoutResponse> { + public override async bushTimeout(options: BushTimeoutOptions): Promise<TimeoutResponse> { // checks if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ModerateMembers)) return timeoutResponse.MISSING_PERMISSIONS; @@ -811,7 +894,7 @@ export class BushGuildMember extends GuildMember { * Removes a timeout from a user. * @param options Options for removing the timeout. */ - public async bushRemoveTimeout(options: BushPunishmentOptions): Promise<RemoveTimeoutResponse> { + public override async bushRemoveTimeout(options: BushPunishmentOptions): Promise<RemoveTimeoutResponse> { // checks if (!this.guild.members.me!.permissions.has(PermissionFlagsBits.ModerateMembers)) return removeTimeoutResponse.MISSING_PERMISSIONS; @@ -869,14 +952,14 @@ export class BushGuildMember extends GuildMember { /** * Whether or not the user is an owner of the bot. */ - public isOwner(): boolean { + public override isOwner(): boolean { return client.isOwner(this); } /** * Whether or not the user is a super user of the bot. */ - public isSuperUser(): boolean { + public override isSuperUser(): boolean { return client.isSuperUser(this); } } @@ -893,7 +976,7 @@ export interface BushPunishmentOptions { /** * The moderator who punished the user. */ - moderator?: BushGuildMember; + moderator?: GuildMember; /** * Evidence for the punishment. @@ -923,7 +1006,7 @@ export interface AddRoleOptions extends BushTimedPunishmentOptions { /** * The role to add to the user. */ - role: BushRole | Role; + role: Role; /** * Whether to create a modlog entry for this punishment. @@ -938,7 +1021,7 @@ export interface RemoveRoleOptions extends BushTimedPunishmentOptions { /** * The role to remove from the user. */ - role: BushRole | Role; + role: Role; /** * Whether to create a modlog entry for this punishment. @@ -963,7 +1046,7 @@ export interface BlockOptions extends BushTimedPunishmentOptions { /** * The channel to block the user from. */ - channel: BushGuildTextChannelResolvable | BushThreadChannelResolvable; + channel: GuildChannelResolvable; } /** @@ -973,7 +1056,7 @@ export interface UnblockOptions extends BushPunishmentOptions { /** * The channel to unblock the user from. */ - channel: BushGuildTextChannelResolvable | BushThreadChannelResolvable; + channel: GuildChannelResolvable; } /** @@ -1152,8 +1235,6 @@ export type TimeoutResponse = ValueOf<typeof timeoutResponse>; */ export type RemoveTimeoutResponse = ValueOf<typeof removeTimeoutResponse>; -export type PartialBushGuildMember = Partialize<BushGuildMember, 'joinedAt' | 'joinedTimestamp' | 'pending'>; - /** * @typedef {BushClientEvents} VSCodePleaseDontRemove */ diff --git a/src/lib/extensions/discord.js/ExtendedMessage.ts b/src/lib/extensions/discord.js/ExtendedMessage.ts new file mode 100644 index 0000000..4431077 --- /dev/null +++ b/src/lib/extensions/discord.js/ExtendedMessage.ts @@ -0,0 +1,12 @@ +import { CommandUtil } from 'discord-akairo'; +import { Message, type Client } from 'discord.js'; +import { type RawMessageData } from 'discord.js/typings/rawDataTypes.js'; + +export class ExtendedMessage<Cached extends boolean = boolean> extends Message<Cached> { + public declare util: CommandUtil<Message>; + + public constructor(client_: Client, data: RawMessageData) { + super(client_, data); + this.util = new CommandUtil(client.commandHandler, this); + } +} diff --git a/src/lib/extensions/discord.js/ExtendedUser.ts b/src/lib/extensions/discord.js/ExtendedUser.ts new file mode 100644 index 0000000..556ab85 --- /dev/null +++ b/src/lib/extensions/discord.js/ExtendedUser.ts @@ -0,0 +1,35 @@ +import { User, type Partialize } from 'discord.js'; + +declare module 'discord.js' { + export interface User { + /** + * Indicates whether the user is an owner of the bot. + */ + isOwner(): boolean; + /** + * Indicates whether the user is a superuser of the bot. + */ + isSuperUser(): boolean; + } +} + +export type PartialBushUser = Partialize<ExtendedUser, 'username' | 'tag' | 'discriminator' | 'isOwner' | 'isSuperUser'>; + +/** + * Represents a user on Discord. + */ +export class ExtendedUser extends User { + /** + * Indicates whether the user is an owner of the bot. + */ + public override isOwner(): boolean { + return client.isOwner(this); + } + + /** + * Indicates whether the user is a superuser of the bot. + */ + public override isSuperUser(): boolean { + return client.isSuperUser(this); + } +} diff --git a/src/lib/extensions/discord.js/other.ts b/src/lib/extensions/discord.js/other.ts deleted file mode 100644 index 0560ffc..0000000 --- a/src/lib/extensions/discord.js/other.ts +++ /dev/null @@ -1,188 +0,0 @@ -import type { - BushApplicationCommand, - BushCategoryChannel, - BushDMChannel, - BushGuild, - BushGuildEmoji, - BushGuildMember, - BushMessage, - BushNewsChannel, - BushReactionEmoji, - BushRole, - BushStageChannel, - BushTextChannel, - BushThreadChannel, - BushThreadMember, - BushUser, - BushVoiceChannel, - PartialBushDMChannel -} from '#lib'; -import { APIMessage } from 'discord-api-types/v10'; -import type { - ApplicationCommandResolvable, - CacheType, - CacheTypeReducer, - ChannelResolvable, - ChannelType, - Collection, - EmojiIdentifierResolvable, - EmojiResolvable, - FetchedThreads, - GuildChannelResolvable, - GuildMemberResolvable, - GuildTextChannelResolvable, - MessageResolvable, - PartialGroupDMChannel, - RoleResolvable, - Snowflake, - ThreadChannelResolvable, - ThreadMemberResolvable, - UserResolvable -} from 'discord.js'; - -/** - * Data that resolves to give a ThreadMember object. - */ -export type BushThreadMemberResolvable = ThreadMemberResolvable | BushThreadMember | BushUserResolvable; - -/** - * Data that resolves to give a User object. - */ -export type BushUserResolvable = UserResolvable | BushUser | Snowflake | BushMessage | BushGuildMember | BushThreadMember; - -/** - * Data that resolves to give a GuildMember object. - */ -export type BushGuildMemberResolvable = GuildMemberResolvable | BushGuildMember | BushUserResolvable; - -/** - * Data that can be resolved to a Role object. - */ -export type BushRoleResolvable = RoleResolvable | BushRole | Snowflake; - -/** - * Data that can be resolved to a Message object. - */ -export type BushMessageResolvable = MessageResolvable | BushMessage | Snowflake; - -/** - * Data that can be resolved into a GuildEmoji object. - */ -export type BushEmojiResolvable = EmojiResolvable | Snowflake | BushGuildEmoji | BushReactionEmoji; - -/** - * Data that can be resolved to give an emoji identifier. This can be: - * * The unicode representation of an emoji - * * The `<a:name:id>`, `<:name:id>`, `a:name:id` or `name:id` emoji identifier string of an emoji - * * An EmojiResolvable - */ -export type BushEmojiIdentifierResolvable = EmojiIdentifierResolvable | string | BushEmojiResolvable; - -/** - * Data that can be resolved to a Thread Channel object. - */ -export type BushThreadChannelResolvable = ThreadChannelResolvable | BushThreadChannel | Snowflake; - -/** - * Data that resolves to give an ApplicationCommand object. - */ -export type BushApplicationCommandResolvable = ApplicationCommandResolvable | BushApplicationCommand | Snowflake; - -/** - * Data that can be resolved to a GuildTextChannel object. - */ -export type BushGuildTextChannelResolvable = GuildTextChannelResolvable | BushTextChannel | BushNewsChannel | Snowflake; - -/** - * Data that can be resolved to give a Channel object. - */ -export type BushChannelResolvable = ChannelResolvable | BushAnyChannel | Snowflake; - -/** - * Data that can be resolved to give a Guild Channel object. - */ -export type BushGuildChannelResolvable = GuildChannelResolvable | Snowflake | BushGuildBasedChannel; - -export type BushAnyChannel = - | BushCategoryChannel - | BushDMChannel - | PartialBushDMChannel - | PartialGroupDMChannel - | BushNewsChannel - | BushStageChannel - | BushTextChannel - | BushThreadChannel - | BushVoiceChannel; - -/** - * The channels that are text-based. - */ -export type BushTextBasedChannel = - | BushDMChannel - | PartialBushDMChannel - | BushNewsChannel - | BushTextChannel - | BushThreadChannel - | BushVoiceChannel; - -/** - * The types of channels that are text-based. - */ -export type BushTextBasedChannelTypes = BushTextBasedChannel['type']; - -export type BushVoiceBasedChannel = Extract<BushAnyChannel, { bitrate: number }>; - -export type BushGuildBasedChannel = Extract<BushAnyChannel, { guild: BushGuild }>; - -export type BushNonCategoryGuildBasedChannel = Exclude<BushGuildBasedChannel, BushCategoryChannel>; - -export type BushNonThreadGuildBasedChannel = Exclude<BushGuildBasedChannel, BushThreadChannel>; - -export type BushGuildTextBasedChannel = Extract<BushGuildBasedChannel, BushTextBasedChannel>; - -/** - * Data that can be resolved to a Text Channel object. - */ -export type BushTextChannelResolvable = Snowflake | BushTextChannel; - -/** - * Data that can be resolved to a GuildVoiceChannel object. - */ -export type BushGuildVoiceChannelResolvable = BushVoiceBasedChannel | Snowflake; - -export interface BushMappedChannelCategoryTypes { - [ChannelType.GuildNews]: BushNewsChannel; - [ChannelType.GuildVoice]: BushVoiceChannel; - [ChannelType.GuildText]: BushTextChannel; - [ChannelType.GuildStageVoice]: BushStageChannel; - [ChannelType.GuildForum]: never; // TODO: Fix when guild forums come out -} - -export type BushMappedGuildChannelTypes = { - [ChannelType.GuildCategory]: BushCategoryChannel; -} & BushMappedChannelCategoryTypes; - -/** - * The data returned from a thread fetch that returns multiple threads. - */ -export interface BushFetchedThreads extends FetchedThreads { - /** - * The threads that were fetched, with any members returned - */ - threads: Collection<Snowflake, BushThreadChannel>; - - /** - * Whether there are potentially additional threads that require a subsequent call - */ - hasMore?: boolean; -} - -export type BushGuildCacheMessage<Cached extends CacheType> = CacheTypeReducer< - Cached, - BushMessage<true>, - APIMessage, - BushMessage | APIMessage, - BushMessage | APIMessage ->; - -export { ApplicationCommandOptionType as SlashType } from 'discord.js'; diff --git a/src/lib/index.ts b/src/lib/index.ts index 8a6b75d..221f360 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -12,61 +12,18 @@ export * from './extensions/discord-akairo/BushClient.js'; export * from './extensions/discord-akairo/BushClientUtil.js'; export * from './extensions/discord-akairo/BushCommand.js'; export * from './extensions/discord-akairo/BushCommandHandler.js'; -export * from './extensions/discord-akairo/BushCommandUtil.js'; export * from './extensions/discord-akairo/BushInhibitor.js'; export * from './extensions/discord-akairo/BushInhibitorHandler.js'; export * from './extensions/discord-akairo/BushListener.js'; export * from './extensions/discord-akairo/BushListenerHandler.js'; -export * from './extensions/discord-akairo/BushSlashMessage.js'; export * from './extensions/discord-akairo/BushTask.js'; export * from './extensions/discord-akairo/BushTaskHandler.js'; -export * from './extensions/discord.js/BushActivity.js'; -export * from './extensions/discord.js/BushApplicationCommand.js'; -export type { BushApplicationCommandManager } from './extensions/discord.js/BushApplicationCommandManager.js'; -export type { BushApplicationCommandPermissionsManager } from './extensions/discord.js/BushApplicationCommandPermissionsManager.js'; -export type { BushBaseGuildEmojiManager } from './extensions/discord.js/BushBaseGuildEmojiManager.js'; -export type { BushBaseGuildVoiceChannel } from './extensions/discord.js/BushBaseGuildVoiceChannel.js'; -export * from './extensions/discord.js/BushButtonInteraction.js'; -export * from './extensions/discord.js/BushCategoryChannel.js'; -export type { BushCategoryChannelChildManager } from './extensions/discord.js/BushCategoryChannelChildManager.js'; -export type { BushChannel } from './extensions/discord.js/BushChannel.js'; -export type { BushChannelManager } from './extensions/discord.js/BushChannelManager.js'; -export * from './extensions/discord.js/BushChatInputCommandInteraction.js'; +export * from './extensions/discord-akairo/SlashMessage.js'; export type { BushClientEvents } from './extensions/discord.js/BushClientEvents.js'; -export type { BushClientUser } from './extensions/discord.js/BushClientUser.js'; -export * from './extensions/discord.js/BushDMChannel.js'; -export * from './extensions/discord.js/BushEmoji.js'; -export * from './extensions/discord.js/BushGuild.js'; -export type { BushGuildApplicationCommandManager } from './extensions/discord.js/BushGuildApplicationCommandManager.js'; -export type { BushGuildBan } from './extensions/discord.js/BushGuildBan.js'; -export * from './extensions/discord.js/BushGuildChannel.js'; -export type { BushGuildChannelManager } from './extensions/discord.js/BushGuildChannelManager.js'; -export * from './extensions/discord.js/BushGuildEmoji.js'; -export type { BushGuildEmojiRoleManager } from './extensions/discord.js/BushGuildEmojiRoleManager.js'; -export type { BushGuildManager } from './extensions/discord.js/BushGuildManager.js'; -export * from './extensions/discord.js/BushGuildMember.js'; -export type { BushGuildMemberManager } from './extensions/discord.js/BushGuildMemberManager.js'; -export * from './extensions/discord.js/BushMessage.js'; -export type { BushMessageManager } from './extensions/discord.js/BushMessageManager.js'; -export * from './extensions/discord.js/BushMessageReaction.js'; -export * from './extensions/discord.js/BushModalSubmitInteraction.js'; -export * from './extensions/discord.js/BushNewsChannel.js'; -export * from './extensions/discord.js/BushPresence.js'; -export * from './extensions/discord.js/BushReactionEmoji.js'; -export * from './extensions/discord.js/BushRole.js'; -export * from './extensions/discord.js/BushSelectMenuInteraction.js'; -export * from './extensions/discord.js/BushStageChannel.js'; -export * from './extensions/discord.js/BushStageInstance.js'; -export * from './extensions/discord.js/BushTextChannel.js'; -export * from './extensions/discord.js/BushThreadChannel.js'; -export type { BushThreadManager } from './extensions/discord.js/BushThreadManager.js'; -export * from './extensions/discord.js/BushThreadMember.js'; -export type { BushThreadMemberManager } from './extensions/discord.js/BushThreadMemberManager.js'; -export * from './extensions/discord.js/BushUser.js'; -export type { BushUserManager } from './extensions/discord.js/BushUserManager.js'; -export * from './extensions/discord.js/BushVoiceChannel.js'; -export * from './extensions/discord.js/BushVoiceState.js'; -export * from './extensions/discord.js/other.js'; +export * from './extensions/discord.js/ExtendedGuild.js'; +export * from './extensions/discord.js/ExtendedGuildMember.js'; +export * from './extensions/discord.js/ExtendedMessage.js'; +export * from './extensions/discord.js/ExtendedUser.js'; export * from './models/BaseModel.js'; export * from './models/instance/ActivePunishment.js'; export * from './models/instance/Guild.js'; diff --git a/src/lib/utils/BushLogger.ts b/src/lib/utils/BushLogger.ts index 91c23d3..073b8e2 100644 --- a/src/lib/utils/BushLogger.ts +++ b/src/lib/utils/BushLogger.ts @@ -4,7 +4,7 @@ import { EmbedBuilder, Util, type Message, type PartialTextBasedChannelFields } import repl, { REPLServer, REPL_MODE_STRICT } from 'repl'; import { WriteStream } from 'tty'; import { inspect } from 'util'; -import { type BushSendMessageType } from '../extensions/discord-akairo/BushClient.js'; +import { type SendMessageType } from '../extensions/discord-akairo/BushClient.js'; let REPL: REPLServer; let replGone = false; @@ -147,7 +147,7 @@ export class BushLogger { * @param message The parameter to pass to {@link PartialTextBasedChannelFields.send}. * @returns The message sent. */ - public static async channelLog(message: BushSendMessageType): Promise<Message | null> { + public static async channelLog(message: SendMessageType): Promise<Message | null> { const channel = await util.getConfigChannel('log'); return await channel.send(message).catch(() => null); } @@ -157,7 +157,7 @@ export class BushLogger { * @param message The parameter to pass to {@link PartialTextBasedChannelFields.send}. * @returns The message sent. */ - public static async channelError(message: BushSendMessageType): Promise<Message | null> { + public static async channelError(message: SendMessageType): Promise<Message | null> { const channel = await util.getConfigChannel('error'); if (!channel) { void this.error( diff --git a/src/listeners/bush/joinAutoBan.ts b/src/listeners/bush/joinAutoBan.ts index 0b38766..83efa06 100644 --- a/src/listeners/bush/joinAutoBan.ts +++ b/src/listeners/bush/joinAutoBan.ts @@ -1,4 +1,5 @@ -import { AllowedMentions, BushListener, type BushClientEvents, type BushTextChannel } from '#lib'; +import { AllowedMentions, BushListener, type BushClientEvents } from '#lib'; +import { TextChannel } from 'discord.js'; export default class JoinAutoBanListener extends BushListener { public constructor() { @@ -52,7 +53,7 @@ export default class JoinAutoBanListener extends BushListener { ? `${util.emojis.warn} Banned ${util.format.input(member.user.tag)} however I could not send them a dm.` : `${util.emojis.success} Successfully banned ${util.format.input(member.user.tag)}.`; - (<BushTextChannel>guild.channels.cache.find((c) => c.name === 'general')) + (<TextChannel>guild.channels.cache.find((c) => c.name === 'general')) ?.send({ content, allowedMentions: AllowedMentions.none() }) .catch(() => {}); } diff --git a/src/listeners/bush/supportThread.ts b/src/listeners/bush/supportThread.ts index e809176..46ac96f 100644 --- a/src/listeners/bush/supportThread.ts +++ b/src/listeners/bush/supportThread.ts @@ -1,7 +1,7 @@ -import { BushListener, BushTextChannel, type BushClientEvents } from '#lib'; +import { BushListener, type BushClientEvents } from '#lib'; import { stripIndent } from '#tags'; import assert from 'assert'; -import { EmbedBuilder, MessageType, PermissionFlagsBits } from 'discord.js'; +import { EmbedBuilder, MessageType, PermissionFlagsBits, TextChannel } from 'discord.js'; export default class SupportThreadListener extends BushListener { public constructor() { @@ -12,7 +12,7 @@ export default class SupportThreadListener extends BushListener { }); } - public override async exec(...[message]: BushClientEvents['messageCreate']): Promise<Promise<void> | undefined> { + public override async exec(...[message]: BushClientEvents['messageCreate']): Promise<void | undefined> { if (!client.config.isProduction || !message.inGuild()) return; if (![MessageType.Default, MessageType.Reply].includes(message.type)) return; if (message.thread) return; @@ -30,7 +30,7 @@ export default class SupportThreadListener extends BushListener { ) return; - assert(message.channel instanceof BushTextChannel); + assert(message.channel instanceof TextChannel); if (!message.channel.permissionsFor(message.guild.members.me!).has(PermissionFlagsBits.CreatePublicThreads)) return; const thread = await message diff --git a/src/listeners/bush/userUpdateAutoBan.ts b/src/listeners/bush/userUpdateAutoBan.ts index 68dfa38..b9485b3 100644 --- a/src/listeners/bush/userUpdateAutoBan.ts +++ b/src/listeners/bush/userUpdateAutoBan.ts @@ -1,4 +1,5 @@ -import { AllowedMentions, BushGuildMember, BushListener, type BushClientEvents, type BushTextChannel } from '#lib'; +import { AllowedMentions, BushListener, type BushClientEvents } from '#lib'; +import { GuildMember, type TextChannel } from 'discord.js'; export default class UserUpdateAutoBanListener extends BushListener { public constructor() { @@ -21,7 +22,7 @@ export default class UserUpdateAutoBanListener extends BushListener { .get(client.consts.mappings.guilds.bush) ?.members.fetch(newUser.id) .catch(() => undefined); - if (!member || !(member instanceof BushGuildMember)) return; + if (!member || !(member instanceof GuildMember)) return; const guild = member.guild; @@ -58,7 +59,7 @@ export default class UserUpdateAutoBanListener extends BushListener { ? `${util.emojis.warn} Banned ${util.format.input(member.user.tag)} however I could not send them a dm.` : `${util.emojis.success} Successfully banned ${util.format.input(member.user.tag)}.`; - (<BushTextChannel>guild.channels.cache.find((c) => c.name === 'general')) + (<TextChannel>guild.channels.cache.find((c) => c.name === 'general')) ?.send({ content, allowedMentions: AllowedMentions.none() }) .catch(() => {}); } diff --git a/src/listeners/commands/commandBlocked.ts b/src/listeners/commands/commandBlocked.ts index 0d3c1d9..feb85d1 100644 --- a/src/listeners/commands/commandBlocked.ts +++ b/src/listeners/commands/commandBlocked.ts @@ -1,5 +1,5 @@ -import { BushListener, type BushCommand, type BushCommandHandlerEvents, type BushMessage, type BushSlashMessage } from '#lib'; -import { type InteractionReplyOptions, type Message, type MessagePayload, type ReplyMessageOptions } from 'discord.js'; +import { BushListener, type BushCommand, type BushCommandHandlerEvents, type CommandMessage, type SlashMessage } from '#lib'; +import { type InteractionReplyOptions, type MessagePayload, type ReplyMessageOptions } from 'discord.js'; export default class CommandBlockedListener extends BushListener { public constructor() { @@ -14,11 +14,7 @@ export default class CommandBlockedListener extends BushListener { return await CommandBlockedListener.handleBlocked(message, command, reason); } - public static async handleBlocked( - message: Message | BushMessage | BushSlashMessage, - command: BushCommand | null, - reason?: string - ) { + public static async handleBlocked(message: CommandMessage | SlashMessage, command: BushCommand | null, reason?: string) { const isSlash = !!command && !!message.util?.isSlash; void client.console.info( @@ -64,7 +60,7 @@ export default class CommandBlockedListener extends BushListener { content: `${util.emojis.error} You cannot use this bot in this channel.`, ephemeral: true }) - : await (message as BushMessage).react(util.emojis.cross); + : await (message as CommandMessage).react(util.emojis.cross); case reasons.USER_GLOBAL_BLACKLIST: case reasons.USER_GUILD_BLACKLIST: return isSlash @@ -72,14 +68,14 @@ export default class CommandBlockedListener extends BushListener { content: `${util.emojis.error} You are blacklisted from using this bot.`, ephemeral: true }) - : await (message as BushMessage).react(util.emojis.cross); + : await (message as CommandMessage).react(util.emojis.cross); case reasons.ROLE_BLACKLIST: { return isSlash ? await respond({ content: `${util.emojis.error} One of your roles blacklists you from using this bot.`, ephemeral: true }) - : await (message as BushMessage).react(util.emojis.cross); + : await (message as CommandMessage).react(util.emojis.cross); } case reasons.RESTRICTED_CHANNEL: { if (!command) break; diff --git a/src/listeners/commands/commandError.ts b/src/listeners/commands/commandError.ts index f830cca..878e459 100644 --- a/src/listeners/commands/commandError.ts +++ b/src/listeners/commands/commandError.ts @@ -1,6 +1,6 @@ -import { type BushCommandHandlerEvents } from '#lib'; +import { SlashMessage, type BushCommandHandlerEvents } from '#lib'; import { type AkairoMessage, type Command } from 'discord-akairo'; -import { EmbedBuilder, Formatters, GuildTextBasedChannel, type Message } from 'discord.js'; +import { ChannelType, EmbedBuilder, Formatters, GuildTextBasedChannel, type Message } from 'discord.js'; import { BushListener } from '../../lib/extensions/discord-akairo/BushListener.js'; export default class CommandErrorListener extends BushListener { @@ -20,10 +20,13 @@ export default class CommandErrorListener extends BushListener { ...[error, message, _command]: BushCommandHandlerEvents['error'] | BushCommandHandlerEvents['slashError'] ) { try { - const isSlash = message.util.isSlash; + const isSlash = message.util?.isSlash; const errorNum = Math.floor(Math.random() * 6969696969) + 69; // hehe funny number - const channel = message.channel?.isDM() ? message.channel.recipient?.tag : (<GuildTextBasedChannel>message.channel)?.name; - const command = _command ?? message.util.parsed?.command; + const channel = + message.channel?.type === ChannelType.DM + ? message.channel.recipient?.tag + : (<GuildTextBasedChannel>message.channel)?.name; + const command = _command ?? message.util?.parsed?.command; client.sentry.captureException(error, { level: 'error', @@ -31,9 +34,10 @@ export default class CommandErrorListener extends BushListener { extra: { 'command.name': command?.id, 'message.id': message.id, - 'message.type': message.util.isSlash ? 'slash' : 'normal', - 'message.parsed.content': message.util.parsed?.content, - 'channel.id': (message.channel?.isDM() ? message.channel.recipient?.id : message.channel?.id) ?? '¯\\_(ツ)_/¯', + 'message.type': message.util ? (message.util.isSlash ? 'slash' : 'normal') : 'unknown', + 'message.parsed.content': message.util?.parsed?.content, + 'channel.id': + (message.channel?.type === ChannelType.DM ? message.channel.recipient?.id : message.channel?.id) ?? '¯\\_(ツ)_/¯', 'channel.name': channel, 'guild.id': message.guild?.id ?? '¯\\_(ツ)_/¯', 'guild.name': message.guild?.name ?? '¯\\_(ツ)_/¯', @@ -87,7 +91,7 @@ export default class CommandErrorListener extends BushListener { | { message: Message | AkairoMessage; error: Error | any; - isSlash: boolean; + isSlash?: boolean; type: 'command-log' | 'command-dev' | 'command-user'; errorNum: number; command?: Command; @@ -105,9 +109,9 @@ export default class CommandErrorListener extends BushListener { private static _generateErrorEmbed( options: | { - message: Message | AkairoMessage; + message: Message | SlashMessage; error: Error | any; - isSlash: boolean; + isSlash?: boolean; type: 'command-log' | 'command-dev' | 'command-user'; errorNum: number; command?: Command; diff --git a/src/listeners/commands/commandMissingPermissions.ts b/src/listeners/commands/commandMissingPermissions.ts index 19c0860..2cbf17c 100644 --- a/src/listeners/commands/commandMissingPermissions.ts +++ b/src/listeners/commands/commandMissingPermissions.ts @@ -1,5 +1,5 @@ import { BushListener, type BushCommandHandlerEvents } from '#lib'; -import { PermissionsString } from 'discord.js'; +import { type PermissionsString } from 'discord.js'; export default class CommandMissingPermissionsListener extends BushListener { public constructor() { diff --git a/src/listeners/contextCommands/contextCommandBlocked.ts b/src/listeners/contextCommands/contextCommandBlocked.ts index 7fe381e..ba4af8c 100644 --- a/src/listeners/contextCommands/contextCommandBlocked.ts +++ b/src/listeners/contextCommands/contextCommandBlocked.ts @@ -1,5 +1,5 @@ import { BushListener } from '#lib'; -import { ContextMenuCommandHandlerEvents } from 'discord-akairo'; +import { type ContextMenuCommandHandlerEvents } from 'discord-akairo'; export default class ContextCommandBlockedListener extends BushListener { public constructor() { diff --git a/src/listeners/contextCommands/contextCommandError.ts b/src/listeners/contextCommands/contextCommandError.ts index a532d5e..19b5708 100644 --- a/src/listeners/contextCommands/contextCommandError.ts +++ b/src/listeners/contextCommands/contextCommandError.ts @@ -1,6 +1,6 @@ -import { ContextMenuCommand, ContextMenuCommandHandlerEvents } from 'discord-akairo'; -import { ContextMenuCommandInteraction, EmbedBuilder, GuildTextBasedChannel } from 'discord.js'; -import { BushListener } from '../../lib/extensions/discord-akairo/BushListener.js'; +import { BushListener } from '#lib'; +import { type ContextMenuCommand, type ContextMenuCommandHandlerEvents } from 'discord-akairo'; +import { ChannelType, ContextMenuCommandInteraction, EmbedBuilder, GuildTextBasedChannel } from 'discord.js'; import CommandErrorListener, { IFuckedUpError } from '../commands/commandError.js'; export default class ContextCommandErrorListener extends BushListener { @@ -19,9 +19,10 @@ export default class ContextCommandErrorListener extends BushListener { public static async handleError(...[error, interaction, command]: ContextMenuCommandHandlerEvents['error']) { try { const errorNum = Math.floor(Math.random() * 6969696969) + 69; // hehe funny number - const channel = interaction.channel?.isDM() - ? interaction.channel.recipient?.tag - : (<GuildTextBasedChannel>interaction.channel)?.name; + const channel = + interaction.channel?.type === ChannelType.DM + ? interaction.channel.recipient?.tag + : (<GuildTextBasedChannel>interaction.channel)?.name; client.sentry.captureException(error, { level: 'error', @@ -31,7 +32,8 @@ export default class ContextCommandErrorListener extends BushListener { 'message.id': interaction.id, 'message.type': 'context command', 'channel.id': - (interaction.channel?.isDM() ? interaction.channel.recipient?.id : interaction.channel?.id) ?? '¯\\_(ツ)_/¯', + (interaction.channel?.type === ChannelType.DM ? interaction.channel.recipient?.id : interaction.channel?.id) ?? + '¯\\_(ツ)_/¯', 'channel.name': channel, 'guild.id': interaction.guild?.id ?? '¯\\_(ツ)_/¯', 'guild.name': interaction.guild?.name ?? '¯\\_(ツ)_/¯', diff --git a/src/listeners/contextCommands/contextCommandNotFound.ts b/src/listeners/contextCommands/contextCommandNotFound.ts index b0a8f62..ca97ad1 100644 --- a/src/listeners/contextCommands/contextCommandNotFound.ts +++ b/src/listeners/contextCommands/contextCommandNotFound.ts @@ -1,5 +1,5 @@ import { BushListener } from '#lib'; -import { ContextMenuCommandHandlerEvents } from 'discord-akairo'; +import { type ContextMenuCommandHandlerEvents } from 'discord-akairo'; export default class ContextCommandNotFoundListener extends BushListener { public constructor() { diff --git a/src/listeners/guild/guildMemberAdd.ts b/src/listeners/guild/guildMemberAdd.ts index 94d35a5..de1f859 100644 --- a/src/listeners/guild/guildMemberAdd.ts +++ b/src/listeners/guild/guildMemberAdd.ts @@ -1,5 +1,5 @@ -import { BushListener, type BushClientEvents, type BushGuildMember, type BushTextChannel } from '#lib'; -import { EmbedBuilder } from 'discord.js'; +import { BushListener, type BushClientEvents } from '#lib'; +import { EmbedBuilder, type GuildMember, type TextChannel } from 'discord.js'; export default class GuildMemberAddListener extends BushListener { public constructor() { @@ -14,11 +14,11 @@ export default class GuildMemberAddListener extends BushListener { void this.sendWelcomeMessage(member); } - private async sendWelcomeMessage(member: BushGuildMember) { + private async sendWelcomeMessage(member: GuildMember) { if (client.config.isDevelopment) return; const welcomeChannel = await member.guild.getSetting('welcomeChannel'); if (!welcomeChannel) return; - const welcome = client.channels.cache.get(welcomeChannel) as BushTextChannel | undefined; + const welcome = client.channels.cache.get(welcomeChannel) as TextChannel | undefined; if (!welcome) return; if (member.guild.id !== welcome?.guild.id) throw new Error('Welcome channel must be in the guild.'); diff --git a/src/listeners/guild/guildMemberRemove.ts b/src/listeners/guild/guildMemberRemove.ts index 8e7ce0d..59f8800 100644 --- a/src/listeners/guild/guildMemberRemove.ts +++ b/src/listeners/guild/guildMemberRemove.ts @@ -1,13 +1,5 @@ -import { - BushListener, - StickyRole, - Time, - type BushClientEvents, - type BushGuildMember, - type BushTextChannel, - type PartialBushGuildMember -} from '#lib'; -import { EmbedBuilder } from 'discord.js'; +import { BushListener, StickyRole, Time, type BushClientEvents } from '#lib'; +import { EmbedBuilder, type GuildMember, type PartialGuildMember, type TextChannel } from 'discord.js'; export default class GuildMemberRemoveListener extends BushListener { public constructor() { @@ -23,14 +15,14 @@ export default class GuildMemberRemoveListener extends BushListener { void this.stickyRoles(member); } - private async sendWelcomeMessage(member: BushGuildMember | PartialBushGuildMember) { + private async sendWelcomeMessage(member: GuildMember | PartialGuildMember) { if (client.config.isDevelopment) return; const user = member.partial ? await client.users.fetch(member.id) : member.user; await util.sleep(50 * Time.Millisecond); // ban usually triggers after member leave const isBan = member.guild.bans.cache.has(member.id); const welcomeChannel = await member.guild.getSetting('welcomeChannel'); if (!welcomeChannel) return; - const welcome = client.channels.cache.get(welcomeChannel) as BushTextChannel | undefined; + const welcome = client.channels.cache.get(welcomeChannel) as TextChannel | undefined; if (member.guild.id !== welcome?.guild.id) throw new Error('Welcome channel must be in the guild.'); const embed: EmbedBuilder = new EmbedBuilder() .setDescription( @@ -55,7 +47,7 @@ export default class GuildMemberRemoveListener extends BushListener { ); } - private async stickyRoles(member: BushGuildMember | PartialBushGuildMember) { + private async stickyRoles(member: GuildMember | PartialGuildMember) { if (!(await member.guild.hasFeature('stickyRoles'))) return; if (member.partial) { await member.guild.members.fetch(); // try to prevent in the future diff --git a/src/listeners/guild/joinRoles.ts b/src/listeners/guild/joinRoles.ts index 81a07e5..dab623f 100644 --- a/src/listeners/guild/joinRoles.ts +++ b/src/listeners/guild/joinRoles.ts @@ -1,5 +1,5 @@ -import { BushListener, StickyRole, type BushClientEvents, type BushGuildMember } from '#lib'; -import { type Snowflake } from 'discord.js'; +import { BushListener, StickyRole, type BushClientEvents } from '#lib'; +import { type GuildMember, type Snowflake } from 'discord.js'; export default class JoinRolesListener extends BushListener { public constructor() { @@ -37,7 +37,7 @@ export default class JoinRolesListener extends BushListener { * @param member The member to add sticky roles to. * @returns Whether or not sticky roles were added. */ - private async stickyRoles(member: BushGuildMember): Promise<boolean> { + private async stickyRoles(member: GuildMember): Promise<boolean> { const hadRoles = await StickyRole.findOne({ where: { guild: member.guild.id, user: member.id } }); if (hadRoles?.roles?.length) { @@ -98,7 +98,7 @@ export default class JoinRolesListener extends BushListener { * Add the guild's join roles to the member. * @param member The member to add the join roles to. */ - private async joinRoles(member: BushGuildMember): Promise<void> { + private async joinRoles(member: GuildMember): Promise<void> { const joinRoles = await member.guild.getSetting('joinRoles'); if (!joinRoles || !joinRoles.length) return; await member.roles diff --git a/src/listeners/interaction/interactionCreate.ts b/src/listeners/interaction/interactionCreate.ts index 13c4c74..48a2149 100644 --- a/src/listeners/interaction/interactionCreate.ts +++ b/src/listeners/interaction/interactionCreate.ts @@ -1,5 +1,5 @@ -import { AutoMod, BushListener, type BushButtonInteraction, type BushClientEvents } from '#lib'; -import { InteractionType } from 'discord-api-types/v10'; +import { AutoMod, BushListener, type BushClientEvents } from '#lib'; +import { InteractionType } from 'discord.js'; export default class InteractionCreateListener extends BushListener { public constructor() { @@ -17,12 +17,12 @@ export default class InteractionCreateListener extends BushListener { 'interactionVerbose', `An interaction of type <<${InteractionType[interaction.type]}>> was received from <<${interaction.user.tag}>>.` ); - if (interaction.isCommand()) { + if (interaction.type === InteractionType.ApplicationCommand) { return; } else if (interaction.isButton()) { const id = interaction.customId; if (['paginate_', 'command_', 'confirmationPrompt_', 'appeal'].some((s) => id.startsWith(s))) return; - else if (id.startsWith('automod;')) void AutoMod.handleInteraction(interaction as BushButtonInteraction); + else if (id.startsWith('automod;')) void AutoMod.handleInteraction(interaction); else if (id.startsWith('button-role;') && interaction.inCachedGuild()) { const [, roleId] = id.split(';'); const role = interaction.guild.roles.cache.get(roleId); diff --git a/src/listeners/member-custom/bushLevelUpdate.ts b/src/listeners/member-custom/bushLevelUpdate.ts index c43e341..2a7b75b 100644 --- a/src/listeners/member-custom/bushLevelUpdate.ts +++ b/src/listeners/member-custom/bushLevelUpdate.ts @@ -1,4 +1,5 @@ import { BushListener, type BushClientEvents } from '#lib'; +import assert from 'assert'; import { type TextChannel } from 'discord.js'; type Args = BushClientEvents['bushLevelUpdate']; @@ -18,6 +19,7 @@ export default class BushLevelUpdateListener extends BushListener { } private async sendLevelUpMessages(member: Args[0], newLevel: Args[2], message: Args[4]) { + assert(message.inGuild()); if (!(await message.guild.hasFeature('sendLevelUpMessages'))) return; const channel = ((await message.guild.channels @@ -36,6 +38,7 @@ export default class BushLevelUpdateListener extends BushListener { } private async assignLevelRoles(member: Args[0], newLevel: Args[2], message: Args[4]) { + assert(message.inGuild()); const levelRoles = await message.guild.getSetting('levelRoles'); if (!Object.keys(levelRoles).length) return; diff --git a/src/listeners/member-custom/bushPurge.ts b/src/listeners/member-custom/bushPurge.ts index 49d848f..3334bad 100644 --- a/src/listeners/member-custom/bushPurge.ts +++ b/src/listeners/member-custom/bushPurge.ts @@ -1,5 +1,5 @@ import { BushListener, type BushClientEvents } from '#lib'; -import { EmbedBuilder } from '@discordjs/builders'; +import { EmbedBuilder } from 'discord.js'; export default class BushPurgeListener extends BushListener { public constructor() { diff --git a/src/listeners/message/autoPublisher.ts b/src/listeners/message/autoPublisher.ts index b074fda..8f3462f 100644 --- a/src/listeners/message/autoPublisher.ts +++ b/src/listeners/message/autoPublisher.ts @@ -1,4 +1,5 @@ import { BushListener, type BushClientEvents } from '#lib'; +import { ChannelType } from 'discord.js'; export default class autoPublisherListener extends BushListener { public constructor() { @@ -13,7 +14,7 @@ export default class autoPublisherListener extends BushListener { if (!message.guild || !(await message.guild.hasFeature('autoPublish'))) return; const autoPublishChannels = await message.guild.getSetting('autoPublishChannels'); if (autoPublishChannels) { - if (message.channel.isNews() && autoPublishChannels.some((x) => message.channel.id.includes(x))) { + if (message.channel.type === ChannelType.GuildNews && autoPublishChannels.some((x) => message.channel.id.includes(x))) { await message .crosspost() .then( diff --git a/src/listeners/message/blacklistedFile.ts b/src/listeners/message/blacklistedFile.ts index a6216a5..122f289 100644 --- a/src/listeners/message/blacklistedFile.ts +++ b/src/listeners/message/blacklistedFile.ts @@ -128,7 +128,7 @@ export default class BlacklistedFileListener extends BushListener { } await message.delete(); - await message.util.send( + await message.util!.send( `<@!${message.author.id}>, please do not send ${foundFiles.map((f) => f.description).join(' or ')}.` ); if (message.channel.type === ChannelType.DM) return; @@ -139,7 +139,7 @@ export default class BlacklistedFileListener extends BushListener { }.` ); } catch (e) { - void message.util.send( + void message.util!.send( `<@!${message.author.id}>, please do not send ${foundFiles.map((f) => f.description).join(' or ')}.` ); void client.console.warn( diff --git a/src/listeners/message/level.ts b/src/listeners/message/level.ts index 5abfd6f..08a8a7c 100644 --- a/src/listeners/message/level.ts +++ b/src/listeners/message/level.ts @@ -1,4 +1,4 @@ -import { BushListener, Level, type BushCommandHandlerEvents, type BushGuild, type BushMessage } from '#lib'; +import { BushListener, Level, type BushCommandHandlerEvents } from '#lib'; import { MessageType } from 'discord.js'; export default class LevelListener extends BushListener { @@ -37,15 +37,7 @@ export default class LevelListener extends BushListener { return false; }); const newLevel = Level.convertXpToLevel(user.xp); - if (previousLevel !== newLevel) - client.emit( - 'bushLevelUpdate', - message.member!, - previousLevel, - newLevel, - user.xp, - message as BushMessage & { guild: BushGuild } - ); + if (previousLevel !== newLevel) client.emit('bushLevelUpdate', message.member!, previousLevel, newLevel, user.xp, message); if (success) void client.logger.verbose(`level`, `Gave <<${xpToGive}>> XP to <<${message.author.tag}>> in <<${message.guild}>>.`); this.#levelCooldowns.add(`${message.guildId}-${message.author.id}`); diff --git a/src/listeners/rest/rateLimit.ts b/src/listeners/rest/rateLimit.ts index 600ef07..4884e9f 100644 --- a/src/listeners/rest/rateLimit.ts +++ b/src/listeners/rest/rateLimit.ts @@ -1,5 +1,5 @@ import { BushListener } from '#lib'; -import { RestEvents } from '@discordjs/rest'; +import type { RestEvents } from '@discordjs/rest'; export default class RateLimitedListener extends BushListener { public constructor() { diff --git a/src/listeners/track-manual-punishments/modlogSyncBan.ts b/src/listeners/track-manual-punishments/modlogSyncBan.ts index 504992f..be937b9 100644 --- a/src/listeners/track-manual-punishments/modlogSyncBan.ts +++ b/src/listeners/track-manual-punishments/modlogSyncBan.ts @@ -1,7 +1,5 @@ -import { BushListener, BushUser, Moderation, ModLogType, Time, type BushClientEvents } from '#lib'; -import { EmbedBuilder } from '@discordjs/builders'; -import { AuditLogEvent } from 'discord-api-types/v10'; -import { PermissionFlagsBits } from 'discord.js'; +import { BushListener, Moderation, ModLogType, Time, type BushClientEvents } from '#lib'; +import { AuditLogEvent, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; export default class ModlogSyncBanListener extends BushListener { public constructor() { @@ -43,7 +41,7 @@ export default class ModlogSyncBanListener extends BushListener { const { log } = await Moderation.createModLogEntry({ type: ModLogType.PERM_BAN, user: ban.user, - moderator: <BushUser>first.executor, + moderator: first.executor, reason: `[Manual] ${first.reason ? first.reason : 'No reason given'}`, guild: ban.guild }); diff --git a/src/listeners/track-manual-punishments/modlogSyncKick.ts b/src/listeners/track-manual-punishments/modlogSyncKick.ts index 7a2c154..d136780 100644 --- a/src/listeners/track-manual-punishments/modlogSyncKick.ts +++ b/src/listeners/track-manual-punishments/modlogSyncKick.ts @@ -1,6 +1,5 @@ -import { BushListener, BushUser, Moderation, ModLogType, Time, type BushClientEvents } from '#lib'; -import { AuditLogEvent } from 'discord-api-types/v10'; -import { EmbedBuilder, PermissionFlagsBits } from 'discord.js'; +import { BushListener, Moderation, ModLogType, Time, type BushClientEvents } from '#lib'; +import { AuditLogEvent, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; export default class ModlogSyncKickListener extends BushListener { public constructor() { @@ -42,7 +41,7 @@ export default class ModlogSyncKickListener extends BushListener { const { log } = await Moderation.createModLogEntry({ type: ModLogType.KICK, user: member.user, - moderator: <BushUser>first.executor, + moderator: first.executor, reason: `[Manual] ${first.reason ? first.reason : 'No reason given'}`, guild: member.guild }); diff --git a/src/listeners/track-manual-punishments/modlogSyncTimeout.ts b/src/listeners/track-manual-punishments/modlogSyncTimeout.ts index f6235a9..adcd7fe 100644 --- a/src/listeners/track-manual-punishments/modlogSyncTimeout.ts +++ b/src/listeners/track-manual-punishments/modlogSyncTimeout.ts @@ -1,6 +1,5 @@ -import { BushListener, BushUser, Moderation, ModLogType, Time, type BushClientEvents } from '#lib'; -import { AuditLogEvent } from 'discord-api-types/v10'; -import { EmbedBuilder, PermissionFlagsBits } from 'discord.js'; +import { BushListener, Moderation, ModLogType, Time, type BushClientEvents } from '#lib'; +import { AuditLogEvent, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; export default class ModlogSyncTimeoutListener extends BushListener { public constructor() { @@ -46,7 +45,7 @@ export default class ModlogSyncTimeoutListener extends BushListener { const { log } = await Moderation.createModLogEntry({ type: newTime ? ModLogType.TIMEOUT : ModLogType.REMOVE_TIMEOUT, user: newMember.user, - moderator: <BushUser>first.executor, + moderator: first.executor, reason: `[Manual] ${first.reason ? first.reason : 'No reason given'}`, guild: newMember.guild, duration: newTime ? newTime.getTime() - now.getTime() : undefined diff --git a/src/listeners/track-manual-punishments/modlogSyncUnban.ts b/src/listeners/track-manual-punishments/modlogSyncUnban.ts index cdf18d9..af0b21f 100644 --- a/src/listeners/track-manual-punishments/modlogSyncUnban.ts +++ b/src/listeners/track-manual-punishments/modlogSyncUnban.ts @@ -1,7 +1,5 @@ -import { BushListener, BushUser, Moderation, ModLogType, Time, type BushClientEvents } from '#lib'; -import { EmbedBuilder } from '@discordjs/builders'; -import { AuditLogEvent } from 'discord-api-types/v10'; -import { PermissionFlagsBits } from 'discord.js'; +import { BushListener, Moderation, ModLogType, Time, type BushClientEvents } from '#lib'; +import { AuditLogEvent, EmbedBuilder, PermissionFlagsBits } from 'discord.js'; export default class ModlogSyncUnbanListener extends BushListener { public constructor() { @@ -42,7 +40,7 @@ export default class ModlogSyncUnbanListener extends BushListener { const { log } = await Moderation.createModLogEntry({ type: ModLogType.UNBAN, user: ban.user, - moderator: <BushUser>first.executor, + moderator: first.executor, reason: `[Manual] ${first.reason ? first.reason : 'No reason given'}`, guild: ban.guild }); diff --git a/src/listeners/ws/INTERACTION_CREATE.ts b/src/listeners/ws/INTERACTION_CREATE.ts index d3ca70c..408e7e5 100644 --- a/src/listeners/ws/INTERACTION_CREATE.ts +++ b/src/listeners/ws/INTERACTION_CREATE.ts @@ -1,22 +1,25 @@ -import { BushListener, BushUser, Moderation, PunishmentTypePresent } from '#lib'; -import { EmbedBuilder } from '@discordjs/builders'; +import { BushListener, Moderation, PunishmentTypePresent } from '#lib'; import assert from 'assert'; import { - APIEmbed, - APIInteraction, - APIInteractionResponseChannelMessageWithSource, - APIInteractionResponseDeferredMessageUpdate, - APIInteractionResponseUpdateMessage, - APIModalInteractionResponse, + ActionRowBuilder, + ButtonBuilder, ButtonStyle, ComponentType, + EmbedBuilder, GatewayDispatchEvents, InteractionResponseType, InteractionType, Routes, - TextInputStyle -} from 'discord-api-types/v10'; -import { ActionRowBuilder, ButtonBuilder, Snowflake } from 'discord.js'; + Snowflake, + TextInputStyle, + User, + type APIEmbed, + type APIInteraction, + type APIInteractionResponseChannelMessageWithSource, + type APIInteractionResponseDeferredMessageUpdate, + type APIInteractionResponseUpdateMessage, + type APIModalInteractionResponse +} from 'discord.js'; export default class WsInteractionCreateListener extends BushListener { public constructor() { @@ -188,7 +191,7 @@ export default class WsInteractionCreateListener extends BushListener { }); assert(interaction.user); - const user = new BushUser(client, interaction.user as any); + const user = new User(client, interaction.user); assert(user); // const caseId = await ModLog.findOne({ where: { user: userId, guild: guildId, id: modlogCase } }); diff --git a/src/tasks/removeExpiredPunishements.ts b/src/tasks/removeExpiredPunishements.ts index cba939e..6b36473 100644 --- a/src/tasks/removeExpiredPunishements.ts +++ b/src/tasks/removeExpiredPunishements.ts @@ -1,4 +1,4 @@ -import { ActivePunishment, ActivePunishmentType, BushTask, Time, type BushGuild, type BushUser } from '#lib'; +import { ActivePunishment, ActivePunishmentType, BushTask, Time } from '#lib'; import assert from 'assert'; const { Op } = (await import('sequelize')).default; @@ -25,13 +25,13 @@ export default class RemoveExpiredPunishmentsTask extends BushTask { ); for (const entry of expiredEntries) { - const guild = client.guilds.cache.get(entry.guild) as BushGuild; + const guild = client.guilds.cache.get(entry.guild); if (!guild) continue; // eslint-disable-next-line @typescript-eslint/no-misused-promises setTimeout(async () => { const member = guild.members.cache.get(entry.user); - const user = (await util.resolveNonCachedUser(entry.user)) as BushUser; + const user = await util.resolveNonCachedUser(entry.user); assert(guild); switch (entry.type) { @@ -14,9 +14,9 @@ __metadata: languageName: node linkType: hard -"@discordjs/builders@npm:^0.14.0-dev": - version: 0.14.0 - resolution: "@discordjs/builders@npm:0.14.0" +"@discordjs/builders@npm:^0.15.0": + version: 0.15.0 + resolution: "@discordjs/builders@npm:0.15.0" dependencies: "@sapphire/shapeshift": ^3.1.0 "@sindresorhus/is": ^4.6.0 @@ -24,32 +24,39 @@ __metadata: fast-deep-equal: ^3.1.3 ts-mixer: ^6.0.1 tslib: ^2.4.0 - checksum: 044f1864bc5a027c6a4021cc428e98362a8466d7539ae4ec17681157ffc3e9a36a5a8f52b8874eabff11c5d6dca9f7870c516d27d8e090a05a9b23eeb81d6bb8 + checksum: 1a8a4ffe048243ebb9fbbc76a113e4994c68904a5b3d256a6b10c0123f1d0fb58b45809d134ba993293fb2190c9f3506663ddfb5068a86ec6b9c53b5db61f6a6 languageName: node linkType: hard -"@discordjs/builders@npm:^0.15.0": - version: 0.15.0 - resolution: "@discordjs/builders@npm:0.15.0" +"@discordjs/builders@npm:^0.16.0-dev": + version: 0.16.0-dev.1655165432-b4e28a8 + resolution: "@discordjs/builders@npm:0.16.0-dev.1655165432-b4e28a8" dependencies: "@sapphire/shapeshift": ^3.1.0 "@sindresorhus/is": ^4.6.0 - discord-api-types: ^0.33.3 + discord-api-types: ^0.33.5 fast-deep-equal: ^3.1.3 ts-mixer: ^6.0.1 tslib: ^2.4.0 - checksum: 1a8a4ffe048243ebb9fbbc76a113e4994c68904a5b3d256a6b10c0123f1d0fb58b45809d134ba993293fb2190c9f3506663ddfb5068a86ec6b9c53b5db61f6a6 + checksum: 6e1f10093a61d942e953380b081a5f7a63e5e5db5c2c3e943a21a34a240eb04bf9c8659d3c68f9c8585fc7518dabe28f0795287a70134752c568057be0ecf81c languageName: node linkType: hard -"@discordjs/collection@npm:^0.7.0, @discordjs/collection@npm:^0.7.0-dev": +"@discordjs/collection@npm:^0.7.0": version: 0.7.0 resolution: "@discordjs/collection@npm:0.7.0" checksum: 141aa35a5433bacba3617b533557b4948388c7b59cdaecee51ccd721c1b9242e50d95bdef53ee2491535a017095f5072ace3c3e9e594193f67a1c5a8a4b7db93 languageName: node linkType: hard -"@discordjs/rest@npm:^0.5.0, @discordjs/rest@npm:^0.5.0-dev": +"@discordjs/collection@npm:^0.8.0-dev": + version: 0.8.0-dev.1655165444-b4e28a8 + resolution: "@discordjs/collection@npm:0.8.0-dev.1655165444-b4e28a8" + checksum: 3a505484e6bc1a85fd891c5f934224b70696988b612c8db4dceec203d7e0a9856545124674a2fa069a6470c88254e601ef20876e1cb8cc6ec80282cc0f52f6c2 + languageName: node + linkType: hard + +"@discordjs/rest@npm:^0.5.0": version: 0.5.0 resolution: "@discordjs/rest@npm:0.5.0" dependencies: @@ -63,6 +70,20 @@ __metadata: languageName: node linkType: hard +"@discordjs/rest@npm:^0.6.0-dev": + version: 0.6.0-dev.1655165427-b4e28a8 + resolution: "@discordjs/rest@npm:0.6.0-dev.1655165427-b4e28a8" + dependencies: + "@discordjs/collection": ^0.8.0-dev + "@sapphire/async-queue": ^1.3.1 + "@sapphire/snowflake": ^3.2.2 + discord-api-types: ^0.33.5 + tslib: ^2.4.0 + undici: ^5.4.0 + checksum: 8ea6857fb3c00220ca1ceafd15aa34ec3b3864a04359269fe35f0a991009475f7da1e743e1e821bf46de7e7b78c7e11b88f6db28e728fdc15e2518a862c87fd6 + languageName: node + linkType: hard + "@eslint/eslintrc@npm:^1.3.0": version: 1.3.0 resolution: "@eslint/eslintrc@npm:1.3.0" @@ -214,13 +235,13 @@ __metadata: linkType: hard "@sapphire/shapeshift@npm:^3.1.0": - version: 3.1.0 - resolution: "@sapphire/shapeshift@npm:3.1.0" - checksum: d28035fe9dd2b59feda24daad4ae5f3ae16bf98312e726df85c79cf071de3447a2a0e81f818471a7abb8d6678423e7e6ece57687d162269624e503e62cae26a4 + version: 3.2.0 + resolution: "@sapphire/shapeshift@npm:3.2.0" + checksum: 166c590e66e222f20bc92e21b50390b687eca5c948a4bbf6a4cf8745189fa35972f41b1022a3a35c4e0f2e2c808232f18f46ddb1db12b84c10bd1c9145740ff0 languageName: node linkType: hard -"@sapphire/snowflake@npm:^3.2.1, @sapphire/snowflake@npm:^3.2.2": +"@sapphire/snowflake@npm:^3.2.2": version: 3.2.2 resolution: "@sapphire/snowflake@npm:3.2.2" checksum: 315fecef4738092c2a2f3509b132b811fcbfa6c98d5d45d951adaf3ca21608be69043bcc137cc6933a7c3e55cbdc066daa5bb484603e6575422b335445b59315 @@ -590,13 +611,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^5.27.1": - version: 5.27.1 - resolution: "@typescript-eslint/eslint-plugin@npm:5.27.1" +"@typescript-eslint/eslint-plugin@npm:^5.28.0": + version: 5.28.0 + resolution: "@typescript-eslint/eslint-plugin@npm:5.28.0" dependencies: - "@typescript-eslint/scope-manager": 5.27.1 - "@typescript-eslint/type-utils": 5.27.1 - "@typescript-eslint/utils": 5.27.1 + "@typescript-eslint/scope-manager": 5.28.0 + "@typescript-eslint/type-utils": 5.28.0 + "@typescript-eslint/utils": 5.28.0 debug: ^4.3.4 functional-red-black-tree: ^1.0.1 ignore: ^5.2.0 @@ -609,53 +630,53 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: ee00d8d3a7b395e346801b7bf30209e278f06b5c283ad71c03b34db9e2d68a43ca0e292e315fa7e5bf131a8839ff4a24e0ed76c37811d230f97aae7e123d73ea + checksum: 49e08865abd35acdc44829b929f2cd01d01a1f91d3c3c357963b6980e938de365f178efcec21e0ed6ec13a2ad9373f52b73001ddd5cdc7b0245fcf02b9564dd3 languageName: node linkType: hard "@typescript-eslint/experimental-utils@npm:^5.0.0": - version: 5.27.1 - resolution: "@typescript-eslint/experimental-utils@npm:5.27.1" + version: 5.28.0 + resolution: "@typescript-eslint/experimental-utils@npm:5.28.0" dependencies: - "@typescript-eslint/utils": 5.27.1 + "@typescript-eslint/utils": 5.28.0 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 180c1dc79b5c0e954eb9ab9c449eec3a5a808f3c5b21ead9661feb542e41c186f49c6da42a7197c2c6e2614a71dadb328ff10e2eaf87bfc317fb03de02e16c8f + checksum: 500c5955621f0b15d69c32c068ad64c7121f1343887c347140943a353909bb6c00242d6fcb3ea36fd3de004a76a2d4e07d9a08c5a09bcec989d17e987ed2e3f5 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^5.27.1": - version: 5.27.1 - resolution: "@typescript-eslint/parser@npm:5.27.1" +"@typescript-eslint/parser@npm:^5.28.0": + version: 5.28.0 + resolution: "@typescript-eslint/parser@npm:5.28.0" dependencies: - "@typescript-eslint/scope-manager": 5.27.1 - "@typescript-eslint/types": 5.27.1 - "@typescript-eslint/typescript-estree": 5.27.1 + "@typescript-eslint/scope-manager": 5.28.0 + "@typescript-eslint/types": 5.28.0 + "@typescript-eslint/typescript-estree": 5.28.0 debug: ^4.3.4 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 0f1df76142c9d7a6c6dbfc5d19fdee02bbc0e79def6e6df4b126c7eaae1c3a46a3871ad498d4b1fc7ad5cb58d6eb70f020807f600d99c0b9add98441fc12f23b + checksum: cb18ff47b0a10373ba1c05c90901d08f5f99180e624f3f2faa85f13d1048fc59601a3cab6b852f72d13287b314d94c4d4997129ff6c639496a9144c762f6d31e languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.27.1": - version: 5.27.1 - resolution: "@typescript-eslint/scope-manager@npm:5.27.1" +"@typescript-eslint/scope-manager@npm:5.28.0": + version: 5.28.0 + resolution: "@typescript-eslint/scope-manager@npm:5.28.0" dependencies: - "@typescript-eslint/types": 5.27.1 - "@typescript-eslint/visitor-keys": 5.27.1 - checksum: 401bf2b46de08ddb80ec9f36df7d58bf5de7837185a472b190b670d421d685743aad4c9fa8a6893f65ba933b822c5d7060c640e87cf0756d7aa56abdd25689cc + "@typescript-eslint/types": 5.28.0 + "@typescript-eslint/visitor-keys": 5.28.0 + checksum: f187fd295d152508aa85233ef3ac89031952300fbbe277e188dfba3fbfd82656b15d3d8daa6d85984970ce00a30fdf75da912c4024df982004b24f3a95420b8f languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.27.1": - version: 5.27.1 - resolution: "@typescript-eslint/type-utils@npm:5.27.1" +"@typescript-eslint/type-utils@npm:5.28.0": + version: 5.28.0 + resolution: "@typescript-eslint/type-utils@npm:5.28.0" dependencies: - "@typescript-eslint/utils": 5.27.1 + "@typescript-eslint/utils": 5.28.0 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -663,23 +684,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 43b7da26ea1bd7d249c45d168ec88f971fb71362bbc21ec4748d73b1ecb43f4ca59f5ed338e8dbc74272ae4ebac1cab87a9b62c0fa616c6f9bd833a212dc8a40 + checksum: 05563dab5414a42b7781f5ce65ee540b10a946c419bde3fbc45593aa3b1225b2a70558581f311720d670dc82ab699a3f9ecb4b1447d6fd557bd330cf8890d8ca languageName: node linkType: hard -"@typescript-eslint/types@npm:5.27.1": - version: 5.27.1 - resolution: "@typescript-eslint/types@npm:5.27.1" - checksum: 81faa50256ba67c23221273744c51676774fe6a1583698c3a542f3e2fd21ab34a4399019527c9cf7ab4e5a1577272f091d5848d3af937232ddb2dbf558a7c39a +"@typescript-eslint/types@npm:5.28.0": + version: 5.28.0 + resolution: "@typescript-eslint/types@npm:5.28.0" + checksum: e948915d6f24ece98043763a48e34ced5e16a1aa88cc86ea7d9057010ed92ce39457a753dd7a140be52f9b546b27f8a3b33bdc7d671427a386aa1aa381d908ef languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.27.1": - version: 5.27.1 - resolution: "@typescript-eslint/typescript-estree@npm:5.27.1" +"@typescript-eslint/typescript-estree@npm:5.28.0": + version: 5.28.0 + resolution: "@typescript-eslint/typescript-estree@npm:5.28.0" dependencies: - "@typescript-eslint/types": 5.27.1 - "@typescript-eslint/visitor-keys": 5.27.1 + "@typescript-eslint/types": 5.28.0 + "@typescript-eslint/visitor-keys": 5.28.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -688,33 +709,33 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 59d2a0885be7d54bd86472a446d84930cc52d2690ea432d9164075ea437b3b4206dadd49799764ad0fb68f3e4ebb4e36db9717c7a443d0f3c82d5659e41fbd05 + checksum: e7be6e9ff778ab2728bdc545713f29cd40bbe1282662461453fe46bc18f676f9b33c60e3514347fbc4e5e94d764525c20b8ef3d47baa62fec6bd3ce05fdde6eb languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.27.1": - version: 5.27.1 - resolution: "@typescript-eslint/utils@npm:5.27.1" +"@typescript-eslint/utils@npm:5.28.0": + version: 5.28.0 + resolution: "@typescript-eslint/utils@npm:5.28.0" dependencies: "@types/json-schema": ^7.0.9 - "@typescript-eslint/scope-manager": 5.27.1 - "@typescript-eslint/types": 5.27.1 - "@typescript-eslint/typescript-estree": 5.27.1 + "@typescript-eslint/scope-manager": 5.28.0 + "@typescript-eslint/types": 5.28.0 + "@typescript-eslint/typescript-estree": 5.28.0 eslint-scope: ^5.1.1 eslint-utils: ^3.0.0 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 51add038226cddad2b3322225de18d53bc1ed44613f7b3a379eb597114b8830a632990b0f4321e0ddf3502b460d80072d7e789be89135b5e11e8dae167005625 + checksum: d30958552470c3f46b2183b690fa8c922a375a84ef83ccfda4785148b8dafb7bf428ab01de6608f67cefbcae35c6a2b0c54b5a6a89bba31566ec3b41f098c02e languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.27.1": - version: 5.27.1 - resolution: "@typescript-eslint/visitor-keys@npm:5.27.1" +"@typescript-eslint/visitor-keys@npm:5.28.0": + version: 5.28.0 + resolution: "@typescript-eslint/visitor-keys@npm:5.28.0" dependencies: - "@typescript-eslint/types": 5.27.1 + "@typescript-eslint/types": 5.28.0 eslint-visitor-keys: ^3.3.0 - checksum: 8f104eda321cd6c613daf284fbebbd32b149d4213d137b0ce1caec7a1334c9f46c82ed64aff1243b712ac8c13f67ac344c996cd36d21fbb15032c24d9897a64a + checksum: e97251968ea273ce33fa0de8a9c04426499b797f6f7800379ff880c4be6e6e02fe023038be0092c595be394a8636f73ee8911974214d5232b3d59492a50771bf languageName: node linkType: hard @@ -1031,13 +1052,13 @@ __metadata: "@types/rimraf": ^3.0.2 "@types/tinycolor2": ^1.4.3 "@types/validator": ^13.7.3 - "@typescript-eslint/eslint-plugin": ^5.27.1 - "@typescript-eslint/parser": ^5.27.1 + "@typescript-eslint/eslint-plugin": ^5.28.0 + "@typescript-eslint/parser": ^5.28.0 canvas: ^2.9.1 chalk: ^5.0.1 deep-lock: ^1.0.0 discord-akairo: "npm:@notenoughupdates/discord-akairo@dev" - discord-api-types: 0.33.5 + discord-api-types: 0.34.0 discord.js: "npm:@notenoughupdates/discord.js@dev" eslint: ^8.17.0 eslint-config-prettier: ^8.5.0 @@ -1045,17 +1066,17 @@ __metadata: eslint-plugin-import: ^2.26.0 fuse.js: ^6.6.2 gif-to-apng: ^0.1.2 - googleapis: ^101.0.0 + googleapis: ^102.0.0 got: ^12.1.0 lodash: ^4.17.21 mathjs: ^10.6.1 nanoid: ^4.0.0 node-fetch: ^3.2.6 - node-os-utils: ^1.3.6 + node-os-utils: ^1.3.7 numeral: ^2.0.6 pg: ^8.7.3 pg-hstore: ^2.3.4 - prettier: ^2.6.2 + prettier: ^2.7.0 pretty-bytes: ^6.0.0 rimraf: ^3.0.2 sequelize: 6.20.1 @@ -1468,13 +1489,20 @@ __metadata: linkType: hard "discord-akairo@npm:@notenoughupdates/discord-akairo@dev": - version: 9.1.3-dev.1653854301.456923a - resolution: "@notenoughupdates/discord-akairo@npm:9.1.3-dev.1653854301.456923a" - checksum: 0a53fecf84daade8a3aac16b2f9c968149501c70add3ec59591783eff79d60803c52842067ecc9984fcacc5548807c1b57ff4f2d6309657ad5db365443a39368 + version: 9.1.3-dev.1655212954.1d6b00f + resolution: "@notenoughupdates/discord-akairo@npm:9.1.3-dev.1655212954.1d6b00f" + checksum: 0d17ecd941d594723dd1d82f75bf48a007c030798466400d47d88352766d46b25ed310fb5b946da363cd7b6d84727cf65ea1035883caf4ed35f25dbd7e8d30e4 languageName: node linkType: hard -"discord-api-types@npm:0.33.5, discord-api-types@npm:^0.33.0, discord-api-types@npm:^0.33.3": +"discord-api-types@npm:0.34.0": + version: 0.34.0 + resolution: "discord-api-types@npm:0.34.0" + checksum: 16ef4a7e82c442808447d2062adb907c050f1c0b10b0dd7ffd459b5cbc2ae8e5ba46d17c645e401500a0263ee661c651d29ab5b41bd2af15a72281d03cba90dc + languageName: node + linkType: hard + +"discord-api-types@npm:^0.33.3, discord-api-types@npm:^0.33.5": version: 0.33.5 resolution: "discord-api-types@npm:0.33.5" checksum: 6dcaad640c5693a69c9a4f5e444e739dde11ba835164ae6fd3dd5a1ab7b4d7f96cd022ed653eeaff2c8051ead0d998a5d502a2915cfacdde596364b82d9e3b3f @@ -1482,21 +1510,21 @@ __metadata: linkType: hard "discord.js@npm:@notenoughupdates/discord.js@dev": - version: 14.0.0-dev.1653272547-60b1118 - resolution: "@notenoughupdates/discord.js@npm:14.0.0-dev.1653272547-60b1118" + version: 14.0.0-dev.1655126646-6dfc4f06d + resolution: "@notenoughupdates/discord.js@npm:14.0.0-dev.1655126646-6dfc4f06d" dependencies: - "@discordjs/builders": ^0.14.0-dev - "@discordjs/collection": ^0.7.0-dev - "@discordjs/rest": ^0.5.0-dev - "@sapphire/snowflake": ^3.2.1 + "@discordjs/builders": ^0.16.0-dev + "@discordjs/collection": ^0.8.0-dev + "@discordjs/rest": ^0.6.0-dev + "@sapphire/snowflake": ^3.2.2 "@types/ws": ^8.5.3 - discord-api-types: ^0.33.0 + discord-api-types: ^0.33.5 fast-deep-equal: ^3.1.3 lodash.snakecase: ^4.1.1 - tslib: ^2.3.1 - undici: ^5.2.0 - ws: ^8.5.0 - checksum: 4151631e445e282772af1dd69d53a8f350470ac8e9a3a77d106c591a7ead83e2a77e5e9db91b97999e6e77004e782e8667dbabe7cd2da5788b87674303d44c2e + tslib: ^2.4.0 + undici: ^5.4.0 + ws: ^8.8.0 + checksum: ad0e12b2c99232a7e5b8f728b0a29c61832e5ad9507b5fa24835a593b7ba0639107d16eb15d4354bd20296127331af4fdfe0617640224b8433f775cfd126cf63 languageName: node linkType: hard @@ -2338,13 +2366,13 @@ __metadata: languageName: node linkType: hard -"googleapis@npm:^101.0.0": - version: 101.0.0 - resolution: "googleapis@npm:101.0.0" +"googleapis@npm:^102.0.0": + version: 102.0.0 + resolution: "googleapis@npm:102.0.0" dependencies: google-auth-library: ^8.0.2 googleapis-common: ^6.0.0 - checksum: ee0b2d3b2250195231f016a951696422233bcf80387624e7ae17f7693352ec1031b7ce6f2f068a3511147405b2e1eb3ba9f53bce13dd46210e6cf3b24e7723f7 + checksum: 599cb57d00f623ea968aaa8e75f421d29545b3b2e0a29b454165839db25379a793a338c71e1235c8f4e8f9f4f01c4b33b6e98bbd46e05e720631ac77a09d64b4 languageName: node linkType: hard @@ -3297,10 +3325,10 @@ __metadata: languageName: node linkType: hard -"node-os-utils@npm:^1.3.6": - version: 1.3.6 - resolution: "node-os-utils@npm:1.3.6" - checksum: 8ce66b648061dff3978c6e63ca7fa8748b285d28a5ebb57c6e6ce2250c34d8be408344d24a79590725a542eb4b6b297b1fa32ac6d73d85a3871b16afa204df6c +"node-os-utils@npm:^1.3.7": + version: 1.3.7 + resolution: "node-os-utils@npm:1.3.7" + checksum: 4059d74def168e2ffcd28e879731fd68f6e9b1e623804224e34bf0ca3c8968070e9e2cbc0cb57d80dd05d27552495a65c865b93ae5f54e61389e5af0b92ee818 languageName: node linkType: hard @@ -3697,12 +3725,12 @@ __metadata: languageName: node linkType: hard -"prettier@npm:^2.6.2": - version: 2.6.2 - resolution: "prettier@npm:2.6.2" +"prettier@npm:^2.7.0": + version: 2.7.0 + resolution: "prettier@npm:2.7.0" bin: prettier: bin-prettier.js - checksum: 48d08dde8e9fb1f5bccdd205baa7f192e9fc8bc98f86e1b97d919de804e28c806b0e6cc685e4a88211aa7987fa9668f30baae19580d87ced3ed0f2ec6572106f + checksum: 5b55bb1dced9d16635b83229df8e670d150890fdb343f19e8a66e610094a108e960c0f57352b3e5cdbc4eff4ef00a834406047ffcd9f20bd22a6497ba143c81f languageName: node linkType: hard @@ -4468,10 +4496,10 @@ __metadata: languageName: node linkType: hard -"undici@npm:^5.2.0, undici@npm:^5.4.0": - version: 5.4.0 - resolution: "undici@npm:5.4.0" - checksum: 2852397ee1dbb2b3ad58166520ec30f4f0143895f6e7b157dbedfac4e43b522a710a3927be61a67b2ae791190973f206d30785564ece7675e08133427cebaaa1 +"undici@npm:^5.4.0": + version: 5.5.1 + resolution: "undici@npm:5.5.1" + checksum: c041c9093df7ec683479a9555581206a7c7bebfc1ed6e8669920e55618461fc4ce08938e2fbf8ef7d692c2813c44392b5ed25c58396ee4a72ffd1f1f953712c9 languageName: node linkType: hard @@ -4642,7 +4670,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.5.0": +"ws@npm:^8.8.0": version: 8.8.0 resolution: "ws@npm:8.8.0" peerDependencies: |