diff --git a/.eslintrc.json b/.eslintrc.json index d9f1353..d3c83fb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,36 +1,23 @@ { - "env": { - "browser": true, - "es6": true - }, - "extends": [ - "airbnb-base" - ], - "globals": { - "Atomics": "readonly", - "SharedArrayBuffer": "readonly" - }, - "parserOptions": { - "ecmaVersion": 2018, - "sourceType": "module" - }, - "rules": { - "consistent-return": 0, - "no-console": 0, - "max-len": 0, - "no-useless-return": 0, - "linebreak-style": 0, - "no-case-declarations": 0, - "no-shadow": 0, - "no-restricted-globals": 0, - "no-plusplus": 0, - "camelcase": 0, - "global-require":0, - "import/no-dynamic-require": 0, - "no-unused-expressions": 0, - "no-unused-vars": 0, - "prefer-destructuring": 0, - "no-return-assign": 0, - "no-undef": 0 - } -} \ No newline at end of file + "env": { + "es2021": true, + "node": true + }, + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], + "overrides": [], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["@typescript-eslint", "prettier"], + "rules": { + "prettier/prettier": "warn", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_" + } + ] + } +} diff --git a/.gitignore b/.gitignore index 94fc1be..8e16fba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,48 +1,8 @@ # Logs logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release # Dependency directories node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ # TypeScript cache *.tsbuildinfo @@ -53,58 +13,13 @@ typings/ # Optional eslint cache .eslintcache -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - # dotenv environment variables file .env .env.test -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt +# TS Output dist -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - # Custom -test_token.json -config/config.json -.vscode/settings.json -.vsls.json \ No newline at end of file +.vscode/*.json +!.vscode/launch.json \ No newline at end of file diff --git a/.husky/.gitignore b/.husky/.gitignore new file mode 100644 index 0000000..31354ec --- /dev/null +++ b/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..20d0d06 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npm run lint diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..249459a --- /dev/null +++ b/.prettierignore @@ -0,0 +1,24 @@ +# Logs +logs + +# Dependency directories +node_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# dotenv environment variables file +.env +.env.test + +# TS Output +dist + +# Custom +.vscode/settings.json \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..b14cf56 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "trailingComma": "none", + "tabWidth": 2, + "semi": true, + "singleQuote": true, + "endOfLine": "lf", + "printWidth": 120 +} \ No newline at end of file diff --git a/.snyk b/.snyk new file mode 100644 index 0000000..af1a88f --- /dev/null +++ b/.snyk @@ -0,0 +1,5 @@ +exclude: + global: + - dist/** + - src/typings/Bitfield.js + - src/configs/** \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 3cbc8d8..0c57b8c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,15 +1,23 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "node", - "request": "launch", - "name": "Agent Black", - "program": "${workspaceFolder}/index.js", - "envFile": "${workspaceFolder}/.env" - } - ] -} \ No newline at end of file + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Run Agent Black", + "skipFiles": [ + "/**" + ], + "program": "index.js", + "cwd": "${workspaceFolder}/dist", + "runtimeArgs": [ + "--no-warnings" + ], + "envFile": "${workspaceFolder}/.env", + "preLaunchTask": "tsc: build - tsconfig.json", + "outFiles": [ + "${workspaceFolder}/dist/**/*.js" + ] + } + ] +} diff --git a/ABOUT.md b/ABOUT.md new file mode 100644 index 0000000..aae1581 --- /dev/null +++ b/ABOUT.md @@ -0,0 +1,5 @@ +# Agent Black + +Agent Black is a blacklist bot. It stores every ban of every participating server. This bot is designed to warn participating servers of members who have been banned (or who are troublesome) in other participating servers. Currently, the bot has more than several thousand users blacklisted. + +The guide on how to add the bot to your server, can be found [here](https://github.com/FlippedCode/agent-black/wiki/Bot---Getting-Started). If you have trouble with something, feel free to [have a look into the wiki](https://github.com/FlippedCode/agent-black/wiki) or [join our Discord server](https://discord.gg/TqBwHtzzhD) \ No newline at end of file diff --git a/about.txt b/about.txt deleted file mode 100644 index 7a82efa..0000000 --- a/about.txt +++ /dev/null @@ -1,3 +0,0 @@ -Agent Black is a blacklist bot. It stores every ban of every participating server. This bot is designed to warn participating servers of members who have been banned (or who are troublesome) in other participating servers. Currently, the bot has more than several thousand users blacklisted. - -For more Information, please have a look at the wiki https://github.com/FlippedCodes/agent-black/wiki or join our Discord server https://discord.gg/TqBwHtzzhD if you need any assistance. diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..fd0b39c --- /dev/null +++ b/changelog.md @@ -0,0 +1,16 @@ +# Agent Black Changelog + +## 4.0.0 - New Beginnings +### Additions +* Add typings for models and functions +* Add TypeScript configuration files + +### Changes +* Fixed some typos +* Updated string concatenation +* Upgraded and version locked all dependencies +* Changed file structure to support TS compiler + +### Deletions +* Removed all archive files +* Removed unneeded gitignore entries \ No newline at end of file diff --git a/changelog.txt b/changelog.txt deleted file mode 100644 index da03556..0000000 --- a/changelog.txt +++ /dev/null @@ -1,23 +0,0 @@ -**Changelog:** -__Bot update - 3.0.0 - Discord-App-y-fyed the bot__ -New Stuff: -- A new command to retrieve user banners -- Added bot to status monitoring: status.flipped.codes - -Important Changes: -- completely remade agent-black with the new slash-commands (complete remake of backend) -- the help comamnd has been stripped down to just display a simple message to now use the build in slash command help provided by discord (Temporary) ---> **You now need use the slash commands to interact with the bot** -- Ban command removed: Discord already provides a Ban command with the same functionality EDIT: Ban reason correction cannot be done this way, so a implementation of the old ban command will come -- Free-Search for user tags has been disabled temporarily as not working properly with slash commands - -Boring Bug Fixes: -- Updated dependencies to new versions -- added failsafe to not demote own maintainer account -- Now using genrelized embed colors for easyer coding -- Better error handling with output in support server for devs to stop issues more quickly -- Blacklisting Bot ID from ban recording - -Planned for the Future: -- Hard mode: kick/ban everyone on global ban list; kick every unverified bot;... -- everything else \ No newline at end of file diff --git a/classes/banManager.js b/classes/banManager.js deleted file mode 100644 index f3e943f..0000000 --- a/classes/banManager.js +++ /dev/null @@ -1,68 +0,0 @@ -const { Guild, GuildBan } = require('discord.js'); - -const { Sequelize } = require('sequelize'); - -module.exports.BanManager = class BanManager { - /** - * @typedef {Object} ManagerData - * @property {Array} bans Array of bans - * @property {Sequelize} sequelize Sequelize instance - */ - /** - * @param {ManagerData} data Data to initialize the manager with - */ - constructor(data) { - if (Array.isArray(data.bans) === false) throw new SyntaxError('Invalid bans array'); - this.bans = data.bans; - if (!data.sequelize || data.sequelize instanceof Sequelize === false || !data.sequelize.models.Ban) throw new SyntaxError('Invalid Sequelize instance'); - this.sequelize = data.sequelize; - } - - /** - * @description Adds a ban to the manager - * @param {GuildBan} ban Ban to add to the manager - * @returns {Promise} Promise of the ban added - */ - addBan(ban) { - if (ban instanceof GuildBan === false) return Promise.reject(new SyntaxError('Invalid Ban instance')); - return Promise.resolve(this.bans.push(ban)); - } - - /** - * @description Adds multiple bans to the manager - * @param {Guild} guild Guild to add bans from - * @returns {Promise>} Array of bans added - */ - addGuildBans(guild) { - if (guild instanceof Guild === false) return Promise.reject(new SyntaxError('Invalid Guild instance')); - if (!guild.me.permissions.has('BAN_MEMBERS')) return Promise.reject(new SyntaxError('Missing BAN_MEMBERS in guild')); - return Promise.resolve(guild.bans.fetch().then((bans) => { - if (bans instanceof Collection === false) return this.addBan(bans.first()); - return Array.from(bans.values()).forEach((ban) => this.addBan(ban)); - })); - } - - /** - * @description Syncs the manager with the database, adding bans that don't exist in the database - * @returns {Promise>} Array of bans added - */ - sync() { - this.bans.forEach((ban) => { - if (ban.user.bot && ban.user.fetchFlags().then((f) => f.has('VERIFIED_BOT'))) return; // Ignore verified bots - this.sequelize.models.Ban.findOrCreate({ - where: { - serverID: ban.guild.id, - userID: ban.user.id, - reason: ban.reason, - }, - defaults: { - // userID: ban.user.id, - // serverID: ban.guild.id, - userTag: ban.user.tag, - // reason: ban.reason, - }, - }); - }) - .then(() => Promise.resolve(this.bans), (err) => Promise.reject(err)); - } -}; diff --git a/commands/about.js b/commands/about.js deleted file mode 100644 index 8cec434..0000000 --- a/commands/about.js +++ /dev/null @@ -1,16 +0,0 @@ -const fs = require('fs'); - -module.exports.run = async (interaction) => { - fs.readFile(config.commands.about.text, 'utf8', (err, body) => { - if (err) { - ERR(err); - messageFail(interaction, 'Something went wrong, try again another time!'); - return; - } - messageSuccess(interaction, body, null, true); - }); -}; - -module.exports.data = new CmdBuilder() - .setName('about') - .setDescription('Displays some information about the bot.'); diff --git a/commands/alias.js b/commands/alias.js deleted file mode 100644 index 5afa737..0000000 --- a/commands/alias.js +++ /dev/null @@ -1,62 +0,0 @@ -const UserAlias = require('../database/models/UserAlias'); - -function addAlias(userID, groupingID, addedBy) { - // const [output] = await UserAlias.findOrCreate({ - UserAlias.findOrCreate({ - where: { userID, groupingID }, - defaults: { addedBy }, - }).catch(ERR); - // return output; -} - -async function checkAlias(userID) { - const found = await UserAlias.findOne({ where: { userID } }) - .catch(ERR); - return found; -} - -module.exports.run = async (interaction) => { - // check permissions if user has teamrole - if (!await client.functions.get('CHECK_DB_perms').run(interaction.user.id, 'staff', interaction.guild.id, interaction.member)) { - messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - - const mainUser = interaction.options.getUser('mainuser').id; - const aliasUser = interaction.options.getUser('user2').id; - - // get entries for both IDs - const resultMainID = await checkAlias(mainUser); - const resultAliasID = await checkAlias(aliasUser); - // check if borth are already in aliases - if (resultMainID && resultAliasID) { - messageFail(interaction, 'Both users are already linked or in two different groupings!'); - return; - } - // add both if not found - if (!resultMainID && !resultAliasID) { - const groupingID = await interaction.id; - [mainUser, aliasUser].forEach((uID) => addAlias(uID, groupingID, interaction.user.id)); - messageSuccess(interaction, 'Entry added!'); - return; - } - // add mainUser if not found - if (!resultMainID && resultAliasID) { - addAlias(mainUser, resultAliasID.groupingID, interaction.user.id); - messageSuccess(interaction, 'Entry added!'); - return; - } - // add aliasUser if not found - if (resultMainID && !resultAliasID) { - console.log(resultAliasID); - addAlias(aliasUser, resultMainID.groupingID, interaction.user.id); - messageSuccess(interaction, 'Entry added!'); - return; - } -}; - -module.exports.data = new CmdBuilder() - .setName('alias') - .setDescription('Add an alias for secound accounts.') - .addUserOption((option) => option.setName('mainuser').setDescription('Provide the main user the person uses.').setRequired(true)) - .addUserOption((option) => option.setName('user2').setDescription('2. user').setRequired(true)); diff --git a/commands/archive/checkpermissions.js b/commands/archive/checkpermissions.js deleted file mode 100644 index 3f31846..0000000 --- a/commands/archive/checkpermissions.js +++ /dev/null @@ -1,4 +0,0 @@ -/* -A command to check if all the permissions are setup correctly. -It should take a server as a non reqiered argument -*/ diff --git a/commands/archive/lookup.js b/commands/archive/lookup.js deleted file mode 100644 index add3961..0000000 --- a/commands/archive/lookup.js +++ /dev/null @@ -1,217 +0,0 @@ -const { Op } = require('sequelize'); - -const { MessageEmbed } = require('discord.js'); - -const config = require('../../config/main.json'); - -const Ban = require('../../database/models/Ban'); - -const Warn = require('../../database/models/Warn'); - -const ParticipatingServer = require('../../database/models/ParticipatingServer'); - -const UserIDAssociation = require('../../database/models/UserIDAssociation'); - -// looksup usertag in list if recorded -async function checkTag(userTag) { - const found = await UserIDAssociation.findOne({ where: { userTag } }) - .catch(ERR); - return found; -} - -async function postUserinfo(message, userID, bans, warns) { - const embed = new MessageEmbed().setColor(message.member.displayColor); - let failed = false; - const discordUser = await client.users.fetch(userID, false) - .catch((err) => { - if (err.code === 10013) embed.setAuthor({ name: 'This user doesn\'t exist.' }); - else embed.setAuthor({ name: 'An error occurred!' }); - embed.addField('Stopcode', err.message); - failed = true; - return message.channel.send({ embed }); - }); - // get all server that the bot shares with the user - const sharedServers = await client.guilds.cache.filter((guild) => !!guild.member(discordUser)); - // post userinfo if no errors accour - if (!failed) { - let botBadge = ''; - if (discordUser.bot) botBadge = config.commands.lookup.botBadge; - embed - .addField('Usertag', `\`${discordUser.tag}\` ${botBadge}`) - .addField('ID', `\`${userID}\``) - .addField('Account Creation Date', discordUser.createdAt, true) - .setThumbnail(discordUser.displayAvatarURL({ format: 'png', dynamic: true, size: 1024 })); - if (bans) embed.addField('Bans', bans, true); - if (warns) embed.addField('Warns', warns, true); - if (sharedServers.size) embed.addField(`Shared servers - ${sharedServers.size}`, `\`\`\`${sharedServers.map((sharedMember) => sharedMember.name).join('\n')}\`\`\``, false); - return message.channel.send({ embed }); - } -} - -async function getBanns(userID) { - // adds a user to the Maintainer table - const found = await Ban.findAll({ where: { userID } }) - .catch(ERR); - return found; -} - -async function getWarns(userID) { - // adds a user to the Maintainer table - const found = await Warn.findAll({ where: { userID } }) - .catch(ERR); - return found; -} - -async function getServerName(serverID) { - // adds a user to the Maintainer table - const found = await ParticipatingServer.findOne({ where: { serverID } }) - .catch(ERR); - if (!found) return 'unknown server'; - return found.serverName; -} - -// final ban posting function -function postBans(message, banns) { - banns.forEach(async (ban) => { - const embed = new MessageEmbed() - .setDescription(`**Reason**:\n\`\`\`${ban.reason || 'None'}\`\`\``) - .addField('ServerID', `\`${ban.serverID}\``, true) - .addField('Is banned', `\`${ban.userBanned}\``, true) - .addField('BanID', `\`${ban.banID}\``, true) - .addField('Ban creation date', ban.createdAt, true) - .addField('Ban updated date', ban.updatedAt, true); - const serverName = await getServerName(ban.serverID); - // check if user is still banned - if (ban.userBanned) { - embed - .setColor('ORANGE') - .setAuthor({ name: `Banned on ${serverName}` }); - } else { - embed - .setColor('GREEN') - .setAuthor({ name: `Was banned on ${serverName}` }); - } - message.channel.send({ embed }); - }); -} - -// final warn posting function -function postWarns(message, warns) { - warns.forEach(async (warn) => { - const serverName = await getServerName(warn.serverID); - const embed = new MessageEmbed() - .setColor(16755456) // yellow - .setDescription(`**Reason**:\n\`\`\`${warn.reason || 'None'}\`\`\``) - .setAuthor({ name: `Warned on ${serverName}` }) - .addField('ServerID', `\`${warn.serverID}\``, true) - .addField('WarnID', `\`${warn.warnID}\``, true) - .addField('Warning creation date', warn.createdAt, true) - .addField('Warning updated date', warn.updatedAt, true); - message.channel.send({ embed }); - }); -} - -// prepares for bans and warnings from other servers -async function postInfractions(message, bans, warns) { - postBans(message, bans); - postWarns(message, warns); -} - -function getID(message, args) { - // check if mention is in content - if (message.mentions.members.first()) return message.mentions.members.first().id; - // get userID - const [userID] = args; - // check if id argument is present - if (!userID) return message.author.id; - // ckeck if content is not NaN - if (!isNaN(userID)) return userID; -} - -async function checkUserTag(uTag, IDArr) { - // adds a user to the Maintainer table - // FIXME: lowercase DB search - const results = await UserIDAssociation.findAll({ limit: 4, where: { userTag: { [Op.substring]: uTag } } }) - .catch(ERR); - if (!results) return; - results.forEach((result) => { - if (IDArr.includes(result.userID)) return; - IDArr.push(result.userID); - }); - return IDArr; -} - -async function postLookup(message, ID) { - const bans = await getBanns(ID); - const warns = await getWarns(ID); - await postUserinfo(message, ID, bans.length, warns.length); - await postInfractions(message, bans, warns); -} - -module.exports.run = async (message, args, config, prefix) => { - // check permissions if user has teamrole - if (!await client.functions.get('FUNC_checkPermissionsDB').run(message.author.id, 'staff', message.guild.id, message.member)) { - messageFail(message, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - - let IDArr = []; - const userID = getID(message, args); - if (userID) IDArr.push(userID); - else { - // parse username - const userTag = message.content.slice(prefix.length + module.exports.data.name.length + 1); - // check length - if (userTag.length < config.commands.lookup.lowerQuerryLimit) return messageFail(message, 'Your search querry must be at least 5 characters long.'); - // make DB search - await checkUserTag(userTag, IDArr); - } - // if no info is given, return author ID - if (IDArr.length === 0 && args.length === 0) IDArr.push(message.author.id); - if (IDArr.length === 0 && args.length !== 0) return messageFail(message, 'Couldn\'t find any results with your search querry.'); - - const orgID = IDArr[0]; - // check for aliases and overwrite array - if (IDArr.length === 1) { - const output = await client.functions.get('FUNC_checkAlias').run(IDArr[0]); - if (output) IDArr = output; - } - // only post the one that has the orginal user id - IDArr.forEach(async (ID) => { - if (ID === orgID) postLookup(message, ID); - }); - // if more then 1 entry in array... - if (IDArr.length !== 1) { - // ask if rest should be posted - const confirmMessage = await messageFail(message, `Show all (+${IDArr.length - 1}) results?`, true); - await confirmMessage.react('❌'); - await confirmMessage.react('✅'); - // start reaction collector - const filter = (reaction, user) => user.id === message.author.id; - const reactionCollector = confirmMessage.createReactionCollector(filter, { time: 10000 }); - reactionCollector.on('collect', async (reaction) => { - reactionCollector.stop(); - switch (reaction.emoji.name) { - case '❌': return; - case '✅': - // post bans - // post all besides orginal userID - IDArr.forEach(async (ID) => { - if (ID !== orgID) postLookup(message, ID); - }); - return; - default: - // wrong reaction - messageFail(message, 'Please only choose one of the two options! Try again.'); - return; - } - }); - reactionCollector.on('end', () => confirmMessage.delete()); - } -}; - -module.exports.data = new CmdBuilder() - .setName('lookup') - .setDescription('Uses the Discord API to lookup user information.') - .addUserOption((option) => option.setName('user').setDescription('Provide a user id or search from the drop down.')) - .addStringOption((option) => option.setName('search').setDescription('Search database for a user.')); diff --git a/commands/archive/punish-handler.js b/commands/archive/punish-handler.js deleted file mode 100644 index 730eada..0000000 --- a/commands/archive/punish-handler.js +++ /dev/null @@ -1,44 +0,0 @@ -// module.exports.run = async (message, args, config, prefix) => { -// // check permissions -// // check server settings (is punishing feature enabled?) -// // command handler for subcommands: manualAdd, manualRemove, stats, userStats (calls lookup), add, remove, list, listPunishments -// }; - -const ServerSetting = require('../../database/models/ServerSetting'); - -// prepares command usage message -function CommandUsage(prefix, cmdName, subcmd) { - return `Command usage: - \`\`\`/${cmdName} ${subcmd}\`\`\``; -} - -// check if server has feature enabled. -async function checkFeature(serverID) { - const found = await ServerSetting.findOne({ where: { serverID, pointsSystemEnabled: true } }) - .catch(ERR); - return found; -} - -// is used to configure settings -// if setting is not set, use default from config -module.exports.run = async (message, args, config, prefix) => { - // TODO: check permissions (Servermanager) - // check DM - if (message.channel.type === 'dm') return messageFail(message, 'This comamnd is for servers only.'); - // check if user is teammember - if (!message.member.roles.cache.find(({ id }) => id === config.teamRole)) return messageFail(message, `You are not authorized to use \`/${module.exports.data.name}\``); - const [subcmd] = args; - const commandValues = ['manualAdd', 'manualRemove', 'stats', 'userStats(callsLookup)', 'add', 'remove', 'list', 'listPunishments']; - const currentCMD = module.exports.help; - if (commandValues.toLowerCase().includes(subcmd)) { - if (subcmd === 'enable' || await checkFeature(message.guild.id)) { - client.functions.get(`CMD_${currentCMD.name}_${subcmd}`) - .run(message, args, config, prefix); - } else messageFail(message, `To use the comamnds, you need to enable the feature in this server first!\n${CommandUsage(prefix, currentCMD.name, 'enable true')}`); - } else messageFail(message, CommandUsage(prefix, currentCMD.name, commandValues.join('|'))); -}; - -module.exports.help = { - name: 'punish', - desc: 'Punishes a user.', -}; diff --git a/commands/archive/punishsettings-handler.js b/commands/archive/punishsettings-handler.js deleted file mode 100644 index cf31ee1..0000000 --- a/commands/archive/punishsettings-handler.js +++ /dev/null @@ -1,38 +0,0 @@ -const ServerSetting = require('../../database/models/ServerSetting'); - -// prepares command usage message -function CommandUsage(prefix, cmdName, subcmd) { - return `Command usage: - \`\`\`/${cmdName} ${subcmd}\`\`\``; -} - -// check if server has feature enabled. -async function checkFeature(serverID) { - const found = await ServerSetting.findOne({ where: { serverID, pointsSystemEnabled: true } }) - .catch(ERR); - return found; -} - -// is used to configure settings -// if setting is not set, use default from config -module.exports.run = async (message, args, config, prefix) => { - // TODO: check permissions (Servermanager) - // check DM - if (message.channel.type === 'dm') return messageFail(message, 'This comamnd is for servers only.'); - // check if user is teammember - if (!message.member.roles.cache.find(({ id }) => id === config.teamRole)) return messageFail(message, `You are not authorized to use \`/${module.exports.data.name}\``); - const [subcmd] = args; - const commandValues = ['enable', 'listSettings', 'forceReason', 'pointLifetime', 'listReasons', 'addReason', 'removeReason', 'listPunishment', 'addPunishment', 'removePunishment']; - const currentCMD = module.exports.help; - if (commandValues.toLowerCase().includes(subcmd)) { - if (subcmd === 'enable' || await checkFeature(message.guild.id)) { - client.functions.get(`CMD_${currentCMD.name}_${subcmd}`) - .run(message, args, config, prefix); - } else messageFail(message, `To use the comamnds, you need to enable the feature in this server first!\n${CommandUsage(prefix, currentCMD.name, 'enable true')}`); - } else messageFail(message, CommandUsage(prefix, currentCMD.name, commandValues.join('|'))); -}; - -module.exports.help = { - name: 'punishsettings', - desc: 'Managing command for setting up pointslists.', -}; diff --git a/commands/archive/unban.js b/commands/archive/unban.js deleted file mode 100644 index 2c06585..0000000 --- a/commands/archive/unban.js +++ /dev/null @@ -1,59 +0,0 @@ -// TODO: not yet completed beforehand - -// prepares command usage message -function CommandUsage(prefix, cmdName, subcmd) { - return `Command usage: - \`\`\`/${cmdName} ${subcmd}\`\`\``; -} - -module.exports.run = async (interaction) => { - // check permissions - if (!await client.functions.get('FUNC_checkPermissionsChannel').run(message.member, message, 'BAN_MEMBERS')) { - messageFail(message, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - // get args - const [userID, reasonTester] = args; - - // get member - const toBanMember = await message.guild.members.cache.get(userID); - // check if member is bannable - if (toBanMember) { - if (!toBanMember.bannable) { - messageFail(message, `The user \`${toBanMember.user.tag}\` can't be banned!\nHe owns the server, has higher permissions or is a system user!`); - return; - } - } - // check if user is already banned - const banList = await message.guild.fetchBans(); - const existingBan = await banList.find((ban) => ban.user.id === userID); - if (existingBan) { - // unbanning so reason gets updated - await message.guild.members.unban(userID); - // messageFail(message, `The user \`${toBanUser.tag}\` has been already banned!`); - // return; - } - // get complete reason - const slicedReason = await args.join(' ').slice(userID.length + 1); - // check ban reason length for discord max ban reason - if (slicedReason.length > 512) { - messageFail(message, 'Your ban reason is too long. Discord only allows a maximum length of 512 characters.'); - return; - } - // exec ban - const processedBanUser = await message.guild.members.ban(userID, { reason: slicedReason }); - // write confirmation - messageSuccess(message, `The user \`${processedBanUser.tag}\` has been banned!\nReason: \`${slicedReason}\``); -}; - -module.exports.help = { - name: 'unban', - usage: 'USERID REASON', - desc: '', -}; - -module.exports.data = new CmdBuilder() - .setName('unban') - .setDescription('Pardons a user by ID.') - .addUserOption((option) => option.setName('user').setDescription('Provide the user you wish to ban.').setRequired(true)) - .addStringOption((option) => option.setName('reason').setDescription('Reason for the server ban.').setRequired(true)); diff --git a/commands/avatar.js b/commands/avatar.js deleted file mode 100644 index 5504c6d..0000000 --- a/commands/avatar.js +++ /dev/null @@ -1,29 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -module.exports.run = async (interaction) => { - // needs to be local as settings overlap from dofferent embed-requests - const embedDefault = new MessageEmbed(); - const command = interaction.options; - // get user and ID - const rawUser = command.get('user', true); - const user = rawUser.user; - const member = rawUser.member; - const defaultPFP = user.displayAvatarURL({ format: 'png', dynamic: true, size: 4096 }); - embedDefault.setAuthor({ name: user.tag }) - .setImage(defaultPFP); - await reply(interaction, { embeds: [embedDefault] }); - - if (member && member.avatar) { - const embedServer = new MessageEmbed(); - const serverPFP = member.displayAvatarURL({ format: 'png', dynamic: true, size: 4096 }); - embedServer.setAuthor({ name: member.nickname }) - .setImage(serverPFP) - .setFooter({ text: 'Server profile picture' }); - interaction.followUp({ embeds: [embedServer] }); - } -}; - -module.exports.data = new CmdBuilder() - .setName('avatar') - .setDescription('Retrieves the profile picture of the provided user ID.') - .addUserOption((option) => option.setName('user').setDescription('Provide a user to get the avatar from.').setRequired(true)); diff --git a/commands/banner.js b/commands/banner.js deleted file mode 100644 index 11f6acf..0000000 --- a/commands/banner.js +++ /dev/null @@ -1,22 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -module.exports.run = async (interaction) => { - // needs to be local as settings overlap from dofferent embed-requests - const embed = new MessageEmbed(); - const command = interaction.options; - // get user and Pic - const user = command.getUser('user', true); - // need to be fetched so banner url can be generated - await user.fetch(true); - const pic = await user.bannerURL({ format: 'png', dynamic: true, size: 4096 }); - if (!pic) return messageFail(interaction, 'This user doesn\'t have a banner.'); - embed.setAuthor({ name: user.tag }); - embed.setImage(pic); - - reply(interaction, { embeds: [embed] }); -}; - -module.exports.data = new CmdBuilder() - .setName('banner') - .setDescription('Retrieves the banner of a users profile via user ID.') - .addUserOption((option) => option.setName('user').setDescription('Provide a user to get the bannner from.').setRequired(true)); diff --git a/commands/broadcast.js b/commands/broadcast.js deleted file mode 100644 index 691af10..0000000 --- a/commands/broadcast.js +++ /dev/null @@ -1,39 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -const ParticipatingServer = require('../database/models/ParticipatingServer'); - -function getChannels() { - return ParticipatingServer.findAll({ where: { active: true, blocked: false }, attributes: ['logChannelID'] }) - .catch(ERR); -} - -async function sendMessage(author, body) { - const channels = await getChannels(); - channels.forEach((DBchannel) => { - const channelID = DBchannel.logChannelID; - const channel = client.channels.cache.find((channel) => channel.id === channelID); - const embed = new MessageEmbed() - .setAuthor({ name: `${author} broadcasted` }) - .setDescription(body) - .setColor(4182379); - channel.send({ embeds: [embed] }); - }); -} - -module.exports.run = async (interaction) => { - // check maintainer permissions - if (!await client.functions.get('CHECK_DB_perms').run(interaction.user.id)) { - messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - const body = interaction.options.getString('message', true); - await messageSuccess(interaction, 'Sending messages...'); - await sendMessage(interaction.user.tag, body.replaceAll('\\n', ` - `)); - await messageSuccess(interaction, 'Sent messages to all servers!'); -}; - -module.exports.data = new CmdBuilder() - .setName('broadcast') - .setDescription('Broadcasts a message to all servers.') - .addStringOption((option) => option.setName('message').setDescription('Message that should be broadcasted').setRequired(true)); diff --git a/commands/changelog.js b/commands/changelog.js deleted file mode 100644 index 8122ea6..0000000 --- a/commands/changelog.js +++ /dev/null @@ -1,16 +0,0 @@ -const fs = require('fs'); - -module.exports.run = async (interaction) => { - fs.readFile(config.commands.changelog.text, 'utf8', (err, body) => { - if (err) { - ERR(err); - messageFail(interaction, 'Something went wrong, try again another time!'); - return; - } - messageSuccess(interaction, body, null, true); - }); -}; - -module.exports.data = new CmdBuilder() - .setName('changelog') - .setDescription('Displays information about the most recent bot changes and what\'s to come.'); diff --git a/commands/checkallusers.js b/commands/checkallusers.js deleted file mode 100644 index 6341d91..0000000 --- a/commands/checkallusers.js +++ /dev/null @@ -1,92 +0,0 @@ -const { MessageEmbed, MessageActionRow, MessageButton } = require('discord.js'); - -const ParticipatingServer = require('../database/models/ParticipatingServer'); - -const Ban = require('../database/models/Ban'); - -const buttons = new MessageActionRow() - .addComponents([ - new MessageButton() - .setCustomId('accept') - .setEmoji('✅') - .setLabel('Show \'em all') - .setStyle('PRIMARY'), - new MessageButton() - .setCustomId('deny') - .setEmoji('❌') - .setLabel('Abort') - .setStyle('SECONDARY'), - ]); - -async function getBanns(userID) { - const found = await Ban.findAll({ where: { userID } }).catch(ERR); - return found; -} - -// send message when user is banned -async function sendBanMessage(interaction, serverName, serverID, userID, userTag) { - const message = await new MessageEmbed() - .setDescription(`serverID: \`${serverID}\` - servername: \`${serverName}\` - userID: \`${userID}\` - username: \`${userTag}\``) - .setFooter({ text: `For more information use \`/lookup ${userID}\`` }) - .setColor('ORANGE'); - reply(interaction, { embeds: [message] }, true); -} - -async function getServerName(serverID) { - // adds a user to the Maintainer table - const found = await ParticipatingServer.findOne({ where: { serverID } }) - .catch(ERR); - if (!found) return 'unknown server'; - return found.serverName; -} - -async function postBans(allBans, interaction) { - await messageSuccess(interaction, 'Starting... Please note, because of Discords API limit, the messages take some time to process.'); - allBans.forEach(async (foundBan) => { - const serverID = foundBan.serverID; - sendBanMessage(interaction, await getServerName(serverID), serverID, foundBan.userID, foundBan.userTag); - }); -} - -module.exports.run = async (interaction) => { - // check MANAGE_GUILD permissions - if (!interaction.memberPermissions.has('MANAGE_GUILD')) { - messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - - // get all userIDs - const users = await interaction.guild.members.fetch({ cache: false }); - const IDs = users.map((user) => user.id); - // get all user bans - const allBans = await getBanns(IDs); - if (allBans.length === 0) return messageSuccess(interaction, 'Your server is clear! No known users so far.'); - // check if up to 5 entries - if (allBans.length < 5) return postBans(allBans, interaction); - - const message = await new MessageEmbed() - .setDescription(`The bot is about to spam ${allBans.length} listed bans into this channel! This action can not be stopped midway through. \nAre you sure?`) - .setColor('ORANGE'); - const confirmMessage = await reply(interaction, { - embeds: [message], components: [buttons], fetchReply: true, ephemeral: true, - }); - - // start button collector - const filter = (i) => interaction.user.id === i.user.id; - const buttonCollector = confirmMessage.createMessageComponentCollector({ filter, time: 10000 }); - buttonCollector.on('collect', async (used) => { - buttonCollector.stop(); - if (used.customId === 'accept') return postBans(allBans, interaction); - return messageFail(interaction, 'Aborted!'); - }); - buttonCollector.on('end', async (collected) => { - if (collected.size === 0) messageFail(interaction, 'Your response took too long. Please run the command again.'); - }); -}; - -module.exports.data = new CmdBuilder() - .setName('checkallusers') - .setDescription('Checks all users in current server, if found on banlist.'); diff --git a/commands/eval.js b/commands/eval.js deleted file mode 100644 index 209055f..0000000 --- a/commands/eval.js +++ /dev/null @@ -1,31 +0,0 @@ -const clean = (text) => { - if (typeof (text) === 'string') { - Object.values(process.env).forEach((env) => { - if (env.length <= 3) return; - // eslint-disable-next-line no-param-reassign - text = text.replaceAll(env, '****NOPE****'); - }); - return text.replaceAll(/`/g, `\`${String.fromCharCode(8203)}`) - .replaceAll(/@/g, `@${String.fromCharCode(8203)}`); - } - return text; -}; - -module.exports.run = async (interaction) => { - // check owner permissions - if (interaction.user.id !== '172031697355800577') return messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``, null, false); - const code = interaction.options.getString('codeline', true); - try { - // eslint-disable-next-line no-eval - let evaled = eval(code); - - if (typeof evaled !== 'string') { evaled = require('util').inspect(evaled); } - - messageSuccess(interaction, `\`\`\`xl\n${clean(evaled)}\n\`\`\``, null, true); - } catch (err) { messageFail(interaction, `\`ERROR\` \`\`\`xl\n${clean(err)}\n\`\`\``); } -}; - -module.exports.data = new CmdBuilder() - .setName('eval') - .setDescription('Command used to run snippets of code. [OWNER ONLY].') - .addStringOption((option) => option.setName('codeline').setDescription('Commandline to execute').setRequired(true)); diff --git a/commands/guild.js b/commands/guild.js deleted file mode 100644 index 428dc71..0000000 --- a/commands/guild.js +++ /dev/null @@ -1,48 +0,0 @@ -const ParticipatingServer = require('../database/models/ParticipatingServer'); - -// check if server has feature enabled. -async function checkFeature(serverID) { - const found = await ParticipatingServer.findOne({ where: { serverID, active: true } }) - .catch(ERR); - return found; -} - -// is used to configure settings -// if setting is not set, use default from config -module.exports.run = async (interaction) => { - // check MANAGE_GUILD permissions - if (!interaction.memberPermissions.has('MANAGE_GUILD')) { - messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - - const subName = interaction.options.getSubcommand(true); - if (subName === 'setup' || subName === 'enable' || await checkFeature(interaction.guild.id)) { - client.commands.get(`${module.exports.data.name}_${subName}`).run(interaction, ParticipatingServer); - } else messageFail(interaction, 'You can\'t use this command without setting up your server first!'); -}; - -module.exports.data = new CmdBuilder() - .setName('guild') - .setDescription('Config for setting up your server with the bot.') - .addSubcommand((SC) => SC - .setName('setup') - .setDescription('First time setup.') - .addChannelOption((option) => option - .setName('channel') - .setDescription('Provide a channel you want Agent Black to report to.') - .addChannelType(0) - .setRequired(true)) - .addRoleOption((option) => option - .setName('role') - .setDescription('Provide your teams role, so the bot know who to listen to.') - .setRequired(true))) - .addSubcommand((SC) => SC - .setName('stats') - .setDescription('View stats.')) - .addSubcommand((SC) => SC - .setName('enable') - .setDescription('Enable this guild.')) - .addSubcommand((SC) => SC - .setName('disable') - .setDescription('Disable this guild.')); diff --git a/commands/guild/disable.js b/commands/guild/disable.js deleted file mode 100644 index 9034ba1..0000000 --- a/commands/guild/disable.js +++ /dev/null @@ -1,23 +0,0 @@ -// removes a server from the ParticipatingServers table -async function removeServer(ParticipatingServer, serverID) { - const success = await ParticipatingServer.update( - { active: false }, - { where: { serverID, active: true } }, - ) - .catch(ERR); - return success[0]; -} - -module.exports.run = async (interaction, ParticipatingServer) => { - const serverID = interaction.guildId; - const serverRemoved = await removeServer(ParticipatingServer, serverID); - if (serverRemoved >= 1) { - messageSuccess(interaction, - `The server with the ID \`${serverID}\` got disabled from the participating Servers list.`); - } else { - messageFail(interaction, - `The server with the ID \`${serverID}\` couldn't be found of the list.`); - } -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/guild/enable.js b/commands/guild/enable.js deleted file mode 100644 index 50ab542..0000000 --- a/commands/guild/enable.js +++ /dev/null @@ -1,33 +0,0 @@ -// enables guild in ParticipatingServers table -async function enableServer(ParticipatingServer, serverID) { - const success = await ParticipatingServer.update( - { active: true }, - { where: { serverID, active: false, blocked: false } }, - ) - .catch(ERR); - return success[0]; -} - -// check if server has feature enabled. -async function checkData(ParticipatingServer, serverID) { - const found = await ParticipatingServer.findOne({ - where: { serverID }, - attributes: ['logChannelID', 'teamRoleID'], - }).catch(ERR); - return found; -} - -module.exports.run = async (interaction, ParticipatingServer) => { - const serverID = interaction.guildId; - if (!await checkData(ParticipatingServer, serverID)) return messageFail(interaction, 'You can\'t use this command without setting up your server first!'); - const serverRemoved = await enableServer(ParticipatingServer, serverID); - if (serverRemoved >= 1) { - messageSuccess(interaction, - `The server with the ID \`${serverID}\` got re-enabled in the participating Servers list.`); - } else { - messageFail(interaction, - `The server with the ID \`${serverID}\` couldn't be found of the list or is already active.`); - } -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/guild/setup.js b/commands/guild/setup.js deleted file mode 100644 index f6542e1..0000000 --- a/commands/guild/setup.js +++ /dev/null @@ -1,72 +0,0 @@ -const { MessageEmbed, MessageActionRow, MessageButton } = require('discord.js'); - -const buttons = new MessageActionRow() - .addComponents([ - new MessageButton() - .setCustomId('accept') - .setEmoji('✅') - .setLabel('Accept') - .setStyle('PRIMARY'), - new MessageButton() - .setCustomId('deny') - .setEmoji('❌') - .setLabel('Deny') - .setStyle('SECONDARY'), - new MessageButton() - .setLabel('ToS') - .setURL('https://github.com/FlippedCode/agent-black/wiki/ToS-and-Privacy-Policy') - .setStyle('LINK'), - ]); - -// adds a server to the ParticipatingServers table -async function addServer(ParticipatingServer, serverID, logChannelID, teamRoleID, serverName) { - await ParticipatingServer.destroy({ limit: 1, where: { serverID, active: false } }); - const added = await ParticipatingServer.findOrCreate( - { - where: { serverID }, - defaults: { - logChannelID, teamRoleID, serverName, active: true, - }, - }, - ).catch(ERR); - const created = await added[1]; - return created; -} - -module.exports.run = async (interaction, ParticipatingServer) => { - const message = await new MessageEmbed() - .setDescription('Please confirm that you have read the ToS and Privacy Policy.') - .setColor('ORANGE'); - const confirmMessage = await reply(interaction, { - embeds: [message], components: [buttons], fetchReply: true, ephemeral: true, - }); - // start button collector - const filter = (i) => interaction.user.id === i.user.id; - const buttonCollector = confirmMessage.createMessageComponentCollector({ filter, time: 10000 }); - buttonCollector.on('collect', async (used) => { - buttonCollector.stop(); - if (used.customId === 'accept') { - // confirm - const logChannelID = interaction.options.getChannel('channel', true).id; - const teamRoleID = interaction.options.getRole('role', true).id; - const serverName = interaction.guild.name; - const serverID = interaction.guild.id; - const serverAdded = await addServer(ParticipatingServer, serverID, logChannelID, teamRoleID, serverName); - // post outcome - if (serverAdded) { - messageSuccess(interaction, - `\`${serverName}\` with the ID \`${serverID}\` got added to / updated in the participating Servers list.\nYou can now use all the other commands in this server.\nConsider running \`/checkallusers\` in your log channel once.`); - } else { - messageFail(interaction, - `An active server entry for \`${serverName}\` with the ID \`${serverID}\` already exists! If you want to change info, remove it first with \`/${interaction.commandName} disable\``); - } - return; - } - return messageFail(interaction, 'The bot setup cannot be continued without accepting the ToS. Please run the command again.'); - }); - buttonCollector.on('end', async (collected) => { - if (collected.size === 0) messageFail(interaction, 'Your response took too long. Please run the command again.'); - }); -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/guild/stats.js b/commands/guild/stats.js deleted file mode 100644 index f779219..0000000 --- a/commands/guild/stats.js +++ /dev/null @@ -1,35 +0,0 @@ -const Ban = require('../../database/models/Ban'); - -// finds a server in the ParticipatingServers table -async function findServer(ParticipatingServer, serverID) { - const found = await ParticipatingServer.findOne({ where: { serverID } }) - .catch(ERR); - return found; -} - -async function getBanCount(serverID) { - const result = await Ban.findAndCountAll({ where: { serverID } }); - return result.count; -} - -module.exports.run = async (interaction, ParticipatingServer) => { - // get entry - const serverFound = await findServer(ParticipatingServer, interaction.guildId); - // if entry is found - if (serverFound) { - let content = ` - Servername: \`${serverFound.serverName}\` - Server ID: \`${serverFound.serverID}\` - Log Channel: <#${serverFound.logChannelID}> (\`${serverFound.logChannelID}\`) - Team Role ID: \`${serverFound.teamRoleID}\` - Submitted Bans: \`${await getBanCount(serverFound.serverID)}\` - Is server apart of Association: \`${serverFound.active}\``; - if (serverFound.active) content += `\nParticipating Server since \`${serverFound.updatedAt}\``; - messageSuccess(interaction, content); - } else { - messageFail(interaction, - `The server with the ID \`${serverID}\` couldn't be found.`); - } -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/guildmgr.js b/commands/guildmgr.js deleted file mode 100644 index adbc7b0..0000000 --- a/commands/guildmgr.js +++ /dev/null @@ -1,58 +0,0 @@ -const ParticipatingServer = require('../database/models/ParticipatingServer'); - -module.exports.run = async (interaction) => { - // check maintainer permissions - if (!await client.functions.get('CHECK_DB_perms').run(interaction.user.id)) { - messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - const subName = interaction.options.getSubcommand(true); - const serverID = interaction.options.getString('server'); - client.commands.get(`${module.exports.data.name}_${subName}`).run(interaction, ParticipatingServer, serverID); -}; - -module.exports.data = new CmdBuilder() - .setName('guildmgr') - .setDescription('Manages guilds. [MAINTAINER ONLY]') - .addSubcommand((SC) => SC - .setName('add') - .setDescription('Add guild. [MAINTAINER ONLY]') - .addStringOption((option) => option - .setName('server') - .setDescription('Provide a guild ID you want to edit.') - .setAutocomplete(true) - .setRequired(true)) - .addStringOption((option) => option - .setName('channel') - .setDescription('Provide a channel you want Agent Black to report to.') - .setAutocomplete(true) - .setRequired(true)) - .addStringOption((option) => option - .setName('role') - .setDescription('Provide your teams role, so the bot know who to listen to.') - .setAutocomplete(true) - .setRequired(true))) - .addSubcommand((SC) => SC - .setName('info') - .setDescription('Disply info about a guild. [MAINTAINER ONLY]') - .addStringOption((option) => option - .setName('server') - .setDescription('Provide a guild ID you want to edit.') - .setAutocomplete(true) - .setRequired(true))) - .addSubcommand((SC) => SC - .setName('remove') - .setDescription('Remove guild. [MAINTAINER ONLY]') - .addStringOption((option) => option - .setName('server') - .setDescription('Provide a guild ID you want to edit.') - .setAutocomplete(true) - .setRequired(true))) - .addSubcommand((SC) => SC - .setName('block') - .setDescription('Block guild. [MAINTAINER ONLY]') - .addStringOption((option) => option - .setName('server') - .setDescription('Provide a guild ID you want to edit.') - .setAutocomplete(true) - .setRequired(true))); diff --git a/commands/guildmgr/add.js b/commands/guildmgr/add.js deleted file mode 100644 index d6bb1bd..0000000 --- a/commands/guildmgr/add.js +++ /dev/null @@ -1,32 +0,0 @@ -async function addServer(ParticipatingServer, serverID, logChannelID, teamRoleID, serverName) { - await ParticipatingServer.destroy({ limit: 1, where: { serverID, active: false } }); - const added = await ParticipatingServer.findOrCreate( - { - where: { serverID }, - defaults: { - logChannelID, teamRoleID, serverName, active: true, - }, - }, - ).catch(ERR); - const created = await added[1]; - return created; -} - -module.exports.run = async (interaction, ParticipatingServer, serverID) => { - // FIXME: no valid check of provided IDs - const logChannelID = interaction.options.getString('channel', true); - const teamRoleID = interaction.options.getString('role', true); - const serverName = await interaction.client.guilds.cache.find((guild) => guild.id === serverID).name; - // add server - const serverAdded = await addServer(ParticipatingServer, serverID, logChannelID, teamRoleID, serverName); - // post outcome - if (serverAdded) { - messageSuccess(interaction, - `\`${serverName}\` with the ID \`${serverID}\` got added to / updated for the participating Servers list and marked as active.`); - } else { - messageFail(interaction, - `An active server entry for \`${serverName}\` with the ID \`${serverID}\` already exists! If you want to change info, remove it first.`); - } -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/guildmgr/block.js b/commands/guildmgr/block.js deleted file mode 100644 index 9b5e88a..0000000 --- a/commands/guildmgr/block.js +++ /dev/null @@ -1,17 +0,0 @@ -async function blacklistServer(ParticipatingServer, serverID) { - const success = await ParticipatingServer.update({ blocked: true }, { where: { serverID } }).catch(ERR); - return success[0]; -} - -module.exports.run = async (interaction, ParticipatingServer, serverID) => { - const serverBlocked = await blacklistServer(ParticipatingServer, serverID); - if (serverBlocked >= 1) { - messageSuccess(interaction, - `The server with the ID \`${serverID}\` got blocked from using the bot.`); - } else { - messageFail(interaction, - `The server with the ID \`${serverID}\` couldn't be found of the list.`); - } -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/guildmgr/info.js b/commands/guildmgr/info.js deleted file mode 100644 index fadb10f..0000000 --- a/commands/guildmgr/info.js +++ /dev/null @@ -1,33 +0,0 @@ -const Ban = require('../../database/models/Ban'); - -// finds a server in the ParticipatingServers table -async function findServer(ParticipatingServer, serverID) { - const found = await ParticipatingServer.findOne({ where: { serverID } }) - .catch(ERR); - return found; -} - -async function getBanCount(serverID) { - const result = await Ban.findAndCountAll({ where: { serverID } }); - return result.count; -} - -module.exports.run = async (interaction, ParticipatingServer, serverID) => { - const serverFound = await findServer(ParticipatingServer, serverID); - if (serverFound) { - let content = ` - Servername: \`${serverFound.serverName}\` - Server ID: \`${serverFound.serverID}\` - Log Channel: <#${serverFound.logChannelID}> (\`${serverFound.logChannelID}\`) - Team Role ID: \`${serverFound.teamRoleID}\` - Submitted Bans: \`${await getBanCount(serverID)}\` - Is server apart of Association: \`${serverFound.active}\``; - if (serverFound.active) content += `\nParticipating Server since \`${serverFound.updatedAt}\``; - messageSuccess(interaction, content); - } else { - messageFail(interaction, - `The server with the ID \`${serverID}\` couldn't be found in the list.`); - } -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/guildmgr/remove.js b/commands/guildmgr/remove.js deleted file mode 100644 index 45787b2..0000000 --- a/commands/guildmgr/remove.js +++ /dev/null @@ -1,19 +0,0 @@ -async function removeServer(ParticipatingServer, serverID) { - const success = await ParticipatingServer.update({ active: false }, - { where: { serverID, active: true } }) - .catch(ERR); - return success[0]; -} - -module.exports.run = async (interaction, ParticipatingServer, serverID) => { - const serverRemoved = await removeServer(ParticipatingServer, serverID); - if (serverRemoved >= 1) { - messageSuccess(interaction, - `The server with the ID \`${serverID}\` got disabled from the participating Servers list.`); - } else { - messageFail(interaction, - `The server with the ID \`${serverID}\` couldn't be found of the list.`); - } -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/help.js b/commands/help.js deleted file mode 100644 index e386863..0000000 --- a/commands/help.js +++ /dev/null @@ -1,16 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -module.exports.run = async (interaction) => { - const embed = new MessageEmbed() - .setTitle('Halp') - .setColor(interaction.member.displayColor) - .setDescription('This command is deprecated, please use discord embedded slash-commands feature instead.') - .addField('Still need help?', ` - Read the wiki here: https://github.com/FlippedCode/agent-black/wiki - or join our server here: https://discord.gg/TqBwHtzzhD`); - return reply(interaction, { embeds: [embed] }); -}; - -module.exports.data = new CmdBuilder() - .setName('help') - .setDescription('Shows a list of commands. [Deprecated]'); diff --git a/commands/lookup.js b/commands/lookup.js deleted file mode 100644 index d19bbc2..0000000 --- a/commands/lookup.js +++ /dev/null @@ -1,234 +0,0 @@ -const { Op } = require('sequelize'); - -const { MessageEmbed, MessageActionRow, MessageButton } = require('discord.js'); - -const Ban = require('../database/models/Ban'); - -const Warn = require('../database/models/Warn'); - -const ParticipatingServer = require('../database/models/ParticipatingServer'); - -const UserIDAssociation = require('../database/models/UserIDAssociation'); - -const buttons = new MessageActionRow() - .addComponents([ - new MessageButton() - .setCustomId('show') - .setEmoji('✅') - .setLabel('Show all users') - .setStyle('PRIMARY'), - new MessageButton() - .setCustomId('dontshow') - .setEmoji('❌') - .setLabel('Nah, im good') - .setStyle('SECONDARY'), - ]); - -// looksup usertag in list if recorded -async function checkTag(userTag) { - const found = await UserIDAssociation.findOne({ where: { userTag } }) - .catch(ERR); - return found; -} - -async function postUserinfo(interaction, userID, bans, warns, followUp = false) { - const embed = new MessageEmbed().setColor(interaction.member.displayColor); - const discordUser = await client.users.fetch(userID, false); - // get all server that the bot shares with the user - const sharedServers = await client.guilds.cache.filter((guild) => !!guild.members.cache.get(discordUser.id)); - // There seems to be a bug on the discord api that doesnt allow intigers in body: 'RangeError [EMBED_FIELD_NAME]: MessageEmbed field names must be non-empty strings.' So a convertion needed to be done - embed - .addField('Usertag', `\`${discordUser.tag}\` ${discordUser.bot ? config.commands.lookup.botBadge : ''}`) - .addField('ID', `\`${userID}\``) - .addField('Account Creation Date', date(discordUser.createdAt), true) - .setThumbnail(discordUser.displayAvatarURL({ format: 'png', dynamic: true, size: 1024 })); - if (bans) embed.addField('Bans', `${bans}`, true); - if (warns) embed.addField('Warns', `${warns}`, true); - if (sharedServers.size) { - // FIXME: check if it really only shows one server - const serverlist = sharedServers.map((sharedMember) => sharedMember.name).join('\n'); - const cutServerlist = serverlist.length > 1024 ? `${serverlist.slice(0, 1021)}...` : serverlist; - let serverList = `\`\`\`${cutServerlist}\`\`\``; - // hide serverlist for bot if not maintainer - if (userID === client.user.id) { - if (!await client.functions.get('CHECK_DB_perms').run(interaction.user.id)) serverList = 'REDACTED'; - } - embed.addField(`Shared servers - ${sharedServers.size}`, serverList, false); - } - return reply(interaction, { embeds: [embed] }, followUp); - // } -} - -async function getBanns(userID) { - // adds a user to the Maintainer table - const found = await Ban.findAll({ where: { userID } }) - .catch(ERR); - return found; -} - -async function getWarns(userID) { - // adds a user to the Maintainer table - const found = await Warn.findAll({ where: { userID } }) - .catch(ERR); - return found; -} - -async function getServerName(serverID) { - // adds a user to the Maintainer table - const found = await ParticipatingServer.findOne({ where: { serverID } }) - .catch(ERR); - if (!found) return 'unknown server'; - return found.serverName; -} - -// final ban posting function -function postBans(interaction, banns) { - banns.forEach(async (ban) => { - const embed = new MessageEmbed() - .setDescription(`**Reason**:\n\`\`\`${ban.reason || 'None'}\`\`\``) - .addField('ServerID', `\`${ban.serverID}\``, true) - .addField('Is banned', `\`${ban.userBanned}\``, true) - .addField('BanID', `\`${ban.banID}\``, true) - .addField('Ban creation date', date(ban.createdAt)); - if (date(ban.createdAt) !== date(ban.updatedAt)) embed.addField('Ban updated date', date(ban.updatedAt)); - const serverName = await getServerName(ban.serverID); - // check if user is still banned - if (ban.userBanned) { - embed - .setColor('ORANGE') // orange - .setAuthor({ name: `Banned on ${serverName}` }); - } else { - embed - .setColor('GREEN') // green - .setAuthor({ name: `Was banned on ${serverName}` }); - } - reply(interaction, { embeds: [embed] }, true); - }); -} - -// final warn posting function -function postWarns(interaction, warns) { - warns.forEach(async (warn) => { - const serverName = await getServerName(warn.serverID); - const embed = new MessageEmbed() - .setColor(16755456) // yellow - .setDescription(`**Reason**:\n\`\`\`${warn.reason || 'None'}\`\`\``) - .setAuthor({ name: `Warned on ${serverName}` }) - .addField('ServerID', `\`${warn.serverID}\``, true) - .addField('WarnID', `\`${warn.warnID}\``, true) - .addField('Warning creation date', date(warn.createdAt)); - if (date(warn.createdAt) !== date(warn.updatedAt)) embed.addField('Warning updated date', date(warn.updatedAt)); - reply(interaction, { embeds: [embed] }, true); - }); -} - -// prepares for bans and warnings from other servers -async function postInfractions(interaction, bans, warns) { - postBans(interaction, bans); - postWarns(interaction, warns); -} - -// function getID(interaction, args) { -// // check if mention is in content -// if (interaction.mentions.members.first()) return interaction.mentions.members.first().id; -// // get userID -// const [userID] = args; -// // check if id argument is present -// if (!userID) return interaction.author.id; -// // ckeck if content is not NaN -// if (!isNaN(userID)) return userID; -// } - -async function checkUserTag(uTag, IDArr) { - // adds a user to the Maintainer table - // FIXME: lowercase DB search - const results = await UserIDAssociation.findAll({ limit: 4, where: { userTag: { [Op.substring]: uTag } } }) - .catch(ERR); - if (!results) return; - results.forEach((result) => { - if (IDArr.includes(result.userID)) return; - IDArr.push(result.userID); - }); - return IDArr; -} - -async function postLookup(interaction, ID, followUp) { - const bans = await getBanns(ID); - const warns = await getWarns(ID); - await postUserinfo(interaction, ID, bans.length, warns.length, followUp); - await postInfractions(interaction, bans, warns); -} - -async function showAdditionalUsers(interaction, IDArr, orgID) { - const message = await new MessageEmbed() - .setDescription(`Show all (+${IDArr.length - 1}) results?`) - .setColor('ORANGE'); - const confirmMessage = await reply(interaction, { - embeds: [message], components: [buttons], fetchReply: true, - }); - // start button collector - const filter = (i) => interaction.user.id === i.user.id; - const buttonCollector = confirmMessage.createMessageComponentCollector({ filter, time: 20000 }); - buttonCollector.on('collect', async (used) => { - buttonCollector.stop(); - if (used.customId === 'show') { - // post all bans besides orginal userID - // FIXME: bad implementation of a array filter - IDArr.forEach(async (ID) => { - if (ID !== orgID) postLookup(interaction, ID, true); - }); - } - message.setFooter({ text: `Answered with '${used.component.label}'` }); - confirmMessage.edit({ embeds: [message], components: [] }); - }); - buttonCollector.on('end', async (collected) => { - if (collected.size !== 0) return; - message.setFooter({ text: 'Your response took too long. Please run the command again.' }); - confirmMessage.edit({ embeds: [message], components: [] }); - }); -} - -module.exports.run = async (interaction) => { - // check permissions if user has teamrole - if (!await client.functions.get('CHECK_DB_perms').run(interaction.user.id, 'staff', interaction.guild.id, interaction.member)) { - messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - - const requestedUser = interaction.options.getUser('user'); - let IDArr = [requestedUser.id]; - // if (userID) IDArr.push(userID); - // else { - // // parse username - // const userTag = message.content.slice(prefix.length + module.exports.data.name.length + 1); - // // check length - // if (userTag.length < config.commands.lookup.lowerQuerryLimit) return messageFail(message, 'Your search querry must be at least 5 characters long.'); - // // make DB search - // await checkUserTag(userTag, IDArr); - // } - - // DEPRECATED: if no info is given, return author ID - // if (IDArr.length === 0 && args.length === 0) IDArr.push(message.author.id); - // if (IDArr.length === 0 && args.length !== 0) return messageFail(message, 'Couldn\'t find any results with your search querry.'); - - const orgID = IDArr[0]; - // check for aliases and overwrite array - // if not needed of upper code is DEPRECATED: - if (IDArr.length === 1) { - const output = await client.functions.get('GET_DB_alias').run(IDArr[0]); - if (output) IDArr = output; - } - - const multipleAccounts = IDArr.length !== 1; - if (multipleAccounts) await showAdditionalUsers(interaction, IDArr, orgID); - // only post the one that has the orginal user id - // FIXME: bad implementation of a array filter - IDArr.forEach(async (ID, i) => { - if (ID === orgID) postLookup(interaction, ID, multipleAccounts); - }); -}; - -module.exports.data = new CmdBuilder() - .setName('lookup') - .setDescription('Uses the Discord API and ABB database to look up user information.') - .addUserOption((option) => option.setName('user').setDescription('Provide a user or a user id.').setRequired(true)); diff --git a/commands/maintainer.js b/commands/maintainer.js deleted file mode 100644 index 9dfce8f..0000000 --- a/commands/maintainer.js +++ /dev/null @@ -1,25 +0,0 @@ -const Maintainer = require('../database/models/Maintainer'); - -module.exports.run = async (interaction) => { - // check maintainer permissions - if (!await client.functions.get('CHECK_DB_perms').run(interaction.user.id)) { - messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - const subName = interaction.options.getString('action', true); - client.commands.get(`${module.exports.data.name}_${subName}`).run(interaction, Maintainer); -}; - -module.exports.data = new CmdBuilder() - .setName('maintainer') - .setDescription('Manages the maintainers. [MAINTAINER ONLY]') - .addUserOption((option) => option.setName('user').setDescription('Provide a user you want to edit.').setRequired(true)) - .addStringOption((option) => option - .setName('action') - .setDescription('What do you want to do with this user?') - .addChoices([ - ['Add user', 'add'], - ['Remove user', 'remove'], - ['Display info about user', 'info'], - ]) - .setRequired(true)); diff --git a/commands/maintainer/add.js b/commands/maintainer/add.js deleted file mode 100644 index d4bdc3f..0000000 --- a/commands/maintainer/add.js +++ /dev/null @@ -1,28 +0,0 @@ -// adds a user to the Maintainer table -async function addUser(Maintainer, userID) { - const added = await Maintainer.findOrCreate( - { - where: { userID }, - }, - ).catch(ERR); - const created = await added[1]; - return created; -} - -// adds user entry -module.exports.run = async (interaction, Maintainer) => { - const userID = await interaction.options.getUser('user').id; - if (userID === interaction.user.id) return messageFail(interaction, 'You cant edit yourself.'); - // add server - const userAdded = await addUser(Maintainer, userID); - // post outcome - if (userAdded) { - messageSuccess(interaction, - `<@${userID}> with the ID \`${userID}\` got added to the maintainers list.`); - } else { - messageFail(interaction, - `The entry for the user <@${userID}> with the ID \`${userID}\` already exists!`); - } -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/maintainer/info.js b/commands/maintainer/info.js deleted file mode 100644 index af287e5..0000000 --- a/commands/maintainer/info.js +++ /dev/null @@ -1,25 +0,0 @@ -// finds a user in the Maintainers table -async function findUser(Maintainer, userID) { - const found = await Maintainer.findOne({ where: { userID } }) - .catch(ERR); - return found; -} - -// adds user entry -module.exports.run = async (interaction, Maintainer) => { - const user = interaction.options.getUser('user'); - const userID = user.id; - const userFound = await findUser(Maintainer, userID); - if (userFound) { - const userID = userFound.userID; - messageSuccess(interaction, - `User tag: <@${userID}> (\`${user.tag}\`) - User ID: \`${userID}\` - Maintainer since \`${userFound.createdAt}\``); - } else { - messageFail(interaction, - `The user with the ID \`${userID}\` couldn't be found in the list.`); - } -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/maintainer/remove.js b/commands/maintainer/remove.js deleted file mode 100644 index 43139c7..0000000 --- a/commands/maintainer/remove.js +++ /dev/null @@ -1,21 +0,0 @@ -// removes a user from the Maintainer table -async function removeUser(Maintainer, userID) { - const destroyed = await Maintainer.destroy({ limit: 1, where: { userID } }); - return destroyed; -} - -// adds user entry -module.exports.run = async (interaction, Maintainer) => { - const userID = await interaction.options.getUser('user').id; - if (userID === interaction.user.id) return messageFail(interaction, 'You cant edit yourself.'); - const userRemoved = await removeUser(Maintainer, userID); - if (userRemoved >= 1) { - messageSuccess(interaction, - `The user with the ID \`${userID}\` got removed from the maintainers list.`); - } else { - messageFail(interaction, - `The user with the ID \`${userID}\` couldn't be found of the list.`); - } -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/ping.js b/commands/ping.js deleted file mode 100644 index 819cf80..0000000 --- a/commands/ping.js +++ /dev/null @@ -1,33 +0,0 @@ -const { MessageEmbed, MessageActionRow, MessageButton } = require('discord.js'); - -// Ping kickoff for bot latency -async function kickoff(interaction) { - const sendMessage = await new MessageEmbed() - .setDescription('📤 Pong...') - .setColor(); - const sentMessage = await reply(interaction, { embeds: [sendMessage], fetchReply: true }); - return sentMessage; -} - -// message for data return -function editedMessage(sentMessage, interaction) { - const api_latency = Math.round(sentMessage.client.ws.ping); - const body = `📥 Pong! - Bot latency is \`${sentMessage.createdTimestamp - interaction.createdTimestamp}\`ms. - API latency is \`${api_latency}\`ms`; - return new MessageEmbed() - .setDescription(body) - .setColor(); -} - -// posts ping message and edits it afterwards -async function checkPing(interaction) { - const sentReply = await kickoff(interaction); - reply(interaction, { embeds: [editedMessage(sentReply, interaction)] }); -} - -module.exports.run = async (interaction) => checkPing(interaction); - -module.exports.data = new CmdBuilder() - .setName('ping') - .setDescription('Shows API and bot latencies.'); diff --git a/commands/syncallbans.js b/commands/syncallbans.js deleted file mode 100644 index 253646e..0000000 --- a/commands/syncallbans.js +++ /dev/null @@ -1,35 +0,0 @@ -const Ban = require('../database/models/Ban'); - -module.exports.run = async (interaction) => { - // check owner permissions - if (interaction.user.id !== '172031697355800577') return messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - - if (!DEBUG) await interaction.deferReply(); - await client.guilds.cache.forEach(async (guild) => { - const bans = await guild.bans.fetch({ cache: false }); - await bans.forEach(async ({ user, reason }) => { - const userTag = user.tag; - const userBanned = true; - const userID = user.id; - const serverID = guild.id; - let fixedReason = reason; - if (reason !== null) fixedReason = reason.replace(new RegExp('\'', 'g'), '`'); - const [banEntry] = await Ban.findOrCreate({ - where: { userID, serverID }, - defaults: { reason: fixedReason, userTag, userBanned }, - }).catch(ERR); - if (!banEntry.isNewRecord) { - Ban.update({ reason: fixedReason, userBanned }, - { where: { userID, serverID } }) - .catch(ERR); - } - }); - }); - await setTimeout(() => { - messageSuccess(interaction, 'Done!'); - }, client.guilds.cache.size * 300); -}; - -module.exports.data = new CmdBuilder() - .setName('syncallbans') - .setDescription('Adds all bans from all participating servers. [OWNER ONLY].'); diff --git a/commands/syncbans.js b/commands/syncbans.js deleted file mode 100644 index fef425f..0000000 --- a/commands/syncbans.js +++ /dev/null @@ -1,49 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -const Ban = require('../database/models/Ban'); - -module.exports.run = async (interaction) => { - // check maintainer permissions - if (!await client.functions.get('CHECK_DB_perms').run(interaction.user.id)) { - messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - - const serverID = interaction.options.getString('server'); - - const server = await interaction.client.guilds.cache.find((guild) => guild.id === serverID); - - if (!server) return messageFail(interaction, 'Sorry, but I am unable to find that server.'); - - if (!DEBUG) await interaction.deferReply({ ephemeral: false }); - - const bans = await server.bans.fetch({ cache: false }).catch(ERR); - await bans.forEach(async ({ user, reason: reasonRaw }) => { - const reason = reasonRaw === null ? reasonRaw : reasonRaw.replace(new RegExp('\'', 'g'), '`'); - const userID = user.id; - const userBanned = true; - const userTag = user.tag; - - const [banEntry] = await Ban.findOrCreate({ - where: { userID, serverID }, - defaults: { reason, userTag, userBanned }, - }).catch(ERR); - if (!banEntry.isNewRecord) { - Ban.update({ reason, userBanned }, - { where: { userID, serverID } }) - .catch(ERR); - } - }); - - await reply(interaction, { embeds: [new MessageEmbed().setAuthor({ name: `Done importing bans from ${server.name}!` })] }); -}; - -module.exports.data = new CmdBuilder() - .setName('syncbans') - .setDescription('Adds all bans from the current server its beeing used in. [MAINTAINER ONLY]') - .addStringOption((option) => option - .setName('server') - .setDescription('Provide a guild ID you want to edit.') - .setAutocomplete(true) - // Needs to be required, otherwise servername is passed and not the serverID from Autocomplete - .setRequired(true)); diff --git a/commands/unban.js b/commands/unban.js deleted file mode 100644 index 13e750f..0000000 --- a/commands/unban.js +++ /dev/null @@ -1,33 +0,0 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); - -const { CommandInteraction } = require('discord.js'); - -/** - * @param { CommandInteraction } interaction - */ - -module.exports.run = async (interaction) => { - // check MANAGE_GUILD permissions - if (!interaction.memberPermissions.has('BAN_MEMBERS')) { - messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - const guild = interaction.guild; - // TODO: Filter the reason - update event-guildBanRemove - // const reason = options.getString('reason'); - - const user = interaction.options.getUser('user'); - - // Existing ban? - // FIXME: Bad implementation of catch() - const existingBan = await guild.bans.fetch(user).catch((e) => e); - if (existingBan.code) return messageFail(interaction, 'That user is not banned.'); - // unban user - await guild.bans.remove(user); - messageSuccess(interaction, `\`${user.tag}\` has been unbanned!`); -}; - -module.exports.data = new SlashCommandBuilder() - .setName('unban') - .setDescription('Unbans a user.') - .addUserOption((option) => option.setName('user').setDescription('Provide a user.').setRequired(true)); diff --git a/commands/warn.js b/commands/warn.js deleted file mode 100644 index df85854..0000000 --- a/commands/warn.js +++ /dev/null @@ -1,94 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -const Warn = require('../database/models/Warn'); - -// TODO: recreate richmessage embed sender to it can be sent to other servers - -// checks if server is partisipating server -function getServerEntry(serverID) { - return client.functions.get('GET_DB_server').run(serverID, true); -} - -// warns other servers -async function messageWarnedUserInGuild(channelID, userTag, userID, warnMessage, serverName) { - const embed = new MessageEmbed(); - embed.setColor(16755456); - embed.setFooter({ text: `For more information about this user, use '/lookup ${userID}'` }); - embed.setTitle(`A user on your server has been warned on '${serverName}'!`); - embed.setDescription(`Tag: \`${userTag}\` - ID: \`${userID}\` - Reason: \`\`\`${warnMessage || 'none'}\`\`\``); - const channel = await client.channels.cache.get(channelID); - channel.send({ embeds: [embed] }); -} - -// warns other servers for aliases -async function messageWarnedAliasUserInGuild(channelID, userTag, userID, warnMessage, serverName, orgUserTag) { - const embed = new MessageEmbed(); - embed.setColor(16755456); - embed.setFooter({ text: `For more information about this user, use '/lookup ${orgUserTag}'` }); - embed.setTitle(`An alias of a user on your server has been warned on '${serverName}'!`); - embed.setDescription(`**The user \`${userTag}\` is an alias of a user that has been warned!** - - Tag: \`${orgUserTag}\` - ID: \`${userID}\` - Reason: \`\`\`${warnMessage || 'none'}\`\`\``); - const channel = await client.channels.cache.get(channelID); - channel.send({ embeds: [embed] }); -} - -async function checkforInfectedGuilds(guild, orgUserID, warnMessage) { - let aliases = await client.functions.get('GET_DB_alias').run(orgUserID); - if (!aliases) aliases = [orgUserID]; - const orgUser = await client.users.fetch(orgUserID, false); - // look for each of the conencted users (alias) if they are a member in the corresponding guild - aliases.forEach((userID) => { - client.guilds.cache.forEach(async (toTestGuild) => { - // dont post in own guild - // TODO: warn own server that there are aliases: let through, if user is not the same as who a warn was issued for - if (guild.id === toTestGuild.id) return; - const serverMember = toTestGuild.members.cache.get(userID); - if (!serverMember) return; - const serverID = toTestGuild.id; - const infectedGuild = await getServerEntry(serverID); - if (infectedGuild && infectedGuild.active && infectedGuild.logChannelID) { - if (orgUserID === userID) messageWarnedUserInGuild(infectedGuild.logChannelID, orgUser.tag, orgUserID, warnMessage, guild.name); - else messageWarnedAliasUserInGuild(infectedGuild.logChannelID, serverMember.user.tag, orgUserID, warnMessage, guild.name, orgUser.tag); - } - }); - }); -} - -module.exports.run = async (interaction) => { - // check maintainer permissions - if (!await client.functions.get('CHECK_DB_perms').run(interaction.user.id, 'staff', interaction.guild.id, interaction.member)) { - messageFail(interaction, `You are not authorized to use \`/${module.exports.data.name}\``); - return; - } - const subName = interaction.options.getSubcommand(true); - const warnMessage = interaction.options.getString('message', true); - client.commands.get(`${module.exports.data.name}_${subName}`).run(interaction, warnMessage, Warn, checkforInfectedGuilds); -}; - -module.exports.data = new CmdBuilder() - .setName('warn') - .setDescription('Warns other servers about a specific user.') - .addSubcommand((SC) => SC - .setName('add') - .setDescription('Add warning.') - .addUserOption((option) => option.setName('user').setDescription('Provide a user.').setRequired(true)) - .addStringOption((option) => option - .setName('message') - .setDescription('Message this warning should be.') - .setRequired(true))) - .addSubcommand((SC) => SC - .setName('edit') - .setDescription('Edit a existing warning.') - .addNumberOption((option) => option - .setName('warnid') - .setDescription('Provide the warn ID of the one you want to edit.') - .setRequired(true)) - .addStringOption((option) => option - .setName('message') - .setDescription('Message this warning should be.') - .setRequired(true))); diff --git a/commands/warn/add.js b/commands/warn/add.js deleted file mode 100644 index 1e6fbce..0000000 --- a/commands/warn/add.js +++ /dev/null @@ -1,15 +0,0 @@ -// adds a Warn to the warning table -async function addWarn(Warn, serverID, userID, reason) { - await Warn.create({ userID, serverID, reason }).catch(ERR); -} - -module.exports.run = async (interaction, warnMessage, Warn, checkforInfectedGuilds) => { - // get information - const userID = interaction.options.getUser('user', true).id; - // add warn - await addWarn(Warn, interaction.guild.id, userID, warnMessage); - messageSuccess(interaction, `The user with the ID \`${userID}\` got a new warning added.\n Warning other servers.`); - checkforInfectedGuilds(interaction.guild, userID, warnMessage); -}; - -module.exports.data = { subcommand: true }; diff --git a/commands/warn/edit.js b/commands/warn/edit.js deleted file mode 100644 index 7d7adcc..0000000 --- a/commands/warn/edit.js +++ /dev/null @@ -1,33 +0,0 @@ -// edits a Warn to the warning table -async function editWarn(Warn, warnID, reason) { - Warn.update({ reason }, { where: { warnID } }).catch(ERR); -} - -async function getWarning(Warn, warnID) { - const found = await Warn.findOne({ where: { warnID } }).catch(ERR); - return found; -} - -module.exports.run = async (interaction, warnMessage, Warn, checkforInfectedGuilds) => { - // check if user exists - // if (isNaN(userIDOrWarnID)) { - // messageFail(interaction, 'This is not a warn-ID!'); - // return; - // } - const warnID = interaction.options.getNumber('warnid', true); - const serverID = interaction.guild.id; - const warning = await getWarning(Warn, warnID); - // check if warn is existent - if (!warning) return messageFail(interaction, 'A Warning with this ID doesn\'t exist!'); - // check if warn is from the same server - if (warning.serverID !== serverID) { - messageFail(interaction, 'You can only edit warnings form the server where they have been issued from.'); - return; - } - // add warn - await editWarn(Warn, warnID, warnMessage); - messageSuccess(interaction, `The warning with the the ID ${warnID} has been edited. Warning other servers.`); - checkforInfectedGuilds(interaction.guild, warning.userID, warnMessage); -}; - -module.exports.data = { subcommand: true }; diff --git a/config.json b/config.json deleted file mode 100644 index 553d909..0000000 --- a/config.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "Agent Black", - "teamRole": "638670637052854282", - "logChannel": "638793508202741790", - "setup": { - "setupFunctions": [ - "SETUP_heartbeat", - "SETUP_offlineStat", - "SETUP_status" - ] - }, - "commands": { - "lookup": { - "lowerQuerryLimit": 5, - "botBadge": "<:system_bot_notifier:813101401646432298>" - }, - "about": { - "text": "./about.txt" - }, - "changelog": { - "text": "./changelog.txt" - } - }, - "functions": { - "userTagRecord": { - "maxCacheTimeout": 10800000 - }, - "heartbeat": { - "uptime": { - "interval": 50000, - "endpoint": "http://statuspage_app_sp_1:3001/api/push/" - } - } - } -} \ No newline at end of file diff --git a/config/example_config.json b/config/example_config.json deleted file mode 100644 index dd75f26..0000000 --- a/config/example_config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "README": "THIS FILE OF FOR DEBUGGING PURPOSES ONLY! USE ENVIRONMENT VARIABLES IN PRODUCTION.", - "token": "**************************", - "development": { - "username": "***", - "password": "*****************", - "database": "**********************", - "host": "*****************", - "dialect": "mysql" - } -} \ No newline at end of file diff --git a/config/main.json b/config/main.json deleted file mode 100644 index bd8a0c8..0000000 --- a/config/main.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "Agent Black", - "prefix": { - "default": "a!", - "nicknameSpacer": " | " - }, - "setup": { - "moduleFolders": { - "functionsFolder": "functions", - "commandsFolder": "commands" - }, - "startupFunctions": [ - "STARTUP_initCommands", - "STARTUP_initFunctions", - "STARTUP_envPrep", - "STARTUP_DBConnection" - ], - "setupFunctions": [ - "SETUP_offlineStat", - "SETUP_status" - ], - "setupFunctionsOnce": [ - "TCKR_offlineStat" - ] - }, - "commands": { - "lookup": { - "lowerQuerryLimit": 5 - } - }, - "functions": { - "userTagRecord": { - "maxCacheTimeout": 10800000 - } - }, - "emojiLayout": "/(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c[\ude32-\ude3a]|[\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g", - "aboutText": "./config/about.txt", - "teamRole": "638670637052854282", - "logStatusChannel": "638793508202741790", - "lookupBotBadge": "<:system_bot_notifier:813101401646432298>" -} \ No newline at end of file diff --git a/database/models/Ban.js b/database/models/Ban.js deleted file mode 100644 index 9e9d83e..0000000 --- a/database/models/Ban.js +++ /dev/null @@ -1,27 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('Ban', { - banID: { - type: Sequelize.INTEGER(11), - primaryKey: true, - autoIncrement: true, - }, - userID: { - type: Sequelize.STRING(30), - allowNull: false, - }, - serverID: { - type: Sequelize.STRING(30), - allowNull: false, - }, - userTag: Sequelize.TEXT('tiny'), - reason: Sequelize.TEXT, - userBanned: Sequelize.BOOLEAN, -}, -{ - uniqueKeys: { - banUnique: { - fields: ['userID', 'serverID'], - }, - }, -}); diff --git a/database/models/Maintainer.js b/database/models/Maintainer.js deleted file mode 100644 index 5e0b343..0000000 --- a/database/models/Maintainer.js +++ /dev/null @@ -1,9 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('Maintainer', { - userID: { - type: Sequelize.STRING(30), - primaryKey: true, - unique: true, - }, -}); diff --git a/database/models/OfflineStat.js b/database/models/OfflineStat.js deleted file mode 100644 index c1017d5..0000000 --- a/database/models/OfflineStat.js +++ /dev/null @@ -1,9 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('OfflineStat', { - ID: { - type: Sequelize.STRING(30), - primaryKey: true, - }, - time: Sequelize.STRING(30), -}); diff --git a/database/models/ParticipatingServer.js b/database/models/ParticipatingServer.js deleted file mode 100644 index 578287f..0000000 --- a/database/models/ParticipatingServer.js +++ /dev/null @@ -1,25 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('ParticipatingServer', { - serverID: { - type: Sequelize.STRING(30), - primaryKey: true, - unique: true, - }, - logChannelID: Sequelize.STRING(30), - teamRoleID: Sequelize.STRING(30), - serverName: { - type: Sequelize.TEXT('tiny'), - allowNull: false, - }, - active: { - type: Sequelize.BOOLEAN, - allowNull: false, - defaultValue: false, - }, - blocked: { - type: Sequelize.BOOLEAN, - allowNull: false, - defaultValue: false, - }, -}); diff --git a/database/models/PointList.js b/database/models/PointList.js deleted file mode 100644 index 526eeb8..0000000 --- a/database/models/PointList.js +++ /dev/null @@ -1,21 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('PointList', { - ID: { - type: Sequelize.INTEGER, - primaryKey: true, - autoIncrement: true, - }, - name: { - type: Sequelize.TEXT('tiny'), - allowNull: false, - }, - description: { - type: Sequelize.TEXT, - allowNull: false, - }, - points: { - type: Sequelize.INTEGER, - allowNull: false, - }, -}); diff --git a/database/models/PunishmentLevel.js b/database/models/PunishmentLevel.js deleted file mode 100644 index 9255753..0000000 --- a/database/models/PunishmentLevel.js +++ /dev/null @@ -1,17 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('PunishmentLevel', { - ID: { - type: Sequelize.INTEGER, - primaryKey: true, - }, - name: { - type: Sequelize.TEXT('tiny'), - allowNull: false, - }, - command: { - type: Sequelize.TEXT('tiny'), - allowNull: false, - }, - amount: Sequelize.INTEGER, -}); diff --git a/database/models/ServerSetting.js b/database/models/ServerSetting.js deleted file mode 100644 index 5a2f74b..0000000 --- a/database/models/ServerSetting.js +++ /dev/null @@ -1,23 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('ServerSetting', { - serverID: { - type: Sequelize.STRING(30), - primaryKey: true, - }, - pointsSystemEnabled: { - type: Sequelize.BOOLEAN, - allowNull: false, - defaultValue: false, - }, - pointsSystemForceReason: { - type: Sequelize.BOOLEAN, - allowNull: false, - defaultValue: true, - }, - pointLifetime: { - type: Sequelize.STRING(30), - allowNull: false, - defaultValue: 1210000000, - }, -}); diff --git a/database/models/UserAlias.js b/database/models/UserAlias.js deleted file mode 100644 index 5f65e6a..0000000 --- a/database/models/UserAlias.js +++ /dev/null @@ -1,21 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('UserAlias', { - aliasID: { - type: Sequelize.INTEGER(11), - primaryKey: true, - autoIncrement: true, - }, - groupingID: { - type: Sequelize.STRING(30), - allowNull: false, - }, - userID: { - type: Sequelize.STRING(30), - allowNull: false, - }, - addedBy: { - type: Sequelize.STRING(30), - allowNull: false, - }, -}); diff --git a/database/models/UserIDAssociation.js b/database/models/UserIDAssociation.js deleted file mode 100644 index 8c804ba..0000000 --- a/database/models/UserIDAssociation.js +++ /dev/null @@ -1,24 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('UserIDAssociation', { - ID: { - type: Sequelize.INTEGER, - primaryKey: true, - autoIncrement: true, - }, - userID: { - type: Sequelize.STRING(30), - allowNull: false, - }, - userTag: { - type: Sequelize.TEXT('tiny'), - allowNull: false, - }, -// }, -// { -// uniqueKeys: { -// uniqueUserTagID: { -// fields: ['userTag', 'userID'], -// }, -// }, -}); diff --git a/database/models/UserPoint.js b/database/models/UserPoint.js deleted file mode 100644 index 47c2971..0000000 --- a/database/models/UserPoint.js +++ /dev/null @@ -1,28 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('UserPoint', { - ID: { - type: Sequelize.INTEGER, - primaryKey: true, - autoIncrement: true, - }, - pointsID: { - type: Sequelize.INTEGER, - references: { - model: 'PointsList', - key: 'ID', - }, - }, - userID: { - type: Sequelize.STRING(30), - allowNull: false, - }, - teamMember: { - type: Sequelize.STRING(30), - allowNull: false, - }, - note: { - type: Sequelize.TEXT, - allowNull: false, - }, -}); diff --git a/database/models/UserPunnishmentTicker.js b/database/models/UserPunnishmentTicker.js deleted file mode 100644 index a02eb4f..0000000 --- a/database/models/UserPunnishmentTicker.js +++ /dev/null @@ -1,25 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('UserPunishmentTicker', { - ID: { - type: Sequelize.INTEGER, - primaryKey: true, - autoIncrement: true, - }, - punishmentID: { - type: Sequelize.INTEGER, - allowNull: false, - references: { - model: 'PunishmentLevels', - key: 'ID', - }, - }, - userID: { - type: Sequelize.STRING(30), - allowNull: false, - }, - amountLeft: { - type: Sequelize.INTEGER, - allowNull: false, - }, -}); diff --git a/database/models/Warn.js b/database/models/Warn.js deleted file mode 100644 index a283005..0000000 --- a/database/models/Warn.js +++ /dev/null @@ -1,21 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('Warn', { - warnID: { - type: Sequelize.INTEGER(11), - primaryKey: true, - autoIncrement: true, - }, - userID: { - type: Sequelize.STRING(30), - allowNull: false, - }, - serverID: { - type: Sequelize.STRING(30), - allowNull: false, - }, - reason: { - type: Sequelize.TEXT, - allowNull: false, - }, -}); diff --git a/database/models/discardDeprecationWarning.js b/database/models/discardDeprecationWarning.js deleted file mode 100644 index bcf1f9f..0000000 --- a/database/models/discardDeprecationWarning.js +++ /dev/null @@ -1,8 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = sequelize.define('discardDeprecationWarning', { - userID: { - type: Sequelize.STRING(30), - primaryKey: true, - }, -}); diff --git a/functions/AUTOCOMPLETE/RESOLVE/channel.js b/functions/AUTOCOMPLETE/RESOLVE/channel.js deleted file mode 100644 index 37353d4..0000000 --- a/functions/AUTOCOMPLETE/RESOLVE/channel.js +++ /dev/null @@ -1,31 +0,0 @@ -/* -This function provides a autocomplete for channels in another server. -This is needed, as discords built in search only searches the server where the command is executed in -*/ - -module.exports.run = async (searchInput, guildId) => { - // if (searchInput.length <= 2) return []; - - const guild = client.guilds.cache.find((guild) => guild.id === guildId); - if (!guild) return [{ name: 'Define server first.', value: '0' }]; - - const channels = guild.channels.cache - .filter((channel) => channel.type === 'GUILD_TEXT'); - - // id search - if (searchInput !== '' && !isNaN(searchInput)) { - const found = channels.find((channel) => channel.id === searchInput); - if (found) return [{ name: found.name, value: found.id }]; - return [{ name: 'Unkown', value: searchInput }]; - } - - // text search - const channelReply = await channels - .filter((channel) => channel.name.toLowerCase().search(searchInput.toLowerCase()) !== -1) - .map((channel) => ({ name: channel.name, value: channel.id })); - return channelReply.slice(0, 24); -}; - -module.exports.data = { - name: 'server', -}; diff --git a/functions/AUTOCOMPLETE/RESOLVE/role.js b/functions/AUTOCOMPLETE/RESOLVE/role.js deleted file mode 100644 index 2c7c7c9..0000000 --- a/functions/AUTOCOMPLETE/RESOLVE/role.js +++ /dev/null @@ -1,30 +0,0 @@ -/* -This function provides a autocomplete for roles in another server. -This is needed, as discords built in search only searches the server where the command is executed in. -*/ - -module.exports.run = async (searchInput, guildId) => { - // if (searchInput.length <= 2) return []; - - const guild = client.guilds.cache.find((guild) => guild.id === guildId); - if (!guild) return [{ name: 'Define server first.', value: '0' }]; - - const roles = guild.roles.cache; - - // id search - if (searchInput !== '' && !isNaN(searchInput)) { - const found = roles.find((role) => role.id === searchInput); - if (found) return [{ name: found.name, value: found.id }]; - return [{ name: 'Unkown', value: searchInput }]; - } - - // text search - const channelReply = await roles - .filter((role) => role.name.toLowerCase().search(searchInput.toLowerCase()) !== -1) - .map((role) => ({ name: role.name, value: role.id })); - return channelReply.slice(0, 24); -}; - -module.exports.data = { - name: 'server', -}; diff --git a/functions/AUTOCOMPLETE/RESOLVE/server.js b/functions/AUTOCOMPLETE/RESOLVE/server.js deleted file mode 100644 index 18527ad..0000000 --- a/functions/AUTOCOMPLETE/RESOLVE/server.js +++ /dev/null @@ -1,27 +0,0 @@ -/* -This function provides a autocomplete for a full serverlist. -Discord doesn't provide a functionality for that. -*/ - -module.exports.run = async (searchInput) => { - if (searchInput.length <= 2) return []; - - const guilds = client.guilds.cache; - - // id search - if (!isNaN(searchInput)) { - const found = guilds.find((guild) => guild.id === searchInput); - if (found) return [{ name: found.name, value: found.id }]; - return [{ name: 'Unkown', value: searchInput }]; - } - - // text search - const guildReply = await guilds - .filter((guild) => guild.name.toLowerCase().search(searchInput.toLowerCase()) !== -1) - .map((guild) => ({ name: guild.name, value: guild.id })); - return guildReply.slice(0, 24); -}; - -module.exports.data = { - name: 'server', -}; diff --git a/functions/AUTOCOMPLETE/guildmgr.js b/functions/AUTOCOMPLETE/guildmgr.js deleted file mode 100644 index 7e42513..0000000 --- a/functions/AUTOCOMPLETE/guildmgr.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports.run = async (interaction) => { - // check maintainer permissions - if (!await client.functions.get('CHECK_DB_perms').run(interaction.user.id)) { - interaction.respond([{ name: `You are not authorized to use \`/${module.exports.data.name}\``, value: '0' }]); - return; - } - - const command = interaction.options.getFocused(true); - const guild = interaction.options.getString('server'); - const response = await client.functions.get(`AUTOCOMPLETE_RESOLVE_${command.name}`).run(command.value, guild).catch(ERR); - return interaction.respond(response); -}; - -module.exports.data = { - name: 'guildmgr', -}; diff --git a/functions/AUTOCOMPLETE/syncbans.js b/functions/AUTOCOMPLETE/syncbans.js deleted file mode 100644 index fe545b8..0000000 --- a/functions/AUTOCOMPLETE/syncbans.js +++ /dev/null @@ -1,18 +0,0 @@ -// TODO: better implementation of duplicate code - -module.exports.run = async (interaction) => { - // check maintainer permissions - if (!await client.functions.get('CHECK_DB_perms').run(interaction.user.id)) { - interaction.respond([{ name: `You are not authorized to use \`/${module.exports.data.name}\``, value: '0' }]); - return; - } - - const command = interaction.options.getFocused(true); - const guild = interaction.options.getString('server'); - const response = await client.functions.get(`AUTOCOMPLETE_RESOLVE_${command.name}`).run(command.value, guild).catch(ERR); - return interaction.respond(response); -}; - -module.exports.data = { - name: 'syncbans', -}; diff --git a/functions/CHECK/DB/perms.js b/functions/CHECK/DB/perms.js deleted file mode 100644 index 56cf24c..0000000 --- a/functions/CHECK/DB/perms.js +++ /dev/null @@ -1,20 +0,0 @@ -const Maintainer = require('../../../database/models/Maintainer'); - -const ParticipatingServer = require('../../../database/models/ParticipatingServer'); - -// TODO: pass interaction to use #memberPermissions -module.exports.run = async (userID, type, serverID, member) => { - switch (type || 'maintainer') { - case 'maintainer': return Maintainer.findOne({ where: { userID } }).catch(ERR); - case 'staff': - const serverSettings = await ParticipatingServer.findOne({ where: { serverID } }).catch(ERR); - const output = await member.roles.cache.find((role) => role.id === serverSettings.teamRoleID); - return output; - default: - return 'null'; - } -}; - -module.exports.data = { - name: 'perms', -}; diff --git a/functions/EVENT/guildBanAdd.js b/functions/EVENT/guildBanAdd.js deleted file mode 100644 index 0e87a6a..0000000 --- a/functions/EVENT/guildBanAdd.js +++ /dev/null @@ -1,116 +0,0 @@ -// TODO: better message implementation - -const { MessageEmbed } = require('discord.js'); - -const Ban = require('../../database/models/Ban'); - -// const ParticipatingServer = require('../database/models/ParticipatingServer'); - -async function sendMessage(channel, body, title, color, footer) { - // needs to be local as settings overlap from dofferent embed-requests - const embed = new MessageEmbed(); - - if (body) embed.setDescription(body); - if (title) embed.setTitle(title); - if (color) embed.setColor(color); - if (footer) embed.setFooter({ text: footer }); - - return channel.send({ embeds: [embed] }); -} - -// checks if server is partisipating server -function getServerEntry(serverID) { - return client.functions.get('GET_DB_registered').run(serverID, true); -} - -// creates a embed messagetemplate for succeded actions -async function messageBanSuccess(channelID, body) { - const channel = await client.channels.cache.get(channelID); - sendMessage(channel, body, 'A user has been banned!', 'GREEN', 'The ban has been recorded and other servers are getting warned!'); -} - -// creates a embed messagetemplate for failed actions -async function messageBannedUserInGuild(channelID, userTag, userID, banReason, serverName) { - const channel = await client.channels.cache.get(channelID); - sendMessage(channel, - `Tag: \`${userTag}\` - ID: \`${userID}\` - Reason: \`\`\`${banReason || 'none'}\`\`\``, - `A user on your server has been banned on '${serverName}'!`, - 'ORANGE', - `For more information and other bans and warns use '/lookup ${userID}'`); -} - -// warns other servers for aliases -async function messageBannedAliasUserInGuild(channelID, userTag, userID, warnReason, serverName, orgUserTag) { - const channel = await client.channels.cache.get(channelID); - const body = `**The user \`${userTag}\` is an alias of a user that has been banned!** - - Tag: \`${orgUserTag}\` - ID: \`${userID}\` - Reason: \`\`\`${warnReason || 'none'}\`\`\``; - const title = `A alias of a user on your server has been banned on '${serverName}'!`; - const footer = `For more information and other bans and warns use '/lookup ${orgUserTag}'`; - sendMessage(channel, body, title, 'ORANGE', footer); -} - -module.exports.run = async ({ guild, user }) => { - // check if server is setup - if (!await client.functions.get('GET_DB_registered').run(guild.id, false)) return; - // outside of ban due to followup code - const userID = user.id; - const userTag = user.tag; - const serverID = guild.id; - - // checking if user is AB - if (userID === client.user.id) return; - // check if server is blacklsited before sending api request - const bannedGuild = await getServerEntry(serverID); - if (bannedGuild.blocked) return; - // declaring so ban reason can be used in foreach loop - // getting newly added ban - const ban = await guild.bans.fetch(user); - // assign simpler values - const userBanned = '1'; - const reason = ban.reason; - // fix ban reason by filtering new line breaks - const fixedReason = reason === null ? reason : reason.replace(new RegExp('\'', 'g'), '`'); - // create of find DB entry - const [banEntry] = await Ban.findOrCreate({ - where: { userID, serverID }, - defaults: { userTag, reason: fixedReason, userBanned }, - }).catch(ERR); - // check if entry is already on DB - if (await !banEntry.isNewRecord) { - // update DB entry - Ban.update({ reason: fixedReason, userTag, userBanned }, - { where: { userTag, userID, serverID } }) - .catch(ERR); - } - // logic, to only output if not banned, is active and has a log channel - if (bannedGuild && bannedGuild.active && bannedGuild.logChannelID) { - messageBanSuccess(bannedGuild.logChannelID, `The user \`${userTag}\` with the ID \`${userID}\` has been banned from this server!\nReason: \`${fixedReason}\``); - } - // post for other servers - let aliases = await user.client.functions.get('GET_DB_alias').run(userID); - if (!aliases) aliases = [userID]; - aliases.forEach((toCheckUserID) => { - user.client.guilds.cache.forEach(async (toTestGuild) => { - if (guild.id === toTestGuild.id) return; - const serverMember = toTestGuild.members.cache.get(toCheckUserID); - // TODO: warn own server that there are aliases - if (!serverMember) return; - const serverID = toTestGuild.id; - const infectedGuild = await getServerEntry(serverID); - if (infectedGuild && infectedGuild.blocked) return; - if (infectedGuild && infectedGuild.active && infectedGuild.logChannelID) { - if (userID === toCheckUserID) messageBannedUserInGuild(infectedGuild.logChannelID, userTag, userID, fixedReason, guild.name); - else messageBannedAliasUserInGuild(infectedGuild.logChannelID, serverMember.user.tag, userID, fixedReason, guild.name, userTag); - } - }); - }); -}; - -module.exports.data = { - name: 'guildBanAdd', -}; diff --git a/functions/EVENT/guildBanRemove.js b/functions/EVENT/guildBanRemove.js deleted file mode 100644 index 438fafa..0000000 --- a/functions/EVENT/guildBanRemove.js +++ /dev/null @@ -1,15 +0,0 @@ -const Ban = require('../../database/models/Ban'); - -module.exports.run = async ({ guild, user }) => { - // check if server is setup - if (!await client.functions.get('GET_DB_registered').run(guild.id, false)) return; - // setting userBanned value to false for existing ban - const userID = user.id; - const serverID = guild.id; - // update ban-DB entry - Ban.update({ userBanned: false }, { where: { userID, serverID } }).catch(ERR); -}; - -module.exports.data = { - name: 'guildBanRemove', -}; diff --git a/functions/EVENT/guildCreate.js b/functions/EVENT/guildCreate.js deleted file mode 100644 index 8cfdc78..0000000 --- a/functions/EVENT/guildCreate.js +++ /dev/null @@ -1,61 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -const Ban = require('../../database/models/Ban'); - -const ParticipatingServer = require('../../database/models/ParticipatingServer'); - -// checks if server is participating server -function getServerEntry(serverID) { - return client.functions.get('GET_DB_registered').run(serverID, true); -} - -async function addServerEntry(serverID, serverName) { - await ParticipatingServer.findOrCreate({ where: { serverID, serverName } }).catch(ERR); -} - -module.exports.run = async (guild) => { - // debug protection - if (DEBUG) return; - const serverID = guild.id; - // check if was alreads added: add a server entry in the DB - if (!await getServerEntry(serverID)) await addServerEntry(serverID, guild.name); - // message owner about adding the bot and how to procceed - const owner = await guild.members.fetch(guild.ownerId); - const embed = new MessageEmbed() - .setTitle('Hello World!') - .setFooter({ text: 'Only you received this message.' }) - .setDescription(`Thanks for adding me to your delightful server. -Before you expect anything from me, I need you to complete some more steps before I get completely functional. - -In order to use me properly, you need to run the following commands in your server: -\`/guild setup\` -Then I will ask you for a log channel, where I am allowed to send messages, and a staff/team role that are authorized to use some of the commands. -After you run the command you need to confirm the Terms of Service and you are good to go! - -If you added our bot before already: Keep in mind, that you need to run \`/guild enable\` to use the old configuration. - -As the last step, it's recommended joining our Discord server for frequent updates or if there are questions about a ban. -We also gladly help you out, if you need any assistance with the bot. https://discord.gg/TqBwHtzzhD`); - owner.send({ embeds: [embed] }); - // add all bans to DB - const allBans = await guild.bans.fetch(); - allBans.forEach(async ({ user, reason }) => { - const regex = config.emojiLayout; - const userTag = user.tag.replace(regex, 'X'); - const userBanned = true; - const userID = user.id; - let fixedReason = reason; - if (reason !== null) fixedReason = reason.replace(new RegExp('\'', 'g'), '`'); - const [banEntry] = await Ban.findOrCreate({ - where: { userID, serverID }, - defaults: { reason: fixedReason, userTag, userBanned }, - }).catch(ERR); - if (!banEntry.isNewRecord) { - Ban.update({ reason: fixedReason, userBanned }, { where: { userID, serverID } }).catch(ERR); - } - }); -}; - -module.exports.data = { - name: 'guildCreate', -}; diff --git a/functions/EVENT/guildDelete.js b/functions/EVENT/guildDelete.js deleted file mode 100644 index 1db2a23..0000000 --- a/functions/EVENT/guildDelete.js +++ /dev/null @@ -1,20 +0,0 @@ -const ParticipatingServer = require('../../database/models/ParticipatingServer'); - -// removes a server from the ParticipatingServers table -async function removeServer(serverID) { - const success = await ParticipatingServer.update( - { active: false }, - { where: { serverID, active: true } }, - ).catch(ERR); - return success[0]; -} - -module.exports.run = async (guild) => { - // check if server is setup - if (!await client.functions.get('GET_DB_registered').run(guild.id, false)) return; - await removeServer(guild.id); -}; - -module.exports.data = { - name: 'guildDelete', -}; diff --git a/functions/EVENT/guildMemberAdd.js b/functions/EVENT/guildMemberAdd.js deleted file mode 100644 index 86e20e9..0000000 --- a/functions/EVENT/guildMemberAdd.js +++ /dev/null @@ -1,78 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -const Ban = require('../../database/models/Ban'); - -const Warn = require('../../database/models/Warn'); - -// checks if server is participating server -function getServerEntry(serverID) { - return client.functions.get('GET_DB_registered').run(serverID, false); -} - -// get log channel of server -function findLogChannel(logChannelID) { - return client.channels.cache.find((channel) => channel.id === logChannelID); -} - -async function sendMessage(channel, body, title, color, footer) { - // needs to be local as settings overlap from dofferent embed-requests - const embed = new MessageEmbed(); - - if (body) embed.setDescription(body); - if (title) embed.setTitle(title); - if (color) embed.setColor(color); - if (footer) embed.setFooter({ text: footer }); - - return channel.send({ embeds: [embed] }); -} - -// send message when user is banned -async function prepareMessage(serverID, userID, userTag, userBans, userWarns, alias, orgUserTag) { - const server = await getServerEntry(serverID); - const logChannelID = server.logChannelID; - const logChannel = await findLogChannel(logChannelID); - const serverName = server.serverName; - - // update title, when alias - const title = alias ? `Alias of '${orgUserTag}'` : `Known user joined '${serverName}'`; - - sendMessage(logChannel, `tag: \`${userTag}\` - ID: \`${userID}\` - bans: \`${userBans}\` - warns: \`${userWarns}\` - For more information use \`/lookup ${userID}\``, title, 'ORANGE'); -} - -module.exports.run = async (member) => { - // check if server is setup - if (!await client.functions.get('GET_DB_registered').run(member.guild.id, false)) return; - // record user tag - client.functions.get('SET_DB_userTagRecord').run(member.id, member.user.tag); - // check if user is banned on some server - const [serverID, orgUserID, orgUserTag] = [member.guild.id, member.id, member.user.tag]; - // get all bans and warnings the joined user has - const userBans = await Ban.count({ where: { userID: orgUserID } }).catch(ERR); - const userWarns = await Warn.count({ where: { userID: orgUserID } }).catch(ERR); - // calculate sum and check if sum is 0 - const overallAmmount = userBans + userWarns; - if (overallAmmount === 0) return; - // post message - prepareMessage(serverID, orgUserID, orgUserTag, userBans, userWarns); - - // lookup aliases - // check if user has aliases - const output = await client.functions.get('GET_DB_alias').run(member.id); - if (output) { - output.forEach(async (aliasUserID) => { - if (orgUserID === aliasUserID) return; - const aliasUser = await client.users.fetch(aliasUserID, false).catch(ERR); - const aliasUserBans = await Ban.count({ where: { userID: aliasUserID } }).catch(ERR); - const aliasUserWarns = await Warn.count({ where: { userID: aliasUserID } }).catch(ERR); - prepareMessage(serverID, aliasUserID, aliasUser.tag, aliasUserBans, aliasUserWarns, true, orgUserTag); - }); - } -}; - -module.exports.data = { - name: 'guildMemberAdd', -}; diff --git a/functions/EVENT/interaction/isAutocomplete.js b/functions/EVENT/interaction/isAutocomplete.js deleted file mode 100644 index c59b397..0000000 --- a/functions/EVENT/interaction/isAutocomplete.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports.run = async (interaction) => { - // const commandName = DEBUG ? interaction.commandName.replace('_dev', '') : interaction.commandName; - const commandName = interaction.commandName.replace('_dev', ''); - return client.functions.get(`AUTOCOMPLETE_${commandName}`).run(interaction).catch(ERR); -}; - -module.exports.data = { - name: 'isAutocomplete', -}; diff --git a/functions/EVENT/interaction/isCommand.js b/functions/EVENT/interaction/isCommand.js deleted file mode 100644 index 1aa293f..0000000 --- a/functions/EVENT/interaction/isCommand.js +++ /dev/null @@ -1,44 +0,0 @@ -async function checkServerBlockStatus(serverID) { - const ParticipatingServer = require('../../../database/models/ParticipatingServer'); - const found = await ParticipatingServer.findOne({ where: { serverID, blocked: true } }).catch(ERR); - return found; -} - -module.exports.run = async (interaction) => { - // debug protection - if (!DEBUG && interaction.commandName.includes('_dev')) return; - if (DEBUG && !interaction.commandName.includes('_dev')) return; - - const mainCMD = interaction.commandName.replace('_dev', ''); - // commands to let through, when guild is blocked - const infoCMDs = ['about', 'ping']; - // check if blocked - if (!infoCMDs.includes(mainCMD) && await checkServerBlockStatus(interaction.guild.id)) { - messageFail(interaction, 'It seems your server got blocked from the bot usage. If you want to know the reason and/or want to appeal, feel free to join the server linked in /about.'); - return; - } - // commands to block, when guild has not been setup yet - const mgmtCMDs = ['alias', 'ban', 'broadcast', 'eval', 'lookup', 'maintainer', 'warn']; - // check if active and if its a management command - if (mgmtCMDs.includes(mainCMD) && !await client.functions.get('GET_DB_server').run(interaction.guild.id, false)) { - messageFail(interaction, - `You need to setup the server first before you can use this command. - Please run \`/guild setup\`. - If you need help, please view the respective wiki article here (https://github.com/FlippedCode/agent-black/wiki/Adding-the-Bot) - or join our support server (https://discord.gg/TqBwHtzzhD).`); - return; - } - - const command = client.commands.get(DEBUG ? mainCMD : interaction.commandName); - if (command) { - // if debuging trigger application thinking - // TEMP: set to false to test some public commands - if (DEBUG) await interaction.deferReply({ ephemeral: false }); - command.run(interaction).catch(ERR); - return; - } -}; - -module.exports.data = { - name: 'isCommand', -}; diff --git a/functions/EVENT/interactionCreate.js b/functions/EVENT/interactionCreate.js deleted file mode 100644 index 9f291e4..0000000 --- a/functions/EVENT/interactionCreate.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports.run = async (interaction) => { - // only guild command - // TODO: check if neseccary, because this seems to be a useless intent 'DIRECT_MESSAGES' - // TODO: maybe check if command deployment to DM can be supressed - if (!await interaction.inGuild()) return messageFail(interaction, 'The bot is for server-use only.'); - - // autocomplete hanlder - if (interaction.isAutocomplete()) return client.functions.get('EVENT_interaction_isAutocomplete').run(interaction).catch(ERR); - // command handler - if (interaction.isCommand()) return client.functions.get('EVENT_interaction_isCommand').run(interaction).catch(ERR); -}; - -module.exports.data = { - name: 'interactionCreate', -}; diff --git a/functions/GET/DB/alias.js b/functions/GET/DB/alias.js deleted file mode 100644 index 4151c21..0000000 --- a/functions/GET/DB/alias.js +++ /dev/null @@ -1,28 +0,0 @@ -const UserAlias = require('../../../database/models/UserAlias'); - -async function getGroupID(userID) { - const found = await UserAlias.findOne({ where: { userID } }) - .catch(ERR); - return found; -} - -async function getUserIDs(groupingID) { - const found = await UserAlias.findAll({ where: { groupingID } }) - .catch(ERR); - return found; -} - -module.exports.run = async (userID) => { - const groupID = await getGroupID(userID); - if (!groupID) return; - const users = await getUserIDs(groupID.groupingID); - return users.map((user) => user.userID); -}; - -module.exports.data = { - name: 'alias', -}; - -// update table to make pairs and check then for the pair, makes easyer sql questioning -// when adding a user, check if user OR ALIAS is already in a pair and add the new user to it -// when both users are in a pair throw error diff --git a/functions/GET/DB/registered.js b/functions/GET/DB/registered.js deleted file mode 100644 index e7c9bf9..0000000 --- a/functions/GET/DB/registered.js +++ /dev/null @@ -1,10 +0,0 @@ -const ParticipatingServer = require('../../../database/models/ParticipatingServer'); - -module.exports.run = async (serverID, onlyCheckEntry) => { - if (onlyCheckEntry) return ParticipatingServer.findOne({ where: { serverID } }).catch(ERR); - return ParticipatingServer.findOne({ where: { serverID, active: true, blocked: false } }).catch(ERR); -}; - -module.exports.data = { - name: 'registered', -}; diff --git a/functions/GET/DB/server.js b/functions/GET/DB/server.js deleted file mode 100644 index 3545d8a..0000000 --- a/functions/GET/DB/server.js +++ /dev/null @@ -1,14 +0,0 @@ -const ParticipatingServer = require('../../../database/models/ParticipatingServer'); - -module.exports.run = async (serverID, onlyCheckEntry) => { - if (onlyCheckEntry) { - return ParticipatingServer.findOne({ where: { serverID } }) - .catch(ERR); - } - return ParticipatingServer.findOne({ where: { serverID, active: true, blocked: false } }) - .catch(ERR); -}; - -module.exports.help = { - name: 'server', -}; diff --git a/functions/HEARTBEAT/BOTLIST/botsondiscord.js b/functions/HEARTBEAT/BOTLIST/botsondiscord.js deleted file mode 100644 index 17bbafe..0000000 --- a/functions/HEARTBEAT/BOTLIST/botsondiscord.js +++ /dev/null @@ -1,24 +0,0 @@ -const axios = require('axios'); - -function sendHeartbeat() { - axios({ - method: 'post', - url: `${config.functions.heartbeat.discordbotlist.endpoint}${client.id}/guilds`, - headers: { - Authorization: process.env.token_botsondiscord, - 'Content-Type': 'application/json', - 'User-Agent': `FurExplicitBot/${config.package.version} by Phil | Flipper#3621 on Discord`, - }, - data: { guildCount: client.guilds.cache.size }, - }); -} - -module.exports.run = async () => { - setInterval(() => { - sendHeartbeat(); - }, config.functions.heartbeat.discordbotlist.interval); -}; - -module.exports.data = { - name: 'botsondiscord', -}; diff --git a/functions/HEARTBEAT/BOTLIST/discordbotlist.js b/functions/HEARTBEAT/BOTLIST/discordbotlist.js deleted file mode 100644 index 76d0ec4..0000000 --- a/functions/HEARTBEAT/BOTLIST/discordbotlist.js +++ /dev/null @@ -1,23 +0,0 @@ -const axios = require('axios'); - -function sendHeartbeat() { - axios({ - method: 'post', - url: `${config.functions.heartbeat.discordbotlist.endpoint}${client.id}/stats`, - headers: { - Authorization: process.env.token_discordbotlist, - 'User-Agent': `FurExplicitBot/${config.package.version} by Phil | Flipper#3621 on Discord`, - }, - data: { guilds: client.guilds.cache.size }, - }); -} - -module.exports.run = async () => { - setInterval(() => { - sendHeartbeat(); - }, config.functions.heartbeat.discordbotlist.interval); -}; - -module.exports.data = { - name: 'discordbotlist', -}; diff --git a/functions/HEARTBEAT/BOTLIST/discordlist.js b/functions/HEARTBEAT/BOTLIST/discordlist.js deleted file mode 100644 index ef88fcd..0000000 --- a/functions/HEARTBEAT/BOTLIST/discordlist.js +++ /dev/null @@ -1,24 +0,0 @@ -const axios = require('axios'); - -function sendHeartbeat() { - axios({ - method: 'post', - url: `${config.functions.heartbeat.discordbotlist.endpoint}${client.id}`, - headers: { - Authorization: process.env.token_discordlist, - 'Content-Type': 'application/json', - 'User-Agent': `FurExplicitBot/${config.package.version} by Phil | Flipper#3621 on Discord`, - }, - data: { serverCount: client.guilds.cache.size }, - }); -} - -module.exports.run = async () => { - setInterval(() => { - sendHeartbeat(); - }, config.functions.heartbeat.discordbotlist.interval); -}; - -module.exports.data = { - name: 'discordlist', -}; diff --git a/functions/HEARTBEAT/BOTLIST/discords.js b/functions/HEARTBEAT/BOTLIST/discords.js deleted file mode 100644 index 814a4cd..0000000 --- a/functions/HEARTBEAT/BOTLIST/discords.js +++ /dev/null @@ -1,24 +0,0 @@ -const axios = require('axios'); - -function sendHeartbeat() { - axios({ - method: 'post', - url: `${config.functions.heartbeat.discordbotlist.endpoint}${client.id}`, - headers: { - Authorization: process.env.token_discords, - // 'Content-Type': 'application/json', - 'User-Agent': `FurExplicitBot/${config.package.version} by Phil | Flipper#3621 on Discord`, - }, - data: { server_count: client.guilds.cache.size }, - }); -} - -module.exports.run = async () => { - setInterval(() => { - sendHeartbeat(); - }, config.functions.heartbeat.discordbotlist.interval); -}; - -module.exports.data = { - name: 'discords', -}; diff --git a/functions/HEARTBEAT/BOTLIST/disordbots.js b/functions/HEARTBEAT/BOTLIST/disordbots.js deleted file mode 100644 index 3c6d390..0000000 --- a/functions/HEARTBEAT/BOTLIST/disordbots.js +++ /dev/null @@ -1,24 +0,0 @@ -const axios = require('axios'); - -function sendHeartbeat() { - axios({ - method: 'post', - url: `${config.functions.heartbeat.discordbotlist.endpoint}${client.id}/stats`, - headers: { - Authorization: process.env.token_discordbots, - 'Content-Type': 'application/json', - 'User-Agent': `FurExplicitBot/${config.package.version} by Phil | Flipper#3621 on Discord`, - }, - data: { guildCount: client.guilds.cache.size }, - }); -} - -module.exports.run = async () => { - setInterval(() => { - sendHeartbeat(); - }, config.functions.heartbeat.discordbotlist.interval); -}; - -module.exports.data = { - name: 'disordbots', -}; diff --git a/functions/HEARTBEAT/BOTLIST/motiondevelopment.js b/functions/HEARTBEAT/BOTLIST/motiondevelopment.js deleted file mode 100644 index c6d2eb1..0000000 --- a/functions/HEARTBEAT/BOTLIST/motiondevelopment.js +++ /dev/null @@ -1,24 +0,0 @@ -const axios = require('axios'); - -function sendHeartbeat() { - axios({ - method: 'post', - url: `${config.functions.heartbeat.motiondevelopment.endpoint}${client.id}/stats`, - headers: { - key: process.env.token_motiondevelopment, - 'Content-Type': 'application/json', - // 'User-Agent': `FurExplicitBot/${config.package.version} by Phil | Flipper#3621 on Discord`, - }, - data: { guilds: client.guilds.cache.size }, - }); -} - -module.exports.run = async () => { - setInterval(() => { - sendHeartbeat(); - }, config.functions.heartbeat.motiondevelopment.interval); -}; - -module.exports.data = { - name: 'motiondevelopment', -}; diff --git a/functions/HEARTBEAT/uptime.js b/functions/HEARTBEAT/uptime.js deleted file mode 100644 index 9482ae7..0000000 --- a/functions/HEARTBEAT/uptime.js +++ /dev/null @@ -1,23 +0,0 @@ -// TODO: use vanilla implementation so not an entire packige is needed -const axios = require('axios'); - -const params = (pingRaw) => ( - { - msg: 'OK', - ping: Math.round(pingRaw), - } -); - -function sendHeartbeat() { - axios.get(`${config.functions.heartbeat.uptime.endpoint}${process.env.token_uptime}`, { params: params(client.ws.ping) }); -} - -module.exports.run = async () => { - setInterval(() => { - sendHeartbeat(); - }, config.functions.heartbeat.uptime.interval); -}; - -module.exports.data = { - name: 'uptime', -}; diff --git a/functions/SET/DB/userTagRecord.js b/functions/SET/DB/userTagRecord.js deleted file mode 100644 index 09c3429..0000000 --- a/functions/SET/DB/userTagRecord.js +++ /dev/null @@ -1,29 +0,0 @@ -const config = require('../../../config/main.json'); - -const UserIDAssociation = require('../../../database/models/UserIDAssociation'); - -const cachedUsers = new Set(); - -function timeout(id) { - cachedUsers.add(id); - setTimeout(() => cachedUsers.delete(id), config.functions.userTagRecord.maxCacheTimeout); -} - -module.exports.run = async (userID, userTag) => { - // return in discriminator is "#0000" - if (userTag.indexOf('#0000') !== -1) return; - // check if user has said anything in the last 3hrs - if (cachedUsers.has(userID)) return; - // if not, add it - timeout(userID); - // and add entry to DB if not yet existent - UserIDAssociation.findOrCreate({ - where: { userID }, - defaults: { userTag }, - }) - .catch(ERR); -}; - -module.exports.data = { - name: 'userTagRecord', -}; diff --git a/functions/SETUP/heartbeat.js b/functions/SETUP/heartbeat.js deleted file mode 100644 index 6a7b9d5..0000000 --- a/functions/SETUP/heartbeat.js +++ /dev/null @@ -1,21 +0,0 @@ -// Calls all the functions that are needed for a heartbeat -module.exports.run = async () => { - if (DEBUG) return; - console.log(`[${module.exports.data.name}] Start sending heartbeats...`); - // botlists - // TODO: Better implementation: call on startup or when servercount changes - // TODO: Generelize function as all are quite simmilar - // client.functions.get('HEARTBEAT_BOTLIST_botsondiscord').run(); - // client.functions.get('HEARTBEAT_BOTLIST_discordbotlist').run(); - // client.functions.get('HEARTBEAT_BOTLIST_discordlist').run(); - // client.functions.get('HEARTBEAT_BOTLIST_discords').run(); - // client.functions.get('HEARTBEAT_BOTLIST_discordbots').run(); - // client.functions.get('HEARTBEAT_BOTLIST_motiondevelopment').run(); - // uptime page - // client.functions.get('HEARTBEAT_uptime').run(); -}; - -module.exports.data = { - name: 'heartbeat', - callOn: '-', -}; diff --git a/functions/SETUP/offlineStat.js b/functions/SETUP/offlineStat.js deleted file mode 100644 index 4ec5025..0000000 --- a/functions/SETUP/offlineStat.js +++ /dev/null @@ -1,41 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -const toTime = require('pretty-ms'); - -const startupTime = +new Date(); - -const OfflineStat = require('../../database/models/OfflineStat'); - -module.exports.run = async () => { - if (DEBUG) return; - console.log(`[${module.exports.data.name}] Posting bot status message!`); - const embed = new MessageEmbed() - .setTitle('AgentBlack - Bot back online!') - .setColor('GREEN') - .setFooter({ text: client.user.tag, iconURL: client.user.displayAvatarURL }) - .setTimestamp(); - const offlineTime = await OfflineStat.findOne({ where: { ID: 1 } }).catch(ERR); - if (offlineTime) { - embed - .addField('The time the bot went offline:', `${toTime(startupTime - offlineTime.time * 1)}`, false) - .addField('The bot went offline at:', `${new Date(offlineTime.time * 1)}`, false); - } else { - embed.setDescription('The time that the bot was offline, is missing. A new entry got created!'); - } - client.channels.cache.get(config.logChannel).send({ embeds: [embed] }); - - setInterval(async () => { - // loop db update in 5 sec intervall - const [offlineStat] = await OfflineStat.findOrCreate({ - where: { ID: 1 }, defaults: { time: startupTime }, - }).catch(ERR); - if (!offlineStat.isNewRecord) { - OfflineStat.update({ time: +new Date() }, { where: { ID: 1 } }).catch(ERR); - } - }, 1 * 5000); -}; - -module.exports.data = { - name: 'offlineStat', - callOn: 'setup', -}; diff --git a/functions/SETUP/status.js b/functions/SETUP/status.js deleted file mode 100644 index 8dcbb8b..0000000 --- a/functions/SETUP/status.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports.run = async () => { - if (DEBUG) return; - console.log(`[${module.exports.data.name}] Setting status...`); - await client.user.setStatus('online'); - // const membercount = await client.guilds.cache.reduce((previousCount, currentGuild) => previousCount + currentGuild.memberCount, 0); - // TODO: update activity message, maybe with servercount, once reached 100 servers - await client.user.setActivity('with /help'); - console.log(`[${module.exports.data.name}] Status set!`); -}; - -module.exports.data = { - name: 'status', - callOn: '-', -}; diff --git a/functions/STARTUP/DBConnection.js b/functions/STARTUP/DBConnection.js deleted file mode 100644 index bb0ca34..0000000 --- a/functions/STARTUP/DBConnection.js +++ /dev/null @@ -1,24 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports.run = () => { - console.log('[DB] Connecting...'); - - const sequelize = new Sequelize( - process.env.DBName, - process.env.DBUsername, - process.env.DBPassword, - { - host: process.env.DBHost, - dialect: 'mysql', - logging: DEBUG ? console.log : false, - }, - ); - sequelize.query('SET NAMES utf8mb4;'); - console.log('[DB] Connected!'); - - global.sequelize = sequelize; -}; - -module.exports.data = { - name: 'DBConnection', -}; diff --git a/functions/STARTUP/initCommands.js b/functions/STARTUP/initCommands.js deleted file mode 100644 index 3a794b1..0000000 --- a/functions/STARTUP/initCommands.js +++ /dev/null @@ -1,64 +0,0 @@ -const Path = require('path'); - -const files = []; - -function getFiles(fs, Directory) { - fs.readdirSync(Directory).forEach((File) => { - const Absolute = Path.join(Directory, File); - if (fs.statSync(Absolute).isDirectory()) return getFiles(fs, Absolute); - files.push(Absolute); - }); - return files; -} - -module.exports.run = async (fs) => { - // create empty array to store command submittions - const commandsSubmit = []; - // get all command files - const files = await getFiles(fs, './commands/'); - // only get file with '.js' - const jsfiles = files.filter((f) => f.split('.').pop() === 'js'); - const cmdLength = jsfiles.length; - // check if commands are there - if (cmdLength <= 0) return console.log(`[${module.exports.data.name}] No command(s) to load!`); - // announcing command loading - if (DEBUG) console.log(`[${module.exports.data.name}] Loading ${cmdLength} command${cmdLength !== 1 ? 's' : ''}...`); - - // adding all commands - await jsfiles.forEach((f, i) => { - // get module functions and info - const probs = require(`../../${f}`); - // cleanup name - const cleanName = f - .replace(/\\|\//g, '_') - .replace('commands_', '') - .replace('.js', ''); - // abort entry if in disabled folder - if (cleanName.search('archive_') !== -1) return; - // announcing command loading - if (DEBUG) console.log(`[${module.exports.data.name}] ${i + 1}) Loaded: ${cleanName}!`); - // adding command to collection - client.commands.set(cleanName, probs); - // if not subcommand: adding command to submittion to discord - if (!probs.data.subcommand) commandsSubmit.push(probs.data.toJSON()); - }); - const registerLength = commandsSubmit.length; - - await console.log(`[${module.exports.data.name}] Loaded ${cmdLength} command${cmdLength !== 1 ? 's' : ''}!`); - await console.log(`[${module.exports.data.name}] Registering ${registerLength} command${registerLength !== 1 ? 's' : ''}...`); - // submit commands to discord api| Dev: one guild only, prod: globaly - // WARN: TODO: make sure it doesn't disable the production commands while in debug mode - if (DEBUG) { - const changedCommands = commandsSubmit.map((command) => { - const newCommand = command; - newCommand.name = `${command.name}_dev`; - return newCommand; - }); - await client.application.commands.set(changedCommands, process.env.devGuild).catch(ERR); - } else await client.application.commands.set(commandsSubmit).catch(ERR); - console.log(`[${module.exports.data.name}] ${registerLength} command${registerLength !== 1 ? 's' : ''} registered!`); -}; - -module.exports.data = { - name: 'initCommands', -}; diff --git a/functions/STARTUP/initFunctions.js b/functions/STARTUP/initFunctions.js deleted file mode 100644 index a46182a..0000000 --- a/functions/STARTUP/initFunctions.js +++ /dev/null @@ -1,46 +0,0 @@ -const Path = require('path'); - -const files = []; - -// read directory with functions -function getFiles(fs, Directory) { - fs.readdirSync(Directory).forEach((File) => { - const Absolute = Path.join(Directory, File); - if (fs.statSync(Absolute).isDirectory()) return getFiles(fs, Absolute); - files.push(Absolute); - }); - return files; -} - -module.exports.run = async (fs) => { - // get all function files - const files = await getFiles(fs, './functions/'); - // only get file with '.js' - const jsfiles = files.filter((f) => f.split('.').pop() === 'js'); - const funcLength = jsfiles.length; - // check if functions are there - if (jsfiles.length <= 0) return console.log(`[${module.exports.data.name}] No function(s) to load!`); - - if (DEBUG) console.log(`[${module.exports.data.name}] Loading ${funcLength} function${funcLength !== 1 ? 's' : ''}...`); - - // adding all functions - jsfiles.forEach((f, i) => { - const probs = require(`../../${f}`); - // cleanup name - const cleanName = f - .replace(/\\|\//g, '_') - .replace('functions_', '') - .replace('.js', ''); - // abort entry if in disabled folder - if (cleanName.search('archive_') !== -1) return; - if (DEBUG) console.log(`[${module.exports.data.name}] ${i + 1}) Loaded: ${cleanName}!`); - // adding function to collection - client.functions.set(cleanName, probs); - }); - - console.log(`[${module.exports.data.name}] Loaded ${funcLength} function${funcLength !== 1 ? 's' : ''}!`); -}; - -module.exports.data = { - name: 'initFunctions', -}; diff --git a/functions/archive/CMD_punish_add.js b/functions/archive/CMD_punish_add.js deleted file mode 100644 index f7e6bb9..0000000 --- a/functions/archive/CMD_punish_add.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punish_add', - parent: 'punish', -}; diff --git a/functions/archive/CMD_punish_list.js b/functions/archive/CMD_punish_list.js deleted file mode 100644 index acce195..0000000 --- a/functions/archive/CMD_punish_list.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punish_list', - parent: 'punish', -}; diff --git a/functions/archive/CMD_punish_listPunnishments.js b/functions/archive/CMD_punish_listPunnishments.js deleted file mode 100644 index 20bd6d0..0000000 --- a/functions/archive/CMD_punish_listPunnishments.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punish_listPunishments', - parent: 'punish', -}; diff --git a/functions/archive/CMD_punish_manualAdd.js b/functions/archive/CMD_punish_manualAdd.js deleted file mode 100644 index d91e789..0000000 --- a/functions/archive/CMD_punish_manualAdd.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punish_manualAdd', - parent: 'punish', -}; diff --git a/functions/archive/CMD_punish_manualRemove.js b/functions/archive/CMD_punish_manualRemove.js deleted file mode 100644 index 086ea58..0000000 --- a/functions/archive/CMD_punish_manualRemove.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punish_manualRemove', - parent: 'punish', -}; diff --git a/functions/archive/CMD_punish_remove.js b/functions/archive/CMD_punish_remove.js deleted file mode 100644 index 3b3490b..0000000 --- a/functions/archive/CMD_punish_remove.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punish_remove', - parent: 'punish', -}; diff --git a/functions/archive/CMD_punish_stats.js b/functions/archive/CMD_punish_stats.js deleted file mode 100644 index 6e1f1bd..0000000 --- a/functions/archive/CMD_punish_stats.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punish_stats', - parent: 'punish', -}; diff --git a/functions/archive/CMD_punish_userStats.js b/functions/archive/CMD_punish_userStats.js deleted file mode 100644 index 65f5d3f..0000000 --- a/functions/archive/CMD_punish_userStats.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punish_userStats', - parent: 'punish', -}; diff --git a/functions/archive/CMD_punishsettings_addPunnishment.js b/functions/archive/CMD_punishsettings_addPunnishment.js deleted file mode 100644 index 0b826a3..0000000 --- a/functions/archive/CMD_punishsettings_addPunnishment.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punishsettings_addPunishment', - parent: 'punishsettings', -}; diff --git a/functions/archive/CMD_punishsettings_addReason.js b/functions/archive/CMD_punishsettings_addReason.js deleted file mode 100644 index 9c0831f..0000000 --- a/functions/archive/CMD_punishsettings_addReason.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punishsettings_addReason', - parent: 'punishsettings', -}; diff --git a/functions/archive/CMD_punishsettings_enable.js b/functions/archive/CMD_punishsettings_enable.js deleted file mode 100644 index 0499aa4..0000000 --- a/functions/archive/CMD_punishsettings_enable.js +++ /dev/null @@ -1,56 +0,0 @@ -const ServerSetting = require('../../database/models/ServerSetting'); - -// adds server if not existent -async function createServer(serverID) { - const created = await ServerSetting.findOrCreate({ where: { serverID } }).catch(ERR); - return created; -} - -// checks is server is on list -async function checkServer(serverID) { - const found = await ServerSetting.findOne({ where: { serverID } }) - .catch(ERR); - return found; -} - -// enables points system -async function enablePointsSystem(serverID) { - const enabled = await ServerSetting.update({ pointsSystemEnabled: true }, - { where: { serverID } }) - .catch(ERR); - return enabled; -} - -// disables points system -async function disablePointsSystem(serverID) { - const disabled = await ServerSetting.update({ pointsSystemEnabled: false }, - { where: { serverID } }) - .catch(ERR); - return disabled; -} - -module.exports.run = async (message, args, config, prefix) => { - const serverID = message.guild.id; - const [subcmd, enable] = args; - const lowercaseEnable = enable.toLowerCase(); - // check if value is a bool - if (!(lowercaseEnable === 'true' || lowercaseEnable === 'false')) { - messageFail(message, CommandUsage(config.prefix, module.exports.help.parent, 'enable TRUEORFALSE')); - return; - } - // check if server exists in list and create it - const serverExist = await checkServer(serverID); - if (!serverExist) await createServer(serverID); - // set value - let messageState = 'disabled'; - if (lowercaseEnable === 'true') { - await enablePointsSystem(serverID); - messageState = 'enabled'; - } else await disablePointsSystem(serverID); - messageSuccess(message, `Successfully ${messageState} setting.`); -}; - -module.exports.help = { - name: 'CMD_punishsettings_enable', - parent: 'punishsettings', -}; diff --git a/functions/archive/CMD_punishsettings_forceReason.js b/functions/archive/CMD_punishsettings_forceReason.js deleted file mode 100644 index 943327c..0000000 --- a/functions/archive/CMD_punishsettings_forceReason.js +++ /dev/null @@ -1,40 +0,0 @@ -const ServerSetting = require('../../database/models/ServerSetting'); - -// enables points system -async function enableForceReason(serverID) { - const enabled = await ServerSetting.update({ pointsSystemForceReason: true }, - { where: { serverID } }) - .catch(ERR); - return enabled; -} - -// disables points system -async function disableForceReason(serverID) { - const disabled = await ServerSetting.update({ pointsSystemForceReason: false }, - { where: { serverID } }) - .catch(ERR); - return disabled; -} - -module.exports.run = async (message, args, config, prefix) => { - const [subcmd, enable] = args; - const lowercaseEnable = enable.toLowerCase(); - const serverID = message.guild.id; - // check if value is a bool - if (!(lowercaseEnable === 'true' || lowercaseEnable === 'false')) { - messageFail(message, CommandUsage(config.prefix, module.exports.help.parent, 'forceReason TRUEORFALSE')); - return; - } - // set value - let messageState = 'disabled'; - if (lowercaseEnable === 'true') { - await enableForceReason(serverID); - messageState = 'enabled'; - } else await disableForceReason(serverID); - messageSuccess(message, `Successfully ${messageState} setting.`); -}; - -module.exports.help = { - name: 'CMD_punishsettings_forceReason', - parent: 'punishsettings', -}; diff --git a/functions/archive/CMD_punishsettings_listPunnishment.js b/functions/archive/CMD_punishsettings_listPunnishment.js deleted file mode 100644 index dca529e..0000000 --- a/functions/archive/CMD_punishsettings_listPunnishment.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punishsettings_listPunishment', - parent: 'punishsettings', -}; diff --git a/functions/archive/CMD_punishsettings_listReasons.js b/functions/archive/CMD_punishsettings_listReasons.js deleted file mode 100644 index 5a843ad..0000000 --- a/functions/archive/CMD_punishsettings_listReasons.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punishsettings_listReasons', - parent: 'punishsettings', -}; diff --git a/functions/archive/CMD_punishsettings_listSettings.js b/functions/archive/CMD_punishsettings_listSettings.js deleted file mode 100644 index ab8a7c2..0000000 --- a/functions/archive/CMD_punishsettings_listSettings.js +++ /dev/null @@ -1,42 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -const ServerSetting = require('../../database/models/ServerSetting'); - -// gets server settings -async function getSettings(serverID) { - const found = await ServerSetting.findOne({ where: { serverID } }) - .catch(ERR); - return found; -} - -module.exports.run = async (message, args, config, prefix) => { - const serverID = message.guild.id; - const serverSettings = await getSettings(serverID); - // prepare message - const embed = new MessageEmbed() - .setTitle('Punishment Settings') - .addFields([ - { - name: 'enable', - value: serverSettings.pointsSystemEnabled, - inline: true, - }, - { - name: 'forceReason', - value: serverSettings.pointsSystemForceReason, - inline: true, - }, - { - name: 'pointLifetime', - value: serverSettings.pointLifetime, - inline: true, - }, - ]); - // send it - message.channel.send(embed); -}; - -module.exports.help = { - name: 'CMD_punishsettings_listSettings', - parent: 'punishsettings', -}; diff --git a/functions/archive/CMD_punishsettings_pointLifetime.js b/functions/archive/CMD_punishsettings_pointLifetime.js deleted file mode 100644 index 6cebc31..0000000 --- a/functions/archive/CMD_punishsettings_pointLifetime.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punishsettings_pointLifetime', - parent: 'punishsettings', -}; diff --git a/functions/archive/CMD_punishsettings_removePunnishment.js b/functions/archive/CMD_punishsettings_removePunnishment.js deleted file mode 100644 index 62416df..0000000 --- a/functions/archive/CMD_punishsettings_removePunnishment.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punishsettings_removePunishment', - parent: 'punishsettings', -}; diff --git a/functions/archive/CMD_punishsettings_removeReason.js b/functions/archive/CMD_punishsettings_removeReason.js deleted file mode 100644 index af99885..0000000 --- a/functions/archive/CMD_punishsettings_removeReason.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports.run = async (message, args, config, prefix) => { - -}; - -module.exports.help = { - name: 'CMD_punishsettings_removeReason', - parent: 'punishsettings', -}; diff --git a/functions/archive/FUNC_checkUserPunishment.js b/functions/archive/FUNC_checkUserPunishment.js deleted file mode 100644 index 461ac5e..0000000 --- a/functions/archive/FUNC_checkUserPunishment.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports.run = async () => { - // lookup if threshhold has been passed - // check if passed - // check if ongoing punishment is already in process with same punishmentID - // return result -}; - -module.exports.help = { - name: 'FUNC_checkPermissionsDBPunishment', -}; diff --git a/functions/archive/FUNC_userPunishmentHandler.js b/functions/archive/FUNC_userPunishmentHandler.js deleted file mode 100644 index ba78ca1..0000000 --- a/functions/archive/FUNC_userPunishmentHandler.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports.run = async (fromTicker, comamnd) => { - // if "fromTicker" is true, dont checkuserPunishment and use "command" - // call checkUserPunishment, return: if not exist, then - // create punishment entry - // get punishment command and values - // get server specific values (RoleID, serverID, ...) - // call correct command: Ban, temp-ban, Unban, kick, assignRole, removeRole - // if code for commands is small, use functions. if too big use own file functions -}; - -module.exports.help = { - name: 'FUNC_createUserPunishment', -}; diff --git a/functions/archive/TCKR_punishmentTimer.js b/functions/archive/TCKR_punishmentTimer.js deleted file mode 100644 index b170c4f..0000000 --- a/functions/archive/TCKR_punishmentTimer.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports.run = async () => { - // check all 5 mins: - // remove time from all punishments - // if punishment is beyond 0: Delete entry; call FUNC_userPunishmentHandler with opposite command -}; - -module.exports.help = { - name: 'TCKR_punishmentTimer', -}; diff --git a/functions/globalFuncs.js b/functions/globalFuncs.js deleted file mode 100644 index d04dbda..0000000 --- a/functions/globalFuncs.js +++ /dev/null @@ -1,33 +0,0 @@ -global.messageFail = async (interaction, body, color, ephemeral) => { - const sentMessage = await client.functions.get('richEmbedMessage') - .run(interaction, body, '', color || 'RED', false, ephemeral || true); - return sentMessage; -}; - -global.messageSuccess = async (interaction, body, color, ephemeral) => { - const sentMessage = await client.functions.get('richEmbedMessage') - .run(interaction, body, '', color || 'GREEN', false, ephemeral || false); - return sentMessage; -}; - -// raw reply to commands -global.reply = (interaction, payload, followUp = false) => { - if (followUp) return interaction.followUp(payload); - // check if message needs to be edited or if its a first reply - if (interaction.deferred || interaction.replied) return interaction.editReply(payload); - return interaction.reply(payload); -}; - -global.prettyCheck = (question) => { - if (question) return '✅'; - return '❌'; -}; - -global.date = (date) => { - const newTimestamp = new Date(date).getTime() / 1000; - return ``; -}; - -module.exports.data = { - name: 'globalFunc', -}; diff --git a/functions/richEmbedMessage.js b/functions/richEmbedMessage.js deleted file mode 100644 index ce6509c..0000000 --- a/functions/richEmbedMessage.js +++ /dev/null @@ -1,24 +0,0 @@ -const { MessageEmbed } = require('discord.js'); - -module.exports.run = async (interaction, body, title, color, footer, ephemeral) => { - // needs to be local as settings overlap from dofferent embed-requests - const embed = new MessageEmbed(); - - if (body) embed.setDescription(body); - if (title) embed.setTitle(title); - if (color) embed.setColor(color); - if (footer) embed.setFooter({ text: footer }); - - const options = { - embeds: [embed], - components: [], - ephemeral: String(ephemeral) ? ephemeral : true, - }; - - return reply(interaction, options).catch(ERR); - // return channel.send(embed); -}; - -module.exports.data = { - name: 'richEmbedMessage', -}; diff --git a/index.js b/index.js deleted file mode 100644 index 2b94457..0000000 --- a/index.js +++ /dev/null @@ -1,100 +0,0 @@ -// init Discord -const { Client, Intents, Collection } = require('discord.js'); -// init file system -const fs = require('fs'); -// init command builder -const { SlashCommandBuilder } = require('@discordjs/builders'); -// setting essential global values -// init Discord client -global.client = new Client({ - disableEveryone: true, - intents: [ - Intents.FLAGS.GUILDS, - Intents.FLAGS.GUILD_MEMBERS, - Intents.FLAGS.GUILD_BANS, - Intents.FLAGS.GUILD_EMOJIS_AND_STICKERS, - Intents.FLAGS.GUILD_MESSAGES, - Intents.FLAGS.DIRECT_MESSAGES, - ], -}); -// init config -global.config = require('./config.json'); - -global.DEBUG = process.env.NODE_ENV === 'development'; - -global.CmdBuilder = SlashCommandBuilder; - -global.ERR = (err) => { - console.error('ERROR:', err); - if (DEBUG) return; - const { MessageEmbed } = require('discord.js'); - const stack = err.stack.length > 4000 ? `${err.stack.slice(0, 4000)}...` : err.stack; - const embed = new MessageEmbed() - .setAuthor({ name: `Error: '${err.message}'` }) - .setDescription(`STACKTRACE:\n\`\`\`${stack}\`\`\``) - .setColor('RED'); - // client.channels.fetch(config.logChannel).send({ embeds: [embed] }); - client.channels.cache.get(config.logChannel).send({ embeds: [embed] }); - return; -}; - -// creating collections -client.commands = new Collection(); -client.functions = new Collection(); - -// anouncing debug mode -if (DEBUG) console.log(`[${config.name}] Bot is on Debug-Mode. Some functions are not going to be loaded.`); - -// Login the bot -client.login(process.env.DCtoken) -// TODO: cleanup - .then(() => { - // import Functions and Commands; startup database connection - fs.readdirSync('./functions/STARTUP').forEach((FCN) => { - if (FCN.search('.js') === -1) return; - const INIT = require(`./functions/STARTUP/${FCN}`); - INIT.run(fs); - }); - }); - -client.on('ready', async () => { - // confirm user logged in - console.log(`[${config.name}] Logged in as "${client.user.tag}"!`); - - // setup tables - console.log('[DB] Syncing tables...'); - await sequelize.sync(); - await console.log('[DB] Done syncing!'); - - // run startup functions - config.setup.setupFunctions.forEach((FCN) => { - client.functions.get(FCN).run(config); - }); -}); - -// EVENT user gets banned -client.on('guildBanAdd', (ban) => client.functions.get('EVENT_guildBanAdd').run(ban)); - -// EVENT user gets unbanned -client.on('guildBanRemove', (ban) => client.functions.get('EVENT_guildBanRemove').run(ban)); - -// user joins the server -client.on('guildMemberAdd', (member) => client.functions.get('EVENT_guildMemberAdd').run(member)); - -// bot joins the server -client.on('guildCreate', (guild) => client.functions.get('EVENT_guildCreate').run(guild)); - -// bot leaves the server -client.on('guildDelete', (guild) => client.functions.get('EVENT_guildDelete').run(guild)); - -// TODO: check what information is shared without message intent, so tag recording is still possible -// // record user tag -// client.functions.get('SET_DB_userTagRecord').run(member.id, member.user.tag); - -// itneraction is triggered (command, autocomplete, etc.) -client.on('interactionCreate', (interaction) => client.functions.get('EVENT_interactionCreate').run(interaction)); - -// logging errors and warns -client.on('error', (ERR)); -client.on('warn', (ERR)); -process.on('uncaughtException', (ERR)); diff --git a/package-lock.json b/package-lock.json index 9b9a228..eb50f88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,64 +1,177 @@ { "name": "agent-black", - "version": "3.0.0", + "version": "4.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "agent-black", - "version": "3.0.0", + "version": "4.0.0", "license": "MIT", "dependencies": { - "@discordjs/builders": "^0.12.0", - "axios": "^0.26.1", - "bufferutil": "^4.0.5", - "discord.js": "^13.6.0", - "html-to-image": "^1.6.2", - "mysql2": "^2.3.2", - "pretty-ms": "^5.1.0", - "sequelize": "^6.9.0", - "utf-8-validate": "^5.0.7" + "axios": "1.6.2", + "bufferutil": "4.0.8", + "discord.js": "14.14.1", + "mysql2": "3.6.5", + "pino": "8.17.1", + "sequelize": "6.35.2", + "typescript": "5.3.3", + "utf-8-validate": "6.0.3" }, "devDependencies": { - "eslint": "8.23.0", - "eslint-config-airbnb-base": "15.0.0", - "eslint-plugin-import": "2.26.0" + "@types/node": "20.10.4", + "@typescript-eslint/eslint-plugin": "6.14.0", + "@typescript-eslint/parser": "6.14.0", + "eslint": "8.56.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-import": "2.29.1", + "eslint-plugin-prettier": "5.0.1", + "husky": "8.0.3", + "lint-staged": "15.2.0", + "prettier": "3.1.1" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/@discordjs/builders": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.12.0.tgz", - "integrity": "sha512-Vx2MjUZd6QVo1uS2uWt708Fd6cHWGFblAvbpL5EBO+kLl0BADmPwwvts+YJ/VfSywed6Vsk6K2cEooR/Ytjhjw==", - "dependencies": { - "@sindresorhus/is": "^4.3.0", - "discord-api-types": "^0.26.1", - "ts-mixer": "^6.0.0", - "tslib": "^2.3.1", - "zod": "^3.11.6" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz", + "integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==", + "dependencies": { + "@discordjs/formatters": "^0.3.3", + "@discordjs/util": "^1.0.2", + "@sapphire/shapeshift": "^3.9.3", + "discord-api-types": "0.37.61", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.3", + "tslib": "^2.6.2" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/@discordjs/collection": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.4.0.tgz", - "integrity": "sha512-zmjq+l/rV35kE6zRrwe8BHqV78JvIh2ybJeZavBi5NySjWXqN3hmmAKg7kYMMXSeiWtSsMoZ/+MQi0DiQWy2lw==", + "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.0.0", - "npm": ">=7.0.0" + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/formatters": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz", + "integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==", + "dependencies": { + "discord-api-types": "0.37.61" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/rest": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz", + "integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==", + "dependencies": { + "@discordjs/collection": "^2.0.0", + "@discordjs/util": "^1.0.2", + "@sapphire/async-queue": "^1.5.0", + "@sapphire/snowflake": "^3.5.1", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.61", + "magic-bytes.js": "^1.5.0", + "tslib": "^2.6.2", + "undici": "5.27.2" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/rest/node_modules/@discordjs/collection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz", + "integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@discordjs/util": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz", + "integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==", + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/ws": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz", + "integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==", + "dependencies": { + "@discordjs/collection": "^2.0.0", + "@discordjs/rest": "^2.1.0", + "@discordjs/util": "^1.0.2", + "@sapphire/async-queue": "^1.5.0", + "@types/ws": "^8.5.9", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.61", + "tslib": "^2.6.2", + "ws": "^8.14.2" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/ws/node_modules/@discordjs/collection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz", + "integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -72,30 +185,37 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", + "engines": { + "node": ">=14" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", - "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -110,9 +230,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@nodelib/fs.scandir": { @@ -150,58 +270,328 @@ "node": ">= 8" } }, + "node_modules/@pkgr/utils": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", + "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "fast-glob": "^3.3.0", + "is-glob": "^4.0.3", + "open": "^9.1.0", + "picocolors": "^1.0.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@sapphire/async-queue": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.9.tgz", - "integrity": "sha512-CbXaGwwlEMq+l1TRu01FJCvySJ1CEFKFclHT48nIfNeZXaAAmmwwy7scUKmYHPUa3GhoMp6Qr1B3eAJux6XgOQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", + "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" } }, - "node_modules/@sindresorhus/is": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz", - "integrity": "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==", - "engines": { - "node": ">=10" + "node_modules/@sapphire/shapeshift": { + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.3.tgz", + "integrity": "sha512-WzKJSwDYloSkHoBbE8rkRW8UNKJiSRJ/P8NqJ5iVq7U2Yr/kriIBx2hW+wj2Z5e5EnXL1hgYomgaFsdK6b+zqQ==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "lodash": "^4.17.21" }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/snowflake": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz", + "integrity": "sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, - "node_modules/@types/node": { - "version": "16.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", - "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, - "node_modules/@types/node-fetch": { - "version": "2.5.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz", - "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==", + "node_modules/@types/node": { + "version": "20.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", + "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", "dependencies": { - "@types/node": "*", - "form-data": "^3.0.0" + "undici-types": "~5.26.4" } }, + "node_modules/@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "node_modules/@types/validator": { + "version": "13.7.17", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.17.tgz", + "integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==" + }, "node_modules/@types/ws": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.2.tgz", - "integrity": "sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dependencies": { "@types/node": "*" } }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.14.0.tgz", + "integrity": "sha512-1ZJBykBCXaSHG94vMMKmiHoL0MhNHKSVlcHVYZNw+BKxufhqQVTOawNpwwI1P5nIFZ/4jLVop0mcY6mJJDFNaw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.14.0", + "@typescript-eslint/type-utils": "6.14.0", + "@typescript-eslint/utils": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.14.0.tgz", + "integrity": "sha512-QjToC14CKacd4Pa7JK4GeB/vHmWFJckec49FR4hmIRf97+KXole0T97xxu9IFiPxVQ1DBWrQ5wreLwAGwWAVQA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.14.0", + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/typescript-estree": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.14.0.tgz", + "integrity": "sha512-VT7CFWHbZipPncAZtuALr9y3EuzY1b1t1AEkIq2bTXUPKw+pHoXflGNG5L+Gv6nKul1cz1VH8fz16IThIU0tdg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.14.0.tgz", + "integrity": "sha512-x6OC9Q7HfYKqjnuNu5a7kffIYs3No30isapRBJl1iCHLitD8O0lFbRcVGiOcuyN837fqXzPZ1NS10maQzZMKqw==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.14.0", + "@typescript-eslint/utils": "6.14.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.14.0.tgz", + "integrity": "sha512-uty9H2K4Xs8E47z3SnXEPRNDfsis8JO27amp2GNCnzGETEW3yTqEIVg5+AI7U276oGF/tw6ZA+UesxeQ104ceA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.14.0.tgz", + "integrity": "sha512-yPkaLwK0yH2mZKFE/bXkPAkkFgOv15GJAUzgUVonAbv0Hr4PK/N2yaA/4XQbTZQdygiDkpt5DkxPELqHguNvyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.14.0.tgz", + "integrity": "sha512-XwRTnbvRr7Ey9a1NT6jqdKX8y/atWG+8fAIu3z73HSP8h06i3r/ClMhmaF/RGWGW1tHJEwij1uEg2GbEmPYvYg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.14.0", + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/typescript-estree": "6.14.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.14.0.tgz", + "integrity": "sha512-fB5cw6GRhJUz03MrROVuj5Zm/Q+XWlVdIsFj+Zb1Hvqouc8t+XP2H5y53QYU/MGtd2dPg6/vJJlhoX3xc2ehfw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.14.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vladfrangu/async_event_emitter": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz", + "integrity": "sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -235,6 +625,33 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "dev": true, + "dependencies": { + "type-fest": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -259,27 +676,35 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "is-string": "^1.0.7" }, "engines": { @@ -298,15 +723,74 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -318,14 +802,36 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "dependencies": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/balanced-match": { @@ -334,6 +840,46 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.44" + }, + "engines": { + "node": ">= 5.10.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -356,10 +902,33 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/bufferutil": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", - "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", "hasInstallScript": true, "dependencies": { "node-gyp-build": "^4.3.0" @@ -368,14 +937,30 @@ "node": ">=6.14.2" } }, + "node_modules/bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "dependencies": { + "run-applescript": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -406,6 +991,37 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -424,6 +1040,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -435,18 +1057,21 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "node_modules/confusing-browser-globals": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", - "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", - "dev": true - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -462,9 +1087,9 @@ } }, "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, @@ -483,101 +1108,195 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "node_modules/default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", "dev": true, "dependencies": { - "object-keys": "^1.0.12" + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "node_modules/default-browser-id": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", + "dev": true, + "dependencies": { + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" + }, "engines": { - "node": ">=0.4.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/denque": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", - "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==", + "node_modules/default-browser/node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, "engines": { - "node": ">=0.10" + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/default-browser/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/default-browser/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dev": true, "dependencies": { - "path-type": "^4.0.0" + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/discord-api-types": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.26.1.tgz", - "integrity": "sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ==", + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/discord.js": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.6.0.tgz", - "integrity": "sha512-tXNR8zgsEPxPBvGk3AQjJ9ljIIC6/LOPjzKwpwz8Y1Q2X66Vi3ZqFgRHYwnHKC0jC0F+l4LzxlhmOJsBZDNg9g==", - "dependencies": { - "@discordjs/builders": "^0.11.0", - "@discordjs/collection": "^0.4.0", - "@sapphire/async-queue": "^1.1.9", - "@types/node-fetch": "^2.5.12", - "@types/ws": "^8.2.2", - "discord-api-types": "^0.26.0", - "form-data": "^4.0.0", - "node-fetch": "^2.6.1", - "ws": "^8.4.0" + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=16.6.0", - "npm": ">=7.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/discord.js/node_modules/@discordjs/builders": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.11.0.tgz", - "integrity": "sha512-ZTB8yJdJKrKlq44dpWkNUrAtEJEq0gqpb7ASdv4vmq6/mZal5kOv312hQ56I/vxwMre+VIkoHquNUAfnTbiYtg==", - "dependencies": { - "@sindresorhus/is": "^4.2.0", - "discord-api-types": "^0.26.0", - "ts-mixer": "^6.0.0", - "tslib": "^2.3.1", - "zod": "^3.11.6" - }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=0.4.0" } }, - "node_modules/discord.js/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==", + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "path-type": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">=8" + } + }, + "node_modules/discord-api-types": { + "version": "0.37.61", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz", + "integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==" + }, + "node_modules/discord.js": { + "version": "14.14.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz", + "integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==", + "dependencies": { + "@discordjs/builders": "^1.7.0", + "@discordjs/collection": "1.5.3", + "@discordjs/formatters": "^0.3.3", + "@discordjs/rest": "^2.1.0", + "@discordjs/util": "^1.0.2", + "@discordjs/ws": "^1.0.2", + "@sapphire/snowflake": "3.5.1", + "@types/ws": "8.5.9", + "discord-api-types": "0.37.61", + "fast-deep-equal": "3.1.3", + "lodash.snakecase": "4.1.1", + "tslib": "2.6.2", + "undici": "5.27.2", + "ws": "8.14.2" + }, + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/discord.js/node_modules/@types/ws": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", + "integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==", + "dependencies": { + "@types/node": "*" } }, "node_modules/doctrine": { @@ -593,36 +1312,61 @@ } }, "node_modules/dottie": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", - "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz", + "integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==" + }, + "node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true }, "node_modules/es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -631,6 +1375,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -661,49 +1428,48 @@ } }, "node_modules/eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.1", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", - "ajv": "^6.10.0", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", - "grapheme-splitter": "^1.0.4", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -716,42 +1482,27 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "bin": { + "eslint-config-prettier": "bin/cli.js" }, "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-config-airbnb-base/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "eslint": ">=7.0.0" } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -764,16 +1515,20 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "engines": { "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/eslint-module-utils/node_modules/debug": { @@ -786,24 +1541,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -813,12 +1572,12 @@ } }, "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { @@ -833,59 +1592,70 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/eslint-plugin-prettier": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", + "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.5" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://opencollective.com/prettier" }, "peerDependencies": { - "eslint": ">=5" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } } }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/find-up": { @@ -959,14 +1729,14 @@ } }, "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -975,19 +1745,10 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -1026,16 +1787,66 @@ "node": ">=0.10.0" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -1069,13 +1880,21 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-redact": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz", + "integrity": "sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -1105,18 +1924,6 @@ "node": ">=8" } }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -1137,9 +1944,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "funding": [ { "type": "individual", @@ -1155,10 +1962,19 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "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==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -1175,16 +1991,40 @@ "dev": true }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/generate-function": { "version": "2.3.1", @@ -1194,20 +2034,45 @@ "is-property": "^1.0.2" } }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -1257,9 +2122,9 @@ } }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1271,6 +2136,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -1291,10 +2171,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/has": { @@ -1310,9 +2202,9 @@ } }, "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1327,10 +2219,34 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, "engines": { "node": ">= 0.4" @@ -1354,10 +2270,41 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/html-to-image": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.9.0.tgz", - "integrity": "sha512-9gaDCIYg62Ek07F2pBk76AHgYZ2gxq2YALU7rK3gNCqXuhu6cWzsOQqM7qGbjZiOzxGzrU1deDqZpAod2NEwbA==" + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } }, "node_modules/iconv-lite": { "version": "0.6.3", @@ -1370,10 +2317,29 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" @@ -1405,9 +2371,9 @@ } }, "node_modules/inflection": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.1.tgz", - "integrity": "sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", + "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==", "engines": [ "node >= 0.4.0" ] @@ -1429,12 +2395,12 @@ "dev": true }, "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.2.0", "has": "^1.0.3", "side-channel": "^1.0.4" }, @@ -1442,6 +2408,20 @@ "node": ">= 0.4" } }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -1471,9 +2451,9 @@ } }, "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { "node": ">= 0.4" @@ -1483,12 +2463,12 @@ } }, "node_modules/is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1509,6 +2489,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1518,6 +2513,18 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -1530,10 +2537,28 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, "engines": { "node": ">= 0.4" @@ -1552,9 +2577,9 @@ } }, "node_modules/is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" @@ -1566,6 +2591,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", @@ -1588,14 +2622,29 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -1626,18 +2675,66 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0" + "call-bind": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-wsl/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1669,9 +2766,9 @@ "dev": true }, "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -1693,17 +2790,69 @@ "node": ">= 0.8.0" } }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/lint-staged": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.0.tgz", + "integrity": "sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==", "dev": true, "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "chalk": "5.3.0", + "commander": "11.1.0", + "debug": "4.3.4", + "execa": "8.0.1", + "lilconfig": "3.0.0", + "listr2": "8.0.0", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.4" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": ">=4" + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/listr2": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", + "integrity": "sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.3.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/lodash": { @@ -1717,10 +2866,104 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" + }, + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/lru-cache": { "version": "6.0.0", @@ -1733,6 +2976,17 @@ "node": ">=10" } }, + "node_modules/magic-bytes.js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.5.0.tgz", + "integrity": "sha512-wJkXvutRbNWcc37tt5j1HyOK1nosspdh3dj6LUYYAvF6JYNqs53IfRvK9oEpcwiDA1NdoIi64yAMfdivPeVAyw==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -1756,24 +3010,36 @@ } }, "node_modules/mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "mime-db": "1.50.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1787,10 +3053,13 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/moment": { "version": "2.29.4", @@ -1801,11 +3070,11 @@ } }, "node_modules/moment-timezone": { - "version": "0.5.37", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", - "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", + "version": "0.5.43", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz", + "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==", "dependencies": { - "moment": ">= 2.9.0" + "moment": "^2.29.4" }, "engines": { "node": "*" @@ -1817,16 +3086,16 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mysql2": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.2.tgz", - "integrity": "sha512-JUSA50rt/nSew8aq8xe3pRk5Q4y/M5QdSJn7Ey3ndOlPp2KXuialQ0sS35DNhPT5Z5PnOiIwSSQvKkl1WorqRA==", + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.5.tgz", + "integrity": "sha512-pS/KqIb0xlXmtmqEuTvBXTmLoQ5LmAz5NW/r8UyQ1ldvnprNEj3P9GbmuQQ2J0A4LO+ynotGi6TbscPa8OUb+w==", "dependencies": { - "denque": "^2.0.1", + "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.6.3", - "long": "^4.0.0", - "lru-cache": "^6.0.0", - "named-placeholders": "^1.1.2", + "long": "^5.2.1", + "lru-cache": "^8.0.0", + "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" }, @@ -1834,56 +3103,39 @@ "node": ">= 8.0" } }, + "node_modules/mysql2/node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "engines": { + "node": ">=16.14" + } + }, "node_modules/named-placeholders": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", - "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", "dependencies": { - "lru-cache": "^4.1.3" + "lru-cache": "^7.14.1" }, "engines": { - "node": ">=6.0.0" + "node": ">=12.0.0" } }, "node_modules/named-placeholders/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" } }, - "node_modules/named-placeholders/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-gyp-build": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", @@ -1894,10 +3146,37 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1913,14 +3192,14 @@ } }, "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -1930,29 +3209,44 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" } }, "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" @@ -1961,6 +3255,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1970,54 +3272,54 @@ "wrappy": "1" } }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "node_modules/open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", "dev": true, "dependencies": { - "p-try": "^1.0.0" + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" }, "engines": { - "node": ">=4" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { - "p-limit": "^1.1.0" + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, - "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, "node_modules/parent-module": { @@ -2032,23 +3334,6 @@ "node": ">=6" } }, - "node_modules/parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -2082,6 +3367,17 @@ "node": ">=8" } }, + "node_modules/pg-connection-string": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2094,6 +3390,53 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pino": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.17.1.tgz", + "integrity": "sha512-YoN7/NJgnsJ+fkADZqjhRt96iepWBndQHeClmSBH0sQWCb8zGD74t00SK4eOtKFi/f8TUmQnfmgglEhd2kI1RQ==", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.1.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.7.0", + "thread-stream": "^2.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz", + "integrity": "sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2103,29 +3446,55 @@ "node": ">= 0.8.0" } }, - "node_modules/pretty-ms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-5.1.0.tgz", - "integrity": "sha512-4gaK1skD2gwscCfkswYQRmddUb2GJZtzDGRjHWadVHtK/DIKFufa12MvES6/xu1tVbUYeia5bmLcwJtZJQUqnw==", - "dependencies": { - "parse-ms": "^2.1.0" + "node_modules/prettier": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", + "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=8" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-warning": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.1.tgz", + "integrity": "sha512-JjBvFEn7MwFbzUDa2SRtKJSsyO0LlER4V/FmwLMhBlXNbGgGxdyFCxIdMDLerWUycsVUyaoM9QFLvppFy4IWaQ==" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -2151,25 +3520,58 @@ } ] }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, + "node_modules/readable-stream": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -2189,14 +3591,57 @@ "node": ">=4" } }, - "node_modules/retry-as-promised": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", - "integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==", + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "dependencies": { - "any-promise": "^1.3.0" + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/retry-as-promised": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz", + "integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==" + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -2207,6 +3652,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2222,6 +3673,128 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/run-applescript/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/run-applescript/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/run-applescript/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-applescript/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/run-applescript/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -2245,15 +3818,74 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2270,40 +3902,58 @@ "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" }, "node_modules/sequelize": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.9.0.tgz", - "integrity": "sha512-tFROh9T9GgyY6aTV2+aGdfVNvrppuTOo1EFln9AtV8wXJTOOr7Nan7pZum5oLy87CGWl0YeHzAwg99tz04OqNA==", + "version": "6.35.2", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.35.2.tgz", + "integrity": "sha512-EdzLaw2kK4/aOnWQ7ed/qh3B6/g+1DvmeXr66RwbcqSm/+QRS9X0LDI5INBibsy4eNJHWIRPo3+QK0zL+IPBHg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/sequelize" + } + ], "dependencies": { - "debug": "^4.1.1", - "dottie": "^2.0.0", - "inflection": "1.13.1", - "lodash": "^4.17.20", - "moment": "^2.26.0", - "moment-timezone": "^0.5.31", - "retry-as-promised": "^3.2.0", - "semver": "^7.3.2", - "sequelize-pool": "^6.0.0", + "@types/debug": "^4.1.8", + "@types/validator": "^13.7.17", + "debug": "^4.3.4", + "dottie": "^2.0.6", + "inflection": "^1.13.4", + "lodash": "^4.17.21", + "moment": "^2.29.4", + "moment-timezone": "^0.5.43", + "pg-connection-string": "^2.6.1", + "retry-as-promised": "^7.0.4", + "semver": "^7.5.4", + "sequelize-pool": "^7.1.0", "toposort-class": "^1.0.1", - "uuid": "^8.1.0", - "validator": "^13.6.0", + "uuid": "^8.3.2", + "validator": "^13.9.0", "wkx": "^0.5.0" }, "engines": { "node": ">=10.0.0" }, "peerDependenciesMeta": { + "ibm_db": { + "optional": true + }, "mariadb": { "optional": true }, "mysql2": { "optional": true }, + "oracledb": { + "optional": true + }, "pg": { "optional": true }, "pg-hstore": { "optional": true }, + "snowflake-sdk": { + "optional": true + }, "sqlite3": { "optional": true }, @@ -2313,13 +3963,42 @@ } }, "node_modules/sequelize-pool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-6.1.0.tgz", - "integrity": "sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", + "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==", "engines": { "node": ">= 10.0.0" } }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -2355,6 +4034,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -2364,6 +4055,50 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/sonic-boom": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz", + "integrity": "sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/sqlstring": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz", @@ -2372,27 +4107,107 @@ "node": ">= 0.6" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2413,12 +4228,24 @@ "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, "engines": { "node": ">=4" } }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2455,12 +4282,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/synckit": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.6.tgz", + "integrity": "sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA==", + "dev": true, + "dependencies": { + "@pkgr/utils": "^2.4.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "node_modules/thread-stream": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.1.tgz", + "integrity": "sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2478,32 +4341,39 @@ "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } }, "node_modules/ts-mixer": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.0.tgz", - "integrity": "sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", + "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/type-check": { "version": "0.4.0", @@ -2529,21 +4399,123 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici": { + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz", + "integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -2554,9 +4526,9 @@ } }, "node_modules/utf-8-validate": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", - "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-6.0.3.tgz", + "integrity": "sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==", "hasInstallScript": true, "dependencies": { "node-gyp-build": "^4.3.0" @@ -2574,27 +4546,13 @@ } }, "node_modules/validator": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", - "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", "engines": { "node": ">= 0.10" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2623,24 +4581,90 @@ "is-symbol": "^1.0.3" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wkx": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", - "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", - "dependencies": { - "@types/node": "*" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wkx": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", + "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/wrappy": { @@ -2650,15 +4674,15 @@ "dev": true }, "node_modules/ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -2674,6 +4698,15 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -2685,44 +4718,118 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zod": { - "version": "3.11.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.11.6.tgz", - "integrity": "sha512-daZ80A81I3/9lIydI44motWe6n59kRBfNzTuS2bfzVh1nAXi667TOTWWtatxyG+fwgNUiagSj/CWZwRRbevJIg==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@discordjs/builders": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.12.0.tgz", - "integrity": "sha512-Vx2MjUZd6QVo1uS2uWt708Fd6cHWGFblAvbpL5EBO+kLl0BADmPwwvts+YJ/VfSywed6Vsk6K2cEooR/Ytjhjw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz", + "integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==", "requires": { - "@sindresorhus/is": "^4.3.0", - "discord-api-types": "^0.26.1", - "ts-mixer": "^6.0.0", - "tslib": "^2.3.1", - "zod": "^3.11.6" + "@discordjs/formatters": "^0.3.3", + "@discordjs/util": "^1.0.2", + "@sapphire/shapeshift": "^3.9.3", + "discord-api-types": "0.37.61", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.3", + "tslib": "^2.6.2" } }, "@discordjs/collection": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.4.0.tgz", - "integrity": "sha512-zmjq+l/rV35kE6zRrwe8BHqV78JvIh2ybJeZavBi5NySjWXqN3hmmAKg7kYMMXSeiWtSsMoZ/+MQi0DiQWy2lw==" + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==" + }, + "@discordjs/formatters": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz", + "integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==", + "requires": { + "discord-api-types": "0.37.61" + } + }, + "@discordjs/rest": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz", + "integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==", + "requires": { + "@discordjs/collection": "^2.0.0", + "@discordjs/util": "^1.0.2", + "@sapphire/async-queue": "^1.5.0", + "@sapphire/snowflake": "^3.5.1", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.61", + "magic-bytes.js": "^1.5.0", + "tslib": "^2.6.2", + "undici": "5.27.2" + }, + "dependencies": { + "@discordjs/collection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz", + "integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==" + } + } + }, + "@discordjs/util": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz", + "integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==" + }, + "@discordjs/ws": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz", + "integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==", + "requires": { + "@discordjs/collection": "^2.0.0", + "@discordjs/rest": "^2.1.0", + "@discordjs/util": "^1.0.2", + "@sapphire/async-queue": "^1.5.0", + "@types/ws": "^8.5.9", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.61", + "tslib": "^2.6.2", + "ws": "^8.14.2" + }, + "dependencies": { + "@discordjs/collection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz", + "integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==" + } + } + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true }, "@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -2730,23 +4837,28 @@ "strip-json-comments": "^3.1.1" } }, + "@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "dev": true + }, + "@fastify/busboy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==" + }, "@humanwhocodes/config-array": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", - "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" } }, - "@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true - }, "@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -2754,9 +4866,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "@nodelib/fs.scandir": { @@ -2785,48 +4897,214 @@ "fastq": "^1.6.0" } }, + "@pkgr/utils": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", + "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "fast-glob": "^3.3.0", + "is-glob": "^4.0.3", + "open": "^9.1.0", + "picocolors": "^1.0.0", + "tslib": "^2.6.0" + } + }, "@sapphire/async-queue": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.9.tgz", - "integrity": "sha512-CbXaGwwlEMq+l1TRu01FJCvySJ1CEFKFclHT48nIfNeZXaAAmmwwy7scUKmYHPUa3GhoMp6Qr1B3eAJux6XgOQ==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", + "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==" + }, + "@sapphire/shapeshift": { + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.3.tgz", + "integrity": "sha512-WzKJSwDYloSkHoBbE8rkRW8UNKJiSRJ/P8NqJ5iVq7U2Yr/kriIBx2hW+wj2Z5e5EnXL1hgYomgaFsdK6b+zqQ==", + "requires": { + "fast-deep-equal": "^3.1.3", + "lodash": "^4.17.21" + } }, - "@sindresorhus/is": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz", - "integrity": "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==" + "@sapphire/snowflake": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz", + "integrity": "sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==" + }, + "@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "requires": { + "@types/ms": "*" + } + }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, - "@types/node": { - "version": "16.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", - "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" + "@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, - "@types/node-fetch": { - "version": "2.5.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz", - "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==", + "@types/node": { + "version": "20.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", + "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", "requires": { - "@types/node": "*", - "form-data": "^3.0.0" + "undici-types": "~5.26.4" } }, + "@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "@types/validator": { + "version": "13.7.17", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.17.tgz", + "integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==" + }, "@types/ws": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.2.tgz", - "integrity": "sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "requires": { "@types/node": "*" } }, + "@typescript-eslint/eslint-plugin": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.14.0.tgz", + "integrity": "sha512-1ZJBykBCXaSHG94vMMKmiHoL0MhNHKSVlcHVYZNw+BKxufhqQVTOawNpwwI1P5nIFZ/4jLVop0mcY6mJJDFNaw==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.14.0", + "@typescript-eslint/type-utils": "6.14.0", + "@typescript-eslint/utils": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/parser": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.14.0.tgz", + "integrity": "sha512-QjToC14CKacd4Pa7JK4GeB/vHmWFJckec49FR4hmIRf97+KXole0T97xxu9IFiPxVQ1DBWrQ5wreLwAGwWAVQA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "6.14.0", + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/typescript-estree": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.14.0.tgz", + "integrity": "sha512-VT7CFWHbZipPncAZtuALr9y3EuzY1b1t1AEkIq2bTXUPKw+pHoXflGNG5L+Gv6nKul1cz1VH8fz16IThIU0tdg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.14.0.tgz", + "integrity": "sha512-x6OC9Q7HfYKqjnuNu5a7kffIYs3No30isapRBJl1iCHLitD8O0lFbRcVGiOcuyN837fqXzPZ1NS10maQzZMKqw==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "6.14.0", + "@typescript-eslint/utils": "6.14.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/types": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.14.0.tgz", + "integrity": "sha512-uty9H2K4Xs8E47z3SnXEPRNDfsis8JO27amp2GNCnzGETEW3yTqEIVg5+AI7U276oGF/tw6ZA+UesxeQ104ceA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.14.0.tgz", + "integrity": "sha512-yPkaLwK0yH2mZKFE/bXkPAkkFgOv15GJAUzgUVonAbv0Hr4PK/N2yaA/4XQbTZQdygiDkpt5DkxPELqHguNvyw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/utils": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.14.0.tgz", + "integrity": "sha512-XwRTnbvRr7Ey9a1NT6jqdKX8y/atWG+8fAIu3z73HSP8h06i3r/ClMhmaF/RGWGW1tHJEwij1uEg2GbEmPYvYg==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.14.0", + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/typescript-estree": "6.14.0", + "semver": "^7.5.4" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.14.0.tgz", + "integrity": "sha512-fB5cw6GRhJUz03MrROVuj5Zm/Q+XWlVdIsFj+Zb1Hvqouc8t+XP2H5y53QYU/MGtd2dPg6/vJJlhoX3xc2ehfw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.14.0", + "eslint-visitor-keys": "^3.4.1" + } + }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "@vladfrangu/async_event_emitter": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz", + "integrity": "sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==" + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true }, "acorn-jsx": { @@ -2848,6 +5126,23 @@ "uri-js": "^4.2.2" } }, + "ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "dev": true, + "requires": { + "type-fest": "^3.0.0" + }, + "dependencies": { + "type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true + } + } + }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2863,27 +5158,32 @@ "color-convert": "^2.0.1" } }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + } + }, "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "is-string": "^1.0.7" } }, @@ -2893,28 +5193,82 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", "dev": true, "requires": { + "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" } }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true }, "axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "requires": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "balanced-match": { @@ -2923,6 +5277,26 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "dev": true + }, + "bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "requires": { + "big-integer": "^1.6.44" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2942,22 +5316,41 @@ "fill-range": "^7.0.1" } }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "bufferutil": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", - "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", "requires": { "node-gyp-build": "^4.3.0" } }, + "bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "requires": { + "run-applescript": "^5.0.0" + } + }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" } }, "callsites": { @@ -2976,6 +5369,25 @@ "supports-color": "^7.1.0" } }, + "cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "requires": { + "restore-cursor": "^4.0.0" + } + }, + "cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "requires": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2991,6 +5403,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2999,18 +5417,18 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "confusing-browser-globals": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", - "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", - "dev": true - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3023,9 +5441,9 @@ } }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } @@ -3036,24 +5454,101 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "requires": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "dependencies": { + "execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + } + } + }, + "default-browser-id": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", + "dev": true, + "requires": { + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" + } + }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true + }, "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "dev": true, "requires": { - "object-keys": "^1.0.12" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" } }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "denque": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", - "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" }, "dir-glob": { "version": "3.0.1", @@ -3065,46 +5560,37 @@ } }, "discord-api-types": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.26.1.tgz", - "integrity": "sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ==" + "version": "0.37.61", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz", + "integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==" }, "discord.js": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.6.0.tgz", - "integrity": "sha512-tXNR8zgsEPxPBvGk3AQjJ9ljIIC6/LOPjzKwpwz8Y1Q2X66Vi3ZqFgRHYwnHKC0jC0F+l4LzxlhmOJsBZDNg9g==", - "requires": { - "@discordjs/builders": "^0.11.0", - "@discordjs/collection": "^0.4.0", - "@sapphire/async-queue": "^1.1.9", - "@types/node-fetch": "^2.5.12", - "@types/ws": "^8.2.2", - "discord-api-types": "^0.26.0", - "form-data": "^4.0.0", - "node-fetch": "^2.6.1", - "ws": "^8.4.0" - }, - "dependencies": { - "@discordjs/builders": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.11.0.tgz", - "integrity": "sha512-ZTB8yJdJKrKlq44dpWkNUrAtEJEq0gqpb7ASdv4vmq6/mZal5kOv312hQ56I/vxwMre+VIkoHquNUAfnTbiYtg==", - "requires": { - "@sindresorhus/is": "^4.2.0", - "discord-api-types": "^0.26.0", - "ts-mixer": "^6.0.0", - "tslib": "^2.3.1", - "zod": "^3.11.6" - } - }, - "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": "14.14.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz", + "integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==", + "requires": { + "@discordjs/builders": "^1.7.0", + "@discordjs/collection": "1.5.3", + "@discordjs/formatters": "^0.3.3", + "@discordjs/rest": "^2.1.0", + "@discordjs/util": "^1.0.2", + "@discordjs/ws": "^1.0.2", + "@sapphire/snowflake": "3.5.1", + "@types/ws": "8.5.9", + "discord-api-types": "0.37.61", + "fast-deep-equal": "3.1.3", + "lodash.snakecase": "4.1.1", + "tslib": "2.6.2", + "undici": "5.27.2", + "ws": "8.14.2" + }, + "dependencies": { + "@types/ws": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", + "integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==", "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "@types/node": "*" } } } @@ -3119,36 +5605,81 @@ } }, "dottie": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", - "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz", + "integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==" + }, + "emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true }, "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, "requires": { - "call-bind": "^1.0.2", + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" + } + }, + "es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + } + }, + "es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "requires": { + "hasown": "^2.0.0" } }, "es-to-primitive": { @@ -3169,58 +5700,51 @@ "dev": true }, "eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.1", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", - "ajv": "^6.10.0", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", - "grapheme-splitter": "^1.0.4", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3266,34 +5790,22 @@ } } }, - "eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } + "requires": {} }, "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "requires": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" }, "dependencies": { "debug": { @@ -3308,13 +5820,12 @@ } }, "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "dependencies": { "debug": { @@ -3329,33 +5840,37 @@ } }, "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "doctrine": { @@ -3367,62 +5882,55 @@ "esutils": "^2.0.2" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "eslint-plugin-prettier": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", + "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", "dev": true, "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.5" } }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { - "eslint-visitor-keys": "^2.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - } + "eslint-visitor-keys": "^3.4.1" } }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -3449,16 +5957,54 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -3488,13 +6034,18 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "fast-redact": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz", + "integrity": "sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==" + }, "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -3518,15 +6069,6 @@ "to-regex-range": "^5.0.1" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -3544,14 +6086,23 @@ "dev": true }, "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } }, "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -3565,15 +6116,27 @@ "dev": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true }, "generate-function": { @@ -3584,17 +6147,30 @@ "is-property": "^1.0.2" } }, + "get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true + }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -3629,14 +6205,23 @@ } }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" } }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -3651,10 +6236,19 @@ "slash": "^3.0.0" } }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "has": { @@ -3667,9 +6261,9 @@ } }, "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true }, "has-flag": { @@ -3678,10 +6272,25 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true }, "has-tostringtag": { @@ -3693,10 +6302,26 @@ "has-symbols": "^1.0.2" } }, - "html-to-image": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.9.0.tgz", - "integrity": "sha512-9gaDCIYg62Ek07F2pBk76AHgYZ2gxq2YALU7rK3gNCqXuhu6cWzsOQqM7qGbjZiOzxGzrU1deDqZpAod2NEwbA==" + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, + "human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true + }, + "husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true }, "iconv-lite": { "version": "0.6.3", @@ -3706,10 +6331,15 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "import-fresh": { @@ -3729,9 +6359,9 @@ "dev": true }, "inflection": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.1.tgz", - "integrity": "sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA==" + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", + "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==" }, "inflight": { "version": "1.0.6", @@ -3750,16 +6380,27 @@ "dev": true }, "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "requires": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.2.0", "has": "^1.0.3", "side-channel": "^1.0.4" } }, + "is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + } + }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -3780,18 +6421,18 @@ } }, "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true }, "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "requires": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "is-date-object": { @@ -3803,12 +6444,24 @@ "has-tostringtag": "^1.0.0" } }, + "is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, + "is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -3818,10 +6471,19 @@ "is-extglob": "^2.1.1" } }, + "is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "requires": { + "is-docker": "^3.0.0" + } + }, "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true }, "is-number": { @@ -3831,14 +6493,20 @@ "dev": true }, "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "requires": { "has-tostringtag": "^1.0.0" } }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", @@ -3855,9 +6523,18 @@ } }, "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true }, "is-string": { @@ -3878,15 +6555,47 @@ "has-symbols": "^1.0.2" } }, + "is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.11" + } + }, "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "requires": { - "call-bind": "^1.0.0" + "is-docker": "^2.0.0" + }, + "dependencies": { + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + } } }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3915,9 +6624,9 @@ "dev": true }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -3933,14 +6642,50 @@ "type-check": "~0.4.0" } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "dev": true + }, + "lint-staged": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.0.tgz", + "integrity": "sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==", + "dev": true, + "requires": { + "chalk": "5.3.0", + "commander": "11.1.0", + "debug": "4.3.4", + "execa": "8.0.1", + "lilconfig": "3.0.0", + "listr2": "8.0.0", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.4" + }, + "dependencies": { + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true + } + } + }, + "listr2": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", + "integrity": "sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.3.0", + "wrap-ansi": "^9.0.0" } }, "lodash": { @@ -3954,10 +6699,70 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" + }, + "log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "requires": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "requires": { + "get-east-asian-width": "^1.0.0" + } + }, + "slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "requires": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "lru-cache": { "version": "6.0.0", @@ -3967,6 +6772,17 @@ "yallist": "^4.0.0" } }, + "magic-bytes.js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.5.0.tgz", + "integrity": "sha512-wJkXvutRbNWcc37tt5j1HyOK1nosspdh3dj6LUYYAvF6JYNqs53IfRvK9oEpcwiDA1NdoIi64yAMfdivPeVAyw==" + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3984,18 +6800,24 @@ } }, "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.50.0" + "mime-db": "1.52.0" } }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4006,9 +6828,9 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, "moment": { @@ -4017,11 +6839,11 @@ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, "moment-timezone": { - "version": "0.5.37", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", - "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", + "version": "0.5.43", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz", + "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==", "requires": { - "moment": ">= 2.9.0" + "moment": "^2.29.4" } }, "ms": { @@ -4030,41 +6852,39 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "mysql2": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.2.tgz", - "integrity": "sha512-JUSA50rt/nSew8aq8xe3pRk5Q4y/M5QdSJn7Ey3ndOlPp2KXuialQ0sS35DNhPT5Z5PnOiIwSSQvKkl1WorqRA==", + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.5.tgz", + "integrity": "sha512-pS/KqIb0xlXmtmqEuTvBXTmLoQ5LmAz5NW/r8UyQ1ldvnprNEj3P9GbmuQQ2J0A4LO+ynotGi6TbscPa8OUb+w==", "requires": { - "denque": "^2.0.1", + "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.6.3", - "long": "^4.0.0", - "lru-cache": "^6.0.0", - "named-placeholders": "^1.1.2", + "long": "^5.2.1", + "lru-cache": "^8.0.0", + "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" + }, + "dependencies": { + "lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==" + } } }, "named-placeholders": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", - "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", "requires": { - "lru-cache": "^4.1.3" + "lru-cache": "^7.14.1" }, "dependencies": { "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" } } }, @@ -4074,23 +6894,32 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, "node-gyp-build": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" }, + "npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + }, + "dependencies": { + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + } + } + }, "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true }, "object-keys": { @@ -4100,39 +6929,56 @@ "dev": true }, "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } }, - "object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" } }, "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, + "on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4142,44 +6988,41 @@ "wrappy": "1" } }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "mimic-fn": "^4.0.0" } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", "dev": true, "requires": { - "p-try": "^1.0.0" + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" } }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4189,17 +7032,6 @@ "callsites": "^3.0.0" } }, - "parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -4224,35 +7056,101 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, + "pg-connection-string": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true + }, + "pino": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.17.1.tgz", + "integrity": "sha512-YoN7/NJgnsJ+fkADZqjhRt96iepWBndQHeClmSBH0sQWCb8zGD74t00SK4eOtKFi/f8TUmQnfmgglEhd2kI1RQ==", + "requires": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.1.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.7.0", + "thread-stream": "^2.0.0" + } + }, + "pino-abstract-transport": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz", + "integrity": "sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==", + "requires": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "pino-std-serializers": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "pretty-ms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-5.1.0.tgz", - "integrity": "sha512-4gaK1skD2gwscCfkswYQRmddUb2GJZtzDGRjHWadVHtK/DIKFufa12MvES6/xu1tVbUYeia5bmLcwJtZJQUqnw==", + "prettier": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", + "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, "requires": { - "parse-ms": "^2.1.0" + "fast-diff": "^1.1.2" } }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, + "process-warning": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.1.tgz", + "integrity": "sha512-JjBvFEn7MwFbzUDa2SRtKJSsyO0LlER4V/FmwLMhBlXNbGgGxdyFCxIdMDLerWUycsVUyaoM9QFLvppFy4IWaQ==" + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "queue-microtask": { @@ -4261,19 +7159,46 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true + "quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, + "readable-stream": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "requires": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + } + }, + "real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==" + }, + "regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + } }, "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "requires": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -4284,20 +7209,56 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, - "retry-as-promised": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", - "integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==", + "restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, "requires": { - "any-promise": "^1.3.0" + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + } } }, + "retry-as-promised": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz", + "integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==" + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -4307,6 +7268,88 @@ "glob": "^7.1.3" } }, + "run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "requires": { + "execa": "^5.0.0" + }, + "dependencies": { + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + } + } + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4316,15 +7359,48 @@ "queue-microtask": "^1.2.2" } }, + "safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, + "safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==" + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "requires": { "lru-cache": "^6.0.0" } @@ -4335,29 +7411,55 @@ "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" }, "sequelize": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.9.0.tgz", - "integrity": "sha512-tFROh9T9GgyY6aTV2+aGdfVNvrppuTOo1EFln9AtV8wXJTOOr7Nan7pZum5oLy87CGWl0YeHzAwg99tz04OqNA==", + "version": "6.35.2", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.35.2.tgz", + "integrity": "sha512-EdzLaw2kK4/aOnWQ7ed/qh3B6/g+1DvmeXr66RwbcqSm/+QRS9X0LDI5INBibsy4eNJHWIRPo3+QK0zL+IPBHg==", "requires": { - "debug": "^4.1.1", - "dottie": "^2.0.0", - "inflection": "1.13.1", - "lodash": "^4.17.20", - "moment": "^2.26.0", - "moment-timezone": "^0.5.31", - "retry-as-promised": "^3.2.0", - "semver": "^7.3.2", - "sequelize-pool": "^6.0.0", + "@types/debug": "^4.1.8", + "@types/validator": "^13.7.17", + "debug": "^4.3.4", + "dottie": "^2.0.6", + "inflection": "^1.13.4", + "lodash": "^4.17.21", + "moment": "^2.29.4", + "moment-timezone": "^0.5.43", + "pg-connection-string": "^2.6.1", + "retry-as-promised": "^7.0.4", + "semver": "^7.5.4", + "sequelize-pool": "^7.1.0", "toposort-class": "^1.0.1", - "uuid": "^8.1.0", - "validator": "^13.6.0", + "uuid": "^8.3.2", + "validator": "^13.9.0", "wkx": "^0.5.0" } }, "sequelize-pool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-6.1.0.tgz", - "integrity": "sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", + "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==" + }, + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "requires": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + } }, "shebang-command": { "version": "2.0.0", @@ -4385,35 +7487,127 @@ "object-inspect": "^1.9.0" } }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + } + } + }, + "sonic-boom": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz", + "integrity": "sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==", + "requires": { + "atomic-sleep": "^1.0.0" + } + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" + }, "sqlstring": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz", "integrity": "sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==" }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true + }, + "string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", + "dev": true, + "requires": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "strip-ansi": { @@ -4428,7 +7622,13 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true }, "strip-json-comments": { @@ -4452,12 +7652,36 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "synckit": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.6.tgz", + "integrity": "sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA==", + "dev": true, + "requires": { + "@pkgr/utils": "^2.4.2", + "tslib": "^2.6.2" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "thread-stream": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.1.tgz", + "integrity": "sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==", + "requires": { + "real-require": "^0.2.0" + } + }, + "titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", + "dev": true + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4472,32 +7696,34 @@ "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "requires": {} }, "ts-mixer": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.0.tgz", - "integrity": "sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", + "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" }, "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "requires": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "type-check": { "version": "0.4.0", @@ -4514,18 +7740,89 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, + "typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==" + }, "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" } }, + "undici": { + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz", + "integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==", + "requires": { + "@fastify/busboy": "^2.0.0" + } + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -4536,9 +7833,9 @@ } }, "utf-8-validate": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", - "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-6.0.3.tgz", + "integrity": "sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==", "requires": { "node-gyp-build": "^4.3.0" } @@ -4549,23 +7846,9 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "validator": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", - "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==" }, "which": { "version": "2.0.2", @@ -4589,6 +7872,19 @@ "is-symbol": "^1.0.3" } }, + "which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, "wkx": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", @@ -4597,11 +7893,39 @@ "@types/node": "*" } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "requires": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } }, "wrappy": { "version": "1.0.2", @@ -4610,9 +7934,9 @@ "dev": true }, "ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", "requires": {} }, "yallist": { @@ -4620,16 +7944,17 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true - }, - "zod": { - "version": "3.11.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.11.6.tgz", - "integrity": "sha512-daZ80A81I3/9lIydI44motWe6n59kRBfNzTuS2bfzVh1nAXi667TOTWWtatxyG+fwgNUiagSj/CWZwRRbevJIg==" } } } diff --git a/package.json b/package.json index 1c36c7b..14130c2 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,47 @@ { "name": "agent-black", - "version": "3.0.0", - "main": "index.js", + "description": "A Discord ban management bot.", + "version": "4.0.0", + "main": "dist/index.js", "dependencies": { - "@discordjs/builders": "^0.12.0", - "axios": "^0.26.1", - "bufferutil": "^4.0.5", - "discord.js": "^13.6.0", - "html-to-image": "^1.6.2", - "mysql2": "^2.3.2", - "pretty-ms": "^5.1.0", - "sequelize": "^6.9.0", - "utf-8-validate": "^5.0.7" + "axios": "1.6.2", + "bufferutil": "4.0.8", + "discord.js": "14.14.1", + "mysql2": "3.6.5", + "pino": "8.17.1", + "sequelize": "6.35.2", + "typescript": "5.3.3", + "utf-8-validate": "6.0.3" }, "devDependencies": { - "eslint": "8.23.0", - "eslint-config-airbnb-base": "15.0.0", - "eslint-plugin-import": "2.26.0" + "@types/node": "20.10.4", + "@typescript-eslint/eslint-plugin": "6.14.0", + "@typescript-eslint/parser": "6.14.0", + "eslint": "8.56.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-import": "2.29.1", + "eslint-plugin-prettier": "5.0.1", + "husky": "8.0.3", + "lint-staged": "15.2.0", + "prettier": "3.1.1" }, "scripts": { - "start": "node index.js" + "build": "npx tsc -v -b", + "lint": "npx eslint --fix ./src && npx prettier --check ./src --write", + "prepare": "husky install" }, "keywords": [], - "author": "phil", + "author": { + "name": "Phil", + "url": "https://github.com/FlipperLP" + }, + "contributors": [ + { + "email": "tavi@tavis.page", + "name": "Tavi", + "url": "https://tavis.page" + } + ], "license": "MIT", "repository": { "type": "git", @@ -32,5 +51,8 @@ "url": "https://github.com/FlipperLP/agent-black/issues" }, "homepage": "https://github.com/FlipperLP/agent-black#readme", - "description": "A Discord ban management bot." + "lint-staged": { + "*.ts": "eslint --cache --fix && prettier --write" + }, + "type": "module" } diff --git a/src/classes/banManager.ts b/src/classes/banManager.ts new file mode 100644 index 0000000..cb316e6 --- /dev/null +++ b/src/classes/banManager.ts @@ -0,0 +1,104 @@ +import { Guild, GuildBan, PermissionFlagsBits, UserFlags } from 'discord.js'; +import { Sequelize } from 'sequelize'; +import { ban } from '../typings/Models.js'; + +/** + * @description Ban manager data + */ +type ManagerData = { + /** + * Array of bans + */ + bans: GuildBan[]; + /** + * Sequelize + */ + sequelize: Sequelize; +}; + +class BanManager { + declare bans: GuildBan[]; + declare sequelize: Sequelize; + + /** + * @param {ManagerData} data Data to initialize the manager with + */ + constructor(data: ManagerData) { + this.bans = data.bans || []; + if (data.sequelize instanceof Sequelize === false || !data.sequelize.models.ban) + throw new SyntaxError('Invalid sequelize instance'); + this.sequelize = data.sequelize; + } + + /** + * @description Adds bans to the manager + * @param {GuildBan[]} bans Bans to add to the manager + * @returns {Promise} Bans in the manager + */ + add(bans: GuildBan[]): Promise { + if (bans instanceof GuildBan === false) return Promise.reject('Invalid Ban instance'); + this.bans.push(...bans); + return; + } + + /** + * @async + * @description Adds all bans from a guild to the manager + * @param {Guild} guild Guild to add bans from + * @param {boolean} [cache=false] Should the manager cache the bans + * @returns {Promise} Bans in the manager + */ + async addGuild(guild: Guild, cache = false): Promise { + if (guild instanceof Guild === false) return Promise.reject('Invalid Guild instance'); + if (!guild.members.me.permissions.has(PermissionFlagsBits.BanMembers)) + return Promise.reject('Missing BanMembers in guild'); + const bans = await guild.bans.fetch({ cache }); + this.bans.push(...bans.values()); + return; + } + + /** + * @private + * @description Removes invalid bans from the manager + * @returns {void} + */ + clean(): void { + // If ban features a user or non verified bot, remove it + this.bans = this.bans.filter(async (b) => !b.user.bot ?? (await b.user.fetchFlags()).has(UserFlags.VerifiedBot)); + return; + } + + /** + * @description Syncs the manager with the database, adding bans that don't exist in the database + * @returns {Promise} Result from Sequelize + */ + sync(): Promise[]> { + this.clean(); // Clean bans + const p: Promise<[ban, boolean]>[] = []; + for (const ban of this.bans) { + p.push( + this.sequelize.models.ban.findOrCreate({ + where: { + guildId: ban.guild.id, + targetId: ban.user.id, + reason: String(ban.reason) + } + }) as Promise<[ban, boolean]> + ); + } + return Promise.allSettled(p); + } + + /** + * @description Removes a ban from the manager + * @param {GuildBan} ban Ban to remove from the manager + * @returns {Promise} + */ + remove(ban: GuildBan): Promise { + if (ban instanceof GuildBan === false) return Promise.reject('Invalid Ban instance'); + this.bans.splice(this.bans.indexOf(ban), 1); + return; + } +} + +export { BanManager }; diff --git a/src/commands/about.ts b/src/commands/about.ts new file mode 100644 index 0000000..98b11e8 --- /dev/null +++ b/src/commands/about.ts @@ -0,0 +1,16 @@ +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; +import { readFileSync } from 'node:fs'; +import { default as config } from '../configs/config.json' assert { type: 'json' }; +import { CmdFileArgs } from '../typings/Extensions.js'; +const { commands } = config; + +export const ephemeral = false; +export const data = new SlashCommandBuilder() + .setName('about') + .setDescription('Displays some information about the bot'); +export async function execute({ interaction }: CmdFileArgs): Promise { + interaction.editReply({ + embeds: [new EmbedBuilder().setDescription(readFileSync(commands.about).toString())] + }); + return; +} diff --git a/src/commands/alias.ts b/src/commands/alias.ts new file mode 100644 index 0000000..e7d1db3 --- /dev/null +++ b/src/commands/alias.ts @@ -0,0 +1,50 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('alias') + .setDescription('Creates, updates, or removes an alias for a user') + .addSubcommand((subcommand) => { + return subcommand + .setName('add') + .setDescription('Adds an alias for a user') + .addUserOption((option) => { + return option.setName('user').setDescription('Primary user').setRequired(true); + }) + .addUserOption((option) => { + return option.setName('alias').setDescription('Alternative account').setRequired(true); + }); + }) + .addSubcommand((subcommand) => { + return subcommand + .setName('update') + .setDescription('Updates an alias') + .addUserOption((option) => { + return option.setName('target').setDescription('Alias ID in the database').setRequired(true); + }) + .addUserOption((option) => { + return option.setName('alias').setDescription('New alternative account').setRequired(true); + }); + }) + .addSubcommand((subcommand) => { + return subcommand + .setName('remove') + .setDescription('Deletes an alias from the database') + .addStringOption((option) => { + return option.setName('alias').setDescription('Alias ID to delete').setRequired(true); + }); + }); +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + // If they don't have the staff role, they can't use this command + if (!(await client.functions.get('utils_guildAuth').execute(client, interaction.member))) { + interaction.editReply({ + content: 'You are not authorized to use this command' + }); + return; + } + await client.commands + .get(`${interaction.commandName}_${options.getSubcommand()}`) + .execute({ client, interaction, options }); + return; +} diff --git a/src/commands/alias/add.ts b/src/commands/alias/add.ts new file mode 100644 index 0000000..66d600a --- /dev/null +++ b/src/commands/alias/add.ts @@ -0,0 +1,76 @@ +import { Op, UniqueConstraintError } from 'sequelize'; +import { CmdFileArgs } from '../../typings/Extensions.js'; +import { alias, aliasCreationAttributes } from '../../typings/Models.js'; + +export const name = 'add'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const optUser = options.getUser('user', true); + const optAlias = options.getUser('alias', true); + // Check if aliasing the same two users + if (optUser.id === optAlias.id) { + interaction.editReply({ content: 'You cannot alias the same two users' }); + return; + } + // Check if the alias already exists or exists in reverse + const alias = await client.models.alias.findOne({ + where: { + [Op.or]: [ + { + user: optUser.id, + alternative: optAlias.id + }, + { + user: optAlias.id, + alternative: optUser.id + } + ] + } + }); + if (alias !== null) { + interaction.editReply({ + content: 'The alias you attempted to set already exists' + }); + return; + } + // Create the alias + const attr: aliasCreationAttributes = { + user: optUser.id, + alternative: optAlias.id, + moderator: interaction.user.id + }; + // Check if alternative has an alias. If so, set the alternative to the primary account + const alt = await client.models.alias.findOne({ where: { user: optAlias.id } }); + if (alt !== null) { + attr.user = alt.user; + attr.alternative = optUser.id; + } + // Create and handle the alias + await client.models.alias.create(attr).then( + (dbAlias: alias) => { + if (!dbAlias) { + interaction.editReply({ + content: 'Failed to create the association in the database. Please try again later' + }); + return; + } + interaction.editReply({ + content: `Success! ${optUser.toString()} has been aliased to ${options + .getUser('alias', true) + .toString()} with ID \`${dbAlias.aliasId}\`` + }); + }, + (e: Error) => { + // Check for UniqueConstraintError + // Indicates that the user has already been alised to someone else + if (e instanceof UniqueConstraintError) { + interaction.editReply({ + content: 'The alternative account you attempted to alias already has an existing primary account' + }); + return; + } + interaction.editReply({ + content: 'An unexpected error occurred while creating the alias. Please try again later' + }); + } + ); +} diff --git a/src/commands/alias/remove.ts b/src/commands/alias/remove.ts new file mode 100644 index 0000000..92d737f --- /dev/null +++ b/src/commands/alias/remove.ts @@ -0,0 +1,19 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'remove'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const dbAlias = await client.models.alias.findOne({ + where: { aliasId: options.getString('alias', true) } + }); + if (!dbAlias) { + interaction.editReply({ + content: 'The alias you attempted to remove does not exist' + }); + return; + } + // Delete the alias + await dbAlias.destroy(); + interaction.editReply({ + content: `Success! Alias \`${dbAlias.aliasId}\` has been removed` + }); +} diff --git a/src/commands/alias/update.ts b/src/commands/alias/update.ts new file mode 100644 index 0000000..229b1b8 --- /dev/null +++ b/src/commands/alias/update.ts @@ -0,0 +1,30 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'update'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + if ( + options.getUser('user', true).id === options.getUser('alias', true).id || + options.getUser('user', true).id === interaction.user.id || + options.getUser('alias', true).id === interaction.user.id + ) { + interaction.editReply({ content: 'You cannot alias yourself or the same two users' }); + return; + } + // -- // + const dbAlias = await client.models.alias.findOne({ + where: { aliasId: options.getString('target', true) } + }); + if (!dbAlias) { + interaction.editReply({ + content: 'The alias you attempted to update does not exist' + }); + return; + } + // Set the new alias + dbAlias.alternative = options.getUser('alias', true).id; + dbAlias.moderator = interaction.user.id; + await dbAlias.save(); + interaction.editReply({ + content: `Success! Alias \`${dbAlias.aliasId}\` has been updated` + }); +} diff --git a/src/commands/avatar.ts b/src/commands/avatar.ts new file mode 100644 index 0000000..32f8768 --- /dev/null +++ b/src/commands/avatar.ts @@ -0,0 +1,24 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('avatar') + .setDescription("Fetches a user's profile picture") + .addUserOption((option) => { + return option.setName('user').setDescription('User to fetch').setRequired(true); + }); +export async function execute({ interaction, options }: CmdFileArgs): Promise { + interaction.editReply({ + embeds: [ + { + description: `Avatar for ${options.getUser('user', true).toString()}`, + image: { + url: + options.getUser('user', true).displayAvatarURL({ size: 4096 }) || + 'https://cdn.discordapp.com/embed/avatars/5.png' + } + } + ] + }); +} diff --git a/src/commands/ban.ts b/src/commands/ban.ts new file mode 100644 index 0000000..8ee4e46 --- /dev/null +++ b/src/commands/ban.ts @@ -0,0 +1,70 @@ +import { PermissionFlagsBits, SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('ban') + .setDescription('Permanently bans a user from the server') + .addUserOption((option) => { + return option.setName('user').setDescription('The user to ban').setRequired(true); + }) + .addStringOption((option) => { + return option.setName('reason').setDescription('Reason for ban, if any').setAutocomplete(true).setRequired(false); + }) + .addNumberOption((option) => { + return option.setName('delete_messages').setDescription('Time to delete messages').setChoices( + { + name: "Don't Delete Any", + value: 0 + }, + { + name: '1 Hour', + value: 3600 + }, + { + name: '6 Hours', + value: 21600 + }, + { + name: '12 Hours', + value: 43200 + }, + { + name: '24 Hours', + value: 86400 + }, + { + name: '3 Days', + value: 259200 + }, + { + name: '7 Days', + value: 604800 + } + ); + }) + // Only allow users with the Ban Members permission to use this command + .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers); +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const target = options.getUser('user', true); + // Check if we can ban + if (!interaction.guild.members.me.permissions.has(PermissionFlagsBits.BanMembers)) { + interaction.editReply({ content: 'This bot needs the `Ban Members` permission' }); + return; + } + // Ban on Discord's side, removiung the ban if it exists + const b = await interaction.guild.bans.fetch(target); + if (b) await interaction.guild.bans.remove(target.id); + await interaction.guild.bans.create(target, { + reason: options.getString('reason') || undefined, + deleteMessageSeconds: options.getNumber('deleteMessages') || undefined + }); + // Find or create the ban in the database + await client.models.ban.findOrCreate({ + where: { + guildId: interaction.guild.id, + targetId: target.id, + reason: options.getString('reason') || null + } + }); +} diff --git a/src/commands/banner.ts b/src/commands/banner.ts new file mode 100644 index 0000000..1f17319 --- /dev/null +++ b/src/commands/banner.ts @@ -0,0 +1,24 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('banner') + .setDescription("Fetches a user's banner") + .addUserOption((option) => { + return option.setName('user').setDescription('User to fetch').setRequired(true); + }); +export async function execute({ interaction, options }: CmdFileArgs): Promise { + await options.getUser('user').fetch(); + interaction.editReply({ + embeds: [ + { + description: `Banner for ${options.getUser('user', true).toString()}`, + image: { + url: + options.getUser('user', true).bannerURL({ size: 2048 }) || 'https://cdn.discordapp.com/embed/avatars/5.png' + } + } + ] + }); +} diff --git a/src/commands/broadcast.ts b/src/commands/broadcast.ts new file mode 100644 index 0000000..a16416a --- /dev/null +++ b/src/commands/broadcast.ts @@ -0,0 +1,54 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('broadcast') + .setDescription('Broadcasts a message to all participating servers') + .addNumberOption((option) => { + return option.setName('type').setDescription('Type of message').setRequired(true).setChoices( + { + name: 'Broadcast', + value: 0x6699ff + }, + { + name: 'Maintenance', + value: 0x77b300 + }, + { + name: 'Security Alert', + value: 0xff0000 + }, + { + name: 'Other', + value: 0x000000 + } + ); + }) + .addStringOption((option) => { + return option.setName('message').setDescription('Content to message to servers').setRequired(true); + }); +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const kind = options.getNumber('type', true); + const dbUser = await client.models.user.findOne({ + where: { userId: interaction.user.id } + }); + if (!dbUser) { + await interaction.editReply({ + content: 'You are not authorized to use this command' + }); + return; + } + const flags = dbUser.flags; + if (!flags.has('Maintainer')) { + await interaction.editReply({ + content: 'You are not authorized to use this command' + }); + return; + } + // Clean body + const body = options.getString('message', true).replace(/\\n/g, '\n'); + // Send message + client.functions.get('utils_masterMessage').execute(client, kind, body); + interaction.editReply({ content: 'Messages are being sent!' }); +} diff --git a/src/commands/changelog.ts b/src/commands/changelog.ts new file mode 100644 index 0000000..696a1b2 --- /dev/null +++ b/src/commands/changelog.ts @@ -0,0 +1,16 @@ +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; +import { readFileSync } from 'node:fs'; +import { default as config } from '../configs/config.json' assert { type: 'json' }; +import { CmdFileArgs } from '../typings/Extensions.js'; +const { commands } = config; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('changelog') + .setDescription('Displays current version and changes as of the most recent update'); +export async function execute({ interaction }: CmdFileArgs): Promise { + interaction.editReply({ + embeds: [new EmbedBuilder().setDescription(readFileSync(commands.changelog).toString())] + }); + return; +} diff --git a/src/commands/checkallusers.ts b/src/commands/checkallusers.ts new file mode 100644 index 0000000..d7bc0ef --- /dev/null +++ b/src/commands/checkallusers.ts @@ -0,0 +1,78 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('checkallusers') + .setDescription('Checks all users in the current server') + .addStringOption((option) => { + return option + .setName('spam_warning') + .setDescription('I am aware that this bot may spam the channel and this cannot be stopped midway through') + .addChoices({ + name: 'I have read the above', + value: 'yes' + }); + }); +export async function execute({ client, interaction }: CmdFileArgs): Promise { + // Check if they have the role + if (!(await client.functions.get('utils_guildAuth').execute(client, interaction.member))) { + interaction.editReply({ + content: 'You are not authorized to use this command' + }); + return; + } + + const users = await interaction.guild.members.fetch(); + if (!users) { + interaction.editReply({ content: 'Could not fetch users' }); + return; + } + const ids = users.map((user) => user.id); + // Get their aliases, if any exist + await client.models.alias + .findAll({ + where: { user: ids } + }) + // Map to alternative + .then((aliases) => aliases.map((a) => a.alternative)) + // Push to the list + .then((aliases) => aliases.forEach((a) => ids.push(a))) + // Catch and log the errors for later inspection + .catch((err) => client.logs.error({ err })); + // Find all bans relevant to the server + const allBans = await client.models.ban.findAll({ + where: { targetId: ids } + }); + // We didn't find anyone banned + if (!allBans || allBans.length === 0) { + interaction.editReply({ + content: `Success! Scanned all members and found no bans. Your server is clean` + }); + return; + } + // If less than 5, emit embeds + if (allBans.length <= 5) { + allBans.forEach(async (ban) => { + const g = await client.guilds.fetch(ban.guildId); + interaction.followUp({ + embeds: [ + { + description: `Guild: ${g.name} (${ban.guildId}) + User: <@${ban.targetId}> (${ban.targetId}) + Reason: + \`\`\`\n${ban.reason}\`\`\`` + } + ] + }); + }); + interaction.editReply({ + content: `Success! Scanned all members and found ${allBans.length} bans. See below for details` + }); + return; + } + // If there's more than 5, send to the handler + // @ts-expect-error This function has different parameters + await client.commands.get('checkallusers_handler').execute(client, interaction, allBans); + return; +} diff --git a/src/commands/checkallusers/handler.ts b/src/commands/checkallusers/handler.ts new file mode 100644 index 0000000..a901057 --- /dev/null +++ b/src/commands/checkallusers/handler.ts @@ -0,0 +1,47 @@ +import { ChatInputCommandInteraction, EmbedBuilder } from 'discord.js'; +import { CustomClient } from '../../typings/Extensions.js'; +import { ban } from '../../typings/Models.js'; + +export const name = 'handler'; +export async function execute( + client: CustomClient, + interaction: ChatInputCommandInteraction, + bans: ban[] +): Promise { + // Split the bans into groups of 5 + const banGroups: EmbedBuilder[][] = []; + let temp: EmbedBuilder[] = []; + bans.forEach(async (ban, index) => { + // Fetch guild if not cached + const g = client.guilds.cache.get(ban.guildId) || (await client.guilds.fetch(ban.guildId)); + // Create embed to push to array + const embed = new EmbedBuilder().setDescription(`Guild: ${g.name} (${ban.guildId}) + User: <@${ban.targetId}> (${ban.targetId}) + Reason: + \`\`\`\n${ban.reason}\`\`\``); + // If array is full, push to banGroups + if (index % 5 === 0 && index !== 0) { + banGroups.push(temp); + temp = []; + } + // Push embed to temp array + temp.push(embed); + }); + // Push remaining embeds to banGroups + if (temp.length > 0) { + banGroups.push(temp); + } + // Every 10 seconds, send 5 embeds + const i = setInterval(() => { + interaction.followUp({ embeds: banGroups.shift() }); + // If there are no more embeds to send, clear the interval + if (banGroups.length === 0) { + clearInterval(i); + // Inform the user of completion + interaction.editReply({ + content: `Success! Scanned all members and found ${bans.length} bans. See below for details` + }); + } + }, 10_000); + return; +} diff --git a/src/commands/eval.ts b/src/commands/eval.ts new file mode 100644 index 0000000..a7d71c6 --- /dev/null +++ b/src/commands/eval.ts @@ -0,0 +1,35 @@ +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('eval') + .setDescription('Runs snippets of code') + .addStringOption((option) => { + return option.setName('script').setDescription('The code to run').setRequired(true); + }); +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const dbUser = await client.models.user.findOne({ + where: { userId: interaction.user.id } + }); + if (!dbUser) { + interaction.editReply({ + content: 'You are not authorized to use this command' + }); + return; + } + if (!dbUser.flags.has('Owner')) { + interaction.editReply({ + content: 'You are not authorized to use this command' + }); + return; + } + // Execute command + const result = eval(options.getString('script', true)); + interaction.editReply({ + embeds: [ + new EmbedBuilder().setTitle('Evaluation').setDescription(`\`\`\`js\n${JSON.stringify(result, null, 2)}\`\`\``) + ] + }); + return; +} diff --git a/src/commands/guild.ts b/src/commands/guild.ts new file mode 100644 index 0000000..a498bec --- /dev/null +++ b/src/commands/guild.ts @@ -0,0 +1,39 @@ +import { ChannelType, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('guild') + .setDescription('Manages your server') + .addSubcommand((subcommand) => { + return subcommand + .setName('setup') + .setDescription('Sets up your server with the bot') + .addChannelOption((option) => { + return option + .setName('staff_channel') + .setDescription('Channel to log known users that staff can see') + .addChannelTypes(ChannelType.GuildText) + .setRequired(true); + }) + .addRoleOption((option) => { + return option + .setName('staff_role') + .setDescription('Role that is required when running staff-only commands') + .setRequired(true); + }); + }) + .addSubcommand((subcommand) => { + return subcommand.setName('enable').setDescription('Enables the bot in the guild'); + }) + .addSubcommand((subcommand) => { + return subcommand.setName('disable').setDescription('Disables the bot in the guild'); + }) + .addSubcommand((subcommand) => { + return subcommand.setName('stats').setDescription('Returns statistics of the guild'); + }) + .setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild); +export async function execute({ client, interaction, options }: CmdFileArgs) { + await client.commands.get(`guild_${options.getSubcommand()}`).execute({ client, interaction, options }); + return; +} diff --git a/src/commands/guild/disable.ts b/src/commands/guild/disable.ts new file mode 100644 index 0000000..a387552 --- /dev/null +++ b/src/commands/guild/disable.ts @@ -0,0 +1,24 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'disable'; +export async function execute({ client, interaction }: CmdFileArgs): Promise { + const guild = await client.models.guild.findOne({ + where: { guildId: interaction.guildId } + }); + if (!guild) { + interaction.editReply({ + content: 'This server has not been set up yet. Please run `/guild setup`' + }); + return; + } + if (!guild.enabled) { + interaction.editReply({ content: 'This server is already disabled' }); + return; + } + guild.enabled = false; + await guild.save(); + interaction.editReply({ + content: 'Successfully disabled the bot in this server' + }); + return; +} diff --git a/src/commands/guild/enable.ts b/src/commands/guild/enable.ts new file mode 100644 index 0000000..d7e66e3 --- /dev/null +++ b/src/commands/guild/enable.ts @@ -0,0 +1,24 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'disable'; +export async function execute({ client, interaction }: CmdFileArgs): Promise { + const guild = await client.models.guild.findOne({ + where: { guildId: interaction.guildId as string } + }); + if (!guild) { + interaction.editReply({ + content: 'This server has not been set up yet. Please run `/guild setup`' + }); + return; + } + if (guild.enabled) { + interaction.editReply({ content: 'This server is already enabled' }); + return; + } + guild.enabled = true; + await guild.save(); + interaction.editReply({ + content: 'Successfully enabled the bot in this server' + }); + return; +} diff --git a/src/commands/guild/setup.ts b/src/commands/guild/setup.ts new file mode 100644 index 0000000..d5391ae --- /dev/null +++ b/src/commands/guild/setup.ts @@ -0,0 +1,39 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'setup'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const existingGuild = await client.models.guild.findOne({ + where: { + guildId: interaction.guildId + }, + include: [{ model: client.models.guildsettings, as: 'setting' }] + }); + // Update the database if it exists + if (existingGuild) { + existingGuild.setting.staffRole = options.getRole('staff_role').id; + existingGuild.setting.logChannel = options.getChannel('staff_channel').id; + await existingGuild.setting.save(); + } else { + // Create guild settings first + await client.models.guildsettings + .create({ + staffRole: options.getRole('staff_role').id, + logChannel: options.getChannel('staff_channel').id + }) + // And use that to create the guild entry + .then((s) => + client.models.guild.create({ + guildId: interaction.guildId, + settingsId: s.settingsId, + enabled: true + }) + ) + // Safely catch and log errors + .catch((err) => client.logs.error({ err })); + } + // User reply + interaction.editReply({ + content: `Success! ${existingGuild !== null ? 'Updated' : 'Registered and created'} the settings for this server!` + }); + return; +} diff --git a/src/commands/guild/stats.ts b/src/commands/guild/stats.ts new file mode 100644 index 0000000..f702abf --- /dev/null +++ b/src/commands/guild/stats.ts @@ -0,0 +1,53 @@ +import { EmbedBuilder } from 'discord.js'; +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'stats'; +export async function execute({ client, interaction }: CmdFileArgs): Promise { + const guild = await client.models.guild.findOne({ + where: { guildId: interaction.guildId }, + include: [{ model: client.models.guildsettings, as: 'setting' }] + }); + const owner = await interaction.guild.fetchOwner(); + if (!owner) { + interaction.editReply({ + content: 'An error occurred while fetching guild data. Please try again later' + }); + return; + } + const embed = new EmbedBuilder() + .setTitle(`Statistics for ${interaction.guild.name}`) + .setAuthor({ + name: owner.user.tag, + iconURL: owner.displayAvatarURL({ size: 1024 }) + }) + .addFields([ + { + name: 'Server Info', + value: `${interaction.guild.name} (\`${interaction.guildId}\`)`, + inline: true + } + ]) + .setTimestamp(); + if (guild) { + embed.addFields([ + { + name: 'Logging Channel', + value: `<#${guild.setting.logChannel}> (\`${guild.setting.logChannel}\`)`, + inline: true + }, + { + name: 'Authorised Role', + value: `<@&${guild.setting.staffRole}> (\`${guild.setting.staffRole}\`)`, + inline: true + }, + { + name: 'Association Information', + value: `Participating Since: \`${ + guild.enabled ? `${Math.floor(guild.updatedAt.getTime() / 1000)}` : 'N/A' + }\`\nBans Submitted: \`${await guild.countBans()}\`` + } + ]); + } + interaction.editReply({ embeds: [embed] }); + return; +} diff --git a/src/commands/guildmgr.ts b/src/commands/guildmgr.ts new file mode 100644 index 0000000..02c30f8 --- /dev/null +++ b/src/commands/guildmgr.ts @@ -0,0 +1,67 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; +import { StaffFlags } from '../typings/StaffFlags.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('guildmgr') + .setDescription('[Maintainer] Manages guilds') + .addSubcommand((subcommand) => { + return subcommand + .setName('add') + .setDescription('Add guild') + .addStringOption((option) => { + return option.setName('server').setDescription('Guild ID to add').setAutocomplete(true).setRequired(true); + }) + .addStringOption((option) => { + return option + .setName('channel') + .setDescription("Guild's staff channel") + .setAutocomplete(true) + .setRequired(true); + }) + .addStringOption((option) => { + return option.setName('role').setDescription("Guild's authorised role").setAutocomplete(true).setRequired(true); + }); + }) + .addSubcommand((subcommand) => { + return subcommand + .setName('info') + .setDescription('Display info about a guild') + .addStringOption((option) => { + return option + .setName('server') + .setDescription('Guild ID to fetch information for') + .setAutocomplete(true) + .setRequired(true); + }); + }) + .addSubcommand((subcommand) => { + return subcommand + .setName('remove') + .setDescription('Remove guild') + .addStringOption((option) => { + return option.setName('server').setDescription('Guild ID to remove').setAutocomplete(true).setRequired(true); + }); + }) + .addSubcommand((subcommand) => { + return subcommand + .setName('block') + .setDescription('Block guild') + .addStringOption((option) => { + return option.setName('server').setDescription('Guild ID to block').setAutocomplete(true).setRequired(true); + }); + }); +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const user = await client.models.user.findOne({ where: { userId: interaction.user.id } }); + if (!user) { + interaction.editReply({ content: 'You are not authorized to use this command.' }); + return; + } + if (!user.flags.has(StaffFlags.Maintainer)) { + interaction.editReply({ content: 'You are not authorized to use this command.' }); + return; + } + await client.commands.get(`guildmgr_${options.getSubcommand(true)}`).execute({ client, interaction, options }); + return; +} diff --git a/src/commands/guildmgr/add.ts b/src/commands/guildmgr/add.ts new file mode 100644 index 0000000..abad548 --- /dev/null +++ b/src/commands/guildmgr/add.ts @@ -0,0 +1,56 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'add'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + // Options + const guildId = options.getString('server', true); + const channelId = options.getString('channel', true); + const roleId = options.getString('role', true); + // Try to find guild + const guild = await client.guilds.fetch(guildId); + if (!guild) { + await interaction.editReply('Invalid argument: Guild not found'); + return; + } + // Try to find channel and role + const channel = guild.channels.cache.get(channelId); + const role = guild.roles.cache.get(roleId); + if (!channel || !role) { + await interaction.editReply('Invalid argument: Channel and/or role not found'); + return; + } + // Check if guild already exists + const dbGuild = await client.models.guild.findOne({ + where: { guildId }, + include: [{ model: client.models.guildsettings, as: 'setting' }] + }); + // If it does, update settings + if (dbGuild) { + dbGuild.setting.logChannel = channelId; + dbGuild.setting.staffRole = roleId; + await dbGuild.setting.save(); + } else { + // Otherwise create settings + await client.models.guildsettings + .create({ + staffRole: roleId, + logChannel: channelId + }) + // And use that to create the guild entry + .then((s) => + client.models.guild.create({ + guildId, + settingsId: s.settingsId + }) + ) + // Safely catch and log errors + .catch((err) => client.logs.error({ err })); + } + // User reply + await interaction.editReply({ + content: `Success! ${dbGuild !== null ? 'Updated' : 'Registered and created'} the settings for ${ + guild.name + } (${guildId})!` + }); + return; +} diff --git a/src/commands/guildmgr/block.ts b/src/commands/guildmgr/block.ts new file mode 100644 index 0000000..ad8268a --- /dev/null +++ b/src/commands/guildmgr/block.ts @@ -0,0 +1,21 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'block'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const guildId = options.getString('server', true); + const guild = client.guilds.cache.get(guildId); + if (!guild) { + interaction.editReply({ content: 'Specified guild ID does not exist' }); + return; + } + const dbGuild = await client.models.guild.findOne({ where: { guildId } }); + if (!dbGuild) { + interaction.editReply({ content: 'Specified guild ID is not in the database' }); + return; + } + dbGuild.banned = true; + dbGuild.enabled = false; + await dbGuild.save(); + interaction.editReply({ content: `Guild ${guild.name} has been blocked from using the bot` }); + return; +} diff --git a/src/commands/guildmgr/info.ts b/src/commands/guildmgr/info.ts new file mode 100644 index 0000000..58ab397 --- /dev/null +++ b/src/commands/guildmgr/info.ts @@ -0,0 +1,54 @@ +import { EmbedBuilder } from 'discord.js'; +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'info'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const guildId = options.getString('server', true); + const guild = await client.models.guild.findOne({ + where: { guildId }, + include: [{ model: client.models.guildsettings, as: 'setting' }] + }); + const owner = await interaction.guild.fetchOwner(); + if (!owner) { + interaction.editReply({ + content: 'An error occurred while fetching guild data. Please try again later' + }); + return; + } + const embed = new EmbedBuilder() + .setTitle(`Statistics for ${interaction.guild.name}`) + .setAuthor({ + name: owner.user.tag, + iconURL: owner.displayAvatarURL({ size: 1024 }) + }) + .addFields([ + { + name: 'Server Info', + value: `${interaction.guild.name} (\`${interaction.guildId}\`)`, + inline: true + } + ]) + .setTimestamp(); + if (guild) { + embed.addFields([ + { + name: 'Logging Channel', + value: `<#${guild.setting.logChannel}> (\`${guild.setting.logChannel}\`)`, + inline: true + }, + { + name: 'Authorised Role', + value: `<@&${guild.setting.staffRole}> (\`${guild.setting.staffRole}\`)`, + inline: true + }, + { + name: 'Association Information', + value: `Participating Since: \`${ + guild.enabled ? `${Math.floor(guild.updatedAt.getTime() / 1000)}` : 'N/A' + }\`\nBans Submitted: \`${await guild.countBans()}\`` + } + ]); + } + interaction.editReply({ embeds: [embed] }); + return; +} diff --git a/src/commands/guildmgr/remove.ts b/src/commands/guildmgr/remove.ts new file mode 100644 index 0000000..917bda9 --- /dev/null +++ b/src/commands/guildmgr/remove.ts @@ -0,0 +1,15 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'block'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const guildId = options.getString('server', true); + const dbGuild = await client.models.guild.findOne({ where: { guildId } }); + if (!dbGuild) { + interaction.editReply({ content: 'Specified guild ID is not in the database' }); + return; + } + dbGuild.enabled = false; + await dbGuild.save(); + interaction.editReply({ content: `Guild \`${guildId}\` has been disabled from using the bot` }); + return; +} diff --git a/src/commands/help.ts b/src/commands/help.ts new file mode 100644 index 0000000..8c7b8cb --- /dev/null +++ b/src/commands/help.ts @@ -0,0 +1,13 @@ +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = false; +export const data = new SlashCommandBuilder().setName('help').setDescription('Displays help menu'); +export async function execute({ interaction }: CmdFileArgs): Promise { + const embed = new EmbedBuilder().setTitle('Help Panel').setDescription( + `Our wiki is found here and details every command: https://github.com/FlippedCode/agent-black/wiki + You can also join our server found here: https://discord.gg/TqBwHtzzhD` + ); + interaction.editReply({ embeds: [embed] }); + return; +} diff --git a/src/commands/lookup.ts b/src/commands/lookup.ts new file mode 100644 index 0000000..be051fc --- /dev/null +++ b/src/commands/lookup.ts @@ -0,0 +1,111 @@ +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; +import { FlagEmoji, CmdFileArgs } from '../typings/Extensions.js'; +// Load functions from other files +import { execute as aliasOverview } from './lookup/aliasOverview.js'; +import { execute as userBans } from './lookup/userBans.js'; +import { execute as userWarns } from './lookup/userWarns.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('lookup') + .setDescription('Fetches data from the Discord API and Agent Black database') + .addUserOption((option) => { + return option.setName('user').setDescription('The user to search').setRequired(true); + }); +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + // Definitions + const user = options.getUser('user', true), + aliases = (await client.models.alias.findAll({ where: { user: user.id } })) || []; + // Get their user information + const discordUser = options.getUser('user', true); + const dFlags = await discordUser.fetchFlags(); + const flags: string[] = dFlags + .toArray() + // Map to emojis + .map((flag) => FlagEmoji[String(flag) as keyof typeof FlagEmoji]) + .filter((v) => v !== undefined); + + // Unverified Bot + if (discordUser.bot && !flags.includes(FlagEmoji.VerifiedBot)) flags.push('**Unverified Bot**'); + + /** @desc List of categories that can be switched through */ + const categories: { [key: string]: EmbedBuilder[] } = { + overview: [], + aliases: [], + warns: [], + bans: [] + }; + //#region Overview + categories.overview.push( + new EmbedBuilder() + .setTitle(`User Information`) + .setDescription('Contains basic information about this user') + .addFields( + { + name: 'Username', + value: discordUser.username, + inline: true + }, + { + name: 'Display Name', + value: String(discordUser.globalName || 'N/A'), + inline: true + }, + { + name: 'ID', + value: String(discordUser.id), + inline: true + }, + { + name: 'Created At', + value: ``, + inline: true + }, + { + name: 'Flags', + value: flags.join(' ') || 'None', + inline: true + } + ) + .setTimestamp() + ); + //#endregion + //#region Warns & Bans + categories['warns'] = await userWarns(client, user.id); + categories['bans'] = await userBans(client, user.id); + categories['aliases'] = await aliasOverview(client, user.id); + // Use an array to store promises + const aliasBans: Promise[] = []; + const aliasWarns: Promise[] = []; + for (const alias of aliases) { + aliasBans.push(userBans(client, String(alias.alternative))); + aliasWarns.push(userWarns(client, String(alias.alternative))); + } + // Wait for all promises to resolve + // Flatten to return a single array + categories['bans'].push(...(await Promise.all(aliasBans)).flat()); + categories['warns'].push(...(await Promise.all(aliasWarns)).flat()); + //#endregion + await client.functions.get('utils_pagination').execute(client, interaction, categories, [ + { + label: 'Overview', + value: 'overview', + description: `View general information on ${user.username}` + }, + { + label: 'Alias', + value: 'aliases', + description: `View aliases for ${user.username}` + }, + { + label: 'Bans', + value: 'bans', + description: `${user.username}'s bans across all servers` + }, + { + label: 'Warns', + value: 'warns', + description: `${user.username}'s warnings across all servers` + } + ]); +} diff --git a/src/commands/lookup/aliasOverview.ts b/src/commands/lookup/aliasOverview.ts new file mode 100644 index 0000000..4858330 --- /dev/null +++ b/src/commands/lookup/aliasOverview.ts @@ -0,0 +1,34 @@ +import { EmbedBuilder } from 'discord.js'; +import { CustomClient } from '../../typings/Extensions.js'; + +export const name = 'aliasOverview'; +export async function execute(client: CustomClient, target: string): Promise { + // Variables + const aliases = await client.models.alias.findAll({ where: { user: target } }); + // No aliases + if (!aliases || aliases.length === 0) { + return [ + new EmbedBuilder() + .setTitle('Aliases') + .setDescription(`No aliases exist for the selected user <@${target}> (${target})`) + ]; + } + // Add aliases, 6 per embed + const embeds: EmbedBuilder[] = []; + let embed = new EmbedBuilder().setTitle('Aliases').setDescription(`Aliases for <@${target}> (${target})`); + for (let i = 0; i < aliases.length; i++) { + // Add field + embed.addFields({ + name: `Alias ${aliases[i].aliasId}`, + value: `<@${aliases[i].alternative}> (${aliases[i].alternative})`, + inline: true + }); + // Add embed to array if 6 fields have been added + if ((i % 6 === 0 && i !== 0) || i === aliases.length - 1) { + embed.setFooter({ text: `Page ${embeds.length + 1}` }); + embeds.push(embed); + embed = new EmbedBuilder().setTitle('Aliases').setDescription(`Aliases for <@${target}> (${target})`); + } + } + return embeds; +} diff --git a/src/commands/lookup/userBans.ts b/src/commands/lookup/userBans.ts new file mode 100644 index 0000000..e7337f4 --- /dev/null +++ b/src/commands/lookup/userBans.ts @@ -0,0 +1,49 @@ +import { EmbedBuilder } from 'discord.js'; +import { CustomClient } from '../../typings/Extensions.js'; + +function escape(str: string): string { + return str.replace(/`/g, '\\`'); +} + +export const name = 'userBans'; +export async function execute(client: CustomClient, user: string): Promise { + const bans = await client.models.ban.findAll({ where: { targetId: user } }); + const u = await client.users.fetch(user); + const e: EmbedBuilder[] = []; + if (!bans || bans.length === 0) + return [new EmbedBuilder().setTitle('No Bans Found').setDescription(`No bans were found for <@${user}> (${user})`)]; + for (const ban of bans) { + const g = await client.guilds.fetch(ban.guildId); + e.push( + new EmbedBuilder() + .setTitle(`${u.username}'s Bans`) + .setDescription( + `This ban is: **${!ban.isSoftDeleted() ? 'Active' : 'Removed'}**\`\`\`\n${escape(ban.reason)}\`\`\`` + ) + .setFields( + { + name: 'Target', + value: `<@${ban.targetId}>`, + inline: true + }, + { + name: 'Server', + value: `${g.name} (${g.id})`, + inline: true + }, + { + name: 'Timings', + value: `Created: \nUpdated: `, + inline: true + } + ) + .setFooter({ + text: `${bans.indexOf(ban) + 1}/${bans.length}` + }) + .setTimestamp() + ); + } + return e; +} diff --git a/src/commands/lookup/userWarns.ts b/src/commands/lookup/userWarns.ts new file mode 100644 index 0000000..05c59b3 --- /dev/null +++ b/src/commands/lookup/userWarns.ts @@ -0,0 +1,52 @@ +import { EmbedBuilder } from 'discord.js'; +import { CustomClient } from '../../typings/Extensions.js'; + +function escape(str: string): string { + return str.replace(/`/g, '\\`'); +} + +export const name = 'userWarns'; +export async function execute(client: CustomClient, user: string): Promise { + const warns = await client.models.warn.findAll({ where: { targetId: user } }); + const u = await client.users.fetch(user); + if (!u) return []; + const e: EmbedBuilder[] = []; + if (!warns || warns.length === 0) + return [ + new EmbedBuilder().setTitle('No Warns Found').setDescription(`No warns were found for <@${user}> (${user})`) + ]; + for (const warn of warns) { + const g = await client.guilds.fetch(warn.guildId); + e.push( + new EmbedBuilder() + .setTitle(`${u.username}'s Warnings`) + .setDescription( + `This warn is: **${!warn.isSoftDeleted() ? 'Active' : 'Removed'}**\`\`\`\n${escape(warn.reason)}\`\`\`` + ) + .setFields( + { + name: 'Target', + value: `<@${warn.targetId}>`, + inline: true + }, + { + name: 'Server', + value: `${g.name} (${g.id})`, + inline: true + }, + { + name: 'Timings', + value: `Created: \nUpdated: `, + inline: true + } + ) + .setFooter({ + text: `${warns.indexOf(warn) + 1}/${warns.length}` + }) + .setTimestamp() + ); + } + return e; +} diff --git a/src/commands/maintainer.ts b/src/commands/maintainer.ts new file mode 100644 index 0000000..02642e4 --- /dev/null +++ b/src/commands/maintainer.ts @@ -0,0 +1,38 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('maintainer') + .setDescription('Manages the maintainers [STAFF ONLY]') + .addUserOption((option) => option.setName('user').setDescription('Target user').setRequired(true)) + .addStringOption((option) => + option + .setName('action') + .setDescription('What do you want to do with this user?') + .addChoices( + { + name: 'Add maintainer', + value: 'add' + }, + { + name: 'Remove maintainer', + value: 'remove' + }, + { + name: 'Display info about user', + value: 'info' + } + ) + .setRequired(true) + ); +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const act = options.getString('action', true); + const u = await client.models.user.findOne({ where: { userId: interaction.user.id } }); + if (act !== 'info' && !u.flags.has('Owner')) { + interaction.editReply({ content: 'You are not authorised to use perform that action' }); + return; + } + // -- // + client.commands.get(`${interaction.commandName}_${act}`).execute({ client, interaction, options }); +} diff --git a/src/commands/maintainer/add.ts b/src/commands/maintainer/add.ts new file mode 100644 index 0000000..bc9d9ac --- /dev/null +++ b/src/commands/maintainer/add.ts @@ -0,0 +1,18 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'add'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const m = await options.getUser('user'); + // Find or create the user + const [u] = await client.models.user.findOrCreate({ + where: { userId: m.id } + }); + if (!u) { + interaction.editReply({ content: 'Sequelize failed to find or create the staff member' }); + return; + } + // -- // + u.flags.add('Maintainer'); + u.save(); + interaction.editReply({ content: 'Added maintainer' }); +} diff --git a/src/commands/maintainer/info.ts b/src/commands/maintainer/info.ts new file mode 100644 index 0000000..7b0ba01 --- /dev/null +++ b/src/commands/maintainer/info.ts @@ -0,0 +1,39 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'info'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const m = await options.getUser('user'); + const u = await client.models.user.findOne({ where: { userId: m.id } }); + if (!u) { + interaction.editReply({ content: 'User is not a member of staff' }); + return; + } + // -- // + interaction.editReply({ + embeds: [ + { + title: `Staff Information | ` + m.globalName, + author: { + name: m.username, + icon_url: m.displayAvatarURL() + }, + fields: [ + { + name: 'Role', + value: u.flags.has('Owner', false) ? 'Owner' : u.flags.has('Maintainer') ? 'Maintainer' : 'Moderator' + }, + { + name: 'Flags', + value: u.flags.toArray().join(', ') + }, + { + name: 'Staff Since', + value: ` ()` + } + ] + } + ] + }); +} diff --git a/src/commands/maintainer/remove.ts b/src/commands/maintainer/remove.ts new file mode 100644 index 0000000..88c8355 --- /dev/null +++ b/src/commands/maintainer/remove.ts @@ -0,0 +1,18 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +export const name = 'remove'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const u = await client.models.user.findOne({ where: { userId: options.getUser('user').id } }); + if (!u) { + interaction.editReply({ content: 'User is not a member of staff' }); + return; + } + if (u.flags.has('Owner') || u.userId === interaction.user.id) { + interaction.editReply({ content: 'You cannot remove this user' }); + return; + } + // -- // + u.flags.remove('Maintainer'); + u.save(); + interaction.editReply({ content: 'Removed maintainer' }); +} diff --git a/src/commands/ping.ts b/src/commands/ping.ts new file mode 100644 index 0000000..4f95d90 --- /dev/null +++ b/src/commands/ping.ts @@ -0,0 +1,23 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder().setName('ping').setDescription('Shows Discord API and bot latency'); +export async function execute({ client, interaction }: CmdFileArgs): Promise { + const t0 = Date.now(); + await interaction.editReply({ content: 'Pinging services, please wait (0/1)' }); + // -- // + await interaction.editReply({ content: 'Pinging services, please wait (1/1)' }); + const t1 = Date.now(); + const latency = t1 - t0; + // -- // + interaction.editReply({ + content: 'Pinged services!', + embeds: [ + { + title: 'Latency Results', + description: `Discord API: ${latency}ms\nWebsocket: ${client.ws.ping}ms` + } + ] + }); +} diff --git a/src/commands/syncallbans.ts b/src/commands/syncallbans.ts new file mode 100644 index 0000000..d47301f --- /dev/null +++ b/src/commands/syncallbans.ts @@ -0,0 +1,36 @@ +import { SlashCommandBuilder, Team } from 'discord.js'; +import { BanManager } from '../classes/banManager.js'; +import { CmdFileArgs, CustomClient } from '../typings/Extensions.js'; + +function authorised(client: CustomClient, user: string): boolean { + return ( + (client.application.owner instanceof Team && client.application.owner.members.has(user)) || + client.application.owner.id === user + ); +} + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('syncallbans') + .setDescription('Adds all bans from all participating servers [OWNER ONLY]'); +export async function execute({ client, interaction }: CmdFileArgs): Promise { + // Check owner + if (!authorised(client, interaction.user.id)) { + interaction.editReply({ content: 'You are not authorised to use this command' }); + return; + } + // Fetch guilds + const guilds = await client.guilds.fetch(); + const manager = new BanManager({ bans: [], sequelize: client.sequelize }); + // Loop through guilds, adding promises + const p = []; + for (const g of guilds.values()) { + // Add guild, using ID from OAuthGuild + p.push(manager.addGuild(client.guilds.cache.get(g.id), true)); + } + await Promise.all(p); + // Sync bans + await manager.sync(); + // Reply + interaction.editReply({ content: `Synced ${manager.bans.length} bans` }); +} diff --git a/src/commands/syncbans.ts b/src/commands/syncbans.ts new file mode 100644 index 0000000..5755a10 --- /dev/null +++ b/src/commands/syncbans.ts @@ -0,0 +1,38 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { BanManager } from '../classes/banManager.js'; +import { CmdFileArgs, CustomClient } from '../typings/Extensions.js'; + +async function authorised(client: CustomClient, user: string): Promise { + try { + const u = await client.models.user.findOne({ where: { userId: user } }); + return u.flags.has('Maintainer'); + } catch { + return false; + } +} + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('syncbans') + .setDescription('Adds bans from the current guild [MAINTAINER ONLY]'); +export async function execute({ client, interaction }: CmdFileArgs): Promise { + // Check owner + if (!(await authorised(client, interaction.user.id))) { + interaction.editReply({ content: 'You are not authorised to use this command' }); + return; + } + // Fetch guild + const g = await client.models.guild.findOne({ where: { guildId: interaction.guildId } }); + if (!g) { + interaction.editReply({ content: 'This server is not participating! Run `/guild setup` to add the server' }); + return; + } + const manager = new BanManager({ bans: [], sequelize: client.sequelize }); + // Loop through guild + await manager.addGuild(interaction.guild, true); + // Sync bans + const bans = await manager.sync(); + const success = bans.filter((b) => b.status !== 'rejected'); + // Reply + interaction.editReply({ content: `Synced ${success.length}/${bans.length} bans` }); +} diff --git a/src/commands/unban.ts b/src/commands/unban.ts new file mode 100644 index 0000000..324f0b9 --- /dev/null +++ b/src/commands/unban.ts @@ -0,0 +1,29 @@ +import { PermissionFlagsBits, SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('unban') + .setDescription('Unbans a user') + .addUserOption((option) => option.setName('user').setDescription('Banned user').setRequired(true)) + // Only allow users with BanMembers permission to use this command + .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers); +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + // Find ban + const b = await interaction.guild.bans.fetch(options.getUser('user')); + if (!b) { + interaction.editReply({ content: 'The supplied user is not banned' }); + return; + } + // Unban on Discord's side + await interaction.guild.bans.remove(b.user); + // Remove from database + await client.models.ban.destroy({ + where: { + targetId: b.user.id, + guildId: interaction.guild.id + } + }); + // Reply + interaction.editReply({ content: `Unbanned ${b.user.toString()}` }); +} diff --git a/src/commands/warn.ts b/src/commands/warn.ts new file mode 100644 index 0000000..94cae82 --- /dev/null +++ b/src/commands/warn.ts @@ -0,0 +1,36 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { CmdFileArgs } from '../typings/Extensions.js'; + +export const ephemeral = true; +export const data = new SlashCommandBuilder() + .setName('warn') + .setDescription('Warns other servers about a specific user') + .addSubcommand((cmd) => { + return cmd + .setName('add') + .setDescription('Add warning to a user') + .addUserOption((option) => + option.setName('target').setDescription('User to issue a warning to').setRequired(true) + ) + .addStringOption((option) => + option.setName('message').setDescription('Statement regarding the user').setRequired(true) + ); + }) + .addSubcommand((cmd) => { + return cmd + .setName('edit') + .setDescription('Edit a existing warning.') + .addNumberOption((option) => option.setName('id').setDescription('Unique warning ID').setRequired(true)) + .addStringOption((option) => + option.setName('message').setDescription('Statement regarding the user').setRequired(true) + ); + }); +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const dbUser = await client.models.user.findOne({ where: { userId: interaction.user.id } }); + if ((!dbUser || dbUser.flags.has('Staff')) && interaction.memberPermissions.has('ModerateMembers')) { + interaction.editReply({ content: 'You are not authorised to perform that action' }); + return; + } + const act = options.getSubcommand(true); + client.commands.get(`${interaction.commandName}_${act}`).execute({ client, interaction, options }); +} diff --git a/src/commands/warn/add.ts b/src/commands/warn/add.ts new file mode 100644 index 0000000..e0b27fe --- /dev/null +++ b/src/commands/warn/add.ts @@ -0,0 +1,26 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +// Safely escapes backticks and backslashes +function escape(str: string): string { + return str.replace('\\', '\\\\').replace('`', '\\`'); +} + +export const name = 'add'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const t = options.getUser('target'); + const w = await client.models.warn.create({ + guildId: interaction.guild.id, + targetId: t.id, + reason: options.getString('message') + }); + interaction.editReply({ content: `Successfully created warning ${w.warnId}. Scanning for affected servers` }); + // Warn servers + client.functions + .get('utils_masterMessage') + .execute( + client, + `New warning issued for ${t.username} (${t.id}) who is in your server. Reason: \n\`\`\`\n${escape( + w.reason + )}\`\`\`` + ); +} diff --git a/src/commands/warn/edit.ts b/src/commands/warn/edit.ts new file mode 100644 index 0000000..e7789ec --- /dev/null +++ b/src/commands/warn/edit.ts @@ -0,0 +1,35 @@ +import { CmdFileArgs } from '../../typings/Extensions.js'; + +// Safely escapes backticks and backslashes +function escape(str: string): string { + return str.replace('\\', '\\\\').replace('`', '\\`'); +} + +export const name = 'edit'; +export async function execute({ client, interaction, options }: CmdFileArgs): Promise { + const entry = await client.models.warn.findOne({ + where: { + warnId: options.getNumber('id', true), + guildId: interaction.guildId + } + }); + if (!entry) { + interaction.editReply({ content: 'That warning does not exist' }); + return; + } + // Get the target + // Update the entry + entry.reason = options.getString('message', true); + await entry.save(); + interaction.editReply({ content: 'Warning updated. Servers will be updated shortly' }); + // Warn other servers + const t = await client.users.fetch(entry.targetId)!; + client.functions + .get('utils_masterMessage') + .execute( + client, + `Warning updated for ${t.username} (${t.id}) who is in your server. Reason: \n\`\`\`\n${escape( + entry.reason + )}\`\`\`` + ); +} diff --git a/src/configs/config.json b/src/configs/config.json new file mode 100644 index 0000000..6102070 --- /dev/null +++ b/src/configs/config.json @@ -0,0 +1,28 @@ +{ + "name": "Agent Black", + "teamRole": "638670637052854282", + "logChannel": "638793508202741790", + "setup": { + "setupFunctions": ["SETUP_heartbeat", "SETUP_offlineStat", "SETUP_status"] + }, + "commands": { + "lookup": { + "lowerQuerryLimit": 5, + "botBadge": "<:system_bot_notifier:813101401646432298>" + }, + "about": "../ABOUT.md", + "changelog": "../CHANGELOG.md", + "avatar": "../assets/agentBlack.jpg" + }, + "functions": { + "userTagRecord": { + "maxCacheTimeout": 10800000 + }, + "heartbeat": { + "uptime": { + "interval": 50000, + "endpoints": ["http://statuspage_app_sp_1:3001/api/push/"] + } + } + } +} diff --git a/src/configs/main.json b/src/configs/main.json new file mode 100644 index 0000000..08194f1 --- /dev/null +++ b/src/configs/main.json @@ -0,0 +1,31 @@ +{ + "name": "Agent Black", + "prefix": { + "default": "a!", + "nicknameSpacer": " | " + }, + "setup": { + "moduleFolders": { + "functionsFolder": "functions", + "commandsFolder": "commands" + }, + "startupFunctions": ["STARTUP_initCommands", "STARTUP_initFunctions", "STARTUP_envPrep", "STARTUP_DBConnection"], + "setupFunctions": ["SETUP_offlineStat", "SETUP_status"], + "setupFunctionsOnce": ["TCKR_offlineStat"] + }, + "commands": { + "lookup": { + "lowerQuerryLimit": 5 + } + }, + "functions": { + "userTagRecord": { + "maxCacheTimeout": 10800000 + } + }, + "emojiLayout": "/(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c[\ude32-\ude3a]|[\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g", + "aboutText": "./config/about.txt", + "teamRole": "638670637052854282", + "logStatusChannel": "638793508202741790", + "lookupBotBadge": "<:system_bot_notifier:813101401646432298>" +} diff --git a/src/database/models/alias.ts b/src/database/models/alias.ts new file mode 100644 index 0000000..e1356f3 --- /dev/null +++ b/src/database/models/alias.ts @@ -0,0 +1,60 @@ +import * as Sequelize from 'sequelize'; +import { DataTypes, Model, Optional } from 'sequelize'; + +export interface aliasAttributes { + aliasId: number; + user: string; + alternative: string; + moderator: string; +} + +export type aliasPk = 'aliasId'; +export type aliasId = alias[aliasPk]; +export type aliasOptionalAttributes = 'aliasId'; +export type aliasCreationAttributes = Optional; + +export class alias extends Model implements aliasAttributes { + //? Convert non null assertions to declare to prevent shadowing + declare aliasId: number; + declare user: string; + declare alternative: string; + declare moderator: string; + + static initModel(sequelize: Sequelize.Sequelize): typeof alias { + return alias.init( + { + aliasId: { + autoIncrement: true, + type: DataTypes.INTEGER, + allowNull: false, + primaryKey: true + }, + user: { + type: DataTypes.STRING(30), + allowNull: false + }, + alternative: { + type: DataTypes.STRING(30), + allowNull: false + }, + moderator: { + type: DataTypes.STRING(30), + allowNull: false + } + }, + { + sequelize, + tableName: 'alias', + timestamps: true, + indexes: [ + { + name: 'PRIMARY', + unique: true, + using: 'BTREE', + fields: [{ name: 'aliasId' }] + } + ] + } + ); + } +} diff --git a/src/database/models/ban.ts b/src/database/models/ban.ts new file mode 100644 index 0000000..c99665e --- /dev/null +++ b/src/database/models/ban.ts @@ -0,0 +1,80 @@ +import * as Sequelize from 'sequelize'; +import { DataTypes, Model, Optional } from 'sequelize'; +import type { guild, guildId } from './guild.js'; + +export interface banAttributes { + banId: number; + guildId: string; + targetId: string; + reason: string; +} + +export type banPk = 'banId'; +export type banId = ban[banPk]; +export type banOptionalAttributes = 'banId'; +export type banCreationAttributes = Optional; + +export class ban extends Model implements banAttributes { + //? Convert non null assertions to declare to prevent shadowing + declare banId: number; + declare guildId: string; + declare targetId: string; + declare reason: string; + declare createdAt: Date; + declare updatedAt: Date; + declare deletedAt?: Date; + + // ban belongsTo guild via guildId + declare guild: guild; + declare getGuild: Sequelize.BelongsToGetAssociationMixin; + declare setGuild: Sequelize.BelongsToSetAssociationMixin; + declare createGuild: Sequelize.BelongsToCreateAssociationMixin; + + static initModel(sequelize: Sequelize.Sequelize): typeof ban { + return ban.init( + { + banId: { + autoIncrement: true, + type: DataTypes.INTEGER, + allowNull: false, + primaryKey: true + }, + guildId: { + type: DataTypes.STRING(30), + allowNull: false, + references: { + model: 'guild', + key: 'guildId' + } + }, + targetId: { + type: DataTypes.STRING(30), + allowNull: false + }, + reason: { + type: DataTypes.TEXT, + allowNull: false + } + }, + { + sequelize, + tableName: 'ban', + timestamps: true, + paranoid: true, + indexes: [ + { + name: 'PRIMARY', + unique: true, + using: 'BTREE', + fields: [{ name: 'banId' }] + }, + { + name: 'bans_ibfk_1', + using: 'BTREE', + fields: [{ name: 'guildId' }] + } + ] + } + ); + } +} diff --git a/src/database/models/guild.ts b/src/database/models/guild.ts new file mode 100644 index 0000000..4cfc86d --- /dev/null +++ b/src/database/models/guild.ts @@ -0,0 +1,92 @@ +import * as Sequelize from 'sequelize'; +import { DataTypes, Model, Optional } from 'sequelize'; +import type { ban, banId } from './ban.js'; +import type { guildsettings, guildsettingsId } from './guildsettings.js'; + +export interface guildAttributes { + guildId: string; + enabled: boolean; + banned: boolean; + settingsId: number; +} + +export type guildPk = 'guildId'; +export type guildId = guild[guildPk]; +export type guildOptionalAttributes = 'enabled' | 'banned'; +export type guildCreationAttributes = Optional; + +export class guild extends Model implements guildAttributes { + //? Convert non null assertions to declare to prevent shadowing + declare guildId: string; + declare enabled: boolean; + declare banned: boolean; + declare settingsId: number; + declare createdAt: Date; + declare updatedAt: Date; + + // guild hasMany ban via guildId + declare bans: ban[]; + declare getBans: Sequelize.HasManyGetAssociationsMixin; + declare setBans: Sequelize.HasManySetAssociationsMixin; + declare addBan: Sequelize.HasManyAddAssociationMixin; + declare addBans: Sequelize.HasManyAddAssociationsMixin; + declare createBan: Sequelize.HasManyCreateAssociationMixin; + declare removeBan: Sequelize.HasManyRemoveAssociationMixin; + declare removeBans: Sequelize.HasManyRemoveAssociationsMixin; + declare hasBan: Sequelize.HasManyHasAssociationMixin; + declare hasBans: Sequelize.HasManyHasAssociationsMixin; + declare countBans: Sequelize.HasManyCountAssociationsMixin; + // guild belongsTo guildsettings via settingsId + declare setting: guildsettings; + declare getSetting: Sequelize.BelongsToGetAssociationMixin; + declare setSetting: Sequelize.BelongsToSetAssociationMixin; + declare createSetting: Sequelize.BelongsToCreateAssociationMixin; + + static initModel(sequelize: Sequelize.Sequelize): typeof guild { + return guild.init( + { + guildId: { + type: DataTypes.STRING(30), + allowNull: false, + primaryKey: true + }, + enabled: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, + banned: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, + settingsId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'guildsettings', + key: 'settingsId' + } + } + }, + { + sequelize, + tableName: 'guild', + timestamps: true, + indexes: [ + { + name: 'PRIMARY', + unique: true, + using: 'BTREE', + fields: [{ name: 'guildId' }] + }, + { + name: 'guild_fk_1', + using: 'BTREE', + fields: [{ name: 'settingsId' }] + } + ] + } + ); + } +} diff --git a/src/database/models/guildsettings.ts b/src/database/models/guildsettings.ts new file mode 100644 index 0000000..3cee287 --- /dev/null +++ b/src/database/models/guildsettings.ts @@ -0,0 +1,98 @@ +import * as Sequelize from 'sequelize'; +import { DataTypes, Model, Optional } from 'sequelize'; +import type { guild, guildId } from './guild.js'; + +export interface guildsettingsAttributes { + settingsId: number; + logChannel: string; + staffRole: string; + pointsSystemEnabled: number; + pointsSystemForceReason: number; + pointLifetime: string; +} + +export type guildsettingsPk = 'settingsId'; +export type guildsettingsId = guildsettings[guildsettingsPk]; +export type guildsettingsOptionalAttributes = + | 'settingsId' + | 'pointsSystemEnabled' + | 'pointsSystemForceReason' + | 'pointLifetime'; +export type guildsettingsCreationAttributes = Optional; + +export class guildsettings + extends Model + implements guildsettingsAttributes +{ + //? Convert non null assertions to declare to prevent shadowing + declare settingsId: number; + declare logChannel: string; + declare staffRole: string; + declare pointsSystemEnabled: number; + declare pointsSystemForceReason: number; + declare pointLifetime: string; + declare createdAt: Date; + declare updatedAt: Date; + + // guildsettings hasMany guild via settingsId + declare guilds: guild[]; + declare getGuilds: Sequelize.HasManyGetAssociationsMixin; + declare setGuilds: Sequelize.HasManySetAssociationsMixin; + declare addGuild: Sequelize.HasManyAddAssociationMixin; + declare addGuilds: Sequelize.HasManyAddAssociationsMixin; + declare createGuild: Sequelize.HasManyCreateAssociationMixin; + declare removeGuild: Sequelize.HasManyRemoveAssociationMixin; + declare removeGuilds: Sequelize.HasManyRemoveAssociationsMixin; + declare hasGuild: Sequelize.HasManyHasAssociationMixin; + declare hasGuilds: Sequelize.HasManyHasAssociationsMixin; + declare countGuilds: Sequelize.HasManyCountAssociationsMixin; + + static initModel(sequelize: Sequelize.Sequelize): typeof guildsettings { + return guildsettings.init( + { + settingsId: { + autoIncrement: true, + type: DataTypes.INTEGER, + allowNull: false, + primaryKey: true + }, + logChannel: { + type: DataTypes.STRING(30), + allowNull: false + }, + staffRole: { + type: DataTypes.STRING(30), + allowNull: false + }, + pointsSystemEnabled: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: 0 + }, + pointsSystemForceReason: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: 0 + }, + pointLifetime: { + type: DataTypes.STRING(30), + allowNull: false, + defaultValue: '1210000000' + } + }, + { + sequelize, + tableName: 'guildsettings', + timestamps: true, + indexes: [ + { + name: 'PRIMARY', + unique: true, + using: 'BTREE', + fields: [{ name: 'settingsId' }] + } + ] + } + ); + } +} diff --git a/src/database/models/user.ts b/src/database/models/user.ts new file mode 100644 index 0000000..73f9815 --- /dev/null +++ b/src/database/models/user.ts @@ -0,0 +1,59 @@ +import * as Sequelize from 'sequelize'; +import { DataTypes, Model, Optional } from 'sequelize'; +import { StaffFlagsBitField } from '../../typings/Bitfield.js'; + +export interface userAttributes { + userId: string; + flags: StaffFlagsBitField; +} + +export type userPk = 'userId'; +export type userId = user[userPk]; +export type userOptionalAttributes = 'flags'; +export type userCreationAttributes = Optional; + +export class user extends Model implements userAttributes { + //? Convert non null assertions to declare to prevent shadowing + declare userId: string; + declare flags: StaffFlagsBitField; + declare createdAt: Date; + declare updatedAt: Date; + + static initModel(sequelize: Sequelize.Sequelize): typeof user { + return user.init( + { + userId: { + type: DataTypes.CHAR(30), + allowNull: false, + primaryKey: true + }, + flags: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0, + get() { + const f = BigInt(this.getDataValue('flags') as unknown as number); + return new StaffFlagsBitField(f); + }, + set(val: StaffFlagsBitField) { + // @ts-expect-error Intentional assignment + this.setDataValue('flags', val.bitfield); + } + } + }, + { + sequelize, + tableName: 'user', + timestamps: true, + indexes: [ + { + name: 'PRIMARY', + unique: true, + using: 'BTREE', + fields: [{ name: 'userId' }] + } + ] + } + ); + } +} diff --git a/src/database/models/warn.ts b/src/database/models/warn.ts new file mode 100644 index 0000000..b85d575 --- /dev/null +++ b/src/database/models/warn.ts @@ -0,0 +1,77 @@ +import * as Sequelize from 'sequelize'; +import { DataTypes, Model, Optional } from 'sequelize'; + +export interface warnAttributes { + warnId: number; + guildId: string; + targetId: string; + reason: string; + readonly active: boolean; +} + +export type warnPk = 'warnId'; +export type warnId = warn[warnPk]; +export type warnOptionalAttributes = 'warnId'; +export type warnCreationAttributes = Optional; + +export class warn extends Model implements warnAttributes { + //? Convert non null assertions to declare to prevent shadowing + declare warnId: number; + declare guildId: string; + declare targetId: string; + declare reason: string; + declare readonly active: boolean; + declare createdAt: Date; + declare updatedAt: Date; + declare deletedAt?: Date; + + static initModel(sequelize: Sequelize.Sequelize): typeof warn { + return warn.init( + { + warnId: { + autoIncrement: true, + type: DataTypes.INTEGER, + allowNull: false, + primaryKey: true + }, + guildId: { + type: DataTypes.STRING(30), + allowNull: false + }, + targetId: { + type: DataTypes.STRING(30), + allowNull: false + }, + reason: { + type: DataTypes.TEXT, + allowNull: false + }, + active: { + type: DataTypes.VIRTUAL, + get() { + return !this.isSoftDeleted(); + } + } + }, + { + sequelize, + tableName: 'warn', + timestamps: true, + paranoid: true, + indexes: [ + { + name: 'PRIMARY', + unique: true, + using: 'BTREE', + fields: [{ name: 'warnId' }] + }, + { + name: 'warns_index_1', + using: 'BTREE', + fields: [{ name: 'guildId' }] + } + ] + } + ); + } +} diff --git a/src/functions/STARTUP/dbInit.ts b/src/functions/STARTUP/dbInit.ts new file mode 100644 index 0000000..4ce2dbe --- /dev/null +++ b/src/functions/STARTUP/dbInit.ts @@ -0,0 +1,27 @@ +import { Sequelize } from 'sequelize'; +import { CustomClient } from '../../typings/Extensions.js'; + +export const name = 'database'; +export async function execute(client: CustomClient): Promise { + const { DBdatabase, DBusername, DBpassword, NODE_ENV } = process.env; + // Intentional delay to allow other startup functions to finish + await new Promise((resolve) => setTimeout(resolve, 500)); + // Login to Sequelize + const sequelize = new Sequelize(DBdatabase, DBusername, DBpassword, { + dialect: 'mysql', + logging: NODE_ENV === 'development' ? (sql, timings) => client.logs.debug({ msg: sql, timings }) : false, + benchmark: true + }); + // Load models + const loader = await import('../../typings/Models.js'); + client.models = loader.initModels(sequelize); + await sequelize + .authenticate() + .then(() => sequelize.sync()) + .then(() => client.logs.info(`F | ✓ Database connection established`)) + .catch((err) => client.logs.warn({ msg: `F | ✘ Failed to create database connection`, err })); + // Add Sequelize + client.models = sequelize.models as unknown as ReturnType; + client.sequelize = sequelize; + return; +} diff --git a/src/functions/STARTUP/logs.ts b/src/functions/STARTUP/logs.ts new file mode 100644 index 0000000..cbcce68 --- /dev/null +++ b/src/functions/STARTUP/logs.ts @@ -0,0 +1,27 @@ +import { CustomClient } from '../../typings/Extensions.js'; +import { existsSync, mkdirSync, createWriteStream } from 'node:fs'; +import { stdSerializers, pino } from 'pino'; + +export const name = 'pino'; +export async function execute(client: CustomClient, _ready: boolean): Promise { + // Create logs directory at TLD if it doesn't exist + if (!existsSync('../logs')) mkdirSync('../logs'); + // Overwrite console logger with pino + client.logs = pino( + { + name: 'main', + // Warn if production, trace if development + level: process.env.NODE_ENV === 'development' ? 'trace' : 'warn', + serializers: { + // Default error serializer + err: stdSerializers.err + } + }, + // Create log file + createWriteStream(`../logs/pino-${new Date().getTime()}.log`, { + flags: 'wx' + }) + ); + // Inform user we have switched to pino + console.debug('F | ✦ Pino logger created, using that for logging'); +} diff --git a/src/functions/events/guildRemove/removeBans.ts b/src/functions/events/guildRemove/removeBans.ts new file mode 100644 index 0000000..357d9c5 --- /dev/null +++ b/src/functions/events/guildRemove/removeBans.ts @@ -0,0 +1,19 @@ +import { CustomClient } from '../../../typings/Extensions.js'; + +export const name = 'removeBans'; +export async function execute(client: CustomClient, guildId: string) { + // GDPR, remove all bans from the database + await client.models.ban.destroy({ + where: { + guildId + }, + force: true + }); + // Disable the guild + await client.models.guild.update( + { + enabled: false + }, + { where: { guildId } } + ); +} diff --git a/src/functions/events/interactionCreate/autocomplete.ts b/src/functions/events/interactionCreate/autocomplete.ts new file mode 100644 index 0000000..0edce81 --- /dev/null +++ b/src/functions/events/interactionCreate/autocomplete.ts @@ -0,0 +1,36 @@ +import { ApplicationCommandOptionChoiceData, AutocompleteInteraction } from 'discord.js'; +import { CustomClient } from '../../../typings/Extensions.js'; + +export const name = 'autocomplete'; +export async function execute(client: CustomClient, interaction: AutocompleteInteraction) { + const focus = interaction.options.getFocused(true); + const lowerVal = focus.value.toLowerCase(); + const returnValue: ApplicationCommandOptionChoiceData[] = []; + switch (focus.name) { + case 'server': { + client.guilds.cache + .filter((g) => g.name.toLowerCase().includes(lowerVal)) + .forEach((g) => returnValue.push({ name: g.name, value: g.id })); + break; + } + case 'role': { + const g = interaction.options.getString('server'); + client.guilds.cache + .get(g) + .roles.cache.filter((r) => r.name.toLowerCase().includes(lowerVal)) + .forEach((r) => returnValue.push({ name: r.name, value: r.id })); + break; + } + case 'channel': { + const g = interaction.options.getString('server'); + client.guilds.cache + .get(g) + .channels.cache.filter((c) => c.name.toLowerCase().includes(lowerVal)) + .forEach((c) => returnValue.push({ name: c.name, value: c.id })); + break; + } + } + // Trim to 25 + if (returnValue.length > 25) returnValue.length = 25; + await interaction.respond(returnValue); +} diff --git a/src/functions/events/interactionCreate/command.ts b/src/functions/events/interactionCreate/command.ts new file mode 100644 index 0000000..a79d65c --- /dev/null +++ b/src/functions/events/interactionCreate/command.ts @@ -0,0 +1,34 @@ +import { ChatInputCommandInteraction } from 'discord.js'; +import { CustomClient } from '../../../typings/Extensions.js'; + +export const name = 'command'; +export async function execute(client: CustomClient, interaction: ChatInputCommandInteraction) { + if (!interaction.isChatInputCommand()) return; + // Create name for command + const name = interaction.commandName.replace('d_', ''); + // Get command + const cmd = client.commands.get(name); + if (!cmd) return; + await interaction.deferReply({ ephemeral: cmd.ephemeral || false }); + // Check for ban + const allowedCommands = ['about', 'ping']; + const g = await client.models.guild.findOne({ where: { guildId: interaction.guildId } }); + if (!allowedCommands.includes(name) && g && g.banned === true) { + interaction.editReply({ + embeds: [ + { + color: 0xff0000, + description: 'This server has been banned from using the bot' + } + ] + }); + return; + } + // Run command + try { + cmd.execute({ client, interaction, options: interaction.options }); + } catch (err) { + interaction.editReply({ content: 'Something went wrong while replying! This error has been logged' }); + client.logs.error({ msg: `E | ✘ ${name}`, err }); + } +} diff --git a/src/functions/events/interactionCreate/component.ts b/src/functions/events/interactionCreate/component.ts new file mode 100644 index 0000000..16b34bd --- /dev/null +++ b/src/functions/events/interactionCreate/component.ts @@ -0,0 +1,19 @@ +import { Message, MessageComponentInteraction } from 'discord.js'; +import { CustomClient } from '../../../typings/Extensions.js'; + +function messageEqual(m1: Message, m2: Message) { + return m1.content === m2.content && m1.embeds === m2.embeds && m1.components === m2.components; +} + +export const name = 'component'; +export async function execute(_client: CustomClient, interaction: MessageComponentInteraction) { + // Store the state of message and compare it 1s later + const m = Object.assign({}, interaction.message); + await new Promise((resolve) => setTimeout(resolve, 2000)); + if (!messageEqual(m, interaction.message)) return; + // Remove components and mark expired + interaction.update({ + components: [], + content: `This embed has timed out. Please run the command again` + }); +} diff --git a/src/functions/events/interactionCreate/main.ts b/src/functions/events/interactionCreate/main.ts new file mode 100644 index 0000000..ebd330e --- /dev/null +++ b/src/functions/events/interactionCreate/main.ts @@ -0,0 +1,34 @@ +import { Interaction, InteractionType } from 'discord.js'; +import { CustomClient } from '../../../typings/Extensions.js'; + +export const name = 'main'; +export async function execute(client: CustomClient, interaction: Interaction): Promise { + // Avoid running commands before the bot is ready + if (!client.ready && interaction.isCommand()) { + interaction.reply({ + content: 'The bot is still starting up. Please wait a few seconds and try again.', + ephemeral: true + }); + } else if (!client.ready) { + return; + } + // Get the interaction function + let func: string; + switch (interaction.type) { + case InteractionType.ApplicationCommand: { + func = 'command'; + break; + } + case InteractionType.MessageComponent: { + func = 'component'; + break; + } + case InteractionType.ApplicationCommandAutocomplete: { + func = 'autocomplete'; + break; + } + } + // Run all interaction functions + client.functions.get(`events_interactionCreate_${func}`).execute(client, interaction); + return; +} diff --git a/src/functions/events/ready/commands.ts b/src/functions/events/ready/commands.ts new file mode 100644 index 0000000..906f5d2 --- /dev/null +++ b/src/functions/events/ready/commands.ts @@ -0,0 +1,53 @@ +import { SlashCommandBuilder } from 'discord.js'; +import { readdirSync } from 'node:fs'; +import { CommandFile, CustomClient } from '../../../typings/Extensions.js'; + +export const name = 'commands'; +export async function execute(client: CustomClient): Promise { + const { NODE_ENV, devGuild } = process.env; + // Get all files in the commands directory + const files = readdirSync('./commands', { recursive: true }) + // Map Buffers to string + .map((f) => String(f)) + // Trim directory + .map((f) => f.replace('./commands/', '')) + // Remove Windows backslashes + .map((f) => f.replace('\\', '/')) + // Filter out non-JS files + .filter((f) => f.endsWith('.js')); + // For each file, load the command + const cmds: ReturnType[] = []; + client.logs.debug(`F | ✦ Expecting ${files.length} command files`); + // Initially use the raw filename + for (let name of files) { + try { + const command: CommandFile = await import(`../../../commands/${name}`); + // Rewrite cmd name if development + if (command.data && NODE_ENV === 'development') command.data.setName(`d_${command.data.name}`); + // If the command has data, use that and push data + if (command.data) { + name = command.data.name; + cmds.push(command.data.toJSON()); + } + // Reassign to function-friendly name + name = name.replace(/\.js$/, '').replace(/\//g, '_'); + client.commands.set(name, command); + client.logs.info(`F | ✓ ${name}`); + } catch (err) { + client.logs.error({ msg: `F | ✘ ${name}`, err }); + } + } + // Register the commands + if (NODE_ENV === 'development') { + // Testing server if development + client.guilds + .fetch(devGuild) + .then((g) => g.commands.set(cmds)) + .catch(() => null); + } else { + // Global if production + await client.application.commands.set(cmds); + } + client.logs.debug(`F | ✦ Registered ${cmds.length} commands`); + return; +} diff --git a/src/functions/load.ts b/src/functions/load.ts new file mode 100644 index 0000000..fc15964 --- /dev/null +++ b/src/functions/load.ts @@ -0,0 +1,43 @@ +import { existsSync, readdirSync } from 'node:fs'; +import { CustomClient, FunctionFile } from '../typings/Extensions.js'; + +export const name = 'load'; +// This loads all functions +export async function execute(client: CustomClient): Promise> { + // Check for functions folder + if (!existsSync('./functions')) { + console.warn('F | ! No functions were found! Make sure you are running index.js from the dist directory'); + return new Map() as Map; + } + client.logs.debug('F | ✦ Loading all functions'); + // Read the directory + const functionFiles: string[] = readdirSync(`./functions`, { recursive: true }) + // Ensure all file names are strings + .map((f: unknown) => String(f)) + // Trim directory + .map((f: string) => f.replace(`./functions/`, '')) + // Remove Windows backslashes + .map((f: string) => f.replace(/\\/g, '/')) + // Filter out non-JS files + .filter((f: string) => f.endsWith('.js')); + // Load the functions + client.logs.debug(`F | ✦ Found ${functionFiles.length} function`); + // Initialise variables + // deepcode ignore CollectionUpdatedButNeverQueried: Used in return + const functions = new Map(); + for (const file of functionFiles) { + // Set the file + try { + const func: FunctionFile = await import(`../functions/${file}`); + const name = file.replace(/\.js$/, '').replace(/\//g, '_'); + // Skip if it's an archive + if (name.includes('archive_')) continue; + functions.set(name, func); + client.logs.debug(`F | ✓ ${name}`); + } catch (err) { + client.logs.error({ msg: `F | ✗ ${file}`, err }); + } + } + // Return values + return functions; +} diff --git a/src/functions/utils/guildAuth.ts b/src/functions/utils/guildAuth.ts new file mode 100644 index 0000000..49e6ee6 --- /dev/null +++ b/src/functions/utils/guildAuth.ts @@ -0,0 +1,16 @@ +import { GuildMember } from 'discord.js'; +import { CustomClient } from '../../typings/Extensions.js'; + +export const name = 'guildAuth'; +export async function execute(client: CustomClient, member: GuildMember): Promise { + // Find DB entry + const dbGuild = await client.models.guild.findOne({ + where: { guildId: member.guild.id } + }); + if (!dbGuild) return false; + // Get settings + const settings = await dbGuild.getSetting(); + if (!settings) return false; + // Return whether they have the role or not + return member.roles.cache.has(settings.staffRole); +} diff --git a/src/functions/utils/masterMessage.ts b/src/functions/utils/masterMessage.ts new file mode 100644 index 0000000..8e17579 --- /dev/null +++ b/src/functions/utils/masterMessage.ts @@ -0,0 +1,68 @@ +import { ChannelType, Collection, EmbedBuilder, Guild, Webhook } from 'discord.js'; +import { readFileSync } from 'node:fs'; +import { BroadcastType, CustomClient } from '../../typings/Extensions.js'; + +export const name = 'masterMessage'; +export async function execute( + client: CustomClient, + type: BroadcastType, + msg: string, + targetUser?: string +): Promise { + const embed = new EmbedBuilder().setDescription(msg).setColor(type); + switch (type) { + case BroadcastType.Broadcast: + embed.setTitle('Maintainer Broadcast'); + break; + case BroadcastType.UserBanned: + embed.setTitle('User in This Server Banned'); + break; + case BroadcastType.UserWarned: + embed.setTitle('User in This Server Warned'); + break; + case BroadcastType.Maintenance: + embed.setTitle('Maintenance Notice'); + break; + case BroadcastType.SecurityAlert: + embed.setTitle('** Security Alert **'); + break; + case BroadcastType.Other: + embed.setTitle('General Notice'); + break; + } + const servers: Guild[] = []; + if (type === BroadcastType.UserBanned || type === BroadcastType.UserWarned) { + // Find affected guilds + client.guilds.cache.each((g) => + g.members + .fetch(targetUser) + .then(() => servers.push(g)) + .catch(() => undefined) + ); + } else { + // Send to all servers + client.guilds.cache.each((g) => servers.push(g)); + } + servers.forEach(async (g) => { + // Check guilds for active status and send to participating ones + const s = await client.models.guild.findOne({ + where: { guildId: g.id }, + include: [{ model: client.models.guildsettings, as: 'setting' }] + }); + if (!s || !s.enabled) return; // The server's not participating or inactive + // Find channel and grab webhooks + const c = await client.channels.fetch(s.setting.logChannel); + if (!c || c.type !== ChannelType.GuildText) return; // Invalid channel + const webhooks = await c + .fetchWebhooks() + .then((w) => w.filter((w) => w.applicationId === client.application.id)) + .catch(() => new Collection()); + // Use the first webhook or create one + const hook = + webhooks.size > 1 + ? (webhooks.first() as Webhook | Record) + : await c.createWebhook({ name: 'Agent Black', avatar: readFileSync('../assets/agentBlack.jpg') }); + // Send message + hook.send({ embeds: [embed] }); + }); +} diff --git a/src/functions/utils/pagination.ts b/src/functions/utils/pagination.ts new file mode 100644 index 0000000..b45c418 --- /dev/null +++ b/src/functions/utils/pagination.ts @@ -0,0 +1,124 @@ +import { + ActionRowBuilder, + ButtonBuilder, + ButtonInteraction, + ButtonStyle, + ChatInputCommandInteraction, + EmbedBuilder, + SelectMenuComponentOptionData, + StringSelectMenuBuilder, + StringSelectMenuInteraction +} from 'discord.js'; +import { CustomClient } from '../../typings/Extensions.js'; + +export const name = 'pagination'; +export async function execute( + _client: CustomClient, + interaction: ChatInputCommandInteraction, + categories: { [key: string]: EmbedBuilder[] }, + options: SelectMenuComponentOptionData[] +): Promise { + /** @desc Current category's embeds */ + let embeds: EmbedBuilder[] = []; + /** @desc Current page index */ + let page = 0; + options.push({ + label: 'Cancel', + value: 'cancel', + description: 'Cancel the command', + emoji: '❌' + }); + const selectorRow: ActionRowBuilder = new ActionRowBuilder({ + components: [ + new StringSelectMenuBuilder({ + customId: 'profile-category', + placeholder: 'Select a category to review', + options, + min_values: 1, + max_values: 1 + }) + ] + }); + const paginationRow: ActionRowBuilder = new ActionRowBuilder({ + components: [ + new ButtonBuilder({ customId: 'previous', label: '◀️', style: ButtonStyle.Primary }), + new ButtonBuilder({ customId: 'cancel', label: '🟥', style: ButtonStyle.Danger }), + new ButtonBuilder({ customId: 'next', label: '▶️', style: ButtonStyle.Primary }) + ] + }); + + //#region Pagination + const coll = await interaction + .editReply({ embeds: [categories.overview[0]], components: [selectorRow] }) + .then((m) => m.createMessageComponentCollector({ filter: (i) => i.user.id === interaction.user.id, time: 180_000 })) + .catch(() => null); + + if (!coll) { + interaction.editReply({ content: 'Something went wrong. Please try again later.', components: [] }); + return; + } + coll.on('collect', (i: ButtonInteraction | StringSelectMenuInteraction) => { + const selectors: ActionRowBuilder[] = [selectorRow]; + // If they select the menu, switch category + if (i.isStringSelectMenu()) { + // If they cancel, stop the collector + if (i.values[0] === 'cancel') return coll.stop(); + // Get the category + embeds = categories[i.values[0]]; + // New category, so page #0 + page = 0; + // If the length is greater than 2, add pagination row + if (embeds.length > 1) selectors.unshift(paginationRow); + // Update the message + i.update({ embeds: [embeds[page]], components: selectors }); + return; + } + // Pagination row + switch (i.customId) { + // Cancel + case 'cancel': { + coll.stop(); + break; + } + // Previous + case 'previous': { + page = page - 1; + // If the page is less than 0, set it to the last page + if (page < 0) page = embeds.length - 1; + // If the length is greater than the length, add pagination row + if (embeds.length > 1) selectors.unshift(paginationRow); + // Update the message + i.update({ embeds: [embeds[page]], components: selectors }); + break; + } + // Next + case 'next': { + page = page + 1; + // If the page is greater than the length, set it to the first page + if (page > embeds.length - 1) page = 0; + // If the length is greater than 2, add pagination row + if (embeds.length > 1) selectors.unshift(paginationRow); + // Update the message + i.update({ embeds: [embeds[page]], components: selectors }); + break; + } + // Theoretically impossible to reach + default: { + i.update({ + content: "You shouldn't be seeing this! Report this to an Engineer\n\n**CUSTOMID**: " + i.customId, + embeds: [], + components: [] + }); + } + } + }); + coll.on('end', () => { + interaction + .editReply({ + content: `This embed has timed out. Please run the command again: `, + components: [] + }) + .catch(() => null); + }); + //#endregion +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..5990cb6 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,46 @@ +//#region Packages +import { Client, Collection, IntentsBitField } from 'discord.js'; +import { CustomClient } from './typings/Extensions.js'; +// Log developer mode +if (process.env.NODE_ENV === 'development') console.debug('Starting in development mode'); +//#endregion + +//#region Discord init +const client: CustomClient = new Client({ + intents: [ + IntentsBitField.Flags.Guilds, + IntentsBitField.Flags.GuildMembers, + IntentsBitField.Flags.GuildModeration, + IntentsBitField.Flags.GuildEmojisAndStickers, + IntentsBitField.Flags.GuildMessages, + IntentsBitField.Flags.DirectMessages + ] +}); +client.logs = console; +// Load all functions +const funcs = await import('./functions/load.js').then((f) => f.execute(client)).catch((e) => client.logs.error(e)); +if (!funcs) process.exit(1); +client.functions = funcs; +// Run all startup functions +Array.from(client.functions.keys()) + .filter((f) => f.startsWith('startup_')) + .forEach((f) => client.functions.get(f).execute(client)); +//#endregion +//#region Variables +client.commands = new Collection(); +//#endregion +//#region Discord events +client.on('ready', () => { + client.logs.info(`Logged in as ${client.user.tag}!`); + // Run all ready functions + Array.from(client.functions.keys()) + .filter((f) => f.startsWith('events_ready')) + .forEach((f) => client.functions.get(f).execute(client)); +}); + +client.on('interactionCreate', async (interaction) => { + client.functions.get('events_interactionCreate_main').execute(client, interaction); +}); + +client.login(process.env.DCtoken); +//#endregion diff --git a/src/typings/Bitfield.d.ts b/src/typings/Bitfield.d.ts new file mode 100644 index 0000000..aa78746 --- /dev/null +++ b/src/typings/Bitfield.d.ts @@ -0,0 +1,36 @@ +import { BitFieldResolvable } from 'discord.js'; +import { StaffFlags } from './StaffFlags'; + +export class BitField { + public constructor(bits?: BitFieldResolvable); + public bitfield: N; + public add(...bits: BitFieldResolvable[]): BitField; + public any(bit: BitFieldResolvable): boolean; + public equals(bit: BitFieldResolvable): boolean; + public freeze(): Readonly>; + public has(bit: BitFieldResolvable): boolean; + public missing(bits: BitFieldResolvable, ...hasParams: readonly unknown[]): S[]; + public remove(...bits: BitFieldResolvable[]): BitField; + public serialize(...hasParams: readonly unknown[]): Record; + public toArray(...hasParams: readonly unknown[]): S[]; + public toJSON(): N extends number ? number : string; + public valueOf(): N; + public [Symbol.iterator](): IterableIterator; + public static Flags: EnumLike; + public static resolve(bit?: BitFieldResolvable): number | bigint; +} +export type StaffFlagsString = keyof typeof StaffFlags; +export type StaffFlagResolvable = BitFieldResolvable; +export class StaffFlagsBitField extends BitField { + public any(StaffFlag: StaffFlagResolvable, checkAdmin?: boolean): boolean; + public has(StaffFlag: StaffFlagResolvable, checkAdmin?: boolean): boolean; + public missing(bits: BitFieldResolvable, checkAdmin?: boolean): StaffFlagsString[]; + public serialize(checkAdmin?: boolean): Record; + public toArray(): StaffFlagsString[]; + + public static All: bigint; + public static Default: bigint; + public static StageModerator: bigint; + public static Flags: typeof StaffFlagBits; + public static resolve(StaffFlag?: StaffFlagResolvable): bigint; +} diff --git a/src/typings/Bitfield.js b/src/typings/Bitfield.js new file mode 100644 index 0000000..2e68651 --- /dev/null +++ b/src/typings/Bitfield.js @@ -0,0 +1,250 @@ +import { DiscordjsErrorCodes, DiscordjsRangeError } from 'discord.js'; +import { StaffFlags } from './StaffFlags.js'; + +/** + * Data structure that makes it easy to interact with a bitfield. + */ +class BitField { + /** + * Numeric bitfield flags. + * Defined in extension classes + * @type {Object} + * @memberof BitField + * @abstract + */ + static Flags = {}; + + /** + * @type {number|bigint} + * @memberof BitField + * @private + */ + static DefaultBit = 0; + + /** + * @param {BitFieldResolvable} [bits=this.constructor.DefaultBit] Bit(s) to read from + */ + constructor(bits = this.constructor.DefaultBit) { + /** + * Bitfield of the packed bits + * @type {number|bigint} + */ + this.bitfield = this.constructor.resolve(bits); + } + + /** + * Checks whether the bitfield has a bit, or any of multiple bits. + * @param {BitFieldResolvable} bit Bit(s) to check for + * @returns {boolean} + */ + any(bit) { + return (this.bitfield & this.constructor.resolve(bit)) !== this.constructor.DefaultBit; + } + + /** + * Checks if this bitfield equals another + * @param {BitFieldResolvable} bit Bit(s) to check for + * @returns {boolean} + */ + equals(bit) { + return this.bitfield === this.constructor.resolve(bit); + } + + /** + * Checks whether the bitfield has a bit, or multiple bits. + * @param {BitFieldResolvable} bit Bit(s) to check for + * @returns {boolean} + */ + has(bit) { + bit = this.constructor.resolve(bit); + return (this.bitfield & bit) === bit; + } + + /** + * Gets all given bits that are missing from the bitfield. + * @param {BitFieldResolvable} bits Bit(s) to check for + * @param {...*} hasParams Additional parameters for the has method, if any + * @returns {string[]} + */ + missing(bits, ...hasParams) { + return new this.constructor(bits).remove(this).toArray(...hasParams); + } + + /** + * Freezes these bits, making them immutable. + * @returns {Readonly} + */ + freeze() { + return Object.freeze(this); + } + + /** + * Adds bits to these ones. + * @param {...BitFieldResolvable} [bits] Bits to add + * @returns {BitField} These bits or new BitField if the instance is frozen. + */ + add(...bits) { + let total = this.constructor.DefaultBit; + for (const bit of bits) { + total |= this.constructor.resolve(bit); + } + if (Object.isFrozen(this)) return new this.constructor(this.bitfield | total); + this.bitfield |= total; + return this; + } + + /** + * Removes bits from these. + * @param {...BitFieldResolvable} [bits] Bits to remove + * @returns {BitField} These bits or new BitField if the instance is frozen. + */ + remove(...bits) { + let total = this.constructor.DefaultBit; + for (const bit of bits) { + total |= this.constructor.resolve(bit); + } + if (Object.isFrozen(this)) return new this.constructor(this.bitfield & ~total); + this.bitfield &= ~total; + return this; + } + + /** + * Gets an object mapping field names to a {@link boolean} indicating whether the + * bit is available. + * @param {...*} hasParams Additional parameters for the has method, if any + * @returns {Object} + */ + serialize(...hasParams) { + const serialized = {}; + for (const [flag, bit] of Object.entries(this.constructor.Flags)) { + if (isNaN(flag)) serialized[flag] = this.has(bit, ...hasParams); + } + return serialized; + } + + /** + * Gets an {@link Array} of bitfield names based on the bits available. + * @param {...*} hasParams Additional parameters for the has method, if any + * @returns {string[]} + */ + toArray(...hasParams) { + return [...this[Symbol.iterator](...hasParams)]; + } + + toJSON() { + return typeof this.bitfield === 'number' ? this.bitfield : this.bitfield.toString(); + } + + valueOf() { + return this.bitfield; + } + + *[Symbol.iterator](...hasParams) { + for (const bitName of Object.keys(this.constructor.Flags)) { + if (isNaN(bitName) && this.has(bitName, ...hasParams)) yield bitName; + } + } + + /** + * Data that can be resolved to give a bitfield. This can be: + * * A bit number (this can be a number literal or a value taken from {@link BitField.Flags}) + * * A string bit number + * * An instance of BitField + * * An Array of BitFieldResolvable + * @typedef {number|string|bigint|BitField|BitFieldResolvable[]} BitFieldResolvable + */ + + /** + * Resolves bitfields to their numeric form. + * @param {BitFieldResolvable} [bit] bit(s) to resolve + * @returns {number|bigint} + */ + static resolve(bit) { + const { DefaultBit } = this; + if (typeof DefaultBit === typeof bit && bit >= DefaultBit) return bit; + if (bit instanceof BitField) return bit.bitfield; + if (Array.isArray(bit)) return bit.map((p) => this.resolve(p)).reduce((prev, p) => prev | p, DefaultBit); + if (typeof bit === 'string') { + if (!isNaN(bit)) return typeof DefaultBit === 'bigint' ? BigInt(bit) : Number(bit); + if (this.Flags[bit] !== undefined) return this.Flags[bit]; + } + throw new DiscordjsRangeError(DiscordjsErrorCodes.BitFieldInvalid, bit); + } +} + +/** + * Data structure that makes it easy to interact with a user flag bitfield. + * @extends {BitField} + */ +export class StaffFlagsBitField extends BitField { + /** + * Numeric user flags. + * @memberof StaffFlagsBitField + */ + static Flags = StaffFlags; + + /** + * Bitfield representing every flag combined + * @type {bigint} + * @memberof StaffFlagsBitField + */ + static All = Object.values(this.Flags).reduce((all, p) => all | p, 0n); + + /** + * Bitfield representing the default user flags for staff members + * @type {bigint} + * @memberof StaffFlagsBitField + */ + static Default = BigInt(0); + + /** + * @type {bigint} + * @memberof StaffFlagsBitField + * @private + */ + static DefaultBit = BigInt(0); + + /** + * Bitfield of the packed bits + * @type {bigint} + * @name StaffFlagsBitField#bitfield + */ + + /** + * Gets all given bits that are missing from the bitfield. + * @param {BitFieldResolvable[]} bits Bit(s) to check for + * @param {boolean} [checkAdmin=true] Whether to allow the maintainer flag to override + * @returns {string[]} + */ + missing(bits, checkAdmin = true) { + return checkAdmin && super.has(StaffFlags.Owner) ? [] : super.missing(bits, null); + } + + /** + * Checks whether the bitfield has a flag, or any of multiple flags. + * @param {BitFieldResolvable} flag Flag(s) to check for + * @param {boolean} [checkAdmin=true] Whether to allow the maintainer flag to override + * @returns {boolean} + */ + any(flag, checkAdmin = true) { + return (checkAdmin && super.has(StaffFlags.Owner)) || super.any(flag); + } + + /** + * Checks whether the bitfield has a flag, or multiple flags. + * @param {BitFieldResolvable} flag Flag(s) to check for + * @param {boolean} [checkAdmin=true] Whether to allow the maintainer flag to override + * @returns {boolean} + */ + has(flag, checkAdmin = true) { + return (checkAdmin && super.has(StaffFlags.Owner)) || super.has(flag); + } + + /** + * Gets an {@link Array} of bitfield names based on the flags available. + * @returns {string[]} + */ + toArray() { + return super.toArray(false); + } +} diff --git a/src/typings/Extensions.ts b/src/typings/Extensions.ts new file mode 100644 index 0000000..ed42b7d --- /dev/null +++ b/src/typings/Extensions.ts @@ -0,0 +1,71 @@ +import { ChatInputCommandInteraction, Client, SlashCommandBuilder } from 'discord.js'; +import { Logger } from 'pino'; +import { Sequelize } from 'sequelize'; +import { initModels } from './Models.js'; + +export interface CustomClient extends Client { + /** @desc Commands for the bot to handle */ + commands?: Map; + /** @desc Functions dynamically imported */ + functions?: Map; + /** @desc Sequelize instance */ + sequelize?: Sequelize; + /** @desc Sequelize models for the database */ + models?: ReturnType; + /** @desc Whether the bot is ready to accept commands */ + ready?: boolean; + /** @desc Logging ({@link Ready} determines type: true is {@link Logger}, false is {@link Console}) */ + logs?: Ready extends true ? Logger : Console; +} +// Various types of file that will be imported +export interface CommandFile { + name?: string; + ephemeral?: boolean; + data?: SlashCommandBuilder; + execute: ({ client, interaction, options }: CmdFileArgs) => Promise; +} +export interface FunctionFile { + name: string; + execute: (client: CustomClient, ...args: unknown[]) => Promise; +} + +export enum FlagEmoji { + ActiveDeveloper = '<:DB_ActiveDeveloper:1118377588063227964>', + BugHunterLevel1 = '<:DB_BugHunterL1:1118377590521081908>', + BugHunterLevel2 = '<:DB_BugHunterL2:1118377591754194988>', + CertifiedModerator = '<:DB_ModeratorProgramAlumni:1118377602671972424>', + Hypesquad = '<:DB_HypesquadEvents:1118377600876822590>', + HypeSquadOnlineHouse1 = '<:DB_HypesquadBravery:1118377597823365191>', + HypeSquadOnlineHouse2 = '<:DB_HypesquadBrilliance:1118377599702401126>', + HypeSquadOnlineHouse3 = '<:DB_HypesquadBalance:1118377596640567366>', + Nitro = '<:DB_Nitro:1118377784310509578>', + Quarantined = '<:DB_Quarantine:1118377861984813177>', + Spammer = '<:DB_Spammer:1118377609030533160>', + Staff = '<:DB_Staff:1118377789716955176>', + Partner = '<:DB_Partner:1118377786478960711>', + Pomelo = '<:DB_Pomelo:1118377605935140934>', + PremiumEarlySupporter = '<:DB_EarlySupporter:1118377593176076378>', + VerifiedBot = '<:DB_VerifiedBot:1118377792652980224>', + VerifiedDeveloper = '<:DB_VerifiedDeveloper:1118377595277418576>' +} +/** @desc Messages to be sent to the masterMessage function */ +export enum BroadcastType { + /** @desc Broadcast from Maintainer+ */ + Broadcast = 0x6699ff, + /** @desc User banned alert */ + UserBanned = 0xff0000, + /** @desc User warned alert */ + UserWarned = 0xff9933, + /** @desc Maintenance warning */ + Maintenance = 0x77b300, + /** @desc Security alert */ + SecurityAlert = 0xff00ff, + /** @desc Other - All servers */ + Other = 0xffffff +} + +export type CmdFileArgs = { + client: CustomClient; + interaction: ChatInputCommandInteraction; + options: ChatInputCommandInteraction['options']; +}; diff --git a/src/typings/Models.ts b/src/typings/Models.ts new file mode 100644 index 0000000..3df5054 --- /dev/null +++ b/src/typings/Models.ts @@ -0,0 +1,53 @@ +import type { Sequelize } from 'sequelize'; +import type { aliasAttributes, aliasCreationAttributes } from '../database/models/alias.js'; +import { alias as _alias } from '../database/models/alias.js'; +import type { banAttributes, banCreationAttributes } from '../database/models/ban.js'; +import { ban as _ban } from '../database/models/ban.js'; +import type { guildAttributes, guildCreationAttributes } from '../database/models/guild.js'; +import { guild as _guild } from '../database/models/guild.js'; +import type { guildsettingsAttributes, guildsettingsCreationAttributes } from '../database/models/guildsettings.js'; +import { guildsettings as _guildsettings } from '../database/models/guildsettings.js'; +import type { userAttributes, userCreationAttributes } from '../database/models/user.js'; +import { user as _user } from '../database/models/user.js'; +import type { warnAttributes, warnCreationAttributes } from '../database/models/warn.js'; +import { warn as _warn } from '../database/models/warn.js'; + +export { _alias as alias, _ban as ban, _guild as guild, _guildsettings as guildsettings, _user as user, _warn as warn }; + +export type { + aliasAttributes, + aliasCreationAttributes, + banAttributes, + banCreationAttributes, + guildAttributes, + guildCreationAttributes, + guildsettingsAttributes, + guildsettingsCreationAttributes, + userAttributes, + userCreationAttributes, + warnAttributes, + warnCreationAttributes +}; + +export function initModels(sequelize: Sequelize) { + const alias = _alias.initModel(sequelize); + const ban = _ban.initModel(sequelize); + const guild = _guild.initModel(sequelize); + const guildsettings = _guildsettings.initModel(sequelize); + const user = _user.initModel(sequelize); + const warn = _warn.initModel(sequelize); + + ban.belongsTo(guild, { as: 'guild', foreignKey: 'guildId' }); + guild.hasMany(ban, { as: 'bans', foreignKey: 'guildId' }); + guild.belongsTo(guildsettings, { as: 'setting', foreignKey: 'settingsId' }); + guildsettings.hasMany(guild, { as: 'guilds', foreignKey: 'settingsId' }); + + return { + alias: alias, + ban: ban, + guild: guild, + guildsettings: guildsettings, + user: user, + warn: warn + }; +} diff --git a/src/typings/StaffFlags.ts b/src/typings/StaffFlags.ts new file mode 100644 index 0000000..df62f5d --- /dev/null +++ b/src/typings/StaffFlags.ts @@ -0,0 +1,26 @@ +/** + * Types adapted from discord.js's UserFlags class + * @link {https://github.com/discordjs/discord-api-types/blob/052ceb2d02da4f71cf619511a3eb47b1844237fe/payloads/v10/user.ts} + */ + +/** + * User flags + */ +const StaffFlags = { + // -- GLOBAL ROLES -- // + + /** + * Owner + */ + Owner: BigInt(1 << 0), + /** + * Maintainer + */ + Maintainer: BigInt(1 << 1), + /** + * Moderator + */ + Moderator: BigInt(1 << 2) +} as const; + +export { StaffFlags }; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..9e733ce --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + // Module resolution + "target": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "resolveJsonModule": true, + "newLine": "LF", + // Setup project files + "rootDir": "src", + "outDir": "dist", + "allowJs": true, + // Skip checking of library files + "skipLibCheck": true + }, + // Ignores + "exclude": ["node_modules", "dist", "assets"], + "watchOptions": { + "excludeDirectories": ["**/node_modules", "dist", "assets"] + } +}