diff --git a/.env.example b/.env.example index e226d2c..806548f 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,4 @@ DISCORDAPIKEY=TOKEN APIURL=http://example.com +APIKEY=KEY TZ=Australia/Sydney \ No newline at end of file diff --git a/.gitignore b/.gitignore index 80df32d..1dcef2d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ node_modules -.env -config.json \ No newline at end of file +.env \ No newline at end of file diff --git a/app.js b/app.js index 291817d..3dcb566 100644 --- a/app.js +++ b/app.js @@ -9,18 +9,21 @@ dotenv.config(); // Discord // const client = new SapphireClient({ - intents: [ - 'GUILDS', - 'GUILD_MESSAGES', - 'GUILD_MEMBERS', + intents: [ + "GUILDS", + "GUILD_MESSAGES", + "GUILD_MEMBERS", + "GUILD_MESSAGE_REACTIONS", + ], + presence: { + status: "online", + activities: [ + { + name: "https://modularsoft.org/docs/products/devoteMe/", + type: "PLAYING", + }, ], - presence: { - status: "online", - activities: [{ - name: 'https://modularsoft.org/docs/products/devoteMe/', - type: 'PLAYING' - }] - } + }, }); // diff --git a/commands/configure.mjs b/commands/configure.mjs new file mode 100644 index 0000000..93dd1a0 --- /dev/null +++ b/commands/configure.mjs @@ -0,0 +1,163 @@ +import { Command, RegisterBehavior } from "@sapphire/framework"; +import { MessageEmbed, Permissions } from "discord.js"; +import fetch from "node-fetch"; +import { getTenantConfiguration } from "../controller/tenantController.js"; + +export class ConfigureCommand extends Command { + constructor(context, options) { + super(context, { + ...options, + description: "Configure various settings for the server.", + chatInputCommand: { + register: true, + behaviorWhenNotIdentical: RegisterBehavior.Overwrite, + }, + }); + } + + registerApplicationCommands(registry) { + registry.registerChatInputCommand((builder) => + builder + .setName("configure") + .setDescription(this.description) + .addSubcommand((subcommand) => + subcommand + .setName("votd-channel") + .setDescription( + "Set the VOTD channel (only text channels can be selected)." + ) + .addChannelOption( + (option) => + option + .setName("channel") + .setDescription("The channel to set as VOTD channel") + .setRequired(true) + .addChannelTypes(0) // Only text channels + ) + ) + .addSubcommand((subcommand) => + subcommand + .setName("devotion-channel") + .setDescription("Set the Devotion channel.") + .addChannelOption( + (option) => + option + .setName("channel") + .setDescription("The channel to set as Devotion channel") + .setRequired(true) + .addChannelTypes(0) // Only text channels + ) + ) + .addSubcommand((subcommand) => + subcommand + .setName("view") + .setDescription( + "View the current VOTD and Devotion channel configuration." + ) + ) + ); + } + + async chatInputRun(interaction) { + if (!interaction.member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) { + const embed = new MessageEmbed() + .setColor("RED") + .setTitle("Permission Denied") + .setDescription("You need to be an admin to run this command."); + return interaction.reply({ embeds: [embed], ephemeral: true }); + } + + const subcommand = interaction.options.getSubcommand(); + + try { + if (subcommand === "votd-channel") { + const channel = interaction.options.getChannel("channel"); + await this.updateChannelConfig( + interaction.guild.id, + "votd_channel", + channel.id + ); + + const embed = new MessageEmbed() + .setColor("GREEN") + .setTitle("Configuration Updated") + .setDescription(`VOTD channel has been set to <#${channel.id}>.`); + return interaction.reply({ embeds: [embed], ephemeral: true }); + } + + if (subcommand === "devotion-channel") { + const channel = interaction.options.getChannel("channel"); + await this.updateChannelConfig( + interaction.guild.id, + "devotion_channel", + channel.id + ); + + const embed = new MessageEmbed() + .setColor("GREEN") + .setTitle("Configuration Updated") + .setDescription(`Devotion channel has been set to <#${channel.id}>.`); + return interaction.reply({ embeds: [embed], ephemeral: true }); + } + + if (subcommand === "view") { + const config = await getTenantConfiguration(interaction.guild.id); + const embed = new MessageEmbed() + .setTitle("Current Configuration") + .setColor("#0099ff") + .addFields( + { + name: "VOTD Channel", + value: config.votd_channel + ? `<#${config.votd_channel}>` + : "Not configured", + }, + { + name: "Devotion Channel", + value: config.devotion_channel + ? `<#${config.devotion_channel}>` + : "Not configured", + } + ); + + return interaction.reply({ embeds: [embed], ephemeral: true }); + } + } catch (error) { + console.error(error); + const embed = new MessageEmbed() + .setColor("RED") + .setTitle("Error") + .setDescription("There was an error while configuring the channels."); + return interaction.reply({ embeds: [embed], ephemeral: true }); + } + } + + async updateChannelConfig(tenantId, channelType, channelId) { + try { + const fetchURL = `${process.env.APIURL}/api/tenant/update`; + const response = await fetch(fetchURL, { + method: "POST", + headers: { + "x-access-token": process.env.APIKEY, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + tenantId: tenantId, + [channelType]: channelId, + }), + }); + + if (!response.ok) { + throw new Error(`Failed to update ${channelType}`); + } + + const data = await response.json(); + if (!data.success) { + throw new Error(`API response: ${data.message}`); + } + } catch (error) { + console.error(`Error updating channel configuration: ${error.message}`); + throw new Error("Failed to update channel configuration."); + } + } +} \ No newline at end of file diff --git a/commands/devotion.mjs b/commands/devotion.mjs index 5b0fb39..ad529cf 100644 --- a/commands/devotion.mjs +++ b/commands/devotion.mjs @@ -1,14 +1,18 @@ -import { Command, RegisterBehavior } from '@sapphire/framework'; -import { compileDevotionMessage, getDevotion } from '../controller/devotionController'; +import { Command, RegisterBehavior } from "@sapphire/framework"; +import { + compileDevotionMessage, + getDevotion, +} from "../controller/devotionController.js"; +import { MessageEmbed } from "discord.js"; export class DevotionCommand extends Command { constructor(context, options) { super(context, { ...options, - description: 'Display today\'s Devotion.', + description: "Display today's Devotion.", chatInputCommand: { register: true, - behaviorWhenNotIdentical: RegisterBehavior.Overwrite + behaviorWhenNotIdentical: RegisterBehavior.Overwrite, }, }); } @@ -22,9 +26,25 @@ export class DevotionCommand extends Command { } async chatInputRun(interaction) { - const devotionData = await getDevotion(); - const embed = await compileDevotionMessage(devotionData); + try { + const devotionData = await getDevotion(); + const embed = await compileDevotionMessage(devotionData); - return interaction.reply({ embeds: [embed] }); + // Reply with the devotion message embed + await interaction.reply({ embeds: [embed] }); + } catch (error) { + console.error(error); + + // Create an error embed + const errorEmbed = new MessageEmbed() + .setColor("RED") + .setTitle("Error") + .setDescription( + "An error occurred while processing the devotion. Please try again later." + ); + + // Reply with the error embed + await interaction.reply({ embeds: [errorEmbed], ephemeral: true }); + } } } \ No newline at end of file diff --git a/commands/votd.mjs b/commands/votd.mjs index 50babc4..05727a1 100644 --- a/commands/votd.mjs +++ b/commands/votd.mjs @@ -1,5 +1,5 @@ import { Command, RegisterBehavior } from '@sapphire/framework'; -import { compileVotdMessage, getVotd } from '../controller/votdController'; +import { compileVotdMessage, getVotd } from '../controller/votdController.js'; export class VotdCommand extends Command { constructor(context, options) { diff --git a/config.json.example b/config.json.example deleted file mode 100644 index 641644d..0000000 --- a/config.json.example +++ /dev/null @@ -1,9 +0,0 @@ -{ - "discord": { - "guildID": "GUILDID", - "channel": { - "devotion": "DEVOTIONCHANNELID", - "votd": "VOTDCHANNELID" - } - } -} \ No newline at end of file diff --git a/controller/devotionController.js b/controller/devotionController.js index 326eee2..ab9e2b9 100644 --- a/controller/devotionController.js +++ b/controller/devotionController.js @@ -1,6 +1,6 @@ import fetch from 'node-fetch'; -import config from '../config.json' assert {type: "json"}; -import { MessageEmbed } from 'discord.js'; +import { MessageActionRow, MessageButton, MessageEmbed } from 'discord.js'; +import { getTenantConfiguration, getTenants } from './tenantController.js'; /* Get Devotion from API. @@ -46,25 +46,113 @@ export async function compileDevotionMessage(devotionData) { Send Devotion to channel */ export async function sendDevotion(client) { - try { - const devotionData = await getDevotion(); - const embed = await compileDevotionMessage(devotionData); + try { + const devotionData = await getDevotion(); + const embed = await compileDevotionMessage(devotionData); - const guild = await client.guilds.cache.get(config.discord.guildID); - if (!guild) { - console.log('Guild not found.'); - return; - } + const doneButton = new MessageButton() + .setCustomId("done_button") + .setLabel("📖 Complete") + .setStyle("SUCCESS"); + + const actionRow = new MessageActionRow().addComponents(doneButton); + + let tenants = await getTenants(); + if (!Array.isArray(tenants)) { + tenants = [tenants]; + } + + for (const tenant of tenants) { + const guild = await client.guilds.cache.get(tenant.tenantId); + if (!guild) { + console.log("Guild not found."); + continue; + } + + const tenantConfig = await getTenantConfiguration(tenant.tenantId); + const devotionChannel = guild.channels.cache.get( + tenantConfig.devotion_channel + ); + if (!devotionChannel) { + console.log("Channel not found."); + continue; + } + + const message = await devotionChannel.send({ + embeds: [embed], + components: [actionRow], + }); + + console.log(`Devotion Message sent to: ${tenant.tenantName}`); + + const filter = (interaction) => interaction.customId === "done_button"; + const collector = message.createMessageComponentCollector({ + filter, + time: 86400000, // Collect for 24 hours + }); - const devotionChannel = guild.channels.cache.get(config.discord.channel.devotion); - if (!devotionChannel) { - console.log('Channel not found.'); - return; + collector.on("collect", async (interaction) => { + await interaction.deferUpdate(); + + const checkURL = `${process.env.APIURL}/api/devotion/check?tenantId=${interaction.guild.id}&messageId=${message.id}&userId=${interaction.user.id}`; + const checkResponse = await fetch(checkURL, { + method: "GET", + headers: { + "x-access-token": process.env.APIKEY, + "Content-Type": "application/json", + }, + }); + + const checkData = await checkResponse.json(); + + if (checkData.exists) { + const completedEmbed = new MessageEmbed() + .setColor("RED") + .setTitle("Error") + .setDescription("You have already completed this devotion!"); + await interaction.followUp({ + embeds: [completedEmbed], + ephemeral: true, + }); + return; } - devotionChannel.send({ embeds: [embed] }); - } catch (error) { - console.log(error); - return; + const fetchURL = `${process.env.APIURL}/api/devotion/add`; + const response = await fetch(fetchURL, { + method: "POST", + headers: { + "x-access-token": process.env.APIKEY, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + tenantId: interaction.guild.id, + userId: interaction.user.id, + messageId: message.id, + }), + }); + + if (response.ok) { + const successEmbed = new MessageEmbed() + .setColor("GREEN") + .setTitle("Devotion Completed") + .setDescription("Devotion marked as complete!"); + await interaction.followUp({ + embeds: [successEmbed], + ephemeral: true, + }); + } else { + const errorEmbed = new MessageEmbed() + .setColor("RED") + .setTitle("Error") + .setDescription("An error occurred while marking as complete."); + await interaction.followUp({ + embeds: [errorEmbed], + ephemeral: true, + }); + } + }); } + } catch (error) { + console.log(error); + } } \ No newline at end of file diff --git a/controller/tenantController.js b/controller/tenantController.js new file mode 100644 index 0000000..9d83a31 --- /dev/null +++ b/controller/tenantController.js @@ -0,0 +1,51 @@ +export async function getTenants() { + try { + const fetchURL = `${process.env.APIURL}/api/tenant/get`; + const response = await fetch(fetchURL, { + method: "GET", + headers: { + "x-access-token": process.env.APIKEY, + }, + }); + + if (!response.ok) { + throw new Error("Failed to fetch tenants."); + } + + const data = await response.json(); + if (!data.success) { + throw new Error(`API response: ${data.message}`); + } + + return data.data; + } catch (error) { + console.error(`Error fetching configuration: ${error.message}`); + throw new Error("Failed to fetch tenants."); + } +} + +export async function getTenantConfiguration(tenantId) { + try { + const fetchURL = `${process.env.APIURL}/api/tenant/configuration/get?id=${tenantId}`; + const response = await fetch(fetchURL, { + method: "GET", + headers: { + "x-access-token": process.env.APIKEY, + }, + }); + + if (!response.ok) { + throw new Error("Failed to fetch current configuration."); + } + + const data = await response.json(); + if (!data.success) { + throw new Error(`API response: ${data.message}`); + } + + return data.data[0]; + } catch (error) { + console.error(`Error fetching configuration: ${error.message}`); + throw new Error("Failed to fetch current configuration."); + } +} diff --git a/controller/votdController.js b/controller/votdController.js index e148544..7bee837 100644 --- a/controller/votdController.js +++ b/controller/votdController.js @@ -1,6 +1,6 @@ import fetch from 'node-fetch'; -import config from '../config.json' assert {type: "json"}; -import { MessageEmbed } from 'discord.js'; +import { MessageActionRow, MessageButton, MessageEmbed } from 'discord.js'; +import { getTenantConfiguration, getTenants } from './tenantController.js'; /* Get VOTD from API. @@ -40,25 +40,121 @@ export async function compileVotdMessage(votdData) { Send Votd to channel */ export async function sendVotd(client) { - try { - const votdData = await getVotd(); - const embed = await compileVotdMessage(votdData); + try { + const votdData = await getVotd(); + const embed = await compileVotdMessage(votdData); - const guild = await client.guilds.cache.get(config.discord.guildID); - if (!guild) { - console.log('Guild not found.'); - return; - } + // Create the "Done" button with primary color (PRIMARY style) + const doneButton = new MessageButton() + .setCustomId("done_button") + .setLabel("💭 Reflected") + .setStyle("PRIMARY"); - const votdChannel = guild.channels.cache.get(config.discord.channel.votd); - if (!votdChannel) { - console.log('Channel not found.'); - return; - } + // Create an action row and add the button to it + const actionRow = new MessageActionRow().addComponents(doneButton); - votdChannel.send({ embeds: [embed] }); - } catch (error) { - console.log(error); - return; + let tenants = await getTenants(); + if (!Array.isArray(tenants)) { + tenants = [tenants]; } -} \ No newline at end of file + + for (const tenant of tenants) { + const guild = await client.guilds.cache.get(tenant.tenantId); + if (!guild) { + console.log("Guild not found."); + continue; + } + + const tenantConfig = await getTenantConfiguration(tenant.tenantId); + console.log(tenantConfig); + + const votdChannel = guild.channels.cache.get( + tenantConfig.votd_channel + ); + if (!votdChannel) { + console.log("Channel not found."); + return; + } + + // Send the embed message with the button + const message = await votdChannel.send({ + embeds: [embed], + components: [actionRow], // Add the button to the components field + }); + + // Set up a collector to track button interactions + const filter = (interaction) => interaction.customId === "done_button"; + const collector = message.createMessageComponentCollector({ + filter, + time: 86400000, // Collect for 24 hours + }); + + collector.on("collect", async (interaction) => { + // Acknowledge the interaction + await interaction.deferUpdate(); + + // Check if the user already has a VOTD entry + const checkURL = `${process.env.APIURL}/api/votd/check?tenantId=${interaction.guild.id}&messageId=${message.id}&userId=${interaction.user.id}`; + const checkResponse = await fetch(checkURL, { + method: "GET", + headers: { + "x-access-token": process.env.APIKEY, + "Content-Type": "application/json", + }, + }); + + const checkData = await checkResponse.json(); + + // If the entry exists, notify the user and return early + if (checkData.exists) { + const completedEmbed = new MessageEmbed() + .setColor("RED") + .setTitle("Error") + .setDescription("You have already reflected on this VOTD!"); + await interaction.followUp({ + embeds: [completedEmbed], + ephemeral: true, + }); + return; + } + + // Otherwise, add the VOTD entry + const fetchURL = `${process.env.APIURL}/api/votd/add`; + const response = await fetch(fetchURL, { + method: "POST", + headers: { + "x-access-token": process.env.APIKEY, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + tenantId: interaction.guild.id, + userId: interaction.user.id, + messageId: message.id, + }), + }); + + if (response.ok) { + const successEmbed = new MessageEmbed() + .setColor("GREEN") + .setTitle("VOTD Completed") + .setDescription("VOTD marked as complete!"); + await interaction.followUp({ + embeds: [successEmbed], + ephemeral: true, + }); + } else { + const errorEmbed = new MessageEmbed() + .setColor("RED") + .setTitle("Error") + .setDescription("An error occurred while marking as complete."); + await interaction.followUp({ + embeds: [errorEmbed], + ephemeral: true, + }); + } + }); + } + } catch (error) { + console.log(error); + } +} diff --git a/cron/daily.js b/cron/daily.js index c10fe25..dd73116 100644 --- a/cron/daily.js +++ b/cron/daily.js @@ -1,12 +1,12 @@ import cron from 'node-cron'; -import { sendDevotion } from '../controller/devotionController'; -import { sendVotd } from '../controller/votdController'; +import { sendDevotion } from '../controller/devotionController.js'; +import { sendVotd } from '../controller/votdController.js'; // -// DAILY Cron Jobs [Firing at 7:00am] +// DAILY Cron Jobs [Firing at 6:00am] // export default async function dailyCron(client) { - const sendDevotionTask = cron.schedule('0 7 * * *', async function () { + const sendDevotionTask = cron.schedule('0 6 * * *', async function () { sendDevotion(client); }, { scheduled: true, @@ -15,7 +15,7 @@ export default async function dailyCron(client) { sendDevotionTask.start(); - const sendVotdTask = cron.schedule('0 7 * * *', async function () { + const sendVotdTask = cron.schedule('0 6 * * *', async function () { sendVotd(client); }, { scheduled: true, diff --git a/listeners/guildCreate.js b/listeners/guildCreate.js new file mode 100644 index 0000000..a7cf267 --- /dev/null +++ b/listeners/guildCreate.js @@ -0,0 +1,44 @@ +import { Listener } from "@sapphire/framework"; +import fetch from "node-fetch"; + +export class GuildCreateListener extends Listener { + async run(guild) { + console.log(`Guild created: ${guild.name} (ID: ${guild.id})`); + + const fetchURL = `${process.env.APIURL}/api/tenant/create`; + console.log(`Making API request to: ${fetchURL}`); + + try { + const response = await fetch(fetchURL, { + method: "POST", + headers: { + "x-access-token": process.env.APIKEY, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + tenantId: guild.id, + tenantName: guild.name, + }), + }); + + const responseData = await response.json(); + + if (response.ok && responseData.success) { + console.log( + `Successfully created tenant for guild: ${guild.name} (ID: ${guild.id}). Response: `, + responseData + ); + } else { + console.error( + `Failed to create tenant for guild: ${guild.name} (ID: ${guild.id}). Response status: ${response.status}, Response: `, + responseData + ); + } + } catch (error) { + console.error( + `Error occurred while making API request for guild: ${guild.name} (ID: ${guild.id})`, + error + ); + } + } +} diff --git a/listeners/messageDelete.js b/listeners/messageDelete.js new file mode 100644 index 0000000..6b65658 --- /dev/null +++ b/listeners/messageDelete.js @@ -0,0 +1,16 @@ +import { Listener } from "@sapphire/framework"; + +export class MessageDeleteListener extends Listener { + constructor(context) { + super(context, { + event: "messageDelete", + }); + } + + async run(message) { + console.log( + `Message deleted in guild: ${message.guild.name} (ID: ${message.guild.id}), channel: ${message.channel.name} (ID: ${message.channel.id})` + ); + console.log(`Deleted Message ID: ${message.id}`); + } +} \ No newline at end of file diff --git a/listeners/messageUpdate.js b/listeners/messageUpdate.js new file mode 100644 index 0000000..5ff2834 --- /dev/null +++ b/listeners/messageUpdate.js @@ -0,0 +1,17 @@ +import { Listener } from "@sapphire/framework"; + +export class MessageUpdateListener extends Listener { + constructor(context) { + super(context, { + event: "messageUpdate", + }); + } + + async run(oldMessage, newMessage) { + console.log( + `Message updated in guild: ${newMessage.guild.name} (ID: ${newMessage.guild.id}), channel: ${newMessage.channel.name} (ID: ${newMessage.channel.id})` + ); + console.log(`Old Content: ${oldMessage.content}`); + console.log(`New Content: ${newMessage.content}`); + } +} \ No newline at end of file diff --git a/listeners/ready.js b/listeners/ready.js index a6d4a6c..5a5d181 100644 --- a/listeners/ready.js +++ b/listeners/ready.js @@ -1,4 +1,5 @@ import { Listener } from '@sapphire/framework'; +import { sendDevotion } from '../controller/devotionController.js'; export class ReadyListener extends Listener { async run(client) { diff --git a/package-lock.json b/package-lock.json index 0f93059..a343f52 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,14 +10,14 @@ "license": "ISC", "dependencies": { "@sapphire/framework": "^3.2.0", - "discord.js": "^13.16.0", - "dotenv": "^16.0.3", - "node-cron": "^3.0.2", - "node-fetch": "^3.3.1", + "discord.js": "^13.17.1", + "dotenv": "^16.4.7", + "node-cron": "^3.0.3", + "node-fetch": "^3.3.2", "nodemon": "^2.0.22" }, "engines": { - "node": "16.17.0", + "node": "20.0.0", "npm": ">=8.5.0" } }, @@ -38,17 +38,17 @@ } }, "node_modules/@discordjs/collection": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.0.tgz", - "integrity": "sha512-suyVndkEAAWrGxyw/CPGdtXoRRU6AUNkibtnbJevQzpelkJh3Q1gQqWDpqf5i39CnAn5+LrN0YS+cULeEjq2Yw==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/@sapphire/async-queue": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", - "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz", + "integrity": "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" @@ -82,9 +82,9 @@ } }, "node_modules/@sapphire/duration": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@sapphire/duration/-/duration-1.1.0.tgz", - "integrity": "sha512-ATb2pWPLcSgG7bzvT6MglUcDexFSufr2FLXUmhipWGFtZbvDhkopGBIuHyzoGy7LZvL8UY5T6pRLNdFv5pl/Lg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@sapphire/duration/-/duration-1.1.4.tgz", + "integrity": "sha512-hxtuE8HvmWcRok2A10lJ+ic8qY0oYGTTn44XmESUYJYYSVJWmqlCH1LnNYi6Ul+LRjxNUfFQEL/TJS0GJ+8kew==", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" @@ -111,11 +111,11 @@ } }, "node_modules/@sapphire/lexure": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@sapphire/lexure/-/lexure-1.1.2.tgz", - "integrity": "sha512-+v3P3EMDdFoybHH7c7cMcz30jEyxujkxWu5f958cf/Sm27fMM0IqwILnNFUpExZCBAueEM/eoSgbRl4q+K+0jg==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@sapphire/lexure/-/lexure-1.1.10.tgz", + "integrity": "sha512-odE4FD0SkCxkwEOhzAOqEnCJ/oJlPUuyFEw2KJacIuGiwY86WRTPIHLg1rt6XmfSYLxGXiqRf74req43+wRV9g==", "dependencies": { - "@sapphire/result": "^2.6.0" + "@sapphire/result": "^2.7.2" }, "engines": { "node": ">=v14.0.0", @@ -123,13 +123,13 @@ } }, "node_modules/@sapphire/pieces": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@sapphire/pieces/-/pieces-3.6.1.tgz", - "integrity": "sha512-LKa0WaaDNwLP0pkRRSgZ9POrH/S2xx+iiymbp8TcB1U5R8ra9y1ijgHwksJJ/ofL/zEHN1Dgx6gZwLBn+Mkb7Q==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@sapphire/pieces/-/pieces-3.10.0.tgz", + "integrity": "sha512-iBaux50dA+VYjtBqmaceWcskdmw7ua51ojEPkyaSJyg2t9ln/Wc9NqYoQheRCWltZeDTERCUBIYYMqDuCs1Okw==", "dependencies": { - "@discordjs/collection": "^1.4.0", - "@sapphire/utilities": "^3.11.0", - "tslib": "^2.5.0" + "@discordjs/collection": "^1.5.3", + "@sapphire/utilities": "^3.13.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=v14.0.0", @@ -137,42 +137,41 @@ } }, "node_modules/@sapphire/ratelimits": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/@sapphire/ratelimits/-/ratelimits-2.4.6.tgz", - "integrity": "sha512-E8ZogD+gtXw/iAFuyd42ZzUcYzOC3qGXZFOjU12o0cSYWObh7kQEqkS62BB0hMXy+GJH0X2+kqgMklME8EhWUg==", + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/@sapphire/ratelimits/-/ratelimits-2.4.11.tgz", + "integrity": "sha512-O6FNA/P0wxU4Ve9gxL948CoZw7+sSpujyUR2CLyLLCNuNvuFGFxPCJVl5crFVLXMIyBIrc2qk+/H9bsqsyQK1Q==", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" } }, "node_modules/@sapphire/result": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@sapphire/result/-/result-2.6.0.tgz", - "integrity": "sha512-gdW6n/oDZ8aC1439Ub3RiLQ6L4VHAxbN0AhGJWNkEZ6Z6Ww2V62fwRiA/73OPfgYQKXk9ljhAFiqNO91KAonHQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@sapphire/result/-/result-2.7.2.tgz", + "integrity": "sha512-DJbCGmvi8UZAu/hh85auQL8bODFlpcS3cWjRJZ5/cXTLekmGvs/CrRxrIzwbA6+poyYojo5rK4qu8trmjfneog==", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" } }, "node_modules/@sapphire/shapeshift": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.8.2.tgz", - "integrity": "sha512-NXpnJAsxN3/h9TqQPntOeVWZrpIuucqXI3IWF6tj2fWCoRLCuVK5wx7Dtg7pRrtkYfsMUbDqgKoX26vrC5iYfA==", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz", + "integrity": "sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==", "dependencies": { "fast-deep-equal": "^3.1.3", "lodash": "^4.17.21" }, "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" + "node": ">=v16" } }, "node_modules/@sapphire/stopwatch": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@sapphire/stopwatch/-/stopwatch-1.5.0.tgz", - "integrity": "sha512-DtyKugdy3JTqm6JnEepTY64fGJAqlusDVrlrzifEgSCfGYCqpvB+SBldkWtDH+z+zLcp+PyaFLq7xpVfkhmvGg==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@sapphire/stopwatch/-/stopwatch-1.5.4.tgz", + "integrity": "sha512-IVI48D2yAz411bSttXyTkBH0p2vhrXoqWLn5loDDSAAEUGkM1r5KNCX2027ifQ8svdoMkUfIGjFueR+satLeWw==", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.8.1" }, "engines": { "node": ">=v14.0.0", @@ -180,54 +179,38 @@ } }, "node_modules/@sapphire/utilities": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@sapphire/utilities/-/utilities-3.11.0.tgz", - "integrity": "sha512-ich7J+329UTEgWxgk8b871rMhbFW/hvXdabdiKaUKd6g10eIMkIakWf+EGkDQsiDSiebIXll9TIPPmWtN3cVSw==", + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/@sapphire/utilities/-/utilities-3.18.1.tgz", + "integrity": "sha512-zyEyQOQb2/t2mKRmu8T+M4r1Ulb+54BjwDS5pfzf6abGzTAcUg4VDWjHeKX7p3IgiZTcpN4Ij77b9k+K1KV4Lg==", "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" + "node": ">=v14.0.0" } }, "node_modules/@types/node": { - "version": "18.15.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", - "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" - }, - "node_modules/@types/node-fetch": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.3.tgz", - "integrity": "sha512-ETTL1mOEdq/sxUtgtOhKjyB2Irra4cjxksvcMUR5Zr4n+PxVhsCD9WS46oPbHL3et9Zde7CNRr+WUNlcHvsX+w==", + "version": "22.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz", + "integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==", "dependencies": { - "@types/node": "*", - "form-data": "^3.0.0" + "undici-types": "~6.20.0" } }, - "node_modules/@types/node-fetch/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" + "@types/node": "*", + "form-data": "^4.0.0" } }, "node_modules/@types/ws": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", - "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", "dependencies": { "@types/node": "*" } }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -251,11 +234,14 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/brace-expansion": { @@ -268,26 +254,20 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -300,6 +280,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -350,9 +333,9 @@ "integrity": "sha512-bz/NDyG0KBo/tY14vSkrwQ/n3HKPf87a0WFW/1M9+tXYK+vp5Z5EksawfCWo2zkAc6o7CClc0eff1Pjrqznlwg==" }, "node_modules/discord.js": { - "version": "13.16.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.16.0.tgz", - "integrity": "sha512-bOoCs1Ilojd/UshZVxmEcpxVmHcYOv2fPVZOVq3aFV8xrKLJfaF9mxlvGZ1D1z9aIqf2NkptDr+QndeNuQBTxQ==", + "version": "13.17.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.17.1.tgz", + "integrity": "sha512-h13kUf+7ZaP5ZWggzooCxFutvJJvugcAO54oTEIdVr3zQWi0Sf/61S1kETtuY9nVAyYebXR/Ey4C+oWbsgEkew==", "dependencies": { "@discordjs/builders": "^0.16.0", "@discordjs/collection": "^0.7.0", @@ -384,9 +367,9 @@ "integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg==" }, "node_modules/discord.js/node_modules/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -403,11 +386,14 @@ } }, "node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", "engines": { "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, "node_modules/fast-deep-equal": { @@ -438,9 +424,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -449,9 +435,9 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -473,9 +459,9 @@ } }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "optional": true, "os": [ @@ -588,9 +574,9 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/node-cron": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.2.tgz", - "integrity": "sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz", + "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", "dependencies": { "uuid": "8.3.2" }, @@ -617,9 +603,9 @@ } }, "node_modules/node-fetch": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", - "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -660,20 +646,6 @@ "url": "https://opencollective.com/nodemon" } }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -710,9 +682,9 @@ } }, "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "bin": { "semver": "bin/semver" } @@ -759,12 +731,9 @@ } }, "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dependencies": { - "nopt": "~1.0.10" - }, + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", "bin": { "nodetouch": "bin/nodetouch.js" } @@ -775,20 +744,25 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/ts-mixer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", - "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==" }, "node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -798,9 +772,9 @@ } }, "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "engines": { "node": ">= 8" } @@ -820,9 +794,9 @@ } }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index 55df41b..1408ef5 100644 --- a/package.json +++ b/package.json @@ -12,17 +12,17 @@ }, "engines": { "npm": ">=8.5.0", - "node": "16.17.0" + "node": "20.0.0" }, "keywords": [], "author": "ModularSoft", "license": "ISC", "dependencies": { "@sapphire/framework": "^3.2.0", - "discord.js": "^13.16.0", - "dotenv": "^16.0.3", - "node-cron": "^3.0.2", - "node-fetch": "^3.3.1", + "discord.js": "^13.17.1", + "dotenv": "^16.4.7", + "node-cron": "^3.0.3", + "node-fetch": "^3.3.2", "nodemon": "^2.0.22" } }