aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package.json5
-rw-r--r--src/arguments/abbreviatedNumber.ts2
-rw-r--r--src/arguments/contentWithDuration.ts2
-rw-r--r--src/arguments/discordEmoji.ts2
-rw-r--r--src/arguments/duration.ts2
-rw-r--r--src/arguments/durationSeconds.ts2
-rw-r--r--src/arguments/globalUser.ts2
-rw-r--r--src/arguments/index.ts10
-rw-r--r--src/arguments/messageLink.ts3
-rw-r--r--src/arguments/permission.ts2
-rw-r--r--src/arguments/roleWithDuration.ts2
-rw-r--r--src/arguments/snowflake.ts2
-rw-r--r--src/commands/admin/channelPermissions.ts8
-rw-r--r--src/commands/admin/roleAll.ts6
-rw-r--r--src/commands/config/blacklist.ts6
-rw-r--r--src/commands/config/config.ts12
-rw-r--r--src/commands/config/disable.ts4
-rw-r--r--src/commands/config/log.ts8
-rw-r--r--src/commands/dev/__template.ts1
-rw-r--r--src/commands/dev/dm.ts7
-rw-r--r--src/commands/dev/eval.ts4
-rw-r--r--src/commands/dev/javascript.ts4
-rw-r--r--src/commands/dev/superUser.ts5
-rw-r--r--src/commands/fun/minesweeper.ts10
-rw-r--r--src/commands/info/avatar.ts6
-rw-r--r--src/commands/info/color.ts6
-rw-r--r--src/commands/info/guildInfo.ts9
-rw-r--r--src/commands/info/help.ts4
-rw-r--r--src/commands/info/pronouns.ts7
-rw-r--r--src/commands/info/snowflake.ts5
-rw-r--r--src/commands/info/userInfo.ts6
-rw-r--r--src/commands/leveling/leaderboard.ts4
-rw-r--r--src/commands/leveling/level.ts3
-rw-r--r--src/commands/leveling/setLevel.ts8
-rw-r--r--src/commands/leveling/setXp.ts8
-rw-r--r--src/commands/moderation/ban.ts18
-rw-r--r--src/commands/moderation/kick.ts4
-rw-r--r--src/commands/moderation/modlog.ts28
-rw-r--r--src/commands/moderation/mute.ts4
-rw-r--r--src/commands/moderation/purge.ts4
-rw-r--r--src/commands/moderation/removeReactionEmoji.ts9
-rw-r--r--src/commands/moderation/role.ts18
-rw-r--r--src/commands/moderation/slowmode.ts15
-rw-r--r--src/commands/moderation/unban.ts7
-rw-r--r--src/commands/moderation/unmute.ts7
-rw-r--r--src/commands/moderation/warn.ts7
-rw-r--r--src/commands/moulberry-bush/capePerms.ts4
-rw-r--r--src/commands/moulberry-bush/capes.ts4
-rw-r--r--src/commands/moulberry-bush/moulHammer.ts6
-rw-r--r--src/commands/moulberry-bush/report.ts6
-rw-r--r--src/commands/moulberry-bush/rule.ts13
-rw-r--r--src/commands/utilities/activity.ts6
-rw-r--r--src/commands/utilities/steal.ts6
-rw-r--r--src/commands/utilities/uuid.ts5
-rw-r--r--src/commands/utilities/viewRaw.ts23
-rw-r--r--src/commands/utilities/whoHasRole.ts6
-rw-r--r--src/lib/extensions/discord-akairo/BushClientUtil.ts5
-rw-r--r--src/lib/extensions/discord-akairo/BushCommand.ts121
-rw-r--r--src/lib/extensions/discord-akairo/BushSlashMessage.ts16
-rw-r--r--tsconfig.json29
60 files changed, 371 insertions, 177 deletions
diff --git a/package.json b/package.json
index f8a756f..8d7b80d 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,9 @@
"imports": {
"#lib": {
"default": "./src/lib/index.js"
+ },
+ "#args": {
+ "default": "./src/arguments/index.js"
}
},
"scripts": {
@@ -100,4 +103,4 @@
"eslint-plugin-deprecation": "^1.3.2"
},
"packageManager": "yarn@3.1.1"
-}
+} \ No newline at end of file
diff --git a/src/arguments/abbreviatedNumber.ts b/src/arguments/abbreviatedNumber.ts
index 3a447d7..3027cb2 100644
--- a/src/arguments/abbreviatedNumber.ts
+++ b/src/arguments/abbreviatedNumber.ts
@@ -1,7 +1,7 @@
import { type BushArgumentTypeCaster } from '#lib';
import numeral from 'numeral';
-export const abbreviatedNumber: BushArgumentTypeCaster = (_, phrase): number | null => {
+export const abbreviatedNumber: BushArgumentTypeCaster<number | null> = (_, phrase) => {
if (!phrase) return null;
const num = numeral(phrase?.toLowerCase()).value();
diff --git a/src/arguments/contentWithDuration.ts b/src/arguments/contentWithDuration.ts
index 41cb9bb..3d87061 100644
--- a/src/arguments/contentWithDuration.ts
+++ b/src/arguments/contentWithDuration.ts
@@ -1,5 +1,5 @@
import { ParsedDuration, type BushArgumentTypeCaster } from '#lib';
-export const contentWithDuration: BushArgumentTypeCaster = async (_, phrase): Promise<ParsedDuration> => {
+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 a3c531c..d9428e1 100644
--- a/src/arguments/discordEmoji.ts
+++ b/src/arguments/discordEmoji.ts
@@ -1,7 +1,7 @@
import { type BushArgumentTypeCaster } from '#lib';
import { type Snowflake } from 'discord-api-types';
-export const discordEmoji: BushArgumentTypeCaster = (_, phrase): DiscordEmojiInfo | null => {
+export const discordEmoji: BushArgumentTypeCaster<DiscordEmojiInfo | null> = (_, phrase) => {
if (!phrase) return null;
const validEmoji: RegExpExecArray | null = client.consts.regex.discordEmoji.exec(phrase);
if (!validEmoji || !validEmoji.groups) return null;
diff --git a/src/arguments/duration.ts b/src/arguments/duration.ts
index 9cb1d03..58593ef 100644
--- a/src/arguments/duration.ts
+++ b/src/arguments/duration.ts
@@ -1,5 +1,5 @@
import { type BushArgumentTypeCaster } from '#lib';
-export const duration: BushArgumentTypeCaster = (_, phrase): number | null => {
+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 8cbfa21..74d136f 100644
--- a/src/arguments/durationSeconds.ts
+++ b/src/arguments/durationSeconds.ts
@@ -1,6 +1,6 @@
import { type BushArgumentTypeCaster } from '#lib';
-export const durationSeconds: BushArgumentTypeCaster = (_, phrase): number | null => {
+export const durationSeconds: BushArgumentTypeCaster<number | null> = (_, phrase) => {
phrase += 's';
return client.util.parseDuration(phrase).duration;
};
diff --git a/src/arguments/globalUser.ts b/src/arguments/globalUser.ts
index 081eabf..89e8324 100644
--- a/src/arguments/globalUser.ts
+++ b/src/arguments/globalUser.ts
@@ -1,7 +1,7 @@
import { BushUser, type BushArgumentTypeCaster } from '#lib';
// resolve non-cached users
-export const globalUser: BushArgumentTypeCaster = async (_, phrase): Promise<BushUser | null> => {
+export const globalUser: BushArgumentTypeCaster<Promise<BushUser | null>> = async (_, phrase) => {
return client.users.cache.has(phrase)
? client.users.cache.get(`${phrase}`) ?? null
: await client.users.fetch(`${phrase}`).catch(() => null);
diff --git a/src/arguments/index.ts b/src/arguments/index.ts
new file mode 100644
index 0000000..eebf0a2
--- /dev/null
+++ b/src/arguments/index.ts
@@ -0,0 +1,10 @@
+export * from './abbreviatedNumber.js';
+export * from './contentWithDuration.js';
+export * from './discordEmoji.js';
+export * from './duration.js';
+export * from './durationSeconds.js';
+export * from './globalUser.js';
+export * from './messageLink.js';
+export * from './permission.js';
+export * from './roleWithDuration.js';
+export * from './snowflake.js';
diff --git a/src/arguments/messageLink.ts b/src/arguments/messageLink.ts
index d270abd..80aacde 100644
--- a/src/arguments/messageLink.ts
+++ b/src/arguments/messageLink.ts
@@ -1,6 +1,7 @@
+import { Message } from 'discord.js';
import { type BushArgumentTypeCaster } from '../lib';
-export const messageLink: BushArgumentTypeCaster = async (_, phrase) => {
+export const messageLink: BushArgumentTypeCaster<Promise<Message | null>> = async (_, phrase) => {
const match = client.consts.regex.messageLink.exec(phrase);
if (!match || !match.groups) return null;
diff --git a/src/arguments/permission.ts b/src/arguments/permission.ts
index b5ff4bf..7a43216 100644
--- a/src/arguments/permission.ts
+++ b/src/arguments/permission.ts
@@ -1,7 +1,7 @@
import { type BushArgumentTypeCaster } from '#lib';
import { Permissions, PermissionString } from 'discord.js';
-export const permission: BushArgumentTypeCaster = (_, phrase): PermissionString | null => {
+export const permission: BushArgumentTypeCaster<PermissionString | null> = (_, phrase) => {
if (!phrase) return null;
phrase = phrase.toUpperCase().replace(/ /g, '_');
if (!(phrase in Permissions.FLAGS)) {
diff --git a/src/arguments/roleWithDuration.ts b/src/arguments/roleWithDuration.ts
index 999ac1c..b0357dd 100644
--- a/src/arguments/roleWithDuration.ts
+++ b/src/arguments/roleWithDuration.ts
@@ -1,7 +1,7 @@
import { type BushArgumentTypeCaster } from '#lib';
import { Role } from 'discord.js';
-export const roleWithDuration: BushArgumentTypeCaster = async (message, phrase): Promise<RoleWithDuration | null> => {
+export const roleWithDuration: BushArgumentTypeCaster<Promise<RoleWithDuration | null>> = async (message, phrase) => {
// eslint-disable-next-line prefer-const
let { duration, contentWithoutTime } = client.util.parseDuration(phrase);
if (contentWithoutTime === null || contentWithoutTime === undefined) return null;
diff --git a/src/arguments/snowflake.ts b/src/arguments/snowflake.ts
index 455ed63..15896ae 100644
--- a/src/arguments/snowflake.ts
+++ b/src/arguments/snowflake.ts
@@ -1,7 +1,7 @@
import { type BushArgumentTypeCaster } from '#lib';
import { type Snowflake } from 'discord.js';
-export const snowflake: BushArgumentTypeCaster = (_, phrase): Snowflake | null => {
+export const snowflake: BushArgumentTypeCaster<Snowflake | null> = (_, phrase) => {
if (!phrase) return null;
if (client.consts.regex.snowflake.test(phrase)) return phrase;
return null;
diff --git a/src/commands/admin/channelPermissions.ts b/src/commands/admin/channelPermissions.ts
index 17bea40..b94094c 100644
--- a/src/commands/admin/channelPermissions.ts
+++ b/src/commands/admin/channelPermissions.ts
@@ -1,5 +1,5 @@
-import { BushCommand, ButtonPaginator, type BushMessage, type BushSlashMessage } from '#lib';
-import { MessageEmbed, type GuildMember, type PermissionString, type Role } from 'discord.js';
+import { ArgType, BushCommand, ButtonPaginator, type BushMessage, type BushSlashMessage } from '#lib';
+import { MessageEmbed } from 'discord.js';
export default class ChannelPermissionsCommand extends BushCommand {
public constructor() {
@@ -57,8 +57,8 @@ export default class ChannelPermissionsCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
args: {
- target: Role | GuildMember;
- permission: PermissionString;
+ target: ArgType<'member'> | ArgType<'role'>;
+ permission: ArgType<'permission'>;
state: 'true' | 'false' | 'neutral';
}
) {
diff --git a/src/commands/admin/roleAll.ts b/src/commands/admin/roleAll.ts
index 585e6cc..a946e33 100644
--- a/src/commands/admin/roleAll.ts
+++ b/src/commands/admin/roleAll.ts
@@ -1,5 +1,5 @@
-import { AllowedMentions, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
-import { type GuildMember, type Role } from 'discord.js';
+import { AllowedMentions, ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { type GuildMember } from 'discord.js';
export default class RoleAllCommand extends BushCommand {
public constructor() {
@@ -37,7 +37,7 @@ export default class RoleAllCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { role: Role; bots: boolean }) {
+ public override async exec(message: BushMessage | BushSlashMessage, args: { role: ArgType<'role'>; bots: boolean }) {
if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be run in a server.`);
if (!message.member!.permissions.has('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/blacklist.ts b/src/commands/config/blacklist.ts
index a6e6a3d..d119774 100644
--- a/src/commands/config/blacklist.ts
+++ b/src/commands/config/blacklist.ts
@@ -1,5 +1,5 @@
-import { AllowedMentions, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
-import { GuildTextBasedChannel, User } from 'discord.js';
+import { AllowedMentions, ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { User } from 'discord.js';
export default class BlacklistCommand extends BushCommand {
public constructor() {
@@ -51,7 +51,7 @@ export default class BlacklistCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { action?: 'blacklist' | 'unblacklist'; target: GuildTextBasedChannel | User | string; global: boolean }
+ args: { action?: 'blacklist' | 'unblacklist'; target: ArgType<'channel'> | ArgType<'user'> | string; global: boolean }
) {
let action: 'blacklist' | 'unblacklist' | 'toggle' =
args.action ?? (message?.util?.parsed?.alias as 'blacklist' | 'unblacklist' | undefined) ?? 'toggle';
diff --git a/src/commands/config/config.ts b/src/commands/config/config.ts
index b88147d..9377dd0 100644
--- a/src/commands/config/config.ts
+++ b/src/commands/config/config.ts
@@ -1,4 +1,12 @@
-import { BushCommand, guildSettingsObj, settingsArr, type BushMessage, type BushSlashMessage, type GuildSettings } from '#lib';
+import {
+ ArgType,
+ BushCommand,
+ guildSettingsObj,
+ settingsArr,
+ type BushMessage,
+ type BushSlashMessage,
+ type GuildSettings
+} from '#lib';
import { type ArgumentOptions, type Flag } from 'discord-akairo';
import {
Channel,
@@ -172,7 +180,7 @@ export default class SettingsCommand extends BushCommand {
subcommandGroup?: GuildSettings;
action?: Action;
subcommand?: Action;
- value: string | Channel | Role;
+ value: ArgType<'channel'> | ArgType<'role'> | string;
}
) {
if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be used in servers.`);
diff --git a/src/commands/config/disable.ts b/src/commands/config/disable.ts
index 44c28d3..f6bce3a 100644
--- a/src/commands/config/disable.ts
+++ b/src/commands/config/disable.ts
@@ -1,4 +1,4 @@
-import { AllowedMentions, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { AllowedMentions, ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
export default class DisableCommand extends BushCommand {
private static blacklistedCommands = ['eval', 'disable'];
@@ -49,7 +49,7 @@ export default class DisableCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { action?: 'enable' | 'disable'; command: BushCommand | string; global: boolean }
+ args: { action?: 'enable' | 'disable'; command: ArgType<'commandAlias'> | string; global: boolean }
) {
let action = (args.action ?? message?.util?.parsed?.alias ?? 'toggle') as 'disable' | 'enable' | 'toggle';
const global = args.global && message.author.isOwner();
diff --git a/src/commands/config/log.ts b/src/commands/config/log.ts
index 52cb8f5..c61a6d5 100644
--- a/src/commands/config/log.ts
+++ b/src/commands/config/log.ts
@@ -1,6 +1,5 @@
-import { BushCommand, guildLogsArr, type BushMessage, type BushSlashMessage, type GuildLogType } from '#lib';
+import { ArgType, BushCommand, guildLogsArr, type BushMessage, type BushSlashMessage, type GuildLogType } from '#lib';
import { type ArgumentOptions, type Flag } from 'discord-akairo';
-import { type TextChannel } from 'discord.js';
export default class LogCommand extends BushCommand {
public constructor() {
@@ -62,7 +61,10 @@ export default class LogCommand extends BushCommand {
return { log_type, channel };
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { log_type: GuildLogType; channel: TextChannel }) {
+ public override async exec(
+ message: BushMessage | BushSlashMessage,
+ args: { log_type: GuildLogType; channel: ArgType<'textChannel'> }
+ ) {
if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be used in servers.`);
const currentLogs = await message.guild.getSetting('logChannels');
const oldChannel = currentLogs[args.log_type] ?? undefined;
diff --git a/src/commands/dev/__template.ts b/src/commands/dev/__template.ts
index 5bb29c8..4341198 100644
--- a/src/commands/dev/__template.ts
+++ b/src/commands/dev/__template.ts
@@ -36,6 +36,7 @@ export default class TemplateCommand extends BushCommand {
userPermissions: []
});
}
+
public override async exec(
message: BushMessage | BushSlashMessage,
args: { required_argument: string; optional_argument: string }
diff --git a/src/commands/dev/dm.ts b/src/commands/dev/dm.ts
index 5031dfd..4133b96 100644
--- a/src/commands/dev/dm.ts
+++ b/src/commands/dev/dm.ts
@@ -1,4 +1,4 @@
-import { BushCommand, BushUser, type BushMessage, type BushSlashMessage } from '#lib';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
export default class DMCommand extends BushCommand {
public constructor() {
@@ -11,7 +11,7 @@ export default class DMCommand extends BushCommand {
args: [
{
id: 'user',
- type: 'string',
+ type: 'user',
description: 'The user to send the dm to.',
prompt: 'Who would you like to dm?',
retry: '{error} Pick a valid user to send a dm to.',
@@ -20,6 +20,7 @@ export default class DMCommand extends BushCommand {
{
id: 'content',
type: 'string',
+ match: 'rest',
description: 'This is the second argument.',
prompt: 'What would you like to set your second argument to be?',
retry: '{error} Pick a valid argument.',
@@ -34,7 +35,7 @@ export default class DMCommand extends BushCommand {
userPermissions: []
});
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { user: BushUser; content: string }) {
+ public override async exec(message: BushMessage | BushSlashMessage, args: { user: ArgType<'user'>; content: string }) {
try {
const u = await client.users.fetch(args.user.id);
await u.send(args.content);
diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts
index 2393a9b..f97f00d 100644
--- a/src/commands/dev/eval.ts
+++ b/src/commands/dev/eval.ts
@@ -1,4 +1,4 @@
-import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
import { exec } from 'child_process';
import { MessageEmbed as _MessageEmbed } from 'discord.js';
import ts from 'typescript';
@@ -119,7 +119,7 @@ export default class EvalCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
args: {
- sel_depth: number;
+ sel_depth: ArgType<'integer'>;
code: string;
sudo: boolean;
silent: boolean;
diff --git a/src/commands/dev/javascript.ts b/src/commands/dev/javascript.ts
index d832c09..2a6a87b 100644
--- a/src/commands/dev/javascript.ts
+++ b/src/commands/dev/javascript.ts
@@ -1,4 +1,4 @@
-import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
import { MessageEmbed } from 'discord.js';
import { VM } from 'vm2';
@@ -51,7 +51,7 @@ export default class JavascriptCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
args: {
- sel_depth: number;
+ sel_depth: ArgType<'integer'>;
code: string;
}
) {
diff --git a/src/commands/dev/superUser.ts b/src/commands/dev/superUser.ts
index f38419f..35e98aa 100644
--- a/src/commands/dev/superUser.ts
+++ b/src/commands/dev/superUser.ts
@@ -1,6 +1,5 @@
-import { BushCommand, Global, type BushMessage, type BushSlashMessage } from '#lib';
+import { ArgType, BushCommand, Global, type BushMessage, type BushSlashMessage } from '#lib';
import { type ArgumentOptions, type Flag } from 'discord-akairo';
-import { type User } from 'discord.js';
export default class SuperUserCommand extends BushCommand {
public constructor() {
@@ -56,7 +55,7 @@ export default class SuperUserCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- { action, user }: { action: 'add' | 'remove'; user: User }
+ { action, user }: { 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.`);
diff --git a/src/commands/fun/minesweeper.ts b/src/commands/fun/minesweeper.ts
index 16352ce..0b6c89c 100644
--- a/src/commands/fun/minesweeper.ts
+++ b/src/commands/fun/minesweeper.ts
@@ -1,4 +1,4 @@
-import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
import { Minesweeper } from '@notenoughupdates/discord.js-minesweeper';
export default class MinesweeperCommand extends BushCommand {
@@ -67,7 +67,13 @@ export default class MinesweeperCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { rows: number; columns: number; mines: number; spaces: boolean; reveal_first_cell: boolean }
+ args: {
+ rows: ArgType<'integer'>;
+ columns: ArgType<'integer'>;
+ mines: ArgType<'integer'>;
+ spaces: boolean;
+ reveal_first_cell: boolean;
+ }
) {
const minesweeper = new Minesweeper({
rows: args.rows ?? 9,
diff --git a/src/commands/info/avatar.ts b/src/commands/info/avatar.ts
index 36504f8..3436b87 100644
--- a/src/commands/info/avatar.ts
+++ b/src/commands/info/avatar.ts
@@ -1,5 +1,5 @@
-import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
-import { GuildMember, MessageEmbed, type User } from 'discord.js';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { GuildMember, MessageEmbed } from 'discord.js';
export default class AvatarCommand extends BushCommand {
constructor() {
@@ -27,7 +27,7 @@ export default class AvatarCommand extends BushCommand {
});
}
- override async exec(message: BushMessage | BushSlashMessage, args: { user: GuildMember | User }) {
+ override async exec(message: BushMessage | BushSlashMessage, args: { user: ArgType<'member'> | ArgType<'globalUser'> }) {
const params: { size: 2048; format: 'png'; dynamic: true } = { size: 2048, format: 'png', dynamic: true };
const defaultAvatar = `https://cdn.discordapp.com/embed/avatars/${Math.ceil(Math.random() * 6) - 1}.png`;
diff --git a/src/commands/info/color.ts b/src/commands/info/color.ts
index 4277d56..2f9751b 100644
--- a/src/commands/info/color.ts
+++ b/src/commands/info/color.ts
@@ -1,5 +1,6 @@
import {
AllowedMentions,
+ ArgType,
BushArgumentTypeCaster,
BushCommand,
type BushGuildMember,
@@ -46,7 +47,10 @@ export default class ColorCommand extends BushCommand {
return color.substring(4, color.length - 5);
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { color: string | BushRole | BushGuildMember }) {
+ public override async exec(
+ message: BushMessage | BushSlashMessage,
+ args: { color: string | ArgType<'role'> | ArgType<'member'> }
+ ) {
const _color = message.util.isSlashMessage(message)
? ((await util.arg.cast(util.arg.union(isValidTinyColor as any, 'role', 'member'), message, args.color as string)) as
| string
diff --git a/src/commands/info/guildInfo.ts b/src/commands/info/guildInfo.ts
index ab09741..67150f6 100644
--- a/src/commands/info/guildInfo.ts
+++ b/src/commands/info/guildInfo.ts
@@ -1,4 +1,4 @@
-import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
import {
Constants,
Guild,
@@ -35,7 +35,7 @@ export default class GuildInfoCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { guild: Guild | Snowflake | GuildPreview }) {
+ public override async exec(message: BushMessage | BushSlashMessage, args: { guild: ArgType<'guild'> | ArgType<'snowflake'> }) {
if (!args?.guild && !message.guild) {
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.`
@@ -43,16 +43,17 @@ export default class GuildInfoCommand extends BushCommand {
}
const otherEmojis = client.consts.mappings.otherEmojis;
let isPreview = false;
+ let _guild: ArgType<'guild'> | ArgType<'snowflake'> | GuildPreview = args.guild;
if (['number', 'string'].includes(typeof args?.guild)) {
const preview = await client.fetchGuildPreview(`${args.guild}` as Snowflake).catch(() => {});
if (preview) {
- args.guild = preview;
+ _guild = preview;
isPreview = true;
} else {
return await message.util.reply(`${util.emojis.error} That guild is not discoverable or does not exist.`);
}
}
- const guild: Guild | GuildPreview = (args?.guild as Guild | GuildPreview) || (message.guild as Guild);
+ const guild: Guild | GuildPreview = (_guild as Guild | GuildPreview) || (_guild as Guild);
const emojis: string[] = [];
const guildAbout: string[] = [];
const guildStats: string[] = [];
diff --git a/src/commands/info/help.ts b/src/commands/info/help.ts
index 4999446..277017e 100644
--- a/src/commands/info/help.ts
+++ b/src/commands/info/help.ts
@@ -1,4 +1,4 @@
-import { BushCommand, BushMessage, BushSlashMessage } from '#lib';
+import { ArgType, BushCommand, BushMessage, BushSlashMessage } from '#lib';
import { MessageActionRow, MessageButton, MessageEmbed } from 'discord.js';
import packageDotJSON from '../../../package.json' assert { type: 'json' };
@@ -40,7 +40,7 @@ export default class HelpCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { command: BushCommand | string; showHidden?: boolean }
+ args: { command: ArgType<'commandAlias'> | string; showHidden?: boolean }
) {
const prefix = util.prefix(message);
const row = this.addLinks(message);
diff --git a/src/commands/info/pronouns.ts b/src/commands/info/pronouns.ts
index 29cd2ce..3dacede 100644
--- a/src/commands/info/pronouns.ts
+++ b/src/commands/info/pronouns.ts
@@ -1,5 +1,5 @@
-import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
-import { MessageEmbed, type User } from 'discord.js';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { MessageEmbed } from 'discord.js';
export default class PronounsCommand extends BushCommand {
public constructor() {
@@ -25,7 +25,8 @@ export default class PronounsCommand extends BushCommand {
slash: true
});
}
- override async exec(message: BushMessage | BushSlashMessage, args: { user?: User }) {
+
+ override async exec(message: BushMessage | BushSlashMessage, args: { user?: ArgType<'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 f2ffaa8..1658da9 100644
--- a/src/commands/info/snowflake.ts
+++ b/src/commands/info/snowflake.ts
@@ -1,4 +1,4 @@
-import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
import {
MessageEmbed,
SnowflakeUtil,
@@ -39,7 +39,8 @@ export default class SnowflakeCommand extends BushCommand {
slash: true
});
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { snowflake: Snowflake }) {
+
+ public override async exec(message: BushMessage | BushSlashMessage, args: { snowflake: ArgType<'snowflake'> }) {
const snowflake = `${args.snowflake}` as Snowflake;
const snowflakeEmbed = new MessageEmbed().setTitle('Unknown :snowflake:').setColor(util.colors.default);
diff --git a/src/commands/info/userInfo.ts b/src/commands/info/userInfo.ts
index 98ead3d..9c7a2a7 100644
--- a/src/commands/info/userInfo.ts
+++ b/src/commands/info/userInfo.ts
@@ -1,5 +1,5 @@
-import { BushCommand, BushGuild, BushGuildMember, type BushMessage, type BushSlashMessage, type BushUser } from '#lib';
-import { MessageEmbed, type Snowflake } from 'discord.js';
+import { ArgType, BushCommand, BushGuild, BushGuildMember, type BushMessage, type BushSlashMessage, type BushUser } from '#lib';
+import { MessageEmbed } from 'discord.js';
// TODO: Add bot information
export default class UserInfoCommand extends BushCommand {
@@ -28,7 +28,7 @@ export default class UserInfoCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { user: BushUser | Snowflake }) {
+ public override async exec(message: BushMessage | BushSlashMessage, args: { user: ArgType<'user'> | ArgType<'snowflake'> }) {
const user =
args?.user === undefined || args?.user === null
? message.author
diff --git a/src/commands/leveling/leaderboard.ts b/src/commands/leveling/leaderboard.ts
index 6bf66d1..d53d358 100644
--- a/src/commands/leveling/leaderboard.ts
+++ b/src/commands/leveling/leaderboard.ts
@@ -1,4 +1,4 @@
-import { BushCommand, ButtonPaginator, Level, type BushMessage, type BushSlashMessage } from '#lib';
+import { ArgType, BushCommand, ButtonPaginator, Level, type BushMessage, type BushSlashMessage } from '#lib';
import { MessageEmbed } from 'discord.js';
export default class LeaderboardCommand extends BushCommand {
@@ -27,7 +27,7 @@ export default class LeaderboardCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { page: number }) {
+ public override async exec(message: BushMessage | BushSlashMessage, args: { page: ArgType<'integer'> }) {
if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be run in a server.`);
if (!(await message.guild.hasFeature('leveling')))
return await message.util.reply(
diff --git a/src/commands/leveling/level.ts b/src/commands/leveling/level.ts
index 61e5d0b..ed8466d 100644
--- a/src/commands/leveling/level.ts
+++ b/src/commands/leveling/level.ts
@@ -1,5 +1,6 @@
import {
AllowedMentions,
+ ArgType,
BushCommand,
CanvasProgressBar,
Level,
@@ -41,7 +42,7 @@ export default class LevelCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { user?: BushUser }) {
+ public override async exec(message: BushMessage | BushSlashMessage, args: { user?: ArgType<'user'> }) {
if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be run in a server.`);
if (!(await message.guild.hasFeature('leveling')))
return await message.util.reply(
diff --git a/src/commands/leveling/setLevel.ts b/src/commands/leveling/setLevel.ts
index 69f562d..5118a8b 100644
--- a/src/commands/leveling/setLevel.ts
+++ b/src/commands/leveling/setLevel.ts
@@ -1,5 +1,4 @@
-import { AllowedMentions, BushCommand, Level, type BushMessage, type BushSlashMessage } from '#lib';
-import { type User } from 'discord.js';
+import { AllowedMentions, ArgType, BushCommand, Level, type BushMessage, type BushSlashMessage } from '#lib';
export default class SetLevelCommand extends BushCommand {
public constructor() {
@@ -34,7 +33,10 @@ export default class SetLevelCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage | BushSlashMessage, { user, level }: { user: User; level: number }) {
+ public override async exec(
+ message: BushMessage | BushSlashMessage,
+ { user, level }: { user: ArgType<'user'>; level: ArgType<'integer'> }
+ ) {
if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be run in a guild.`);
if (!user.id) throw new Error('user.id is null');
diff --git a/src/commands/leveling/setXp.ts b/src/commands/leveling/setXp.ts
index 68be528..eeafff3 100644
--- a/src/commands/leveling/setXp.ts
+++ b/src/commands/leveling/setXp.ts
@@ -1,5 +1,4 @@
-import { AllowedMentions, BushCommand, Level, type BushMessage, type BushSlashMessage } from '#lib';
-import { type User } from 'discord.js';
+import { AllowedMentions, ArgType, BushCommand, Level, type BushMessage, type BushSlashMessage } from '#lib';
export default class SetXpCommand extends BushCommand {
public constructor() {
@@ -35,7 +34,10 @@ export default class SetXpCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage | BushSlashMessage, { user, xp }: { user: User; xp: number }) {
+ public override async exec(
+ message: BushMessage | BushSlashMessage,
+ { user, xp }: { user: ArgType<'user'>; xp: ArgType<'abbreviatedNumber'> }
+ ) {
if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be run in a guild.`);
if (!user.id) throw new Error('user.id is null');
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts
index 506a7c3..c0375e0 100644
--- a/src/commands/moderation/ban.ts
+++ b/src/commands/moderation/ban.ts
@@ -1,5 +1,13 @@
-import { AllowedMentions, BushCommand, Moderation, type BushMessage, type BushSlashMessage } from '#lib';
-import { type Snowflake, type User } from 'discord.js';
+import {
+ AllowedMentions,
+ ArgType,
+ BushCommand,
+ Moderation,
+ OptionalArgType,
+ type BushMessage,
+ type BushSlashMessage
+} from '#lib';
+import { type User } from 'discord.js';
export default class BanCommand extends BushCommand {
public constructor() {
@@ -61,9 +69,9 @@ export default class BanCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
args: {
- user: User | Snowflake;
- reason: { duration: number | null; contentWithoutTime: string } | null;
- days: number | null;
+ user: ArgType<'user'> | ArgType<'snowflake'>;
+ reason: OptionalArgType<'contentWithDuration'>;
+ days: OptionalArgType<'integer'>;
force: boolean;
}
) {
diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts
index 9463154..b59b9f9 100644
--- a/src/commands/moderation/kick.ts
+++ b/src/commands/moderation/kick.ts
@@ -1,4 +1,4 @@
-import { AllowedMentions, BushCommand, Moderation, type BushMessage, type BushSlashMessage, type BushUser } from '#lib';
+import { AllowedMentions, ArgType, BushCommand, Moderation, type BushMessage, type BushSlashMessage } from '#lib';
export default class KickCommand extends BushCommand {
public constructor() {
@@ -46,7 +46,7 @@ export default class KickCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- { user, reason, force }: { user: BushUser; reason?: string; force: boolean }
+ { user, reason, force }: { user: ArgType<'user'>; reason: ArgType<'string'>; force: boolean }
) {
const member = await message.guild!.members.fetch(user.id);
diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts
index 0f2d33c..be6e6b4 100644
--- a/src/commands/moderation/modlog.ts
+++ b/src/commands/moderation/modlog.ts
@@ -1,4 +1,4 @@
-import { BushCommand, ButtonPaginator, ModLog, type BushMessage, type BushSlashMessage, type BushUser } from '#lib';
+import { ArgType, BushCommand, ButtonPaginator, ModLog, type BushMessage, type BushSlashMessage } from '#lib';
import { MessageEmbed, User } from 'discord.js';
export default class ModlogCommand extends BushCommand {
@@ -35,21 +35,9 @@ export default class ModlogCommand extends BushCommand {
});
}
- static generateModlogInfo(log: ModLog, showUser: boolean): string {
- const trim = (str: string): string => (str.endsWith('\n') ? str.substring(0, str.length - 1).trim() : str.trim());
- const modLog = [`**Case ID**: ${util.discord.escapeMarkdown(log.id)}`, `**Type**: ${log.type.toLowerCase()}`];
- if (showUser) modLog.push(`**User**: <@!${log.user}>`);
- modLog.push(`**Moderator**: <@!${log.moderator}>`);
- if (log.duration) modLog.push(`**Duration**: ${util.humanizeDuration(log.duration)}`);
- modLog.push(`**Reason**: ${trim(log.reason ?? 'No Reason Specified.')}`);
- modLog.push(`**Date**: ${util.timestamp(log.createdAt)}`);
- if (log.evidence) modLog.push(`**Evidence:** ${trim(log.evidence)}`);
- return modLog.join(`\n`);
- }
-
public override async exec(
message: BushMessage | BushSlashMessage,
- { search, hidden }: { search: BushUser | string; hidden: boolean }
+ { search, hidden }: { search: ArgType<'user'> | string; hidden: boolean }
) {
const foundUser = search instanceof User ? search : await util.resolveUserAsync(search);
if (foundUser) {
@@ -90,4 +78,16 @@ export default class ModlogCommand extends BushCommand {
return await ButtonPaginator.send(message, [embed]);
}
}
+
+ public static generateModlogInfo(log: ModLog, showUser: boolean): string {
+ const trim = (str: string): string => (str.endsWith('\n') ? str.substring(0, str.length - 1).trim() : str.trim());
+ const modLog = [`**Case ID**: ${util.discord.escapeMarkdown(log.id)}`, `**Type**: ${log.type.toLowerCase()}`];
+ if (showUser) modLog.push(`**User**: <@!${log.user}>`);
+ modLog.push(`**Moderator**: <@!${log.moderator}>`);
+ if (log.duration) modLog.push(`**Duration**: ${util.humanizeDuration(log.duration)}`);
+ modLog.push(`**Reason**: ${trim(log.reason ?? 'No Reason Specified.')}`);
+ modLog.push(`**Date**: ${util.timestamp(log.createdAt)}`);
+ if (log.evidence) modLog.push(`**Evidence:** ${trim(log.evidence)}`);
+ return modLog.join(`\n`);
+ }
}
diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts
index c7091b3..2c0a1e8 100644
--- a/src/commands/moderation/mute.ts
+++ b/src/commands/moderation/mute.ts
@@ -1,4 +1,4 @@
-import { AllowedMentions, BushCommand, Moderation, type BushMessage, type BushSlashMessage, type BushUser } from '#lib';
+import { AllowedMentions, ArgType, BushCommand, Moderation, type BushMessage, type BushSlashMessage } from '#lib';
export default class MuteCommand extends BushCommand {
public constructor() {
@@ -47,7 +47,7 @@ export default class MuteCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { user: BushUser; reason?: { duration: number | null; contentWithoutTime: string } | string; force: boolean }
+ args: { user: ArgType<'user'>; reason?: ArgType<'contentWithDuration'> | string; force: boolean }
) {
const reason: { duration: number | null; contentWithoutTime: string | null } = args.reason
? typeof args.reason === 'string'
diff --git a/src/commands/moderation/purge.ts b/src/commands/moderation/purge.ts
index f039046..7a25a0d 100644
--- a/src/commands/moderation/purge.ts
+++ b/src/commands/moderation/purge.ts
@@ -1,4 +1,4 @@
-import { BushCommand, BushMessage, BushUser } from '#lib';
+import { ArgType, BushCommand, BushMessage } from '#lib';
import { Collection, type Snowflake } from 'discord.js';
export default class PurgeCommand extends BushCommand {
@@ -47,7 +47,7 @@ export default class PurgeCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage, args: { amount: number; bot: boolean; user: BushUser }) {
+ public override async exec(message: BushMessage, args: { amount: number; bot: boolean; user: ArgType<'user'> }) {
if (message.channel.type === 'DM') return message.util.reply(`${util.emojis.error} You cannot run this command in dms.`);
if (args.amount > 100 || args.amount < 1) return message.util.reply(`${util.emojis.error} `);
diff --git a/src/commands/moderation/removeReactionEmoji.ts b/src/commands/moderation/removeReactionEmoji.ts
index 4ada9d5..bede2cf 100644
--- a/src/commands/moderation/removeReactionEmoji.ts
+++ b/src/commands/moderation/removeReactionEmoji.ts
@@ -1,5 +1,5 @@
-import { BushCommand, type BushMessage } from '#lib';
-import { Message, type Emoji, type Snowflake } from 'discord.js';
+import { ArgType, BushCommand, type BushMessage } from '#lib';
+import { Message, type Emoji } from 'discord.js';
export default class RemoveReactionEmojiCommand extends BushCommand {
public constructor() {
@@ -36,7 +36,10 @@ export default class RemoveReactionEmojiCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage, args: { message: BushMessage | Snowflake; emoji: Emoji | Snowflake }) {
+ public override async exec(
+ message: BushMessage,
+ args: { message: ArgType<'guildMessage'> | string; emoji: ArgType<'emoji'> | ArgType<'snowflake'> }
+ ) {
const resolvedMessage = args.message instanceof Message ? args.message : await message.channel.messages.fetch(args.message);
const id = !(['string'] as const).includes(typeof args.emoji);
diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts
index 689ef1e..651762b 100644
--- a/src/commands/moderation/role.ts
+++ b/src/commands/moderation/role.ts
@@ -1,4 +1,4 @@
-import { AllowedMentions, BushCommand, type BushGuildMember, type BushMessage, type BushRole, type BushSlashMessage } from '#lib';
+import { AllowedMentions, ArgType, BushCommand, OptionalArgType, type BushMessage, type BushSlashMessage } from '#lib';
import { type ArgumentOptions, type Flag } from 'discord-akairo';
import { Snowflake } from 'discord.js';
@@ -98,12 +98,24 @@ export default class RoleCommand extends BushCommand {
match: 'flag'
};
- return { action, member: member, role: (_role as any).role ?? _role, duration: (_role as any).duration, force };
+ return {
+ action,
+ member: member,
+ role: (_role as ArgType<'roleWithDuration'>).role ?? _role,
+ duration: (_role as ArgType<'roleWithDuration'>).duration,
+ force
+ };
}
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { action: 'add' | 'remove'; member: BushGuildMember; role: BushRole; duration?: number | null; force?: boolean }
+ args: {
+ action: 'add' | 'remove';
+ member: ArgType<'member'>;
+ role: ArgType<'role'>;
+ duration?: OptionalArgType<'duration'>;
+ force?: boolean;
+ }
) {
if (!args.role) return await message.util.reply(`${util.emojis.error} You must specify a role.`);
if (args.duration === null) args.duration = 0;
diff --git a/src/commands/moderation/slowmode.ts b/src/commands/moderation/slowmode.ts
index f4ab822..d38b266 100644
--- a/src/commands/moderation/slowmode.ts
+++ b/src/commands/moderation/slowmode.ts
@@ -1,13 +1,6 @@
-import {
- BushCommand,
- type BushMessage,
- type BushNewsChannel,
- type BushSlashMessage,
- type BushTextChannel,
- type BushThreadChannel
-} from '#lib';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
import { Argument } from 'discord-akairo';
-import { TextChannel, ThreadChannel, type NewsChannel } from 'discord.js';
+import { TextChannel, ThreadChannel } from 'discord.js';
export default class SlowModeCommand extends BushCommand {
public constructor() {
@@ -52,8 +45,8 @@ export default class SlowModeCommand extends BushCommand {
length,
channel
}: {
- length: number | 'off' | 'none' | 'disable' | null;
- channel: TextChannel | ThreadChannel | BushTextChannel | BushNewsChannel | BushThreadChannel | NewsChannel;
+ length: ArgType<'duration'> | ArgType<'durationSeconds'> | 'off' | 'none' | 'disable' | null;
+ channel: ArgType<'channel'>;
}
) {
if (message.channel!.type === 'DM')
diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts
index 8444801..dbbb9a5 100644
--- a/src/commands/moderation/unban.ts
+++ b/src/commands/moderation/unban.ts
@@ -1,4 +1,4 @@
-import { AllowedMentions, BushCommand, type BushMessage, type BushSlashMessage, type BushUser } from '#lib';
+import { AllowedMentions, ArgType, BushCommand, OptionalArgType, type BushMessage, type BushSlashMessage } from '#lib';
export default class UnbanCommand extends BushCommand {
public constructor() {
@@ -34,7 +34,10 @@ export default class UnbanCommand extends BushCommand {
userPermissions: ['BAN_MEMBERS']
});
}
- public override async exec(message: BushMessage | BushSlashMessage, { user, reason }: { user: BushUser; reason?: string }) {
+ public override async exec(
+ message: BushMessage | BushSlashMessage,
+ { user, reason }: { user: ArgType<'user'>; reason: OptionalArgType<'string'> }
+ ) {
const responseCode = await message.guild!.bushUnban({
user,
moderator: message.author,
diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts
index 0c59b1f..d36a5db 100644
--- a/src/commands/moderation/unmute.ts
+++ b/src/commands/moderation/unmute.ts
@@ -1,11 +1,12 @@
import {
AllowedMentions,
+ ArgType,
BushCommand,
Moderation,
+ OptionalArgType,
type BushGuildMember,
type BushMessage,
- type BushSlashMessage,
- type BushUser
+ type BushSlashMessage
} from '#lib';
export default class UnmuteCommand extends BushCommand {
@@ -55,7 +56,7 @@ export default class UnmuteCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- { user, reason, force }: { user: BushUser; reason?: string; force: boolean }
+ { user, reason, force }: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force: boolean }
) {
const error = util.emojis.error;
const member = message.guild!.members.cache.get(user.id) as BushGuildMember;
diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts
index 2212548..95e409d 100644
--- a/src/commands/moderation/warn.ts
+++ b/src/commands/moderation/warn.ts
@@ -1,11 +1,12 @@
import {
AllowedMentions,
+ ArgType,
BushCommand,
Moderation,
+ OptionalArgType,
type BushGuildMember,
type BushMessage,
- type BushSlashMessage,
- type BushUser
+ type BushSlashMessage
} from '#lib';
export default class WarnCommand extends BushCommand {
@@ -54,7 +55,7 @@ export default class WarnCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- { user, reason, force }: { user: BushUser; reason: string; force: boolean }
+ { user, reason, force }: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force?: boolean }
) {
const member = message.guild!.members.cache.get(user.id) as BushGuildMember;
if (!member) return message.util.reply(`${util.emojis.error} I cannot warn users that are not in the server.`);
diff --git a/src/commands/moulberry-bush/capePerms.ts b/src/commands/moulberry-bush/capePerms.ts
index 2749430..8dd51fe 100644
--- a/src/commands/moulberry-bush/capePerms.ts
+++ b/src/commands/moulberry-bush/capePerms.ts
@@ -1,4 +1,4 @@
-import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
import { MessageEmbed } 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: string }) {
+ public override async exec(message: BushMessage | BushSlashMessage, args: { ign: ArgType<'string'> }) {
interface CapePerms {
success: boolean;
perms: User[];
diff --git a/src/commands/moulberry-bush/capes.ts b/src/commands/moulberry-bush/capes.ts
index 1734568..fe18d89 100644
--- a/src/commands/moulberry-bush/capes.ts
+++ b/src/commands/moulberry-bush/capes.ts
@@ -1,4 +1,4 @@
-import { BushCommand, ButtonPaginator, DeleteButton, type BushMessage } from '#lib';
+import { BushCommand, ButtonPaginator, DeleteButton, OptionalArgType, type BushMessage } from '#lib';
import { type MessageEmbedOptions } from 'discord.js';
import got from 'got';
@@ -28,7 +28,7 @@ export default class CapesCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage, args: { cape: string | null }) {
+ public override async exec(message: BushMessage, args: { cape: OptionalArgType<'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/moulHammer.ts b/src/commands/moulberry-bush/moulHammer.ts
index 2811f80..ffb9afb 100644
--- a/src/commands/moulberry-bush/moulHammer.ts
+++ b/src/commands/moulberry-bush/moulHammer.ts
@@ -1,5 +1,5 @@
-import { BushCommand, BushSlashMessage, type BushMessage } from '#lib';
-import { MessageEmbed, type User } from 'discord.js';
+import { ArgType, BushCommand, BushSlashMessage, type BushMessage } from '#lib';
+import { MessageEmbed } from 'discord.js';
export default class MoulHammerCommand extends BushCommand {
public constructor() {
@@ -27,7 +27,7 @@ export default class MoulHammerCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage | BushSlashMessage, { user }: { user: User }) {
+ public override async exec(message: BushMessage | BushSlashMessage, { user }: { user: ArgType<'user'> }) {
await message.delete();
const embed = new MessageEmbed()
.setTitle('L')
diff --git a/src/commands/moulberry-bush/report.ts b/src/commands/moulberry-bush/report.ts
index 2a0d06f..a65cfcf 100644
--- a/src/commands/moulberry-bush/report.ts
+++ b/src/commands/moulberry-bush/report.ts
@@ -1,5 +1,5 @@
-import { AllowedMentions, BushCommand, type BushMessage } from '#lib';
-import { MessageEmbed, type GuildMember } from 'discord.js';
+import { AllowedMentions, ArgType, BushCommand, type BushMessage } from '#lib';
+import { MessageEmbed } from 'discord.js';
import moment from 'moment';
export default class ReportCommand extends BushCommand {
@@ -37,7 +37,7 @@ export default class ReportCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage, { member, evidence }: { member: GuildMember; evidence: string }) {
+ public override async exec(message: BushMessage, { member, evidence }: { member: ArgType<'member'>; evidence: string }) {
if (!message.guild || !(await message.guild.hasFeature('reporting')))
return await message.util.reply(
`${util.emojis.error} This command can only be used in servers where reporting is enabled.`
diff --git a/src/commands/moulberry-bush/rule.ts b/src/commands/moulberry-bush/rule.ts
index 2404c4d..cc59db5 100644
--- a/src/commands/moulberry-bush/rule.ts
+++ b/src/commands/moulberry-bush/rule.ts
@@ -1,5 +1,5 @@
-import { AllowedMentions, BushCommand, type BushMessage } from '#lib';
-import { MessageEmbed, type User } from 'discord.js';
+import { AllowedMentions, BushCommand, OptionalArgType, type BushMessage } from '#lib';
+import { MessageEmbed } from 'discord.js';
const rules = [
{
@@ -90,14 +90,17 @@ export default class RuleCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage, { rule, user }: { rule: undefined | number; user: User }) {
+ public override async exec(
+ message: BushMessage,
+ { rule, user }: { rule: OptionalArgType<'integer'>; user: OptionalArgType<'user'> }
+ ) {
const rulesEmbed = new MessageEmbed()
.setColor('#ef3929')
.setFooter(`Triggered by ${message.author.tag}`, message.author.avatarURL({ dynamic: true }) ?? undefined)
.setTimestamp();
- if (rule !== undefined && (rule > 12 || rule < 1)) {
- rule = undefined;
+ if (rule != null && (rule > 12 || rule < 1)) {
+ rule = null;
}
if (rule) {
if (rules[rule - 1]?.title && rules[rule - 1]?.description)
diff --git a/src/commands/utilities/activity.ts b/src/commands/utilities/activity.ts
index 2ab56cc..fe21aec 100644
--- a/src/commands/utilities/activity.ts
+++ b/src/commands/utilities/activity.ts
@@ -1,5 +1,5 @@
-import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
-import { DiscordAPIError, Message, VoiceChannel } from 'discord.js';
+import { ArgType, BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
+import { DiscordAPIError, Message } from 'discord.js';
const activityMap = {
'Poker Night': {
@@ -131,7 +131,7 @@ export default class YouTubeCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { channel: VoiceChannel; activity: string }) {
+ public override async exec(message: BushMessage | BushSlashMessage, args: { channel: ArgType<'channel'>; activity: string }) {
const channel = typeof args.channel === 'string' ? message.guild?.channels.cache.get(args.channel) : args.channel;
if (!channel || channel.type !== 'GUILD_VOICE')
return await message.util.reply(`${util.emojis.error} Choose a valid voice channel`);
diff --git a/src/commands/utilities/steal.ts b/src/commands/utilities/steal.ts
index 6a15d71..480201a 100644
--- a/src/commands/utilities/steal.ts
+++ b/src/commands/utilities/steal.ts
@@ -1,7 +1,7 @@
-import { BushCommand, BushSlashMessage, type BushMessage } from '#lib';
+import { ArgType, BushCommand, BushSlashMessage, type BushMessage } from '#lib';
import { ArgumentOptions, ArgumentType, ArgumentTypeCaster, Flag } from 'discord-akairo';
-import { type Snowflake } from 'discord.js';
import _ from 'lodash';
+import { URL } from 'url';
export default class StealCommand extends BushCommand {
public constructor() {
@@ -72,7 +72,7 @@ export default class StealCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args?: { emoji?: { name: string; id: Snowflake } | Snowflake | URL | string; name: string }
+ args?: { emoji?: ArgType<'discordEmoji'> | ArgType<'snowflake'> | ArgType<'url'> | string; name: string }
) {
if (!args || !args.emoji) return await message.util.reply(`${util.emojis.error} You must provide an emoji to steal.`);
diff --git a/src/commands/utilities/uuid.ts b/src/commands/utilities/uuid.ts
index e0f6b1c..6195edd 100644
--- a/src/commands/utilities/uuid.ts
+++ b/src/commands/utilities/uuid.ts
@@ -34,7 +34,10 @@ export default class UuidCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage, { ign, dashed }: { ign: { match: any[]; matches: any[] }; dashed: boolean }) {
+ public override async exec(
+ message: BushMessage,
+ { ign, dashed }: { ign: { match: RegExpMatchArray; matches: any[] }; dashed: boolean }
+ ) {
if (!ign) return await message.util.reply(`${util.emojis.error} Please enter a valid ign.`);
const readableIGN = ign.match[0];
try {
diff --git a/src/commands/utilities/viewRaw.ts b/src/commands/utilities/viewRaw.ts
index 0809a39..eeec4d9 100644
--- a/src/commands/utilities/viewRaw.ts
+++ b/src/commands/utilities/viewRaw.ts
@@ -1,5 +1,13 @@
-import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib';
-import { Message, MessageEmbed, type DMChannel, type NewsChannel, type Snowflake, type TextChannel } from 'discord.js';
+import {
+ ArgType,
+ BushCommand,
+ BushNewsChannel,
+ BushTextChannel,
+ OptionalArgType,
+ type BushMessage,
+ type BushSlashMessage
+} from '#lib';
+import { Message, MessageEmbed, type Snowflake } from 'discord.js';
export default class ViewRawCommand extends BushCommand {
public constructor() {
@@ -22,7 +30,7 @@ export default class ViewRawCommand extends BushCommand {
{
id: 'channel',
description: 'The channel that the message is in.',
- type: 'channel',
+ type: util.arg.union('textChannel', 'newsChannel'),
prompt: 'What channel is the message in?',
retry: '{error} Choose a valid channel.',
optional: true,
@@ -57,9 +65,14 @@ export default class ViewRawCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { message: BushMessage | Snowflake; channel: TextChannel | NewsChannel | DMChannel; json?: boolean; js: boolean }
+ args: {
+ message: ArgType<'guildMessage'> | ArgType<'messageLink'>;
+ channel: OptionalArgType<'textChannel'> | OptionalArgType<'newsChannel'>;
+ json: boolean;
+ js: boolean;
+ }
) {
- if (!args.channel) args.channel = (message.channel as TextChannel | NewsChannel | DMChannel)!;
+ if (!args.channel) args.channel = (message.channel as BushTextChannel | BushNewsChannel)!;
const newMessage =
args.message instanceof Message
? args.message
diff --git a/src/commands/utilities/whoHasRole.ts b/src/commands/utilities/whoHasRole.ts
index 45cf77f..ffb7ce1 100644
--- a/src/commands/utilities/whoHasRole.ts
+++ b/src/commands/utilities/whoHasRole.ts
@@ -1,5 +1,5 @@
-import { BushCommand, ButtonPaginator, type BushMessage, type BushSlashMessage } from '#lib';
-import { Util, type CommandInteraction, type Role } from 'discord.js';
+import { ArgType, BushCommand, ButtonPaginator, type BushMessage, type BushSlashMessage } from '#lib';
+import { Util, type CommandInteraction } from 'discord.js';
export default class WhoHasRoleCommand extends BushCommand {
public constructor() {
@@ -27,7 +27,7 @@ export default class WhoHasRoleCommand extends BushCommand {
typing: true
});
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { role: Role }) {
+ public override async exec(message: BushMessage | BushSlashMessage, args: { role: ArgType<'role'> }) {
if (message.util.isSlash) await (message.interaction as CommandInteraction).deferReply();
const roleMembers = args.role.members.map((member) => `${member.user} (${Util.escapeMarkdown(member.user.tag)})`);
diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts
index 5ae2ac0..f44c80d 100644
--- a/src/lib/extensions/discord-akairo/BushClientUtil.ts
+++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts
@@ -513,7 +513,7 @@ export class BushClientUtil extends ClientUtil {
if (!content) return { duration: 0, contentWithoutTime: null };
// eslint-disable-next-line prefer-const
- let duration = null;
+ let duration: number | null = null;
// Try to reduce false positives by requiring a space before the duration, this makes sure it still matches if it is
// in the beginning of the argument
let contentWithoutTime = ` ${content}`;
@@ -522,8 +522,7 @@ export class BushClientUtil extends ClientUtil {
const regex = BushConstants.TimeUnits[unit as keyof typeof BushConstants.TimeUnits].match;
const match = regex.exec(contentWithoutTime);
const value = Number(match?.groups?.[unit]);
- if (!isNaN(value))
- (duration as unknown as number) += value * BushConstants.TimeUnits[unit as keyof typeof BushConstants.TimeUnits].value;
+ if (!isNaN(value)) duration! += value * BushConstants.TimeUnits[unit as keyof typeof BushConstants.TimeUnits].value;
if (remove) contentWithoutTime = contentWithoutTime.replace(regex, '');
}
diff --git a/src/lib/extensions/discord-akairo/BushCommand.ts b/src/lib/extensions/discord-akairo/BushCommand.ts
index 6b54e20..0d0a0a8 100644
--- a/src/lib/extensions/discord-akairo/BushCommand.ts
+++ b/src/lib/extensions/discord-akairo/BushCommand.ts
@@ -1,34 +1,109 @@
+import { type DiscordEmojiInfo, type RoleWithDuration } from '#args';
import {
- BushArgumentTypeCaster,
- BushUser,
- ParsedDuration,
+ 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 BushSlashMessage
+ type BushNewsChannel,
+ type BushRole,
+ type BushSlashMessage,
+ type BushStageChannel,
+ type BushStoreChannel,
+ type BushTask,
+ type BushTextChannel,
+ type BushThreadChannel,
+ type BushUser,
+ type BushVoiceChannel,
+ type ParsedDuration
} from '#lib';
import {
- AkairoApplicationCommandAutocompleteOption,
- AkairoApplicationCommandChannelOptionData,
- AkairoApplicationCommandChoicesData,
- AkairoApplicationCommandNonOptionsData,
- AkairoApplicationCommandNumericOptionData,
- AkairoApplicationCommandOptionData,
- AkairoApplicationCommandSubCommandData,
- AkairoApplicationCommandSubGroupData,
Command,
- MissingPermissionSupplier,
- SlashOption,
- SlashResolveTypes,
+ type AkairoApplicationCommandAutocompleteOption,
+ type AkairoApplicationCommandChannelOptionData,
+ type AkairoApplicationCommandChoicesData,
+ type AkairoApplicationCommandNonOptionsData,
+ type AkairoApplicationCommandNumericOptionData,
+ type AkairoApplicationCommandOptionData,
+ type AkairoApplicationCommandSubCommandData,
+ type AkairoApplicationCommandSubGroupData,
type ArgumentOptions,
- type CommandOptions
+ type ArgumentType,
+ type ArgumentTypeCaster,
+ type BaseArgumentType,
+ type CommandOptions,
+ type ContextMenuCommand,
+ type MissingPermissionSupplier,
+ type SlashOption,
+ type SlashResolveTypes
} from 'discord-akairo';
-import { ArgumentType, ArgumentTypeCaster, BaseArgumentType } from 'discord-akairo/dist/src/struct/commands/arguments/Argument';
-import { ApplicationCommandOptionChoice, PermissionString, type PermissionResolvable, type Snowflake } from 'discord.js';
-import { DiscordEmojiInfo } from '../../../arguments/discordEmoji';
-import { RoleWithDuration } from '../../../arguments/roleWithDuration';
+import {
+ type ApplicationCommandOptionChoice,
+ type Collection,
+ type Invite,
+ type PermissionResolvable,
+ type PermissionString,
+ type Snowflake
+} from 'discord.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;
+ // eslint-disable-next-line deprecation/deprecation
+ storeChannel: BushStoreChannel | null;
+ // eslint-disable-next-line deprecation/deprecation
+ storeChannels: Collection<string, BushStoreChannel> | 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;
+ listener: BushListener | null;
+ task: BushTask | null;
+ contextMenuCommand: ContextMenuCommand | null;
+}
-export interface BaseBushArgumentType extends BaseArgumentType {
+export interface BaseBushArgumentType extends OverriddenBaseArgumentType {
duration: number | null;
contentWithDuration: ParsedDuration;
permission: PermissionString | null;
@@ -38,6 +113,7 @@ export interface BaseBushArgumentType extends BaseArgumentType {
abbreviatedNumber: number | null;
globalUser: BushUser | null;
messageLink: BushMessage | null;
+ durationSeconds: number | null;
}
export type BushArgumentType = keyof BaseBushArgumentType | RegExp;
@@ -446,3 +522,6 @@ type SlashOptionKeys =
| keyof AkairoApplicationCommandAutocompleteOption
| keyof AkairoApplicationCommandNumericOptionData
| keyof AkairoApplicationCommandSubCommandData;
+
+export type ArgType<T extends keyof BaseBushArgumentType> = NonNullable<BaseBushArgumentType[T]>;
+export type OptionalArgType<T extends keyof BaseBushArgumentType> = BaseBushArgumentType[T];
diff --git a/src/lib/extensions/discord-akairo/BushSlashMessage.ts b/src/lib/extensions/discord-akairo/BushSlashMessage.ts
index 448963b..3cd167d 100644
--- a/src/lib/extensions/discord-akairo/BushSlashMessage.ts
+++ b/src/lib/extensions/discord-akairo/BushSlashMessage.ts
@@ -1,4 +1,11 @@
-import { type BushClient, type BushCommandUtil, type BushGuild, type BushGuildMember, type BushUser } from '#lib';
+import {
+ type BushClient,
+ type BushCommandUtil,
+ type BushGuild,
+ type BushGuildMember,
+ type BushTextBasedChannel,
+ type BushUser
+} from '#lib';
import { AkairoMessage } from 'discord-akairo';
import { type CommandInteraction } from 'discord.js';
@@ -13,5 +20,12 @@ export class BushSlashMessage extends AkairoMessage {
}
export interface BushSlashMessage extends AkairoMessage {
+ /**
+ * The channel that the interaction was sent in.
+ */
+ get channel(): BushTextBasedChannel | null;
+}
+
+export interface BushSlashMessage extends AkairoMessage {
get guild(): BushGuild | null;
}
diff --git a/tsconfig.json b/tsconfig.json
index df315ca..d47c02b 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -4,7 +4,13 @@
"target": "ESNext",
"moduleResolution": "Node",
"outDir": "dist",
- "lib": ["esnext", "esnext.array", "esnext.asyncIterable", "esnext.intl", "esnext.symbol"],
+ "lib": [
+ "esnext",
+ "esnext.array",
+ "esnext.asyncIterable",
+ "esnext.intl",
+ "esnext.symbol"
+ ],
"sourceMap": true,
"incremental": true,
"experimentalDecorators": true,
@@ -22,9 +28,22 @@
"preserveValueImports": true,
"removeComments": true,
"paths": {
- "#lib": ["./src/lib/index.js"]
+ "#lib": [
+ "./src/lib/index.js"
+ ],
+ "#args": [
+ "./src/arguments/index.ts"
+ ],
}
},
- "include": ["src/**/*.ts", "src/**/*d.ts", "lib/**/*.ts", "ecosystem.config.cjs"],
- "exclude": ["dist", "node_modules"]
-}
+ "include": [
+ "src/**/*.ts",
+ "src/**/*d.ts",
+ "lib/**/*.ts",
+ "ecosystem.config.cjs"
+ ],
+ "exclude": [
+ "dist",
+ "node_modules"
+ ]
+} \ No newline at end of file