diff --git a/package-lock.json b/package-lock.json index 32a80bff..284aec9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "joi": "^17.13.1", "jsdom": "^24.0.0", "node-libcurl": "^4.0.0", - "zod": "^3.23.5" + "zod": "^3.23.6" }, "devDependencies": { "@hapi/code": "^9.0.3", @@ -42,7 +42,7 @@ "prettier": "^3.2.5", "prisma": "^5.13.0", "rimraf": "^5.0.5", - "tsx": "^4.8.2", + "tsx": "^4.9.0", "typescript": "^5.4.5" }, "optionalDependencies": { @@ -6989,9 +6989,9 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsx": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.8.2.tgz", - "integrity": "sha512-hmmzS4U4mdy1Cnzpl/NQiPUC2k34EcNSTZYVJThYKhdqTwuBeF+4cG9KUK/PFQ7KHaAaYwqlb7QfmsE2nuj+WA==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.9.0.tgz", + "integrity": "sha512-UY0UUhDPL6MkqkZU4xTEjEBOLfV+RIt4xeeJ1qwK73xai4/zveG+X6+tieILa7rjtegUW2LE4p7fw7gAoLuytA==", "dev": true, "dependencies": { "esbuild": "~0.20.2", @@ -7497,9 +7497,9 @@ } }, "node_modules/zod": { - "version": "3.23.5", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.5.tgz", - "integrity": "sha512-fkwiq0VIQTksNNA131rDOsVJcns0pfVUjHzLrNBiF/O/Xxb5lQyEXkhZWcJ7npWsYlvs+h0jFWXXy4X46Em1JA==", + "version": "3.23.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.6.tgz", + "integrity": "sha512-RTHJlZhsRbuA8Hmp/iNL7jnfc4nZishjsanDAfEY1QpDQZCahUp3xDzl+zfweE9BklxMUcgBgS1b7Lvie/ZVwA==", "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 14bf2ecb..bd0439c4 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "joi": "^17.13.1", "jsdom": "^24.0.0", "node-libcurl": "^4.0.0", - "zod": "^3.23.5" + "zod": "^3.23.6" }, "devDependencies": { "@hapi/code": "^9.0.3", @@ -61,7 +61,7 @@ "prettier": "^3.2.5", "prisma": "^5.13.0", "rimraf": "^5.0.5", - "tsx": "^4.8.2", + "tsx": "^4.9.0", "typescript": "^5.4.5" }, "config": { diff --git a/src/base/Base.ts b/src/base/Base.ts index 44fdfa20..31df0347 100644 --- a/src/base/Base.ts +++ b/src/base/Base.ts @@ -1,4 +1,3 @@ -import type { GuildSettings } from '@prisma/client'; import type { Guild, TextChannel } from 'discord.js'; import { ChannelType } from 'discord.js'; import packageJson from '../../package.json' with { type: 'json' }; @@ -12,7 +11,7 @@ export default abstract class Base { this.db = prisma; this.Sanction = SanctionManager; } - async getGuildSettings(guildId: string): Promise { + async getGuildSettings(guildId: string) { return await this.db.guildSettings.findUnique({ where: { id: guildId, diff --git a/src/commands/Settings.ts b/src/commands/Settings.ts index aaf25040..9ed07b85 100644 --- a/src/commands/Settings.ts +++ b/src/commands/Settings.ts @@ -3,7 +3,9 @@ import { ChannelType, PermissionFlagsBits, SlashCommandBuilder, + inlineCode, } from 'discord.js'; +import { client } from 'index.js'; import type { Config } from '../base/Command.js'; import Command from '../base/Command.js'; @@ -68,7 +70,9 @@ export default class Ping extends Command { .addSubcommand(subcommand => subcommand .setName('ban-approvals') - .setDescription('Set ban approvals') + .setDescription( + 'Set the numbers of ban approvals needed to ban the user.' + ) .addNumberOption(numberOption => numberOption .setName('ban-approvals-setting') @@ -94,6 +98,31 @@ export default class Ping extends Command { ) .setRequired(true) ) + ) + .addSubcommand(subcommand => + subcommand + .setName('enabled-commands') + .setDescription('Toggle active state of commands') + .addStringOption(stringOption => + stringOption + .setName('command-name') + .setDescription( + 'The command name to toggle on/off.' + ) + .setRequired(true) + .setChoices( + ...client.commands.map(command => ({ + name: command.name, + value: command.name, + })) + ) + ) + .addBooleanOption(booleanOption => + booleanOption + .setName('enabled') + .setDescription('Set the status') + .setRequired(true) + ) ); super(cmd as unknown as Config); @@ -112,6 +141,9 @@ export default class Ping extends Command { case 'welcome-message': this.setWelcomeMessage(interaction); break; + case 'enabled-commands': + this.setEnabledCommand(interaction); + break; default: break; } @@ -120,7 +152,7 @@ export default class Ping extends Command { private async setSetting( guildId: string, setting: string, - value: string | number + value: string | string[] | number ) { await this.db.guildSettings.upsert({ where: { @@ -149,40 +181,55 @@ export default class Ping extends Command { } private async setChannel(interaction: ChatInputCommandInteraction) { - const setting = interaction.options.getString('channel-setting'); + if (!interaction.guildId) return; + const setting = interaction.options.getString('channel-setting', true); const channel = interaction.options.getChannel('channel', true); - await this.setSetting( - interaction.guildId as string, - setting as string, - channel.id - ); + await this.setSetting(interaction.guildId, setting, channel.id); interaction.reply(`${setting} set to ${channel}`); } private async setRole(interaction: ChatInputCommandInteraction) { - const setting = interaction.options.getString('role-setting'); + if (!interaction.guildId) return; + const setting = interaction.options.getString('role-setting', true); const role = interaction.options.getRole('role', true); - await this.setSetting( - interaction.guildId as string, - setting as string, - role.id - ); + await this.setSetting(interaction.guildId, setting, role.id); interaction.reply(`${setting} set to ${role}`); } private async setWelcomeMessage(interaction: ChatInputCommandInteraction) { + if (!interaction.guildId) return; const welcomeMessage = interaction.options.getString( - 'welcome-message-setting' + 'welcome-message-setting', + true ); await this.setSetting( - interaction.guildId as string, + interaction.guildId, 'welcomeMessage', - welcomeMessage as string + welcomeMessage ); interaction.reply(`welcomeMessage set to ${welcomeMessage}`); } + + private async setEnabledCommand(interaction: ChatInputCommandInteraction) { + if (!interaction.guildId) return; + const commandName = interaction.options.getString('command-name', true); + const isEnabled = interaction.options.getBoolean('enabled', true); + const guildSettings = await this.getGuildSettings(interaction.guildId); + if (!guildSettings) return; + const disabledCommands = new Set(guildSettings.disabledCommands); + + if (isEnabled) disabledCommands.delete(commandName); + else disabledCommands.add(commandName); + await this.setSetting(interaction.guildId, 'disabledCommands', [ + ...disabledCommands, + ]); + + interaction.reply( + `disabledCommands set to ${inlineCode([...disabledCommands].join(', '))}` + ); + } }