import { SlashCommandBuilder, ChatInputCommandInteraction, EmbedBuilder, APIEmbedField, PermissionFlagsBits } from 'discord.js' import dbGuildInit from '../../utils/dbGuildInit' import dbGuild from '../../schemas/guild' const parseObject = (obj: object, prefix = ''): { name: string, value: object | string | boolean }[] => { let fields: { name: string, value: object | string | boolean }[] = [] for (let [key, value] of Object.entries(obj)) { if (typeof value === 'object') fields.push(...parseObject(value, `${prefix}${key}.`)) else { if (typeof value === 'boolean') value = value ? 'True' : 'False' else if (!value) value = 'None' else value = value.toString() fields.push({ name: `${prefix}${key}`, value }) } } return fields } export default { data: new SlashCommandBuilder() .setName('database') .setDescription('Communicate with the database') .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .addSubcommand(subcommand => subcommand.setName('info').setDescription('Returns information about the current guild')) .addSubcommand(subcommand => subcommand.setName('init').setDescription('Force initialize an entry for the current guild in the database')) .addSubcommand(subcommand => subcommand.setName('edit').setDescription('Modify parameters for the current guild') .addStringOption(option => option.setName('key').setDescription('Key to modify').setRequired(true)) .addStringOption(option => option.setName('value').setDescription('Value to set').setRequired(true))), async execute(interaction: ChatInputCommandInteraction) { let guild = interaction.guild if (!guild) return await interaction.reply({ content: 'This command must be used in a server.', ephemeral: true }) let guildProfile = await dbGuild.findOne({ guildId: guild.id }) if (interaction.options.getSubcommand() === 'info') { if (!guildProfile) return await interaction.reply({ content: `Database data for **${guild.name}** does not exist !` }) let fields = parseObject(guildProfile.toObject()) let embed = new EmbedBuilder() .setTitle('Database Information') .setDescription(`Guild **${guildProfile.guildName}** (ID: ${guildProfile.guildId})`) .setThumbnail(guildProfile.guildIcon as string) .setTimestamp() //.addFields(fields as APIEmbedField[]) // Limit the number of fields to 25 .addFields(fields.slice(0, 25) as APIEmbedField[]) return await interaction.reply({ embeds: [embed] }) } else if (interaction.options.getSubcommand() === 'init') { if (guildProfile) return await interaction.reply({ content: `Database data for **${guildProfile.guildName}** already exists !` }) guildProfile = await dbGuildInit(guild) if (!guildProfile) return await interaction.reply({ content: `An error occured while initializing database data for **${guild.name}** !` }) return await interaction.reply({ content: `Database data for **${guildProfile.guildName}** successfully initialized !` }) } else if (interaction.options.getSubcommand() === 'edit') { if (!guildProfile) return await interaction.reply({ content: `Database data for **${guild.name}** does not exist, please init with \`/database init\` !` }) let key = interaction.options.getString('key', true) let value = interaction.options.getString('value', true) let oldValue = guildProfile.get(key) if (!oldValue) oldValue = 'None' guildProfile.set(key, value) await guildProfile.save().catch(console.error) return await interaction.reply({ content: `Database data for **${guildProfile.guildName}** successfully updated !\n**${key}**: ${oldValue} -> ${value}` }) } } }