aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commands/dev/__template.ts4
-rw-r--r--src/commands/dev/test.ts18
-rw-r--r--src/commands/info/guildInfo.ts4
-rw-r--r--src/commands/info/userInfo.ts2
-rw-r--r--src/commands/leveling/leaderboard.ts2
-rw-r--r--src/commands/leveling/level.ts4
-rw-r--r--src/commands/leveling/levelRoles.ts4
-rw-r--r--src/commands/moderation/_activePunishments.ts151
-rw-r--r--src/commands/moderation/ban.ts6
-rw-r--r--src/commands/moderation/block.ts4
-rw-r--r--src/commands/moderation/evidence.ts6
-rw-r--r--src/commands/moderation/lockdown.ts10
-rw-r--r--src/commands/moderation/massBan.ts4
-rw-r--r--src/commands/moderation/massEvidence.ts4
-rw-r--r--src/commands/moderation/mute.ts4
-rw-r--r--src/commands/moderation/role.ts4
-rw-r--r--src/commands/moderation/unban.ts4
-rw-r--r--src/commands/moderation/unblock.ts4
-rw-r--r--src/commands/moderation/unlockdown.ts6
-rw-r--r--src/commands/moderation/unmute.ts4
-rw-r--r--src/commands/moderation/untimeout.ts4
-rw-r--r--src/commands/moderation/warn.ts4
-rw-r--r--src/commands/moulberry-bush/capes.ts4
-rw-r--r--src/commands/moulberry-bush/rule.ts4
-rw-r--r--src/commands/utilities/steal.ts124
-rw-r--r--src/commands/utilities/viewRaw.ts4
-rw-r--r--src/commands/utilities/whoHasRole.ts4
-rw-r--r--src/lib/extensions/discord-akairo/BushCommand.ts23
-rw-r--r--src/lib/extensions/discord.js/other.ts2
29 files changed, 230 insertions, 192 deletions
diff --git a/src/commands/dev/__template.ts b/src/commands/dev/__template.ts
index 7ea1784..ace8802 100644
--- a/src/commands/dev/__template.ts
+++ b/src/commands/dev/__template.ts
@@ -1,4 +1,4 @@
-import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib';
+import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib';
import { ApplicationCommandOptionType } from 'discord.js';
export default class TemplateCommand extends BushCommand {
@@ -40,7 +40,7 @@ export default class TemplateCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { required_argument: ArgType<'string'>; optional_argument: OptionalArgType<'string'> }
+ args: { required_argument: ArgType<'string'>; optional_argument: OptArgType<'string'> }
) {
return await message.util.reply(`${util.emojis.error} Do not use the template command.`);
args;
diff --git a/src/commands/dev/test.ts b/src/commands/dev/test.ts
index 9365107..2d7b1f8 100644
--- a/src/commands/dev/test.ts
+++ b/src/commands/dev/test.ts
@@ -51,7 +51,7 @@ export default class TestCommand extends BushCommand {
return await message.util.reply(responses[Math.floor(Math.random() * responses.length)]);
}
- if (['button', 'buttons'].includes(args?.feature?.toLowerCase())) {
+ if (['button', 'buttons'].includes(args.feature?.toLowerCase())) {
const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents([
new ButtonBuilder({ style: ButtonStyle.Primary, customId: 'primaryButton', label: 'Primary' }),
new ButtonBuilder({ style: ButtonStyle.Secondary, customId: 'secondaryButton', label: 'Secondary' }),
@@ -60,7 +60,7 @@ export default class TestCommand extends BushCommand {
new ButtonBuilder({ style: ButtonStyle.Link, label: 'Link', url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' })
]);
return await message.util.reply({ content: 'buttons', components: [buttonRow] });
- } else if (['embed', 'button embed'].includes(args?.feature?.toLowerCase())) {
+ } else if (['embed', 'button embed'].includes(args.feature?.toLowerCase())) {
const embed = new EmbedBuilder()
.addFields([{ name: 'Field Name', value: 'Field Content' }])
.setAuthor({ name: 'Author', iconURL: 'https://www.w3schools.com/w3css/img_snowtops.jpg', url: 'https://google.com/' })
@@ -79,7 +79,7 @@ export default class TestCommand extends BushCommand {
new ButtonBuilder({ style: ButtonStyle.Link, label: 'Link', url: 'https://google.com/' })
]);
return await message.util.reply({ content: 'Test', embeds: [embed], components: [buttonRow] });
- } else if (['lots of buttons'].includes(args?.feature?.toLowerCase())) {
+ } else if (['lots of buttons'].includes(args.feature?.toLowerCase())) {
const buttonRows: ActionRowBuilder<ButtonBuilder>[] = [];
for (let a = 1; a <= 5; a++) {
const row = new ActionRowBuilder<ButtonBuilder>();
@@ -91,13 +91,13 @@ export default class TestCommand extends BushCommand {
buttonRows.push(row);
}
return await message.util.reply({ content: 'buttons', components: buttonRows });
- } else if (['paginate'].includes(args?.feature?.toLowerCase())) {
+ } else if (['paginate'].includes(args.feature?.toLowerCase())) {
const embeds = [];
for (let i = 1; i <= 5; i++) {
embeds.push(new EmbedBuilder().setDescription(i.toString()));
}
return await ButtonPaginator.send(message, embeds);
- } else if (['lots of embeds'].includes(args?.feature?.toLowerCase())) {
+ } else if (['lots of embeds'].includes(args.feature?.toLowerCase())) {
const description = 'This is a description.';
const _avatar = message.author.avatarURL() ?? undefined;
const author = { name: 'This is a author', iconURL: _avatar };
@@ -123,7 +123,7 @@ export default class TestCommand extends BushCommand {
ButtonRows.push(row);
}
return await message.util.reply({ content: 'this is content', components: ButtonRows, embeds });
- } else if (['delete slash commands'].includes(args?.feature?.toLowerCase())) {
+ } else if (['delete slash commands'].includes(args.feature?.toLowerCase())) {
if (!message.guild) return await message.util.reply(`${util.emojis.error} This test can only be run in a guild.`);
await client.guilds.fetch();
const promises: Promise<Collection<string, ApplicationCommand>>[] = [];
@@ -136,16 +136,16 @@ export default class TestCommand extends BushCommand {
await client.application!.commands.set([]);
return await message.util.reply(`${util.emojis.success} Removed guild commands and global commands.`);
- } else if (['drop down', 'drop downs', 'select menu', 'select menus'].includes(args?.feature?.toLowerCase())) {
+ } else if (['drop down', 'drop downs', 'select menu', 'select menus'].includes(args.feature?.toLowerCase())) {
return message.util.reply(`${util.emojis.error} no`);
- } else if (['sync automod'].includes(args?.feature?.toLowerCase())) {
+ } else if (['sync automod'].includes(args.feature?.toLowerCase())) {
const row = (await Shared.findByPk(0))!;
row.badLinks = badLinksArray;
row.badLinksSecret = badLinksSecretArray;
row.badWords = badWords;
await row.save();
return await message.util.reply(`${util.emojis.success} Synced automod.`);
- } else if (['modal'].includes(args?.feature?.toLowerCase())) {
+ } else if (['modal'].includes(args.feature?.toLowerCase())) {
const m = await message.util.reply({
content: 'Click for modal',
components: [
diff --git a/src/commands/info/guildInfo.ts b/src/commands/info/guildInfo.ts
index 59a1001..4872497 100644
--- a/src/commands/info/guildInfo.ts
+++ b/src/commands/info/guildInfo.ts
@@ -1,4 +1,4 @@
-import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib';
+import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib';
import assert from 'assert';
import { GuildDefaultMessageNotifications, GuildExplicitContentFilter } from 'discord-api-types/v10';
import {
@@ -43,7 +43,7 @@ export default class GuildInfoCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { guild: OptionalArgType<'guild'> | OptionalArgType<'snowflake'> }
+ args: { guild: OptArgType<'guild'> | OptArgType<'snowflake'> }
) {
if (!args.guild && !message.inGuild()) {
return await message.util.reply(
diff --git a/src/commands/info/userInfo.ts b/src/commands/info/userInfo.ts
index 5f4a1bd..cb2fc5f 100644
--- a/src/commands/info/userInfo.ts
+++ b/src/commands/info/userInfo.ts
@@ -47,7 +47,7 @@ export default class UserInfoCommand extends BushCommand {
public override async exec(message: BushMessage | BushSlashMessage, args: { user: ArgType<'user'> | ArgType<'snowflake'> }) {
const user =
- args?.user === undefined || args?.user === null
+ args.user === null
? message.author
: typeof args.user === 'object'
? args.user
diff --git a/src/commands/leveling/leaderboard.ts b/src/commands/leveling/leaderboard.ts
index c79a4e3..f476ac1 100644
--- a/src/commands/leveling/leaderboard.ts
+++ b/src/commands/leveling/leaderboard.ts
@@ -48,6 +48,6 @@ export default class LeaderboardCommand extends BushCommand {
const embeds = chunked.map((c) =>
new EmbedBuilder().setTitle(`${message.guild.name}'s Leaderboard`).setDescription(c.join('\n'))
);
- return await ButtonPaginator.send(message, embeds, undefined, true, args?.page ?? undefined);
+ return await ButtonPaginator.send(message, embeds, undefined, true, args.page ?? undefined);
}
}
diff --git a/src/commands/leveling/level.ts b/src/commands/leveling/level.ts
index 50742e9..3a9a916 100644
--- a/src/commands/leveling/level.ts
+++ b/src/commands/leveling/level.ts
@@ -7,7 +7,7 @@ import {
type BushMessage,
type BushSlashMessage,
type BushUser,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import { SimplifyNumber } from '@notenoughupdates/simplify-number';
import assert from 'assert';
@@ -46,7 +46,7 @@ export default class LevelCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage | BushSlashMessage, args: { user: OptionalArgType<'user'> }) {
+ public override async exec(message: BushMessage | BushSlashMessage, args: { user: OptArgType<'user'> }) {
assert(message.inGuild());
if (!(await message.guild.hasFeature('leveling')))
diff --git a/src/commands/leveling/levelRoles.ts b/src/commands/leveling/levelRoles.ts
index 3d95933..6886337 100644
--- a/src/commands/leveling/levelRoles.ts
+++ b/src/commands/leveling/levelRoles.ts
@@ -1,4 +1,4 @@
-import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib';
+import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
@@ -40,7 +40,7 @@ export default class LevelRolesCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { level: ArgType<'integer'>; role: OptionalArgType<'role'> }
+ args: { level: ArgType<'integer'>; role: OptArgType<'role'> }
) {
assert(message.inGuild());
assert(message.member);
diff --git a/src/commands/moderation/_activePunishments.ts b/src/commands/moderation/_activePunishments.ts
index cffc39f..e751493 100644
--- a/src/commands/moderation/_activePunishments.ts
+++ b/src/commands/moderation/_activePunishments.ts
@@ -1,78 +1,79 @@
-// import { BushCommand, ModLog, ModLogModel, type BushGuildMember, type BushMessage, type BushSlashMessage } from '#lib';
-// import { FindOptions, Op } from 'sequelize';
-// import { Permissions } from 'discord.js';
+/* import { BushCommand, ModLog, ModLogModel, type BushGuildMember, type BushMessage, type BushSlashMessage } from '#lib';
+import { FindOptions, Op } from 'sequelize';
+import { Permissions } from 'discord.js';
-// const punishmentTypes = ['ban', 'kick', 'mute', 'warn', 'role'] as const;
+const punishmentTypes = ['ban', 'kick', 'mute', 'warn', 'role'] as const;
-// export default class ActivePunishmentsCommand extends BushCommand {
-// public constructor() {
-// super('activePunishments', {
-// aliases: ['active-punishments', 'ap'],
-// category: 'moderation',
-// description: 'Gets a list of all the active punishment in the server.',
-// usage: [`active-punishments [--moderator <user>] [--type <${punishmentTypes.map((v) => `'${v}'`).join('|')}>]`],
-// examples: ['active-punishments'],
-// args: [
-// {
-// id: 'moderator',
-// description: 'Only show active punishments by this moderator.',
-// type: 'user',
-// match: 'option',
-// prompt: 'Only show active punishments from what user?',
-// optional: true,
-// slashType: ApplicationCommandOptionType.User,
-// slashResolve: 'Member'
-// },
-// {
-// id: 'type',
-// description: 'Only show active punishments of this type.',
-// customType: [...punishmentTypes],
-// readableType: punishmentTypes.map((v) => `'${v}'`).join('|'),
-// match: 'option',
-// optional: true,
-// slashType: ApplicationCommandOptionType.String,
-// choices: punishmentTypes.map((v) => ({ name: v, value: v }))
-// }
-// ],
-// slash: true,
-// channel: 'guild',
-// hidden: true,
-// clientPermissions: (m) => util.clientSendAndPermCheck(m),
-// userPermissions: (m) => util.userGuildPermCheck(m, [PermissionFlagsBits.ManageMessages])
-// });
-// }
-//
-// public override async exec(
-// message: BushMessage | BushSlashMessage,
-// args: { moderator?: BushGuildMember; type: typeof punishmentTypes[number] }
-// ) {
-// const where: FindOptions<ModLogModel>['where'] = { guild: message.guild!.id };
-// if (args.moderator?.id) where.user = args.moderator.id;
-// if (args.type) {
-// switch (args.type) {
-// case 'ban':
-// where.type = { [Op.or]: ['PERM_BAN', 'TEMP_BAN', 'UNBAN'] };
-// break;
-// case 'kick':
-// where.type = { [Op.or]: ['KICK'] };
-// break;
-// case 'mute':
-// where.type = { [Op.or]: ['PERM_MUTE', 'TEMP_MUTE', 'UNMUTE'] };
-// break;
-// case 'warn':
-// where.type = { [Op.or]: ['WARN'] };
-// break;
-// case 'role':
-// where.type = { [Op.or]: ['PERM_PUNISHMENT_ROLE', 'TEMP_PUNISHMENT_ROLE', 'REMOVE_PUNISHMENT_ROLE'] };
-// break;
-// default:
-// return message.util.reply(`${util.emojis.error} You supplied an invalid case type to filter by.`);
-// }
-// }
+export default class ActivePunishmentsCommand extends BushCommand {
+ public constructor() {
+ super('activePunishments', {
+ aliases: ['active-punishments', 'ap'],
+ category: 'moderation',
+ description: 'Gets a list of all the active punishment in the server.',
+ usage: [`active-punishments [--moderator <user>] [--type <${punishmentTypes.map((v) => `'${v}'`).join('|')}>]`],
+ examples: ['active-punishments'],
+ args: [
+ {
+ id: 'moderator',
+ description: 'Only show active punishments by this moderator.',
+ type: 'user',
+ match: 'option',
+ prompt: 'Only show active punishments from what user?',
+ optional: true,
+ slashType: ApplicationCommandOptionType.User,
+ slashResolve: 'Member'
+ },
+ {
+ id: 'type',
+ description: 'Only show active punishments of this type.',
+ customType: [...punishmentTypes],
+ readableType: punishmentTypes.map((v) => `'${v}'`).join('|'),
+ match: 'option',
+ optional: true,
+ slashType: ApplicationCommandOptionType.String,
+ choices: punishmentTypes.map((v) => ({ name: v, value: v }))
+ }
+ ],
+ slash: true,
+ channel: 'guild',
+ hidden: true,
+ clientPermissions: (m) => util.clientSendAndPermCheck(m),
+ userPermissions: (m) => util.userGuildPermCheck(m, [PermissionFlagsBits.ManageMessages])
+ });
+ }
-// const logs = await ModLog.findAll({
-// where,
-// order: [['createdAt', 'ASC']]
-// });
-// }
-// }
+ public override async exec(
+ message: BushMessage | BushSlashMessage,
+ args: { moderator?: BushGuildMember; type: typeof punishmentTypes[number] }
+ ) {
+ const where: FindOptions<ModLogModel>['where'] = { guild: message.guild!.id };
+ if (args.moderator?.id) where.user = args.moderator.id;
+ if (args.type) {
+ switch (args.type) {
+ case 'ban':
+ where.type = { [Op.or]: ['PERM_BAN', 'TEMP_BAN', 'UNBAN'] };
+ break;
+ case 'kick':
+ where.type = { [Op.or]: ['KICK'] };
+ break;
+ case 'mute':
+ where.type = { [Op.or]: ['PERM_MUTE', 'TEMP_MUTE', 'UNMUTE'] };
+ break;
+ case 'warn':
+ where.type = { [Op.or]: ['WARN'] };
+ break;
+ case 'role':
+ where.type = { [Op.or]: ['PERM_PUNISHMENT_ROLE', 'TEMP_PUNISHMENT_ROLE', 'REMOVE_PUNISHMENT_ROLE'] };
+ break;
+ default:
+ return message.util.reply(`${util.emojis.error} You supplied an invalid case type to filter by.`);
+ }
+ }
+
+ const logs = await ModLog.findAll({
+ where,
+ order: [['createdAt', 'ASC']]
+ });
+ }
+}
+ */
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts
index 25102e0..14bbba6 100644
--- a/src/commands/moderation/ban.ts
+++ b/src/commands/moderation/ban.ts
@@ -6,7 +6,7 @@ import {
type ArgType,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
@@ -72,8 +72,8 @@ export default class BanCommand extends BushCommand {
message: BushMessage | BushSlashMessage,
args: {
user: ArgType<'user'> | ArgType<'snowflake'>;
- reason_and_duration: OptionalArgType<'contentWithDuration'> | string;
- days: OptionalArgType<'integer'>;
+ reason_and_duration: OptArgType<'contentWithDuration'> | string;
+ days: OptArgType<'integer'>;
force: boolean;
}
) {
diff --git a/src/commands/moderation/block.ts b/src/commands/moderation/block.ts
index 554ef2b..722f08b 100644
--- a/src/commands/moderation/block.ts
+++ b/src/commands/moderation/block.ts
@@ -6,7 +6,7 @@ import {
type ArgType,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
@@ -61,7 +61,7 @@ export default class BlockCommand extends BushCommand {
message: BushMessage | BushSlashMessage,
args: {
user: ArgType<'user'>;
- reason_and_duration: OptionalArgType<'contentWithDuration'> | string;
+ reason_and_duration: OptArgType<'contentWithDuration'> | string;
force?: ArgType<'boolean'>;
}
) {
diff --git a/src/commands/moderation/evidence.ts b/src/commands/moderation/evidence.ts
index 68d7edc..d60a5b0 100644
--- a/src/commands/moderation/evidence.ts
+++ b/src/commands/moderation/evidence.ts
@@ -1,4 +1,4 @@
-import { BushCommand, ModLog, OptionalArgType, type BushMessage, type BushSlashMessage } from '#lib';
+import { BushCommand, ModLog, OptArgType, 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';
@@ -64,7 +64,7 @@ export default class EvidenceCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- { case_id: caseID, evidence }: { case_id: string; evidence: OptionalArgType<'string'> }
+ { case_id: caseID, evidence }: { case_id: string; evidence: OptArgType<'string'> }
) {
assert(message.inGuild());
@@ -85,7 +85,7 @@ export default class EvidenceCommand extends BushCommand {
return message.util.reply(`${util.emojis.success} Successfully updated the evidence for case ${util.format.input(caseID)}.`);
}
- public static getEvidence(message: BushMessage | BushSlashMessage, evidenceArg: OptionalArgType<'string'>): null | string {
+ public static getEvidence(message: BushMessage | BushSlashMessage, evidenceArg: OptArgType<'string'>): null | string {
if (evidenceArg && (message as BushMessage).attachments?.size) {
void message.util.reply(`${util.emojis.error} Please either attach an image or a reason not both.`);
return null;
diff --git a/src/commands/moderation/lockdown.ts b/src/commands/moderation/lockdown.ts
index 36f3240..f298ec9 100644
--- a/src/commands/moderation/lockdown.ts
+++ b/src/commands/moderation/lockdown.ts
@@ -8,7 +8,7 @@ import {
type ArgType,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, ChannelType, Collection, PermissionFlagsBits } from 'discord.js';
@@ -67,8 +67,8 @@ export default class LockdownCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
args: {
- channel: OptionalArgType<'textChannel'> | OptionalArgType<'newsChannel'> | OptionalArgType<'threadChannel'>;
- reason: OptionalArgType<'string'>;
+ channel: OptArgType<'textChannel'> | OptArgType<'newsChannel'> | OptArgType<'threadChannel'>;
+ reason: OptArgType<'string'>;
all: ArgType<'boolean'>;
}
) {
@@ -78,8 +78,8 @@ export default class LockdownCommand extends BushCommand {
public static async lockdownOrUnlockdown(
message: BushMessage | BushSlashMessage,
args: {
- channel: OptionalArgType<'textChannel'> | OptionalArgType<'newsChannel'> | OptionalArgType<'threadChannel'>;
- reason: OptionalArgType<'string'>;
+ channel: OptArgType<'textChannel'> | OptArgType<'newsChannel'> | OptArgType<'threadChannel'>;
+ reason: OptArgType<'string'>;
all: ArgType<'boolean'>;
},
action: 'lockdown' | 'unlockdown'
diff --git a/src/commands/moderation/massBan.ts b/src/commands/moderation/massBan.ts
index 568b6be..f1d85ed 100644
--- a/src/commands/moderation/massBan.ts
+++ b/src/commands/moderation/massBan.ts
@@ -5,7 +5,7 @@ import {
type ArgType,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, Collection, PermissionFlagsBits } from 'discord.js';
@@ -62,7 +62,7 @@ export default class MassBanCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { users: ArgType<'string'>; reason: OptionalArgType<'string'>; days: OptionalArgType<'integer'> }
+ args: { users: ArgType<'string'>; reason: OptArgType<'string'>; days: OptArgType<'integer'> }
) {
assert(message.inGuild());
diff --git a/src/commands/moderation/massEvidence.ts b/src/commands/moderation/massEvidence.ts
index 62421da..67f5a25 100644
--- a/src/commands/moderation/massEvidence.ts
+++ b/src/commands/moderation/massEvidence.ts
@@ -1,4 +1,4 @@
-import { BushCommand, ModLog, type ArgType, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib';
+import { BushCommand, ModLog, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
import { EvidenceCommand } from '../index.js';
@@ -45,7 +45,7 @@ export default class MassEvidenceCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { users: ArgType<'string'>; evidence: OptionalArgType<'string'> }
+ args: { users: ArgType<'string'>; evidence: OptArgType<'string'> }
) {
assert(message.inGuild());
diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts
index e32ece2..d846817 100644
--- a/src/commands/moderation/mute.ts
+++ b/src/commands/moderation/mute.ts
@@ -6,7 +6,7 @@ import {
type ArgType,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
@@ -60,7 +60,7 @@ export default class MuteCommand extends BushCommand {
message: BushMessage | BushSlashMessage,
args: {
user: ArgType<'user'>;
- reason_and_duration: OptionalArgType<'contentWithDuration'> | string;
+ reason_and_duration: OptArgType<'contentWithDuration'> | string;
force?: ArgType<'boolean'>;
}
) {
diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts
index 8580f2f..a87b2bf 100644
--- a/src/commands/moderation/role.ts
+++ b/src/commands/moderation/role.ts
@@ -6,7 +6,7 @@ import {
type ArgType,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import { type ArgumentGeneratorReturn } from 'discord-akairo';
import { ApplicationCommandOptionType, PermissionFlagsBits, type Snowflake } from 'discord.js';
@@ -123,7 +123,7 @@ export default class RoleCommand extends BushCommand {
action: 'add' | 'remove';
member: ArgType<'member'>;
role: ArgType<'role'>;
- duration?: OptionalArgType<'duration'>;
+ duration?: OptArgType<'duration'>;
force?: boolean;
}
) {
diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts
index 9973d61..e6ac6d0 100644
--- a/src/commands/moderation/unban.ts
+++ b/src/commands/moderation/unban.ts
@@ -5,7 +5,7 @@ import {
type ArgType,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
@@ -47,7 +47,7 @@ export default class UnbanCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- { user, reason }: { user: ArgType<'user'>; reason: OptionalArgType<'string'> }
+ { user, reason }: { user: ArgType<'user'>; reason: OptArgType<'string'> }
) {
assert(message.inGuild());
diff --git a/src/commands/moderation/unblock.ts b/src/commands/moderation/unblock.ts
index 34b2075..22c9949 100644
--- a/src/commands/moderation/unblock.ts
+++ b/src/commands/moderation/unblock.ts
@@ -6,7 +6,7 @@ import {
type ArgType,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
@@ -58,7 +58,7 @@ export default class UnblockCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force?: ArgType<'boolean'> }
+ args: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: ArgType<'boolean'> }
) {
assert(message.inGuild());
assert(message.member);
diff --git a/src/commands/moderation/unlockdown.ts b/src/commands/moderation/unlockdown.ts
index 4694518..253ce37 100644
--- a/src/commands/moderation/unlockdown.ts
+++ b/src/commands/moderation/unlockdown.ts
@@ -1,5 +1,5 @@
import { LockdownCommand } from '#commands';
-import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib';
+import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib';
import { ApplicationCommandOptionType, ChannelType, PermissionFlagsBits } from 'discord.js';
export default class UnlockdownCommand extends BushCommand {
@@ -55,8 +55,8 @@ export default class UnlockdownCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
args: {
- channel: OptionalArgType<'textChannel'> | OptionalArgType<'newsChannel'> | OptionalArgType<'threadChannel'>;
- reason: OptionalArgType<'string'>;
+ channel: OptArgType<'textChannel'> | OptArgType<'newsChannel'> | OptArgType<'threadChannel'>;
+ reason: OptArgType<'string'>;
all: ArgType<'boolean'>;
}
) {
diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts
index de16cb5..094cadd 100644
--- a/src/commands/moderation/unmute.ts
+++ b/src/commands/moderation/unmute.ts
@@ -7,7 +7,7 @@ import {
type BushGuildMember,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
@@ -59,7 +59,7 @@ export default class UnmuteCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- { user, reason, force = false }: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force?: boolean }
+ { user, reason, force = false }: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: boolean }
) {
assert(message.inGuild());
assert(message.member);
diff --git a/src/commands/moderation/untimeout.ts b/src/commands/moderation/untimeout.ts
index 636b178..cbaf7d1 100644
--- a/src/commands/moderation/untimeout.ts
+++ b/src/commands/moderation/untimeout.ts
@@ -6,7 +6,7 @@ import {
type ArgType,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
@@ -58,7 +58,7 @@ export default class UntimeoutCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force?: ArgType<'boolean'> }
+ args: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: ArgType<'boolean'> }
) {
assert(message.inGuild());
assert(message.member);
diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts
index 3ab4b0b..87baf4a 100644
--- a/src/commands/moderation/warn.ts
+++ b/src/commands/moderation/warn.ts
@@ -6,7 +6,7 @@ import {
type ArgType,
type BushMessage,
type BushSlashMessage,
- type OptionalArgType
+ type OptArgType
} from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
@@ -57,7 +57,7 @@ export default class WarnCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- { user, reason, force = false }: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force?: boolean }
+ { user, reason, force = false }: { user: ArgType<'user'>; reason: OptArgType<'string'>; force?: boolean }
) {
assert(message.inGuild());
assert(message.member);
diff --git a/src/commands/moulberry-bush/capes.ts b/src/commands/moulberry-bush/capes.ts
index 5564279..a37388b 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, type OptionalArgType } from '#lib';
+import { BushCommand, ButtonPaginator, DeleteButton, type BushMessage, type OptArgType } from '#lib';
import assert from 'assert';
import { APIEmbed } from 'discord-api-types/v10';
import { ApplicationCommandOptionType, AutocompleteInteraction, PermissionFlagsBits } from 'discord.js';
@@ -34,7 +34,7 @@ export default class CapesCommand extends BushCommand {
});
}
- public override async exec(message: BushMessage, args: { cape: OptionalArgType<'string'> }) {
+ public override async exec(message: BushMessage, args: { cape: OptArgType<'string'> }) {
const { tree: neuFileTree }: GithubTreeApi = await got
.get('https://api.github.com/repos/Moulberry/NotEnoughUpdates/git/trees/master?recursive=1')
.json();
diff --git a/src/commands/moulberry-bush/rule.ts b/src/commands/moulberry-bush/rule.ts
index 31f59d7..df6ba88 100644
--- a/src/commands/moulberry-bush/rule.ts
+++ b/src/commands/moulberry-bush/rule.ts
@@ -1,4 +1,4 @@
-import { AllowedMentions, BushCommand, BushSlashMessage, type BushMessage, type OptionalArgType } from '#lib';
+import { AllowedMentions, BushCommand, BushSlashMessage, type BushMessage, type OptArgType } from '#lib';
import { ApplicationCommandOptionType, EmbedBuilder, PermissionFlagsBits } from 'discord.js';
const rules = [
@@ -93,7 +93,7 @@ export default class RuleCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- { rule, user }: { rule: OptionalArgType<'integer'>; user: OptionalArgType<'user'> }
+ { rule, user }: { rule: OptArgType<'integer'>; user: OptArgType<'user'> }
) {
const rulesEmbed = new EmbedBuilder()
.setColor(0xef3929)
diff --git a/src/commands/utilities/steal.ts b/src/commands/utilities/steal.ts
index d603222..765fb24 100644
--- a/src/commands/utilities/steal.ts
+++ b/src/commands/utilities/steal.ts
@@ -1,41 +1,38 @@
-import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib';
+import { BushCommand, OptArgType, type BushMessage, type BushSlashMessage } from '#lib';
import assert from 'assert';
import { type ArgumentGeneratorReturn, type ArgumentType, type ArgumentTypeCaster } from 'discord-akairo';
-import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
+import { ApplicationCommandOptionType, PermissionFlagsBits, type Attachment } from 'discord.js';
import _ from 'lodash';
+import { Stream } from 'stream';
import { URL } from 'url';
assert(_);
+// so I don't have to retype things
+const enum lang {
+ emojiStart = 'What emoji would you like to steal?',
+ emojiRetry = '{error} Pick a valid emoji, emoji id, or image url.',
+ emojiDescription = 'The emoji to steal.',
+ nameStart = 'What would you like to name the emoji?',
+ nameRetry = '{error} Choose a valid name fore the emoji.',
+ nameDescription = 'The name to give the new emoji.'
+}
+
export default class StealCommand extends BushCommand {
public constructor() {
super('steal', {
- aliases: ['steal', 'copy-emoji'],
+ aliases: ['steal', 'copy-emoji', 'emoji'],
category: 'utilities',
description: 'Steal an emoji from another server and add it to your own.',
usage: ['steal <emoji/emojiId/url> [name]'],
examples: ['steal <:omegaclown:782630946435366942> ironm00n'],
- args: [
- {
- id: 'emoji',
- description: 'The emoji to steal.',
- type: util.arg.union('discordEmoji', 'snowflake', 'url'),
- readableType: 'discordEmoji|snowflake|url',
- prompt: 'What emoji would you like to steal?',
- retry: '{error} Pick a valid emoji, emoji id, or image url.',
- optional: true,
- only: 'slash',
- slashType: ApplicationCommandOptionType.String
- },
- {
- id: 'name',
- description: 'The name to give the new emoji.',
- prompt: 'What would you like to name the emoji?',
- retry: '{error} Choose a valid name fore the emoji.',
- optional: true,
- only: 'slash',
- slashType: ApplicationCommandOptionType.String
- }
+ slashOptions: [
+ { name: 'emoji', description: lang.emojiStart, type: ApplicationCommandOptionType.Attachment, required: true },
+ { name: 'name', description: lang.nameStart, type: ApplicationCommandOptionType.String, required: false }
+ ],
+ helpArgs: [
+ { id: 'emoji', description: lang.emojiDescription, readableType: 'emoji|emojiId|url', optional: false },
+ { id: 'name', description: lang.nameDescription, readableType: 'string', optional: true }
],
slash: true,
channel: 'guild',
@@ -50,58 +47,79 @@ export default class StealCommand extends BushCommand {
const emoji = hasImage
? message.attachments.first()!.url
: yield {
- id: 'emoji',
type: util.arg.union('discordEmoji', 'snowflake', 'url') as ArgumentType | ArgumentTypeCaster,
- prompt: {
- start: 'What emoji would you like to steal?',
- retry: '{error} Pick a valid emoji, emoji id, or image url.'
- }
+ prompt: { start: lang.emojiStart, retry: lang.emojiRetry }
};
const name = yield {
- id: 'name',
- prompt: {
- start: 'What would you like to name the emoji?',
- retry: '{error} Choose a valid name fore the emoji.',
- optional: true
- },
- default:
- hasImage && message.attachments.first()?.name
- ? _.camelCase(message.attachments.first()!.name ?? 'stolen_emoji')
- : 'stolen_emoji'
+ prompt: { start: lang.nameStart, retry: lang.nameRetry, optional: true },
+ default: hasImage && message.attachments.first()!.name ? _.snakeCase(message.attachments.first()!.name!) : 'unnamed_emoji'
};
return { emoji, name };
}
public override async exec(
- message: BushMessage | BushSlashMessage,
- args?: { emoji?: ArgType<'discordEmoji'> | ArgType<'snowflake'> | ArgType<'url'> | string; name: string }
+ message: BushMessage,
+ args: { emoji: OptArgType<'discordEmoji'> | OptArgType<'snowflake'> | OptArgType<'url'> | string; name: string }
) {
- if (!args || !args.emoji) return await message.util.reply(`${util.emojis.error} You must provide an emoji to steal.`);
+ assert(message.inGuild());
+
+ if (!args.emoji) return await message.util.reply(`${util.emojis.error} You must provide an emoji to steal.`);
const image =
- args?.emoji instanceof URL
+ args.emoji instanceof URL
? args.emoji.href
- : typeof args?.emoji === 'object'
+ : typeof args.emoji === 'object'
? `https://cdn.discordapp.com/emojis/${args.emoji.id}`
- : client.consts.regex.snowflake.test(args?.emoji ?? '')
+ : client.consts.regex.snowflake.test(args.emoji ?? '')
? `https://cdn.discordapp.com/emojis/${args!.emoji}`
- : (args?.emoji ?? '').match(/https?:\/\//)
- ? args?.emoji
+ : (args.emoji ?? '').match(/https?:\/\//)
+ ? args.emoji
: undefined;
if (image === undefined) return await message.util.reply(`${util.emojis.error} You must provide an emoji to steal.`);
const emojiName =
- args.name ?? args?.emoji instanceof URL
- ? args?.name ?? 'stolen_emoji'
- : typeof args?.emoji === 'object'
- ? args?.name ?? args.emoji.name ?? 'stolen_emoji'
+ args.name ?? args.emoji instanceof URL
+ ? args.name ?? 'stolen_emoji'
+ : typeof args.emoji === 'object'
+ ? args.name ?? args.emoji.name ?? 'stolen_emoji'
: 'stolen_emoji';
- const creationSuccess = await message
- .guild!.emojis.create(image, emojiName, {
+ const creationSuccess = await message.guild.emojis
+ .create(image, emojiName, {
+ reason: `Stolen by ${message.author.tag} (${message.author.id})`
+ })
+ .catch((e: Error) => e);
+
+ if (!(creationSuccess instanceof Error))
+ return await message.util.reply(`${util.emojis.success} You successfully stole ${creationSuccess}.`);
+ else {
+ return await message.util.reply(
+ `${util.emojis.error} The was an error stealing that emoji \`${creationSuccess.message}\`.`
+ );
+ }
+ }
+
+ public override async execSlash(message: BushSlashMessage, args: { emoji: Attachment; name?: string }) {
+ assert(message.inGuild());
+
+ const name = args.name ?? args.emoji.name ?? 'stolen_emoji';
+
+ const data =
+ args.emoji.attachment instanceof Stream
+ ? await (new Promise((resolve, reject) => {
+ let data = '';
+ assert(args.emoji.attachment instanceof Stream);
+ args.emoji.attachment.on('data', (chunk) => (data += chunk));
+ args.emoji.attachment.on('end', () => resolve(data));
+ args.emoji.attachment.on('error', (e) => reject(e));
+ }) as Promise<string>)
+ : args.emoji.attachment;
+
+ const creationSuccess = await message.guild.emojis
+ .create(data, name, {
reason: `Stolen by ${message.author.tag} (${message.author.id})`
})
.catch((e: Error) => e);
diff --git a/src/commands/utilities/viewRaw.ts b/src/commands/utilities/viewRaw.ts
index 20e7272..cb106dd 100644
--- a/src/commands/utilities/viewRaw.ts
+++ b/src/commands/utilities/viewRaw.ts
@@ -1,4 +1,4 @@
-import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib';
+import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptArgType } from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, ChannelType, EmbedBuilder, Message, PermissionFlagsBits } from 'discord.js';
@@ -67,7 +67,7 @@ export default class ViewRawCommand extends BushCommand {
message: BushMessage | BushSlashMessage,
args: {
message: ArgType<'message'> | ArgType<'messageLink'>;
- channel: OptionalArgType<'textChannel'> | OptionalArgType<'newsChannel'> | OptionalArgType<'threadChannel'>;
+ channel: OptArgType<'textChannel'> | OptArgType<'newsChannel'> | OptArgType<'threadChannel'>;
json: boolean;
js: boolean;
}
diff --git a/src/commands/utilities/whoHasRole.ts b/src/commands/utilities/whoHasRole.ts
index ac6f3c5..5f13c02 100644
--- a/src/commands/utilities/whoHasRole.ts
+++ b/src/commands/utilities/whoHasRole.ts
@@ -1,4 +1,4 @@
-import { BushCommand, BushRole, ButtonPaginator, OptionalArgType, type BushMessage, type BushSlashMessage } from '#lib';
+import { BushCommand, BushRole, ButtonPaginator, OptArgType, type BushMessage, type BushSlashMessage } from '#lib';
import assert from 'assert';
import { ApplicationCommandOptionType, Util, type CommandInteraction } from 'discord.js';
@@ -33,7 +33,7 @@ export default class WhoHasRoleCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
args: {
- [K in `role${NumberRange}`]: OptionalArgType<'role'>;
+ [K in `role${NumberRange}`]: OptArgType<'role'>;
}
) {
assert(message.inGuild());
diff --git a/src/lib/extensions/discord-akairo/BushCommand.ts b/src/lib/extensions/discord-akairo/BushCommand.ts
index 958e451..1797be8 100644
--- a/src/lib/extensions/discord-akairo/BushCommand.ts
+++ b/src/lib/extensions/discord-akairo/BushCommand.ts
@@ -284,7 +284,7 @@ interface ExtendedCommandOptions {
/**
* Use instead of {@link BaseBushCommandOptions.args} when using argument generators or custom slashOptions
*/
- helpArgs?: BushArgumentOptions[];
+ helpArgs?: (Omit<BushArgumentOptions, 'slashType'> & { slashType?: AkairoApplicationCommandOptionData['type'] })[];
/**
* Extra information about the command, displayed in the help command.
@@ -340,6 +340,23 @@ export interface ArgsInfo {
type: string;
}
+export interface ArgsInfoText {
+ id: string;
+ description: string;
+ optional?: boolean;
+ only: 'text';
+ type: string;
+}
+
+export interface ArgsInfoSlash {
+ id: string;
+ description: string;
+ optional?: boolean;
+ slashType: AkairoApplicationCommandOptionData['type'] | false;
+ slashResolve?: SlashResolveType;
+ only: 'slash';
+}
+
export class BushCommand extends Command {
public declare client: BushClient;
@@ -486,7 +503,7 @@ export class BushCommand extends Command {
id: arg.id,
description: arg.description,
optional: arg.optional,
- slashType: arg.slashType,
+ slashType: arg.slashType!,
slashResolve: arg.slashResolve,
only: arg.only,
type: (arg.readableType ?? arg.type) as string
@@ -539,4 +556,4 @@ interface PseudoArguments extends BaseBushArgumentType {
}
export type ArgType<T extends keyof PseudoArguments> = NonNullable<PseudoArguments[T]>;
-export type OptionalArgType<T extends keyof PseudoArguments> = PseudoArguments[T];
+export type OptArgType<T extends keyof PseudoArguments> = PseudoArguments[T];
diff --git a/src/lib/extensions/discord.js/other.ts b/src/lib/extensions/discord.js/other.ts
index aeba01c..0560ffc 100644
--- a/src/lib/extensions/discord.js/other.ts
+++ b/src/lib/extensions/discord.js/other.ts
@@ -184,3 +184,5 @@ export type BushGuildCacheMessage<Cached extends CacheType> = CacheTypeReducer<
BushMessage | APIMessage,
BushMessage | APIMessage
>;
+
+export { ApplicationCommandOptionType as SlashType } from 'discord.js';