diff options
Diffstat (limited to 'src/commands/moderation')
-rw-r--r-- | src/commands/moderation/ban.ts | 44 | ||||
-rw-r--r-- | src/commands/moderation/block.ts | 30 | ||||
-rw-r--r-- | src/commands/moderation/evidence.ts | 5 | ||||
-rw-r--r-- | src/commands/moderation/hideCase.ts | 5 | ||||
-rw-r--r-- | src/commands/moderation/kick.ts | 7 | ||||
-rw-r--r-- | src/commands/moderation/massBan.ts | 5 | ||||
-rw-r--r-- | src/commands/moderation/modlog.ts | 9 | ||||
-rw-r--r-- | src/commands/moderation/mute.ts | 25 | ||||
-rw-r--r-- | src/commands/moderation/purge.ts | 9 | ||||
-rw-r--r-- | src/commands/moderation/removeReactionEmoji.ts | 18 | ||||
-rw-r--r-- | src/commands/moderation/role.ts | 22 | ||||
-rw-r--r-- | src/commands/moderation/slowmode.ts | 40 | ||||
-rw-r--r-- | src/commands/moderation/timeout.ts | 22 | ||||
-rw-r--r-- | src/commands/moderation/unban.ts | 7 | ||||
-rw-r--r-- | src/commands/moderation/unblock.ts | 15 | ||||
-rw-r--r-- | src/commands/moderation/unmute.ts | 8 | ||||
-rw-r--r-- | src/commands/moderation/untimeout.ts | 3 | ||||
-rw-r--r-- | src/commands/moderation/warn.ts | 8 |
18 files changed, 116 insertions, 166 deletions
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts index 5e3350f..25102e0 100644 --- a/src/commands/moderation/ban.ts +++ b/src/commands/moderation/ban.ts @@ -8,7 +8,8 @@ import { type BushSlashMessage, type OptionalArgType } from '#lib'; -import { ApplicationCommandOptionType, PermissionFlagsBits, type User } from 'discord.js'; +import assert from 'assert'; +import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; export default class BanCommand extends BushCommand { public constructor() { @@ -71,20 +72,21 @@ export default class BanCommand extends BushCommand { message: BushMessage | BushSlashMessage, args: { user: ArgType<'user'> | ArgType<'snowflake'>; - reason_and_duration: OptionalArgType<'contentWithDuration'>; + reason_and_duration: OptionalArgType<'contentWithDuration'> | string; days: OptionalArgType<'integer'>; force: boolean; } ) { - if (args.reason_and_duration && typeof args.reason_and_duration === 'object') args.reason_and_duration.duration ??= 0; - args.days ??= 0; + assert(message.inGuild()); + assert(message.member); - if (!message.guild) return message.util.reply(`${util.emojis.error} This command cannot be used in dms.`); - const member = message.guild!.members.cache.get((args.user as User)?.id ?? args.user); - const user = member?.user ?? (await util.resolveNonCachedUser((args.user as User)?.id ?? args.user)); + const { duration, content } = await util.castDurationContent(args.reason_and_duration, message); + + args.days ??= message.util.parsed?.alias === 'dban' ? 1 : 0; + const member = message.guild.members.cache.get(typeof args.user === 'string' ? args.user : args.user.id); + const user = member?.user ?? (await util.resolveNonCachedUser(typeof args.user === 'string' ? args.user : args.user.id)); if (!user) return message.util.reply(`${util.emojis.error} Invalid user.`); const useForce = args.force && message.author.isOwner(); - if (!message.member) throw new Error(`message.member is null`); const canModerateResponse = member ? await Moderation.permissionCheck(message.member, member, 'ban', true, useForce) : true; @@ -92,35 +94,13 @@ export default class BanCommand extends BushCommand { return await message.util.reply(canModerateResponse); } - if (message.util.parsed?.alias === 'dban' && !args.days) args.days = 1; - if (!Number.isInteger(args.days) || args.days! < 0 || args.days! > 7) { return message.util.reply(`${util.emojis.error} The delete days must be an integer between 0 and 7.`); } - let time: number | null; - if (args.reason_and_duration) { - time = - typeof args.reason_and_duration === 'string' - ? await util.arg.cast('duration', message, args.reason_and_duration) - : args.reason_and_duration.duration; - } - const parsedReason = args.reason_and_duration?.contentWithoutTime ?? null; + const opts = { reason: content, moderator: message.member, duration: duration, deleteDays: args.days }; - const responseCode = member - ? await member.bushBan({ - reason: parsedReason, - moderator: message.member, - duration: time! ?? 0, - deleteDays: args.days - }) - : await message.guild.bushBan({ - user, - reason: parsedReason, - moderator: message.member, - duration: time! ?? 0, - deleteDays: args.days - }); + const responseCode = member ? await member.bushBan(opts) : await message.guild.bushBan({ user, ...opts }); const responseMessage = (): string => { const victim = util.format.input(user.tag); diff --git a/src/commands/moderation/block.ts b/src/commands/moderation/block.ts index 20c6e86..e6f7849 100644 --- a/src/commands/moderation/block.ts +++ b/src/commands/moderation/block.ts @@ -2,8 +2,6 @@ import { AllowedMentions, blockResponse, BushCommand, - BushTextChannel, - BushThreadChannel, Moderation, type ArgType, type BushMessage, @@ -67,21 +65,17 @@ export default class BlockCommand extends BushCommand { } ) { assert(message.inGuild()); - if (!(message.channel instanceof BushTextChannel || message.channel instanceof BushThreadChannel)) - return message.util.send(`${util.emojis.error} This command can only be used in text and thread channels.`); + assert(message.member); + + if (!message.channel.isTextBased()) + return message.util.send(`${util.emojis.error} This command can only be used in text based channels.`); - const reason = args.reason_and_duration - ? typeof args.reason_and_duration === 'string' - ? await util.arg.cast('contentWithDuration', message, args.reason_and_duration) - : args.reason_and_duration - : { duration: null, contentWithoutTime: '' }; + const { duration, content } = await util.castDurationContent(args.reason_and_duration, message); - if (reason.duration === null) reason.duration = 0; - const member = await message.guild!.members.fetch(args.user.id).catch(() => null); + const member = await message.guild.members.fetch(args.user.id).catch(() => null); if (!member) return await message.util.reply(`${util.emojis.error} The user you selected is not in the server or is not a valid user.`); - assert(message.member); const useForce = args.force && message.author.isOwner(); const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'block', true, useForce); @@ -89,18 +83,10 @@ export default class BlockCommand extends BushCommand { return message.util.reply(canModerateResponse); } - const time = reason - ? typeof reason === 'string' - ? ((await util.arg.cast('duration', message, reason)) as number) - : reason.duration - : undefined; - - const parsedReason = reason?.contentWithoutTime ?? ''; - const responseCode = await member.bushBlock({ - reason: parsedReason, + reason: content, moderator: message.member, - duration: time ?? 0, + duration: duration, channel: message.channel }); diff --git a/src/commands/moderation/evidence.ts b/src/commands/moderation/evidence.ts index 23ccf59..d189e89 100644 --- a/src/commands/moderation/evidence.ts +++ b/src/commands/moderation/evidence.ts @@ -1,4 +1,5 @@ import { BushCommand, ModLog, type BushMessage, type BushSlashMessage } from '#lib'; +import assert from 'assert'; import { ArgumentGeneratorReturn } from 'discord-akairo'; import { ArgumentTypeCasterReturn } from 'discord-akairo/dist/src/struct/commands/arguments/Argument.js'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; @@ -65,9 +66,11 @@ export default class EvidenceCommand extends BushCommand { message: BushMessage | BushSlashMessage, { case_id: caseID, evidence }: { case_id: string; evidence?: string } ) { + assert(message.inGuild()); + const entry = await ModLog.findByPk(caseID); 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.`); + if (entry.guild !== message.guild.id) return message.util.reply(`${util.emojis.error} This modlog is from another server.`); if (evidence && (message as BushMessage).attachments?.size) return message.util.reply(`${util.emojis.error} Please either attach an image or a reason not both.`); diff --git a/src/commands/moderation/hideCase.ts b/src/commands/moderation/hideCase.ts index a59380f..d603953 100644 --- a/src/commands/moderation/hideCase.ts +++ b/src/commands/moderation/hideCase.ts @@ -1,4 +1,5 @@ import { BushCommand, ModLog, type BushMessage, type BushSlashMessage } from '#lib'; +import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; export default class HideCaseCommand extends BushCommand { @@ -27,9 +28,11 @@ export default class HideCaseCommand extends BushCommand { } public override async exec(message: BushMessage | BushSlashMessage, { case_id: caseID }: { case_id: string }) { + assert(message.inGuild()); + const entry = await ModLog.findByPk(caseID); if (!entry || entry.pseudo) return message.util.send(`${util.emojis.error} Invalid entry.`); - if (entry.guild !== message.guild!.id) return message.util.reply(`${util.emojis.error} This modlog is from another server.`); + if (entry.guild !== message.guild.id) return message.util.reply(`${util.emojis.error} This modlog is from another server.`); const action = entry.hidden ? 'no longer hidden' : 'now hidden'; const oldEntry = entry.hidden; entry.hidden = !entry.hidden; diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts index 6dfb09b..26098b5 100644 --- a/src/commands/moderation/kick.ts +++ b/src/commands/moderation/kick.ts @@ -7,6 +7,7 @@ import { type BushMessage, type BushSlashMessage } from '#lib'; +import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; export default class KickCommand extends BushCommand { @@ -57,11 +58,13 @@ export default class KickCommand extends BushCommand { message: BushMessage | BushSlashMessage, { user, reason, force }: { user: ArgType<'user'>; reason: ArgType<'string'>; force: boolean } ) { - const member = await message.guild!.members.fetch(user.id); + assert(message.inGuild()); + assert(message.member); + + const member = await message.guild.members.fetch(user.id); if (!member) return await message.util.reply(`${util.emojis.error} The user you selected is not in the server or is not a valid user.`); - if (!message.member) throw new Error(`message.member is null`); const useForce = force && message.author.isOwner(); const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'kick', true, useForce); diff --git a/src/commands/moderation/massBan.ts b/src/commands/moderation/massBan.ts index 5621011..e4aeb55 100644 --- a/src/commands/moderation/massBan.ts +++ b/src/commands/moderation/massBan.ts @@ -56,6 +56,9 @@ export default class MassBanCommand extends BushCommand { args: { users: ArgType<'string'>; reason: OptionalArgType<'string'>; days: OptionalArgType<'integer'> } ) { assert(message.inGuild()); + + args.days ??= message.util.parsed?.alias?.includes('dban') ? 1 : 0; + const ids = args.users.split(/\n| /).filter((id) => id.length > 0); if (ids.length === 0) return message.util.send(`${util.emojis.error} You must provide at least one user id.`); for (const id of ids) { @@ -67,8 +70,6 @@ export default class MassBanCommand extends BushCommand { return message.util.reply(`${util.emojis.error} The delete days must be an integer between 0 and 7.`); } - if (message.util.parsed?.alias?.includes('dban') && !args.days) args.days = 1; - const promises = ids.map((id) => message.guild.bushBan({ user: id, diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts index 443ffa3..c089d40 100644 --- a/src/commands/moderation/modlog.ts +++ b/src/commands/moderation/modlog.ts @@ -1,4 +1,5 @@ import { BushCommand, ButtonPaginator, ModLog, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import assert from 'assert'; import { ApplicationCommandOptionType, Embed, PermissionFlagsBits, User } from 'discord.js'; export default class ModlogCommand extends BushCommand { @@ -30,6 +31,7 @@ export default class ModlogCommand extends BushCommand { } ], slash: true, + channel: 'guild', clientPermissions: (m) => util.clientSendAndPermCheck(m), userPermissions: (m) => util.userGuildPermCheck(m, [PermissionFlagsBits.ManageMessages]) }); @@ -39,11 +41,13 @@ export default class ModlogCommand extends BushCommand { message: BushMessage | BushSlashMessage, { search, hidden }: { search: ArgType<'user'> | string; hidden: boolean } ) { + assert(message.inGuild()); + const foundUser = search instanceof User ? search : await util.resolveUserAsync(search); if (foundUser) { const logs = await ModLog.findAll({ where: { - guild: message.guild!.id, + guild: message.guild.id, user: foundUser.id }, order: [['createdAt', 'ASC']] @@ -68,8 +72,7 @@ export default class ModlogCommand extends BushCommand { const entry = await ModLog.findByPk(search as string); if (!entry || entry.pseudo || (entry.hidden && !hidden)) return message.util.send(`${util.emojis.error} That modlog does not exist.`); - if (entry.guild !== message.guild!.id) - return message.util.reply(`${util.emojis.error} This modlog is from another server.`); + if (entry.guild !== message.guild.id) return message.util.reply(`${util.emojis.error} This modlog is from another server.`); const embed = { title: `Case ${entry.id}`, description: ModlogCommand.generateModlogInfo(entry, true), diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts index c97ceb7..e32ece2 100644 --- a/src/commands/moderation/mute.ts +++ b/src/commands/moderation/mute.ts @@ -64,18 +64,15 @@ export default class MuteCommand extends BushCommand { force?: ArgType<'boolean'>; } ) { - const reason = args.reason_and_duration - ? typeof args.reason_and_duration === 'string' - ? await util.arg.cast('contentWithDuration', message, args.reason_and_duration) - : args.reason_and_duration - : { duration: null, contentWithoutTime: '' }; + assert(message.inGuild()); + assert(message.member); + + const { duration, content } = await util.castDurationContent(args.reason_and_duration, message); - if (reason.duration === null) reason.duration = 0; - const member = await message.guild!.members.fetch(args.user.id).catch(() => null); + const member = await message.guild.members.fetch(args.user.id).catch(() => null); if (!member) return await message.util.reply(`${util.emojis.error} The user you selected is not in the server or is not a valid user.`); - assert(message.member); const useForce = args.force && message.author.isOwner(); const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'mute', true, useForce); @@ -83,18 +80,10 @@ export default class MuteCommand extends BushCommand { return message.util.reply(canModerateResponse); } - const time = reason - ? typeof reason === 'string' - ? ((await util.arg.cast('duration', message, reason)) as number) - : reason.duration - : undefined; - - const parsedReason = reason?.contentWithoutTime ?? ''; - const responseCode = await member.bushMute({ - reason: parsedReason, + reason: content, moderator: message.member, - duration: time ?? 0 + duration }); const responseMessage = (): string => { diff --git a/src/commands/moderation/purge.ts b/src/commands/moderation/purge.ts index c882b7f..2cc9d04 100644 --- a/src/commands/moderation/purge.ts +++ b/src/commands/moderation/purge.ts @@ -53,8 +53,8 @@ export default class PurgeCommand extends BushCommand { message: BushMessage | BushSlashMessage, args: { amount: number; bot: boolean; user: ArgType<'user'> } ) { - assert(message.channel); - if (!message.inGuild()) return message.util.reply(`${util.emojis.error} You cannot run this command in dms.`); + assert(message.inGuild()); + if (args.amount > 100 || args.amount < 1) return message.util.reply(`${util.emojis.error} `); const messageFilter = (filterMessage: BushMessage): boolean => { @@ -67,13 +67,12 @@ export default class PurgeCommand extends BushCommand { const _messages = (await message.channel.messages.fetch({ limit: 100, before: message.id })) .filter((message) => messageFilter(message)) .first(args.amount); - const messages = new Collection<Snowflake, BushMessage>(); - _messages.forEach((m) => messages.set(m.id, m)); + const messages = new Collection<Snowflake, BushMessage>(_messages.map((m) => [m.id, m])); 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 092b8ac..f511007 100644 --- a/src/commands/moderation/removeReactionEmoji.ts +++ b/src/commands/moderation/removeReactionEmoji.ts @@ -1,6 +1,6 @@ import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; import assert from 'assert'; -import { ApplicationCommandOptionType, Message, PermissionFlagsBits, type Emoji } from 'discord.js'; +import { ApplicationCommandOptionType, Message, PermissionFlagsBits } from 'discord.js'; export default class RemoveReactionEmojiCommand extends BushCommand { public constructor() { @@ -45,23 +45,19 @@ export default class RemoveReactionEmojiCommand extends BushCommand { assert(message.channel); const resolvedMessage = args.message instanceof Message ? args.message : await message.channel.messages.fetch(args.message); - const id = !(['string'] as const).includes(typeof args.emoji); - const emojiID = !id ? `${args.emoji}` : (args.emoji as Emoji).id; - const success = await resolvedMessage.reactions.cache + const emojiID = typeof args.emoji === 'string' ? `${args.emoji}` : args.emoji.id; + const success = !!(await resolvedMessage.reactions.cache ?.get(emojiID!) ?.remove() - ?.catch(() => {}); + ?.catch(() => undefined)); + if (success) { return await message.util.reply( - `${util.emojis.success} Removed all reactions of \`${id ? emojiID : args.emoji}\` from the message with the id of \`${ - resolvedMessage.id - }\`.` + `${util.emojis.success} Removed all reactions of \`${emojiID}\` from the message with the id of \`${resolvedMessage.id}\`.` ); } else { return await message.util.reply( - `${util.emojis.error} There was an error removing all reactions of \`${ - id ? emojiID : args.emoji - }\` from the message with the id of \`${resolvedMessage.id}\`.` + `${util.emojis.error} There was an error removing all reactions of \`${emojiID}\` from the message with the id of \`${resolvedMessage.id}\`.` ); } } diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts index 920ef81..8580f2f 100644 --- a/src/commands/moderation/role.ts +++ b/src/commands/moderation/role.ts @@ -128,7 +128,7 @@ export default class RoleCommand extends BushCommand { } ) { if (!args.role) return await message.util.reply(`${util.emojis.error} You must specify a role.`); - if (args.duration === null) args.duration = 0; + args.duration ??= 0; if ( !message.member!.permissions.has(PermissionFlagsBits.ManageRoles) && message.member!.id !== message.guild?.ownerId && @@ -162,20 +162,12 @@ export default class RoleCommand extends BushCommand { const shouldLog = this.punishmentRoleNames.includes(args.role.name); - const responseCode = - args.action === 'add' - ? await args.member.bushAddRole({ - moderator: message.member!, - addToModlog: shouldLog, - role: args.role, - duration: args.duration - }) - : await args.member.bushRemoveRole({ - moderator: message.member!, - addToModlog: shouldLog, - role: args.role, - duration: args.duration - }); + const responseCode = await args.member[`bush${args.action === 'add' ? 'Add' : 'Remove'}Role`]({ + moderator: message.member!, + addToModlog: shouldLog, + role: args.role, + duration: args.duration + }); const responseMessage = (): string => { const victim = util.format.input(args.member.user.tag); diff --git a/src/commands/moderation/slowmode.ts b/src/commands/moderation/slowmode.ts index fb446d1..c0511f3 100644 --- a/src/commands/moderation/slowmode.ts +++ b/src/commands/moderation/slowmode.ts @@ -1,6 +1,7 @@ import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import assert from 'assert'; import { Argument } from 'discord-akairo'; -import { ApplicationCommandOptionType, ChannelType, PermissionFlagsBits, type TextChannel, type ThreadChannel } from 'discord.js'; +import { ApplicationCommandOptionType, ChannelType, PermissionFlagsBits } from 'discord.js'; export default class SlowmodeCommand extends BushCommand { public constructor() { @@ -42,38 +43,33 @@ export default class SlowmodeCommand extends BushCommand { public override async exec( message: BushMessage | BushSlashMessage, - { - length, - channel - }: { + args: { length: ArgType<'duration'> | ArgType<'durationSeconds'> | 'off' | 'none' | 'disable' | null; channel: ArgType<'channel'>; } ) { - if (message.channel!.type === ChannelType.DM) - return await message.util.reply(`${util.emojis.error} This command cannot be run in dms.`); - if (!channel) channel = message.channel as any; - if (![ChannelType.GuildText, ChannelType.GuildPrivateThread, ChannelType.GuildPublicThread].includes(channel.type)) - return await message.util.reply(`${util.emojis.error} <#${channel.id}> is not a text or thread channel.`); - if (length) { - length = - typeof length === 'string' && !(['off', 'none', 'disable'] as const).includes(length) - ? await util.arg.cast('duration', message, length) - : length; - } + assert(message.inGuild()); + + args.channel ??= message.channel; + + if (!args.channel.isTextBased() || args.channel.isNews()) + return await message.util.reply(`${util.emojis.error} <#${args.channel.id}> is not a text or thread channel.`); - const length2: number = (['off', 'none', 'disable'] as const).includes(length as string) ? 0 : (length as number); + args.length = + typeof args.length === 'string' && !(['off', 'none', 'disable'] as const).includes(args.length) + ? await util.arg.cast('duration', message, args.length) + : args.length; - const setSlowmode = await (channel as ThreadChannel | TextChannel) + const length2: number = (['off', 'none', 'disable'] as const).includes(args.length) || args.length === null ? 0 : args.length; + + const setSlowmode = await args.channel .setRateLimitPerUser(length2 / 1000, `Changed by ${message.author.tag} (${message.author.id}).`) .catch(() => {}); if (!setSlowmode) - return await message.util.reply( - `${util.emojis.error} There was an error changing the slowmode of <#${(channel as ThreadChannel | TextChannel).id}>.` - ); + return await message.util.reply(`${util.emojis.error} There was an error changing the slowmode of <#${args.channel.id}>.`); else return await message.util.reply( - `${util.emojis.success} Successfully changed the slowmode of <#${channel.id}> ${ + `${util.emojis.success} Successfully changed the slowmode of <#${args.channel.id}> ${ length2 ? `to \`${util.humanizeDuration(length2)}` : '`off' }\`.` ); diff --git a/src/commands/moderation/timeout.ts b/src/commands/moderation/timeout.ts index 32fcf76..b8fb78f 100644 --- a/src/commands/moderation/timeout.ts +++ b/src/commands/moderation/timeout.ts @@ -58,19 +58,16 @@ export default class TimeoutCommand extends BushCommand { message: BushMessage | BushSlashMessage, args: { user: ArgType<'user'>; reason_and_duration: ArgType<'contentWithDuration'> | string; force?: ArgType<'boolean'> } ) { - const reason = args.reason_and_duration - ? typeof args.reason_and_duration === 'string' - ? await util.arg.cast('contentWithDuration', message, args.reason_and_duration) - : args.reason_and_duration - : { duration: null, contentWithoutTime: '' }; + assert(message.inGuild()); + assert(message.member); + + const { duration, content } = await util.castDurationContent(args.reason_and_duration, message); - if (reason.duration === null || reason.duration < 1) - return await message.util.reply(`${util.emojis.error} You must specify a duration for timeouts.`); - const member = await message.guild!.members.fetch(args.user.id).catch(() => null); + if (!duration) return await message.util.reply(`${util.emojis.error} You must specify a duration for timeouts.`); + const member = await message.guild.members.fetch(args.user.id).catch(() => null); if (!member) return await message.util.reply(`${util.emojis.error} The user you selected is not in the server or is not a valid user.`); - assert(message.member); const useForce = args.force && message.author.isOwner(); const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'timeout', true, useForce); @@ -78,13 +75,10 @@ export default class TimeoutCommand extends BushCommand { return message.util.reply(canModerateResponse); } - const time = reason.duration; - const parsedReason = reason.contentWithoutTime ?? ''; - const responseCode = await member.bushTimeout({ - reason: parsedReason, + reason: content, moderator: message.member, - duration: time + duration: duration }); const responseMessage = (): string => { diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts index 7bdb32e..a6afc0a 100644 --- a/src/commands/moderation/unban.ts +++ b/src/commands/moderation/unban.ts @@ -7,6 +7,7 @@ import { type BushSlashMessage, type OptionalArgType } from '#lib'; +import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; export default class UnbanCommand extends BushCommand { @@ -21,7 +22,7 @@ export default class UnbanCommand extends BushCommand { { id: 'user', description: 'The user to unban.', - type: 'globalUser', + type: util.arg.compose('user', 'globalUser'), prompt: 'What user would you like to unban?', retry: '{error} Choose a valid user to unban.', slashType: ApplicationCommandOptionType.User @@ -48,7 +49,9 @@ export default class UnbanCommand extends BushCommand { message: BushMessage | BushSlashMessage, { user, reason }: { user: ArgType<'user'>; reason: OptionalArgType<'string'> } ) { - const responseCode = await message.guild!.bushUnban({ + assert(message.inGuild()); + + const responseCode = await message.guild.bushUnban({ user, moderator: message.author, reason diff --git a/src/commands/moderation/unblock.ts b/src/commands/moderation/unblock.ts index 7d36e15..34b2075 100644 --- a/src/commands/moderation/unblock.ts +++ b/src/commands/moderation/unblock.ts @@ -1,8 +1,6 @@ import { AllowedMentions, BushCommand, - BushTextChannel, - BushThreadChannel, Moderation, unblockResponse, type ArgType, @@ -63,14 +61,15 @@ export default class UnblockCommand extends BushCommand { args: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force?: ArgType<'boolean'> } ) { assert(message.inGuild()); - if (!(message.channel instanceof BushTextChannel || message.channel instanceof BushThreadChannel)) - return message.util.send(`${util.emojis.error} This command can only be used in text and thread channels.`); + assert(message.member); + + if (!message.channel.isTextBased()) + return message.util.send(`${util.emojis.error} This command can only be used in text based channels.`); - const member = await message.guild!.members.fetch(args.user.id).catch(() => null); + const member = await message.guild.members.fetch(args.user.id).catch(() => null); if (!member) return await message.util.reply(`${util.emojis.error} The user you selected is not in the server or is not a valid user.`); - assert(message.member); const useForce = args.force && message.author.isOwner(); const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'unblock', true, useForce); @@ -78,10 +77,8 @@ export default class UnblockCommand extends BushCommand { return message.util.reply(canModerateResponse); } - const parsedReason = args.reason ?? ''; - const responseCode = await member.bushUnblock({ - reason: parsedReason, + reason: args.reason ?? '', moderator: message.member, channel: message.channel }); diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts index fb4bb55..de16cb5 100644 --- a/src/commands/moderation/unmute.ts +++ b/src/commands/moderation/unmute.ts @@ -9,6 +9,7 @@ import { type BushSlashMessage, type OptionalArgType } from '#lib'; +import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; export default class UnmuteCommand extends BushCommand { @@ -60,10 +61,11 @@ export default class UnmuteCommand extends BushCommand { message: BushMessage | BushSlashMessage, { user, reason, force = false }: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force?: boolean } ) { - const error = util.emojis.error; - const member = message.guild!.members.cache.get(user.id) as BushGuildMember; + assert(message.inGuild()); + assert(message.member); - if (!message.member) throw new Error(`message.member is null`); + const error = util.emojis.error; + const member = message.guild.members.cache.get(user.id) as BushGuildMember; 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 6d3632d..636b178 100644 --- a/src/commands/moderation/untimeout.ts +++ b/src/commands/moderation/untimeout.ts @@ -60,9 +60,10 @@ export default class UntimeoutCommand extends BushCommand { message: BushMessage | BushSlashMessage, args: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force?: ArgType<'boolean'> } ) { + assert(message.inGuild()); assert(message.member); - const member = await message.guild!.members.fetch(args.user.id).catch(() => null); + const member = await message.guild.members.fetch(args.user.id).catch(() => null); if (!member) return await message.util.reply(`${util.emojis.error} The user you selected is not in the server or is not a valid user.`); diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts index 27d04b3..3ab4b0b 100644 --- a/src/commands/moderation/warn.ts +++ b/src/commands/moderation/warn.ts @@ -4,11 +4,11 @@ import { Moderation, warnResponse, type ArgType, - type BushGuildMember, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib'; +import assert from 'assert'; import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js'; export default class WarnCommand extends BushCommand { @@ -59,10 +59,12 @@ export default class WarnCommand extends BushCommand { message: BushMessage | BushSlashMessage, { user, reason, force = false }: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force?: boolean } ) { - const member = message.guild!.members.cache.get(user.id) as BushGuildMember; + assert(message.inGuild()); + assert(message.member); + + const member = message.guild.members.cache.get(user.id); if (!member) return message.util.reply(`${util.emojis.error} I cannot warn users that are not in the server.`); const useForce = force && message.author.isOwner(); - if (!message.member) throw new Error(`message.member is null`); const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'warn', true, useForce); if (canModerateResponse !== true) { |