From b4cec6778d384f73620cebbf0f4e7316fa6cd3d3 Mon Sep 17 00:00:00 2001 From: Vylpes Date: Tue, 10 May 2022 18:15:40 +0100 Subject: [PATCH 01/56] Change lobby command to error upon making a duplicate lobby channel (#154) --- .env.template | 4 ++-- src/commands/501231711271780357/lobby.ts | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.env.template b/.env.template index 33148ee..8933949 100644 --- a/.env.template +++ b/.env.template @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=3.0.1 +BOT_VER=3.0.2 BOT_AUTHOR=Vylpes -BOT_DATE=24 Apr 2022 +BOT_DATE=09 May 2022 BOT_OWNERID=147392775707426816 \ No newline at end of file diff --git a/src/commands/501231711271780357/lobby.ts b/src/commands/501231711271780357/lobby.ts index 6d3a58c..58793bf 100644 --- a/src/commands/501231711271780357/lobby.ts +++ b/src/commands/501231711271780357/lobby.ts @@ -116,6 +116,15 @@ export default class Lobby extends Command { return; } + const lobby = await eLobby.FetchOneByChannelId(channel.id); + + if (lobby) { + const errorEmbed = new ErrorEmbed(context, "This channel has already been setup."); + errorEmbed.SendToCurrentChannel(); + + return; + } + const entity = new eLobby(channel.id, role.id, cooldown, gameName); await entity.Save(eLobby, entity); From 861676ed0ba8323d6a15ef1ce28122a2d554ebcb Mon Sep 17 00:00:00 2001 From: Vylpes Date: Wed, 11 May 2022 17:26:50 +0100 Subject: [PATCH 02/56] Update lobby command to give proper errors if role or channel id cannot be found (#156) --- src/commands/501231711271780357/lobby.ts | 31 +++++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/commands/501231711271780357/lobby.ts b/src/commands/501231711271780357/lobby.ts index 58793bf..4d0bcfc 100644 --- a/src/commands/501231711271780357/lobby.ts +++ b/src/commands/501231711271780357/lobby.ts @@ -111,8 +111,17 @@ export default class Lobby extends Command { const cooldown = Number(context.args[4]) || 30; const gameName = context.args.splice(5).join(" "); - if (!channel || !role) { - this.SendConfigHelp(context); + if (!channel) { + const errorEmbed = new ErrorEmbed(context, "The channel id you provided is invalid or channel does not exist."); + errorEmbed.SendToCurrentChannel(); + + return; + } + + if (!role) { + const errorEmbed = new ErrorEmbed(context, "The role id you provided is invalid or role does not exist."); + errorEmbed.SendToCurrentChannel(); + return; } @@ -133,20 +142,18 @@ export default class Lobby extends Command { } private async RemoveLobbyConfig(context: ICommandContext) { - const channel = context.message.guild!.channels.cache.find(x => x.id == context.args[2]); + const entity = await eLobby.FetchOneByChannelId(context.args[2]); + + if (!entity) { + const errorEmbed = new ErrorEmbed(context, "The channel id you provided has not been setup as a lobby, unable to remove."); + errorEmbed.SendToCurrentChannel(); - if (!channel) { - this.SendConfigHelp(context); return; } + + await BaseEntity.Remove(eLobby, entity); - const entity = await eLobby.FetchOneByChannelId(channel.id); - - if (entity) { - await BaseEntity.Remove(eLobby, entity); - } - - const embed = new PublicEmbed(context, "", `Removed \`${channel.name}\` from the list of lobby channels`); + const embed = new PublicEmbed(context, "", `Removed <#${context.args[2]}> from the list of lobby channels`); embed.SendToCurrentChannel(); } } \ No newline at end of file From 6522bee37b814cb4c096be56ba765e7d8955314a Mon Sep 17 00:00:00 2001 From: Vylpes Date: Thu, 12 May 2022 18:04:34 +0100 Subject: [PATCH 03/56] Add bunny command back (#157) --- src/commands/bunny.ts | 29 +++++++++++++++++++++++++++++ src/registry.ts | 2 ++ 2 files changed, 31 insertions(+) create mode 100644 src/commands/bunny.ts diff --git a/src/commands/bunny.ts b/src/commands/bunny.ts new file mode 100644 index 0000000..758df44 --- /dev/null +++ b/src/commands/bunny.ts @@ -0,0 +1,29 @@ +import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; +import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import { Command } from "../type/command"; +import { ICommandContext } from "../contracts/ICommandContext"; +import randomBunny from "random-bunny"; + +export default class Bunny extends Command { + constructor() { + super(); + + super.Category = "Fun"; + } + + public override async execute(context: ICommandContext) { + const result = await randomBunny('rabbits', 'hot'); + + if (result.IsSuccess) { + const embed = new PublicEmbed(context, result.Result!.Title, "") + .setImage(result.Result!.Url) + .setURL(`https://reddit.com${result.Result!.Permalink}`) + .setFooter({ text: `r/Rabbits ยท ${result.Result!.Ups} upvotes` }); + + embed.SendToCurrentChannel(); + } else { + const errorEmbed = new ErrorEmbed(context, "There was an error using this command."); + errorEmbed.SendToCurrentChannel(); + } + } +} \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index 19a673a..9d073b1 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -24,11 +24,13 @@ import Lobby from "./commands/501231711271780357/lobby"; // Event Imports import MemberEvents from "./events/MemberEvents"; import MessageEvents from "./events/MessageEvents"; +import Bunny from "./commands/bunny"; export default class Registry { public static RegisterCommands() { CoreClient.RegisterCommand("about", new About()); CoreClient.RegisterCommand("ban", new Ban()); + CoreClient.RegisterCommand("bunny", new Bunny()); CoreClient.RegisterCommand("clear", new Clear()); CoreClient.RegisterCommand("help", new Help()); CoreClient.RegisterCommand("kick", new Kick()); From 514be692fdda70e4401667b991e7198512e51660 Mon Sep 17 00:00:00 2001 From: Vylpes Date: Sat, 14 May 2022 14:59:32 +0100 Subject: [PATCH 04/56] 150 assignable roles should be its own table to prevent limitations on length (#158) * Add entity * Update role config command to use new entity * Update role command to use new entity * Remove legacy code from config command --- data/usage/config.txt | 1 - package.json | 4 +- src/commands/role.ts | 91 ++++++++++++++--------- src/entity/Role.ts | 44 +++++++++++ src/entity/Server.ts | 10 ++- src/migration/1652375907691-CreateRole.ts | 13 ++++ 6 files changed, 126 insertions(+), 37 deletions(-) create mode 100644 src/entity/Role.ts create mode 100644 src/migration/1652375907691-CreateRole.ts diff --git a/data/usage/config.txt b/data/usage/config.txt index ffbcf1b..f284c78 100644 --- a/data/usage/config.txt +++ b/data/usage/config.txt @@ -5,7 +5,6 @@ bot.prefix: The bot prefix for the server (Default: "v!") commands.disabled: Disabled commands, separated by commas (Default: "") -role.assignable: List of roles assignable to user, separated by commas (Default: "") role.moderator: The moderator role name (Default: "Moderator") role.administrator: The administrator role name (Default: "Administrator") role.muted: The muted role name (Default: "Muted") diff --git a/package.json b/package.json index ce8b454..e4416f2 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,9 @@ "scripts": { "build": "tsc", "start": "node ./dist/vylbot", - "test": "jest" + "test": "jest", + "db:up": "typeorm migration:run", + "db:down": "typeorm migration:revert" }, "repository": { "type": "git", diff --git a/src/commands/role.ts b/src/commands/role.ts index 9a0af00..9dbda89 100644 --- a/src/commands/role.ts +++ b/src/commands/role.ts @@ -6,6 +6,9 @@ import { ICommandContext } from "../contracts/ICommandContext"; import ICommandReturnContext from "../contracts/ICommandReturnContext"; import SettingsHelper from "../helpers/SettingsHelper"; import { readFileSync } from "fs"; +import { default as eRole } from "../entity/Role"; +import Server from "../entity/Server"; + export default class Role extends Command { constructor() { super(); @@ -30,27 +33,34 @@ export default class Role extends Command { // ======= private async UseDefault(context: ICommandContext) { - const roles = await SettingsHelper.GetSetting("role.assignable", context.message.guild!.id); - - if (!roles) { - const errorEmbed = new ErrorEmbed(context, "Unable to find any assignable roles"); - errorEmbed.SendToCurrentChannel(); - - return; - } - - const rolesArray = roles.split(","); - if (context.args.length == 0) { - await this.SendRolesList(context, rolesArray, context.message.guild!.id); + await this.SendRolesList(context, context.message.guild!.id); } else { - await this.ToggleRole(context, rolesArray); + await this.ToggleRole(context); } } - public async SendRolesList(context: ICommandContext, roles: String[], serverId: string): Promise { + public async GetRolesList(context: ICommandContext): Promise { + const rolesArray = await eRole.FetchAllByServerId(context.message.guild!.id); + + const stringArray: string[] = []; + + for (let i = 0; i < rolesArray.length; i++) { + const serverRole = context.message.guild!.roles.cache.find(x => x.id == rolesArray[i].RoleId); + + if (serverRole) { + stringArray.push(serverRole.name); + } + } + + return stringArray; + } + + public async SendRolesList(context: ICommandContext, serverId: string): Promise { + const roles = await this.GetRolesList(context); + const botPrefix = await SettingsHelper.GetServerPrefix(serverId); - const description = `Do ${botPrefix}role to get the role!\n${roles.join('\n')}`; + const description = roles.length == 0 ? "*no roles*" : `Do ${botPrefix}role to get the role!\n\n${roles.join('\n')}`; const embed = new PublicEmbed(context, "Roles", description); embed.SendToCurrentChannel(); @@ -61,7 +71,8 @@ export default class Role extends Command { }; } - public async ToggleRole(context: ICommandContext, roles: String[]): Promise { + public async ToggleRole(context: ICommandContext): Promise { + const roles = await this.GetRolesList(context); const requestedRole = context.args.join(" "); if (!roles.includes(requestedRole)) { @@ -164,16 +175,33 @@ export default class Role extends Command { this.SendConfigHelp(context); return; } - - let setting = await SettingsHelper.GetSetting("role.assignable", context.message.guild!.id) || ""; - const settingArray = setting.split(","); + const existingRole = await eRole.FetchOneByRoleId(role.id); - settingArray.push(role.name); + if (existingRole) { + const errorEmbed = new ErrorEmbed(context, "This role has already been setup"); + errorEmbed.SendToCurrentChannel(); - setting = settingArray.join(","); + return; + } - await SettingsHelper.SetSetting("role.assignable", context.message.guild!.id, setting); + const server = await Server.FetchOneById(Server, context.message.guild!.id, [ + "Roles", + ]); + + if (!server) { + const errorEmbed = new ErrorEmbed(context, "Server not setup, please request the server owner runs the setup command."); + errorEmbed.SendToCurrentChannel(); + + return; + } + + const roleSetting = new eRole(role.id); + + await roleSetting.Save(eRole, roleSetting); + + server.AddRoleToServer(roleSetting); + await server.Save(Server, server); const embed = new PublicEmbed(context, "", `Added \`${role.name}\` as a new assignable role`); embed.SendToCurrentChannel(); @@ -187,21 +215,16 @@ export default class Role extends Command { return; } - let setting = await SettingsHelper.GetSetting("role.assignable", context.message.guild!.id); + const existingRole = await eRole.FetchOneByRoleId(role.id); - if (!setting) return; + if (!existingRole) { + const errorEmbed = new ErrorEmbed(context, "Unable to find this role"); + errorEmbed.SendToCurrentChannel(); - const settingArray = setting.split(","); + return; + } - const index = settingArray.findIndex(x => x == role.name); - - if (index == -1) return; - - settingArray.splice(index, 1); - - setting = settingArray.join(","); - - await SettingsHelper.SetSetting("role.assignable", context.message.guild!.id, setting); + await eRole.Remove(eRole, existingRole); const embed = new PublicEmbed(context, "", `Removed \`${role.name}\` from the list of assignable roles`); embed.SendToCurrentChannel(); diff --git a/src/entity/Role.ts b/src/entity/Role.ts new file mode 100644 index 0000000..5b534ad --- /dev/null +++ b/src/entity/Role.ts @@ -0,0 +1,44 @@ +import { Column, Entity, EntityTarget, getConnection, ManyToOne } from "typeorm"; +import BaseEntity from "../contracts/BaseEntity" +import Server from "./Server"; + +@Entity() +export default class Role extends BaseEntity { + constructor(roleId: string) { + super(); + + this.RoleId = roleId; + } + + @Column() + RoleId: string; + + @ManyToOne(() => Server, x => x.Roles) + Server: Server; + + public static async FetchOneByRoleId(roleId: string, relations?: string[]): Promise { + const connection = getConnection(); + + const repository = connection.getRepository(Role); + + const single = await repository.findOne({ RoleId: roleId}, { relations: relations || [] }); + + return single; + } + + public static async FetchAllByServerId(serverId: string): Promise { + const connection = getConnection(); + + const repository = connection.getRepository(Server); + + const all = await repository.findOne(serverId, { relations: [ + "Roles", + ]}); + + if (!all) { + return []; + } + + return all.Roles; + } +} \ No newline at end of file diff --git a/src/entity/Server.ts b/src/entity/Server.ts index 180aef0..f669e58 100644 --- a/src/entity/Server.ts +++ b/src/entity/Server.ts @@ -1,5 +1,6 @@ -import { Column, Entity, getConnection, OneToMany } from "typeorm"; +import { Entity, OneToMany } from "typeorm"; import BaseEntity from "../contracts/BaseEntity"; +import Role from "./Role"; import Setting from "./Setting"; @Entity() @@ -13,7 +14,14 @@ export default class Server extends BaseEntity { @OneToMany(() => Setting, x => x.Server) Settings: Setting[]; + @OneToMany(() => Role, x => x.Server) + Roles: Role[]; + public AddSettingToServer(setting: Setting) { this.Settings.push(setting); } + + public AddRoleToServer(role: Role) { + this.Roles.push(role); + } } \ No newline at end of file diff --git a/src/migration/1652375907691-CreateRole.ts b/src/migration/1652375907691-CreateRole.ts new file mode 100644 index 0000000..255ed0f --- /dev/null +++ b/src/migration/1652375907691-CreateRole.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from "typeorm" + +export class migration1652375907691 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + queryRunner.query(`CREATE TABLE role (Id varchar(255), WhenCreated datetime, WhenUpdated datetime, RoleId varchar(255), serverId varchar(255), PRIMARY KEY (Id), FOREIGN KEY (serverId) REFERENCES server(Id))`); + } + + public async down(queryRunner: QueryRunner): Promise { + queryRunner.query(`DROP TABLE role`); + } + +} From d7576f1863dcf0c911820d166a4236a4589b1dcf Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Mon, 16 May 2022 18:40:34 +0100 Subject: [PATCH 05/56] Update .env template to current date --- .env.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.template b/.env.template index 8933949..91d1655 100644 --- a/.env.template +++ b/.env.template @@ -9,5 +9,5 @@ BOT_TOKEN= BOT_VER=3.0.2 BOT_AUTHOR=Vylpes -BOT_DATE=09 May 2022 -BOT_OWNERID=147392775707426816 \ No newline at end of file +BOT_DATE=16 May 2022 +BOT_OWNERID=147392775707426816 From a01a43788ea7974516130bed420460080588a11e Mon Sep 17 00:00:00 2001 From: Vylpes Date: Sat, 16 Jul 2022 16:12:55 +0100 Subject: [PATCH 06/56] Feature/49 ignore channel lists when logging (#168) * Add entity * Create ignore command * Update message events to ignore channels set --- src/commands/ignore.ts | 37 +++++++++++++++++++ src/entity/IgnoredChannel.ts | 21 +++++++++++ src/events/MessageEvents.ts | 7 ++++ .../1657647026816-CreateIgnoredChannel.ts | 13 +++++++ src/registry.ts | 8 ++-- 5 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 src/commands/ignore.ts create mode 100644 src/entity/IgnoredChannel.ts create mode 100644 src/migration/1657647026816-CreateIgnoredChannel.ts diff --git a/src/commands/ignore.ts b/src/commands/ignore.ts new file mode 100644 index 0000000..2bd3297 --- /dev/null +++ b/src/commands/ignore.ts @@ -0,0 +1,37 @@ +import { ICommandContext } from "../contracts/ICommandContext"; +import IgnoredChannel from "../entity/IgnoredChannel"; +import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import { Command } from "../type/command"; + +export default class Ignore extends Command { + constructor() { + super(); + + super.Category = "Moderation"; + super.Roles = [ + "moderator" + ]; + } + + public override async execute(context: ICommandContext) { + if (!context.message.guild) return; + + const isChannelIgnored = await IgnoredChannel.IsChannelIgnored(context.message.channel.id); + + if (isChannelIgnored) { + const entity = await IgnoredChannel.FetchOneById(IgnoredChannel, context.message.channel.id); + + await IgnoredChannel.Remove(IgnoredChannel, entity); + + const embed = new PublicEmbed(context, "Success", "This channel will start being logged again."); + await embed.SendToCurrentChannel(); + } else { + const entity = new IgnoredChannel(context.message.channel.id); + + await entity.Save(IgnoredChannel, entity); + + const embed = new PublicEmbed(context, "Success", "This channel will now be ignored from logging."); + await embed.SendToCurrentChannel(); + } + } +} \ No newline at end of file diff --git a/src/entity/IgnoredChannel.ts b/src/entity/IgnoredChannel.ts new file mode 100644 index 0000000..cd38dd5 --- /dev/null +++ b/src/entity/IgnoredChannel.ts @@ -0,0 +1,21 @@ +import { Entity, getConnection } from "typeorm"; +import BaseEntity from "../contracts/BaseEntity"; + +@Entity() +export default class IgnoredChannel extends BaseEntity { + constructor(channelId: string) { + super(); + + this.Id = channelId; + } + + public static async IsChannelIgnored(channelId: string): Promise { + const connection = getConnection(); + + const repository = connection.getRepository(IgnoredChannel); + + const single = await repository.findOne(channelId); + + return single != undefined; + } +} \ No newline at end of file diff --git a/src/events/MessageEvents.ts b/src/events/MessageEvents.ts index cfeb13e..9f37a9e 100644 --- a/src/events/MessageEvents.ts +++ b/src/events/MessageEvents.ts @@ -3,6 +3,7 @@ import { Message } from "discord.js"; import EventEmbed from "../helpers/embeds/EventEmbed"; import SettingsHelper from "../helpers/SettingsHelper"; import OnMessage from "./MessageEvents/OnMessage"; +import IgnoredChannel from "../entity/IgnoredChannel"; export default class MessageEvents extends Event { constructor() { @@ -16,6 +17,9 @@ export default class MessageEvents extends Event { const enabled = await SettingsHelper.GetSetting("event.message.delete.enabled", message.guild.id); if (!enabled || enabled.toLowerCase() != "true") return; + const ignored = await IgnoredChannel.IsChannelIgnored(message.channel.id); + if (ignored) return; + const embed = new EventEmbed(message.client, message.guild, "Message Deleted"); embed.AddUser("User", message.author, true); embed.addField("Channel", message.channel.toString(), true); @@ -39,6 +43,9 @@ export default class MessageEvents extends Event { const enabled = await SettingsHelper.GetSetting("event.message.update.enabled", newMessage.guild.id); if (!enabled || enabled.toLowerCase() != "true") return; + const ignored = await IgnoredChannel.IsChannelIgnored(newMessage.channel.id); + if (ignored) return; + const embed = new EventEmbed(newMessage.client, newMessage.guild, "Message Edited"); embed.AddUser("User", newMessage.author, true); embed.addField("Channel", newMessage.channel.toString(), true); diff --git a/src/migration/1657647026816-CreateIgnoredChannel.ts b/src/migration/1657647026816-CreateIgnoredChannel.ts new file mode 100644 index 0000000..aac003a --- /dev/null +++ b/src/migration/1657647026816-CreateIgnoredChannel.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from "typeorm" + +export class migration1657647026816 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + queryRunner.query(`CREATE TABLE ignored_channel (Id varchar(255), PRIMARY KEY (Id))`); + } + + public async down(queryRunner: QueryRunner): Promise { + queryRunner.query(`DROP TABLE ignored_channel`) + } + +} diff --git a/src/registry.ts b/src/registry.ts index 9d073b1..183bac2 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -8,6 +8,7 @@ import Code from "./commands/code"; import Config from "./commands/config"; import Disable from "./commands/disable"; import Help from "./commands/help"; +import Ignore from "./commands/ignore"; import Kick from "./commands/kick"; import Mute from "./commands/mute"; import Poll from "./commands/poll"; @@ -32,7 +33,11 @@ export default class Registry { CoreClient.RegisterCommand("ban", new Ban()); CoreClient.RegisterCommand("bunny", new Bunny()); CoreClient.RegisterCommand("clear", new Clear()); + CoreClient.RegisterCommand("code", new Code()); + CoreClient.RegisterCommand("config", new Config()); + CoreClient.RegisterCommand("disable", new Disable()); CoreClient.RegisterCommand("help", new Help()); + CoreClient.RegisterCommand("ignore", new Ignore()); CoreClient.RegisterCommand("kick", new Kick()); CoreClient.RegisterCommand("mute", new Mute()); CoreClient.RegisterCommand("poll", new Poll()); @@ -41,9 +46,6 @@ export default class Registry { CoreClient.RegisterCommand("unmute", new Unmute()); CoreClient.RegisterCommand("warn", new Warn()); CoreClient.RegisterCommand("setup", new Setup()); - CoreClient.RegisterCommand("config", new Config()); - CoreClient.RegisterCommand("code", new Code()); - CoreClient.RegisterCommand("disable", new Disable()); // Exclusive Commands: MankBot CoreClient.RegisterCommand("lobby", new Lobby(), "501231711271780357"); From 4d01f0b34a2e6c31b73b4e040b3eb075c65d1be4 Mon Sep 17 00:00:00 2001 From: Vylpes Date: Tue, 9 Aug 2022 12:33:03 +0100 Subject: [PATCH 07/56] Pending changes exported from your codespace (#173) --- .env.template | 4 ++-- src/commands/say.ts | 26 ++++++++++++++++++++++++++ src/registry.ts | 2 ++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/commands/say.ts diff --git a/.env.template b/.env.template index ab57e01..88ad8df 100644 --- a/.env.template +++ b/.env.template @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=3.0.4 +BOT_VER=3.1 BOT_AUTHOR=Vylpes -BOT_DATE=06 Jul 2022 +BOT_DATE=08 Aug 2022 BOT_OWNERID=147392775707426816 diff --git a/src/commands/say.ts b/src/commands/say.ts new file mode 100644 index 0000000..433b2b8 --- /dev/null +++ b/src/commands/say.ts @@ -0,0 +1,26 @@ +import { ICommandContext } from "../contracts/ICommandContext"; +import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; +import { Command } from "../type/command"; + +export default class Say extends Command { + constructor() { + super(); + super.Category = "Misc"; + super.Roles = [ + "moderator" + ]; + } + + public override async execute(context: ICommandContext) { + const input = context.args.join(" "); + + if (input.length == 0) { + const errorEmbed = new ErrorEmbed(context, "You must supply a message."); + + await errorEmbed.SendToCurrentChannel(); + return; + } + + context.message.channel.send(input); + } +} \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index 183bac2..4fa68f7 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -14,6 +14,7 @@ import Mute from "./commands/mute"; import Poll from "./commands/poll"; import Role from "./commands/role"; import Rules from "./commands/rules"; +import Say from "./commands/say"; import Setup from "./commands/setup"; import Unmute from "./commands/unmute"; import Warn from "./commands/warn"; @@ -46,6 +47,7 @@ export default class Registry { CoreClient.RegisterCommand("unmute", new Unmute()); CoreClient.RegisterCommand("warn", new Warn()); CoreClient.RegisterCommand("setup", new Setup()); + CoreClient.RegisterCommand("say", new Say()); // Exclusive Commands: MankBot CoreClient.RegisterCommand("lobby", new Lobby(), "501231711271780357"); From 2da5e1aa75aa039d77bf148ad260821a9644a0c0 Mon Sep 17 00:00:00 2001 From: Vylpes Date: Mon, 5 Sep 2022 18:07:32 +0100 Subject: [PATCH 08/56] Feature/vba 52 (#175) * Add say command (#174) Co-authored-by: Ethan Lane Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/174 * Add repo and funding link to about message (#176) Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/176 * Add other subreddits to bunny command * Fix changes requested --- .env.template | 5 ++++- package.json | 9 ++++++--- src/commands/about.ts | 31 +++++++++++++++++++++++++++---- src/commands/bunny.ts | 15 +++++++++++++-- src/helpers/embeds/PublicEmbed.ts | 6 +++--- 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/.env.template b/.env.template index 88ad8df..7f24eab 100644 --- a/.env.template +++ b/.env.template @@ -9,5 +9,8 @@ BOT_TOKEN= BOT_VER=3.1 BOT_AUTHOR=Vylpes -BOT_DATE=08 Aug 2022 +BOT_DATE=04 Sep 2022 BOT_OWNERID=147392775707426816 + +ABOUT_FUNDING= +ABOUT_REPO= diff --git a/package.json b/package.json index b45562f..b7cfc34 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vylbot-app", - "version": "3.0.4", + "version": "3.1.0", "description": "A discord bot made for Vylpes' Den", "main": "./dist/vylbot", "typings": "./dist", @@ -13,11 +13,14 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/Vylpes/vylbot-app.git" + "url": "https://github.com/Vylpes/vylbot-app" }, "author": "Vylpes", "license": "MIT", - "bugs": "https://github.com/Vylpes/vylbot-app/issues", + "bugs": { + "url": "https://github.com/Vylpes/vylbot-app/issues", + "email": "helpdesk@vylpes.com" + }, "homepage": "https://github.com/Vylpes/vylbot-app", "dependencies": { "@types/jest": "^27.0.3", diff --git a/src/commands/about.ts b/src/commands/about.ts index 4246113..1391da9 100644 --- a/src/commands/about.ts +++ b/src/commands/about.ts @@ -1,3 +1,5 @@ +import { Emoji, MessageActionRow, MessageButton } from "discord.js"; +import { MessageButtonStyles } from "discord.js/typings/enums"; import { ICommandContext } from "../contracts/ICommandContext"; import PublicEmbed from "../helpers/embeds/PublicEmbed"; import { Command } from "../type/command"; @@ -9,11 +11,32 @@ export default class About extends Command { } public override async execute(context: ICommandContext) { + const fundingLink = process.env.ABOUT_FUNDING; + const repoLink = process.env.ABOUT_REPO; + const embed = new PublicEmbed(context, "About", "") - .addField("Version", process.env.BOT_VER!) - .addField("Author", process.env.BOT_AUTHOR!) - .addField("Date", process.env.BOT_DATE!); + .addField("Version", process.env.BOT_VER!, true) + .addField("Author", process.env.BOT_AUTHOR!, true) + .addField("Date", process.env.BOT_DATE!, true); + + const row = new MessageActionRow(); + + if (repoLink) { + row.addComponents( + new MessageButton() + .setURL(repoLink) + .setLabel("Repo") + .setStyle(MessageButtonStyles.LINK)); + } + + if (fundingLink) { + row.addComponents( + new MessageButton() + .setURL(fundingLink) + .setLabel("Funding") + .setStyle(MessageButtonStyles.LINK)); + } - await embed.SendToCurrentChannel(); + await embed.SendToCurrentChannel({ components: [row] }); } } \ No newline at end of file diff --git a/src/commands/bunny.ts b/src/commands/bunny.ts index 47bafa6..a41e179 100644 --- a/src/commands/bunny.ts +++ b/src/commands/bunny.ts @@ -12,13 +12,24 @@ export default class Bunny extends Command { } public override async execute(context: ICommandContext) { - const result = await randomBunny('rabbits', 'hot'); + const subreddits = [ + 'rabbits', + 'bunnieswithhats', + 'buncomfortable', + 'bunnytongues', + 'dutchbunnymafia', + ]; + + const random = Math.floor(Math.random() * subreddits.length); + const selectedSubreddit = subreddits[random]; + + const result = await randomBunny(selectedSubreddit, 'hot'); if (result.IsSuccess) { const embed = new PublicEmbed(context, result.Result!.Title, "") .setImage(result.Result!.Url) .setURL(`https://reddit.com${result.Result!.Permalink}`) - .setFooter({ text: `r/Rabbits ยท ${result.Result!.Ups} upvotes` }); + .setFooter({ text: `r/${selectedSubreddit} ยท ${result.Result!.Ups} upvotes` }); await embed.SendToCurrentChannel(); } else { diff --git a/src/helpers/embeds/PublicEmbed.ts b/src/helpers/embeds/PublicEmbed.ts index 84be5c9..059826b 100644 --- a/src/helpers/embeds/PublicEmbed.ts +++ b/src/helpers/embeds/PublicEmbed.ts @@ -1,4 +1,4 @@ -import { MessageEmbed, Permissions, TextChannel } from "discord.js"; +import { MessageEmbed, MessageOptions, Permissions, TextChannel } from "discord.js"; import { ICommandContext } from "../../contracts/ICommandContext"; export default class PublicEmbed extends MessageEmbed { @@ -20,7 +20,7 @@ export default class PublicEmbed extends MessageEmbed { } // Send methods - public async SendToCurrentChannel() { + public async SendToCurrentChannel(options?: MessageOptions) { const channel = this.context.message.channel as TextChannel; const botMember = await this.context.message.guild?.members.fetch({ user: this.context.message.client.user! }); @@ -30,6 +30,6 @@ export default class PublicEmbed extends MessageEmbed { if (!permissions.has(Permissions.FLAGS.SEND_MESSAGES)) return; - this.context.message.channel.send({ embeds: [ this ]}); + this.context.message.channel.send({ embeds: [ this ], ...options}); } } \ No newline at end of file From cd666d24fd1611979bdb1635041f92c41d6f22c6 Mon Sep 17 00:00:00 2001 From: Vylpes Date: Mon, 5 Sep 2022 18:10:04 +0100 Subject: [PATCH 09/56] Feature/vba 77 (#178) * Add say command (#174) Co-authored-by: Ethan Lane Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/174 * Add repo and funding link to about message (#176) Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/176 * Add other subreddits to bunny command (#177) Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/177 * Add database table * Save moderation actions to database * Add audit command to see a user's audits * Add audit view subcommand * Add audit clear subcommand * Create add audit subcommand * Fix bot crashing when viewing an audit with no reason * Fix changes requested --- package.json | 1 + src/commands/about.ts | 2 +- src/commands/audits.ts | 144 +++++++++++++++++++++ src/commands/ban.ts | 8 ++ src/commands/kick.ts | 8 ++ src/commands/mute.ts | 8 ++ src/commands/warn.ts | 8 ++ src/constants/AuditType.ts | 7 + src/entity/Audit.ts | 56 ++++++++ src/helpers/AuditTools.ts | 37 ++++++ src/migration/1660754832945-CreateAudit.ts | 13 ++ src/registry.ts | 2 + 12 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 src/commands/audits.ts create mode 100644 src/constants/AuditType.ts create mode 100644 src/entity/Audit.ts create mode 100644 src/helpers/AuditTools.ts create mode 100644 src/migration/1660754832945-CreateAudit.ts diff --git a/package.json b/package.json index b7cfc34..01955ab 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "email": "helpdesk@vylpes.com" }, "homepage": "https://github.com/Vylpes/vylbot-app", + "funding": "https://ko-fi.com/vylpes", "dependencies": { "@types/jest": "^27.0.3", "@types/uuid": "^8.3.4", diff --git a/src/commands/about.ts b/src/commands/about.ts index 1391da9..b688df6 100644 --- a/src/commands/about.ts +++ b/src/commands/about.ts @@ -1,4 +1,4 @@ -import { Emoji, MessageActionRow, MessageButton } from "discord.js"; +import { MessageActionRow, MessageButton } from "discord.js"; import { MessageButtonStyles } from "discord.js/typings/enums"; import { ICommandContext } from "../contracts/ICommandContext"; import PublicEmbed from "../helpers/embeds/PublicEmbed"; diff --git a/src/commands/audits.ts b/src/commands/audits.ts new file mode 100644 index 0000000..c53fe37 --- /dev/null +++ b/src/commands/audits.ts @@ -0,0 +1,144 @@ +import { ICommandContext } from "../contracts/ICommandContext"; +import Audit from "../entity/Audit"; +import AuditTools from "../helpers/AuditTools"; +import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import { Command } from "../type/command"; +import SettingsHelper from "../helpers/SettingsHelper"; +import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; + +export default class Audits extends Command { + constructor() { + super(); + + super.Category = "Moderation"; + super.Roles = [ + "moderator" + ]; + } + + public override async execute(context: ICommandContext) { + if (!context.message.guild) return; + + switch (context.args[0]) { + case "user": + await this.SendAuditForUser(context); + break; + case "view": + await this.SendAudit(context); + break; + case "clear": + await this.ClearAudit(context); + break; + case "add": + await this.AddAudit(context); + break; + default: + await this.SendUsage(context); + } + } + + private async SendUsage(context: ICommandContext) { + const prefix = await SettingsHelper.GetServerPrefix(context.message.guild!.id); + + const description = [ + `\`${prefix}audits user \` - Send the audits for this user`, + `\`${prefix}audits view \` - Send information about an audit`, + `\`${prefix}audits clear \` - Clears an audit for a user by audit id`, + `\`${prefix}audits add [reason]\` - Manually add an audit for a user`, + ] + + const publicEmbed = new PublicEmbed(context, "Usage", description.join("\n")); + await publicEmbed.SendToCurrentChannel(); + } + + private async SendAuditForUser(context: ICommandContext) { + const userId = context.args[1]; + + const audits = await Audit.FetchAuditsByUserId(userId, context.message.guild!.id); + + if (!audits || audits.length == 0) { + const publicEmbed = new PublicEmbed(context, "", "There are no audits logged for this user."); + await publicEmbed.SendToCurrentChannel(); + + return; + } + + const publicEmbed = new PublicEmbed(context, "Audit Log", ""); + + for (let audit of audits) { + publicEmbed.addField(`${audit.AuditId} // ${AuditTools.TypeToFriendlyText(audit.AuditType)}`, audit.WhenCreated.toString()); + } + + await publicEmbed.SendToCurrentChannel(); + } + + private async SendAudit(context: ICommandContext) { + const auditId = context.args[1]; + + if (!auditId) { + await this.SendUsage(context); + return; + } + + const audit = await Audit.FetchAuditByAuditId(auditId.toUpperCase(), context.message.guild!.id); + + if (!audit) { + const errorEmbed = new ErrorEmbed(context, "This audit can not be found."); + await errorEmbed.SendToCurrentChannel(); + + return; + } + + const publicEmbed = new PublicEmbed(context, `Audit ${audit.AuditId.toUpperCase()}`, ""); + + publicEmbed.addField("Reason", audit.Reason || "*none*", true); + publicEmbed.addField("Type", AuditTools.TypeToFriendlyText(audit.AuditType), true); + publicEmbed.addField("Moderator", `<@${audit.ModeratorId}>`, true); + + await publicEmbed.SendToCurrentChannel(); + } + + private async ClearAudit(context: ICommandContext) { + const auditId = context.args[1]; + + if (!auditId) { + await this.SendUsage(context); + return; + } + + const audit = await Audit.FetchAuditByAuditId(auditId.toUpperCase(), context.message.guild!.id); + + if (!audit) { + const errorEmbed = new ErrorEmbed(context, "This audit can not be found."); + await errorEmbed.SendToCurrentChannel(); + + return; + } + + await Audit.Remove(Audit, audit); + + const publicEmbed = new PublicEmbed(context, "", "Audit cleared"); + await publicEmbed.SendToCurrentChannel(); + } + + private async AddAudit(context: ICommandContext) { + const userId = context.args[1]; + const typeString = context.args[2]; + const reason = context.args.splice(3) + .join(" "); + + if (!userId || !typeString) { + await this.SendUsage(context); + return; + } + + const type = AuditTools.StringToType(typeString); + + const audit = new Audit(userId, type, reason, context.message.author.id, context.message.guild!.id); + + await audit.Save(Audit, audit); + + const publicEmbed = new PublicEmbed(context, "", `Created new audit with ID \`${audit.AuditId}\``); + await publicEmbed.SendToCurrentChannel(); + } +} \ No newline at end of file diff --git a/src/commands/ban.ts b/src/commands/ban.ts index ad39f03..8d50132 100644 --- a/src/commands/ban.ts +++ b/src/commands/ban.ts @@ -5,6 +5,8 @@ import PublicEmbed from "../helpers/embeds/PublicEmbed"; import { Command } from "../type/command"; import { ICommandContext } from "../contracts/ICommandContext"; import ICommandReturnContext from "../contracts/ICommandReturnContext"; +import Audit from "../entity/Audit"; +import { AuditType } from "../constants/AuditType"; export default class Ban extends Command { constructor() { @@ -75,6 +77,12 @@ export default class Ban extends Command { await logEmbed.SendToModLogsChannel(); await publicEmbed.SendToCurrentChannel(); + if (context.message.guild) { + const audit = new Audit(targetUser.id, AuditType.Ban, reason, context.message.author.id, context.message.guild.id); + + await audit.Save(Audit, audit); + } + return { commandContext: context, embeds: [logEmbed, publicEmbed], diff --git a/src/commands/kick.ts b/src/commands/kick.ts index 81b1af9..c1b2572 100644 --- a/src/commands/kick.ts +++ b/src/commands/kick.ts @@ -1,6 +1,8 @@ +import { AuditType } from "../constants/AuditType"; import ErrorMessages from "../constants/ErrorMessages"; import { ICommandContext } from "../contracts/ICommandContext"; import ICommandReturnContext from "../contracts/ICommandReturnContext"; +import Audit from "../entity/Audit"; import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; import LogEmbed from "../helpers/embeds/LogEmbed"; import PublicEmbed from "../helpers/embeds/PublicEmbed"; @@ -74,6 +76,12 @@ export default class Kick extends Command { await logEmbed.SendToModLogsChannel(); await publicEmbed.SendToCurrentChannel(); + + if (context.message.guild) { + const audit = new Audit(targetUser.id, AuditType.Kick, reason, context.message.author.id, context.message.guild.id); + + await audit.Save(Audit, audit); + } return { commandContext: context, diff --git a/src/commands/mute.ts b/src/commands/mute.ts index e5d43df..7a45b87 100644 --- a/src/commands/mute.ts +++ b/src/commands/mute.ts @@ -1,6 +1,8 @@ +import { AuditType } from "../constants/AuditType"; import ErrorMessages from "../constants/ErrorMessages"; import { ICommandContext } from "../contracts/ICommandContext"; import ICommandReturnContext from "../contracts/ICommandReturnContext"; +import Audit from "../entity/Audit"; import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; import LogEmbed from "../helpers/embeds/LogEmbed"; import PublicEmbed from "../helpers/embeds/PublicEmbed"; @@ -87,6 +89,12 @@ export default class Mute extends Command { await logEmbed.SendToModLogsChannel(); await publicEmbed.SendToCurrentChannel(); + + if (context.message.guild) { + const audit = new Audit(targetUser.id, AuditType.Mute, reason, context.message.author.id, context.message.guild.id); + + await audit.Save(Audit, audit); + } return { commandContext: context, diff --git a/src/commands/warn.ts b/src/commands/warn.ts index a36e28e..00f9efe 100644 --- a/src/commands/warn.ts +++ b/src/commands/warn.ts @@ -1,5 +1,7 @@ +import { AuditType } from "../constants/AuditType"; import { ICommandContext } from "../contracts/ICommandContext"; import ICommandReturnContext from "../contracts/ICommandReturnContext"; +import Audit from "../entity/Audit"; import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; import LogEmbed from "../helpers/embeds/LogEmbed"; import PublicEmbed from "../helpers/embeds/PublicEmbed"; @@ -62,6 +64,12 @@ export default class Warn extends Command { await logEmbed.SendToModLogsChannel(); await publicEmbed.SendToCurrentChannel(); + + if (context.message.guild) { + const audit = new Audit(user.id, AuditType.Warn, reason, context.message.author.id, context.message.guild.id); + + await audit.Save(Audit, audit); + } return { commandContext: context, diff --git a/src/constants/AuditType.ts b/src/constants/AuditType.ts new file mode 100644 index 0000000..4ad8df6 --- /dev/null +++ b/src/constants/AuditType.ts @@ -0,0 +1,7 @@ +export enum AuditType { + General, + Warn, + Mute, + Kick, + Ban, +} \ No newline at end of file diff --git a/src/entity/Audit.ts b/src/entity/Audit.ts new file mode 100644 index 0000000..0ec1ea7 --- /dev/null +++ b/src/entity/Audit.ts @@ -0,0 +1,56 @@ +import { Column, Entity, getConnection, ManyToOne } from "typeorm"; +import { AuditType } from "../constants/AuditType"; +import BaseEntity from "../contracts/BaseEntity"; +import StringTools from "../helpers/StringTools"; + +@Entity() +export default class Audit extends BaseEntity { + constructor(userId: string, auditType: AuditType, reason: string, moderatorId: string, serverId: string) { + super(); + + this.AuditId = StringTools.RandomString(5).toUpperCase(); + this.UserId = userId; + this.AuditType = auditType; + this.Reason = reason; + this.ModeratorId = moderatorId; + this.ServerId = serverId; + } + + @Column() + AuditId: string; + + @Column() + UserId: string; + + @Column() + AuditType: AuditType; + + @Column() + Reason: string; + + @Column() + ModeratorId: string; + + @Column() + ServerId: string; + + public static async FetchAuditsByUserId(userId: string, serverId: string): Promise { + const connection = getConnection(); + + const repository = connection.getRepository(Audit); + + const all = await repository.find({ UserId: userId, ServerId: serverId }); + + return all; + } + + public static async FetchAuditByAuditId(auditId: string, serverId: string): Promise { + const connection = getConnection(); + + const repository = connection.getRepository(Audit); + + const single = await repository.findOne({ AuditId: auditId, ServerId: serverId }); + + return single; + } +} \ No newline at end of file diff --git a/src/helpers/AuditTools.ts b/src/helpers/AuditTools.ts new file mode 100644 index 0000000..fa06c43 --- /dev/null +++ b/src/helpers/AuditTools.ts @@ -0,0 +1,37 @@ +import { AuditType } from "../constants/AuditType"; + +export default class AuditTools { + public static TypeToFriendlyText(auditType: AuditType): string { + switch (auditType) { + case AuditType.General: + return "General"; + case AuditType.Warn: + return "Warn"; + case AuditType.Mute: + return "Mute"; + case AuditType.Kick: + return "Kick"; + case AuditType.Ban: + return "Ban"; + default: + return "Other"; + } + } + + public static StringToType(str: string): AuditType { + switch (str.toLowerCase()) { + case "general": + return AuditType.General; + case "warn": + return AuditType.Warn; + case "mute": + return AuditType.Mute; + case "kick": + return AuditType.Kick; + case "ban": + return AuditType.Ban; + default: + return AuditType.General; + } + } +} \ No newline at end of file diff --git a/src/migration/1660754832945-CreateAudit.ts b/src/migration/1660754832945-CreateAudit.ts new file mode 100644 index 0000000..9dab091 --- /dev/null +++ b/src/migration/1660754832945-CreateAudit.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from "typeorm" + +export class CreateAudit1660754832945 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + queryRunner.query(`CREATE TABLE audit (Id varchar(255), WhenCreated datetime, WhenUpdated datetime, auditId varchar(255), userId varchar(255), auditType int, reason varchar(255), moderatorId varchar(255), serverId varchar(255), PRIMARY KEY (Id))`); + } + + public async down(queryRunner: QueryRunner): Promise { + queryRunner.query(`DROP TABLE audit`); + } + +} diff --git a/src/registry.ts b/src/registry.ts index 4fa68f7..c34c098 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -2,6 +2,7 @@ import { CoreClient } from "./client/client"; // Command Imports import About from "./commands/about"; +import Audits from "./commands/audits"; import Ban from "./commands/ban"; import Clear from "./commands/clear"; import Code from "./commands/code"; @@ -48,6 +49,7 @@ export default class Registry { CoreClient.RegisterCommand("warn", new Warn()); CoreClient.RegisterCommand("setup", new Setup()); CoreClient.RegisterCommand("say", new Say()); + CoreClient.RegisterCommand("audits", new Audits()); // Exclusive Commands: MankBot CoreClient.RegisterCommand("lobby", new Lobby(), "501231711271780357"); From 7decd28dc9aea8f935464e7f2895eb0f0a3e757e Mon Sep 17 00:00:00 2001 From: Vylpes Date: Tue, 6 Sep 2022 19:24:40 +0100 Subject: [PATCH 10/56] Feature/182 setup actions (#186) * Create scripts * Create github workflows * Create initial DB migration script * Make default bot prefix configurable * Add bot token fetcher --- .dev.env | 17 +++++++++ .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++ .github/ISSUE_TEMPLATE/epic.md | 16 ++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++ .github/ISSUE_TEMPLATE/user-story.md | 24 ++++++++++++ .github/pull_request_template.md | 30 +++++++++++++++ .github/workflows/deployment.yml | 28 ++++++++++++++ .github/workflows/integration.yml | 20 ++++++++++ .github/workflows/staging.yml | 28 ++++++++++++++ .github/workflows/testing.yml | 27 ------------- .env.template => .prod.env | 7 ++-- .stage.env | 17 +++++++++ .../Up/01-table/Audit.sql | 11 ++++++ .../Up/01-table/IgnoredChannel.sql | 5 +++ .../Up/01-table/Lobby.sql | 10 +++++ .../Up/01-table/Role.sql | 7 ++++ .../Up/01-table/Server.sql | 5 +++ .../Up/01-table/Setting.sql | 8 ++++ .../Up/02-key/Audit.sql | 2 + .../Up/02-key/IgnoredChannel.sql | 2 + .../Up/02-key/Lobby.sql | 2 + .../Up/02-key/Role.sql | 3 ++ .../Up/02-key/Server.sql | 2 + .../Up/02-key/Setting.sql | 3 ++ .../Up/03-constraint/Role.sql | 2 + .../Up/03-constraint/Setting.sql | 2 + docker-compose.prod.yml | 31 +++++++++++++++ docker-compose.stage.yml | 31 +++++++++++++++ docker-compose.yml | 11 +++++- ormconfig.json.template => ormconfig.dev.json | 2 +- ormconfig.prod.json | 24 ++++++++++++ ormconfig.stage.json | 24 ++++++++++++ scripts/deploy_prod.sh | 23 +++++++++++ scripts/deploy_stage.sh | 23 +++++++++++ src/client/client.ts | 4 +- src/constants/DefaultValues.ts | 6 +-- src/helpers/MigrationHelper.ts | 20 ++++++++++ src/migration/1652375907691-CreateRole.ts | 13 ------- .../1657647026816-CreateIgnoredChannel.ts | 13 ------- src/migration/1660754832945-CreateAudit.ts | 13 ------- src/migration/3.1/1662399171315-CreateBase.ts | 30 +++++++++++++++ src/vylbot.ts | 4 +- 42 files changed, 525 insertions(+), 83 deletions(-) create mode 100644 .dev.env create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/epic.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/user-story.md create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/deployment.yml create mode 100644 .github/workflows/integration.yml create mode 100644 .github/workflows/staging.yml delete mode 100644 .github/workflows/testing.yml rename .env.template => .prod.env (75%) create mode 100644 .stage.env create mode 100644 database/3.1/1662399171315-CreateBase/Up/01-table/Audit.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/01-table/IgnoredChannel.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/01-table/Lobby.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/01-table/Role.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/01-table/Server.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/01-table/Setting.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/02-key/Audit.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/02-key/IgnoredChannel.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/02-key/Lobby.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/02-key/Role.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/02-key/Server.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/02-key/Setting.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/03-constraint/Role.sql create mode 100644 database/3.1/1662399171315-CreateBase/Up/03-constraint/Setting.sql create mode 100644 docker-compose.prod.yml create mode 100644 docker-compose.stage.yml rename ormconfig.json.template => ormconfig.dev.json (96%) create mode 100644 ormconfig.prod.json create mode 100644 ormconfig.stage.json create mode 100644 scripts/deploy_prod.sh create mode 100644 scripts/deploy_stage.sh create mode 100644 src/helpers/MigrationHelper.ts delete mode 100644 src/migration/1652375907691-CreateRole.ts delete mode 100644 src/migration/1657647026816-CreateIgnoredChannel.ts delete mode 100644 src/migration/1660754832945-CreateAudit.ts create mode 100644 src/migration/3.1/1662399171315-CreateBase.ts diff --git a/.dev.env b/.dev.env new file mode 100644 index 0000000..2d8cbd1 --- /dev/null +++ b/.dev.env @@ -0,0 +1,17 @@ +# Security Warning! Do not commit this file to any VCS! +# This is a local file to speed up development process, +# so you don't have to change your environment variables. +# +# This is not applied to `.env.template`! +# Template files must be committed to the VCS, but must not contain +# any secret values. + +BOT_TOKEN= +BOT_VER=DEV +BOT_AUTHOR=Vylpes +BOT_DATE=DEV +BOT_OWNERID=147392775707426816 +BOT_PREFIX=d! + +ABOUT_FUNDING=https://ko-fi.com/vylpes +ABOUT_REPO=https://github.com/vylpes/vylbot-app diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..f3d5c41 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/epic.md b/.github/ISSUE_TEMPLATE/epic.md new file mode 100644 index 0000000..8dfd3c5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/epic.md @@ -0,0 +1,16 @@ +--- +name: Epic +about: Agile Epic +title: '' +labels: epic +assignees: '' + +--- + +*Description here* + +## Stories +*Stories linked to this epic* + +## Bugs +*Bugs linked to this epic* diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..11fc491 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/user-story.md b/.github/ISSUE_TEMPLATE/user-story.md new file mode 100644 index 0000000..644fad5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/user-story.md @@ -0,0 +1,24 @@ +--- +name: User Story +about: Agile User Story +title: '' +labels: needs criteria, story +assignees: '' + +--- + +Epic Link: N/A +Story Points: N/A + +--- + +*Description here* + +## Acceptance Criteria +*Add your ACs here* + +## Notes +*Any extra information* + +## Subtasks +*Add technical subtasks here* diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..a773253 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,30 @@ +# Description + +Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. + +Fixes # (issue) + +## Type of change + +Please delete options that are not relevant. + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +# How Has This Been Tested? + +Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration + + +# Checklist: + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes +- [ ] Any dependent changes have been merged and published in downstream modules \ No newline at end of file diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml new file mode 100644 index 0000000..d7e85be --- /dev/null +++ b/.github/workflows/deployment.yml @@ -0,0 +1,28 @@ +name: deployment + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build and Test + uses: actions/setup-node@v1 + with: + node-version: 16.x + - run: yarn install --frozen-lockfile + - run: yarn build + - run: yarn test + - name: Deploy Production + uses: D3rHase/ssh-command-action@v0.2.1 + with: + HOST: ${{secrets.HOST}} + PORT: ${{secrets.PORT}} + USER: ${{secrets.USER}} + PRIVATE_SSH_KEY: ${{secrets.PRIVATE_SSH_KEY}} + COMMAND: ${{secrets.PROD_COMMAND}} \ No newline at end of file diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000..d74e7aa --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,20 @@ +name: integration + +on: + push: + branches: + - feature/* + - hotfix/* + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build and Test + uses: actions/setup-node@v1 + with: + node-version: 16.x + - run: yarn install --frozen-lockfile + - run: yarn build + - run: yarn test \ No newline at end of file diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml new file mode 100644 index 0000000..a441cc3 --- /dev/null +++ b/.github/workflows/staging.yml @@ -0,0 +1,28 @@ +name: staging + +on: + push: + branches: + - develop + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build and Test + uses: actions/setup-node@v1 + with: + node-version: 16.x + - run: yarn install --frozen-lockfile + - run: yarn build + - run: yarn test + - name: Deploy Staging + uses: D3rHase/ssh-command-action@v0.2.1 + with: + HOST: ${{secrets.HOST}} + PORT: ${{secrets.PORT}} + USER: ${{secrets.USER}} + PRIVATE_SSH_KEY: ${{secrets.PRIVATE_SSH_KEY}} + COMMAND: ${{secrets.STAGE_COMMAND}} \ No newline at end of file diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml deleted file mode 100644 index 1f76252..0000000 --- a/.github/workflows/testing.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Testing - -on: - pull_request: - branches: - - main - - develop - -jobs: - build: - - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [16.x] - - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: yarn install - - run: yarn build - - run: yarn test - diff --git a/.env.template b/.prod.env similarity index 75% rename from .env.template rename to .prod.env index 7f24eab..f5efcb5 100644 --- a/.env.template +++ b/.prod.env @@ -9,8 +9,9 @@ BOT_TOKEN= BOT_VER=3.1 BOT_AUTHOR=Vylpes -BOT_DATE=04 Sep 2022 +BOT_DATE=05 Sep 2022 BOT_OWNERID=147392775707426816 +BOT_PREFIX=v! -ABOUT_FUNDING= -ABOUT_REPO= +ABOUT_FUNDING=https://ko-fi.com/vylpes +ABOUT_REPO=https://github.com/vylpes/vylbot-app diff --git a/.stage.env b/.stage.env new file mode 100644 index 0000000..0477d32 --- /dev/null +++ b/.stage.env @@ -0,0 +1,17 @@ +# Security Warning! Do not commit this file to any VCS! +# This is a local file to speed up development process, +# so you don't have to change your environment variables. +# +# This is not applied to `.env.template`! +# Template files must be committed to the VCS, but must not contain +# any secret values. + +BOT_TOKEN= +BOT_VER=3.1 +BOT_AUTHOR=Vylpes +BOT_DATE=05 Sep 2022 +BOT_OWNERID=147392775707426816 +BOT_PREFIX=s! + +ABOUT_FUNDING=https://ko-fi.com/vylpes +ABOUT_REPO=https://github.com/vylpes/vylbot-app diff --git a/database/3.1/1662399171315-CreateBase/Up/01-table/Audit.sql b/database/3.1/1662399171315-CreateBase/Up/01-table/Audit.sql new file mode 100644 index 0000000..fa4db1b --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/01-table/Audit.sql @@ -0,0 +1,11 @@ +CREATE TABLE `audit` ( + `Id` varchar(255) NOT NULL, + `WhenCreated` datetime NOT NULL, + `WhenUpdated` datetime NOT NULL, + `AuditId` varchar(255) NOT NULL, + `UserId` varchar(255) NOT NULL, + `AuditType` int NOT NULL, + `Reason` varchar(255) NOT NULL, + `ModeratorId` varchar(255) NOT NULL, + `ServerId` varchar(255) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/01-table/IgnoredChannel.sql b/database/3.1/1662399171315-CreateBase/Up/01-table/IgnoredChannel.sql new file mode 100644 index 0000000..93d919b --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/01-table/IgnoredChannel.sql @@ -0,0 +1,5 @@ +CREATE TABLE `ignored_channel` ( + `Id` varchar(255) NOT NULL, + `WhenCreated` datetime NOT NULL, + `WhenUpdated` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/01-table/Lobby.sql b/database/3.1/1662399171315-CreateBase/Up/01-table/Lobby.sql new file mode 100644 index 0000000..e8ec996 --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/01-table/Lobby.sql @@ -0,0 +1,10 @@ +CREATE TABLE `lobby` ( + `Id` varchar(255) NOT NULL, + `WhenCreated` datetime NOT NULL, + `WhenUpdated` datetime NOT NULL, + `ChannelId` varchar(255) NOT NULL, + `RoleId` varchar(255) NOT NULL, + `Cooldown` int NOT NULL, + `LastUsed` datetime NOT NULL, + `Name` varchar(255) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/01-table/Role.sql b/database/3.1/1662399171315-CreateBase/Up/01-table/Role.sql new file mode 100644 index 0000000..7c781db --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/01-table/Role.sql @@ -0,0 +1,7 @@ +CREATE TABLE `role` ( + `Id` varchar(255) NOT NULL, + `WhenCreated` datetime NOT NULL, + `WhenUpdated` datetime NOT NULL, + `RoleId` varchar(255) NOT NULL, + `serverId` varchar(255) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/01-table/Server.sql b/database/3.1/1662399171315-CreateBase/Up/01-table/Server.sql new file mode 100644 index 0000000..c6c721f --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/01-table/Server.sql @@ -0,0 +1,5 @@ +CREATE TABLE `server` ( + `Id` varchar(255) NOT NULL, + `WhenCreated` datetime NOT NULL, + `WhenUpdated` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/01-table/Setting.sql b/database/3.1/1662399171315-CreateBase/Up/01-table/Setting.sql new file mode 100644 index 0000000..dac609a --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/01-table/Setting.sql @@ -0,0 +1,8 @@ +CREATE TABLE `setting` ( + `Id` varchar(255) NOT NULL, + `WhenCreated` datetime NOT NULL, + `WhenUpdated` datetime NOT NULL, + `Key` varchar(255) NOT NULL, + `Value` varchar(255) NOT NULL, + `serverId` varchar(255) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/02-key/Audit.sql b/database/3.1/1662399171315-CreateBase/Up/02-key/Audit.sql new file mode 100644 index 0000000..b8411a1 --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/02-key/Audit.sql @@ -0,0 +1,2 @@ +ALTER TABLE `audit` + ADD PRIMARY KEY (`Id`); \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/02-key/IgnoredChannel.sql b/database/3.1/1662399171315-CreateBase/Up/02-key/IgnoredChannel.sql new file mode 100644 index 0000000..1288be1 --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/02-key/IgnoredChannel.sql @@ -0,0 +1,2 @@ +ALTER TABLE `ignored_channel` + ADD PRIMARY KEY (`Id`); \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/02-key/Lobby.sql b/database/3.1/1662399171315-CreateBase/Up/02-key/Lobby.sql new file mode 100644 index 0000000..e8e34ef --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/02-key/Lobby.sql @@ -0,0 +1,2 @@ +ALTER TABLE `lobby` + ADD PRIMARY KEY (`Id`); \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/02-key/Role.sql b/database/3.1/1662399171315-CreateBase/Up/02-key/Role.sql new file mode 100644 index 0000000..5d0a591 --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/02-key/Role.sql @@ -0,0 +1,3 @@ +ALTER TABLE `role` + ADD PRIMARY KEY (`Id`), + ADD KEY `FK_d9e438d88cfb64f7f8e1ae593c3` (`serverId`); \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/02-key/Server.sql b/database/3.1/1662399171315-CreateBase/Up/02-key/Server.sql new file mode 100644 index 0000000..951587f --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/02-key/Server.sql @@ -0,0 +1,2 @@ +ALTER TABLE `server` + ADD PRIMARY KEY (`Id`); \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/02-key/Setting.sql b/database/3.1/1662399171315-CreateBase/Up/02-key/Setting.sql new file mode 100644 index 0000000..8d03bec --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/02-key/Setting.sql @@ -0,0 +1,3 @@ +ALTER TABLE `setting` + ADD PRIMARY KEY (`Id`), + ADD KEY `FK_a3623ec541bdb12fa0f58bdfde7` (`serverId`); \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/03-constraint/Role.sql b/database/3.1/1662399171315-CreateBase/Up/03-constraint/Role.sql new file mode 100644 index 0000000..22ffbc0 --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/03-constraint/Role.sql @@ -0,0 +1,2 @@ +ALTER TABLE `role` + ADD CONSTRAINT `FK_d9e438d88cfb64f7f8e1ae593c3` FOREIGN KEY (`serverId`) REFERENCES `server` (`Id`); \ No newline at end of file diff --git a/database/3.1/1662399171315-CreateBase/Up/03-constraint/Setting.sql b/database/3.1/1662399171315-CreateBase/Up/03-constraint/Setting.sql new file mode 100644 index 0000000..d5172ac --- /dev/null +++ b/database/3.1/1662399171315-CreateBase/Up/03-constraint/Setting.sql @@ -0,0 +1,2 @@ +ALTER TABLE `setting` + ADD CONSTRAINT `FK_a3623ec541bdb12fa0f58bdfde7` FOREIGN KEY (`serverId`) REFERENCES `server` (`Id`); \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..ae37fc5 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,31 @@ +version: "3.9" + +volumes: + prod_database_data: + +services: + # discord: + # build: . + + database: + image: mysql/mysql-server + command: --default-authentication-plugin=mysql_native_password + restart: always + environment: + - MYSQL_DATABASE=vylbot + - MYSQL_USER=prod + - MYSQL_PASSWORD=prod + - MYSQL_ROOT_PASSWORD=root + - MYSQL_ROOT_HOST=0.0.0.0 + ports: + - "3121:3306" + volumes: + - prod_database_data:/var/lib/mysql + + phpmyadmin: + image: phpmyadmin + restart: always + ports: + - "3122:80" + environment: + - PMA_ARBITRARY=1 \ No newline at end of file diff --git a/docker-compose.stage.yml b/docker-compose.stage.yml new file mode 100644 index 0000000..e25a6f1 --- /dev/null +++ b/docker-compose.stage.yml @@ -0,0 +1,31 @@ +version: "3.9" + +volumes: + stage_database_data: + +services: + # discord: + # build: . + + database: + image: mysql/mysql-server + command: --default-authentication-plugin=mysql_native_password + restart: always + environment: + - MYSQL_DATABASE=vylbot + - MYSQL_USER=stage + - MYSQL_PASSWORD=stage + - MYSQL_ROOT_PASSWORD=root + - MYSQL_ROOT_HOST=0.0.0.0 + ports: + - "3111:3306" + volumes: + - stage_database_data:/var/lib/mysql + + phpmyadmin: + image: phpmyadmin + restart: always + ports: + - "3112:80" + environment: + - PMA_ARBITRARY=1 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index a10aebd..92ce70a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,8 @@ version: "3.9" + +volumes: + dev_database_data: + services: # discord: # build: . @@ -12,13 +16,16 @@ services: - MYSQL_USER=dev - MYSQL_PASSWORD=dev - MYSQL_ROOT_PASSWORD=root + - MYSQL_ROOT_HOST=0.0.0.0 ports: - - 3306:3306 + - "3101:3306" + volumes: + - dev_database_data:/var/lib/mysql phpmyadmin: image: phpmyadmin restart: always ports: - - 8080:80 + - "3102:80" environment: - PMA_ARBITRARY=1 \ No newline at end of file diff --git a/ormconfig.json.template b/ormconfig.dev.json similarity index 96% rename from ormconfig.json.template rename to ormconfig.dev.json index 0ada020..f6f80c1 100644 --- a/ormconfig.json.template +++ b/ormconfig.dev.json @@ -1,7 +1,7 @@ { "type": "mysql", "host": "localhost", - "port": 3306, + "port": 3101, "username": "dev", "password": "dev", "database": "vylbot", diff --git a/ormconfig.prod.json b/ormconfig.prod.json new file mode 100644 index 0000000..300cfe2 --- /dev/null +++ b/ormconfig.prod.json @@ -0,0 +1,24 @@ +{ + "type": "mysql", + "host": "localhost", + "port": 3121, + "username": "prod", + "password": "prod", + "database": "vylbot", + "synchronize": false, + "logging": false, + "entities": [ + "dist/entity/**/*.js" + ], + "migrations": [ + "dist/migration/**/*.js" + ], + "subscribers": [ + "dist/subscriber/**/*.js" + ], + "cli": { + "entitiesDir": "dist/entity", + "migrationsDir": "dist/migration", + "subscribersDir": "dist/subscriber" + } +} \ No newline at end of file diff --git a/ormconfig.stage.json b/ormconfig.stage.json new file mode 100644 index 0000000..a038f64 --- /dev/null +++ b/ormconfig.stage.json @@ -0,0 +1,24 @@ +{ + "type": "mysql", + "host": "localhost", + "port": 3111, + "username": "stage", + "password": "stage", + "database": "vylbot", + "synchronize": false, + "logging": false, + "entities": [ + "dist/entity/**/*.js" + ], + "migrations": [ + "dist/migration/**/*.js" + ], + "subscribers": [ + "dist/subscriber/**/*.js" + ], + "cli": { + "entitiesDir": "dist/entity", + "migrationsDir": "dist/migration", + "subscribersDir": "dist/subscriber" + } +} \ No newline at end of file diff --git a/scripts/deploy_prod.sh b/scripts/deploy_prod.sh new file mode 100644 index 0000000..dee258f --- /dev/null +++ b/scripts/deploy_prod.sh @@ -0,0 +1,23 @@ +#! /bin/bash + +source "$HOME/.ssh/environment" + +export PATH="$HOME/.yarn/bin:$PATH" +export PATH="$HOME/.nvm/versions/node/v16.17.0/bin/:$PATH" + +cd ~/apps/vylbot/vylbot_prod \ +&& git checkout main \ +&& git fetch \ +&& git pull \ +&& docker-compose --file docker-compose.prod.yml down \ +&& (pm2 stop vylbot_prod || true) \ +&& (pm2 delete vylbot_prod || true) \ +&& cp .prod.env .env \ +&& cp ormconfig.prod.json ormconfig.json \ +&& yarn install --frozen-lockfile \ +&& yarn build \ +&& docker-compose --file docker-compose.prod.yml up -d \ +&& echo "Sleeping for 10 seconds to let database load..." \ +&& sleep 10 \ +&& yarn run db:up \ +&& NODE_ENV=production BOT_TOKEN=$BOT_TOKEN_PROD pm2 start --name vylbot_prod dist/vylbot.js \ No newline at end of file diff --git a/scripts/deploy_stage.sh b/scripts/deploy_stage.sh new file mode 100644 index 0000000..75d664a --- /dev/null +++ b/scripts/deploy_stage.sh @@ -0,0 +1,23 @@ +#! /bin/bash + +source "$HOME/.ssh/environment" + +export PATH="$HOME/.yarn/bin:$PATH" +export PATH="$HOME/.nvm/versions/node/v16.17.0/bin/:$PATH" + +cd ~/apps/vylbot/vylbot_stage \ +&& git checkout develop \ +&& git fetch \ +&& git pull \ +&& docker-compose --file docker-compose.stage.yml down \ +&& (pm2 stop vylbot_stage || true) \ +&& (pm2 delete vylbot_stage || true) \ +&& cp .stage.env .env \ +&& cp ormconfig.stage.json ormconfig.json \ +&& yarn install --frozen-lockfile \ +&& yarn build \ +&& docker-compose --file docker-compose.stage.yml up -d \ +&& echo "Sleeping for 10 seconds to let database load..." \ +&& sleep 10 \ +&& yarn run db:up \ +&& NODE_ENV=production BOT_TOKEN=$BOT_TOKEN_STAGE pm2 start --name vylbot_stage dist/vylbot.js \ No newline at end of file diff --git a/src/client/client.ts b/src/client/client.ts index 36f738f..1f46d7e 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -25,12 +25,10 @@ export class CoreClient extends Client { return this._eventItems; } - constructor(intents: number[], devmode: boolean = false) { + constructor(intents: number[]) { super({ intents: intents }); dotenv.config(); - DefaultValues.useDevPrefix = devmode; - CoreClient._commandItems = []; CoreClient._eventItems = []; diff --git a/src/constants/DefaultValues.ts b/src/constants/DefaultValues.ts index ec2a4b3..3f5ba09 100644 --- a/src/constants/DefaultValues.ts +++ b/src/constants/DefaultValues.ts @@ -17,11 +17,7 @@ export default class DefaultValues { private static SetValues() { if (this.values.length == 0) { // Bot - if (this.useDevPrefix) { - this.values.push({ Key: "bot.prefix", Value: "d!" }); - } else { - this.values.push({ Key: "bot.prefix", Value: "v!" }); - } + this.values.push({ Key: "bot.prefix", Value: process.env.BOT_PREFIX || "v!" }) // Commands this.values.push({ Key: "commands.disabled", Value: "" }); diff --git a/src/helpers/MigrationHelper.ts b/src/helpers/MigrationHelper.ts new file mode 100644 index 0000000..69fee4a --- /dev/null +++ b/src/helpers/MigrationHelper.ts @@ -0,0 +1,20 @@ +import { readFileSync } from "fs"; +import { QueryRunner } from "typeorm"; + +export default class MigrationHelper { + public static Up(migrationName: string, version: string, queryFiles: string[], queryRunner: QueryRunner) { + for (let path of queryFiles) { + const query = readFileSync(`${process.cwd()}/database/${version}/${migrationName}/Up/${path}.sql`).toString(); + + queryRunner.query(query); + } + } + + public static Down(migrationName: string, version: string, queryFiles: string[], queryRunner: QueryRunner) { + for (let path of queryFiles) { + const query = readFileSync(`${process.cwd()}/database/${version}/${migrationName}/Down/${path}.sql`).toString(); + + queryRunner.query(query); + } + } +} \ No newline at end of file diff --git a/src/migration/1652375907691-CreateRole.ts b/src/migration/1652375907691-CreateRole.ts deleted file mode 100644 index 255ed0f..0000000 --- a/src/migration/1652375907691-CreateRole.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm" - -export class migration1652375907691 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - queryRunner.query(`CREATE TABLE role (Id varchar(255), WhenCreated datetime, WhenUpdated datetime, RoleId varchar(255), serverId varchar(255), PRIMARY KEY (Id), FOREIGN KEY (serverId) REFERENCES server(Id))`); - } - - public async down(queryRunner: QueryRunner): Promise { - queryRunner.query(`DROP TABLE role`); - } - -} diff --git a/src/migration/1657647026816-CreateIgnoredChannel.ts b/src/migration/1657647026816-CreateIgnoredChannel.ts deleted file mode 100644 index aac003a..0000000 --- a/src/migration/1657647026816-CreateIgnoredChannel.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm" - -export class migration1657647026816 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - queryRunner.query(`CREATE TABLE ignored_channel (Id varchar(255), PRIMARY KEY (Id))`); - } - - public async down(queryRunner: QueryRunner): Promise { - queryRunner.query(`DROP TABLE ignored_channel`) - } - -} diff --git a/src/migration/1660754832945-CreateAudit.ts b/src/migration/1660754832945-CreateAudit.ts deleted file mode 100644 index 9dab091..0000000 --- a/src/migration/1660754832945-CreateAudit.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm" - -export class CreateAudit1660754832945 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - queryRunner.query(`CREATE TABLE audit (Id varchar(255), WhenCreated datetime, WhenUpdated datetime, auditId varchar(255), userId varchar(255), auditType int, reason varchar(255), moderatorId varchar(255), serverId varchar(255), PRIMARY KEY (Id))`); - } - - public async down(queryRunner: QueryRunner): Promise { - queryRunner.query(`DROP TABLE audit`); - } - -} diff --git a/src/migration/3.1/1662399171315-CreateBase.ts b/src/migration/3.1/1662399171315-CreateBase.ts new file mode 100644 index 0000000..cd4e696 --- /dev/null +++ b/src/migration/3.1/1662399171315-CreateBase.ts @@ -0,0 +1,30 @@ +import { MigrationInterface, QueryRunner } from "typeorm" +import MigrationHelper from "../../helpers/MigrationHelper" + +export class vylbot1662399171315 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + MigrationHelper.Up('1662399171315-CreateBase', '3.1', [ + "01-table/Audit", + "01-table/IgnoredChannel", + "01-table/Lobby", + "01-table/Role", + "01-table/Server", + "01-table/Setting", + + "02-key/Audit", + "02-key/IgnoredChannel", + "02-key/Lobby", + "02-key/Role", + "02-key/Server", + "02-key/Setting", + + "03-constraint/Role", + "03-constraint/Setting", + ], queryRunner); + } + + public async down(queryRunner: QueryRunner): Promise { + } + +} diff --git a/src/vylbot.ts b/src/vylbot.ts index 50f1d87..1d6a420 100644 --- a/src/vylbot.ts +++ b/src/vylbot.ts @@ -19,13 +19,11 @@ requiredConfigs.forEach(config => { } }); -const devmode = process.argv.find(x => x.toLowerCase() == "--dev") != null; - const client = new CoreClient([ Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MEMBERS, -], devmode); +]); registry.RegisterCommands(); registry.RegisterEvents(); From 6238a200029538dd160529cee69e96638573a09e Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 6 Sep 2022 19:26:57 +0100 Subject: [PATCH 11/56] Update dates --- .dev.env | 4 ++-- .prod.env | 2 +- .stage.env | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.dev.env b/.dev.env index 2d8cbd1..2b8f6a5 100644 --- a/.dev.env +++ b/.dev.env @@ -7,9 +7,9 @@ # any secret values. BOT_TOKEN= -BOT_VER=DEV +BOT_VER=3.1 BOT_AUTHOR=Vylpes -BOT_DATE=DEV +BOT_DATE=06 Sep 2022 BOT_OWNERID=147392775707426816 BOT_PREFIX=d! diff --git a/.prod.env b/.prod.env index f5efcb5..2884bbe 100644 --- a/.prod.env +++ b/.prod.env @@ -9,7 +9,7 @@ BOT_TOKEN= BOT_VER=3.1 BOT_AUTHOR=Vylpes -BOT_DATE=05 Sep 2022 +BOT_DATE=06 Sep 2022 BOT_OWNERID=147392775707426816 BOT_PREFIX=v! diff --git a/.stage.env b/.stage.env index 0477d32..bb57e4d 100644 --- a/.stage.env +++ b/.stage.env @@ -9,7 +9,7 @@ BOT_TOKEN= BOT_VER=3.1 BOT_AUTHOR=Vylpes -BOT_DATE=05 Sep 2022 +BOT_DATE=06 Sep 2022 BOT_OWNERID=147392775707426816 BOT_PREFIX=s! From e2988d39b58b7a4028b9c372f26ecc893d019315 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 6 Sep 2022 19:29:16 +0100 Subject: [PATCH 12/56] Remove testing from deployment scripts --- .github/workflows/deployment.yml | 1 - .github/workflows/staging.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index d7e85be..53e7f47 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -17,7 +17,6 @@ jobs: node-version: 16.x - run: yarn install --frozen-lockfile - run: yarn build - - run: yarn test - name: Deploy Production uses: D3rHase/ssh-command-action@v0.2.1 with: diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index a441cc3..5cff552 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -17,7 +17,6 @@ jobs: node-version: 16.x - run: yarn install --frozen-lockfile - run: yarn build - - run: yarn test - name: Deploy Staging uses: D3rHase/ssh-command-action@v0.2.1 with: From d4716e69d5d4642990029578d165611f73613ede Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 6 Sep 2022 19:34:47 +0100 Subject: [PATCH 13/56] Change how bot token is gotten in script --- scripts/deploy_prod.sh | 6 +++--- scripts/deploy_stage.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/deploy_prod.sh b/scripts/deploy_prod.sh index dee258f..781952d 100644 --- a/scripts/deploy_prod.sh +++ b/scripts/deploy_prod.sh @@ -1,10 +1,10 @@ #! /bin/bash -source "$HOME/.ssh/environment" - export PATH="$HOME/.yarn/bin:$PATH" export PATH="$HOME/.nvm/versions/node/v16.17.0/bin/:$PATH" +export BOT_TOKEN=$(cat $HOME/scripts/vylbot/prod_key.txt) + cd ~/apps/vylbot/vylbot_prod \ && git checkout main \ && git fetch \ @@ -20,4 +20,4 @@ cd ~/apps/vylbot/vylbot_prod \ && echo "Sleeping for 10 seconds to let database load..." \ && sleep 10 \ && yarn run db:up \ -&& NODE_ENV=production BOT_TOKEN=$BOT_TOKEN_PROD pm2 start --name vylbot_prod dist/vylbot.js \ No newline at end of file +&& NODE_ENV=production pm2 start --name vylbot_prod dist/vylbot.js \ No newline at end of file diff --git a/scripts/deploy_stage.sh b/scripts/deploy_stage.sh index 75d664a..a921279 100644 --- a/scripts/deploy_stage.sh +++ b/scripts/deploy_stage.sh @@ -1,10 +1,10 @@ #! /bin/bash -source "$HOME/.ssh/environment" - export PATH="$HOME/.yarn/bin:$PATH" export PATH="$HOME/.nvm/versions/node/v16.17.0/bin/:$PATH" +export BOT_TOKEN=$(cat $HOME/scripts/vylbot/prod_key.txt) + cd ~/apps/vylbot/vylbot_stage \ && git checkout develop \ && git fetch \ @@ -20,4 +20,4 @@ cd ~/apps/vylbot/vylbot_stage \ && echo "Sleeping for 10 seconds to let database load..." \ && sleep 10 \ && yarn run db:up \ -&& NODE_ENV=production BOT_TOKEN=$BOT_TOKEN_STAGE pm2 start --name vylbot_stage dist/vylbot.js \ No newline at end of file +&& NODE_ENV=production pm2 start --name vylbot_stage dist/vylbot.js \ No newline at end of file From 0465697b870faefc5eaaaeaa700efea38966e74a Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 6 Sep 2022 19:37:06 +0100 Subject: [PATCH 14/56] Update stage script to use stage key --- scripts/deploy_stage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deploy_stage.sh b/scripts/deploy_stage.sh index a921279..b219c3f 100644 --- a/scripts/deploy_stage.sh +++ b/scripts/deploy_stage.sh @@ -3,7 +3,7 @@ export PATH="$HOME/.yarn/bin:$PATH" export PATH="$HOME/.nvm/versions/node/v16.17.0/bin/:$PATH" -export BOT_TOKEN=$(cat $HOME/scripts/vylbot/prod_key.txt) +export BOT_TOKEN=$(cat $HOME/scripts/vylbot/stage_key.txt) cd ~/apps/vylbot/vylbot_stage \ && git checkout develop \ From ed8f5927c85671fbab2d9ddeb57ed9f9664e486f Mon Sep 17 00:00:00 2001 From: Vylpes Date: Sun, 18 Sep 2022 11:57:22 +0100 Subject: [PATCH 15/56] Feature/81 slash command support (#192) * Update discord.js * Migrate to slash commands * Clean up imports * Update permissions * Fix guild-specific commands not showing up * Fix changes requested --- .dev.env | 3 +- .prod.env | 3 +- .stage.env | 3 +- package.json | 3 +- src/client/client.ts | 8 +- src/client/events.ts | 51 ++-- src/client/util.ts | 100 +++---- src/commands/501231711271780357/Lobby/add.ts | 58 ++++ .../501231711271780357/Lobby/lobby.ts | 41 +++ .../501231711271780357/Lobby/remove.ts | 40 +++ src/commands/501231711271780357/entry.ts | 26 +- src/commands/501231711271780357/lobby.ts | 159 ----------- src/commands/Role/config.ts | 54 ++++ src/commands/Role/role.ts | 109 ++++++++ src/commands/about.ts | 48 ++-- src/commands/audits.ts | 214 +++++++++------ src/commands/ban.ts | 128 ++++----- src/commands/bunny.ts | 27 +- src/commands/clear.ts | 59 ++--- src/commands/code.ts | 94 +++---- src/commands/config.ts | 215 +++++++++------ src/commands/disable.ts | 102 ++++--- src/commands/help.ts | 68 ----- src/commands/ignore.ts | 27 +- src/commands/kick.ts | 130 +++++---- src/commands/mute.ts | 131 ++++----- src/commands/poll.ts | 67 ----- src/commands/role.ts | 232 ---------------- src/commands/rules.ts | 47 ++-- src/commands/say.ts | 26 -- src/commands/setup.ts | 30 +-- src/commands/unmute.ts | 124 ++++----- src/commands/warn.ts | 112 ++++---- src/constants/CommandResponse.ts | 7 - src/constants/EmbedColours.ts | 3 + src/constants/ErrorMessages.ts | 27 -- src/contracts/ICommandContext.ts | 7 - src/contracts/ICommandReturnContext.ts | 7 - src/contracts/IEventReturnContext.ts | 6 - src/entity/Audit.ts | 2 +- src/entity/Role.ts | 6 +- src/events/MemberEvents.ts | 62 +++-- src/events/MemberEvents/GuildMemberUpdate.ts | 37 ++- src/events/MessageEvents.ts | 80 ++++-- src/helpers/embeds/ErrorEmbed.ts | 28 -- src/helpers/embeds/EventEmbed.ts | 83 ------ src/helpers/embeds/LogEmbed.ts | 88 ------- src/helpers/embeds/PublicEmbed.ts | 35 --- src/registry.ts | 21 +- src/type/command.ts | 22 +- src/vylbot.ts | 11 +- yarn.lock | 248 +++++++++++------- 52 files changed, 1469 insertions(+), 1850 deletions(-) create mode 100644 src/commands/501231711271780357/Lobby/add.ts create mode 100644 src/commands/501231711271780357/Lobby/lobby.ts create mode 100644 src/commands/501231711271780357/Lobby/remove.ts delete mode 100644 src/commands/501231711271780357/lobby.ts create mode 100644 src/commands/Role/config.ts create mode 100644 src/commands/Role/role.ts delete mode 100644 src/commands/help.ts delete mode 100644 src/commands/poll.ts delete mode 100644 src/commands/role.ts delete mode 100644 src/commands/say.ts delete mode 100644 src/constants/CommandResponse.ts create mode 100644 src/constants/EmbedColours.ts delete mode 100644 src/constants/ErrorMessages.ts delete mode 100644 src/contracts/ICommandContext.ts delete mode 100644 src/contracts/ICommandReturnContext.ts delete mode 100644 src/contracts/IEventReturnContext.ts delete mode 100644 src/helpers/embeds/ErrorEmbed.ts delete mode 100644 src/helpers/embeds/EventEmbed.ts delete mode 100644 src/helpers/embeds/LogEmbed.ts delete mode 100644 src/helpers/embeds/PublicEmbed.ts diff --git a/.dev.env b/.dev.env index 2b8f6a5..199bb0a 100644 --- a/.dev.env +++ b/.dev.env @@ -9,9 +9,8 @@ BOT_TOKEN= BOT_VER=3.1 BOT_AUTHOR=Vylpes -BOT_DATE=06 Sep 2022 BOT_OWNERID=147392775707426816 -BOT_PREFIX=d! +BOT_CLIENTID=682942374040961060 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://github.com/vylpes/vylbot-app diff --git a/.prod.env b/.prod.env index 2884bbe..c4fd73a 100644 --- a/.prod.env +++ b/.prod.env @@ -9,9 +9,8 @@ BOT_TOKEN= BOT_VER=3.1 BOT_AUTHOR=Vylpes -BOT_DATE=06 Sep 2022 BOT_OWNERID=147392775707426816 -BOT_PREFIX=v! +BOT_CLIENTID=680083120896081954 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://github.com/vylpes/vylbot-app diff --git a/.stage.env b/.stage.env index bb57e4d..85e3068 100644 --- a/.stage.env +++ b/.stage.env @@ -9,9 +9,8 @@ BOT_TOKEN= BOT_VER=3.1 BOT_AUTHOR=Vylpes -BOT_DATE=06 Sep 2022 BOT_OWNERID=147392775707426816 -BOT_PREFIX=s! +BOT_CLIENTID=1016767908740857949 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://github.com/vylpes/vylbot-app diff --git a/package.json b/package.json index 01955ab..8ff2a64 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,10 @@ "homepage": "https://github.com/Vylpes/vylbot-app", "funding": "https://ko-fi.com/vylpes", "dependencies": { + "@discordjs/rest": "^1.1.0", "@types/jest": "^27.0.3", "@types/uuid": "^8.3.4", - "discord.js": "^13.6.0", + "discord.js": "^14.3.0", "dotenv": "^10.0.0", "emoji-regex": "^9.2.0", "jest": "^27.4.5", diff --git a/src/client/client.ts b/src/client/client.ts index 1f46d7e..4b933f3 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -1,7 +1,6 @@ import { Client } from "discord.js"; import * as dotenv from "dotenv"; import { createConnection } from "typeorm"; -import DefaultValues from "../constants/DefaultValues"; import ICommandItem from "../contracts/ICommandItem"; import IEventItem from "../contracts/IEventItem"; import { Command } from "../type/command"; @@ -47,14 +46,13 @@ export class CoreClient extends Client { return; }); - super.on("messageCreate", (message) => { - this._events.onMessageCreate(message, CoreClient._commandItems) - }); + super.on("interactionCreate", this._events.onInteractionCreate); super.on("ready", this._events.onReady); - super.login(process.env.BOT_TOKEN); + await super.login(process.env.BOT_TOKEN); this._util.loadEvents(this, CoreClient._eventItems); + this._util.loadSlashCommands(this); } public static RegisterCommand(name: string, command: Command, serverId?: string) { diff --git a/src/client/events.ts b/src/client/events.ts index 059df52..2d36001 100644 --- a/src/client/events.ts +++ b/src/client/events.ts @@ -1,33 +1,40 @@ -import { Message } from "discord.js"; +import { Interaction } from "discord.js"; import ICommandItem from "../contracts/ICommandItem"; import SettingsHelper from "../helpers/SettingsHelper"; -import { Util } from "./util"; +import { CoreClient } from "./client"; export class Events { - private _util: Util; + public async onInteractionCreate(interaction: Interaction) { + if (!interaction.isChatInputCommand()) return; + if (!interaction.guildId) return; - constructor() { - this._util = new Util(); - } + const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", interaction.guildId); + const disabledCommands = disabledCommandsString?.split(","); - // Emit when a message is sent - // Used to check for commands - public async onMessageCreate(message: Message, commands: ICommandItem[]) { - if (!message.guild) return; - if (message.author.bot) return; + const disabledCommandsMessage = await SettingsHelper.GetSetting("commands.disabled.message", interaction.guildId); - const prefix = await SettingsHelper.GetSetting("bot.prefix", message.guild.id); - - if (!prefix) return; - - if (message.content.substring(0, prefix.length).toLowerCase() == prefix.toLowerCase()) { - const args = message.content.substring(prefix.length).split(" "); - const name = args.shift(); - - if (!name) return; - - await this._util.loadCommand(name, args, message, commands); + if (disabledCommands?.find(x => x == interaction.commandName)) { + await interaction.reply(disabledCommandsMessage || "This command is disabled."); + return; } + + const item = CoreClient.commandItems.find(x => x.Name == interaction.commandName && !x.ServerId); + const itemForServer = CoreClient.commandItems.find(x => x.Name == interaction.commandName && x.ServerId == interaction.guildId); + + let itemToUse: ICommandItem; + + if (!itemForServer) { + if (!item) { + await interaction.reply('Command not found'); + return; + } + + itemToUse = item; + } else { + itemToUse = itemForServer; + } + + itemToUse.Command.execute(interaction); } // Emit when bot is logged in and ready to use diff --git a/src/client/util.ts b/src/client/util.ts index f136e26..7a23542 100644 --- a/src/client/util.ts +++ b/src/client/util.ts @@ -1,83 +1,49 @@ -// Required Components -import { Client, Message } from "discord.js"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ICommandItem from "../contracts/ICommandItem"; +import { Client, REST, Routes, SlashCommandBuilder } from "discord.js"; import IEventItem from "../contracts/IEventItem"; -import SettingsHelper from "../helpers/SettingsHelper"; -import StringTools from "../helpers/StringTools"; -import { CommandResponse } from "../constants/CommandResponse"; -import ErrorMessages from "../constants/ErrorMessages"; +import { CoreClient } from "./client"; -// Util Class export class Util { - public async loadCommand(name: string, args: string[], message: Message, commands: ICommandItem[]) { - if (!message.member) return; - if (!message.guild) return; + public loadSlashCommands(client: Client) { + const registeredCommands = CoreClient.commandItems; - const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", message.guild?.id); - const disabledCommands = disabledCommandsString?.split(","); + const globalCommands = registeredCommands.filter(x => !x.ServerId); + const guildCommands = registeredCommands.filter(x => x.ServerId); - if (disabledCommands?.find(x => x == name)) { - message.reply(process.env.COMMANDS_DISABLED_MESSAGE || "This command is disabled."); - return; - } + const globalCommandData: SlashCommandBuilder[] = globalCommands + .filter(x => x.Command.CommandBuilder) + .flatMap(x => x.Command.CommandBuilder); - const item = commands.find(x => x.Name == name && !x.ServerId); - const itemForServer = commands.find(x => x.Name == name && x.ServerId == message.guild?.id); + const guildIds: string[] = []; - let itemToUse: ICommandItem; - - if (!itemForServer) { - if (!item) { - message.reply('Command not found'); - return; + for (let command of guildCommands) { + if (!guildIds.find(x => x == command.ServerId)) { + guildIds.push(command.ServerId!); } - - itemToUse = item; - } else { - itemToUse = itemForServer; } - const requiredRoles = itemToUse.Command.Roles; + const rest = new REST({ version: '10' }).setToken(process.env.BOT_TOKEN!); - if (message.author.id != process.env.BOT_OWNERID && message.author.id != message.guild.ownerId) { - for (const i in requiredRoles) { - if (message.guild) { - const setting = await SettingsHelper.GetSetting(`role.${requiredRoles[i]}`, message.guild?.id); - - if (!setting) { - message.reply("Unable to verify if you have this role, please contact your bot administrator"); - return; - } - - if (!message.member.roles.cache.find(role => role.name == setting)) { - message.reply(`You require the \`${StringTools.Capitalise(setting)}\` role to run this command`); - return; - } + rest.put( + Routes.applicationCommands(process.env.BOT_CLIENTID!), + { + body: globalCommandData + } + ); + + for (let guild of guildIds) { + const guildCommandData = guildCommands.filter(x => x.ServerId == guild) + .filter(x => x.Command.CommandBuilder) + .flatMap(x => x.Command.CommandBuilder); + + if (!client.guilds.cache.has(guild)) continue; + + rest.put( + Routes.applicationGuildCommands(process.env.BOT_CLIENTID!, guild), + { + body: guildCommandData } - } + ) } - - const context: ICommandContext = { - name: name, - args: args, - message: message - }; - - const precheckResponse = itemToUse.Command.precheck(context); - const precheckAsyncResponse = await itemToUse.Command.precheckAsync(context); - - if (precheckResponse != CommandResponse.Ok) { - message.reply(ErrorMessages.GetErrorMessage(precheckResponse)); - return; - } - - if (precheckAsyncResponse != CommandResponse.Ok) { - message.reply(ErrorMessages.GetErrorMessage(precheckAsyncResponse)); - return; - } - - itemToUse.Command.execute(context); } // Load the events diff --git a/src/commands/501231711271780357/Lobby/add.ts b/src/commands/501231711271780357/Lobby/add.ts new file mode 100644 index 0000000..16a38d2 --- /dev/null +++ b/src/commands/501231711271780357/Lobby/add.ts @@ -0,0 +1,58 @@ +import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; +import { Command } from "../../../type/command"; +import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; + +export default class AddRole extends Command { + constructor() { + super(); + + super.CommandBuilder = new SlashCommandBuilder() + .setName('addlobby') + .setDescription('Add lobby channel') + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) + .addChannelOption(option => + option + .setName('channel') + .setDescription('The channel') + .setRequired(true)) + .addRoleOption(option => + option + .setName('role') + .setDescription('The role to ping on request') + .setRequired(true)) + .addNumberOption(option => + option + .setName('cooldown') + .setDescription('The cooldown in minutes') + .setRequired(true)) + .addStringOption(option => + option + .setName('name') + .setDescription('The game name') + .setRequired(true)); + } + + public override async execute(interaction: CommandInteraction) { + const channel = interaction.options.get('channel'); + const role = interaction.options.get('role'); + const cooldown = interaction.options.get('cooldown'); + const gameName = interaction.options.get('name'); + + if (!channel || !channel.channel || !role || !role.role || !cooldown || !cooldown.value || !gameName || !gameName.value) { + await interaction.reply('Fields are required.'); + return; + } + + const lobby = await eLobby.FetchOneByChannelId(channel.channel.id); + + if (lobby) { + await interaction.reply('This channel has already been setup.'); + return; + } + + const entity = new eLobby(channel.channel.id, role.role.id, cooldown.value as number, gameName.value as string); + await entity.Save(eLobby, entity); + + await interaction.reply(`Added \`${channel.name}\` as a new lobby channel with a cooldown of \`${cooldown.value} minutes \` and will ping \`${role.name}\` on use`); + } +} \ No newline at end of file diff --git a/src/commands/501231711271780357/Lobby/lobby.ts b/src/commands/501231711271780357/Lobby/lobby.ts new file mode 100644 index 0000000..d7f0d42 --- /dev/null +++ b/src/commands/501231711271780357/Lobby/lobby.ts @@ -0,0 +1,41 @@ +import { CommandInteraction, SlashCommandBuilder } from "discord.js"; +import { Command } from "../../../type/command"; +import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; + +export default class Lobby extends Command { + constructor() { + super(); + + super.CommandBuilder = new SlashCommandBuilder() + .setName('lobby') + .setDescription('Attempt to organise a lobby'); + } + + public override async execute(interaction: CommandInteraction) { + if (!interaction.channelId) return; + + const lobby = await eLobby.FetchOneByChannelId(interaction.channelId); + + if (!lobby) { + await interaction.reply('This channel is disabled from using the lobby command.'); + return; + } + + const timeNow = Date.now(); + const timeLength = lobby.Cooldown * 60 * 1000; // x minutes in ms + const timeAgo = timeNow - timeLength; + + // If it was less than x minutes ago + if (lobby.LastUsed.getTime() > timeAgo) { + const timeLeft = Math.ceil((timeLength - (timeNow - lobby.LastUsed.getTime())) / 1000 / 60); + + await interaction.reply(`Requesting a lobby for this game is on cooldown! Please try again in **${timeLeft} minutes**.`); + return; + } + + lobby.MarkAsUsed(); + await lobby.Save(eLobby, lobby); + + await interaction.reply(`${interaction.user} would like to organise a lobby of **${lobby.Name}**! <@&${lobby.RoleId}>`); + } +} \ No newline at end of file diff --git a/src/commands/501231711271780357/Lobby/remove.ts b/src/commands/501231711271780357/Lobby/remove.ts new file mode 100644 index 0000000..b350316 --- /dev/null +++ b/src/commands/501231711271780357/Lobby/remove.ts @@ -0,0 +1,40 @@ +import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; +import { Command } from "../../../type/command"; +import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; +import BaseEntity from "../../../contracts/BaseEntity"; + +export default class RemoveLobby extends Command { + constructor() { + super(); + + super.CommandBuilder = new SlashCommandBuilder() + .setName('removelobby') + .setDescription('Remove a lobby channel') + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) + .addChannelOption(option => + option + .setName('channel') + .setDescription('The channel') + .setRequired(true)); + } + + public override async execute(interaction: CommandInteraction) { + const channel = interaction.options.get('channel'); + + if (!channel || !channel.channel) { + await interaction.reply('Channel is required.'); + return; + } + + const entity = await eLobby.FetchOneByChannelId(channel.channel.id); + + if (!entity) { + await interaction.reply('Channel not found.'); + return; + } + + await BaseEntity.Remove(eLobby, entity); + + await interaction.reply(`Removed <#${channel.channel.id}> from the list of lobby channels`); + } +} \ No newline at end of file diff --git a/src/commands/501231711271780357/entry.ts b/src/commands/501231711271780357/entry.ts index 2c0f4ae..fd246ca 100644 --- a/src/commands/501231711271780357/entry.ts +++ b/src/commands/501231711271780357/entry.ts @@ -1,5 +1,5 @@ -import { ICommandContext } from "../../contracts/ICommandContext"; -import PublicEmbed from "../../helpers/embeds/PublicEmbed"; +import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js"; +import EmbedColours from "../../constants/EmbedColours"; import SettingsHelper from "../../helpers/SettingsHelper"; import { Command } from "../../type/command"; @@ -7,19 +7,23 @@ export default class Entry extends Command { constructor() { super(); - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName('entry') + .setDescription('Sends the entry embed') + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers); } - public override async execute(context: ICommandContext) { - if (!context.message.guild) return; + public override async execute(interaction: CommandInteraction) { + if (!interaction.guildId) return; + if (!interaction.channel) return; - const rulesChannelId = await SettingsHelper.GetSetting("channels.rules", context.message.guild.id) || "rules"; + const rulesChannelId = await SettingsHelper.GetSetting("channels.rules", interaction.guildId) || "rules"; - const embedInfo = new PublicEmbed(context, "", `Welcome to the server! Please make sure to read the rules in the <#${rulesChannelId}> channel and type the code found there in here to proceed to the main part of the server.`); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Welcome") + .setDescription(`Welcome to the server! Please make sure to read the rules in the <#${rulesChannelId}> channel and type the code found there in here to proceed to the main part of the server.`); - await embedInfo.SendToCurrentChannel(); + await interaction.channel.send({ embeds: [ embed ]}); } } \ No newline at end of file diff --git a/src/commands/501231711271780357/lobby.ts b/src/commands/501231711271780357/lobby.ts deleted file mode 100644 index ec74a7f..0000000 --- a/src/commands/501231711271780357/lobby.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { TextChannel } from "discord.js"; -import { ICommandContext } from "../../contracts/ICommandContext"; -import { Command } from "../../type/command"; -import { default as eLobby } from "../../entity/501231711271780357/Lobby"; -import SettingsHelper from "../../helpers/SettingsHelper"; -import PublicEmbed from "../../helpers/embeds/PublicEmbed"; -import { readFileSync } from "fs"; -import ErrorEmbed from "../../helpers/embeds/ErrorEmbed"; -import BaseEntity from "../../contracts/BaseEntity"; - -export default class Lobby extends Command { - constructor() { - super(); - - super.Category = "General"; - } - - public override async execute(context: ICommandContext) { - if (!context.message.guild) return; - - switch (context.args[0]) { - case "config": - await this.UseConfig(context); - break; - default: - await this.UseDefault(context); - } - } - - // ======= - // Default - // ======= - - private async UseDefault(context: ICommandContext) { - const channel = context.message.channel as TextChannel; - const channelId = channel.id; - - const lobby = await eLobby.FetchOneByChannelId(channelId); - - if (!lobby) { - this.SendDisabled(context); - return; - } - - const timeNow = Date.now(); - const timeLength = lobby.Cooldown * 60 * 1000; // x minutes in ms - const timeAgo = timeNow - timeLength; - - // If it was less than x minutes ago - if (lobby.LastUsed.getTime() > timeAgo) { - this.SendOnCooldown(context, timeLength, new Date(timeNow), lobby.LastUsed); - return; - } - - await this.RequestLobby(context, lobby); - } - - private async RequestLobby(context: ICommandContext, lobby: eLobby) { - lobby.MarkAsUsed(); - await lobby.Save(eLobby, lobby); - - context.message.channel.send(`${context.message.author} would like to organise a lobby of **${lobby.Name}**! <@&${lobby.RoleId}>`); - } - - private SendOnCooldown(context: ICommandContext, timeLength: number, timeNow: Date, timeUsed: Date) { - const timeLeft = Math.ceil((timeLength - (timeNow.getTime() - timeUsed.getTime())) / 1000 / 60); - - context.message.reply(`Requesting a lobby for this game is on cooldown! Please try again in **${timeLeft} minutes**.`); - } - - private SendDisabled(context: ICommandContext) { - context.message.reply("This channel hasn't been setup for lobbies."); - } - - // ====== - // Config - // ====== - private async UseConfig(context: ICommandContext) { - const moderatorRole = await SettingsHelper.GetSetting("role.moderator", context.message.guild!.id); - - if (!context.message.member?.roles.cache.find(x => x.name == moderatorRole)) { - const errorEmbed = new ErrorEmbed(context, "Sorry, you must be a moderator to be able to configure this command"); - await errorEmbed.SendToCurrentChannel(); - - return; - } - - switch (context.args[1]) { - case "add": - await this.AddLobbyConfig(context); - break; - case "remove": - await this.RemoveLobbyConfig(context); - break; - case "help": - default: - await this.SendConfigHelp(context); - } - } - - private async SendConfigHelp(context: ICommandContext) { - const helpText = readFileSync(`${process.cwd()}/data/usage/lobby.txt`).toString(); - - const embed = new PublicEmbed(context, "Configure Lobby Command", helpText); - await embed.SendToCurrentChannel(); - } - - private async AddLobbyConfig(context: ICommandContext) { - const channel = context.message.guild!.channels.cache.find(x => x.id == context.args[2]); - const role = context.message.guild!.roles.cache.find(x => x.id == context.args[3]); - const cooldown = Number(context.args[4]) || 30; - const gameName = context.args.splice(5).join(" "); - - if (!channel) { - const errorEmbed = new ErrorEmbed(context, "The channel id you provided is invalid or channel does not exist."); - errorEmbed.SendToCurrentChannel(); - - return; - } - - if (!role) { - const errorEmbed = new ErrorEmbed(context, "The role id you provided is invalid or role does not exist."); - errorEmbed.SendToCurrentChannel(); - - return; - } - - const lobby = await eLobby.FetchOneByChannelId(channel.id); - - if (lobby) { - const errorEmbed = new ErrorEmbed(context, "This channel has already been setup."); - errorEmbed.SendToCurrentChannel(); - - return; - } - - const entity = new eLobby(channel.id, role.id, cooldown, gameName); - await entity.Save(eLobby, entity); - - const embed = new PublicEmbed(context, "", `Added \`${channel.name}\` as a new lobby channel with a cooldown of \`${cooldown} minutes\` and will ping \`${role.name}\` on use`); - await embed.SendToCurrentChannel(); - } - - private async RemoveLobbyConfig(context: ICommandContext) { - const entity = await eLobby.FetchOneByChannelId(context.args[2]); - - if (!entity) { - const errorEmbed = new ErrorEmbed(context, "The channel id you provided has not been setup as a lobby, unable to remove."); - await errorEmbed.SendToCurrentChannel(); - - return; - } - - await BaseEntity.Remove(eLobby, entity); - - const embed = new PublicEmbed(context, "", `Removed <#${context.args[2]}> from the list of lobby channels`); - await embed.SendToCurrentChannel(); - } -} \ No newline at end of file diff --git a/src/commands/Role/config.ts b/src/commands/Role/config.ts new file mode 100644 index 0000000..93d6891 --- /dev/null +++ b/src/commands/Role/config.ts @@ -0,0 +1,54 @@ +import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; +import { Command } from "../../type/command"; +import { default as eRole } from "../../entity/Role"; +import Server from "../../entity/Server"; + +export default class ConfigRole extends Command { + constructor() { + super(); + + super.CommandBuilder = new SlashCommandBuilder() + .setName('configrole') + .setDescription('Toggle your roles') + .setDefaultMemberPermissions(PermissionsBitField.Flags.ManageRoles) + .addRoleOption(option => + option + .setName('role') + .setDescription('The role name') + .setRequired(true)); + } + + public override async execute(interaction: CommandInteraction) { + if (!interaction.guildId || !interaction.guild) return; + if (!interaction.member) return; + + const role = interaction.options.get('role'); + + if (!role || !role.role) { + await interaction.reply('Fields are required.'); + return; + } + + const existingRole = await eRole.FetchOneByRoleId(role.role.id); + + if (existingRole) { + await eRole.Remove(eRole, existingRole); + + await interaction.reply('Removed role from configuration.'); + } else { + const server = await Server.FetchOneById(Server, interaction.guildId); + + if (!server) { + await interaction.reply('This server has not been setup.'); + return; + } + + const newRole = new eRole(role.role.id); + newRole.SetServer(server); + + await newRole.Save(eRole, newRole); + + await interaction.reply('Added role to configuration.'); + } + } +} diff --git a/src/commands/Role/role.ts b/src/commands/Role/role.ts new file mode 100644 index 0000000..85b0abf --- /dev/null +++ b/src/commands/Role/role.ts @@ -0,0 +1,109 @@ +import { CommandInteraction, EmbedBuilder, GuildMemberRoleManager, SlashCommandBuilder } from "discord.js"; +import { Command } from "../../type/command"; +import { default as eRole } from "../../entity/Role"; +import EmbedColours from "../../constants/EmbedColours"; + +export default class Role extends Command { + constructor() { + super(); + + super.CommandBuilder = new SlashCommandBuilder() + .setName('role') + .setDescription('Toggle your roles') + .addSubcommand(subcommand => + subcommand + .setName('toggle') + .setDescription('Toggle your role') + .addRoleOption(option => + option + .setName('role') + .setDescription('The role name') + .setRequired(true))) + .addSubcommand(subcommand => + subcommand + .setName('list') + .setDescription('List togglable roles')); + } + + public override async execute(interaction: CommandInteraction) { + if (!interaction.isChatInputCommand()) return; + + switch (interaction.options.getSubcommand()) { + case 'toggle': + await this.ToggleRole(interaction); + break; + case 'list': + await this.SendRolesList(interaction); + break; + default: + await interaction.reply('Subcommand not found.'); + } + } + + private async SendRolesList(interaction: CommandInteraction) { + const roles = await this.GetRolesList(interaction); + + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Roles") + .setDescription(`Roles: ${roles.length}\n\n${roles.join("\n")}`); + + await interaction.reply({ embeds: [ embed ]}); + } + + private async ToggleRole(interaction: CommandInteraction) { + if (!interaction.guild) return; + if (!interaction.member) return; + + const roles = await this.GetRolesList(interaction); + const requestedRole = interaction.options.get('role'); + + if (!requestedRole || !requestedRole.role) { + await interaction.reply('Fields are required.'); + return; + } + + if (!roles.includes(requestedRole.role.name)) { + await interaction.reply('This role isn\'t marked as assignable.'); + return; + } + + const roleManager = interaction.member.roles as GuildMemberRoleManager; + + const userRole = roleManager.cache.find(x => x.name == requestedRole.role!.name); + const assignRole = interaction.guild.roles.cache.find(x => x.id == requestedRole.role!.id); + + if (!assignRole) return; + + if (!assignRole.editable) { + await interaction.reply('Insufficient permissions. Please contact a moderator.'); + return; + } + + if (!userRole) { + await roleManager.add(assignRole); + await interaction.reply(`Gave role: \`${assignRole.name}\``); + } else { + await roleManager.remove(assignRole); + await interaction.reply(`Removed role: \`${assignRole.name}\``); + } + } + + private async GetRolesList(interaction: CommandInteraction): Promise { + if (!interaction.guildId || !interaction.guild) return []; + + const rolesArray = await eRole.FetchAllByServerId(interaction.guildId); + + const roles: string[] = []; + + for (let i = 0; i < rolesArray.length; i++) { + const serverRole = interaction.guild.roles.cache.find(x => x.id == rolesArray[i].RoleId); + + if (serverRole) { + roles.push(serverRole.name); + } + } + + return roles; + } +} diff --git a/src/commands/about.ts b/src/commands/about.ts index b688df6..b1ad17b 100644 --- a/src/commands/about.ts +++ b/src/commands/about.ts @@ -1,42 +1,56 @@ -import { MessageActionRow, MessageButton } from "discord.js"; -import { MessageButtonStyles } from "discord.js/typings/enums"; -import { ICommandContext } from "../contracts/ICommandContext"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; +import EmbedColours from "../constants/EmbedColours"; import { Command } from "../type/command"; export default class About extends Command { constructor() { super(); - super.Category = "General"; + + super.CommandBuilder = new SlashCommandBuilder() + .setName('about') + .setDescription('About VylBot'); } - public override async execute(context: ICommandContext) { + public override async execute(interaction: CommandInteraction) { const fundingLink = process.env.ABOUT_FUNDING; const repoLink = process.env.ABOUT_REPO; - const embed = new PublicEmbed(context, "About", "") - .addField("Version", process.env.BOT_VER!, true) - .addField("Author", process.env.BOT_AUTHOR!, true) - .addField("Date", process.env.BOT_DATE!, true); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("About") + .setDescription("Discord Bot made by Vylpes"); - const row = new MessageActionRow(); + embed.addFields([ + { + name: "Version", + value: process.env.BOT_VER!, + inline: true, + }, + { + name: "Author", + value: process.env.BOT_AUTHOR!, + inline: true, + }, + ]) + + const row = new ActionRowBuilder(); if (repoLink) { row.addComponents( - new MessageButton() + new ButtonBuilder() .setURL(repoLink) .setLabel("Repo") - .setStyle(MessageButtonStyles.LINK)); + .setStyle(ButtonStyle.Link)); } if (fundingLink) { row.addComponents( - new MessageButton() + new ButtonBuilder() .setURL(fundingLink) .setLabel("Funding") - .setStyle(MessageButtonStyles.LINK)); + .setStyle(ButtonStyle.Link)); } - - await embed.SendToCurrentChannel({ components: [row] }); + + await interaction.reply({ embeds: [ embed ]}); } } \ No newline at end of file diff --git a/src/commands/audits.ts b/src/commands/audits.ts index c53fe37..3dabe26 100644 --- a/src/commands/audits.ts +++ b/src/commands/audits.ts @@ -1,144 +1,212 @@ -import { ICommandContext } from "../contracts/ICommandContext"; import Audit from "../entity/Audit"; import AuditTools from "../helpers/AuditTools"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; import { Command } from "../type/command"; -import SettingsHelper from "../helpers/SettingsHelper"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; +import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js"; +import { AuditType } from "../constants/AuditType"; +import EmbedColours from "../constants/EmbedColours"; export default class Audits extends Command { constructor() { super(); - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName("audits") + .setDescription("View audits of a particular user in the server") + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) + .addSubcommand(subcommand => + subcommand + .setName('user') + .setDescription('View all audits done against a user') + .addUserOption(option => + option + .setName('target') + .setDescription('The user') + .setRequired(true))) + .addSubcommand(subcommand => + subcommand + .setName('view') + .setDescription('View a particular audit') + .addStringOption(option => + option + .setName('auditid') + .setDescription('The audit id in caps') + .setRequired(true))) + .addSubcommand(subcommand => + subcommand + .setName('clear') + .setDescription('Clears an audit from a user') + .addStringOption(option => + option + .setName('auditid') + .setDescription('The audit id in caps') + .setRequired(true))) + .addSubcommand(subcommand => + subcommand + .setName('add') + .setDescription('Manually add an audit') + .addUserOption(option => + option + .setName('target') + .setDescription('The user') + .setRequired(true)) + .addStringOption(option => + option + .setName('type') + .setDescription('The type of audit') + .setRequired(true) + .addChoices( + { name: 'General', value: AuditType.General.toString() }, + { name: 'Warn', value: AuditType.Warn.toString() }, + { name: 'Mute', value: AuditType.Mute.toString() }, + { name: 'Kick', value: AuditType.Kick.toString() }, + { name: 'Ban', value: AuditType.Ban.toString() }, + ) + .setRequired(true)) + .addStringOption(option => + option + .setName('reason') + .setDescription('The reason'))); + } - public override async execute(context: ICommandContext) { - if (!context.message.guild) return; + public override async execute(interaction: CommandInteraction) { + if (!interaction.isChatInputCommand()) return; - switch (context.args[0]) { + switch (interaction.options.getSubcommand()) { case "user": - await this.SendAuditForUser(context); + await this.SendAuditForUser(interaction); break; case "view": - await this.SendAudit(context); + await this.SendAudit(interaction); break; case "clear": - await this.ClearAudit(context); + await this.ClearAudit(interaction); break; case "add": - await this.AddAudit(context); + await this.AddAudit(interaction); break; default: - await this.SendUsage(context); + await interaction.reply("Subcommand doesn't exist."); } } - private async SendUsage(context: ICommandContext) { - const prefix = await SettingsHelper.GetServerPrefix(context.message.guild!.id); + private async SendAuditForUser(interaction: CommandInteraction) { + if (!interaction.guildId) return; - const description = [ - `\`${prefix}audits user \` - Send the audits for this user`, - `\`${prefix}audits view \` - Send information about an audit`, - `\`${prefix}audits clear \` - Clears an audit for a user by audit id`, - `\`${prefix}audits add [reason]\` - Manually add an audit for a user`, - ] + const user = interaction.options.getUser('target'); - const publicEmbed = new PublicEmbed(context, "Usage", description.join("\n")); - await publicEmbed.SendToCurrentChannel(); - } + if (!user) { + await interaction.reply("User not found."); + return; + } - private async SendAuditForUser(context: ICommandContext) { - const userId = context.args[1]; - - const audits = await Audit.FetchAuditsByUserId(userId, context.message.guild!.id); + const audits = await Audit.FetchAuditsByUserId(user.id, interaction.guildId); if (!audits || audits.length == 0) { - const publicEmbed = new PublicEmbed(context, "", "There are no audits logged for this user."); - await publicEmbed.SendToCurrentChannel(); - + await interaction.reply("There are no audits for this user."); return; } - const publicEmbed = new PublicEmbed(context, "Audit Log", ""); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Audits") + .setDescription(`Audits: ${audits.length}`); for (let audit of audits) { - publicEmbed.addField(`${audit.AuditId} // ${AuditTools.TypeToFriendlyText(audit.AuditType)}`, audit.WhenCreated.toString()); + embed.addFields([ + { + name: `${audit.AuditId} // ${AuditTools.TypeToFriendlyText(audit.AuditType)}`, + value: audit.WhenCreated.toString(), + } + ]); } - await publicEmbed.SendToCurrentChannel(); + await interaction.reply({ embeds: [ embed ]}); } - private async SendAudit(context: ICommandContext) { - const auditId = context.args[1]; + private async SendAudit(interaction: CommandInteraction) { + if (!interaction.guildId) return; - if (!auditId) { - await this.SendUsage(context); + const auditId = interaction.options.get('auditid'); + + if (!auditId || !auditId.value) { + await interaction.reply("AuditId not found."); return; } - const audit = await Audit.FetchAuditByAuditId(auditId.toUpperCase(), context.message.guild!.id); + const audit = await Audit.FetchAuditByAuditId(auditId.value.toString().toUpperCase(), interaction.guildId); if (!audit) { - const errorEmbed = new ErrorEmbed(context, "This audit can not be found."); - await errorEmbed.SendToCurrentChannel(); - + await interaction.reply("Audit not found."); return; } - const publicEmbed = new PublicEmbed(context, `Audit ${audit.AuditId.toUpperCase()}`, ""); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Audit") + .setDescription(audit.AuditId.toUpperCase()) + .addFields([ + { + name: "Reason", + value: audit.Reason || "*none*", + inline: true, + }, + { + name: "Type", + value: AuditTools.TypeToFriendlyText(audit.AuditType), + inline: true, + }, + { + name: "Moderator", + value: `<@${audit.ModeratorId}>`, + inline: true, + }, + ]); - publicEmbed.addField("Reason", audit.Reason || "*none*", true); - publicEmbed.addField("Type", AuditTools.TypeToFriendlyText(audit.AuditType), true); - publicEmbed.addField("Moderator", `<@${audit.ModeratorId}>`, true); - - await publicEmbed.SendToCurrentChannel(); + await interaction.reply({ embeds: [ embed ]}); } - private async ClearAudit(context: ICommandContext) { - const auditId = context.args[1]; + private async ClearAudit(interaction: CommandInteraction) { + if (!interaction.guildId) return; - if (!auditId) { - await this.SendUsage(context); + const auditId = interaction.options.get('auditid'); + + if (!auditId || !auditId.value) { + await interaction.reply("AuditId not found."); return; } - const audit = await Audit.FetchAuditByAuditId(auditId.toUpperCase(), context.message.guild!.id); + const audit = await Audit.FetchAuditByAuditId(auditId.value.toString().toUpperCase(), interaction.guildId); if (!audit) { - const errorEmbed = new ErrorEmbed(context, "This audit can not be found."); - await errorEmbed.SendToCurrentChannel(); - + await interaction.reply("Audit not found."); return; } await Audit.Remove(Audit, audit); - const publicEmbed = new PublicEmbed(context, "", "Audit cleared"); - await publicEmbed.SendToCurrentChannel(); + await interaction.reply("Audit cleared."); } - private async AddAudit(context: ICommandContext) { - const userId = context.args[1]; - const typeString = context.args[2]; - const reason = context.args.splice(3) - .join(" "); + private async AddAudit(interaction: CommandInteraction) { + if (!interaction.guildId) return; + + const user = interaction.options.getUser('target'); + const auditType = interaction.options.get('type'); + const reasonInput = interaction.options.get('reason'); - if (!userId || !typeString) { - await this.SendUsage(context); + if (!user || !auditType || !auditType.value) { + await interaction.reply("Invalid input."); return; } - const type = AuditTools.StringToType(typeString); + const type = auditType.value as AuditType; + const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : ""; - const audit = new Audit(userId, type, reason, context.message.author.id, context.message.guild!.id); + const audit = new Audit(user.id, type, reason, interaction.user.id, interaction.guildId); await audit.Save(Audit, audit); - - const publicEmbed = new PublicEmbed(context, "", `Created new audit with ID \`${audit.AuditId}\``); - await publicEmbed.SendToCurrentChannel(); + + await interaction.reply(`Created new audit with ID \`${audit.AuditId}\``); } } \ No newline at end of file diff --git a/src/commands/ban.ts b/src/commands/ban.ts index 8d50132..a7f2d99 100644 --- a/src/commands/ban.ts +++ b/src/commands/ban.ts @@ -1,91 +1,79 @@ -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import ErrorMessages from "../constants/ErrorMessages"; -import LogEmbed from "../helpers/embeds/LogEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; import { Command } from "../type/command"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ICommandReturnContext from "../contracts/ICommandReturnContext"; import Audit from "../entity/Audit"; import { AuditType } from "../constants/AuditType"; +import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; +import EmbedColours from "../constants/EmbedColours"; +import SettingsHelper from "../helpers/SettingsHelper"; export default class Ban extends Command { constructor() { super(); - - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + + super.CommandBuilder = new SlashCommandBuilder() + .setName("ban") + .setDescription("Ban a member from the server with an optional reason") + .setDefaultMemberPermissions(PermissionsBitField.Flags.BanMembers) + .addUserOption(option => + option + .setName('target') + .setDescription('The user') + .setRequired(true)) + .addStringOption(option => + option + .setName('reason') + .setDescription('The reason')); } - public override async execute(context: ICommandContext): Promise { - const targetUser = context.message.mentions.users.first(); + public override async execute(interaction: CommandInteraction) { + if (!interaction.isChatInputCommand()) return; + if (!interaction.guildId) return; + if (!interaction.guild) return; - if (!targetUser) { - const embed = new ErrorEmbed(context, "User does not exist"); - await embed.SendToCurrentChannel(); + const targetUser = interaction.options.get('target'); + const reasonInput = interaction.options.get('reason'); - return { - commandContext: context, - embeds: [embed], - }; + if (!targetUser || !targetUser.user || !targetUser.member) { + await interaction.reply("User not found."); + return; } - const targetMember = context.message.guild?.members.cache.find(x => x.user.id == targetUser.id); + const member = targetUser.member as GuildMember; + const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : "*none*"; - if (!targetMember) { - const embed = new ErrorEmbed(context, "User is not in this server"); - await embed.SendToCurrentChannel(); + const logEmbed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Member Banned") + .setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``) + .addFields([ + { + name: "Moderator", + value: `<@${interaction.user.id}>`, + }, + { + name: "Reason", + value: reason, + }, + ]); - return { - commandContext: context, - embeds: [embed], - }; + if (!member.bannable) { + await interaction.reply('Insufficient permissions. Please contact a moderator.'); + return; } - const reasonArgs = context.args; - reasonArgs.splice(0, 1) - - const reason = reasonArgs.join(" "); - - if (!context.message.guild?.available) { - return { - commandContext: context, - embeds: [], - }; + await member.ban(); + await interaction.reply(`\`${targetUser.user.tag}\` has been banned.`); + + const channelName = await SettingsHelper.GetSetting('channels.logs.mod', interaction.guildId); + + if (!channelName) return; + + const channel = interaction.guild.channels.cache.find(x => x.name == channelName) as TextChannel; + + if (channel) { + await channel.send({ embeds: [ logEmbed ]}); } - if (!targetMember.bannable) { - const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed], - }; - } - - const logEmbed = new LogEmbed(context, "Member Banned"); - logEmbed.AddUser("User", targetUser, true); - logEmbed.AddUser("Moderator", context.message.author); - logEmbed.AddReason(reason); - - const publicEmbed = new PublicEmbed(context, "", `${targetUser} has been banned`); - - await targetMember.ban({ reason: `Moderator: ${context.message.author.tag}, Reason: ${reason || "*none*"}` }); - - await logEmbed.SendToModLogsChannel(); - await publicEmbed.SendToCurrentChannel(); - - if (context.message.guild) { - const audit = new Audit(targetUser.id, AuditType.Ban, reason, context.message.author.id, context.message.guild.id); - - await audit.Save(Audit, audit); - } - - return { - commandContext: context, - embeds: [logEmbed, publicEmbed], - }; + const audit = new Audit(targetUser.user.id, AuditType.Ban, reason, interaction.user.id, interaction.guildId); + await audit.Save(Audit, audit); } } \ No newline at end of file diff --git a/src/commands/bunny.ts b/src/commands/bunny.ts index a41e179..b735f61 100644 --- a/src/commands/bunny.ts +++ b/src/commands/bunny.ts @@ -1,17 +1,20 @@ -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; import { Command } from "../type/command"; -import { ICommandContext } from "../contracts/ICommandContext"; import randomBunny from "random-bunny"; +import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; +import EmbedColours from "../constants/EmbedColours"; export default class Bunny extends Command { constructor() { super(); - super.Category = "Fun"; + super.CommandBuilder = new SlashCommandBuilder() + .setName("bunny") + .setDescription("Get a random picture of a rabbit."); } - public override async execute(context: ICommandContext) { + public override async execute(interaction: CommandInteraction) { + if (!interaction.isChatInputCommand()) return; + const subreddits = [ 'rabbits', 'bunnieswithhats', @@ -26,15 +29,17 @@ export default class Bunny extends Command { const result = await randomBunny(selectedSubreddit, 'hot'); if (result.IsSuccess) { - const embed = new PublicEmbed(context, result.Result!.Title, "") + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle(result.Result!.Title) + .setDescription(result.Result!.Permalink) .setImage(result.Result!.Url) .setURL(`https://reddit.com${result.Result!.Permalink}`) - .setFooter({ text: `r/${selectedSubreddit} ยท ${result.Result!.Ups} upvotes` }); - - await embed.SendToCurrentChannel(); + .setFooter({ text: `r/${selectedSubreddit} ยท ${result.Result!.Ups} upvotes`}); + + await interaction.reply({ embeds: [ embed ]}); } else { - const errorEmbed = new ErrorEmbed(context, "There was an error using this command."); - await errorEmbed.SendToCurrentChannel(); + await interaction.reply("There was an error running this command."); } } } \ No newline at end of file diff --git a/src/commands/clear.ts b/src/commands/clear.ts index 1bd3e55..a448a7b 100644 --- a/src/commands/clear.ts +++ b/src/commands/clear.ts @@ -1,50 +1,43 @@ -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import { TextChannel } from "discord.js"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import { CommandInteraction, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { Command } from "../type/command"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ICommandReturnContext from "../contracts/ICommandReturnContext"; export default class Clear extends Command { constructor() { super(); - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName("clear") + .setDescription("Clears the channel of messages") + .setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages) + .addNumberOption(option => + option + .setName('count') + .setDescription('The amount to delete') + .setRequired(true) + .setMinValue(1) + .setMaxValue(100)); } - public override async execute(context: ICommandContext): Promise { - if (context.args.length == 0) { - const errorEmbed = new ErrorEmbed(context, "Please specify an amount between 1 and 100"); - await errorEmbed.SendToCurrentChannel(); + public override async execute(interaction: CommandInteraction) { + if (!interaction.isChatInputCommand()) return; + if (!interaction.channel) return; - return { - commandContext: context, - embeds: [errorEmbed] - }; - } - - const totalToClear = Number.parseInt(context.args[0]); + const totalToClear = interaction.options.getNumber('count'); if (!totalToClear || totalToClear <= 0 || totalToClear > 100) { - const errorEmbed = new ErrorEmbed(context, "Please specify an amount between 1 and 100"); - await errorEmbed.SendToCurrentChannel(); - return { - commandContext: context, - embeds: [errorEmbed] - }; + await interaction.reply('Please specify an amount between 1 and 100.'); + return; } - await (context.message.channel as TextChannel).bulkDelete(totalToClear); + const channel = interaction.channel as TextChannel; - const embed = new PublicEmbed(context, "", `${totalToClear} message(s) were removed`); - await embed.SendToCurrentChannel(); + if (!channel.manageable) { + await interaction.reply('Insufficient permissions. Please contact a moderator.'); + return; + } - return { - commandContext: context, - embeds: [embed] - }; + await channel.bulkDelete(totalToClear); + + await interaction.reply(`${totalToClear} message(s) were removed.`); } } \ No newline at end of file diff --git a/src/commands/code.ts b/src/commands/code.ts index cdfac96..2f0f7e2 100644 --- a/src/commands/code.ts +++ b/src/commands/code.ts @@ -1,7 +1,4 @@ -import { CommandResponse } from "../constants/CommandResponse"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import SettingsHelper from "../helpers/SettingsHelper"; import StringTools from "../helpers/StringTools"; import { Command } from "../type/command"; @@ -10,85 +7,58 @@ export default class Code extends Command { constructor() { super(); - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName('code') + .setDescription('Manage the verification code of the server') + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) + .addSubcommand(subcommand => + subcommand + .setName('randomise') + .setDescription('Regenerates the verification code for this server')) + .addSubcommand(subcommand => + subcommand + .setName('embed') + .setDescription('Sends the embed with the current code to the current channel')); } - public override async precheckAsync(context: ICommandContext): Promise { - if (!context.message.guild){ - return CommandResponse.NotInServer; - } + public override async execute(interaction: CommandInteraction) { + if (!interaction.isChatInputCommand()) return; - const isEnabled = await SettingsHelper.GetSetting("verification.enabled", context.message.guild?.id); - - if (!isEnabled) { - return CommandResponse.FeatureDisabled; - } - - if (isEnabled.toLocaleLowerCase() != 'true') { - return CommandResponse.FeatureDisabled; - } - - return CommandResponse.Ok; - } - - public override async execute(context: ICommandContext) { - const action = context.args[0]; - - switch (action) { + switch (interaction.options.getSubcommand()) { case "randomise": - await this.Randomise(context); + await this.Randomise(interaction); break; case "embed": - await this.SendEmbed(context); + await this.SendEmbed(interaction); break; - default: - await this.SendUsage(context); } } - private async SendUsage(context: ICommandContext) { - const description = [ - "USAGE: ", - "", - "randomise: Sets the server's entry code to a random code", - "embed: Sends an embed with the server's entry code" - ].join("\n"); - - const embed = new PublicEmbed(context, "", description); - await embed.SendToCurrentChannel(); - } - - private async Randomise(context: ICommandContext) { - if (!context.message.guild) { - return; - } + private async Randomise(interaction: CommandInteraction) { + if (!interaction.guildId) return; const randomCode = StringTools.RandomString(5); - await SettingsHelper.SetSetting("verification.code", context.message.guild.id, randomCode); + await SettingsHelper.SetSetting("verification.code", interaction.guildId, randomCode); - const embed = new PublicEmbed(context, "Code", `Entry code has been set to \`${randomCode}\``); - await embed.SendToCurrentChannel(); + await interaction.reply(`Entry code has been set to \`${randomCode}\``); } - private async SendEmbed(context: ICommandContext) { - if (!context.message.guild) { - return; - } + private async SendEmbed(interaction: CommandInteraction) { + if (!interaction.guildId) return; + if (!interaction.channel) return; - const code = await SettingsHelper.GetSetting("verification.code", context.message.guild.id); + const code = await SettingsHelper.GetSetting("verification.code", interaction.guildId); if (!code || code == "") { - const errorEmbed = new ErrorEmbed(context, "There is no code for this server setup."); - errorEmbed.SendToCurrentChannel(); - + await interaction.reply("There is no code for this server setup."); return; } - const embed = new PublicEmbed(context, "Entry Code", code!); - await embed.SendToCurrentChannel(); + const embed = new EmbedBuilder() + .setTitle("Entry Code") + .setDescription(code); + + await interaction.channel.send({ embeds: [ embed ]}); } } \ No newline at end of file diff --git a/src/commands/config.ts b/src/commands/config.ts index f3710e3..a370f27 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -1,126 +1,186 @@ +import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { readFileSync } from "fs"; -import { CommandResponse } from "../constants/CommandResponse"; import DefaultValues from "../constants/DefaultValues"; -import { ICommandContext } from "../contracts/ICommandContext"; +import EmbedColours from "../constants/EmbedColours"; import Server from "../entity/Server"; import Setting from "../entity/Setting"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; import { Command } from "../type/command"; export default class Config extends Command { constructor() { super(); - super.Category = "Administration"; - super.Roles = [ - "administrator" - ] + + super.CommandBuilder = new SlashCommandBuilder() + .setName('config') + .setDescription('Configure the current server') + .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator) + .addSubcommand(subcommand => + subcommand + .setName('reset') + .setDescription('Reset a setting to the default') + .addStringOption(option => + option + .setName('key') + .setDescription('The key') + .setRequired(true))) + .addSubcommand(subcommand => + subcommand + .setName('get') + .setDescription('Gets a setting for the server') + .addStringOption(option => + option + .setName('key') + .setDescription('The key') + .setRequired(true))) + .addSubcommand(subcommand => + subcommand + .setName('set') + .setDescription('Sets a setting to a specified value') + .addStringOption(option => + option + .setName('key') + .setDescription('The key') + .setRequired(true)) + .addStringOption(option => + option + .setName('value') + .setDescription('The value') + .setRequired(true))) + .addSubcommand(subcommand => + subcommand + .setName('list') + .setDescription('Lists all settings')) } - public override async precheckAsync(context: ICommandContext): Promise { - if (!context.message.guild) { - return CommandResponse.ServerNotSetup; - } + public override async execute(interaction: CommandInteraction) { + if (!interaction.isChatInputCommand()) return; + if (!interaction.guildId) return; - const server = await Server.FetchOneById(Server, context.message.guild?.id, [ + const server = await Server.FetchOneById(Server, interaction.guildId, [ "Settings", ]); if (!server) { - return CommandResponse.ServerNotSetup; - } - - return CommandResponse.Ok; - } - - public override async execute(context: ICommandContext) { - if (!context.message.guild) { + await interaction.reply('Server not setup. Please use the setup command,'); return; } - const server = await Server.FetchOneById(Server, context.message.guild?.id, [ - "Settings", - ]); - - if (!server) { - return; - } - - const key = context.args[0]; - const action = context.args[1]; - const value = context.args.splice(2).join(" "); - - if (!key) { - this.SendHelpText(context); - } else if (!action) { - this.GetValue(context, server, key); - } else { - switch(action) { - case 'reset': - this.ResetValue(context, server, key); - break; - case 'set': - if (!value) { - const errorEmbed = new ErrorEmbed(context, "Value is required when setting"); - errorEmbed.SendToCurrentChannel(); - return; - } - - this.SetValue(context, server, key, value); - break; - default: - const errorEmbed = new ErrorEmbed(context, "Action must be either set or reset"); - errorEmbed.SendToCurrentChannel(); - return; - } + switch (interaction.options.getSubcommand()) { + case 'list': + await this.SendHelpText(interaction); + break; + case 'reset': + await this.ResetValue(interaction); + break; + case 'get': + await this.GetValue(interaction); + break; + case 'set': + await this.SetValue(interaction); + break; + default: + await interaction.reply('Subcommand not found.'); } } - private async SendHelpText(context: ICommandContext) { + private async SendHelpText(interaction: CommandInteraction) { const description = readFileSync(`${process.cwd()}/data/usage/config.txt`).toString(); - const embed = new PublicEmbed(context, "Config", description); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Config") + .setDescription(description); - await embed.SendToCurrentChannel(); + await interaction.reply({ embeds: [ embed ]}); } - private async GetValue(context: ICommandContext, server: Server, key: string) { - const setting = server.Settings.filter(x => x.Key == key)[0]; + private async GetValue(interaction: CommandInteraction) { + if (!interaction.guildId) return; + + const key = interaction.options.get('key'); + + if (!key || !key.value) { + await interaction.reply('Fields are required.'); + return; + } + + const server = await Server.FetchOneById(Server, interaction.guildId, [ + "Settings", + ]); + + if (!server) { + await interaction.reply('Server not found.'); + return; + } + + const setting = server.Settings.filter(x => x.Key == key.value)[0]; if (setting) { - const embed = new PublicEmbed(context, "", `${key}: ${setting.Value}`); - await embed.SendToCurrentChannel(); + await interaction.reply(`\`${key}\`: \`${setting.Value}\``); } else { - const embed = new PublicEmbed(context, "", `${key}: ${DefaultValues.GetValue(key)} `); - await embed.SendToCurrentChannel(); + await interaction.reply(`\`${key}\`: \`${DefaultValues.GetValue(key.value.toString())}\` `); } } - private async ResetValue(context: ICommandContext, server: Server, key: string) { - const setting = server.Settings.filter(x => x.Key == key)[0]; + private async ResetValue(interaction: CommandInteraction) { + if (!interaction.guildId) return; + + const key = interaction.options.get('key'); + + if (!key || !key.value) { + await interaction.reply('Fields are required.'); + return; + } + + const server = await Server.FetchOneById(Server, interaction.guildId, [ + "Settings", + ]); + + if (!server) { + await interaction.reply('Server not found.'); + return; + } + + const setting = server.Settings.filter(x => x.Key == key.value)[0]; if (!setting) { - const embed = new PublicEmbed(context, "", "Setting has been reset"); - await embed.SendToCurrentChannel(); - + await interaction.reply('Setting not found.'); return; } await Setting.Remove(Setting, setting); - const embed = new PublicEmbed(context, "", "Setting has been reset"); - await embed.SendToCurrentChannel(); + await interaction.reply('The setting has been reset to the default.'); } - private async SetValue(context: ICommandContext, server: Server, key: string, value: string) { - const setting = server.Settings.filter(x => x.Key == key)[0]; + private async SetValue(interaction: CommandInteraction) { + if (!interaction.guildId) return; + + const key = interaction.options.get('key'); + const value = interaction.options.get('value'); + + if (!key || !key.value || !value || !value.value) { + await interaction.reply('Fields are required.'); + return; + } + + const server = await Server.FetchOneById(Server, interaction.guildId, [ + "Settings", + ]); + + if (!server) { + await interaction.reply('Server not found.'); + return; + } + + const setting = server.Settings.filter(x => x.Key == key.value)[0]; if (setting) { - setting.UpdateBasicDetails(key, value); + setting.UpdateBasicDetails(key.value.toString(), value.value.toString()); await setting.Save(Setting, setting); } else { - const newSetting = new Setting(key, value); + const newSetting = new Setting(key.value.toString(), value.value.toString()); await newSetting.Save(Setting, newSetting); @@ -129,7 +189,6 @@ export default class Config extends Command { await server.Save(Server, server); } - const embed = new PublicEmbed(context, "", "Setting has been set"); - await embed.SendToCurrentChannel(); + await interaction.reply('Setting has been set.'); } } \ No newline at end of file diff --git a/src/commands/disable.ts b/src/commands/disable.ts index 390da51..4cca622 100644 --- a/src/commands/disable.ts +++ b/src/commands/disable.ts @@ -1,5 +1,4 @@ -import { ICommandContext } from "../contracts/ICommandContext"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import SettingsHelper from "../helpers/SettingsHelper"; import { Command } from "../type/command"; @@ -7,87 +6,86 @@ export default class Disable extends Command { constructor() { super(); - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName('disable') + .setDescription('Disables a command') + .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator) + .addSubcommand(subcommand => + subcommand + .setName('add') + .setDescription('Disables a command for the server') + .addStringOption(option => + option + .setName('name') + .setDescription('The name of the command') + .setRequired(true))) + .addSubcommand(subcommand => + subcommand + .setName('remove') + .setDescription('Enables a command for the server') + .addStringOption(option => + option + .setName('name') + .setDescription('The name of the command') + .setRequired(true))); } - public override async execute(context: ICommandContext) { - const action = context.args[0]; + public override async execute(interaction: CommandInteraction) { + if (!interaction.isChatInputCommand()) return; - switch (action) { + switch (interaction.options.getSubcommand()) { case "add": - await this.Add(context); + await this.Add(interaction); break; case "remove": - await this.Remove(context); + await this.Remove(interaction); break; default: - await this.SendUsage(context); + await interaction.reply('Subcommand not found.'); } } - private async SendUsage(context: ICommandContext) { - const description = [ - "USAGE: ", - "", - "add: Adds the command name to the server's disabled command string", - "remove: Removes the command name from the server's disabled command string", - "name: The name of the command to enable/disable" - ].join("\n"); - - const embed = new PublicEmbed(context, "", description); - await embed.SendToCurrentChannel(); - } + private async Add(interaction: CommandInteraction) { + if (!interaction.guildId) return; - private async Add(context: ICommandContext) { - if (!context.message.guild) { + const commandName = interaction.options.get('name'); + + if (!commandName || !commandName.value) { + await interaction.reply('Fields are required.'); return; } - const commandName = context.args[1]; - - if (!commandName) { - this.SendUsage(context); - return; - } - - const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", context.message.guild.id); + const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", interaction.guildId); const disabledCommands = disabledCommandsString != "" ? disabledCommandsString?.split(",") : []; - disabledCommands?.push(commandName); + disabledCommands?.push(commandName.value.toString()); - await SettingsHelper.SetSetting("commands.disabled", context.message.guild.id, disabledCommands!.join(",")); + await SettingsHelper.SetSetting("commands.disabled", interaction.guildId, disabledCommands!.join(",")); - const embed = new PublicEmbed(context, "", `Disabled command: ${commandName}`); - await embed.SendToCurrentChannel(); + await interaction.reply(`Disabled command ${commandName.value}`); } - private async Remove(context: ICommandContext) { - if (!context.message.guild) { + private async Remove(interaction: CommandInteraction) { + if (!interaction.guildId) return; + + const commandName = interaction.options.get('name'); + + if (!commandName || !commandName.value) { + await interaction.reply('Fields are required.'); return; } - const commandName = context.args[1]; - - if (!commandName) { - this.SendUsage(context); - return; - } - - const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", context.message.guild.id); + const disabledCommandsString = await SettingsHelper.GetSetting("commands.disabled", interaction.guildId); const disabledCommands = disabledCommandsString != "" ? disabledCommandsString?.split(",") : []; - const disabledCommandsInstance = disabledCommands?.findIndex(x => x == commandName); + const disabledCommandsInstance = disabledCommands?.findIndex(x => x == commandName.value!.toString()); if (disabledCommandsInstance! > -1) { disabledCommands?.splice(disabledCommandsInstance!, 1); } - await SettingsHelper.SetSetting("commands.disabled", context.message.guild.id, disabledCommands!.join(",")); + await SettingsHelper.SetSetting("commands.disabled", interaction.guildId, disabledCommands!.join(",")); - const embed = new PublicEmbed(context, "", `Enabled command: ${commandName}`); - await embed.SendToCurrentChannel(); + await interaction.reply(`Enabled command ${commandName.value}`); } } \ No newline at end of file diff --git a/src/commands/help.ts b/src/commands/help.ts deleted file mode 100644 index 5366acf..0000000 --- a/src/commands/help.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { existsSync, readdirSync } from "fs"; -import { CoreClient } from "../client/client"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; -import StringTools from "../helpers/StringTools"; -import { Command } from "../type/command"; - -export interface ICommandData { - Exists: boolean; - Name?: string; - Category?: string; - Roles?: string[]; -} - -export default class Help extends Command { - constructor() { - super(); - - super.Category = "General"; - } - - public override async execute(context: ICommandContext) { - if (context.args.length == 0) { - await this.SendAll(context); - } else { - await this.SendSingle(context); - } - } - - public async SendAll(context: ICommandContext) { - const allCommands = CoreClient.commandItems - .filter(x => !x.ServerId || x.ServerId == context.message.guild?.id); - const cateogries = [...new Set(allCommands.map(x => x.Command.Category))]; - - const embed = new PublicEmbed(context, "Commands", ""); - - cateogries.forEach(category => { - let filtered = allCommands.filter(x => x.Command.Category == category); - - embed.addField(StringTools.Capitalise(category || "Uncategorised"), StringTools.CapitaliseArray(filtered.flatMap(x => x.Name)).join(", ")); - }); - - await embed.SendToCurrentChannel(); - } - - public async SendSingle(context: ICommandContext) { - const command = CoreClient.commandItems.find(x => x.Name == context.args[0] && !x.ServerId); - const exclusiveCommand = CoreClient.commandItems.find(x => x.Name == context.args[0] && x.ServerId == context.message.guild?.id); - - if (exclusiveCommand) { - const embed = new PublicEmbed(context, StringTools.Capitalise(exclusiveCommand.Name), ""); - embed.addField("Category", StringTools.Capitalise(exclusiveCommand.Command.Category || "Uncategorised")); - embed.addField("Required Roles", StringTools.Capitalise(exclusiveCommand.Command.Roles.join(", ")) || "Everyone"); - - await embed.SendToCurrentChannel(); - } else if (command) { - const embed = new PublicEmbed(context, StringTools.Capitalise(command.Name), ""); - embed.addField("Category", StringTools.Capitalise(command.Command.Category || "Uncategorised")); - embed.addField("Required Roles", StringTools.Capitalise(command.Command.Roles.join(", ")) || "Everyone"); - - await embed.SendToCurrentChannel(); - } else { - const errorEmbed = new ErrorEmbed(context, "Command does not exist"); - await errorEmbed.SendToCurrentChannel(); - } - } -} diff --git a/src/commands/ignore.ts b/src/commands/ignore.ts index 2bd3297..2367762 100644 --- a/src/commands/ignore.ts +++ b/src/commands/ignore.ts @@ -1,37 +1,34 @@ -import { ICommandContext } from "../contracts/ICommandContext"; +import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import IgnoredChannel from "../entity/IgnoredChannel"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; import { Command } from "../type/command"; export default class Ignore extends Command { constructor() { super(); - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName('ignore') + .setDescription('Ignore events in this channel') + .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator); } - public override async execute(context: ICommandContext) { - if (!context.message.guild) return; + public override async execute(interaction: CommandInteraction) { + if (!interaction.guildId) return; - const isChannelIgnored = await IgnoredChannel.IsChannelIgnored(context.message.channel.id); + const isChannelIgnored = await IgnoredChannel.IsChannelIgnored(interaction.guildId); if (isChannelIgnored) { - const entity = await IgnoredChannel.FetchOneById(IgnoredChannel, context.message.channel.id); + const entity = await IgnoredChannel.FetchOneById(IgnoredChannel, interaction.guildId); await IgnoredChannel.Remove(IgnoredChannel, entity); - const embed = new PublicEmbed(context, "Success", "This channel will start being logged again."); - await embed.SendToCurrentChannel(); + await interaction.reply('This channel will start being logged again.'); } else { - const entity = new IgnoredChannel(context.message.channel.id); + const entity = new IgnoredChannel(interaction.guildId); await entity.Save(IgnoredChannel, entity); - const embed = new PublicEmbed(context, "Success", "This channel will now be ignored from logging."); - await embed.SendToCurrentChannel(); + await interaction.reply('This channel will now be ignored from logging.'); } } } \ No newline at end of file diff --git a/src/commands/kick.ts b/src/commands/kick.ts index c1b2572..6ddee0c 100644 --- a/src/commands/kick.ts +++ b/src/commands/kick.ts @@ -1,91 +1,79 @@ -import { AuditType } from "../constants/AuditType"; -import ErrorMessages from "../constants/ErrorMessages"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ICommandReturnContext from "../contracts/ICommandReturnContext"; -import Audit from "../entity/Audit"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import LogEmbed from "../helpers/embeds/LogEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; import { Command } from "../type/command"; +import Audit from "../entity/Audit"; +import { AuditType } from "../constants/AuditType"; +import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; +import EmbedColours from "../constants/EmbedColours"; +import SettingsHelper from "../helpers/SettingsHelper"; export default class Kick extends Command { constructor() { super(); - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName("kick") + .setDescription("Kick a member from the server with an optional reason") + .setDefaultMemberPermissions(PermissionsBitField.Flags.KickMembers) + .addUserOption(option => + option + .setName('target') + .setDescription('The user') + .setRequired(true)) + .addStringOption(option => + option + .setName('reason') + .setDescription('The reason')); } - public override async execute(context: ICommandContext): Promise { - const targetUser = context.message.mentions.users.first(); + public override async execute(interaction: CommandInteraction) { + if (!interaction.isChatInputCommand()) return; + if (!interaction.guildId) return; + if (!interaction.guild) return; - if (!targetUser) { - const embed = new ErrorEmbed(context, "User does not exist"); - await embed.SendToCurrentChannel(); + const targetUser = interaction.options.get('target'); + const reasonInput = interaction.options.get('reason'); - return { - commandContext: context, - embeds: [embed] - }; + if (!targetUser || !targetUser.user || !targetUser.member) { + await interaction.reply("User not found."); + return; } - const targetMember = context.message.guild?.members.cache.find(x => x.user.id == targetUser.id); + const member = targetUser.member as GuildMember; + const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : "*none*"; - if (!targetMember) { - const embed = new ErrorEmbed(context, "User is not in this server"); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; - } - - const reasonArgs = context.args; - reasonArgs.splice(0, 1) + const logEmbed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Member Kicked") + .setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``) + .addFields([ + { + name: "Moderator", + value: `<@${interaction.user.id}>`, + }, + { + name: "Reason", + value: reason, + }, + ]); - const reason = reasonArgs.join(" "); - - if (!context.message.guild?.available) { - return { - commandContext: context, - embeds: [] - }; + if (!member.kickable) { + await interaction.reply('Insufficient permissions. Please contact a moderator.'); + return; } - if (!targetMember.kickable) { - const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; + await member.kick(); + await interaction.reply(`\`${targetUser.user.tag}\` has been kicked.`); + + const channelName = await SettingsHelper.GetSetting('channels.logs.mod', interaction.guildId); + + if (!channelName) return; + + const channel = interaction.guild.channels.cache.find(x => x.name == channelName) as TextChannel; + + if (channel) { + await channel.send({ embeds: [ logEmbed ]}); } - const logEmbed = new LogEmbed(context, "Member Kicked"); - logEmbed.AddUser("User", targetUser, true); - logEmbed.AddUser("Moderator", context.message.author); - logEmbed.AddReason(reason); - - const publicEmbed = new PublicEmbed(context, "", `${targetUser} has been kicked`); - - await targetMember.kick(`Moderator: ${context.message.author.tag}, Reason: ${reason || "*none*"}`); - - await logEmbed.SendToModLogsChannel(); - await publicEmbed.SendToCurrentChannel(); - - if (context.message.guild) { - const audit = new Audit(targetUser.id, AuditType.Kick, reason, context.message.author.id, context.message.guild.id); - - await audit.Save(Audit, audit); - } - - return { - commandContext: context, - embeds: [logEmbed, publicEmbed] - }; + const audit = new Audit(targetUser.user.id, AuditType.Kick, reason, interaction.user.id, interaction.guildId); + await audit.Save(Audit, audit); } } \ No newline at end of file diff --git a/src/commands/mute.ts b/src/commands/mute.ts index 7a45b87..d3b1493 100644 --- a/src/commands/mute.ts +++ b/src/commands/mute.ts @@ -1,104 +1,83 @@ +import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { AuditType } from "../constants/AuditType"; -import ErrorMessages from "../constants/ErrorMessages"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ICommandReturnContext from "../contracts/ICommandReturnContext"; +import EmbedColours from "../constants/EmbedColours"; import Audit from "../entity/Audit"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import LogEmbed from "../helpers/embeds/LogEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import SettingsHelper from "../helpers/SettingsHelper"; import { Command } from "../type/command"; export default class Mute extends Command { constructor() { super(); - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName("mute") + .setDescription("Mute a member in the server with an optional reason") + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) + .addUserOption(option => + option + .setName('target') + .setDescription('The user') + .setRequired(true)) + .addStringOption(option => + option + .setName('reason') + .setDescription('The reason')); } - public override async execute(context: ICommandContext): Promise { - const targetUser = context.message.mentions.users.first(); + public override async execute(interaction: CommandInteraction) { + if (!interaction.guild || !interaction.guildId) return; - if (!targetUser) { - const embed = new ErrorEmbed(context, "User does not exist"); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; + const targetUser = interaction.options.get('target'); + const reasonInput = interaction.options.get('reason'); + + if (!targetUser || !targetUser.user || !targetUser.member) { + await interaction.reply('Fields are required.'); + return; } - const targetMember = context.message.guild?.members.cache.find(x => x.user.id == targetUser.id); + const targetMember = targetUser.member as GuildMember; + const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : "*none*"; - if (!targetMember) { - const embed = new ErrorEmbed(context, "User is not in this server"); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; - } + const logEmbed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Member Muted") + .setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``) + .addFields([ + { + name: "Moderator", + value: `<@${interaction.user.id}>`, + }, + { + name: "Reason", + value: reason, + }, + ]); - const reasonArgs = context.args; - reasonArgs.splice(0, 1); + const mutedRole = interaction.guild.roles.cache.find(role => role.name == process.env.ROLES_MUTED); - const reason = reasonArgs.join(" "); - - if (!context.message.guild?.available) { - return { - commandContext: context, - embeds: [] - }; + if (!mutedRole) { + await interaction.reply('Muted role not found.'); + return; } if (!targetMember.manageable) { - const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; + await interaction.reply('Insufficient permissions. Please contact a moderator.'); + return; } - const logEmbed = new LogEmbed(context, "Member Muted"); - logEmbed.AddUser("User", targetUser, true) - logEmbed.AddUser("Moderator", context.message.author); - logEmbed.AddReason(reason); + await targetMember.roles.add(mutedRole); - const publicEmbed = new PublicEmbed(context, "", `${targetUser} has been muted`); - publicEmbed.AddReason(reason); + const channelName = await SettingsHelper.GetSetting('channels.logs.mod', interaction.guildId); - const mutedRole = context.message.guild.roles.cache.find(role => role.name == process.env.ROLES_MUTED); + if (!channelName) return; - if (!mutedRole) { - const embed = new ErrorEmbed(context, ErrorMessages.RoleNotFound); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; + const channel = interaction.guild.channels.cache.find(x => x.name == channelName) as TextChannel; + + if (channel) { + await channel.send({ embeds: [ logEmbed ]}); } - await targetMember.roles.add(mutedRole, `Moderator: ${context.message.author.tag}, Reason: ${reason || "*none*"}`); - - await logEmbed.SendToModLogsChannel(); - await publicEmbed.SendToCurrentChannel(); - - if (context.message.guild) { - const audit = new Audit(targetUser.id, AuditType.Mute, reason, context.message.author.id, context.message.guild.id); - - await audit.Save(Audit, audit); - } - - return { - commandContext: context, - embeds: [logEmbed, publicEmbed] - }; + const audit = new Audit(targetUser.user.id, AuditType.Mute, reason, interaction.user.id, interaction.guildId); + await audit.Save(Audit, audit); } } \ No newline at end of file diff --git a/src/commands/poll.ts b/src/commands/poll.ts deleted file mode 100644 index 3e84220..0000000 --- a/src/commands/poll.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { ICommandContext } from "../contracts/ICommandContext"; -import ICommandReturnContext from "../contracts/ICommandReturnContext"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; -import { Command } from "../type/command"; - -export default class Poll extends Command { - constructor() { - super(); - - super.Category = "General"; - } - - public override async execute(context: ICommandContext): Promise { - const argsJoined = context.args.join(" "); - const argsSplit = argsJoined.split(";"); - - if (argsSplit.length < 3 || argsSplit.length > 10) { - const errorEmbed = new ErrorEmbed(context, "Usage: ;<option 1>;<option 2>... (separate options with semicolons), maximum of 9 options"); - await errorEmbed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [errorEmbed] - }; - } - - const title = argsSplit[0]; - - const arrayOfNumbers = [ - ':one:', - ':two:', - ':three:', - ':four:', - ':five:', - ':six:', - ':seven:', - ':eight:', - ':nine:' - ]; - - const reactionEmojis = ["1๏ธโƒฃ", "2๏ธโƒฃ", "3๏ธโƒฃ", "4๏ธโƒฃ", "5๏ธโƒฃ", "6๏ธโƒฃ", "7๏ธโƒฃ", "8๏ธโƒฃ", "9๏ธโƒฃ"]; - - const description = arrayOfNumbers.splice(0, argsSplit.length - 1); - - description.forEach((value, index) => { - description[index] = `${value} ${argsSplit[index + 1]}`; - }); - - const embed = new PublicEmbed(context, title, description.join("\n")); - - const message = await context.message.channel.send({ embeds: [ embed ]}); - - description.forEach(async (value, index) => { - await message.react(reactionEmojis[index]); - }); - - if (context.message.deletable) { - await context.message.delete(); - } - - return { - commandContext: context, - embeds: [embed] - }; - } -} \ No newline at end of file diff --git a/src/commands/role.ts b/src/commands/role.ts deleted file mode 100644 index 952b590..0000000 --- a/src/commands/role.ts +++ /dev/null @@ -1,232 +0,0 @@ -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; -import { Role as DiscordRole } from "discord.js"; -import { Command } from "../type/command"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ICommandReturnContext from "../contracts/ICommandReturnContext"; -import SettingsHelper from "../helpers/SettingsHelper"; -import { readFileSync } from "fs"; -import { default as eRole } from "../entity/Role"; -import Server from "../entity/Server"; - -export default class Role extends Command { - constructor() { - super(); - - super.Category = "General"; - } - - public override async execute(context: ICommandContext) { - if (!context.message.guild) return; - - switch (context.args[0]) { - case "config": - await this.UseConfig(context); - break; - default: - await this.UseDefault(context); - } - } - - // ======= - // Default - // ======= - - private async UseDefault(context: ICommandContext) { - if (context.args.length == 0) { - await this.SendRolesList(context, context.message.guild!.id); - } else { - await this.ToggleRole(context); - } - } - - public async GetRolesList(context: ICommandContext): Promise<string[]> { - const rolesArray = await eRole.FetchAllByServerId(context.message.guild!.id); - - const stringArray: string[] = []; - - for (let i = 0; i < rolesArray.length; i++) { - const serverRole = context.message.guild!.roles.cache.find(x => x.id == rolesArray[i].RoleId); - - if (serverRole) { - stringArray.push(serverRole.name); - } - } - - return stringArray; - } - - public async SendRolesList(context: ICommandContext, serverId: string): Promise<ICommandReturnContext> { - const roles = await this.GetRolesList(context); - - const botPrefix = await SettingsHelper.GetServerPrefix(serverId); - const description = roles.length == 0 ? "*no roles*" : `Do ${botPrefix}role <role> to get the role!\n\n${roles.join('\n')}`; - - const embed = new PublicEmbed(context, "Roles", description); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; - } - - public async ToggleRole(context: ICommandContext): Promise<ICommandReturnContext> { - const roles = await this.GetRolesList(context); - const requestedRole = context.args.join(" "); - - if (!roles.includes(requestedRole)) { - const errorEmbed = new ErrorEmbed(context, "This role isn't marked as assignable, to see a list of assignable roles, run this command without any parameters"); - await errorEmbed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [errorEmbed] - }; - } - - const assignRole = context.message.guild?.roles.cache.find(x => x.name == requestedRole); - - if (!assignRole) { - const errorEmbed = new ErrorEmbed(context, "The current server doesn't have this role. Please contact the server's moderators"); - await errorEmbed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [errorEmbed] - }; - } - - const role = context.message.member?.roles.cache.find(x => x.name == requestedRole) - - if (!role) { - await this.AddRole(context, assignRole); - } else { - await this.RemoveRole(context, assignRole); - } - - return { - commandContext: context, - embeds: [] - }; - } - - public async AddRole(context: ICommandContext, role: DiscordRole): Promise<ICommandReturnContext> { - await context.message.member?.roles.add(role, "Toggled with role command"); - - const embed = new PublicEmbed(context, "", `Gave role: \`${role.name}\``); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; - } - - public async RemoveRole(context: ICommandContext, role: DiscordRole): Promise<ICommandReturnContext> { - await context.message.member?.roles.remove(role, "Toggled with role command"); - - const embed = new PublicEmbed(context, "", `Removed role: \`${role.name}\``); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; - } - - // ====== - // Config - // ====== - - private async UseConfig(context: ICommandContext) { - const moderatorRole = await SettingsHelper.GetSetting("role.moderator", context.message.guild!.id); - - if (!context.message.member?.roles.cache.find(x => x.name == moderatorRole)) { - const errorEmbed = new ErrorEmbed(context, "Sorry, you must be a moderator to be able to configure this command"); - await errorEmbed.SendToCurrentChannel(); - - return; - } - - switch (context.args[1]) { - case "add": - await this.AddRoleConfig(context); - break; - case "remove": - await this.RemoveRoleConfig(context); - break; - default: - await this.SendConfigHelp(context); - } - } - - private async SendConfigHelp(context: ICommandContext) { - const helpText = readFileSync(`${process.cwd()}/data/usage/role.txt`).toString(); - - const embed = new PublicEmbed(context, "Configure Role Command", helpText); - await embed.SendToCurrentChannel(); - } - - private async AddRoleConfig(context: ICommandContext) { - const role = context.message.guild!.roles.cache.find(x => x.id == context.args[2]); - - if (!role) { - this.SendConfigHelp(context); - return; - } - - const existingRole = await eRole.FetchOneByRoleId(role.id); - - if (existingRole) { - const errorEmbed = new ErrorEmbed(context, "This role has already been setup"); - await errorEmbed.SendToCurrentChannel(); - - return; - } - - const server = await Server.FetchOneById(Server, context.message.guild!.id, [ - "Roles", - ]); - - if (!server) { - const errorEmbed = new ErrorEmbed(context, "Server not setup, please request the server owner runs the setup command."); - await errorEmbed.SendToCurrentChannel(); - - return; - } - - const roleSetting = new eRole(role.id); - - await roleSetting.Save(eRole, roleSetting); - - server.AddRoleToServer(roleSetting); - await server.Save(Server, server); - - const embed = new PublicEmbed(context, "", `Added \`${role.name}\` as a new assignable role`); - await embed.SendToCurrentChannel(); - } - - private async RemoveRoleConfig(context: ICommandContext) { - const role = context.message.guild!.roles.cache.find(x => x.id == context.args[2]); - - if (!role) { - this.SendConfigHelp(context); - return; - } - - const existingRole = await eRole.FetchOneByRoleId(role.id); - - if (!existingRole) { - const errorEmbed = new ErrorEmbed(context, "Unable to find this role"); - errorEmbed.SendToCurrentChannel(); - - return; - } - - await eRole.Remove(eRole, existingRole); - - const embed = new PublicEmbed(context, "", `Removed \`${role.name}\` from the list of assignable roles`); - await embed.SendToCurrentChannel(); - } -} diff --git a/src/commands/rules.ts b/src/commands/rules.ts index 8730057..f6a6406 100644 --- a/src/commands/rules.ts +++ b/src/commands/rules.ts @@ -1,7 +1,6 @@ +import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { existsSync, readFileSync } from "fs"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import EmbedColours from "../constants/EmbedColours"; import { Command } from "../type/command"; interface IRules { @@ -15,38 +14,48 @@ export default class Rules extends Command { constructor() { super(); - super.Category = "Admin"; - super.Roles = [ - "administrator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName("rules") + .setDescription("Send the rules embeds for this server") + .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator); } - public override async execute(context: ICommandContext) { - if (!existsSync(`${process.cwd()}/data/rules/${context.message.guild?.id}.json`)) { - const errorEmbed = new ErrorEmbed(context, "Rules file doesn't exist"); - await errorEmbed.SendToCurrentChannel(); + public override async execute(interaction: CommandInteraction) { + if (!interaction.guildId) return; + if (!existsSync(`${process.cwd()}/data/rules/${interaction.guildId}.json`)) { + await interaction.reply('Rules file doesn\'t exist.'); return; } - const rulesFile = readFileSync(`${process.cwd()}/data/rules/${context.message.guild?.id}.json`).toString(); + const rulesFile = readFileSync(`${process.cwd()}/data/rules/${interaction.guildId}.json`).toString(); const rules = JSON.parse(rulesFile) as IRules[]; - const embeds: PublicEmbed[] = []; + const embeds: EmbedBuilder[] = []; rules.forEach(rule => { - const embed = new PublicEmbed(context, rule.title || "", rule.description?.join("\n") || ""); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle(rule.title || "Rules") + .setDescription(rule.description ? rule.description.join("\n") : "*none*"); + + if (rule.image) { + embed.setImage(rule.image); + } - embed.setImage(rule.image || ""); - embed.setFooter({ text: rule.footer || "" }); + if (rule.footer) { + embed.setFooter({ text: rule.footer }); + } embeds.push(embed); }); - for (let i = 0; i < embeds.length; i++) { - const embed = embeds[i]; + const channel = interaction.channel; - await embed.SendToCurrentChannel(); + if (!channel) { + return; } + + await channel.send({ embeds: embeds }); } } \ No newline at end of file diff --git a/src/commands/say.ts b/src/commands/say.ts deleted file mode 100644 index 433b2b8..0000000 --- a/src/commands/say.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ICommandContext } from "../contracts/ICommandContext"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import { Command } from "../type/command"; - -export default class Say extends Command { - constructor() { - super(); - super.Category = "Misc"; - super.Roles = [ - "moderator" - ]; - } - - public override async execute(context: ICommandContext) { - const input = context.args.join(" "); - - if (input.length == 0) { - const errorEmbed = new ErrorEmbed(context, "You must supply a message."); - - await errorEmbed.SendToCurrentChannel(); - return; - } - - context.message.channel.send(input); - } -} \ No newline at end of file diff --git a/src/commands/setup.ts b/src/commands/setup.ts index 8267ff1..6676ef8 100644 --- a/src/commands/setup.ts +++ b/src/commands/setup.ts @@ -1,37 +1,31 @@ -import { ICommandContext } from "../contracts/ICommandContext"; +import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import Server from "../entity/Server"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; import { Command } from "../type/command"; export default class Setup extends Command { constructor() { super(); - super.Category = "Administration"; - super.Roles = [ - "moderator" - ] + + super.CommandBuilder = new SlashCommandBuilder() + .setName('setup') + .setDescription('Makes the server ready to be configured') + .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator); } - public override async execute(context: ICommandContext) { - if (!context.message.guild) { - return; - } + public override async execute(interaction: CommandInteraction) { + if (!interaction.guildId) return; - const server = await Server.FetchOneById(Server, context.message.guild?.id); + const server = await Server.FetchOneById(Server, interaction.guildId); if (server) { - const embed = new ErrorEmbed(context, "This server has already been setup, please configure using the config command"); - await embed.SendToCurrentChannel(); - + await interaction.reply('This server has already been setup, please configure using the config command.'); return; } - const newServer = new Server(context.message.guild?.id); + const newServer = new Server(interaction.guildId); await newServer.Save(Server, newServer); - const embed = new PublicEmbed(context, "Success", "Please configure using the config command"); - await embed.SendToCurrentChannel(); + await interaction.reply('Success, please configure using the configure command.'); } } \ No newline at end of file diff --git a/src/commands/unmute.ts b/src/commands/unmute.ts index b006dab..59817f8 100644 --- a/src/commands/unmute.ts +++ b/src/commands/unmute.ts @@ -1,96 +1,78 @@ -import ErrorMessages from "../constants/ErrorMessages"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ICommandReturnContext from "../contracts/ICommandReturnContext"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import LogEmbed from "../helpers/embeds/LogEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; +import EmbedColours from "../constants/EmbedColours"; +import SettingsHelper from "../helpers/SettingsHelper"; import { Command } from "../type/command"; export default class Unmute extends Command { constructor() { super(); - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName("unmute") + .setDescription("Unmute a member in the server with an optional reason") + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) + .addUserOption(option => + option + .setName('target') + .setDescription('The user') + .setRequired(true)) + .addStringOption(option => + option + .setName('reason') + .setDescription('The reason')); } - public override async execute(context: ICommandContext): Promise<ICommandReturnContext> { - const targetUser = context.message.mentions.users.first(); + public override async execute(interaction: CommandInteraction) { + if (!interaction.guild || !interaction.guildId) return; - if (!targetUser) { - const embed = new ErrorEmbed(context, "User does not exist"); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; + const targetUser = interaction.options.get('target'); + const reasonInput = interaction.options.get('reason'); + + if (!targetUser || !targetUser.user || !targetUser.member) { + await interaction.reply('Fields are required.'); + return; } - const targetMember = context.message.guild?.members.cache.find(x => x.user.id == targetUser.id); + const targetMember = targetUser.member as GuildMember; + const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : "*none*"; - if (!targetMember) { - const embed = new ErrorEmbed(context, "User is not in this server"); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; - } + const logEmbed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Member Unmuted") + .setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``) + .addFields([ + { + name: "Moderator", + value: `<@${interaction.user.id}>`, + }, + { + name: "Reason", + value: reason, + }, + ]); - const reasonArgs = context.args; - reasonArgs.splice(0, 1); + const mutedRole = interaction.guild.roles.cache.find(role => role.name == process.env.ROLES_MUTED); - const reason = reasonArgs.join(" "); - - if (!context.message.guild?.available) { - return { - commandContext: context, - embeds: [] - }; + if (!mutedRole) { + await interaction.reply('Muted role not found.'); + return; } if (!targetMember.manageable) { - const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; + await interaction.reply('Insufficient permissions. Please contact a moderator.'); + return; } - const logEmbed = new LogEmbed(context, "Member Unmuted"); - logEmbed.AddUser("User", targetUser, true) - logEmbed.AddUser("Moderator", context.message.author); - logEmbed.AddReason(reason); + await targetMember.roles.remove(mutedRole); - const publicEmbed = new PublicEmbed(context, "", `${targetUser} has been unmuted`); - publicEmbed.AddReason(reason); + const channelName = await SettingsHelper.GetSetting('channels.logs.mod', interaction.guildId); - const mutedRole = context.message.guild.roles.cache.find(role => role.name == process.env.ROLES_MUTED); + if (!channelName) return; - if (!mutedRole) { - const embed = new ErrorEmbed(context, ErrorMessages.RoleNotFound); - await embed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [embed] - }; + const channel = interaction.guild.channels.cache.find(x => x.name == channelName) as TextChannel; + + if (channel) { + await channel.send({ embeds: [ logEmbed ]}); } - - await targetMember.roles.remove(mutedRole, `Moderator: ${context.message.author.tag}, Reason: ${reason || "*none*"}`); - - await logEmbed.SendToModLogsChannel(); - await publicEmbed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [logEmbed, publicEmbed] - }; } } \ No newline at end of file diff --git a/src/commands/warn.ts b/src/commands/warn.ts index 00f9efe..5a41985 100644 --- a/src/commands/warn.ts +++ b/src/commands/warn.ts @@ -1,79 +1,69 @@ +import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { AuditType } from "../constants/AuditType"; -import { ICommandContext } from "../contracts/ICommandContext"; -import ICommandReturnContext from "../contracts/ICommandReturnContext"; +import EmbedColours from "../constants/EmbedColours"; import Audit from "../entity/Audit"; -import ErrorEmbed from "../helpers/embeds/ErrorEmbed"; -import LogEmbed from "../helpers/embeds/LogEmbed"; -import PublicEmbed from "../helpers/embeds/PublicEmbed"; +import SettingsHelper from "../helpers/SettingsHelper"; import { Command } from "../type/command"; export default class Warn extends Command { constructor() { super(); - super.Category = "Moderation"; - super.Roles = [ - "moderator" - ]; + super.CommandBuilder = new SlashCommandBuilder() + .setName("warn") + .setDescription("Warns a member in the server with an optional reason") + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) + .addUserOption(option => + option + .setName('target') + .setDescription('The user') + .setRequired(true)) + .addStringOption(option => + option + .setName('reason') + .setDescription('The reason')); } - public override async execute(context: ICommandContext): Promise<ICommandReturnContext> { - const user = context.message.mentions.users.first(); + public override async execute(interaction: CommandInteraction) { + if (!interaction.guild || !interaction.guildId) return; - if (!user) { - const errorEmbed = new ErrorEmbed(context, "User does not exist"); - await errorEmbed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [errorEmbed] - }; + const targetUser = interaction.options.get('target'); + const reasonInput = interaction.options.get('reason'); + + if (!targetUser || !targetUser.user || !targetUser.member) { + await interaction.reply('Fields are required.'); + return; } - const member = context.message.guild?.members.cache.find(x => x.user.id == user.id); + const targetMember = targetUser.member as GuildMember; + const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : "*none*"; - if (!member) { - const errorEmbed = new ErrorEmbed(context, "User is not in this server"); - await errorEmbed.SendToCurrentChannel(); - - return { - commandContext: context, - embeds: [errorEmbed] - }; + const logEmbed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Member Warned") + .setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``) + .addFields([ + { + name: "Moderator", + value: `<@${interaction.user.id}>`, + }, + { + name: "Reason", + value: reason, + }, + ]); + + const channelName = await SettingsHelper.GetSetting('channels.logs.mod', interaction.guildId); + + if (!channelName) return; + + const channel = interaction.guild.channels.cache.find(x => x.name == channelName) as TextChannel; + + if (channel) { + await channel.send({ embeds: [ logEmbed ]}); } - const reasonArgs = context.args; - reasonArgs.splice(0, 1); - - const reason = reasonArgs.join(" "); - - if (!context.message.guild?.available) { - return { - commandContext: context, - embeds: [] - }; - } - - const logEmbed = new LogEmbed(context, "Member Warned"); - logEmbed.AddUser("User", user, true); - logEmbed.AddUser("Moderator", context.message.author); - logEmbed.AddReason(reason); - - const publicEmbed = new PublicEmbed(context, "", `${user} has been warned`); - publicEmbed.AddReason(reason); - - await logEmbed.SendToModLogsChannel(); - await publicEmbed.SendToCurrentChannel(); - - if (context.message.guild) { - const audit = new Audit(user.id, AuditType.Warn, reason, context.message.author.id, context.message.guild.id); - - await audit.Save(Audit, audit); - } - - return { - commandContext: context, - embeds: [logEmbed, publicEmbed] - }; + const audit = new Audit(targetUser.user.id, AuditType.Warn, reason, interaction.user.id, interaction.guildId); + await audit.Save(Audit, audit); } } \ No newline at end of file diff --git a/src/constants/CommandResponse.ts b/src/constants/CommandResponse.ts deleted file mode 100644 index b876ce8..0000000 --- a/src/constants/CommandResponse.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum CommandResponse { - Ok, - Unauthorised, - ServerNotSetup, - NotInServer, - FeatureDisabled, -} \ No newline at end of file diff --git a/src/constants/EmbedColours.ts b/src/constants/EmbedColours.ts new file mode 100644 index 0000000..023c77a --- /dev/null +++ b/src/constants/EmbedColours.ts @@ -0,0 +1,3 @@ +export default class EmbedColours { + public static readonly Ok = 0x3050ba; +} \ No newline at end of file diff --git a/src/constants/ErrorMessages.ts b/src/constants/ErrorMessages.ts deleted file mode 100644 index 588a143..0000000 --- a/src/constants/ErrorMessages.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { CommandResponse } from "./CommandResponse"; - -export default class ErrorMessages { - public static readonly InsufficientBotPermissions = "Unable to do this action, am I missing permissions?"; - public static readonly ChannelNotFound = "Unable to find channel"; - public static readonly RoleNotFound = "Unable to find role"; - - public static readonly UserUnauthorised = "You are not authorised to use this command"; - public static readonly ServerNotSetup = "This server hasn't been setup yet, please run the setup command"; - public static readonly NotInServer = "This command requires to be ran inside of a server"; - public static readonly FeatureDisabled = "This feature is currently disabled by a server moderator"; - - public static GetErrorMessage(response: CommandResponse): string { - switch (response) { - case CommandResponse.Unauthorised: - return this.UserUnauthorised; - case CommandResponse.ServerNotSetup: - return this.ServerNotSetup; - case CommandResponse.NotInServer: - return this.NotInServer; - case CommandResponse.FeatureDisabled: - return this.FeatureDisabled; - default: - return ""; - } - } -} \ No newline at end of file diff --git a/src/contracts/ICommandContext.ts b/src/contracts/ICommandContext.ts deleted file mode 100644 index 78f0d17..0000000 --- a/src/contracts/ICommandContext.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Message } from "discord.js"; - -export interface ICommandContext { - name: string; - args: string[]; - message: Message; -} \ No newline at end of file diff --git a/src/contracts/ICommandReturnContext.ts b/src/contracts/ICommandReturnContext.ts deleted file mode 100644 index 144e981..0000000 --- a/src/contracts/ICommandReturnContext.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { MessageEmbed } from "discord.js"; -import { ICommandContext } from "./ICommandContext"; - -export default interface ICommandReturnContext { - commandContext: ICommandContext, - embeds: MessageEmbed[] -} \ No newline at end of file diff --git a/src/contracts/IEventReturnContext.ts b/src/contracts/IEventReturnContext.ts deleted file mode 100644 index ccbe56d..0000000 --- a/src/contracts/IEventReturnContext.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { MessageEmbed } from "discord.js"; -import { ICommandContext } from "./ICommandContext"; - -export default interface ICommandReturnContext { - embeds: MessageEmbed[] -} \ No newline at end of file diff --git a/src/entity/Audit.ts b/src/entity/Audit.ts index 0ec1ea7..448913d 100644 --- a/src/entity/Audit.ts +++ b/src/entity/Audit.ts @@ -1,4 +1,4 @@ -import { Column, Entity, getConnection, ManyToOne } from "typeorm"; +import { Column, Entity, getConnection } from "typeorm"; import { AuditType } from "../constants/AuditType"; import BaseEntity from "../contracts/BaseEntity"; import StringTools from "../helpers/StringTools"; diff --git a/src/entity/Role.ts b/src/entity/Role.ts index 5b534ad..954c208 100644 --- a/src/entity/Role.ts +++ b/src/entity/Role.ts @@ -1,4 +1,4 @@ -import { Column, Entity, EntityTarget, getConnection, ManyToOne } from "typeorm"; +import { Column, Entity, getConnection, ManyToOne } from "typeorm"; import BaseEntity from "../contracts/BaseEntity" import Server from "./Server"; @@ -15,6 +15,10 @@ export default class Role extends BaseEntity { @ManyToOne(() => Server, x => x.Roles) Server: Server; + + public SetServer(server: Server) { + this.Server = server; + } public static async FetchOneByRoleId(roleId: string, relations?: string[]): Promise<Role | undefined> { const connection = getConnection(); diff --git a/src/events/MemberEvents.ts b/src/events/MemberEvents.ts index 43d07e8..fabf0b9 100644 --- a/src/events/MemberEvents.ts +++ b/src/events/MemberEvents.ts @@ -1,8 +1,8 @@ import { Event } from "../type/event"; -import { GuildMember } from "discord.js"; -import EventEmbed from "../helpers/embeds/EventEmbed"; +import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; import GuildMemberUpdate from "./MemberEvents/GuildMemberUpdate"; import SettingsHelper from "../helpers/SettingsHelper"; +import EmbedColours from "../constants/EmbedColours"; export default class MemberEvents extends Event { constructor() { @@ -15,15 +15,29 @@ export default class MemberEvents extends Event { const enabled = await SettingsHelper.GetSetting("event.member.add.enabled", member.guild.id); if (!enabled || enabled.toLowerCase() != "true") return; - const embed = new EventEmbed(member.client, member.guild, "Member Joined"); - embed.AddUser("User", member.user, true); - embed.addField("Created", member.user.createdAt.toISOString()); - embed.setFooter({ text: `Id: ${member.user.id}` }); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle('Member Joined') + .setDescription(`${member.user} \`${member.user.tag}\``) + .setFooter({ text: `Id: ${member.user.id}` }) + .addFields([ + { + name: 'Created', + value: member.user.createdAt.toISOString(), + } + ]); - const channel = await SettingsHelper.GetSetting("event.member.add.channel", member.guild.id); - if (!channel || !member.guild.channels.cache.find(x => x.name == channel)) return; + const channelSetting = await SettingsHelper.GetSetting("event.member.add.channel", member.guild.id); - await embed.SendToChannel(channel); + if (!channelSetting) return; + + const channel = member.guild.channels.cache.find(x => x.name == channelSetting); + + if (!channel) return; + + const guildChannel = channel as TextChannel; + + await guildChannel.send({ embeds: [embed ]}); } public override async guildMemberRemove(member: GuildMember) { @@ -32,15 +46,29 @@ export default class MemberEvents extends Event { const enabled = await SettingsHelper.GetSetting("event.member.remove.enabled", member.guild.id); if (!enabled || enabled.toLowerCase() != "true") return; - const embed = new EventEmbed(member.client, member.guild, "Member Left"); - embed.AddUser("User", member.user, true); - embed.addField("Joined", member.joinedAt?.toISOString() || "n/a"); - embed.setFooter({ text: `Id: ${member.user.id}` }); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle('Member Left') + .setDescription(`${member.user} \`${member.user.tag}\``) + .setFooter({ text: `Id: ${member.user.id}` }) + .addFields([ + { + name: 'Joined', + value: member.joinedAt ? member.joinedAt.toISOString() : "*none*", + } + ]); - const channel = await SettingsHelper.GetSetting("event.member.remove.channel", member.guild.id); - if (!channel || !member.guild.channels.cache.find(x => x.name == channel)) return; - - await embed.SendToChannel(channel); + const channelSetting = await SettingsHelper.GetSetting("event.member.remove.channel", member.guild.id); + + if (!channelSetting) return; + + const channel = member.guild.channels.cache.find(x => x.name == channelSetting); + + if (!channel) return; + + const guildChannel = channel as TextChannel; + + await guildChannel.send({ embeds: [embed ]}); } public override async guildMemberUpdate(oldMember: GuildMember, newMember: GuildMember) { diff --git a/src/events/MemberEvents/GuildMemberUpdate.ts b/src/events/MemberEvents/GuildMemberUpdate.ts index 0abd37d..6652b96 100644 --- a/src/events/MemberEvents/GuildMemberUpdate.ts +++ b/src/events/MemberEvents/GuildMemberUpdate.ts @@ -1,5 +1,5 @@ -import { GuildMember } from "discord.js"; -import EventEmbed from "../../helpers/embeds/EventEmbed"; +import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; +import EmbedColours from "../../constants/EmbedColours"; import SettingsHelper from "../../helpers/SettingsHelper"; export default class GuildMemberUpdate { @@ -18,15 +18,32 @@ export default class GuildMemberUpdate { const oldNickname = this.oldMember.nickname || "*none*"; const newNickname = this.newMember.nickname || "*none*"; - const embed = new EventEmbed(this.oldMember.client, this.newMember.guild, "Nickname Changed"); - embed.AddUser("User", this.newMember.user, true); - embed.addField("Before", oldNickname, true); - embed.addField("After", newNickname, true); - embed.setFooter({ text: `Id: ${this.newMember.user.id}` }); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle('Nickname Changed') + .setDescription(`${this.newMember.user} \`${this.newMember.user.tag}\``) + .setFooter({ text: `Id: ${this.newMember.user.id}` }) + .addFields([ + { + name: 'Before', + value: oldNickname, + }, + { + name: 'After', + value: newNickname, + }, + ]); - const channel = await SettingsHelper.GetSetting("event.member.update.channel", this.newMember.guild.id); - if (!channel || channel.toLowerCase() != "true") return; + const channelSetting = await SettingsHelper.GetSetting("event.member.update.channel", this.newMember.guild.id); - await embed.SendToChannel(channel); + if (!channelSetting) return; + + const channel = this.newMember.guild.channels.cache.find(x => x.name == channelSetting); + + if (!channel) return; + + const guildChannel = channel as TextChannel; + + await guildChannel.send({ embeds: [embed ]}); } } \ No newline at end of file diff --git a/src/events/MessageEvents.ts b/src/events/MessageEvents.ts index 9f37a9e..714f203 100644 --- a/src/events/MessageEvents.ts +++ b/src/events/MessageEvents.ts @@ -1,9 +1,9 @@ import { Event } from "../type/event"; -import { Message } from "discord.js"; -import EventEmbed from "../helpers/embeds/EventEmbed"; +import { EmbedBuilder, Message, TextChannel } from "discord.js"; import SettingsHelper from "../helpers/SettingsHelper"; import OnMessage from "./MessageEvents/OnMessage"; import IgnoredChannel from "../entity/IgnoredChannel"; +import EmbedColours from "../constants/EmbedColours"; export default class MessageEvents extends Event { constructor() { @@ -20,19 +20,42 @@ export default class MessageEvents extends Event { const ignored = await IgnoredChannel.IsChannelIgnored(message.channel.id); if (ignored) return; - const embed = new EventEmbed(message.client, message.guild, "Message Deleted"); - embed.AddUser("User", message.author, true); - embed.addField("Channel", message.channel.toString(), true); - embed.addField("Content", `\`\`\`${message.content || "*none*"}\`\`\``); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Message Deleted") + .setDescription(`${message.author} \`${message.author.tag}\``) + .addFields([ + { + name: "Channel", + value: message.channel.toString(), + inline: true, + }, + { + name: "Content", + value: `\`\`\`${message.content || "*none*"}\`\`\``, + } + ]); if (message.attachments.size > 0) { - embed.addField("Attachments", `\`\`\`${message.attachments.map(x => x.url).join("\n")}\`\`\``); + embed.addFields([ + { + name: "Attachments", + value: `\`\`\`${message.attachments.map(x => x.url).join("\n")}\`\`\`` + } + ]); } - const channel = await SettingsHelper.GetSetting("event.message.delete.channel", message.guild.id); - if (!channel || !message.guild.channels.cache.find(x => x.name == channel)) return; + const channelSetting = await SettingsHelper.GetSetting("event.message.delete.channel", message.guild.id); - await embed.SendToChannel(channel); + if (!channelSetting) return; + + const channel = message.guild.channels.cache.find(x => x.name == channelSetting); + + if (!channel) return; + + const guildChannel = channel as TextChannel; + + await guildChannel.send({ embeds: [ embed ]}); } public override async messageUpdate(oldMessage: Message, newMessage: Message) { @@ -46,16 +69,37 @@ export default class MessageEvents extends Event { const ignored = await IgnoredChannel.IsChannelIgnored(newMessage.channel.id); if (ignored) return; - const embed = new EventEmbed(newMessage.client, newMessage.guild, "Message Edited"); - embed.AddUser("User", newMessage.author, true); - embed.addField("Channel", newMessage.channel.toString(), true); - embed.addField("Before", `\`\`\`${oldMessage.content || "*none*"}\`\`\``); - embed.addField("After", `\`\`\`${newMessage.content || "*none*"}\`\`\``); + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Message Deleted") + .setDescription(`${newMessage.author} \`${newMessage.author.tag}\``) + .addFields([ + { + name: "Channel", + value: newMessage.channel.toString(), + inline: true, + }, + { + name: "Before", + value: `\`\`\`${oldMessage.content || "*none*"}\`\`\``, + }, + { + name: "After", + value: `\`\`\`${newMessage.content || "*none*"}\`\`\``, + } + ]); - const channel = await SettingsHelper.GetSetting("event.message.update.channel", newMessage.guild.id); - if (!channel || !newMessage.guild.channels.cache.find(x => x.name == channel)) return; + const channelSetting = await SettingsHelper.GetSetting("event.message.delete.channel", newMessage.guild.id); - await embed.SendToChannel(channel); + if (!channelSetting) return; + + const channel = newMessage.guild.channels.cache.find(x => x.name == channelSetting); + + if (!channel) return; + + const guildChannel = channel as TextChannel; + + await guildChannel.send({ embeds: [ embed ]}); } public override async messageCreate(message: Message) { diff --git a/src/helpers/embeds/ErrorEmbed.ts b/src/helpers/embeds/ErrorEmbed.ts deleted file mode 100644 index 958b8fc..0000000 --- a/src/helpers/embeds/ErrorEmbed.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { MessageEmbed, Permissions, TextChannel } from "discord.js"; -import { ICommandContext } from "../../contracts/ICommandContext"; - -export default class ErrorEmbed extends MessageEmbed { - public context: ICommandContext; - - constructor(context: ICommandContext, message: string) { - super(); - - super.setColor(0xd52803); - super.setDescription(message); - - this.context = context; - } - - public async SendToCurrentChannel() { - const channel = this.context.message.channel as TextChannel; - const botMember = await this.context.message.guild?.members.fetch({ user: this.context.message.client.user! }); - - if (!botMember) return; - - const permissions = channel.permissionsFor(botMember); - - if (!permissions.has(Permissions.FLAGS.SEND_MESSAGES)) return; - - this.context.message.channel.send({ embeds: [ this ]}); - } -} \ No newline at end of file diff --git a/src/helpers/embeds/EventEmbed.ts b/src/helpers/embeds/EventEmbed.ts deleted file mode 100644 index 782f98a..0000000 --- a/src/helpers/embeds/EventEmbed.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { MessageEmbed, TextChannel, User, Guild, Client, Permissions } from "discord.js"; -import { ICommandContext } from "../../contracts/ICommandContext"; -import SettingsHelper from "../SettingsHelper"; - -export default class EventEmbed extends MessageEmbed { - public guild: Guild; - - private client: Client; - - constructor(client: Client, guild: Guild, title: string) { - super(); - - super.setColor(0x3050ba); - super.setTitle(title); - - this.guild = guild; - this.client = client; - } - - // Detail methods - public AddUser(title: string, user: User, setThumbnail: boolean = false) { - this.addField(title, `${user} \`${user.tag}\``, true); - - if (setThumbnail) { - this.setThumbnail(user.displayAvatarURL()); - } - } - - public AddReason(message: string) { - this.addField("Reason", message || "*none*"); - } - - // Send methods - public async SendToChannel(name: string) { - const channel = this.guild.channels.cache - .find(channel => channel.name == name) as TextChannel; - - if (!channel) { - console.error(`Unable to find channel ${name}`); - return; - } - - const botMember = await this.guild.members.fetch({ user: this.client.user! }); - - if (!botMember) return; - - const permissions = channel.permissionsFor(botMember); - - if (!permissions.has(Permissions.FLAGS.SEND_MESSAGES)) return; - - channel.send({embeds: [ this ]}); - } - - public async SendToMessageLogsChannel() { - const channelName = await SettingsHelper.GetSetting("channels.logs.message", this.guild.id); - - if (!channelName) { - return; - } - - this.SendToChannel(channelName); - } - - public async SendToMemberLogsChannel() { - const channelName = await SettingsHelper.GetSetting("channels.logs.member", this.guild.id); - - if (!channelName) { - return; - } - - this.SendToChannel(channelName); - } - - public async SendToModLogsChannel() { - const channelName = await SettingsHelper.GetSetting("channels.logs.mod", this.guild.id); - - if (!channelName) { - return; - } - - this.SendToChannel(channelName); - } -} \ No newline at end of file diff --git a/src/helpers/embeds/LogEmbed.ts b/src/helpers/embeds/LogEmbed.ts deleted file mode 100644 index 105c6a9..0000000 --- a/src/helpers/embeds/LogEmbed.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { MessageEmbed, Permissions, TextChannel, User } from "discord.js"; -import ErrorMessages from "../../constants/ErrorMessages"; -import { ICommandContext } from "../../contracts/ICommandContext"; -import SettingsHelper from "../SettingsHelper"; -import ErrorEmbed from "./ErrorEmbed"; - -export default class LogEmbed extends MessageEmbed { - public context: ICommandContext; - - constructor(context: ICommandContext, title: string) { - super(); - - super.setColor(0x3050ba); - super.setTitle(title); - - this.context = context; - } - - // Detail methods - public AddUser(title: string, user: User, setThumbnail: boolean = false) { - this.addField(title, `${user} \`${user.tag}\``, true); - - if (setThumbnail) { - this.setThumbnail(user.displayAvatarURL()); - } - } - - public AddReason(message: string) { - this.addField("Reason", message || "*none*"); - } - - // Send methods - public async SendToCurrentChannel() { - const channel = this.context.message.channel as TextChannel; - const botMember = await this.context.message.guild?.members.fetch({ user: this.context.message.client.user! }); - - if (!botMember) return; - - const permissions = channel.permissionsFor(botMember); - - if (!permissions.has(Permissions.FLAGS.SEND_MESSAGES)) return; - - this.context.message.channel.send({ embeds: [ this ]}); - } - - public SendToChannel(name: string) { - const channel = this.context.message.guild?.channels.cache - .find(channel => channel.name == name) as TextChannel; - - if (!channel) { - const errorEmbed = new ErrorEmbed(this.context, ErrorMessages.ChannelNotFound); - errorEmbed.SendToCurrentChannel(); - return; - } - - channel.send({ embeds: [ this ]}); - } - - public async SendToMessageLogsChannel() { - const channelName = await SettingsHelper.GetSetting("channels.logs.message", this.context.message.guild?.id!); - - if (!channelName) { - return; - } - - this.SendToChannel(channelName); - } - - public async SendToMemberLogsChannel() { - const channelName = await SettingsHelper.GetSetting("channels.logs.member", this.context.message.guild?.id!); - - if (!channelName) { - return; - } - - this.SendToChannel(channelName); - } - - public async SendToModLogsChannel() { - const channelName = await SettingsHelper.GetSetting("channels.logs.mod", this.context.message.guild?.id!); - - if (!channelName) { - return; - } - - this.SendToChannel(channelName); - } -} \ No newline at end of file diff --git a/src/helpers/embeds/PublicEmbed.ts b/src/helpers/embeds/PublicEmbed.ts deleted file mode 100644 index 059826b..0000000 --- a/src/helpers/embeds/PublicEmbed.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { MessageEmbed, MessageOptions, Permissions, TextChannel } from "discord.js"; -import { ICommandContext } from "../../contracts/ICommandContext"; - -export default class PublicEmbed extends MessageEmbed { - public context: ICommandContext; - - constructor(context: ICommandContext, title: string, description: string) { - super(); - - super.setColor(0x3050ba); - super.setTitle(title); - super.setDescription(description); - - this.context = context; - } - - // Detail methods - public AddReason(message: string) { - this.addField("Reason", message || "*none*"); - } - - // Send methods - public async SendToCurrentChannel(options?: MessageOptions) { - const channel = this.context.message.channel as TextChannel; - const botMember = await this.context.message.guild?.members.fetch({ user: this.context.message.client.user! }); - - if (!botMember) return; - - const permissions = channel.permissionsFor(botMember); - - if (!permissions.has(Permissions.FLAGS.SEND_MESSAGES)) return; - - this.context.message.channel.send({ embeds: [ this ], ...options}); - } -} \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index c34c098..a83e7fa 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -8,21 +8,21 @@ import Clear from "./commands/clear"; import Code from "./commands/code"; import Config from "./commands/config"; import Disable from "./commands/disable"; -import Help from "./commands/help"; import Ignore from "./commands/ignore"; import Kick from "./commands/kick"; import Mute from "./commands/mute"; -import Poll from "./commands/poll"; -import Role from "./commands/role"; +import Role from "./commands/Role/role"; +import ConfigRole from "./commands/Role/config"; import Rules from "./commands/rules"; -import Say from "./commands/say"; import Setup from "./commands/setup"; import Unmute from "./commands/unmute"; import Warn from "./commands/warn"; // Command Imports: MankBot import Entry from "./commands/501231711271780357/entry"; -import Lobby from "./commands/501231711271780357/lobby"; +import Lobby from "./commands/501231711271780357/Lobby/lobby"; +import AddLobby from "./commands/501231711271780357/Lobby/add"; +import RemoveLobby from "./commands/501231711271780357/Lobby/remove"; // Event Imports import MemberEvents from "./events/MemberEvents"; @@ -38,25 +38,28 @@ export default class Registry { CoreClient.RegisterCommand("code", new Code()); CoreClient.RegisterCommand("config", new Config()); CoreClient.RegisterCommand("disable", new Disable()); - CoreClient.RegisterCommand("help", new Help()); CoreClient.RegisterCommand("ignore", new Ignore()); CoreClient.RegisterCommand("kick", new Kick()); CoreClient.RegisterCommand("mute", new Mute()); - CoreClient.RegisterCommand("poll", new Poll()); - CoreClient.RegisterCommand("role", new Role()); CoreClient.RegisterCommand("rules", new Rules()); CoreClient.RegisterCommand("unmute", new Unmute()); CoreClient.RegisterCommand("warn", new Warn()); CoreClient.RegisterCommand("setup", new Setup()); - CoreClient.RegisterCommand("say", new Say()); CoreClient.RegisterCommand("audits", new Audits()); + CoreClient.RegisterCommand("role", new Role()); + CoreClient.RegisterCommand("configrole", new ConfigRole()); + // Exclusive Commands: MankBot CoreClient.RegisterCommand("lobby", new Lobby(), "501231711271780357"); + CoreClient.RegisterCommand("lobbyAdd", new AddLobby(), "501231711271780357"); + CoreClient.RegisterCommand("lobbyRemove", new RemoveLobby(), "501231711271780357"); CoreClient.RegisterCommand("entry", new Entry(), "501231711271780357"); // Add Exclusive Commands to Test Server CoreClient.RegisterCommand("lobby", new Lobby(), "442730357897429002"); + CoreClient.RegisterCommand("addlobby", new AddLobby(), "442730357897429002"); + CoreClient.RegisterCommand("removelobby", new RemoveLobby(), "442730357897429002"); CoreClient.RegisterCommand("entry", new Entry(), "442730357897429002"); } diff --git a/src/type/command.ts b/src/type/command.ts index 1d04686..10d091d 100644 --- a/src/type/command.ts +++ b/src/type/command.ts @@ -1,23 +1,9 @@ -import { CommandResponse } from "../constants/CommandResponse"; -import { ICommandContext } from "../contracts/ICommandContext"; +import { CommandInteraction } from "discord.js"; export class Command { - public Roles: string[]; - public Category?: string; - - constructor() { - this.Roles = []; - } - - public precheck(context: ICommandContext): CommandResponse { - return CommandResponse.Ok; - } - - public async precheckAsync(context: ICommandContext): Promise<CommandResponse> { - return CommandResponse.Ok; - } - - public execute(context: ICommandContext) { + public CommandBuilder: any; + + public execute(interaction: CommandInteraction) { } } diff --git a/src/vylbot.ts b/src/vylbot.ts index 1d6a420..16589c2 100644 --- a/src/vylbot.ts +++ b/src/vylbot.ts @@ -1,7 +1,7 @@ import { CoreClient } from "./client/client"; import * as dotenv from "dotenv"; import registry from "./registry"; -import { Intents } from "discord.js"; +import { IntentsBitField } from "discord.js"; dotenv.config(); @@ -9,8 +9,8 @@ const requiredConfigs: string[] = [ "BOT_TOKEN", "BOT_VER", "BOT_AUTHOR", - "BOT_DATE", "BOT_OWNERID", + "BOT_CLIENTID", ]; requiredConfigs.forEach(config => { @@ -20,9 +20,10 @@ requiredConfigs.forEach(config => { }); const client = new CoreClient([ - Intents.FLAGS.GUILDS, - Intents.FLAGS.GUILD_MESSAGES, - Intents.FLAGS.GUILD_MEMBERS, + IntentsBitField.Flags.Guilds, + IntentsBitField.Flags.GuildMessages, + IntentsBitField.Flags.GuildMembers, + IntentsBitField.Flags.MessageContent, ]); registry.RegisterCommands(); diff --git a/yarn.lock b/yarn.lock index 52ebe72..f543110 100644 --- a/yarn.lock +++ b/yarn.lock @@ -286,21 +286,34 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@discordjs/builders@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-0.11.0.tgz#4102abe3e0cd093501f3f71931df43eb92f5b0cc" - integrity sha512-ZTB8yJdJKrKlq44dpWkNUrAtEJEq0gqpb7ASdv4vmq6/mZal5kOv312hQ56I/vxwMre+VIkoHquNUAfnTbiYtg== +"@discordjs/builders@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-1.2.0.tgz#4f5059e258c30a26931ae384985ef8c6b371ba05" + integrity sha512-ARy4BUTMU+S0ZI6605NDqfWO+qZqV2d/xfY32z3hVSsd9IaAKJBZ1ILTZLy87oIjW8+gUpQmk9Kt0ZP9bmmd8Q== 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" + "@sapphire/shapeshift" "^3.5.1" + discord-api-types "^0.37.3" + fast-deep-equal "^3.1.3" + ts-mixer "^6.0.1" + tslib "^2.4.0" -"@discordjs/collection@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.4.0.tgz#b6488286a1cc7b41b644d7e6086f25a1c1e6f837" - integrity sha512-zmjq+l/rV35kE6zRrwe8BHqV78JvIh2ybJeZavBi5NySjWXqN3hmmAKg7kYMMXSeiWtSsMoZ/+MQi0DiQWy2lw== +"@discordjs/collection@^1.0.1", "@discordjs/collection@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-1.1.0.tgz#5f9f926404fd48ccde86a0d2268f202cbec77833" + integrity sha512-PQ2Bv6pnT7aGPCKWbvvNRww5tYCGpggIQVgpuF9TdDPeR6n6vQYxezXiLVOS9z2B62Dp4c+qepQ15SgJbLYtCQ== + +"@discordjs/rest@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@discordjs/rest/-/rest-1.1.0.tgz#5c283571a22b911ca334316245487af40baffe8b" + integrity sha512-yCrthRTQeUyNThQEpCk7bvQJlwQmz6kU0tf3dcWBv2WX3Bncl41x7Wc+v5b5OsIxfNYq38PvVtWircu9jtYZug== + dependencies: + "@discordjs/collection" "^1.0.1" + "@sapphire/async-queue" "^1.5.0" + "@sapphire/snowflake" "^3.2.2" + discord-api-types "^0.37.3" + file-type "^17.1.6" + tslib "^2.4.0" + undici "^5.9.1" "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" @@ -487,12 +500,25 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@sapphire/async-queue@^1.1.9": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.3.1.tgz#9d861e626dbffae02d808e13f823d4510e450a78" - integrity sha512-FFTlPOWZX1kDj9xCAsRzH5xEJfawg1lNoYAA+ecOWJMHOfiZYb1uXOI3ne9U4UILSEPwfE68p3T9wUHwIQfR0g== +"@sapphire/async-queue@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.5.0.tgz#2f255a3f186635c4fb5a2381e375d3dfbc5312d8" + integrity sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA== -"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.2.0": +"@sapphire/shapeshift@^3.5.1": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@sapphire/shapeshift/-/shapeshift-3.6.0.tgz#988ff6576162a581a29bc26deb5492f7d1bf419f" + integrity sha512-tu2WLRdo5wotHRvsCkspg3qMiP6ETC3Q1dns1Q5V6zKUki+1itq6AbhMwohF9ZcLoYqg+Y8LkgRRtVxxTQVTBQ== + dependencies: + fast-deep-equal "^3.1.3" + lodash.uniqwith "^4.5.0" + +"@sapphire/snowflake@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.2.2.tgz#faacdc1b5f7c43145a71eddba917de2b707ef780" + integrity sha512-ula2O0kpSZtX9rKXNeQMrHwNd7E4jPDJYUXmEGTFdMRfyfMw+FPyh04oKMjAiDuOi64bYgVkOV3MjK+loImFhQ== + +"@sindresorhus/is@^4.0.0": version "4.6.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== @@ -523,6 +549,11 @@ dependencies: defer-to-connect "^2.0.0" +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -622,14 +653,6 @@ dependencies: "@types/node" "*" -"@types/node-fetch@^2.5.12": - version "2.6.1" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975" - integrity sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - "@types/node@*": version "18.0.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a" @@ -662,7 +685,7 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== -"@types/ws@^8.2.2": +"@types/ws@^8.5.3": version "8.5.3" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== @@ -1181,25 +1204,27 @@ diff-sequences@^27.4.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== -discord-api-types@^0.26.0: - version "0.26.1" - resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.26.1.tgz#726f766ddc37d60da95740991d22cb6ef2ed787b" - integrity sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ== +discord-api-types@^0.37.3: + version "0.37.9" + resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.9.tgz#3ceba0f047c5239967c50b180fe9d72c55c82464" + integrity sha512-mAJv7EcDDo6YztR3XSIED2IAHJcAlzWFD31Q2cHLURMKPb0CW0TM/r32HhAHO9uHw74N3cviOzJIZfZVB/e/5A== -discord.js@^13.6.0: - version "13.6.0" - resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-13.6.0.tgz#d8a8a591dbf25cbcf9c783d5ddf22c4694860475" - integrity sha512-tXNR8zgsEPxPBvGk3AQjJ9ljIIC6/LOPjzKwpwz8Y1Q2X66Vi3ZqFgRHYwnHKC0jC0F+l4LzxlhmOJsBZDNg9g== +discord.js@^14.3.0: + version "14.3.0" + resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.3.0.tgz#9e43df7e4d2d14b11f3de751236e983159c3d3d0" + integrity sha512-CpIwoAAuELiHSgVKRMzsCADS6ZlJwAZ9RlvcJYdEgS00aW36dSvXyBgE+S3pigkc7G+jU6BEalMUWIJFveqrBQ== 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" + "@discordjs/builders" "^1.2.0" + "@discordjs/collection" "^1.1.0" + "@discordjs/rest" "^1.1.0" + "@sapphire/snowflake" "^3.2.2" + "@types/ws" "^8.5.3" + discord-api-types "^0.37.3" + fast-deep-equal "^3.1.3" + lodash.snakecase "^4.1.1" + tslib "^2.4.0" + undici "^5.9.1" + ws "^8.8.1" domexception@^2.0.1: version "2.0.1" @@ -1319,6 +1344,11 @@ expect@^27.4.2: jest-message-util "^27.4.2" jest-regex-util "^27.4.0" +fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -1336,6 +1366,15 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +file-type@^17.1.6: + version "17.1.6" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-17.1.6.tgz#18669e0577a4849ef6e73a41f8bdf1ab5ae21023" + integrity sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw== + dependencies: + readable-web-to-node-stream "^3.0.2" + strtok3 "^7.0.0-alpha.9" + token-types "^5.0.0-alpha.2" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -1360,15 +1399,6 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1559,7 +1589,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2201,6 +2231,16 @@ lodash.memoize@4.x: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= +lodash.snakecase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" + integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw== + +lodash.uniqwith@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz#7a0cbf65f43b5928625a9d4d0dc54b18cadc7ef3" + integrity sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q== + lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -2323,13 +2363,6 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -node-fetch@^2.6.1: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -2454,6 +2487,11 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +peek-readable@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0.tgz#7ead2aff25dc40458c60347ea76cfdfd63efdfec" + integrity sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -2553,6 +2591,22 @@ readable-stream@2.3.7: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-web-to-node-stream@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== + dependencies: + readable-stream "^3.6.0" + reflect-metadata@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" @@ -2612,7 +2666,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1: +safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -2738,6 +2792,13 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -2762,6 +2823,14 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strtok3@^7.0.0-alpha.9: + version "7.0.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0.tgz#868c428b4ade64a8fd8fee7364256001c1a4cbe5" + integrity sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^5.0.0" + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -2849,6 +2918,14 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +token-types@^5.0.0-alpha.2: + version "5.0.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.1.tgz#aa9d9e6b23c420a675e55413b180635b86a093b4" + integrity sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -2865,11 +2942,6 @@ tr46@^2.1.0: dependencies: punycode "^2.1.1" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= - ts-essentials@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" @@ -2889,16 +2961,21 @@ ts-jest@^27.1.2: semver "7.x" yargs-parser "20.x" -ts-mixer@^6.0.0: +ts-mixer@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.1.tgz#7c2627fb98047eb5f3c7f2fee39d1521d18fe87a" integrity sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg== -tslib@^2.1.0, tslib@^2.3.1: +tslib@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== +tslib@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -2951,12 +3028,17 @@ typescript@^4.5.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998" integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw== +undici@^5.9.1: + version "5.10.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.10.0.tgz#dd9391087a90ccfbd007568db458674232ebf014" + integrity sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g== + universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -2996,11 +3078,6 @@ walker@^1.0.7: dependencies: makeerror "1.0.12" -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= - webidl-conversions@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" @@ -3023,14 +3100,6 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - whatwg-url@^8.0.0, whatwg-url@^8.5.0: version "8.7.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" @@ -3081,10 +3150,10 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== -ws@^8.4.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" - integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== +ws@^8.8.1: + version "8.8.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" + integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== xml-name-validator@^3.0.0: version "3.0.0" @@ -3167,8 +3236,3 @@ zen-observable@0.8.15: version "0.8.15" resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== - -zod@^3.11.6: - version "3.14.4" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.14.4.tgz#e678fe9e5469f4663165a5c35c8f3dc66334a5d6" - integrity sha512-U9BFLb2GO34Sfo9IUYp0w3wJLlmcyGoMd75qU9yf+DrdGA4kEx6e+l9KOkAlyUO0PSQzZCa3TR4qVlcmwqSDuw== From 0d63bd120d969fc56cda8f84971f968b0182c8f6 Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Sun, 9 Oct 2022 15:23:25 +0100 Subject: [PATCH 16/56] Feature/103 improve events (#201) * Improve event handler to only run events that have been registered * Tidy up events into their own function files --- src/client/client.ts | 7 +- src/client/util.ts | 54 ++++++-- src/constants/EventType.ts | 15 +++ src/contracts/IEventItem.ts | 5 +- src/events/MemberEvents.ts | 81 ------------ src/events/MemberEvents/GuildMemberAdd.ts | 34 ++++++ src/events/MemberEvents/GuildMemberRemove.ts | 34 ++++++ src/events/MemberEvents/GuildMemberUpdate.ts | 51 +------- .../GuildMemberUpdate/NicknameChanged.ts | 39 ++++++ src/events/MessageEvents.ts | 115 ------------------ src/events/MessageEvents/MessageCreate.ts | 14 +++ .../MessageCreate/VerificationCheck.ts | 57 +++++++++ src/events/MessageEvents/MessageDelete.ts | 52 ++++++++ src/events/MessageEvents/MessageUpdate.ts | 48 ++++++++ src/events/MessageEvents/OnMessage.ts | 59 --------- src/registry.ts | 20 ++- src/type/event.ts | 55 --------- 17 files changed, 361 insertions(+), 379 deletions(-) create mode 100644 src/constants/EventType.ts delete mode 100644 src/events/MemberEvents.ts create mode 100644 src/events/MemberEvents/GuildMemberAdd.ts create mode 100644 src/events/MemberEvents/GuildMemberRemove.ts create mode 100644 src/events/MemberEvents/GuildMemberUpdate/NicknameChanged.ts delete mode 100644 src/events/MessageEvents.ts create mode 100644 src/events/MessageEvents/MessageCreate.ts create mode 100644 src/events/MessageEvents/MessageCreate/VerificationCheck.ts create mode 100644 src/events/MessageEvents/MessageDelete.ts create mode 100644 src/events/MessageEvents/MessageUpdate.ts delete mode 100644 src/events/MessageEvents/OnMessage.ts delete mode 100644 src/type/event.ts diff --git a/src/client/client.ts b/src/client/client.ts index 4b933f3..75e06fb 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -1,10 +1,10 @@ import { Client } from "discord.js"; import * as dotenv from "dotenv"; import { createConnection } from "typeorm"; +import { EventType } from "../constants/EventType"; import ICommandItem from "../contracts/ICommandItem"; import IEventItem from "../contracts/IEventItem"; import { Command } from "../type/command"; -import { Event } from "../type/event"; import { Events } from "./events"; import { Util } from "./util"; @@ -65,9 +65,10 @@ export class CoreClient extends Client { CoreClient._commandItems.push(item); } - public static RegisterEvent(event: Event) { + public static RegisterEvent(eventType: EventType, func: Function) { const item: IEventItem = { - Event: event, + EventType: eventType, + ExecutionFunction: func, }; CoreClient._eventItems.push(item); diff --git a/src/client/util.ts b/src/client/util.ts index 7a23542..a9c2bad 100644 --- a/src/client/util.ts +++ b/src/client/util.ts @@ -1,4 +1,5 @@ import { Client, REST, Routes, SlashCommandBuilder } from "discord.js"; +import { EventType } from "../constants/EventType"; import IEventItem from "../contracts/IEventItem"; import { CoreClient } from "./client"; @@ -49,19 +50,46 @@ export class Util { // Load the events loadEvents(client: Client, events: IEventItem[]) { events.forEach((e) => { - client.on('channelCreate', e.Event.channelCreate); - client.on('channelDelete', e.Event.channelDelete); - client.on('channelUpdate', e.Event.channelUpdate); - client.on('guildBanAdd', e.Event.guildBanAdd); - client.on('guildBanRemove', e.Event.guildBanRemove); - client.on('guildCreate', e.Event.guildCreate); - client.on('guildMemberAdd', e.Event.guildMemberAdd); - client.on('guildMemberRemove', e.Event.guildMemberRemove); - client.on('guildMemberUpdate', e.Event.guildMemberUpdate); - client.on('messageCreate', e.Event.messageCreate); - client.on('messageDelete', e.Event.messageDelete); - client.on('messageUpdate', e.Event.messageUpdate); - client.on('ready', e.Event.ready); + switch(e.EventType) { + case EventType.ChannelCreate: + client.on('channelCreate', (channel) => e.ExecutionFunction(channel)); + break; + case EventType.ChannelDelete: + client.on('channelDelete', (channel) => e.ExecutionFunction(channel)); + break; + case EventType.ChannelUpdate: + client.on('channelUpdate', (channel) => e.ExecutionFunction(channel)); + break; + case EventType.GuildBanAdd: + client.on('guildBanAdd', (ban) => e.ExecutionFunction(ban)); + break; + case EventType.GuildBanRemove: + client.on('guildBanRemove', (ban) => e.ExecutionFunction(ban)); + break; + case EventType.GuildCreate: + client.on('guildCreate', (guild) => e.ExecutionFunction(guild)); + break; + case EventType.GuildMemberAdd: + client.on('guildMemberAdd', (member) => e.ExecutionFunction(member)); + break; + case EventType.GuildMemberRemove: + client.on('guildMemberRemove', (member) => e.ExecutionFunction(member)); + break; + case EventType.GuildMemberUpdate: + client.on('guildMemberUpdate', (oldMember, newMember) => e.ExecutionFunction(oldMember, newMember)); + break; + case EventType.MessageCreate: + client.on('messageCreate', (message) => e.ExecutionFunction(message)); + break; + case EventType.MessageDelete: + client.on('messageDelete', (message) => e.ExecutionFunction(message)); + break; + case EventType.MessageUpdate: + client.on('messageUpdate', (oldMessage, newMessage) => e.ExecutionFunction(oldMessage, newMessage)); + break; + default: + console.error('Event not implemented.'); + } }); } } diff --git a/src/constants/EventType.ts b/src/constants/EventType.ts new file mode 100644 index 0000000..c27c6ed --- /dev/null +++ b/src/constants/EventType.ts @@ -0,0 +1,15 @@ +export enum EventType { + ChannelCreate, + ChannelDelete, + ChannelUpdate, + GuildBanAdd, + GuildBanRemove, + GuildCreate, + GuildMemberAdd, + GuildMemberRemove, + GuildMemberUpdate, + MessageCreate, + MessageDelete, + MessageUpdate, + Ready, +} \ No newline at end of file diff --git a/src/contracts/IEventItem.ts b/src/contracts/IEventItem.ts index 51bb881..ea32a3e 100644 --- a/src/contracts/IEventItem.ts +++ b/src/contracts/IEventItem.ts @@ -1,6 +1,7 @@ -import { Event } from "../type/event"; +import { EventType } from "../constants/EventType"; export default interface IEventItem { - Event: Event, + EventType: EventType, + ExecutionFunction: Function, } \ No newline at end of file diff --git a/src/events/MemberEvents.ts b/src/events/MemberEvents.ts deleted file mode 100644 index fabf0b9..0000000 --- a/src/events/MemberEvents.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Event } from "../type/event"; -import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; -import GuildMemberUpdate from "./MemberEvents/GuildMemberUpdate"; -import SettingsHelper from "../helpers/SettingsHelper"; -import EmbedColours from "../constants/EmbedColours"; - -export default class MemberEvents extends Event { - constructor() { - super(); - } - - public override async guildMemberAdd(member: GuildMember) { - if (!member.guild) return; - - const enabled = await SettingsHelper.GetSetting("event.member.add.enabled", member.guild.id); - if (!enabled || enabled.toLowerCase() != "true") return; - - const embed = new EmbedBuilder() - .setColor(EmbedColours.Ok) - .setTitle('Member Joined') - .setDescription(`${member.user} \`${member.user.tag}\``) - .setFooter({ text: `Id: ${member.user.id}` }) - .addFields([ - { - name: 'Created', - value: member.user.createdAt.toISOString(), - } - ]); - - const channelSetting = await SettingsHelper.GetSetting("event.member.add.channel", member.guild.id); - - if (!channelSetting) return; - - const channel = member.guild.channels.cache.find(x => x.name == channelSetting); - - if (!channel) return; - - const guildChannel = channel as TextChannel; - - await guildChannel.send({ embeds: [embed ]}); - } - - public override async guildMemberRemove(member: GuildMember) { - if (!member.guild) return; - - const enabled = await SettingsHelper.GetSetting("event.member.remove.enabled", member.guild.id); - if (!enabled || enabled.toLowerCase() != "true") return; - - const embed = new EmbedBuilder() - .setColor(EmbedColours.Ok) - .setTitle('Member Left') - .setDescription(`${member.user} \`${member.user.tag}\``) - .setFooter({ text: `Id: ${member.user.id}` }) - .addFields([ - { - name: 'Joined', - value: member.joinedAt ? member.joinedAt.toISOString() : "*none*", - } - ]); - - const channelSetting = await SettingsHelper.GetSetting("event.member.remove.channel", member.guild.id); - - if (!channelSetting) return; - - const channel = member.guild.channels.cache.find(x => x.name == channelSetting); - - if (!channel) return; - - const guildChannel = channel as TextChannel; - - await guildChannel.send({ embeds: [embed ]}); - } - - public override async guildMemberUpdate(oldMember: GuildMember, newMember: GuildMember) { - const handler = new GuildMemberUpdate(oldMember, newMember); - - if (oldMember.nickname != newMember.nickname) { // Nickname change - await handler.NicknameChanged(); - } - } -} \ No newline at end of file diff --git a/src/events/MemberEvents/GuildMemberAdd.ts b/src/events/MemberEvents/GuildMemberAdd.ts new file mode 100644 index 0000000..62e9f29 --- /dev/null +++ b/src/events/MemberEvents/GuildMemberAdd.ts @@ -0,0 +1,34 @@ +import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; +import EmbedColours from "../../constants/EmbedColours"; +import SettingsHelper from "../../helpers/SettingsHelper"; + +export default async function GuildMemberAdd(member: GuildMember) { + if (!member.guild) return; + + const enabled = await SettingsHelper.GetSetting("event.member.add.enabled", member.guild.id); + if (!enabled || enabled.toLowerCase() != "true") return; + + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle('Member Joined') + .setDescription(`${member.user} \`${member.user.tag}\``) + .setFooter({ text: `Id: ${member.user.id}` }) + .addFields([ + { + name: 'Created', + value: member.user.createdAt.toISOString(), + } + ]); + + const channelSetting = await SettingsHelper.GetSetting("event.member.add.channel", member.guild.id); + + if (!channelSetting) return; + + const channel = member.guild.channels.cache.find(x => x.name == channelSetting); + + if (!channel) return; + + const guildChannel = channel as TextChannel; + + await guildChannel.send({ embeds: [embed ]}); +} \ No newline at end of file diff --git a/src/events/MemberEvents/GuildMemberRemove.ts b/src/events/MemberEvents/GuildMemberRemove.ts new file mode 100644 index 0000000..7f28aff --- /dev/null +++ b/src/events/MemberEvents/GuildMemberRemove.ts @@ -0,0 +1,34 @@ +import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; +import EmbedColours from "../../constants/EmbedColours"; +import SettingsHelper from "../../helpers/SettingsHelper"; + +export default async function GuildMemberRemove(member: GuildMember) { + if (!member.guild) return; + + const enabled = await SettingsHelper.GetSetting("event.member.remove.enabled", member.guild.id); + if (!enabled || enabled.toLowerCase() != "true") return; + + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle('Member Left') + .setDescription(`${member.user} \`${member.user.tag}\``) + .setFooter({ text: `Id: ${member.user.id}` }) + .addFields([ + { + name: 'Joined', + value: member.joinedAt ? member.joinedAt.toISOString() : "*none*", + } + ]); + + const channelSetting = await SettingsHelper.GetSetting("event.member.remove.channel", member.guild.id); + + if (!channelSetting) return; + + const channel = member.guild.channels.cache.find(x => x.name == channelSetting); + + if (!channel) return; + + const guildChannel = channel as TextChannel; + + await guildChannel.send({ embeds: [embed ]}); +} \ No newline at end of file diff --git a/src/events/MemberEvents/GuildMemberUpdate.ts b/src/events/MemberEvents/GuildMemberUpdate.ts index 6652b96..0a7bbb1 100644 --- a/src/events/MemberEvents/GuildMemberUpdate.ts +++ b/src/events/MemberEvents/GuildMemberUpdate.ts @@ -1,49 +1,8 @@ -import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; -import EmbedColours from "../../constants/EmbedColours"; -import SettingsHelper from "../../helpers/SettingsHelper"; +import { GuildMember } from "discord.js"; +import NicknameChanged from "./GuildMemberUpdate/NicknameChanged"; -export default class GuildMemberUpdate { - public oldMember: GuildMember; - public newMember: GuildMember; - - constructor(oldMember: GuildMember, newMember: GuildMember) { - this.oldMember = oldMember; - this.newMember = newMember; - } - - public async NicknameChanged() { - const enabled = await SettingsHelper.GetSetting("event.member.update.enabled", this.newMember.guild.id); - if (!enabled || enabled.toLowerCase() != "true") return; - - const oldNickname = this.oldMember.nickname || "*none*"; - const newNickname = this.newMember.nickname || "*none*"; - - const embed = new EmbedBuilder() - .setColor(EmbedColours.Ok) - .setTitle('Nickname Changed') - .setDescription(`${this.newMember.user} \`${this.newMember.user.tag}\``) - .setFooter({ text: `Id: ${this.newMember.user.id}` }) - .addFields([ - { - name: 'Before', - value: oldNickname, - }, - { - name: 'After', - value: newNickname, - }, - ]); - - const channelSetting = await SettingsHelper.GetSetting("event.member.update.channel", this.newMember.guild.id); - - if (!channelSetting) return; - - const channel = this.newMember.guild.channels.cache.find(x => x.name == channelSetting); - - if (!channel) return; - - const guildChannel = channel as TextChannel; - - await guildChannel.send({ embeds: [embed ]}); +export default async function GuildMemberUpdate(oldMember: GuildMember, newMember: GuildMember) { + if (oldMember.nickname != newMember.nickname) { // Nickname change + await NicknameChanged(oldMember, newMember); } } \ No newline at end of file diff --git a/src/events/MemberEvents/GuildMemberUpdate/NicknameChanged.ts b/src/events/MemberEvents/GuildMemberUpdate/NicknameChanged.ts new file mode 100644 index 0000000..e935aab --- /dev/null +++ b/src/events/MemberEvents/GuildMemberUpdate/NicknameChanged.ts @@ -0,0 +1,39 @@ +import { EmbedBuilder, GuildMember, TextChannel } from "discord.js"; +import EmbedColours from "../../../constants/EmbedColours"; +import SettingsHelper from "../../../helpers/SettingsHelper"; + +export default async function NicknameChanged(oldMember: GuildMember, newMember: GuildMember) { + const enabled = await SettingsHelper.GetSetting("event.member.update.enabled", newMember.guild.id); + if (!enabled || enabled.toLowerCase() != "true") return; + + const oldNickname = oldMember.nickname || "*none*"; + const newNickname = newMember.nickname || "*none*"; + + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle('Nickname Changed') + .setDescription(`${newMember.user} \`${newMember.user.tag}\``) + .setFooter({ text: `Id: ${newMember.user.id}` }) + .addFields([ + { + name: 'Before', + value: oldNickname, + }, + { + name: 'After', + value: newNickname, + }, + ]); + + const channelSetting = await SettingsHelper.GetSetting("event.member.update.channel", newMember.guild.id); + + if (!channelSetting) return; + + const channel = newMember.guild.channels.cache.find(x => x.name == channelSetting); + + if (!channel) return; + + const guildChannel = channel as TextChannel; + + await guildChannel.send({ embeds: [embed ]}); +} \ No newline at end of file diff --git a/src/events/MessageEvents.ts b/src/events/MessageEvents.ts deleted file mode 100644 index 714f203..0000000 --- a/src/events/MessageEvents.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Event } from "../type/event"; -import { EmbedBuilder, Message, TextChannel } from "discord.js"; -import SettingsHelper from "../helpers/SettingsHelper"; -import OnMessage from "./MessageEvents/OnMessage"; -import IgnoredChannel from "../entity/IgnoredChannel"; -import EmbedColours from "../constants/EmbedColours"; - -export default class MessageEvents extends Event { - constructor() { - super(); - } - - public override async messageDelete(message: Message) { - if (!message.guild) return; - if (message.author.bot) return; - - const enabled = await SettingsHelper.GetSetting("event.message.delete.enabled", message.guild.id); - if (!enabled || enabled.toLowerCase() != "true") return; - - const ignored = await IgnoredChannel.IsChannelIgnored(message.channel.id); - if (ignored) return; - - const embed = new EmbedBuilder() - .setColor(EmbedColours.Ok) - .setTitle("Message Deleted") - .setDescription(`${message.author} \`${message.author.tag}\``) - .addFields([ - { - name: "Channel", - value: message.channel.toString(), - inline: true, - }, - { - name: "Content", - value: `\`\`\`${message.content || "*none*"}\`\`\``, - } - ]); - - if (message.attachments.size > 0) { - embed.addFields([ - { - name: "Attachments", - value: `\`\`\`${message.attachments.map(x => x.url).join("\n")}\`\`\`` - } - ]); - } - - const channelSetting = await SettingsHelper.GetSetting("event.message.delete.channel", message.guild.id); - - if (!channelSetting) return; - - const channel = message.guild.channels.cache.find(x => x.name == channelSetting); - - if (!channel) return; - - const guildChannel = channel as TextChannel; - - await guildChannel.send({ embeds: [ embed ]}); - } - - public override async messageUpdate(oldMessage: Message, newMessage: Message) { - if (!newMessage.guild) return; - if (newMessage.author.bot) return; - if (oldMessage.content == newMessage.content) return; - - const enabled = await SettingsHelper.GetSetting("event.message.update.enabled", newMessage.guild.id); - if (!enabled || enabled.toLowerCase() != "true") return; - - const ignored = await IgnoredChannel.IsChannelIgnored(newMessage.channel.id); - if (ignored) return; - - const embed = new EmbedBuilder() - .setColor(EmbedColours.Ok) - .setTitle("Message Deleted") - .setDescription(`${newMessage.author} \`${newMessage.author.tag}\``) - .addFields([ - { - name: "Channel", - value: newMessage.channel.toString(), - inline: true, - }, - { - name: "Before", - value: `\`\`\`${oldMessage.content || "*none*"}\`\`\``, - }, - { - name: "After", - value: `\`\`\`${newMessage.content || "*none*"}\`\`\``, - } - ]); - - const channelSetting = await SettingsHelper.GetSetting("event.message.delete.channel", newMessage.guild.id); - - if (!channelSetting) return; - - const channel = newMessage.guild.channels.cache.find(x => x.name == channelSetting); - - if (!channel) return; - - const guildChannel = channel as TextChannel; - - await guildChannel.send({ embeds: [ embed ]}); - } - - public override async messageCreate(message: Message) { - if (!message.guild) return; - if (message.author.bot) return; - - const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id); - - if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") { - await OnMessage.VerificationCheck(message); - } - } -} \ No newline at end of file diff --git a/src/events/MessageEvents/MessageCreate.ts b/src/events/MessageEvents/MessageCreate.ts new file mode 100644 index 0000000..a91250d --- /dev/null +++ b/src/events/MessageEvents/MessageCreate.ts @@ -0,0 +1,14 @@ +import { Message } from "discord.js"; +import SettingsHelper from "../../helpers/SettingsHelper"; +import VerificationCheck from "./MessageCreate/VerificationCheck"; + +export default async function MessageCreate(message: Message) { + if (!message.guild) return; + if (message.author.bot) return; + + const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id); + + if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") { + await VerificationCheck(message); + } +} \ No newline at end of file diff --git a/src/events/MessageEvents/MessageCreate/VerificationCheck.ts b/src/events/MessageEvents/MessageCreate/VerificationCheck.ts new file mode 100644 index 0000000..1dba4e3 --- /dev/null +++ b/src/events/MessageEvents/MessageCreate/VerificationCheck.ts @@ -0,0 +1,57 @@ +import { Message } from "discord.js"; +import SettingsHelper from "../../../helpers/SettingsHelper"; + +export default async function VerificationCheck(message: Message) { + if (!message.guild) return; + + const verificationChannel = await SettingsHelper.GetSetting("verification.channel", message.guild.id); + + if (!verificationChannel) { + return; + } + + const channel = message.guild.channels.cache.find(x => x.name == verificationChannel); + + if (!channel) { + return; + } + + const currentChannel = message.guild.channels.cache.find(x => x == message.channel); + + if (!currentChannel || currentChannel.name != verificationChannel) { + return; + } + + const verificationCode = await SettingsHelper.GetSetting("verification.code", message.guild.id); + + if (!verificationCode || verificationCode == "") { + await message.reply("`verification.code` is not set inside of the server's config. Please contact the server's mod team."); + await message.delete(); + + return; + } + + const verificationRoleName = await SettingsHelper.GetSetting("verification.role", message.guild.id); + + if (!verificationRoleName) { + await message.reply("`verification.role` is not set inside of the server's config. Please contact the server's mod team."); + await message.delete(); + return; + } + + const role = message.guild.roles.cache.find(x => x.name == verificationRoleName); + + if (!role) { + await message.reply("The entry role configured for this server does not exist. Please contact the server's mod team."); + await message.delete(); + return; + } + + if (message.content.toLocaleLowerCase() != verificationCode.toLocaleLowerCase()) { + await message.delete(); + return; + } + + await message.member?.roles.add(role); + await message.delete(); +} \ No newline at end of file diff --git a/src/events/MessageEvents/MessageDelete.ts b/src/events/MessageEvents/MessageDelete.ts new file mode 100644 index 0000000..cf11484 --- /dev/null +++ b/src/events/MessageEvents/MessageDelete.ts @@ -0,0 +1,52 @@ +import { EmbedBuilder, Message, TextChannel } from "discord.js"; +import EmbedColours from "../../constants/EmbedColours"; +import IgnoredChannel from "../../entity/IgnoredChannel"; +import SettingsHelper from "../../helpers/SettingsHelper"; + +export default async function MessageDelete(message: Message) { + if (!message.guild) return; + if (message.author.bot) return; + + const enabled = await SettingsHelper.GetSetting("event.message.delete.enabled", message.guild.id); + if (!enabled || enabled.toLowerCase() != "true") return; + + const ignored = await IgnoredChannel.IsChannelIgnored(message.channel.id); + if (ignored) return; + + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Message Deleted") + .setDescription(`${message.author} \`${message.author.tag}\``) + .addFields([ + { + name: "Channel", + value: message.channel.toString(), + inline: true, + }, + { + name: "Content", + value: `\`\`\`${message.content || "*none*"}\`\`\``, + } + ]); + + if (message.attachments.size > 0) { + embed.addFields([ + { + name: "Attachments", + value: `\`\`\`${message.attachments.map(x => x.url).join("\n")}\`\`\`` + } + ]); + } + + const channelSetting = await SettingsHelper.GetSetting("event.message.delete.channel", message.guild.id); + + if (!channelSetting) return; + + const channel = message.guild.channels.cache.find(x => x.name == channelSetting); + + if (!channel) return; + + const guildChannel = channel as TextChannel; + + await guildChannel.send({ embeds: [ embed ]}); +} \ No newline at end of file diff --git a/src/events/MessageEvents/MessageUpdate.ts b/src/events/MessageEvents/MessageUpdate.ts new file mode 100644 index 0000000..2422dbc --- /dev/null +++ b/src/events/MessageEvents/MessageUpdate.ts @@ -0,0 +1,48 @@ +import { EmbedBuilder, Message, TextChannel } from "discord.js"; +import EmbedColours from "../../constants/EmbedColours"; +import IgnoredChannel from "../../entity/IgnoredChannel"; +import SettingsHelper from "../../helpers/SettingsHelper"; + +export default async function MessageUpdate(oldMessage: Message, newMessage: Message) { + if (!newMessage.guild) return; + if (newMessage.author.bot) return; + if (oldMessage.content == newMessage.content) return; + + const enabled = await SettingsHelper.GetSetting("event.message.update.enabled", newMessage.guild.id); + if (!enabled || enabled.toLowerCase() != "true") return; + + const ignored = await IgnoredChannel.IsChannelIgnored(newMessage.channel.id); + if (ignored) return; + + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Message Edited") + .setDescription(`${newMessage.author} \`${newMessage.author.tag}\``) + .addFields([ + { + name: "Channel", + value: newMessage.channel.toString(), + inline: true, + }, + { + name: "Before", + value: `\`\`\`${oldMessage.content || "*none*"}\`\`\``, + }, + { + name: "After", + value: `\`\`\`${newMessage.content || "*none*"}\`\`\``, + } + ]); + + const channelSetting = await SettingsHelper.GetSetting("event.message.delete.channel", newMessage.guild.id); + + if (!channelSetting) return; + + const channel = newMessage.guild.channels.cache.find(x => x.name == channelSetting); + + if (!channel) return; + + const guildChannel = channel as TextChannel; + + await guildChannel.send({ embeds: [ embed ]}); +} \ No newline at end of file diff --git a/src/events/MessageEvents/OnMessage.ts b/src/events/MessageEvents/OnMessage.ts deleted file mode 100644 index 18c2a57..0000000 --- a/src/events/MessageEvents/OnMessage.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Message as Message } from "discord.js"; -import SettingsHelper from "../../helpers/SettingsHelper"; - -export default class OnMessage { - public static async VerificationCheck(message: Message) { - if (!message.guild) return; - - const verificationChannel = await SettingsHelper.GetSetting("verification.channel", message.guild.id); - - if (!verificationChannel) { - return; - } - - const channel = message.guild.channels.cache.find(x => x.name == verificationChannel); - - if (!channel) { - return; - } - - const currentChannel = message.guild.channels.cache.find(x => x == message.channel); - - if (!currentChannel || currentChannel.name != verificationChannel) { - return; - } - - const verificationCode = await SettingsHelper.GetSetting("verification.code", message.guild.id); - - if (!verificationCode || verificationCode == "") { - await message.reply("`verification.code` is not set inside of the server's config. Please contact the server's mod team."); - await message.delete(); - - return; - } - - const verificationRoleName = await SettingsHelper.GetSetting("verification.role", message.guild.id); - - if (!verificationRoleName) { - await message.reply("`verification.role` is not set inside of the server's config. Please contact the server's mod team."); - await message.delete(); - return; - } - - const role = message.guild.roles.cache.find(x => x.name == verificationRoleName); - - if (!role) { - await message.reply("The entry role configured for this server does not exist. Please contact the server's mod team."); - await message.delete(); - return; - } - - if (message.content.toLocaleLowerCase() != verificationCode.toLocaleLowerCase()) { - await message.delete(); - return; - } - - await message.member?.roles.add(role); - await message.delete(); - } -} \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index a83e7fa..f9a3278 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -1,9 +1,11 @@ import { CoreClient } from "./client/client"; +import { EventType } from "./constants/EventType"; // Command Imports import About from "./commands/about"; import Audits from "./commands/audits"; import Ban from "./commands/ban"; +import Bunny from "./commands/bunny"; import Clear from "./commands/clear"; import Code from "./commands/code"; import Config from "./commands/config"; @@ -25,9 +27,12 @@ import AddLobby from "./commands/501231711271780357/Lobby/add"; import RemoveLobby from "./commands/501231711271780357/Lobby/remove"; // Event Imports -import MemberEvents from "./events/MemberEvents"; -import MessageEvents from "./events/MessageEvents"; -import Bunny from "./commands/bunny"; +import GuildMemberAdd from "./events/MemberEvents/GuildMemberAdd"; +import GuildMemberRemove from "./events/MemberEvents/GuildMemberRemove"; +import GuildMemberUpdate from "./events/MemberEvents/GuildMemberUpdate"; +import MessageDelete from "./events/MessageEvents/MessageDelete"; +import MessageUpdate from "./events/MessageEvents/MessageUpdate"; +import MessageCreate from "./events/MessageEvents/MessageCreate"; export default class Registry { public static RegisterCommands() { @@ -64,7 +69,12 @@ export default class Registry { } public static RegisterEvents() { - CoreClient.RegisterEvent(new MemberEvents()); - CoreClient.RegisterEvent(new MessageEvents()); + CoreClient.RegisterEvent(EventType.GuildMemberAdd, GuildMemberAdd); + CoreClient.RegisterEvent(EventType.GuildMemberRemove, GuildMemberRemove); + CoreClient.RegisterEvent(EventType.GuildMemberUpdate, GuildMemberUpdate); + + CoreClient.RegisterEvent(EventType.MessageDelete, MessageDelete); + CoreClient.RegisterEvent(EventType.MessageUpdate, MessageUpdate); + CoreClient.RegisterEvent(EventType.MessageCreate, MessageCreate); } } \ No newline at end of file diff --git a/src/type/event.ts b/src/type/event.ts deleted file mode 100644 index 77771de..0000000 --- a/src/type/event.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Channel, Guild, GuildMember, Message, PartialDMChannel, PartialGuildMember, PartialMessage, GuildBan } from "discord.js"; - -export class Event { - public channelCreate(channel: Channel) { - - } - - public channelDelete(channel: Channel | PartialDMChannel) { - - } - - public channelUpdate(oldChannel: Channel, newChannel: Channel) { - - } - - public guildBanAdd(ban: GuildBan) { - - } - - public guildBanRemove(ban: GuildBan) { - - } - - public guildCreate(guild: Guild) { - - } - - public guildMemberAdd(member: GuildMember) { - - } - - public guildMemberRemove(member: GuildMember | PartialGuildMember) { - - } - - public guildMemberUpdate(oldMember: GuildMember | PartialGuildMember, newMember: GuildMember) { - - } - - public messageCreate(message: Message) { - - } - - public messageDelete(message: Message | PartialMessage) { - - } - - public messageUpdate(oldMessage: Message | PartialMessage, newMessage: Message | PartialMessage) { - - } - - public ready() { - - } -} From 0b498eb023e8af2e0c15398e7dad995a3562ab30 Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Sun, 16 Oct 2022 15:10:48 +0100 Subject: [PATCH 17/56] Update MankBot rules to mention me (#203) --- data/rules/442730357897429002.json | 86 ++---------------------------- data/rules/501231711271780357.json | 2 +- 2 files changed, 6 insertions(+), 82 deletions(-) diff --git a/data/rules/442730357897429002.json b/data/rules/442730357897429002.json index 6fef8cd..bf195b1 100644 --- a/data/rules/442730357897429002.json +++ b/data/rules/442730357897429002.json @@ -1,88 +1,12 @@ [ { - "image": "https://i.imgur.com/bjH1gza.png" - }, - { - "title": "Bot Testing Ground", + "title": "Welcome to Mankalor's Discord Server!", "description": [ - "Welcome to Vylpes' Den! Make sure to say hi!", - "Invite link: https://discord.gg/UyAhAVp" - ] - }, - { - "title": "Discord TOS", - "description": [ - "All servers are required to follow the Discord Terms of Service. This includes minimum age requirements (13+). If the moderation team discover a breach of TOS we are required by discord to ban. Make sure you know them!", - "https://discord.com/terms" - ] - }, - { - "title": "Rules", - "description": [ - "**English Only**", - "In order for everyone to understand each other we would like to ask everyone to speak in English only.", + "*You must follow Discord's TOS, including the rule where", "you must be 13 years or older.", + "If moderators know you're under 13, we will have to ban you!*", "", - "**No NSFW or Obscene Content**", - "This includes text, images, or links featuring nudity, sex, hard violence, or other graphically disturbing content.", - "", - "**Treat Everyone with Respect**", - "Absolutely no harassment, witch hunting, sexism, racism, or hate speech will be tolerated.", - "", - "**No spam or self promotion**", - "Outside of #self-promo. This includes DMing fellow members.", - "", - "**Keep Politics to #general**", - "And make sure it doesn't become too heated. Debate don't argue.", - "", - "**Drama From Other Servers**", - "Please don't bring up drama from other servers, keep that to DMs", - "", - "**Bot Abuse**", - "Don't abuse the bots or you will be blocked from using them", - "", - "**Event Spoilers**", - "Contents of events and keynotes, such as the Nintendo Direct, must be spoken about in events, this rule applies for up to 24 hours after the event ends. Even though we will only enforce talking there for a set time, please be considerate of those who haven't watched the event yet." + "You need to input a code in *#entry* which is somewhere in this message before you can start chatting, so read the server rules and info below.", + "If you still don't see the other channels after writing this code, message a moderator. For any issues with this bot, message <@147392775707426816>." ] - }, - { - "title": "Moderators Discretion", - "description": [ - "Don't argue with a mod's decision. A moderator's choice is final. If you have an issue with a member of the mod team DM me (Vylpes#0001)." - ] - }, - { - "title": "Supporters", - "description": [ - "If you are a Twitch Subscriber or a Patreon Member and have linked your profiles to your discord account you will get exclusive access to the Vylpes Plus channels, including early access to videos!" - ] - }, - { - "title": "Self-Assignable Roles", - "description": [ - "If you want to assign yourself roles, go to #bot-stuff and type v!role <role>. The current roles you can get are:", - "Notify: Get pinged when a new stream or video releases.", - "VotePings: Get pinged when I start a new poll", - "ProjectUpdates: Get pinged when I update my projects as well as new for them" - ] - }, - { - "title": "VylBot", - "description": [ - "This server uses a bot made by me, VylBot, to help moderate the server.", - "For more information on it, see the GitHub repositories:", - "https://github.com/Vylpes/vylbot-core", - "https://github.com/Vylpes/vylbot-app" - ] - }, - { - "title": "Links", - "description": [ - "YouTube: https://www.youtube.com/channel/UCwPlzKwCmP5Q9bCX3fHk2BA", - "Patreon: https://www.patreon.com/vylpes", - "Twitch: https://www.twitch.tv/vylpes_", - "Twitter: https://twitter.com/vylpes", - "Blog: https://vylpes.xyz" - ], - "footer": "Last updated 01/02/2022" } ] \ No newline at end of file diff --git a/data/rules/501231711271780357.json b/data/rules/501231711271780357.json index 324c40e..5b1ef37 100644 --- a/data/rules/501231711271780357.json +++ b/data/rules/501231711271780357.json @@ -6,7 +6,7 @@ "If moderators know you're under 13, we will have to ban you!*", "", "You need to input a code in *#entry* which is somewhere in this message before you can start chatting, so read the server rules and info below.", - "If you still don't see the other channels after writing this code, message a moderator. For any issues with this bot, message Vylpes#5725." + "If you still don't see the other channels after writing this code, message a moderator. For any issues with this bot, message <@147392775707426816>." ] }, { From d688d292c3569d5720369fe892a0c087a27f12bb Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 4 Nov 2022 18:07:00 +0000 Subject: [PATCH 18/56] Fix the event embeds not having the user's avatar on the thumbnail (#213) --- src/events/MemberEvents/GuildMemberAdd.ts | 1 + src/events/MemberEvents/GuildMemberRemove.ts | 1 + src/events/MemberEvents/GuildMemberUpdate/NicknameChanged.ts | 1 + src/events/MessageEvents/MessageDelete.ts | 1 + src/events/MessageEvents/MessageUpdate.ts | 1 + 5 files changed, 5 insertions(+) diff --git a/src/events/MemberEvents/GuildMemberAdd.ts b/src/events/MemberEvents/GuildMemberAdd.ts index 62e9f29..025be0b 100644 --- a/src/events/MemberEvents/GuildMemberAdd.ts +++ b/src/events/MemberEvents/GuildMemberAdd.ts @@ -13,6 +13,7 @@ export default async function GuildMemberAdd(member: GuildMember) { .setTitle('Member Joined') .setDescription(`${member.user} \`${member.user.tag}\``) .setFooter({ text: `Id: ${member.user.id}` }) + .setThumbnail(member.avatarURL()) .addFields([ { name: 'Created', diff --git a/src/events/MemberEvents/GuildMemberRemove.ts b/src/events/MemberEvents/GuildMemberRemove.ts index 7f28aff..bf6ae96 100644 --- a/src/events/MemberEvents/GuildMemberRemove.ts +++ b/src/events/MemberEvents/GuildMemberRemove.ts @@ -13,6 +13,7 @@ export default async function GuildMemberRemove(member: GuildMember) { .setTitle('Member Left') .setDescription(`${member.user} \`${member.user.tag}\``) .setFooter({ text: `Id: ${member.user.id}` }) + .setThumbnail(member.avatarURL()) .addFields([ { name: 'Joined', diff --git a/src/events/MemberEvents/GuildMemberUpdate/NicknameChanged.ts b/src/events/MemberEvents/GuildMemberUpdate/NicknameChanged.ts index e935aab..671d755 100644 --- a/src/events/MemberEvents/GuildMemberUpdate/NicknameChanged.ts +++ b/src/events/MemberEvents/GuildMemberUpdate/NicknameChanged.ts @@ -14,6 +14,7 @@ export default async function NicknameChanged(oldMember: GuildMember, newMember: .setTitle('Nickname Changed') .setDescription(`${newMember.user} \`${newMember.user.tag}\``) .setFooter({ text: `Id: ${newMember.user.id}` }) + .setThumbnail(newMember.avatarURL()) .addFields([ { name: 'Before', diff --git a/src/events/MessageEvents/MessageDelete.ts b/src/events/MessageEvents/MessageDelete.ts index cf11484..8d0d40e 100644 --- a/src/events/MessageEvents/MessageDelete.ts +++ b/src/events/MessageEvents/MessageDelete.ts @@ -17,6 +17,7 @@ export default async function MessageDelete(message: Message) { .setColor(EmbedColours.Ok) .setTitle("Message Deleted") .setDescription(`${message.author} \`${message.author.tag}\``) + .setThumbnail(message.author.avatarURL()) .addFields([ { name: "Channel", diff --git a/src/events/MessageEvents/MessageUpdate.ts b/src/events/MessageEvents/MessageUpdate.ts index 2422dbc..2ccd737 100644 --- a/src/events/MessageEvents/MessageUpdate.ts +++ b/src/events/MessageEvents/MessageUpdate.ts @@ -18,6 +18,7 @@ export default async function MessageUpdate(oldMessage: Message, newMessage: Mes .setColor(EmbedColours.Ok) .setTitle("Message Edited") .setDescription(`${newMessage.author} \`${newMessage.author.tag}\``) + .setThumbnail(newMessage.author.avatarURL()) .addFields([ { name: "Channel", From 39967068bbc2d5afccff9517e0613e2ce0e85037 Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Sat, 12 Nov 2022 22:06:41 +0000 Subject: [PATCH 19/56] Feature/155 lobby command list (#215) - Add lobby list command to list all channels setup as a lobby for the current server as well as their last time used Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/215 Reviewed-by: VylpesTester <tester@vylpes.com> --- src/commands/501231711271780357/Lobby/list.ts | 48 +++++++++++++++++++ src/registry.ts | 3 ++ 2 files changed, 51 insertions(+) create mode 100644 src/commands/501231711271780357/Lobby/list.ts diff --git a/src/commands/501231711271780357/Lobby/list.ts b/src/commands/501231711271780357/Lobby/list.ts new file mode 100644 index 0000000..ccf0766 --- /dev/null +++ b/src/commands/501231711271780357/Lobby/list.ts @@ -0,0 +1,48 @@ +import { CacheType, CommandInteraction, EmbedBuilder, GuildBasedChannel, PermissionsBitField, SlashCommandBuilder } from "discord.js"; +import { Command } from "../../../type/command"; +import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; +import EmbedColours from "../../../constants/EmbedColours"; + +export default class ListLobby extends Command { + constructor() { + super(); + + super.CommandBuilder = new SlashCommandBuilder() + .setName('listlobby') + .setDescription('Lists all channels set up as lobbies') + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers); + } + + public override async execute(interaction: CommandInteraction<CacheType>) { + if (!interaction.guild) { + await interaction.reply('Guild not found.'); + return; + } + + const channels: eLobby[] = []; + + for (let channel of interaction.guild.channels.cache.map(x => x)) { + const lobby = await eLobby.FetchOneByChannelId(channel.id); + + if (lobby) { + channels.push(lobby); + } + } + + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Lobbies") + .setDescription(`Channels: ${channels.length}`); + + for (let lobby of channels) { + embed.addFields([ + { + name: `# ${lobby.Name}`, + value: `Last Used: ${lobby.LastUsed}` + } + ]); + } + + await interaction.reply({ embeds: [ embed ]}); + } +} \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index f9a3278..a86ce96 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -25,6 +25,7 @@ import Entry from "./commands/501231711271780357/entry"; import Lobby from "./commands/501231711271780357/Lobby/lobby"; import AddLobby from "./commands/501231711271780357/Lobby/add"; import RemoveLobby from "./commands/501231711271780357/Lobby/remove"; +import ListLobby from "./commands/501231711271780357/Lobby/list"; // Event Imports import GuildMemberAdd from "./events/MemberEvents/GuildMemberAdd"; @@ -59,12 +60,14 @@ export default class Registry { CoreClient.RegisterCommand("lobby", new Lobby(), "501231711271780357"); CoreClient.RegisterCommand("lobbyAdd", new AddLobby(), "501231711271780357"); CoreClient.RegisterCommand("lobbyRemove", new RemoveLobby(), "501231711271780357"); + CoreClient.RegisterCommand("listlobby", new ListLobby(), "501231711271780357"); CoreClient.RegisterCommand("entry", new Entry(), "501231711271780357"); // Add Exclusive Commands to Test Server CoreClient.RegisterCommand("lobby", new Lobby(), "442730357897429002"); CoreClient.RegisterCommand("addlobby", new AddLobby(), "442730357897429002"); CoreClient.RegisterCommand("removelobby", new RemoveLobby(), "442730357897429002"); + CoreClient.RegisterCommand("listlobby", new ListLobby(), "442730357897429002"); CoreClient.RegisterCommand("entry", new Entry(), "442730357897429002"); } From a3e062a1ffc8d414944e97ace0266360a9355fd9 Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Tue, 27 Dec 2022 15:18:55 +0000 Subject: [PATCH 20/56] defect/214-application-did-not-respond (#233) Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/233 --- src/commands/rules.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/commands/rules.ts b/src/commands/rules.ts index f6a6406..930138c 100644 --- a/src/commands/rules.ts +++ b/src/commands/rules.ts @@ -32,13 +32,18 @@ export default class Rules extends Command { const rules = JSON.parse(rulesFile) as IRules[]; const embeds: EmbedBuilder[] = []; - + + if (rules.length == 0) { + await interaction.reply({ content: "No rules have been supplied within code base for this server.", ephemeral: true }); + return; + } + rules.forEach(rule => { const embed = new EmbedBuilder() .setColor(EmbedColours.Ok) .setTitle(rule.title || "Rules") .setDescription(rule.description ? rule.description.join("\n") : "*none*"); - + if (rule.image) { embed.setImage(rule.image); } @@ -53,9 +58,17 @@ export default class Rules extends Command { const channel = interaction.channel; if (!channel) { + await interaction.reply({ content: "Channel not found.", ephemeral: true }); return; } - + await channel.send({ embeds: embeds }); + + const successEmbed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Success") + .setDescription("The rules have sent to this channel successfully"); + + await interaction.reply({ embeds: [ successEmbed ], ephemeral: true }); } } \ No newline at end of file From a001e63857ff999083f3528d339a6774c24c929a Mon Sep 17 00:00:00 2001 From: Ethan Lane <ethan@vylpes.com> Date: Tue, 27 Dec 2022 15:22:11 +0000 Subject: [PATCH 21/56] Update scripts --- package.json | 1 + scripts/deploy_prod.sh | 7 ++++--- scripts/deploy_stage.sh | 7 ++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 6fed251..774499f 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "main": "./dist/vylbot", "typings": "./dist", "scripts": { + "clean": "rm -rf node_modules/ dist/", "build": "tsc", "start": "node ./dist/vylbot", "test": "jest", diff --git a/scripts/deploy_prod.sh b/scripts/deploy_prod.sh index 781952d..d9d5296 100644 --- a/scripts/deploy_prod.sh +++ b/scripts/deploy_prod.sh @@ -1,7 +1,7 @@ #! /bin/bash export PATH="$HOME/.yarn/bin:$PATH" -export PATH="$HOME/.nvm/versions/node/v16.17.0/bin/:$PATH" +export PATH="$HOME/.nodeuse/bin:$PATH" export BOT_TOKEN=$(cat $HOME/scripts/vylbot/prod_key.txt) @@ -9,14 +9,15 @@ cd ~/apps/vylbot/vylbot_prod \ && git checkout main \ && git fetch \ && git pull \ -&& docker-compose --file docker-compose.prod.yml down \ +&& docker compose --file docker-compose.prod.yml down \ && (pm2 stop vylbot_prod || true) \ && (pm2 delete vylbot_prod || true) \ && cp .prod.env .env \ && cp ormconfig.prod.json ormconfig.json \ +&& yarn clean \ && yarn install --frozen-lockfile \ && yarn build \ -&& docker-compose --file docker-compose.prod.yml up -d \ +&& docker compose --file docker-compose.prod.yml up -d \ && echo "Sleeping for 10 seconds to let database load..." \ && sleep 10 \ && yarn run db:up \ diff --git a/scripts/deploy_stage.sh b/scripts/deploy_stage.sh index b219c3f..a6c8c92 100644 --- a/scripts/deploy_stage.sh +++ b/scripts/deploy_stage.sh @@ -1,7 +1,7 @@ #! /bin/bash export PATH="$HOME/.yarn/bin:$PATH" -export PATH="$HOME/.nvm/versions/node/v16.17.0/bin/:$PATH" +export PATH="$HOME/.nodeuse/bin:$PATH" export BOT_TOKEN=$(cat $HOME/scripts/vylbot/stage_key.txt) @@ -9,14 +9,15 @@ cd ~/apps/vylbot/vylbot_stage \ && git checkout develop \ && git fetch \ && git pull \ -&& docker-compose --file docker-compose.stage.yml down \ +&& docker compose --file docker-compose.stage.yml down \ && (pm2 stop vylbot_stage || true) \ && (pm2 delete vylbot_stage || true) \ && cp .stage.env .env \ && cp ormconfig.stage.json ormconfig.json \ +&& yarn clean \ && yarn install --frozen-lockfile \ && yarn build \ -&& docker-compose --file docker-compose.stage.yml up -d \ +&& docker compose --file docker-compose.stage.yml up -d \ && echo "Sleeping for 10 seconds to let database load..." \ && sleep 10 \ && yarn run db:up \ From 2164b9603d4a855fad37ed77bcd23158e87c6eea Mon Sep 17 00:00:00 2001 From: Renovate Bot <renovate@vylpes.com> Date: Wed, 28 Dec 2022 18:52:08 +0000 Subject: [PATCH 22/56] Update dependency @types/node to v18 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 774499f..d80b836 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@types/node": "^16.11.10", + "@types/node": "^18.0.0", "typescript": "^4.5.2" } } diff --git a/yarn.lock b/yarn.lock index 61c11b2..805c772 100644 --- a/yarn.lock +++ b/yarn.lock @@ -658,10 +658,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a" integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA== -"@types/node@^16.11.10": - version "16.11.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.10.tgz#2e3ad0a680d96367103d3e670d41c2fed3da61ae" - integrity sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA== +"@types/node@^18.0.0": + version "18.11.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" + integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== "@types/prettier@^2.1.5": version "2.4.2" From e02e58e28065e511ac6d8d496df5bc195122c1ba Mon Sep 17 00:00:00 2001 From: Renovate Bot <renovate@vylpes.com> Date: Wed, 28 Dec 2022 18:52:11 +0000 Subject: [PATCH 23/56] Update dependency dotenv to v16 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 774499f..e3cc5d2 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@types/jest": "^27.0.3", "@types/uuid": "^8.3.4", "discord.js": "^14.3.0", - "dotenv": "^10.0.0", + "dotenv": "^16.0.0", "emoji-regex": "^9.2.0", "jest": "^27.4.5", "jest-mock-extended": "^2.0.4", diff --git a/yarn.lock b/yarn.lock index 61c11b2..0ba013a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1233,10 +1233,10 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" -dotenv@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" - integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== +dotenv@^16.0.0: + version "16.0.3" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" + integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== dotenv@^8.2.0: version "8.6.0" From e808bbe6a55e3ad04fd6e1c99ecc75278e0f46e5 Mon Sep 17 00:00:00 2001 From: Renovate Bot <renovate@vylpes.com> Date: Wed, 28 Dec 2022 18:52:23 +0000 Subject: [PATCH 24/56] Update dependency jest-mock-extended to v3 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 774499f..2a0372a 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "dotenv": "^10.0.0", "emoji-regex": "^9.2.0", "jest": "^27.4.5", - "jest-mock-extended": "^2.0.4", + "jest-mock-extended": "^3.0.0", "minimatch": "3.1.2", "mysql": "^2.18.1", "random-bunny": "^2.0.0", diff --git a/yarn.lock b/yarn.lock index 61c11b2..fb1f6bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1920,10 +1920,10 @@ jest-message-util@^27.4.2: slash "^3.0.0" stack-utils "^2.0.3" -jest-mock-extended@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/jest-mock-extended/-/jest-mock-extended-2.0.4.tgz#2bb430ba0adb9e10ea6a68d08731f2129330c8fe" - integrity sha512-MgL3B3GjURQFjjPGqbCANydA5BFNPygv0mYp4Tjfxohh9MWwxxX8Eq2p6ncCt/Vt+RAnaLlDaI7gwrDRD7Pt9A== +jest-mock-extended@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jest-mock-extended/-/jest-mock-extended-3.0.1.tgz#5f109d5e1da62851ffc9126a01e83cd6470b810b" + integrity sha512-RF4Ow8pXvbRuEcCTj56oYHmig5311BSFvbEGxPNYL51wGKGu93MvVQgx0UpFmjqyBXIcElkZo2Rke88kR1iSKQ== dependencies: ts-essentials "^7.0.3" From 17ae4079e586311466b0b05ebdc4ab5d459b66c8 Mon Sep 17 00:00:00 2001 From: Renovate Bot <renovate@vylpes.com> Date: Wed, 28 Dec 2022 18:52:33 +0000 Subject: [PATCH 25/56] Update dependency uuid to v9 --- package.json | 4 ++-- yarn.lock | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 774499f..e4658ff 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "dependencies": { "@discordjs/rest": "^1.1.0", "@types/jest": "^27.0.3", - "@types/uuid": "^8.3.4", + "@types/uuid": "^9.0.0", "discord.js": "^14.3.0", "dotenv": "^10.0.0", "emoji-regex": "^9.2.0", @@ -38,7 +38,7 @@ "random-bunny": "^2.0.0", "ts-jest": "^27.1.2", "typeorm": "^0.2.44", - "uuid": "^8.3.2" + "uuid": "^9.0.0" }, "devDependencies": { "@types/node": "^16.11.10", diff --git a/yarn.lock b/yarn.lock index 61c11b2..9acbfe3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -680,10 +680,10 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/uuid@^8.3.4": - version "8.3.4" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" - integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== +"@types/uuid@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.0.tgz#53ef263e5239728b56096b0a869595135b7952d2" + integrity sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q== "@types/ws@^8.5.3": version "8.5.3" @@ -3055,6 +3055,11 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + v8-to-istanbul@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz#0aeb763894f1a0a1676adf8a8b7612a38902446c" From c3d65b5579852ad8bbfed8403996c5360e4d30a5 Mon Sep 17 00:00:00 2001 From: Ethan Lane <ethan@vylpes.com> Date: Fri, 27 Jan 2023 17:41:05 +0000 Subject: [PATCH 26/56] Add .drone.yml --- .drone.yml | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 .drone.yml diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..99949c6 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,76 @@ +--- + +kind: pipeline +type: ssh +name: deployment + +server: + host: 192.168.68.121 + user: vylpes + password: + from_secret: ssh_password + +steps: +- name: deploy + commands: + - sh /home/vylpes/scripts/vylbot/deploy_prod.sh + +trigger: + branch: + - main + event: + - promote + target: + - production + +--- + +kind: pipeline +type: ssh +name: staging + +server: + host: 192.168.68.121 + user: vylpes + password: + from_secret: ssh_password + +steps: +- name: deploy + commands: + - sh /home/vylpes/scripts/vylbot/deploy_stage.sh + +trigger: + branch: + - develop + event: + - push + +--- + +kind: pipeline +name: integration + +steps: +- name: build + image: node + commands: + - yarn install --frozen-lockfile + - yarn build + +- name: test + image: node + commands: + - yarn install --frozen-lockfile + - yarn test + +trigger: + branch: + - main + - develop + - hotfix/* + - feature/* + - renovate/* + event: + - push + - pull_request \ No newline at end of file From 27afb3dd222a38d1adbedeebdf2cb155a8be374f Mon Sep 17 00:00:00 2001 From: Ethan Lane <ethan@vylpes.com> Date: Sat, 28 Jan 2023 14:53:23 +0000 Subject: [PATCH 27/56] Fix not having a link set in the config crashing the bot --- .dev.env | 2 +- .prod.env | 2 +- .stage.env | 2 +- src/commands/about.ts | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.dev.env b/.dev.env index 199bb0a..fb4a31c 100644 --- a/.dev.env +++ b/.dev.env @@ -13,4 +13,4 @@ BOT_OWNERID=147392775707426816 BOT_CLIENTID=682942374040961060 ABOUT_FUNDING=https://ko-fi.com/vylpes -ABOUT_REPO=https://github.com/vylpes/vylbot-app +ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app diff --git a/.prod.env b/.prod.env index c4fd73a..f0c75d5 100644 --- a/.prod.env +++ b/.prod.env @@ -13,4 +13,4 @@ BOT_OWNERID=147392775707426816 BOT_CLIENTID=680083120896081954 ABOUT_FUNDING=https://ko-fi.com/vylpes -ABOUT_REPO=https://github.com/vylpes/vylbot-app +ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app diff --git a/.stage.env b/.stage.env index 85e3068..9b90831 100644 --- a/.stage.env +++ b/.stage.env @@ -13,4 +13,4 @@ BOT_OWNERID=147392775707426816 BOT_CLIENTID=1016767908740857949 ABOUT_FUNDING=https://ko-fi.com/vylpes -ABOUT_REPO=https://github.com/vylpes/vylbot-app +ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app diff --git a/src/commands/about.ts b/src/commands/about.ts index b1ad17b..5da00b8 100644 --- a/src/commands/about.ts +++ b/src/commands/about.ts @@ -31,7 +31,7 @@ export default class About extends Command { value: process.env.BOT_AUTHOR!, inline: true, }, - ]) + ]); const row = new ActionRowBuilder<ButtonBuilder>(); @@ -51,6 +51,6 @@ export default class About extends Command { .setStyle(ButtonStyle.Link)); } - await interaction.reply({ embeds: [ embed ]}); + await interaction.reply({ embeds: [ embed ], components: row.components.length > 0 ? [ row ] : [] }); } } \ No newline at end of file From 4c1726f5c8a91cbd96dfcf7d58e7413f2e34c25b Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Mon, 30 Jan 2023 11:11:04 +0000 Subject: [PATCH 28/56] Update '.drone.yml' --- .drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.drone.yml b/.drone.yml index 99949c6..ec32358 100644 --- a/.drone.yml +++ b/.drone.yml @@ -5,7 +5,7 @@ type: ssh name: deployment server: - host: 192.168.68.121 + host: 192.168.1.2 user: vylpes password: from_secret: ssh_password @@ -30,7 +30,7 @@ type: ssh name: staging server: - host: 192.168.68.121 + host: 192.168.1.2 user: vylpes password: from_secret: ssh_password From 6d7dc26e091b1beb665777007c9053ace69d147a Mon Sep 17 00:00:00 2001 From: Ethan Lane <ethan@vylpes.com> Date: Wed, 1 Feb 2023 17:33:13 +0000 Subject: [PATCH 29/56] Update random-bunny to v2.0.5 --- package.json | 2 +- yarn.lock | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 2ab4f46..5fe1e24 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "jest-mock-extended": "^3.0.0", "minimatch": "3.1.2", "mysql": "^2.18.1", - "random-bunny": "^2.0.0", + "random-bunny": "^2.0.5", "ts-jest": "^27.1.2", "typeorm": "^0.2.44", "uuid": "^9.0.0" diff --git a/yarn.lock b/yarn.lock index f5a318c..69249c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2219,6 +2219,11 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +linqts@^1.14.4: + version "1.14.4" + resolved "https://registry.yarnpkg.com/linqts/-/linqts-1.14.4.tgz#0aa0f78fc6be073d7db874e0a0480fda5d06db7d" + integrity sha512-b5sJjG1ZQ8iLSTJV19jWgMLoQicrQVVRkkQN7B/aboU+cf30lgnhIoGM8vEjqPxZFpryDU78PFpuTnfYNIHMeg== + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -2572,13 +2577,14 @@ quick-lru@^5.1.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== -random-bunny@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/random-bunny/-/random-bunny-2.0.0.tgz#f9950f53c7f5183a6dad26386db14f702d477cf7" - integrity sha512-xIDaPghs0nslKWNfxDLAGNtsUPUlmNagUmdNAHP7U4LSrGySbgSfAzCV8eECTeuny2csmf0SL5dBxEZdVvHgOA== +random-bunny@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/random-bunny/-/random-bunny-2.0.5.tgz#7a6fabc34c1999b13bc30eeb95c92d5cfa743fcb" + integrity sha512-pVSAufABfk1oBR32+gqkvs4s7d0pqKd3wxD09arPbgpR4mEDOVI4yx/BhU4fxyxFKgFnP01fDDAc6jSvr8WWzA== dependencies: glob-parent "^6.0.0" got "^11.8.3" + linqts "^1.14.4" react-is@^17.0.1: version "17.0.2" From 8e5ac6d01e8a2af0096c8c8b68945f50b6c49901 Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Thu, 2 Feb 2023 08:38:14 +0000 Subject: [PATCH 30/56] Update '.drone.yml' --- .drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.drone.yml b/.drone.yml index ec32358..99949c6 100644 --- a/.drone.yml +++ b/.drone.yml @@ -5,7 +5,7 @@ type: ssh name: deployment server: - host: 192.168.1.2 + host: 192.168.68.121 user: vylpes password: from_secret: ssh_password @@ -30,7 +30,7 @@ type: ssh name: staging server: - host: 192.168.1.2 + host: 192.168.68.121 user: vylpes password: from_secret: ssh_password From f5f87a52dc7ccdeb28df991e474002c9b11781c5 Mon Sep 17 00:00:00 2001 From: Ethan Lane <ethan@vylpes.com> Date: Fri, 3 Feb 2023 17:55:10 +0000 Subject: [PATCH 31/56] Update drone.yml --- .drone.yml | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/.drone.yml b/.drone.yml index 99949c6..4ed9c9e 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,44 +1,38 @@ --- kind: pipeline -type: ssh name: deployment -server: +image: appleboy/drone-ssh +settings: host: 192.168.68.121 - user: vylpes + username: vylpes password: from_secret: ssh_password - -steps: -- name: deploy - commands: - - sh /home/vylpes/scripts/vylbot/deploy_prod.sh + port: 22 + script: + - sh /home/vylpes/scripts/vylbot/deploy_prod.sh trigger: branch: - main event: - promote - target: - - production --- kind: pipeline -type: ssh name: staging -server: +image: appleboy/drone-ssh +settings: host: 192.168.68.121 - user: vylpes + username: vylpes password: from_secret: ssh_password - -steps: -- name: deploy - commands: - - sh /home/vylpes/scripts/vylbot/deploy_stage.sh + port: 22 + script: + - sh /home/vylpes/scripts/vylbot/deploy_stage.sh trigger: branch: From 1908f7505c4da29ba97e10b96b32bc798ebe0cb9 Mon Sep 17 00:00:00 2001 From: Ethan Lane <ethan@vylpes.com> Date: Fri, 3 Feb 2023 18:01:06 +0000 Subject: [PATCH 32/56] Update drone.yml --- .drone.yml | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/.drone.yml b/.drone.yml index 4ed9c9e..bdcc199 100644 --- a/.drone.yml +++ b/.drone.yml @@ -3,15 +3,16 @@ kind: pipeline name: deployment -image: appleboy/drone-ssh -settings: - host: 192.168.68.121 - username: vylpes - password: - from_secret: ssh_password - port: 22 - script: - - sh /home/vylpes/scripts/vylbot/deploy_prod.sh +steps: + image: appleboy/drone-ssh + settings: + host: 192.168.68.121 + username: vylpes + password: + from_secret: ssh_password + port: 22 + script: + - sh /home/vylpes/scripts/vylbot/deploy_prod.sh trigger: branch: @@ -24,15 +25,16 @@ trigger: kind: pipeline name: staging -image: appleboy/drone-ssh -settings: - host: 192.168.68.121 - username: vylpes - password: - from_secret: ssh_password - port: 22 - script: - - sh /home/vylpes/scripts/vylbot/deploy_stage.sh +steps: + image: appleboy/drone-ssh + settings: + host: 192.168.68.121 + username: vylpes + password: + from_secret: ssh_password + port: 22 + script: + - sh /home/vylpes/scripts/vylbot/deploy_stage.sh trigger: branch: From b9fdd51897c453f1afa6c5d8eef380bd30634eed Mon Sep 17 00:00:00 2001 From: Ethan Lane <ethan@vylpes.com> Date: Fri, 3 Feb 2023 18:02:40 +0000 Subject: [PATCH 33/56] Update drone.yml --- .drone.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.drone.yml b/.drone.yml index bdcc199..4584051 100644 --- a/.drone.yml +++ b/.drone.yml @@ -4,6 +4,7 @@ kind: pipeline name: deployment steps: +- name: deploy image: appleboy/drone-ssh settings: host: 192.168.68.121 @@ -26,6 +27,7 @@ kind: pipeline name: staging steps: +- name: stage image: appleboy/drone-ssh settings: host: 192.168.68.121 From fabbd84f2a6fb9e3ca2a1c64fe530410d3599e67 Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 20 Mar 2023 17:59:28 +0000 Subject: [PATCH 34/56] Update dependency minimatch to v7 (#271) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [minimatch](https://github.com/isaacs/minimatch) | dependencies | major | [`3.1.2` -> `7.4.2`](https://renovatebot.com/diffs/npm/minimatch/3.1.2/7.4.2) | --- ### Release Notes <details> <summary>isaacs/minimatch</summary> ### [`v7.4.2`](https://github.com/isaacs/minimatch/compare/v7.4.1...v7.4.2) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.4.1...v7.4.2) ### [`v7.4.1`](https://github.com/isaacs/minimatch/compare/v7.4.0...v7.4.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.4.0...v7.4.1) ### [`v7.4.0`](https://github.com/isaacs/minimatch/compare/v7.3.0...v7.4.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.3.0...v7.4.0) ### [`v7.3.0`](https://github.com/isaacs/minimatch/compare/v7.2.0...v7.3.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.2.0...v7.3.0) ### [`v7.2.0`](https://github.com/isaacs/minimatch/compare/v7.1.4...v7.2.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.1.4...v7.2.0) ### [`v7.1.4`](https://github.com/isaacs/minimatch/compare/v7.1.3...v7.1.4) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.1.3...v7.1.4) ### [`v7.1.3`](https://github.com/isaacs/minimatch/compare/v7.1.2...v7.1.3) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.1.2...v7.1.3) ### [`v7.1.2`](https://github.com/isaacs/minimatch/compare/v7.1.1...v7.1.2) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.1.1...v7.1.2) ### [`v7.1.1`](https://github.com/isaacs/minimatch/compare/v7.1.0...v7.1.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.1.0...v7.1.1) ### [`v7.1.0`](https://github.com/isaacs/minimatch/compare/v7.0.1...v7.1.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.0.1...v7.1.0) ### [`v7.0.1`](https://github.com/isaacs/minimatch/compare/v7.0.0...v7.0.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.0.0...v7.0.1) ### [`v7.0.0`](https://github.com/isaacs/minimatch/compare/v6.2.0...v7.0.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.2.0...v7.0.0) ### [`v6.2.0`](https://github.com/isaacs/minimatch/compare/v6.1.10...v6.2.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.10...v6.2.0) ### [`v6.1.10`](https://github.com/isaacs/minimatch/compare/v6.1.9...v6.1.10) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.9...v6.1.10) ### [`v6.1.9`](https://github.com/isaacs/minimatch/compare/v6.1.8...v6.1.9) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.8...v6.1.9) ### [`v6.1.8`](https://github.com/isaacs/minimatch/compare/v6.1.7...v6.1.8) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.7...v6.1.8) ### [`v6.1.7`](https://github.com/isaacs/minimatch/compare/v6.1.6...v6.1.7) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.6...v6.1.7) ### [`v6.1.6`](https://github.com/isaacs/minimatch/compare/v6.1.5...v6.1.6) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.5...v6.1.6) ### [`v6.1.5`](https://github.com/isaacs/minimatch/compare/v6.1.4...v6.1.5) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.4...v6.1.5) ### [`v6.1.4`](https://github.com/isaacs/minimatch/compare/v6.1.3...v6.1.4) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.3...v6.1.4) ### [`v6.1.3`](https://github.com/isaacs/minimatch/compare/v6.1.2...v6.1.3) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.2...v6.1.3) ### [`v6.1.2`](https://github.com/isaacs/minimatch/compare/v6.1.1...v6.1.2) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.1...v6.1.2) ### [`v6.1.1`](https://github.com/isaacs/minimatch/compare/v6.1.0...v6.1.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.1.0...v6.1.1) ### [`v6.1.0`](https://github.com/isaacs/minimatch/compare/v6.0.4...v6.1.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.0.4...v6.1.0) ### [`v6.0.4`](https://github.com/isaacs/minimatch/compare/v6.0.3...v6.0.4) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.0.3...v6.0.4) ### [`v6.0.3`](https://github.com/isaacs/minimatch/compare/v6.0.2...v6.0.3) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.0.2...v6.0.3) ### [`v6.0.2`](https://github.com/isaacs/minimatch/compare/v6.0.1...v6.0.2) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.0.1...v6.0.2) ### [`v6.0.1`](https://github.com/isaacs/minimatch/compare/v6.0.0...v6.0.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v6.0.0...v6.0.1) ### [`v6.0.0`](https://github.com/isaacs/minimatch/compare/v5.1.6...v6.0.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v5.1.6...v6.0.0) ### [`v5.1.6`](https://github.com/isaacs/minimatch/compare/v5.1.5...v5.1.6) [Compare Source](https://github.com/isaacs/minimatch/compare/v5.1.5...v5.1.6) ### [`v5.1.5`](https://github.com/isaacs/minimatch/compare/v5.1.4...v5.1.5) [Compare Source](https://github.com/isaacs/minimatch/compare/v5.1.4...v5.1.5) ### [`v5.1.4`](https://github.com/isaacs/minimatch/compare/v5.1.3...v5.1.4) [Compare Source](https://github.com/isaacs/minimatch/compare/v5.1.3...v5.1.4) ### [`v5.1.3`](https://github.com/isaacs/minimatch/compare/v5.1.2...v5.1.3) [Compare Source](https://github.com/isaacs/minimatch/compare/v5.1.2...v5.1.3) ### [`v5.1.2`](https://github.com/isaacs/minimatch/compare/v5.1.1...v5.1.2) [Compare Source](https://github.com/isaacs/minimatch/compare/v5.1.1...v5.1.2) ### [`v5.1.1`](https://github.com/isaacs/minimatch/compare/v5.1.0...v5.1.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v5.1.0...v5.1.1) ### [`v5.1.0`](https://github.com/isaacs/minimatch/compare/v5.0.1...v5.1.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v5.0.1...v5.1.0) ### [`v5.0.1`](https://github.com/isaacs/minimatch/compare/v5.0.0...v5.0.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v5.0.0...v5.0.1) ### [`v5.0.0`](https://github.com/isaacs/minimatch/compare/v4.2.3...v5.0.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v4.2.3...v5.0.0) ### [`v4.2.3`](https://github.com/isaacs/minimatch/compare/v4.2.2...v4.2.3) [Compare Source](https://github.com/isaacs/minimatch/compare/v4.2.2...v4.2.3) ### [`v4.2.2`](https://github.com/isaacs/minimatch/compare/v4.2.1...v4.2.2) [Compare Source](https://github.com/isaacs/minimatch/compare/v4.2.1...v4.2.2) ### [`v4.2.1`](https://github.com/isaacs/minimatch/compare/v4.2.0...v4.2.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v4.2.0...v4.2.1) ### [`v4.2.0`](https://github.com/isaacs/minimatch/compare/v4.1.1...v4.2.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v4.1.1...v4.2.0) ### [`v4.1.1`](https://github.com/isaacs/minimatch/compare/v4.1.0...v4.1.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v4.1.0...v4.1.1) ### [`v4.1.0`](https://github.com/isaacs/minimatch/compare/v4.0.0...v4.1.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v4.0.0...v4.1.0) ### [`v4.0.0`](https://github.com/isaacs/minimatch/compare/v3.1.2...v4.0.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v3.1.2...v4.0.0) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/271 Reviewed-by: Vylpes <ethan@vylpes.com> Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 5fe1e24..801b960 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "emoji-regex": "^9.2.0", "jest": "^27.4.5", "jest-mock-extended": "^3.0.0", - "minimatch": "3.1.2", + "minimatch": "7.4.2", "mysql": "^2.18.1", "random-bunny": "^2.0.5", "ts-jest": "^27.1.2", diff --git a/yarn.lock b/yarn.lock index 69249c2..5f67dfd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -894,6 +894,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -2322,12 +2329,12 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -minimatch@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== +minimatch@7.4.2: + version "7.4.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.2.tgz#157e847d79ca671054253b840656720cb733f10f" + integrity sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA== dependencies: - brace-expansion "^1.1.7" + brace-expansion "^2.0.1" minimatch@^3.0.4: version "3.0.4" From 580fd497a23b98db6950646750d0deaa1d403a6f Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 20 Mar 2023 18:02:12 +0000 Subject: [PATCH 35/56] Update dependency typescript to v5 (#275) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [typescript](https://www.typescriptlang.org/) ([source](https://github.com/Microsoft/TypeScript)) | devDependencies | major | [`^4.5.2` -> `^5.0.0`](https://renovatebot.com/diffs/npm/typescript/4.5.2/5.0.2) | --- ### Release Notes <details> <summary>Microsoft/TypeScript</summary> ### [`v5.0.2`](https://github.com/microsoft/TypeScript/releases/tag/v5.0.2): TypeScript 5.0 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.9.5...v5.0.2) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/). For new features, check out the [What's new in TypeScript v5.0.2](). For the complete list of fixed issues, check out the - [fixed issues query for Typescript v5.0.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.0.0%22+is%3Aclosed+). - [fixed issues query for Typescript v5.0.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.0.1%22+is%3Aclosed+). - [fixed issues query for Typescript v5.0.2 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.0.2%22+is%3Aclosed+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v4.9.5`](https://github.com/microsoft/TypeScript/releases/tag/v4.9.5): TypeScript 4.9.5 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.9.4...v4.9.5) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) #### Changes: - [`69e88ef`](https://github.com/Microsoft/TypeScript/commit/69e88ef5513a81acf69ec78f4af1f927da0d0584) Port ignore deprecations to 4.9 ([#​52419](https://github.com/Microsoft/TypeScript/issues/52419)) - [`daf4e81`](https://github.com/Microsoft/TypeScript/commit/daf4e817a18def96b70ac34703b158ff0e6d58df) Port timestamp fix to 4.9 ([#​52426](https://github.com/Microsoft/TypeScript/issues/52426)) ### [`v4.9.4`](https://github.com/microsoft/TypeScript/releases/tag/v4.9.4): TypeScript 4.9.4 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.9.3...v4.9.4) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9). For the complete list of fixed issues, check out the - [fixed issues query for Typescript v4.9.4](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+4.9.4%22+is%3Aclosed+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) #### Changes: - [`e286821`](https://github.com/Microsoft/TypeScript/commit/e2868216f637e875a74c675845625eb15dcfe9a2) Bump version to 4.9.4 and LKG. - [`eb5419f`](https://github.com/Microsoft/TypeScript/commit/eb5419fc8d980859b98553586dfb5f40d811a745) Cherry-pick [#​51704](https://github.com/Microsoft/TypeScript/issues/51704) to release 4.9 ([#​51712](https://github.com/Microsoft/TypeScript/issues/51712)) - [`b4d382b`](https://github.com/Microsoft/TypeScript/commit/b4d382b9b12460adf2da4cc0d1429cf19f8dc8be) Cherry-pick changes for narrowing to tagged literal types. - [`e7a02f4`](https://github.com/Microsoft/TypeScript/commit/e7a02f43fce47e1a39259ada5460bcc33c8e98b5) Port of [#​51626](https://github.com/Microsoft/TypeScript/issues/51626) and [#​51689](https://github.com/Microsoft/TypeScript/issues/51689) to release-4.9 ([#​51627](https://github.com/Microsoft/TypeScript/issues/51627)) - [`1727912`](https://github.com/Microsoft/TypeScript/commit/1727912f0437a7f367d90040fc4b0b4f3efd017a) Cherry-pick fix around `visitEachChild` to release-4.9. ([#​51544](https://github.com/Microsoft/TypeScript/issues/51544)) This list of changes was [auto generated](https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/\_release?releaseId=117&\_a=release-summary). ### [`v4.9.3`](https://github.com/microsoft/TypeScript/releases/tag/v4.9.3): TypeScript 4.9 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.8.4...v4.9.3) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) #### Changes: - [`93bd577`](https://github.com/Microsoft/TypeScript/commit/93bd577458d55cd720b2677705feab5c91eb12ce) Bump version to 4.9.3 and LKG. - [`107f832`](https://github.com/Microsoft/TypeScript/commit/107f832b80df2dc97748021cb00af2b6813db75b) Update LKG. - [`31bee56`](https://github.com/Microsoft/TypeScript/commit/31bee5682df130a14ffdd5742f994dbe7313dd0e) Cherry-pick PR [#​50977](https://github.com/Microsoft/TypeScript/issues/50977) into release-4.9 ([#​51363](https://github.com/Microsoft/TypeScript/issues/51363)) \[ [#​50872](https://github.com/Microsoft/TypeScript/issues/50872) ] - [`1e2fa7a`](https://github.com/Microsoft/TypeScript/commit/1e2fa7ae15f8530910fef8b916ec8a4ed0b59c45) Update version to 4.9.2-rc and LKG. - [`7ab89e5`](https://github.com/Microsoft/TypeScript/commit/7ab89e5c6e401d161f31f28a6c555a3ba530910e) Merge remote-tracking branch 'origin/main' into release-4.9 - [`e5cd686`](https://github.com/Microsoft/TypeScript/commit/e5cd686defb1a4cbdb36bd012357ba5bed28f371) Update package-lock.json - [`8d40dc1`](https://github.com/Microsoft/TypeScript/commit/8d40dc15d1b9945837e7860320fdccfe27c40cad) Update package-lock.json - [`5cfb3a2`](https://github.com/Microsoft/TypeScript/commit/5cfb3a2fe344a5350734305193e6cc99516285ca) Only call return() for an abrupt completion in user code ([#​51297](https://github.com/Microsoft/TypeScript/issues/51297)) - [`a7a9d15`](https://github.com/Microsoft/TypeScript/commit/a7a9d158e817fcb0e94dc1c24e0a401b21be0cc9) Fix for broken baseline in yieldInForInInDownlevelGenerator ([#​51345](https://github.com/Microsoft/TypeScript/issues/51345)) - [`7f8426f`](https://github.com/Microsoft/TypeScript/commit/7f8426f4df0d0a7dd8b72079dafc3e60164a23b1) fix for-in enumeration containing yield in generator ([#​51295](https://github.com/Microsoft/TypeScript/issues/51295)) <details><summary><b>See More</b></summary> - [`3d2b401`](https://github.com/Microsoft/TypeScript/commit/3d2b4017eb6b9a2b94bc673291e56ae95e8beddd) Fix assertion functions accessed via wildcard imports ([#​51324](https://github.com/Microsoft/TypeScript/issues/51324)) - [`64d0d5a`](https://github.com/Microsoft/TypeScript/commit/64d0d5ae140b7b26a09e75114517b418d6bcaa9f) fix(51301): Fixing an unused import at the end of a line removes the newline ([#​51320](https://github.com/Microsoft/TypeScript/issues/51320)) - [`754eeb2`](https://github.com/Microsoft/TypeScript/commit/754eeb2986bde30d5926e0fa99c87dda9266d01b) Update CodeQL workflow and configuration, fix found bugs ([#​51263](https://github.com/Microsoft/TypeScript/issues/51263)) - [`d8aad26`](https://github.com/Microsoft/TypeScript/commit/d8aad262006ad2d2c91aa7a0e4449b4b83c57f7b) Update package-lock.json - [`d4f26c8`](https://github.com/Microsoft/TypeScript/commit/d4f26c840b1db76c0b25a405c8e73830a2b45cbc) fix(51245): Class with parameter decorator in arrow function causes "convert to default export" refactoring failure ([#​51256](https://github.com/Microsoft/TypeScript/issues/51256)) - [`16faf45`](https://github.com/Microsoft/TypeScript/commit/16faf45682173ea437a50330feb4785578923d7f) Update package-lock.json - [`8b1ecdb`](https://github.com/Microsoft/TypeScript/commit/8b1ecdb701e2a2e19e9f8bcdd6b2beac087eabee) fix(50654): "Move to a new file" breaks the declaration of referenced variable ([#​50681](https://github.com/Microsoft/TypeScript/issues/50681)) - [`170a17f`](https://github.com/Microsoft/TypeScript/commit/170a17fad57eae619c5ef2b7bdb3ac00d6c32c47) Dom update 2022-10-25 ([#​51300](https://github.com/Microsoft/TypeScript/issues/51300)) - [`9c4e14d`](https://github.com/Microsoft/TypeScript/commit/9c4e14d75174432f6a4dc5967a09712a6784ab88) Remove "No type information for this code" from baseline ([#​51311](https://github.com/Microsoft/TypeScript/issues/51311)) - [`88d25b4`](https://github.com/Microsoft/TypeScript/commit/88d25b4f232929df59729156dfda6b65277affec) fix(50068): Refactors trigger debug failure when JSX text has a ' and a tag on the same line. ([#​51299](https://github.com/Microsoft/TypeScript/issues/51299)) - [`8bee69a`](https://github.com/Microsoft/TypeScript/commit/8bee69acf410d4986cb0cc102b949e2d133d5380) Update package-lock.json - [`702de1e`](https://github.com/Microsoft/TypeScript/commit/702de1eeaaef88a189e4d06e5a2aae287853790a) Fix early call to return/throw on generator ([#​51294](https://github.com/Microsoft/TypeScript/issues/51294)) - [`2c12b14`](https://github.com/Microsoft/TypeScript/commit/2c12b1499908ad7718e65d20e264561207c22375) Add a GH Action to file a new issue if we go a week without seeing a typescript-error-deltas issue ([#​51271](https://github.com/Microsoft/TypeScript/issues/51271)) - [`6af270d`](https://github.com/Microsoft/TypeScript/commit/6af270dee09d62516f6dc02ec102a745ffebc037) Update package-lock.json - [`2cc4c16`](https://github.com/Microsoft/TypeScript/commit/2cc4c16a26672a7ba6c97ba16309fcf334db7cae) Update package-lock.json - [`6093491`](https://github.com/Microsoft/TypeScript/commit/60934915d9ccc4ca9c0fb2cd060d7ec81601942b) Fix apparent typo in getStringMappingType ([#​51248](https://github.com/Microsoft/TypeScript/issues/51248)) - [`61c2609`](https://github.com/Microsoft/TypeScript/commit/61c26096e3373719ece686b84c698423890e9a5f) Update package-lock.json - [`ef69116`](https://github.com/Microsoft/TypeScript/commit/ef69116c41cb6805f89e6592eacb0ccb7f02207d) Generate shortest `rootDirs` module specifier instead of first possible ([#​51244](https://github.com/Microsoft/TypeScript/issues/51244)) - [`bbb42f4`](https://github.com/Microsoft/TypeScript/commit/bbb42f453dc684e03d977c5b70391124d57543a9) Fix typo in canWatchDirectoryOrFile found by CodeQL ([#​51262](https://github.com/Microsoft/TypeScript/issues/51262)) - [`a56b254`](https://github.com/Microsoft/TypeScript/commit/a56b254ad3c52b598bc5d44f83f3d0a1cf806068) Include 'this' type parameter in isRelatedTo fast path ([#​51230](https://github.com/Microsoft/TypeScript/issues/51230)) - [`3abd351`](https://github.com/Microsoft/TypeScript/commit/3abd351c0eea55758f27ee5558a4a1525b77f45b) Fix super property transform in async arrow in method ([#​51240](https://github.com/Microsoft/TypeScript/issues/51240)) - [`eed0511`](https://github.com/Microsoft/TypeScript/commit/eed05112180e0d94f78aa02d676d49468f15dc31) Update package-lock.json - [`2625c1f`](https://github.com/Microsoft/TypeScript/commit/2625c1feae25aede35465ca835440fc57bf13d52) Make the init config category order predictable ([#​51247](https://github.com/Microsoft/TypeScript/issues/51247)) - [`1ca99b3`](https://github.com/Microsoft/TypeScript/commit/1ca99b34029dafad2c18af7bdc0711f4abf7e522) fix(50551): Destructuring assignment with var bypasses "variable is used before being assigned" check (2454) ([#​50560](https://github.com/Microsoft/TypeScript/issues/50560)) - [`3f28fa1`](https://github.com/Microsoft/TypeScript/commit/3f28fa12dfecb8dfd66ce4684bf26f64e1f092f1) Update package-lock.json - [`906ebe4`](https://github.com/Microsoft/TypeScript/commit/906ebe49334a3a9c2dbd73cd3c902898bc712b66) Revert structuredTypeRelatedTo change and fix isUnitLikeType ([#​51076](https://github.com/Microsoft/TypeScript/issues/51076)) - [`8ac4652`](https://github.com/Microsoft/TypeScript/commit/8ac465239f52de1da3ada8cdc4c3f107f4d62e45) change type ([#​51231](https://github.com/Microsoft/TypeScript/issues/51231)) - [`245a02c`](https://github.com/Microsoft/TypeScript/commit/245a02cbed7ad50a21289730159abc8d19a66f40) fix(51222): Go-to-definition on return statements should jump to the containing function declaration ([#​51227](https://github.com/Microsoft/TypeScript/issues/51227)) - [`2dff34e`](https://github.com/Microsoft/TypeScript/commit/2dff34e8c4a91c0005ca9ccfb7e045e225b6f2e4) markAliasReferenced should include ExportValue as well ([#​51219](https://github.com/Microsoft/TypeScript/issues/51219)) - [`5ef2634`](https://github.com/Microsoft/TypeScript/commit/5ef2634f3df138323383c7f2e5a05163a924ee86) Update package-lock.json - [`d0f0e35`](https://github.com/Microsoft/TypeScript/commit/d0f0e35c88ae017fc4c1213eb2f83303ee22ebde) Remove old tslint comments ([#​51220](https://github.com/Microsoft/TypeScript/issues/51220)) - [`85d405a`](https://github.com/Microsoft/TypeScript/commit/85d405a1d74c0730a9d8d6307b26e8d6f3f75421) Fixed a false positive "await has no effect on the type" diagnostic with mixed generic union ([#​50833](https://github.com/Microsoft/TypeScript/issues/50833)) - [`1f8959f`](https://github.com/Microsoft/TypeScript/commit/1f8959f5dc04b2b2c2fc8a7dc53b6ac761e1f754) fix: avoid downleveled dynamic import closing over specifier expression ([#​49663](https://github.com/Microsoft/TypeScript/issues/49663)) - [`11066b2`](https://github.com/Microsoft/TypeScript/commit/11066b264f5d30fb5ac1f6c2f3a155c0190e75d2) Rename internal functions to `narrowTypeBySwitchOnTypeOf` and `narrowTypeByInKeyword` ([#​51215](https://github.com/Microsoft/TypeScript/issues/51215)) - [`4c9afe8`](https://github.com/Microsoft/TypeScript/commit/4c9afe8812fcdb4658472ccbced4a5cd4bae70ea) Update package-lock.json - [`f25bcb7`](https://github.com/Microsoft/TypeScript/commit/f25bcb7c27d78ce89e9c9356d27058cf86dbfb5c) fix(49196): add jsdoc snippet for interface member functions ([#​51135](https://github.com/Microsoft/TypeScript/issues/51135)) - [`7406ee9`](https://github.com/Microsoft/TypeScript/commit/7406ee9c145cd7d6117391818d5a1eca2d66ca8f) fix(51170): Completing an unimplemented property overwrites rest of line ([#​51175](https://github.com/Microsoft/TypeScript/issues/51175)) - [`a1d82fc`](https://github.com/Microsoft/TypeScript/commit/a1d82fc9dcced6ca6bde6e21c385d152d083679f) Remove some unnecessary code discovered by rollup ([#​51204](https://github.com/Microsoft/TypeScript/issues/51204)) - [`0481773`](https://github.com/Microsoft/TypeScript/commit/0481773a27fc6a0132c34502fd2a3b0c73cf63a3) LEGO: Merge pull request 51200 - [`98c19cb`](https://github.com/Microsoft/TypeScript/commit/98c19cbbbe83c2ae3c89a4e08317a4b9ccbcb206) LEGO: Merge pull request 51190 - [`13c9b05`](https://github.com/Microsoft/TypeScript/commit/13c9b05384544262363f3fd8b942b36aeb84fc61) Update package-lock.json - [`673475e`](https://github.com/Microsoft/TypeScript/commit/673475e1c5e582f2fd0bf8d89e33c7708607c8d8) Update package-lock.json - [`f6cf510`](https://github.com/Microsoft/TypeScript/commit/f6cf51053e024714dd6b8463fe6f8e7e33461e6b) Add more tracing to node16/nodenext resolution ([#​51168](https://github.com/Microsoft/TypeScript/issues/51168)) - [`83c5581`](https://github.com/Microsoft/TypeScript/commit/83c5581588f660247bd9648bafe67b49de060a55) Update package-lock.json - [`be5f0fe`](https://github.com/Microsoft/TypeScript/commit/be5f0fe5acfed5146514ebe7c1b65529def8e490) Add an extra regression test for awaited unresolvable recursive union ([#​51167](https://github.com/Microsoft/TypeScript/issues/51167)) - [`2cb7e77`](https://github.com/Microsoft/TypeScript/commit/2cb7e779d70d57ef0d46dd3f768e646b8bbe783a) fix(50416): correctly names disabled export refactors ([#​50663](https://github.com/Microsoft/TypeScript/issues/50663)) \[ [#​50416](https://github.com/Microsoft/TypeScript/issues/50416) ] - [`2bcfed0`](https://github.com/Microsoft/TypeScript/commit/2bcfed01f3458996e71ce37af43e3495cb7e4950) feat(37440): Provide a quick-fix for non-exported types ([#​51038](https://github.com/Microsoft/TypeScript/issues/51038)) - [`a24201c`](https://github.com/Microsoft/TypeScript/commit/a24201c8ef6f82b5729ab677b7a1a1d6d745fcb8) Remove VSDevMode.ps1 and createPlaygroundBuild ([#​51166](https://github.com/Microsoft/TypeScript/issues/51166)) - [`2da62a7`](https://github.com/Microsoft/TypeScript/commit/2da62a784bbba237b8239e84c8629cfafb0f595e) fix(51112): omit parameter names that precede the type ([#​51142](https://github.com/Microsoft/TypeScript/issues/51142)) - [`cf1b6b7`](https://github.com/Microsoft/TypeScript/commit/cf1b6b73330eab2dd484d71cbdb662a83b3c726f) feat(51163): show QF to fill in the missing properties for the mapped type. ([#​51165](https://github.com/Microsoft/TypeScript/issues/51165)) - [`bdcc240`](https://github.com/Microsoft/TypeScript/commit/bdcc240d68245e4be865b385bd6a8fd8fa546f56) Remove bug-causing carve-out in conditional type instantiation that hopefully is no longer required ([#​51151](https://github.com/Microsoft/TypeScript/issues/51151)) - [`37317a2`](https://github.com/Microsoft/TypeScript/commit/37317a208f34c141b64e26d0e92b3aed346e531f) Check nested weak types in intersections on target side of relation ([#​51140](https://github.com/Microsoft/TypeScript/issues/51140)) - [`9f49f9c`](https://github.com/Microsoft/TypeScript/commit/9f49f9ccb05a7bb56b8ca84b8036a3ad4e0e7c2b) Update package-lock.json - [`4f54e7e`](https://github.com/Microsoft/TypeScript/commit/4f54e7e947298162d29f3104265e74dcfbc90d82) Fix isExhaustiveSwitchStatement to better handle circularities ([#​51095](https://github.com/Microsoft/TypeScript/issues/51095)) - [`503604c`](https://github.com/Microsoft/TypeScript/commit/503604c884bd0557c851b11b699ef98cdb65b93b) Overloads shouldn't gain [@​deprecated](https://github.com/deprecated) tags of other overloads in quick info ([#​50904](https://github.com/Microsoft/TypeScript/issues/50904)) - [`e14a229`](https://github.com/Microsoft/TypeScript/commit/e14a2298c5add93816c6f487bcfc5ac72e3a4c59) Update package-lock.json - [`67256e5`](https://github.com/Microsoft/TypeScript/commit/67256e50c41aa9178a60c52de8416477f070b190) Remove unused declarations array in extractSymbol's TargetRange ([#​51091](https://github.com/Microsoft/TypeScript/issues/51091)) - [`9c87ded`](https://github.com/Microsoft/TypeScript/commit/9c87ded2b3fc4ba4a9a7656e9be39d5e404e6ab6) fix(51100): ensure tsserver shuts down when parent process is killed ([#​51107](https://github.com/Microsoft/TypeScript/issues/51107)) - [`c01ae01`](https://github.com/Microsoft/TypeScript/commit/c01ae01fac37268bac3362fb6e6d26db730f7ed5) Fix nightly publish oops in Gulpfile ([#​51131](https://github.com/Microsoft/TypeScript/issues/51131)) - [`a7d10f1`](https://github.com/Microsoft/TypeScript/commit/a7d10f15bbd28166b869ae00482214e360891613) Update package-lock.json - [`d0bfd8c`](https://github.com/Microsoft/TypeScript/commit/d0bfd8caed521bfd24fc44960d9936a891744bb7) fix(51072): ts.preProcessFile finds import in template string after conditional expression with template strings ([#​51082](https://github.com/Microsoft/TypeScript/issues/51082)) - [`ad56b5c`](https://github.com/Microsoft/TypeScript/commit/ad56b5ca56b763ab377e07121ecfebb457a2e810) Convert scripts/Gulpfile to checked mjs/cjs so they can run without compilation ([#​50988](https://github.com/Microsoft/TypeScript/issues/50988)) - [`dbeae5d`](https://github.com/Microsoft/TypeScript/commit/dbeae5d943c784661862c52b8e215a2907c31a33) fix(51017): Make lineText in the references response opt-out ([#​51081](https://github.com/Microsoft/TypeScript/issues/51081)) - [`d06a592`](https://github.com/Microsoft/TypeScript/commit/d06a592d02955822a7407b70969fb7a82bc17d59) Properly defer resolution of mapped types with generic `as` clauses ([#​51050](https://github.com/Microsoft/TypeScript/issues/51050)) - [`42b1049`](https://github.com/Microsoft/TypeScript/commit/42b1049aee8c655631cb4f0065de86ec1023d20a) Update package-lock.json - [`5f3e6cc`](https://github.com/Microsoft/TypeScript/commit/5f3e6cc4980d26af5d8a8f463e59b2c3338165c6) Plugin probe location is higher priority than peer node_modules ([#​51079](https://github.com/Microsoft/TypeScript/issues/51079)) \[ [#​34616](https://github.com/Microsoft/TypeScript/issues/34616) ] - [`2648f6a`](https://github.com/Microsoft/TypeScript/commit/2648f6ab09e3176c7da2c07c54066d3a3433a298) Plugins in project were adding up after every config file reload ([#​51087](https://github.com/Microsoft/TypeScript/issues/51087)) - [`c18791c`](https://github.com/Microsoft/TypeScript/commit/c18791ccf165672df3b55f5bdd4a8655f33be26c) Fix incorrect options type to WatchOptions ([#​51064](https://github.com/Microsoft/TypeScript/issues/51064)) - [`b0795e9`](https://github.com/Microsoft/TypeScript/commit/b0795e9c94757a8ee78077d160cde8819a9801ea) Update package-lock.json - [`43c6fd4`](https://github.com/Microsoft/TypeScript/commit/43c6fd4c09464204bc6a6e1c6c1d32fa12270414) Covert some of the config testing to baselines for easy validation ([#​51063](https://github.com/Microsoft/TypeScript/issues/51063)) - [`fc5e72b`](https://github.com/Microsoft/TypeScript/commit/fc5e72b92cb8ea13c5e0f2cfc35d8b2cbfd1fe36) Remove unused defaultWatchFileKind method since useFsEvents is default for tsserver and tsc ([#​51044](https://github.com/Microsoft/TypeScript/issues/51044)) - [`8af9a93`](https://github.com/Microsoft/TypeScript/commit/8af9a936b5240398370887c22cacaff65fee707b) Use typescript.d.ts in APISample tests ([#​51061](https://github.com/Microsoft/TypeScript/issues/51061)) - [`4953316`](https://github.com/Microsoft/TypeScript/commit/49533168dbb4e19f243b9dbdfd6a3aac69f5b3dd) Remove configureLanguageServiceBuild, instrumenter ([#​51048](https://github.com/Microsoft/TypeScript/issues/51048)) - [`9dfffd0`](https://github.com/Microsoft/TypeScript/commit/9dfffd0fbb406d7f2e5e2ca85768624ca388a7bf) Update GitHub Actions ([#​51045](https://github.com/Microsoft/TypeScript/issues/51045)) - [`4635a5c`](https://github.com/Microsoft/TypeScript/commit/4635a5cef9aefa9aa847ef7ce2e6767ddf4f54c2) Update package-lock.json - [`33a34e5`](https://github.com/Microsoft/TypeScript/commit/33a34e5b96bfe086266f4765ab9789a2a02507f9) Adding a JSDoc comment to the es5 type declarations to describe the functionality of Date.now() ([#​50630](https://github.com/Microsoft/TypeScript/issues/50630)) - [`299745c`](https://github.com/Microsoft/TypeScript/commit/299745cb217c2fc061f75b3735f8420d78b8360a) Fix crash in goto-def on `@override` ([#​51016](https://github.com/Microsoft/TypeScript/issues/51016)) - [`7dcf11f`](https://github.com/Microsoft/TypeScript/commit/7dcf11f13985be927886ebea353d282a9b3418e0) fix(50750): Object type literal with string literal property in contextual typing position causes language service error on all literal type references ([#​50757](https://github.com/Microsoft/TypeScript/issues/50757)) - [`5cd49f6`](https://github.com/Microsoft/TypeScript/commit/5cd49f6cbcd2effe9d425dee3a39cb49209bb656) Update package-lock.json - [`8a1b858`](https://github.com/Microsoft/TypeScript/commit/8a1b85880f89c9cff606c5844e8883e5f483c7db) Update package-lock.json - [`96894db`](https://github.com/Microsoft/TypeScript/commit/96894db6cb5b7af6857b4d0c7f70f7d8ac782d51) Include type parameter defaults in contextual typing ([#​50994](https://github.com/Microsoft/TypeScript/issues/50994)) \[ [#​51002](https://github.com/Microsoft/TypeScript/issues/51002) ] - [`0d0a793`](https://github.com/Microsoft/TypeScript/commit/0d0a79371471d627ae298a145f8009b05cbccb72) Allow Unicode extended escapes in ES5 and earlier ([#​50918](https://github.com/Microsoft/TypeScript/issues/50918)) - [`58bae8d`](https://github.com/Microsoft/TypeScript/commit/58bae8db69b275a3efa57b14b486778c55185552) Update package-lock.json - [`0ce72ef`](https://github.com/Microsoft/TypeScript/commit/0ce72ef6c8b39cd2d07e5b0eb3a0c144a7783ad2) Add option to OrganizeImports for removal only ([#​50931](https://github.com/Microsoft/TypeScript/issues/50931)) - [`42f9143`](https://github.com/Microsoft/TypeScript/commit/42f9143e114c5c07f40df83ed07ffeb3cbaf2101) feat: codefix for `for await of` ([#​50623](https://github.com/Microsoft/TypeScript/issues/50623)) - [`ecf50e8`](https://github.com/Microsoft/TypeScript/commit/ecf50e81a7a9cccd9bf5ea7598764082981faab0) Properly compute `SymbolFlags.Optional` for intersected properties ([#​50958](https://github.com/Microsoft/TypeScript/issues/50958)) - [`d1586de`](https://github.com/Microsoft/TypeScript/commit/d1586de0434567b998876929eb8229235b85b350) Fully resolve aliases when checking symbol flags ([#​50853](https://github.com/Microsoft/TypeScript/issues/50853)) - [`45148dd`](https://github.com/Microsoft/TypeScript/commit/45148dd715a7c3776840778b4df41e7e0bd0bf12) Update LKG to 4.8.4 ([#​50987](https://github.com/Microsoft/TypeScript/issues/50987)) - [`9a83f25`](https://github.com/Microsoft/TypeScript/commit/9a83f2551ded0d88a0ba0ec9af260f83eb3568cd) Update package-lock.json - [`865848f`](https://github.com/Microsoft/TypeScript/commit/865848fcfb9e6ce7dd64be563fc09f83d4bc9df5) Fix `<=` and `>` comparisons when compared against prerelease versions ([#​50915](https://github.com/Microsoft/TypeScript/issues/50915)) - [`fbfe934`](https://github.com/Microsoft/TypeScript/commit/fbfe9340a90777dee03b30f736fab44056123be0) Fix comparability between type parameters related by a union constraint ([#​50978](https://github.com/Microsoft/TypeScript/issues/50978)) - [`b09e93d`](https://github.com/Microsoft/TypeScript/commit/b09e93d3f6d3e999df001b53984954974c25b81f) Merge pull request [#​50041](https://github.com/Microsoft/TypeScript/issues/50041) from microsoft/fix/47969 - [`0ac12bb`](https://github.com/Microsoft/TypeScript/commit/0ac12bbe7a410238ca992a42f41816a97f6906f4) Update package-lock.json - [`8192d55`](https://github.com/Microsoft/TypeScript/commit/8192d550496d884263e292488e325ae96893dc78) Pick correct compilerOptions when checking if we can share emitSignatures ([#​50910](https://github.com/Microsoft/TypeScript/issues/50910)) \[ [#​50902](https://github.com/Microsoft/TypeScript/issues/50902) ] - [`16faef1`](https://github.com/Microsoft/TypeScript/commit/16faef1d8d522b66b6c672bdd15b4026e2018a62) During uptodate ness check with buildInfo, check if there are errors explicitly with noEmit ([#​50974](https://github.com/Microsoft/TypeScript/issues/50974)) \[ [#​50959](https://github.com/Microsoft/TypeScript/issues/50959) ] - [`63791f5`](https://github.com/Microsoft/TypeScript/commit/63791f52d4e7a3bf461b974e94abd8cbb6b546c5) Update package-lock.json - [`09368bc`](https://github.com/Microsoft/TypeScript/commit/09368bcbaebd157d1e66859ab6f5b30c2fd6eaff) Handle if project for open file will get recollected because of pending cleanup from closed script info ([#​50908](https://github.com/Microsoft/TypeScript/issues/50908)) \[ [#​50868](https://github.com/Microsoft/TypeScript/issues/50868) ] - [`c81bf4d`](https://github.com/Microsoft/TypeScript/commit/c81bf4d8b0c12410a082d6598fcc24cc721b6e9e) fix(49594): Typescript 4.7.3 bracketed class property compilation error strictPropertyInitialization:true ([#​49619](https://github.com/Microsoft/TypeScript/issues/49619)) - [`bc9cbbe`](https://github.com/Microsoft/TypeScript/commit/bc9cbbef421ae907f7dfd5a84ca69c4f68a8935b) Merge pull request [#​49912](https://github.com/Microsoft/TypeScript/issues/49912) from microsoft/fix/47508 - [`5a10f46`](https://github.com/Microsoft/TypeScript/commit/5a10f46c0028790120cb85c826efa4248707a964) Update package-lock.json - [`8e71f42`](https://github.com/Microsoft/TypeScript/commit/8e71f429c811ac7811533d7b0e02c32bad5a1b47) Fixing pr comments - [`c100c64`](https://github.com/Microsoft/TypeScript/commit/c100c6488db0482dcc1455290f456dece91cac0a) Update package-lock.json - [`2a91107`](https://github.com/Microsoft/TypeScript/commit/2a91107f7548eeb5e32673e76277d27264ea88e2) Update package-lock.json - [`4ab9e76`](https://github.com/Microsoft/TypeScript/commit/4ab9e76fb748b08712f9d0017dd8f0ba74d1859f) Use paths in package.json 'files' array that work with npm 6 and later. ([#​50930](https://github.com/Microsoft/TypeScript/issues/50930)) - [`549b542`](https://github.com/Microsoft/TypeScript/commit/549b5429d4837344e8c99657109bb6538fd2dbb5) Use paths in package.json 'files' array that work with npm 6 and later. - [`7f37d25`](https://github.com/Microsoft/TypeScript/commit/7f37d251fc69da34659e4c60792177e1e9a8e7a6) Update version to 4.9.1-beta and LKG. - [`f16ca7d`](https://github.com/Microsoft/TypeScript/commit/f16ca7dd364e57ee7ce337f987b20dbc1e34941f) Remove 'async' dependency, used only in errorCheck.ts, modernize file ([#​50667](https://github.com/Microsoft/TypeScript/issues/50667)) - [`c6bef3f`](https://github.com/Microsoft/TypeScript/commit/c6bef3f02874bddf6df120aa4f0d130c58478468) LEGO: Merge pull request 50921 - [`6753027`](https://github.com/Microsoft/TypeScript/commit/675302730b8ca525d47c910bf2d3174bd3b66a1b) Update package-lock.json - [`9740bcc`](https://github.com/Microsoft/TypeScript/commit/9740bcc53418e8792a4dbb978059ff5a02b55c91) Pluralized `hasInvalidatedResolution` -> `hasInvalidatedResolutions` ([#​50912](https://github.com/Microsoft/TypeScript/issues/50912)) - [`84c29cd`](https://github.com/Microsoft/TypeScript/commit/84c29cd576fd1facb9b3a353d5342df04acdb184) ๐Ÿค– Pick PR [#​50912](https://github.com/Microsoft/TypeScript/issues/50912) (Pluralized \`hasInvalidatedResolutio...) into release-4.9 ([#​50913](https://github.com/Microsoft/TypeScript/issues/50913)) - [`a26f634`](https://github.com/Microsoft/TypeScript/commit/a26f63424de249bb106804dfc9a024bb525de93e) Merge remote-tracking branch 'origin/main' into release-4.9 - [`a455955`](https://github.com/Microsoft/TypeScript/commit/a455955aac85ecc5b2182fe50b83670188955feb) Make hasInvalidatedResolution non internal for program and add it watchApi ([#​50776](https://github.com/Microsoft/TypeScript/issues/50776)) \[ [#​48057](https://github.com/Microsoft/TypeScript/issues/48057) ] - [`645d1cd`](https://github.com/Microsoft/TypeScript/commit/645d1cd7c1ee1d65a87b2183b173611467256a09) Fix assert in addIndirectUser in FAR ([#​50905](https://github.com/Microsoft/TypeScript/issues/50905)) - [`bbec17d`](https://github.com/Microsoft/TypeScript/commit/bbec17d9003246fa00d6bf676bb4ce7c54ff2be4) LEGO: Merge pull request 50900 - [`a9ecc67`](https://github.com/Microsoft/TypeScript/commit/a9ecc675d636c3bbca697bc4881b019e8645a7a6) Update package-lock.json - [`221cf55`](https://github.com/Microsoft/TypeScript/commit/221cf55a21e448bd3fe2cf26a754c9c0dda3dca3) package.json `exports` should have priority over `typesVersions` ([#​50890](https://github.com/Microsoft/TypeScript/issues/50890)) - [`acb8977`](https://github.com/Microsoft/TypeScript/commit/acb89771901f8c81c6046fa7c16361a83388ddab) Remove .github/tsc.json ([#​50664](https://github.com/Microsoft/TypeScript/issues/50664)) - [`7a3de81`](https://github.com/Microsoft/TypeScript/commit/7a3de819bfb93fb27ef7ea8305d2df069866c380) fix(49993): skip the quick fix for an expression with an enum type ([#​50625](https://github.com/Microsoft/TypeScript/issues/50625)) - [`2644f28`](https://github.com/Microsoft/TypeScript/commit/2644f2867734d77a3a3939c55d5cc0a5004df0ed) fix(49200): skip duplicated method declarations ([#​50609](https://github.com/Microsoft/TypeScript/issues/50609)) - [`98652a3`](https://github.com/Microsoft/TypeScript/commit/98652a349a67be718e8e8b5fcf590972eb62a104) Bump version to 4.9.0-beta and LKG. - [`4d91204`](https://github.com/Microsoft/TypeScript/commit/4d91204c9d9f27756785f62fade44d93824d47f4) fix(37030): Expand Selection in function and arrow function skips body block ([#​50711](https://github.com/Microsoft/TypeScript/issues/50711)) - [`e2dd508`](https://github.com/Microsoft/TypeScript/commit/e2dd5084f75ac37a78102d212b67d36595596137) DOM update 2022/09/21 ([#​50884](https://github.com/Microsoft/TypeScript/issues/50884)) - [`1d9ab83`](https://github.com/Microsoft/TypeScript/commit/1d9ab83914a551936ce5ef80340ee65cfd1422ba) fix(50866): emit modifiers from export declarations ([#​50874](https://github.com/Microsoft/TypeScript/issues/50874)) - [`92a1b12`](https://github.com/Microsoft/TypeScript/commit/92a1b124c178e1ff4871b29cb9abc00307e21742) LEGO: Merge pull request 50877 - [`e383db6`](https://github.com/Microsoft/TypeScript/commit/e383db692eb44561333c1bbe353788b337aebc99) Fix debug.ts \__debugKind check ([#​50871](https://github.com/Microsoft/TypeScript/issues/50871)) - [`01054e0`](https://github.com/Microsoft/TypeScript/commit/01054e05ab7638e96515619c4ce62200fdf4e0fd) Consistently add undefined/missing to optional tuple element types ([#​50831](https://github.com/Microsoft/TypeScript/issues/50831)) - [`d90795e`](https://github.com/Microsoft/TypeScript/commit/d90795e799ca8e41aabd6d0852abb585138200ef) Improve escape sequence handling in private names ([#​50856](https://github.com/Microsoft/TypeScript/issues/50856)) - [`938a69a`](https://github.com/Microsoft/TypeScript/commit/938a69a526166ca4e7880fa140fba432936f0fe3) Fix import statement completions followed by interface declaration ([#​50350](https://github.com/Microsoft/TypeScript/issues/50350)) - [`e002159`](https://github.com/Microsoft/TypeScript/commit/e002159ad133a024bae48a2e190e54ad93f6b52d) feat(49962): Disallow comparison against NaN ([#​50626](https://github.com/Microsoft/TypeScript/issues/50626)) - [`80ae43d`](https://github.com/Microsoft/TypeScript/commit/80ae43d2399503a04651e3705823137d36148b00) Fixing spaces - [`abc58bd`](https://github.com/Microsoft/TypeScript/commit/abc58bdabcf536bd5204fbc84fb7f45d75f1a9ad) Fixing baseline errors - [`305f4bd`](https://github.com/Microsoft/TypeScript/commit/305f4bd420bf9edc0239fd3a740aa83fbdeb9ba2) Merge branch 'main' into fix/47969 - [`23746af`](https://github.com/Microsoft/TypeScript/commit/23746af766b53fcc3afecfa16478809a5a36628a) fix(50591): RangeError: Maximum call stack size exceeded ([#​50594](https://github.com/Microsoft/TypeScript/issues/50594)) - [`168186f`](https://github.com/Microsoft/TypeScript/commit/168186f93d23ae59dbea3fea2adba453527343fd) Allow a union property of a private/protected member and an intersection property including that same member ([#​50328](https://github.com/Microsoft/TypeScript/issues/50328)) - [`812ebcf`](https://github.com/Microsoft/TypeScript/commit/812ebcf6e3aebfa72b976a6ae4d65929759a2867) Update package-lock.json - [`16156b1`](https://github.com/Microsoft/TypeScript/commit/16156b1baf26a39ce428423f7106f3ef2b4e98bb) Add rules from eslint's recommended set that triggered good lints ([#​50422](https://github.com/Microsoft/TypeScript/issues/50422)) - [`a11c416`](https://github.com/Microsoft/TypeScript/commit/a11c41621bbbab100a391dd348651c6661549663) Improve checking of `in` operator ([#​50666](https://github.com/Microsoft/TypeScript/issues/50666)) - [`67f2b62`](https://github.com/Microsoft/TypeScript/commit/67f2b62ed2bd1de0299781ba659fa638346bcecf) Gabritto/jsemitfixsilly ([#​50849](https://github.com/Microsoft/TypeScript/issues/50849)) - [`3014dec`](https://github.com/Microsoft/TypeScript/commit/3014dec8878a9ff8d86186a6ac3fd9fad4f3b739) Don't elide imports when transforming JS files ([#​50404](https://github.com/Microsoft/TypeScript/issues/50404)) - [`57c7aa7`](https://github.com/Microsoft/TypeScript/commit/57c7aa755ca3028ff13eb6a37d91775a6fac71e3) LEGO: Merge pull request 50842 - [`48a8e89`](https://github.com/Microsoft/TypeScript/commit/48a8e8953a1e609970dc85e08f99ac499bfe8356) Improve check of whether type query node possibly contains reference to type parameter ([#​50070](https://github.com/Microsoft/TypeScript/issues/50070)) - [`af9ced1`](https://github.com/Microsoft/TypeScript/commit/af9ced11f50c8ac15079d2f88f8961f1e5b62f7f) LEGO: Merge pull request 50825 - [`a8e13f7`](https://github.com/Microsoft/TypeScript/commit/a8e13f7340c5229426072d443fa511bba82a0054) Fixed an issue with destructured bindings from a generic union constraint not being narrowed correctly ([#​50221](https://github.com/Microsoft/TypeScript/issues/50221)) - [`08af0b6`](https://github.com/Microsoft/TypeScript/commit/08af0b6bf0041fef52ca8c1b69d6d4a3db439196) Update package-lock.json - [`0df46e8`](https://github.com/Microsoft/TypeScript/commit/0df46e873322b8eeb271a442eaf034d91ae68770) Fix test around RegExp match vs. exec results ([#​50813](https://github.com/Microsoft/TypeScript/issues/50813)) - [`906510e`](https://github.com/Microsoft/TypeScript/commit/906510e0f30590a4c8fdc892905ccb8dbe512e3d) Fixes for pr - [`2970c5d`](https://github.com/Microsoft/TypeScript/commit/2970c5d1671b2376711cd55594c4597d6da7d8c3) make `RegExpExecArray` always include index 0 ([#​50713](https://github.com/Microsoft/TypeScript/issues/50713)) - [`0507192`](https://github.com/Microsoft/TypeScript/commit/05071920a03f8ea530fe01f79f2537c999ec8b02) Accepting baselines - [`29e50b3`](https://github.com/Microsoft/TypeScript/commit/29e50b314900d22b08f6472918f59ae2b40aba08) Rewording documentation - [`01cae69`](https://github.com/Microsoft/TypeScript/commit/01cae69e3403a831bc5c752b95c8b7547dd95821) fix(50796): omit questionToken in object literal method completions ([#​50802](https://github.com/Microsoft/TypeScript/issues/50802)) - [`3b84f76`](https://github.com/Microsoft/TypeScript/commit/3b84f76fb23bd39d14c7243e5cd495fd207916c0) Fix crash caused by incorrect bounds check (regression in 4.8) ([#​50797](https://github.com/Microsoft/TypeScript/issues/50797)) - [`7e51306`](https://github.com/Microsoft/TypeScript/commit/7e51306d30b72ce474054c3f3047f57d90dca41a) Update package-lock.json - [`8b35c13`](https://github.com/Microsoft/TypeScript/commit/8b35c1300e14ebc026b4f1621db8f6f1bba30833) The error "Object is possibly null or undefined" is ambiguous. ([#​49797](https://github.com/Microsoft/TypeScript/issues/49797)) - [`a3f51b3`](https://github.com/Microsoft/TypeScript/commit/a3f51b3b8278b7dc5f59d83f35458338f57c81c7) Update user baselines +cc [@​sandersn](https://github.com/sandersn) ([#​43554](https://github.com/Microsoft/TypeScript/issues/43554)) - [`ba10a0d`](https://github.com/Microsoft/TypeScript/commit/ba10a0d7c06df259e620645a8d6fd9a5262d8b5d) Removing duplicated code - [`ec6ae1c`](https://github.com/Microsoft/TypeScript/commit/ec6ae1c4d0f48f15cd01b1502d0b2e5ac387dcf5) Partially revert [#​41044](https://github.com/Microsoft/TypeScript/issues/41044), restoring parameter destructurings in d.ts files ([#​50779](https://github.com/Microsoft/TypeScript/issues/50779)) - [`28232ca`](https://github.com/Microsoft/TypeScript/commit/28232ca4b8833957cdf8d592f085fb80d97ef604) LEGO: Merge pull request 50783 - [`49cfa1d`](https://github.com/Microsoft/TypeScript/commit/49cfa1db17b593191601736a11cbf165d42510a0) Update package-lock.json - [`4110b80`](https://github.com/Microsoft/TypeScript/commit/4110b80fbb24f2ac6dd284ef3511ca69ac6db517) Fix equality narrowing and comparable relation for intersections with {} ([#​50735](https://github.com/Microsoft/TypeScript/issues/50735)) - [`b23f1d6`](https://github.com/Microsoft/TypeScript/commit/b23f1d6b59beabde1072d14b7fb65781ce209c15) LEGO: Merge pull request 50771 - [`618fb2d`](https://github.com/Microsoft/TypeScript/commit/618fb2d8b92357d564ddb8596296ecaba5468002) Update package-lock.json - [`08b91f6`](https://github.com/Microsoft/TypeScript/commit/08b91f6b827e9ee98407c0eb969579ab77fa9f0c) fix(50717): tsc crashes when it sees a JSDoc tag inside an [@​override](https://github.com/override) annotation ([#​50724](https://github.com/Microsoft/TypeScript/issues/50724)) - [`60963d7`](https://github.com/Microsoft/TypeScript/commit/60963d7216266bca6ef3236f43913de703fe5c7a) Discriminant of type `never` should never be matched ([#​50755](https://github.com/Microsoft/TypeScript/issues/50755)) - [`e37ea53`](https://github.com/Microsoft/TypeScript/commit/e37ea53715a725dd13699dc1be5190c6ebd0d8f8) Update package-lock.json - [`a88c366`](https://github.com/Microsoft/TypeScript/commit/a88c36655b575d3039f187e64016b971efc0f173) Fix test baselining for tsserver host timeouts ([#​50748](https://github.com/Microsoft/TypeScript/issues/50748)) - [`6d38487`](https://github.com/Microsoft/TypeScript/commit/6d384876e5adeffd6e04cf4e6dd7ea5fc0dd0584) Fix workflow typo ([#​50746](https://github.com/Microsoft/TypeScript/issues/50746)) - [`6b890f9`](https://github.com/Microsoft/TypeScript/commit/6b890f93c491d3496dfd7909592c1df8a771fcd0) Handle more places where package direcroy is converted to canonical file path ([#​50740](https://github.com/Microsoft/TypeScript/issues/50740)) - [`f5f2923`](https://github.com/Microsoft/TypeScript/commit/f5f2923c7d0f0963a78b9c5f233b635d4e78ae91) Revert removal of nonInferrableAnyType ([#​50691](https://github.com/Microsoft/TypeScript/issues/50691)) - [`7120b52`](https://github.com/Microsoft/TypeScript/commit/7120b520cfe7b92d2b4bbfd679f1f5bd0c559c2c) Update twoslash workflow ([#​50738](https://github.com/Microsoft/TypeScript/issues/50738)) - [`68d526c`](https://github.com/Microsoft/TypeScript/commit/68d526c200a0a5c51024586890b2473c9819c6ea) Don't run linter after tests runs ([#​50597](https://github.com/Microsoft/TypeScript/issues/50597)) - [`8e5e2e0`](https://github.com/Microsoft/TypeScript/commit/8e5e2e08ead119910d6eb177eab9beb84e3ab311) Fix backticks in our JSDoc comments ([#​50737](https://github.com/Microsoft/TypeScript/issues/50737)) - [`a4cabe7`](https://github.com/Microsoft/TypeScript/commit/a4cabe725b413f154f738b48c1fe2f053cff7d26) Support for auto-accessor fields from the Stage 3 Decorators proposal ([#​49705](https://github.com/Microsoft/TypeScript/issues/49705)) - [`7737473`](https://github.com/Microsoft/TypeScript/commit/77374732df82c9d5c1319677dc595868bbc648b5) Update package-lock.json - [`12ab0fe`](https://github.com/Microsoft/TypeScript/commit/12ab0fea9f45c48ea644c8273bedde235c8bcc61) Update package-lock.json - [`eb40134`](https://github.com/Microsoft/TypeScript/commit/eb40134373cc524bd15432e15490d4e369754c50) Don't leave space for property access on non-integer literals ([#​50703](https://github.com/Microsoft/TypeScript/issues/50703)) - [`a70bb9d`](https://github.com/Microsoft/TypeScript/commit/a70bb9d3ff102e044e83d2db43e585105e9a1761) Preserve special intersections in mapped types ([#​50704](https://github.com/Microsoft/TypeScript/issues/50704)) - [`1a1c271`](https://github.com/Microsoft/TypeScript/commit/1a1c27167536e005a4d241ef84c43c0c0ca0aaf9) Don't remove space before dot if in property access on numeric literal ([#​50695](https://github.com/Microsoft/TypeScript/issues/50695)) - [`7c918fb`](https://github.com/Microsoft/TypeScript/commit/7c918fb76682e79e8fd460cf1c2da9f2f22c91a3) Baseline host state when baselining tsserver tests ([#​50678](https://github.com/Microsoft/TypeScript/issues/50678)) - [`2f1ba45`](https://github.com/Microsoft/TypeScript/commit/2f1ba45cbaca5e95959f9fd43c42edd64bc5638c) Update LKG and devDep of typescript to v4.8.3 ([#​50689](https://github.com/Microsoft/TypeScript/issues/50689)) - [`be4e9ba`](https://github.com/Microsoft/TypeScript/commit/be4e9bac8ff66174d4e856dae06f69aa4ef7e479) Update package-lock.json - [`f46a680`](https://github.com/Microsoft/TypeScript/commit/f46a680863d7ecf7b7aa46b5e056acfe702b78bb) Remove error message in node16 ([#​50673](https://github.com/Microsoft/TypeScript/issues/50673)) - [`ab831d0`](https://github.com/Microsoft/TypeScript/commit/ab831d018030304b886590fc4253f9dab593ddb0) Ignore `--help` and `-?` in `tsc init` generated `compilerOptions` ([#​50628](https://github.com/Microsoft/TypeScript/issues/50628)) - [`bb6f36f`](https://github.com/Microsoft/TypeScript/commit/bb6f36f7c80c290b98759823445dae73ebfd3eb2) Forward intersection state flag to conditional type target check ([#​50620](https://github.com/Microsoft/TypeScript/issues/50620)) - [`b58721f`](https://github.com/Microsoft/TypeScript/commit/b58721fe15a9d58aa9c2b53b6e6fdb7966f56d2c) Update package-lock.json - [`3c3820b`](https://github.com/Microsoft/TypeScript/commit/3c3820b1a4033de90a6f9369b3e714ba58231e99) Simplify CI detection ([#​50661](https://github.com/Microsoft/TypeScript/issues/50661)) - [`9ac1fce`](https://github.com/Microsoft/TypeScript/commit/9ac1fce1175964f71117f6574d96eda127282bf4) Fix eslint not looking at certain scripts, fix lints ([#​50660](https://github.com/Microsoft/TypeScript/issues/50660)) - [`fd05c0c`](https://github.com/Microsoft/TypeScript/commit/fd05c0cc6da676c5b9183ad2a7ced7ce363b855a) Make useFsEvents as default strategy for the watching ([#​50366](https://github.com/Microsoft/TypeScript/issues/50366)) - [`5c2f770`](https://github.com/Microsoft/TypeScript/commit/5c2f770d9714276567e6ef9ec805368756539725) Remove unused cancellation from build ([#​50658](https://github.com/Microsoft/TypeScript/issues/50658)) - [`66fbf05`](https://github.com/Microsoft/TypeScript/commit/66fbf058ece7882f2a964aeeda81bc352e4a6329) Update package-lock.json - [`7910c50`](https://github.com/Microsoft/TypeScript/commit/7910c509c4545517489d6264571bb6c05248fb4a) Update package-lock.json - [`fd3a84c`](https://github.com/Microsoft/TypeScript/commit/fd3a84c3f0c80cb201c47399a055625f919a9b91) Report every instance of TS1208 ([#​50101](https://github.com/Microsoft/TypeScript/issues/50101)) - [`62f980a`](https://github.com/Microsoft/TypeScript/commit/62f980aff82ac8b5939bc9b65cf6e55d122b42d9) Check if its same buildinfo only for directly referenced projects and not recursively ([#​50617](https://github.com/Microsoft/TypeScript/issues/50617)) \[ [#​50545](https://github.com/Microsoft/TypeScript/issues/50545) ] - [`856c7c5`](https://github.com/Microsoft/TypeScript/commit/856c7c5fdd25833dbb0e1e67071200cd706eae4f) Allow `{}` to narrow in same special cases as `unknown` ([#​50601](https://github.com/Microsoft/TypeScript/issues/50601)) - [`854d448`](https://github.com/Microsoft/TypeScript/commit/854d448e5ccf542a05d0b5dcb97e1b925905e258) `in` operator shouldn't narrow `{}` originating in `unknown` ([#​50610](https://github.com/Microsoft/TypeScript/issues/50610)) - [`549e61d`](https://github.com/Microsoft/TypeScript/commit/549e61d0af1ba885be29d69f341e7d3a00686071) Update package-lock.json - [`bcf9949`](https://github.com/Microsoft/TypeScript/commit/bcf994996ea0ddd8ca7daadd6b5fbc712eb5ce6b) fix(50079): show deprecated on JSX attributes ([#​50084](https://github.com/Microsoft/TypeScript/issues/50084)) - [`5df09a5`](https://github.com/Microsoft/TypeScript/commit/5df09a514c99010d3126d8a9f11aa00ecbd0bd21) Use bidirectional comparability in narrowing ([#​50592](https://github.com/Microsoft/TypeScript/issues/50592)) - [`891cdc5`](https://github.com/Microsoft/TypeScript/commit/891cdc58aa4005d7197e76ec0a48afcbc3b44ac3) Remove unused baselines ([#​50593](https://github.com/Microsoft/TypeScript/issues/50593)) - [`6db2c88`](https://github.com/Microsoft/TypeScript/commit/6db2c882f389c95c526df0e890354205b5696a7d) {} & null and {} & undefined should always be never ([#​50553](https://github.com/Microsoft/TypeScript/issues/50553)) - [`238c341`](https://github.com/Microsoft/TypeScript/commit/238c341701439a95d5eb71a4cf421c0574d0ee47) Defer distributing index over generic object types ([#​50540](https://github.com/Microsoft/TypeScript/issues/50540)) - [`2983092`](https://github.com/Microsoft/TypeScript/commit/298309271bc526b9753c10c1c916bfe9d5c89a8b) Do not canonicalize the file names when getting absolute paths during nodenext resolution ([#​50557](https://github.com/Microsoft/TypeScript/issues/50557)) \[ [#​50544](https://github.com/Microsoft/TypeScript/issues/50544) ] - [`dcade77`](https://github.com/Microsoft/TypeScript/commit/dcade7732c142abba88eecae78c115fa37b95e01) Update package-lock.json - [`a9797d2`](https://github.com/Microsoft/TypeScript/commit/a9797d218d34fefc61b823d0e1dd24f6eb5363c8) fix(50340): typeof ... === "undefined" check on discriminated union of undefined and object type doesn't narrow correctly ([#​50344](https://github.com/Microsoft/TypeScript/issues/50344)) - [`43f8ae6`](https://github.com/Microsoft/TypeScript/commit/43f8ae6df4ffefb7e4795808b94bcfbf74628682) Only normalize intersections that include {} ([#​50535](https://github.com/Microsoft/TypeScript/issues/50535)) - [`d293e72`](https://github.com/Microsoft/TypeScript/commit/d293e723a20cdba258238397097e9a4e409bc41f) Rename API to importPlugin ([#​50554](https://github.com/Microsoft/TypeScript/issues/50554)) - [`cd312d3`](https://github.com/Microsoft/TypeScript/commit/cd312d3076c054cdf9ed6f33c2d3e3995bca92eb) Managing control flow - [`19defbf`](https://github.com/Microsoft/TypeScript/commit/19defbfe576f3f2da32b5372274e4664b66ec00d) Update package-lock.json - [`f071d30`](https://github.com/Microsoft/TypeScript/commit/f071d303c182c2a776da1471a3ec9ef05297a9d8) Move contributing related info out of README to CONTRIBUTING ([#​50543](https://github.com/Microsoft/TypeScript/issues/50543)) - [`488d0ee`](https://github.com/Microsoft/TypeScript/commit/488d0eebd0556fcc6e5f4cfc69c2ef7e5c2708ed) Retain name and propertyName in declaration emit copies of binding patterns if property name is a keyword ([#​50537](https://github.com/Microsoft/TypeScript/issues/50537)) - [`8b482b5`](https://github.com/Microsoft/TypeScript/commit/8b482b513d87c6fcda8ece18b99f8a01cff5c605) Update package-lock.json - [`c89f355`](https://github.com/Microsoft/TypeScript/commit/c89f355a41b18c96eccb67dade04fce8c330068b) Remove redundant pretest script ([#​50518](https://github.com/Microsoft/TypeScript/issues/50518)) - [`6d170b4`](https://github.com/Microsoft/TypeScript/commit/6d170b490d5ff5f881f6cbf8cd749e0103ee5d1f) Handle intersections in isGenericTypeWithoutNullableConstraint ([#​50497](https://github.com/Microsoft/TypeScript/issues/50497)) - [`ed6889c`](https://github.com/Microsoft/TypeScript/commit/ed6889cd5b61b9fa5156018362d867def18e281d) LEGO: Merge pull request 50506 - [`29cbfe9`](https://github.com/Microsoft/TypeScript/commit/29cbfe9a2504cfae30bae938bdb2be6081ccc5c8) LEGO: Merge pull request 50493 - [`6faa291`](https://github.com/Microsoft/TypeScript/commit/6faa291b453987192d996517b4376b14980b25c4) LEGO: Merge pull request 50484 - [`71b2ba6`](https://github.com/Microsoft/TypeScript/commit/71b2ba6111e934f2b4ee112bc4d8d2f47ced22f5) Reuse computed type of condition expressions ([#​49881](https://github.com/Microsoft/TypeScript/issues/49881)) - [`8778c1d`](https://github.com/Microsoft/TypeScript/commit/8778c1ded3a1955dce1063d72caf4523bec37c90) Update package-lock.json - [`4579245`](https://github.com/Microsoft/TypeScript/commit/4579245f36d9c3deccb097da9d5545f9c5c1ab26) fix(50427): allow convert function expressions ([#​50430](https://github.com/Microsoft/TypeScript/issues/50430)) - [`cbc0b17`](https://github.com/Microsoft/TypeScript/commit/cbc0b17eac1fcb011a66f0544c813968cdf065c4) Push package-lock.json updates via typescript-bot token ([#​50476](https://github.com/Microsoft/TypeScript/issues/50476)) - [`bb3a7ae`](https://github.com/Microsoft/TypeScript/commit/bb3a7aec11a20afb30c5098a75e001d1a4eb08f9) fix(50415): Language server debug failure - Did not expect GetAccessor to have an Identifier in its trivia ([#​50470](https://github.com/Microsoft/TypeScript/issues/50470)) - [`3557092`](https://github.com/Microsoft/TypeScript/commit/3557092b1474bc3405a29da93bd15c108ab2f8b3) Rephrase error message to be 100% technically correct ([#​50471](https://github.com/Microsoft/TypeScript/issues/50471)) - [`71d1911`](https://github.com/Microsoft/TypeScript/commit/71d19115031ae1c48fa34a24636dfae5e87e1b08) add unknown to DateTimeFormatTypes ([#​50402](https://github.com/Microsoft/TypeScript/issues/50402)) - [`8f89599`](https://github.com/Microsoft/TypeScript/commit/8f895997d2cb79deb937d50fa1bed1c470528025) Don't include .gitattributes in package ([#​50475](https://github.com/Microsoft/TypeScript/issues/50475)) - [`6e8337e`](https://github.com/Microsoft/TypeScript/commit/6e8337ef70e4a36a4df76a3362a41cbcac0dcb84) Optimize substitution types ([#​50397](https://github.com/Microsoft/TypeScript/issues/50397)) - [`226dd0b`](https://github.com/Microsoft/TypeScript/commit/226dd0b7bf5cb5e5bb4dc34ab0e8e14f408f3e20) Fix typechecking related lints that changed post 4.8, update LKG to 4.8.2 ([#​50472](https://github.com/Microsoft/TypeScript/issues/50472)) - [`164dddc`](https://github.com/Microsoft/TypeScript/commit/164dddc48e1eaa83780b8e72bc7afeebe768437b) feat(7481): Operator to ensure an expression is contextually typed by, and satisfies, some type ([#​46827](https://github.com/Microsoft/TypeScript/issues/46827)) - [`0715791`](https://github.com/Microsoft/TypeScript/commit/07157914eb26a6e9abdcda7255c4094c9efff4cd) Update package-lock.json - [`e675ea8`](https://github.com/Microsoft/TypeScript/commit/e675ea8dd83aaed018a67534323305c36d373b40) Remove AUTHORS.md, .mailmap, authors.ts script ([#​50410](https://github.com/Microsoft/TypeScript/issues/50410)) - [`38076df`](https://github.com/Microsoft/TypeScript/commit/38076df3465af555051db06006bbf30323af0e2d) Fix auto import crash due to difference in `paths` handling ([#​50419](https://github.com/Microsoft/TypeScript/issues/50419)) - [`12eb519`](https://github.com/Microsoft/TypeScript/commit/12eb519b3f81d0999bbc4ce9a845744f4dfc215e) fix(50435): Duplicate seeming Code Actions for convert const to let ([#​50442](https://github.com/Microsoft/TypeScript/issues/50442)) - [`a08b045`](https://github.com/Microsoft/TypeScript/commit/a08b045d2b22c87a6341a0c1d1318271d14acc86) Jsdoc property description ([#​50269](https://github.com/Microsoft/TypeScript/issues/50269)) \[ [#​47933](https://github.com/Microsoft/TypeScript/issues/47933) ] - [`5ba22e0`](https://github.com/Microsoft/TypeScript/commit/5ba22e05a96538498a78ab206e1b9892f420e7a1) Remove top level loc folder ([#​50421](https://github.com/Microsoft/TypeScript/issues/50421)) - [`c4eb37c`](https://github.com/Microsoft/TypeScript/commit/c4eb37c8a0d5915d64e3992a91a34724aab19fe6) Update package-lock.json - [`8d7ad8c`](https://github.com/Microsoft/TypeScript/commit/8d7ad8c3aee4130e2b8cc6438e03e12a39cd398a) fix(50375): Errors for missing enum-named properties should attempt to preserve names ([#​50382](https://github.com/Microsoft/TypeScript/issues/50382)) - [`fb717df`](https://github.com/Microsoft/TypeScript/commit/fb717df6bf85318c3d1e833a1dde6789d394cdb2) Discard union types before considering weak type checks on unit-like types ([#​50423](https://github.com/Microsoft/TypeScript/issues/50423)) - [`b9a5bbc`](https://github.com/Microsoft/TypeScript/commit/b9a5bbc9afe9fa231aba5162c258bf1e2fa1e82e) Syntax operations also need to ensure project is present for the open script infos since update could be pending to make sure open script info has project ([#​50418](https://github.com/Microsoft/TypeScript/issues/50418)) \[ [#​50131](https://github.com/Microsoft/TypeScript/issues/50131) ] - [`1d4fbbb`](https://github.com/Microsoft/TypeScript/commit/1d4fbbb529d183b1e6988447e6744cfa7750b9f6) Update package-lock.json - [`44ce3cf`](https://github.com/Microsoft/TypeScript/commit/44ce3cff70cb79d1a45b48def04413db5303a151) fix(50224): Intellisense for strings within a type's Union doesn't work properly for JSX ([#​50231](https://github.com/Microsoft/TypeScript/issues/50231)) - [`6ee5db9`](https://github.com/Microsoft/TypeScript/commit/6ee5db95c2ad4fee74ad02368afa1d2cc693407e) Use package.json files array instead of .npmignore ([#​50408](https://github.com/Microsoft/TypeScript/issues/50408)) This list of changes was [auto generated](https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/\_release?releaseId=116&\_a=release-summary).</details> ### [`v4.8.4`](https://github.com/microsoft/TypeScript/releases/tag/v4.8.4): TypeScript 4.8.4 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.8.3...v4.8.4) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.8.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.0%22+). - [fixed issues query for Typescript 4.8.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.1%22+). - [fixed issues query for Typescript 4.8.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.2%22+). - [fixed issues query for Typescript 4.8.3 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.3%22+). - [fixed issues query for Typescript 4.8.4 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.4%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [Visual Studio 2022/2019](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.TypeScript-484) ([Select new version in project options](https://github.com/Microsoft/TypeScript/wiki/Updating-TypeScript-in-Visual-Studio-2017)) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v4.8.3`](https://github.com/microsoft/TypeScript/releases/tag/v4.8.3): TypeScript 4.8.3 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.8.2...v4.8.3) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.8.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.0%22+). - [fixed issues query for Typescript 4.8.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.1%22+). - [fixed issues query for Typescript 4.8.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.2%22+). - [fixed issues query for Typescript 4.8.3 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.3%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [Visual Studio 2022/2019](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.TypeScript-483) ([Select new version in project options](https://github.com/Microsoft/TypeScript/wiki/Updating-TypeScript-in-Visual-Studio-2017)) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v4.8.2`](https://github.com/microsoft/TypeScript/releases/tag/v4.8.2): TypeScript 4.8 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.7.4...v4.8.2) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.8.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.0%22+). - [fixed issues query for Typescript 4.8.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.1%22+). - [fixed issues query for Typescript 4.8.1 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.8.2%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [Visual Studio 2022/2019](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.TypeScript-48) ([Select new version in project options](https://github.com/Microsoft/TypeScript/wiki/Updating-TypeScript-in-Visual-Studio-2017)) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v4.7.4`](https://github.com/microsoft/TypeScript/releases/tag/v4.7.4): TypeScript 4.7.4 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.7.3...v4.7.4) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.7.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.0%22+). - [fixed issues query for Typescript 4.7.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.1%22+). - [fixed issues query for Typescript 4.7.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.2%22+). - [fixed issues query for Typescript 4.7.3 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.3%22+). - [fixed issues query for Typescript 4.7.4 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.4%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [Visual Studio 2022/2019](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.TypeScript-474) ([Select new version in project options](https://github.com/Microsoft/TypeScript/wiki/Updating-TypeScript-in-Visual-Studio-2017)) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v4.7.3`](https://github.com/microsoft/TypeScript/releases/tag/v4.7.3): TypeScript 4.7.3 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.7.2...v4.7.3) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.7.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.0%22+). - [fixed issues query for Typescript 4.7.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.1%22+). - [fixed issues query for Typescript 4.7.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.2%22+). - [fixed issues query for Typescript 4.7.3 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.3%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [Visual Studio 2022/2019](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.TypeScript-473) ([Select new version in project options](https://github.com/Microsoft/TypeScript/wiki/Updating-TypeScript-in-Visual-Studio-2017)) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v4.7.2`](https://github.com/microsoft/TypeScript/releases/tag/v4.7.2): TypeScript 4.7.2 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.6.4...v4.7.2) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.7.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.0%22+). - [fixed issues query for Typescript 4.7.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.1%22+). - [fixed issues query for Typescript 4.7.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.2%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [Visual Studio 2022/2019](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.TypeScript-472) ([Select new version in project options](https://github.com/Microsoft/TypeScript/wiki/Updating-TypeScript-in-Visual-Studio-2017)) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v4.6.4`](https://github.com/microsoft/TypeScript/releases/tag/v4.6.4): TypeScript 4.6.4 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.6.3...v4.6.4) This release includes [a bug fix for text formatting on certain ranges](Studiohttps://github.com/microsoft/TypeScript/pull/48463), which was impacting Visual Studio users. For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.6.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.0%22+). - [fixed issues query for Typescript 4.6.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.1%22+). - [fixed issues query for Typescript 4.6.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.2%22+). - [fixed issues query for Typescript 4.6.3 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.3%22+). - [fixed issues query for Typescript 4.6.4 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.4%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [Visual Studio 2022/2019](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.TypeScript-464) ([Select new version in project options](https://github.com/Microsoft/TypeScript/wiki/Updating-TypeScript-in-Visual-Studio-2017)) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v4.6.3`](https://github.com/microsoft/TypeScript/releases/tag/v4.6.3): TypeScript 4.6.3 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.6.2...v4.6.3) This release includes fixes for - [an incremental parsing bug caused by faulty error recovery logic](https://github.com/microsoft/TypeScript/issues/47895) - [improved results from the TypeScript API's `preProcessFile` function](https://github.com/microsoft/TypeScript/pull/47657) For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.6.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.0%22+). - [fixed issues query for Typescript 4.6.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.1%22+). - [fixed issues query for Typescript 4.6.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.2%22+). - [fixed issues query for Typescript 4.6.3 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.3%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) ### [`v4.6.2`](https://github.com/microsoft/TypeScript/releases/tag/v4.6.2): TypeScript 4.6.2 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.5.5...v4.6.2) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-6/). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.6.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.0%22+). - [fixed issues query for Typescript 4.6.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.1%22+). - [fixed issues query for Typescript 4.6.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.6.2%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [Visual Studio 2022/2019](https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.TypeScript-46) ([Select new version in project options](https://github.com/Microsoft/TypeScript/wiki/Updating-TypeScript-in-Visual-Studio-2017)) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v4.5.5`](https://github.com/microsoft/TypeScript/releases/tag/v4.5.5): TypeScript 4.5.5 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.5.4...v4.5.5) This [patch release](https://github.com/microsoft/TypeScript/issues?q=is%3Aissue+milestone%3A%22TypeScript+4.5.5%22+is%3Aclosed) includes a number of fixes to language service crashes and assertion violations, along with improvements to JSX attribute snippets. For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.5.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.0%22+). - [fixed issues query for Typescript 4.5.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.1%22+). - [fixed issues query for Typescript 4.5.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.2%22+). - [fixed issues query for Typescript 4.5.3 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.3%22+). - [fixed issues query for Typescript 4.5.4 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.4%22+). - [fixed issues query for Typescript 4.5.5 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.5%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) <!-- * [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) --> ### [`v4.5.4`](https://github.com/microsoft/TypeScript/releases/tag/v4.5.4): TypeScript 4.5.4 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.5.3...v4.5.4) This patch release includes a fix for [incorrectly offering up JSX attribute snippet completions at the beginning of a tag name](https://github.com/microsoft/TypeScript/issues/47090). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.5.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.0%22+). - [fixed issues query for Typescript 4.5.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.1%22+). - [fixed issues query for Typescript 4.5.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.2%22+). - [fixed issues query for Typescript 4.5.3 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.3%22+). - - [fixed issues query for Typescript 4.5.4 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.4%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v4.5.3`](https://github.com/microsoft/TypeScript/releases/tag/v4.5.3): TypeScript 4.5.3 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v4.5.2...v4.5.3) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 4.5.0 (Beta)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.0%22+). - [fixed issues query for Typescript 4.5.1 (RC)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.1%22+). - [fixed issues query for Typescript 4.5.2 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.2%22+). - [fixed issues query for Typescript 4.5.3 (Stable)](https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.5.3%22+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/275 Reviewed-by: Vylpes <ethan@vylpes.com> Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 801b960..b8a09a3 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,6 @@ }, "devDependencies": { "@types/node": "^18.0.0", - "typescript": "^4.5.2" + "typescript": "^5.0.0" } } diff --git a/yarn.lock b/yarn.lock index 5f67dfd..2168cad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3043,10 +3043,10 @@ typeorm@^0.2.44: yargs "^17.0.1" zen-observable-ts "^1.0.0" -typescript@^4.5.2: - version "4.5.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998" - integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw== +typescript@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.2.tgz#891e1a90c5189d8506af64b9ef929fca99ba1ee5" + integrity sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw== undici@^5.9.1: version "5.10.0" From ec1763be265d482d6413eabbbba39ba348964196 Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 27 Mar 2023 17:59:54 +0100 Subject: [PATCH 36/56] Update dependency minimatch to v7.4.3 (#282) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [minimatch](https://github.com/isaacs/minimatch) | dependencies | patch | [`7.4.2` -> `7.4.3`](https://renovatebot.com/diffs/npm/minimatch/7.4.2/7.4.3) | --- ### Release Notes <details> <summary>isaacs/minimatch</summary> ### [`v7.4.3`](https://github.com/isaacs/minimatch/compare/v7.4.2...v7.4.3) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.4.2...v7.4.3) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/282 Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index b8a09a3..03422eb 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "emoji-regex": "^9.2.0", "jest": "^27.4.5", "jest-mock-extended": "^3.0.0", - "minimatch": "7.4.2", + "minimatch": "7.4.3", "mysql": "^2.18.1", "random-bunny": "^2.0.5", "ts-jest": "^27.1.2", diff --git a/yarn.lock b/yarn.lock index 7545374..456f7ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2327,10 +2327,10 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -minimatch@7.4.2: - version "7.4.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.2.tgz#157e847d79ca671054253b840656720cb733f10f" - integrity sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA== +minimatch@7.4.3: + version "7.4.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.3.tgz#012cbf110a65134bb354ae9773b55256cdb045a2" + integrity sha512-5UB4yYusDtkRPbRiy1cqZ1IpGNcJCGlEMG17RKzPddpyiPKoCdwohbED8g4QXT0ewCt8LTkQXuljsUfQ3FKM4A== dependencies: brace-expansion "^2.0.1" From c02dbb30d7afbbb22064511422d9a79db70ac291 Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 27 Mar 2023 18:06:33 +0100 Subject: [PATCH 37/56] Update dependency jest to v29 (#241) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [jest](https://jestjs.io/) ([source](https://github.com/facebook/jest)) | dependencies | major | [`^27.4.5` -> `^29.0.0`](https://renovatebot.com/diffs/npm/jest/27.4.5/29.5.0) | | [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/jest) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped)) | dependencies | major | [`^27.0.3` -> `^29.0.0`](https://renovatebot.com/diffs/npm/@types%2fjest/27.0.3/29.5.0) | --- ### Release Notes <details> <summary>facebook/jest</summary> ### [`v29.5.0`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2950) [Compare Source](https://github.com/facebook/jest/compare/v29.4.3...v29.5.0) ##### Features - `[jest-changed-files]` Support Sapling ([#​13941](https://github.com/facebook/jest/pull/13941)) - `[jest-circus, @​jest/cli, jest-config]` Add feature to randomize order of tests via CLI flag or through the config file([#​12922](https://github.com/facebook/jest/pull/12922)) - `[jest-cli, jest-config, @​jest/core, jest-haste-map, @​jest/reporters, jest-runner, jest-runtime, @​jest/types]` Add `workerThreads` configuration option to allow using [worker threads](https://nodejs.org/dist/latest/docs/api/worker_threads.html) for parallelization ([#​13939](https://github.com/facebook/jest/pull/13939)) - `[jest-cli]` Export `yargsOptions` ([#​13970](https://github.com/facebook/jest/pull/13970)) - `[jest-config]` Add `openHandlesTimeout` option to configure possible open handles warning. ([#​13875](https://github.com/facebook/jest/pull/13875)) - `[@jest/create-cache-key-function]` Allow passing `length` argument to `createCacheKey()` function and set its default value to `16` on Windows ([#​13827](https://github.com/facebook/jest/pull/13827)) - `[jest-message-util]` Add support for [AggregateError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError) ([#​13946](https://github.com/facebook/jest/pull/13946) & [#​13947](https://github.com/facebook/jest/pull/13947)) - `[jest-message-util]` Add support for [Error causes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) in `test` and `it` ([#​13935](https://github.com/facebook/jest/pull/13935) & [#​13966](https://github.com/facebook/jest/pull/13966)) - `[jest-reporters]` Add `summaryThreshold` option to summary reporter to allow overriding the internal threshold that is used to print the summary of all failed tests when the number of test suites surpasses it ([#​13895](https://github.com/facebook/jest/pull/13895)) - `[jest-runtime]` Expose `@sinonjs/fake-timers` async APIs functions `advanceTimersByTimeAsync(msToRun)` (`tickAsync(msToRun)`), `advanceTimersToNextTimerAsync(steps)` (`nextAsync`), `runAllTimersAsync` (`runAllAsync`), and `runOnlyPendingTimersAsync` (`runToLastAsync`) ([#​13981](https://github.com/facebook/jest/pull/13981)) - `[jest-runtime, @​jest/transform]` Allow V8 coverage provider to collect coverage from files which were not loaded explicitly ([#​13974](https://github.com/facebook/jest/pull/13974)) - `[jest-snapshot]` Add support to `cts` and `mts` TypeScript files to inline snapshots ([#​13975](https://github.com/facebook/jest/pull/13975)) - `[jest-worker]` Add `start` method to worker farms ([#​13937](https://github.com/facebook/jest/pull/13937)) - `[jest-worker]` Support passing a URL as path to worker ([#​13982](https://github.com/facebook/jest/pull/13982)) ##### Fixes - `[babel-plugin-jest-hoist]` Fix unwanted hoisting of nested `jest` usages ([#​13952](https://github.com/facebook/jest/pull/13952)) - `[jest-circus]` Send test case results for `todo` tests ([#​13915](https://github.com/facebook/jest/pull/13915)) - `[jest-circus]` Update message printed on test timeout ([#​13830](https://github.com/facebook/jest/pull/13830)) - `[jest-circus]` Avoid creating the word "testfalse" when `takesDoneCallback` is `false` in the message printed on test timeout AND updated timeouts test ([#​13954](https://github.com/facebook/jest/pull/13954)) - `[jest-environment-jsdom]` Stop setting `document` to `null` on teardown ([#​13972](https://github.com/facebook/jest/pull/13972)) - `[@jest/expect-utils]` Update `toStrictEqual()` to be able to check `jest.fn().mock.calls` ([#​13960](https://github.com/facebook/jest/pull/13960)) - `[@jest/test-result]` Allow `TestResultsProcessor` type to return a Promise ([#​13950](https://github.com/facebook/jest/pull/13950)) ##### Chore & Maintenance - `[jest-snapshot]` Remove dependency on `jest-haste-map` ([#​13977](https://github.com/facebook/jest/pull/13977)) ### [`v29.4.3`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2943) [Compare Source](https://github.com/facebook/jest/compare/v29.4.2...v29.4.3) ##### Features - `[expect]` Update `toThrow()` to be able to use error `cause`s ([#​13606](https://github.com/facebook/jest/pull/13606)) - `[jest-core]` allow to use `workerIdleMemoryLimit` with only 1 worker or `runInBand` option ([#​13846](https://github.com/facebook/jest/pull/13846)) - `[jest-message-util]` Add support for [error `cause`s](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) ([#​13868](https://github.com/facebook/jest/pull/13868) & [#​13912](https://github.com/facebook/jest/pull/13912)) - `[jest-runtime]` Revert `import assertions` for JSON modules as it's been relegated to Stage 2 ([#​13911](https://github.com/facebook/jest/pull/13911)) ##### Fixes - `[@jest/expect-utils]` `subsetEquality` should consider also an object's inherited string keys ([#​13824](https://github.com/facebook/jest/pull/13824)) - `[jest-mock]` Clear mock state when `jest.restoreAllMocks()` is called ([#​13867](https://github.com/facebook/jest/pull/13867)) - `[jest-mock]` Prevent `mockImplementationOnce` and `mockReturnValueOnce` bleeding into `withImplementation` ([#​13888](https://github.com/facebook/jest/pull/13888)) - `[jest-mock]` Do not restore mocks when `jest.resetAllMocks()` is called ([#​13866](https://github.com/facebook/jest/pull/13866)) ### [`v29.4.2`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2942) [Compare Source](https://github.com/facebook/jest/compare/v29.4.1...v29.4.2) ##### Features - `[@jest/core]` Instrument significant lifecycle events with [`performance.mark()`](https://nodejs.org/docs/latest-v16.x/api/perf_hooks.html#performancemarkname-options) ([#​13859](https://github.com/facebook/jest/pull/13859)) ##### Fixes - `[expect, @​jest/expect]` Provide type of `actual` as a generic argument to `Matchers` to allow better-typed extensions ([#​13848](https://github.com/facebook/jest/pull/13848)) - `[jest-circus]` Added explicit mention of test failing because `done()` is not being called in error message ([#​13847](https://github.com/facebook/jest/pull/13847)) - `[jest-runtime]` Handle CJS re-exports of node core modules from ESM ([#​13856](https://github.com/facebook/jest/pull/13856)) - `[jest-transform]` Downgrade `write-file-atomic` to v4 ([#​13853](https://github.com/facebook/jest/pull/13853)) - `[jest-worker]` Ignore IPC messages not intended for Jest ([#​13543](https://github.com/facebook/jest/pull/13543)) ##### Chore & Maintenance - `[*]` make sure to exclude `.eslintcache` from published module ([#​13832](https://github.com/facebook/jest/pull/13832)) - `[docs]` Cleanup incorrect links in CHANGELOG.md ([#​13857](https://github.com/facebook/jest/pull/13857)) ### [`v29.4.1`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2941) [Compare Source](https://github.com/facebook/jest/compare/v29.4.0...v29.4.1) ##### Features - `[expect, jest-circus, @​jest/types]` Implement `numPassingAsserts` of testResults to track the number of passing asserts in a test ([#​13795](https://github.com/facebook/jest/pull/13795)) - `[jest-core]` Add newlines to JSON output ([#​13817](https://github.com/facebook/jest/pull/13817)) - `[@jest/reporters]` Automatic log folding in GitHub Actions Reporter ([#​13626](https://github.com/facebook/jest/pull/13626)) ##### Fixes - `[@jest/expect-utils]` `toMatchObject` diffs should include `Symbol` properties ([#​13810](https://github.com/facebook/jest/pull/13810)) - `[jest-runtime]` Handle missing `replaceProperty` ([#​13823](https://github.com/facebook/jest/pull/13823)) - `[@jest/types]` Add partial support for `done` callbacks in typings of `each` ([#​13756](https://github.com/facebook/jest/pull/13756)) ### [`v29.4.0`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2940) [Compare Source](https://github.com/facebook/jest/compare/v29.3.1...v29.4.0) ##### Features - `[expect, @​jest/expect-utils]` Support custom equality testers ([#​13654](https://github.com/facebook/jest/pull/13654)) - `[jest-config, jest-worker]` Use `os.availableParallelism` if available to calculate number of workers to spawn ([#​13738](https://github.com/facebook/jest/pull/13738)) - `[@jest/globals, jest-mock]` Add `jest.replaceProperty()` that replaces property value ([#​13496](https://github.com/facebook/jest/pull/13496)) - `[jest-haste-map]` ignore Sapling vcs directories (`.sl/`) ([#​13674](https://github.com/facebook/jest/pull/13674)) - `[jest-resolve]` Support subpath imports ([#​13705](https://github.com/facebook/jest/pull/13705), [#​13723](https://github.com/facebook/jest/pull/13723), [#​13777](https://github.com/facebook/jest/pull/13777)) - `[jest-runtime]` Add `jest.isolateModulesAsync` for scoped module initialization of asynchronous functions ([#​13680](https://github.com/facebook/jest/pull/13680)) - `[jest-runtime]` Add `jest.isEnvironmentTornDown` function ([#​13741](https://github.com/facebook/jest/pull/13741)) - `[jest-test-result]` Added `skipped` and `focused` status to `FormattedTestResult` ([#​13700](https://github.com/facebook/jest/pull/13700)) - `[jest-transform]` Support for asynchronous `createTransformer` ([#​13762](https://github.com/facebook/jest/pull/13762)) ##### Fixes - `[jest-environment-node]` Fix non-configurable globals ([#​13687](https://github.com/facebook/jest/pull/13687)) - `[@jest/expect-utils]` `toMatchObject` should handle `Symbol` properties ([#​13639](https://github.com/facebook/jest/pull/13639)) - `[jest-mock]` Fix `mockReset` and `resetAllMocks` `undefined` return value([#​13692](https://github.com/facebook/jest/pull/13692)) - `[jest-resolve]` Add global paths to `require.resolve.paths` ([#​13633](https://github.com/facebook/jest/pull/13633)) - `[jest-resolve]` Correct node core module detection when using `node:` specifiers ([#​13806](https://github.com/facebook/jest/pull/13806)) - `[jest-runtime]` Support WASM files that import JS resources ([#​13608](https://github.com/facebook/jest/pull/13608)) - `[jest-runtime]` Use the `scriptTransformer` cache in `jest-runner` ([#​13735](https://github.com/facebook/jest/pull/13735)) - `[jest-runtime]` Enforce import assertions when importing JSON in ESM ([#​12755](https://github.com/facebook/jest/pull/12755) & [#​13805](https://github.com/facebook/jest/pull/13805)) - `[jest-snapshot]` Make sure to import `babel` outside of the sandbox ([#​13694](https://github.com/facebook/jest/pull/13694)) - `[jest-transform]` Ensure the correct configuration is passed to preprocessors specified multiple times in the `transform` option ([#​13770](https://github.com/facebook/jest/pull/13770)) ##### Chore & Maintenance - `[@jest/fake-timers]` Update `@sinonjs/fake-timers` ([#​13612](https://github.com/facebook/jest/pull/13612)) - `[docs]` Improve custom puppeteer example to prevent worker warnings ([#​13619](https://github.com/facebook/jest/pull/13619)) ### [`v29.3.1`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2931) [Compare Source](https://github.com/facebook/jest/compare/v29.3.0...v29.3.1) ##### Fixes - `[jest-config]` Do not warn about `preset` in `ProjectConfig` ([#​13583](https://github.com/facebook/jest/pull/13583)) ##### Performance - `[jest-transform]` Defer creation of cache directory ([#​13420](https://github.com/facebook/jest/pull/13420)) ### [`v29.3.0`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2930) [Compare Source](https://github.com/facebook/jest/compare/v29.2.2...v29.3.0) ##### Features - `[jest-runtime]` Support WebAssembly (Wasm) imports in ESM modules ([#​13505](https://github.com/facebook/jest/pull/13505)) ##### Fixes - `[jest-config]` Add config validation for `projects` option ([#​13565](https://github.com/facebook/jest/pull/13565)) - `[jest-mock]` Treat cjs modules as objects so they can be mocked ([#​13513](https://github.com/facebook/jest/pull/13513)) - `[jest-worker]` Throw an error instead of hanging when jest workers terminate unexpectedly ([#​13566](https://github.com/facebook/jest/pull/13566)) ##### Chore & Maintenance - `[@jest/transform]` Update `convert-source-map` ([#​13509](https://github.com/facebook/jest/pull/13509)) - `[docs]` Mention `toStrictEqual` in UsingMatchers docs. ([#​13560](https://github.com/facebook/jest/pull/13560)) ### [`v29.2.2`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2922) [Compare Source](https://github.com/facebook/jest/compare/v29.2.1...v29.2.2) ##### Fixes - `[@jest/test-sequencer]` Make sure sharding does not produce empty groups ([#​13476](https://github.com/facebook/jest/pull/13476)) - `[jest-circus]` Test marked as `todo` are shown as todo when inside a focussed describe ([#​13504](https://github.com/facebook/jest/pull/13504)) - `[jest-mock]` Ensure mock resolved and rejected values are promises from correct realm ([#​13503](https://github.com/facebook/jest/pull/13503)) - `[jest-snapshot]` Don't highlight passing asymmetric property matchers in snapshot diff ([#​13480](https://github.com/facebook/jest/issues/13480)) ##### Chore & Maintenance - `[docs]` Update link to Jest 28 upgrade guide in error message ([#​13483](https://github.com/facebook/jest/pull/13483)) - `[jest-runner, jest-watcher]` Update `emittery` ([#​13490](https://github.com/facebook/jest/pull/13490)) ### [`v29.2.1`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2921) [Compare Source](https://github.com/facebook/jest/compare/v29.2.0...v29.2.1) ##### Features - `[@jest/globals, jest-mock]` Add `jest.Spied*` utility types ([#​13440](https://github.com/facebook/jest/pull/13440)) ##### Fixes - `[jest-environment-node]` make `globalThis.performance` writable for Node 19 and fake timers ([#​13467](https://github.com/facebook/jest/pull/13467)) - `[jest-mock]` Revert [#​13398](https://github.com/facebook/jest/pull/13398) to restore mocking of setters ([#​13472](https://github.com/facebook/jest/pull/13472)) ##### Performance - `[*]` Use sha1 instead of sha256 for hashing ([#​13421](https://github.com/facebook/jest/pull/13421)) ### [`v29.2.0`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2920) [Compare Source](https://github.com/facebook/jest/compare/v29.1.2...v29.2.0) ##### Features - `[@jest/cli, jest-config]` A seed for the test run will be randomly generated, or set by a CLI option ([#​13400](https://github.com/facebook/jest/pull/13400)) - `[@jest/cli, jest-config]` `--show-seed` will display the seed value in the report, and can be set via a CLI flag or through the config file ([#​13400](https://github.com/facebook/jest/pull/13400)) - `[jest-config]` Add `readInitialConfig` utility function ([#​13356](https://github.com/facebook/jest/pull/13356)) - `[jest-core]` Allow `testResultsProcessor` to be async ([#​13343](https://github.com/facebook/jest/pull/13343)) - `[@jest/environment, jest-environment-node, jest-environment-jsdom, jest-runtime]` Add `getSeed()` to the `jest` object ([#​13400](https://github.com/facebook/jest/pull/13400)) - `[expect, @​jest/expect-utils]` Allow `isA` utility to take a type argument ([#​13355](https://github.com/facebook/jest/pull/13355)) - `[expect]` Expose `AsyncExpectationResult` and `SyncExpectationResult` types ([#​13411](https://github.com/facebook/jest/pull/13411)) ##### Fixes - `[babel-plugin-jest-hoist]` Ignore `TSTypeQuery` when checking for hoisted references ([#​13367](https://github.com/facebook/jest/pull/13367)) - `[jest-core]` Fix `detectOpenHandles` false positives for some special objects such as `TLSWRAP` ([#​13414](https://github.com/facebook/jest/pull/13414)) - `[jest-mock]` Fix mocking of getters and setters on classes ([#​13398](https://github.com/facebook/jest/pull/13398)) - `[jest-reporters]` Revert: Transform file paths into hyperlinks ([#​13399](https://github.com/facebook/jest/pull/13399)) - `[@jest/types]` Infer type of `each` table correctly when the table is a tuple or array ([#​13381](https://github.com/facebook/jest/pull/13381)) - `[@jest/types]` Rework typings to allow the `*ReturnedWith` matchers to be called with no argument ([#​13385](https://github.com/facebook/jest/pull/13385)) ##### Chore & Maintenance - `[*]` Update `@babel/*` deps, resulting in slightly different stack traces for `each` ([#​13422](https://github.com/facebook/jest/pull/13422)) ##### Performance - `[jest-runner]` Do not instrument v8 coverage data if coverage should not be collected ([#​13282](https://github.com/facebook/jest/pull/13282)) ### [`v29.1.2`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2912) [Compare Source](https://github.com/facebook/jest/compare/v29.1.1...v29.1.2) ##### Fixes - `[expect, @​jest/expect]` Revert buggy inference of argument types for `*CalledWith` and `*ReturnedWith` matchers introduced in 29.1.0 ([#​13339](https://github.com/facebook/jest/pull/13339)) - `[jest-worker]` Add missing dependency on `jest-util` ([#​13341](https://github.com/facebook/jest/pull/13341)) ### [`v29.1.1`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2911) [Compare Source](https://github.com/facebook/jest/compare/v29.1.0...v29.1.1) ##### Fixes - `[jest-mock]` Revert [#​13145](https://github.com/facebook/jest/pull/13145) which broke mocking of transpiled ES modules ### [`v29.1.0`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2910) [Compare Source](https://github.com/facebook/jest/compare/v29.0.3...v29.1.0) ##### Features - `[expect, @​jest/expect]` Support type inference for function parameters in `CalledWith` assertions ([#​13268](https://github.com/facebook/jest/pull/13268)) - `[expect, @​jest/expect]` Infer type of `*ReturnedWith` matchers argument ([#​13278](https://github.com/facebook/jest/pull/13278)) - `[@jest/environment, jest-runtime]` Allow `jest.requireActual` and `jest.requireMock` to take a type argument ([#​13253](https://github.com/facebook/jest/pull/13253)) - `[@jest/environment]` Allow `jest.mock` and `jest.doMock` to take a type argument ([#​13254](https://github.com/facebook/jest/pull/13254)) - `[@jest/fake-timers]` Add `jest.now()` to return the current fake clock time ([#​13244](https://github.com/facebook/jest/pull/13244), [#​13246](https://github.com/facebook/jest/pull/13246)) - `[@jest/mock]` Add `withImplementation` method for temporarily overriding a mock ([#​13281](https://github.com/facebook/jest/pull/13281)) - `[expect]` Export `toThrow*` matchers ([#​13328](https://github.com/facebook/jest/pull/13328)) ##### Fixes - `[jest-circus, jest-jasmine2]` Fix error messages for Node's `assert.throes` ([#​13322](https://github.com/facebook/jest/pull/13322)) - `[jest-haste-map]` Remove `__proto__` usage ([#​13256](https://github.com/facebook/jest/pull/13256)) - `[jest-mock]` Improve `spyOn` typings to handle optional properties ([#​13247](https://github.com/facebook/jest/pull/13247)) - `[jest-mock]` Fix mocking of getters and setters on classes ([#​13145](https://github.com/facebook/jest/pull/13145)) - `[jest-snapshot]` Throw useful error when an array is passed as property matchers ([#​13263](https://github.com/facebook/jest/pull/13263)) - `[jest-snapshot]` Prioritize parser used in the project ([#​13323](https://github.com/facebook/jest/pull/13323)) - `[jest-transform]` Attempt to work around issues with atomic writes on Windows ([#​11423](https://github.com/facebook/jest/pull/11423)) ### [`v29.0.3`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2903) [Compare Source](https://github.com/facebook/jest/compare/v29.0.2...v29.0.3) ##### Features - `[@jest/environment, jest-runtime]` Allow passing a generic type argument to `jest.createMockFromModule<T>()` method ([#​13202](https://github.com/facebook/jest/pull/13202)) - `[expect]` Expose `ExpectationResult` type ([#​13240](https://github.com/facebook/jest/pull/13240)) - `[jest-snapshot]` Expose `Context` type ([#​13240](https://github.com/facebook/jest/pull/13240)) - `[@jest/globals]` Add `jest.Mock` type helper ([#​13235](https://github.com/facebook/jest/pull/13235)) ##### Fixes - `[jest-core]` Capture `execError` during `TestScheduler.scheduleTests` and dispatch to reporters ([#​13203](https://github.com/facebook/jest/pull/13203)) - `[jest-resolve]` Make sure to resolve module paths after looking at `exports` ([#​13242](https://github.com/facebook/jest/pull/13242)) - `[jest-resolve]` Improve error on module not found deep in the `require` stack ([#​8704](https://github.com/facebook/jest/pull/8704)) - `[jest-snapshot]` Fix typings of snapshot matchers ([#​13240](https://github.com/facebook/jest/pull/13240)) ##### Chore & Maintenance - `[*]` Fix inconsistent workspace prefixes ([#​13217](https://github.com/facebook/jest/pull/13217)) - `[jest-haste-map]` Expose a minimal public API to TypeScript ([#​13023](https://github.com/facebook/jest/pull/13023)) ### [`v29.0.2`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2902) [Compare Source](https://github.com/facebook/jest/compare/v29.0.1...v29.0.2) ##### Features - `[jest-transform]` Expose `TransformFactory` type ([#​13184](https://github.com/facebook/jest/pull/13184)) ##### Fixes - `[babel-plugin-jest-hoist]` Support imported `jest` in mock factory ([#​13188](https://github.com/facebook/jest/pull/13188)) - `[jest-mock]` Align the behavior and return type of `generateFromMetadata` method ([#​13207](https://github.com/facebook/jest/pull/13207)) - `[jest-runtime]` Support `jest.resetModules()` with ESM ([#​13211](https://github.com/facebook/jest/pull/13211)) ### [`v29.0.1`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2901) [Compare Source](https://github.com/facebook/jest/compare/v29.0.0...v29.0.1) ##### Fixes - `[jest-snapshot]` Pass `snapshotFormat` through when diffing snapshots ([#​13181](https://github.com/facebook/jest/pull/13181)) ### [`v29.0.0`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2900) [Compare Source](https://github.com/facebook/jest/compare/v28.1.3...v29.0.0) ##### Features - `[expect]` \[**BREAKING**] Differentiate between `MatcherContext` `MatcherUtils` and `MatcherState` types ([#​13141](https://github.com/facebook/jest/pull/13141)) - `[jest-circus]` Add support for `test.failing.each` ([#​13142](https://github.com/facebook/jest/pull/13142)) - `[jest-config]` \[**BREAKING**] Make `snapshotFormat` default to `escapeString: false` and `printBasicPrototype: false` ([#​13036](https://github.com/facebook/jest/pull/13036)) - `[jest-config]` \[**BREAKING**] Remove undocumented `collectCoverageOnlyFrom` option ([#​13156](https://github.com/facebook/jest/pull/13156)) - `[jest-environment-jsdom]` \[**BREAKING**] Upgrade to `jsdom@20` ([#​13037](https://github.com/facebook/jest/pull/13037), [#​13058](https://github.com/facebook/jest/pull/13058)) - `[@jest/globals]` Add `jest.Mocked`, `jest.MockedClass`, `jest.MockedFunction` and `jest.MockedObject` utility types ([#​12727](https://github.com/facebook/jest/pull/12727)) - `[jest-mock]` \[**BREAKING**] Refactor `Mocked*` utility types. `MaybeMockedDeep` and `MaybeMocked` became `Mocked` and `MockedShallow` respectively; only deep mocked variants of `MockedClass`, `MockedFunction` and `MockedObject` are exported ([#​13123](https://github.com/facebook/jest/pull/13123), [#​13124](https://github.com/facebook/jest/pull/13124)) - `[jest-mock]` \[**BREAKING**] Change the default `jest.mocked` helperโ€™s behavior to deep mocked ([#​13125](https://github.com/facebook/jest/pull/13125)) - `[jest-snapshot]` \[**BREAKING**] Let `babel` find config when updating inline snapshots ([#​13150](https://github.com/facebook/jest/pull/13150)) - `[@jest/test-result, @​jest/types]` \[**BREAKING**] Replace `Bytes` and `Milliseconds` types with `number` ([#​13155](https://github.com/facebook/jest/pull/13155)) - `[jest-worker]` Adds `workerIdleMemoryLimit` option which is used as a check for worker memory leaks >= Node 16.11.0 and recycles child workers as required ([#​13056](https://github.com/facebook/jest/pull/13056), [#​13105](https://github.com/facebook/jest/pull/13105), [#​13106](https://github.com/facebook/jest/pull/13106), [#​13107](https://github.com/facebook/jest/pull/13107)) - `[pretty-format]` \[**BREAKING**] Remove `ConvertAnsi` plugin in favour of `jest-serializer-ansi-escapes` ([#​13040](https://github.com/facebook/jest/pull/13040)) - `[pretty-format]` Allow to opt out from sorting object keys with `compareKeys: null` ([#​12443](https://github.com/facebook/jest/pull/12443)) ##### Fixes - `[jest-config]` Fix testing multiple projects with TypeScript config files ([#​13099](https://github.com/facebook/jest/pull/13099)) - `[@jest/expect-utils]` Fix deep equality of ImmutableJS Record ([#​13055](https://github.com/facebook/jest/pull/13055)) - `[jest-haste-map]` Increase the maximum possible file size that jest-haste-map can handle ([#​13094](https://github.com/facebook/jest/pull/13094)) - `[jest-runtime]` Properly support CJS re-exports from dual packages ([#​13170](https://github.com/facebook/jest/pull/13170)) - `[jest-snapshot]` Make `prettierPath` optional in `SnapshotState` ([#​13149](https://github.com/facebook/jest/pull/13149)) - `[jest-snapshot]` Fix parsing error from inline snapshot files with `JSX` ([#​12760](https://github.com/facebook/jest/pull/12760)) - `[jest-worker]` When a process runs out of memory worker exits correctly and doesn't spin indefinitely ([#​13054](https://github.com/facebook/jest/pull/13054)) ##### Chore & Maintenance - `[*]` \[**BREAKING**] Drop support for Node v12 and v17 ([#​13033](https://github.com/facebook/jest/pull/13033)) - `[docs]` Fix webpack name ([#​13049](https://github.com/facebook/jest/pull/13049)) - `[docs]` Explicit how to set `n` for `--bail` ([#​13128](https://github.com/facebook/jest/pull/13128)) - `[docs]` Update Enzyme URL ([#​13166](https://github.com/facebook/jest/pull/13166)) - `[jest-leak-detector]` Remove support for `weak-napi` ([#​13035](https://github.com/facebook/jest/pull/13035)) - `[jest-snapshot]` \[**BREAKING**] Require `rootDir` as argument to `SnapshotState` ([#​13150](https://github.com/facebook/jest/pull/13150)) ### [`v28.1.3`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2813) [Compare Source](https://github.com/facebook/jest/compare/v28.1.2...v28.1.3) ##### Features - `[jest-leak-detector]` Use native `FinalizationRegistry` when it exists to get rid of external C dependency ([#​12973](https://github.com/facebook/jest/pull/12973)) ##### Fixes - `[jest-changed-files]` Fix a lock-up after repeated invocations ([#​12757](https://github.com/facebook/jest/issues/12757)) - `[@jest/expect-utils]` Fix deep equality of ImmutableJS OrderedSets ([#​12977](https://github.com/facebook/jest/pull/12977)) - `[jest-mock]` Add index signature support for `spyOn` types ([#​13013](https://github.com/facebook/jest/pull/13013), [#​13020](https://github.com/facebook/jest/pull/13020)) - `[jest-snapshot]` Fix indentation of awaited inline snapshots ([#​12986](https://github.com/facebook/jest/pull/12986)) ##### Chore & Maintenance - `[*]` Replace internal usage of `pretty-format/ConvertAnsi` with `jest-serializer-ansi-escapes` ([#​12935](https://github.com/facebook/jest/pull/12935), [#​13004](https://github.com/facebook/jest/pull/13004)) - `[docs]` Update spyOn docs ([#​13000](https://github.com/facebook/jest/pull/13000)) ### [`v28.1.2`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2812) [Compare Source](https://github.com/facebook/jest/compare/v28.1.1...v28.1.2) ##### Fixes - `[jest-runtime]` Avoid star type import from `@jest/globals` ([#​12949](https://github.com/facebook/jest/pull/12949)) ##### Chore & Maintenance - `[docs]` Mention that jest-codemods now supports Sinon ([#​12898](https://github.com/facebook/jest/pull/12898)) ### [`v28.1.1`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2811) [Compare Source](https://github.com/facebook/jest/compare/v28.1.0...v28.1.1) ##### Features - `[jest]` Expose `Config` type ([#​12848](https://github.com/facebook/jest/pull/12848)) - `[@jest/reporters]` Improve `GitHubActionsReporter`s annotation format ([#​12826](https://github.com/facebook/jest/pull/12826)) - `[@jest/types]` Infer argument types passed to `test` and `describe` callback functions from `each` tables ([#​12885](https://github.com/facebook/jest/pull/12885), [#​12905](https://github.com/facebook/jest/pull/12905)) ##### Fixes - `[@jest/expect-utils]` Fix deep equality of ImmutableJS OrderedMaps ([#​12899](https://github.com/facebook/jest/pull/12899)) - `[jest-docblock]` Handle multiline comments in parseWithComments ([#​12845](https://github.com/facebook/jest/pull/12845)) - `[jest-mock]` Improve `spyOn` error messages ([#​12901](https://github.com/facebook/jest/pull/12901)) - `[jest-runtime]` Correctly report V8 coverage with `resetModules: true` ([#​12912](https://github.com/facebook/jest/pull/12912)) - `[jest-worker]` Make `JestWorkerFarm` helper type to include methods of worker module that take more than one argument ([#​12839](https://github.com/facebook/jest/pull/12839)) ##### Chore & Maintenance - `[docs]` Updated docs to indicate that `jest-environment-jsdom` is a separate package [#​12828](https://github.com/facebook/jest/issues/12828) - `[docs]` Document the comments used by coverage providers [#​12835](https://github.com/facebook/jest/issues/12835) - `[docs]` Use `docusaurus-remark-plugin-tab-blocks` to format tabs with code examples ([#​12859](https://github.com/facebook/jest/pull/12859)) - `[jest-haste-map]` Bump `walker` version ([#​12324](https://github.com/facebook/jest/pull/12324)) ### [`v28.1.0`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2810) [Compare Source](https://github.com/facebook/jest/compare/v28.0.3...v28.1.0) ##### Features - `[jest-circus]` Add `failing` test modifier that inverts the behavior of tests ([#​12610](https://github.com/facebook/jest/pull/12610)) - `[jest-environment-node, jest-environment-jsdom]` Allow specifying `customExportConditions` ([#​12774](https://github.com/facebook/jest/pull/12774)) ##### Fixes - `[expect]` Adjust typings of `lastCalledWith`, `nthCalledWith`, `toBeCalledWith` matchers to allow a case there a mock was called with no arguments ([#​12807](https://github.com/facebook/jest/pull/12807)) - `[@jest/expect-utils]` Fix deep equality of ImmutableJS Lists ([#​12763](https://github.com/facebook/jest/pull/12763)) - `[jest-core]` Do not collect `SIGNREQUEST` as open handles ([#​12789](https://github.com/facebook/jest/pull/12789)) ##### Chore & Maintenance - `[docs]` Specified documentation about `--filter` CLI docs ([#​12799](https://github.com/facebook/jest/pull/12799)) - `[@jest-reporters]` Move helper functions from `utils.ts` into separate files ([#​12782](https://github.com/facebook/jest/pull/12782)) - `[jest-resolve]` Replace `process.versions.pnp` type declaration with `@types/pnpapi` devDependency ([#​12783](https://github.com/facebook/jest/pull/12783)) ### [`v28.0.3`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2803) [Compare Source](https://github.com/facebook/jest/compare/v28.0.2...v28.0.3) ##### Fixes - `[jest-config]` Normalize `reporters` option defined in presets ([#​12769](https://github.com/facebook/jest/pull/12769)) - `[@jest/reporters]` Fix trailing slash in matching `coverageThreshold` key ([#​12714](https://github.com/facebook/jest/pull/12714)) - `[jest-resolve]` Fix (experimental) ESM module mocking for re-exports ([#​12766](https://github.com/facebook/jest/pull/12766)) - `[@jest/transform]` Throw better error if an invalid return value if encountered ([#​12764](https://github.com/facebook/jest/pull/12764)) ##### Chore & Maintenance - `[docs]` Fix typo in `--shard` CLI docs ([#​12761](https://github.com/facebook/jest/pull/12761)) ### [`v28.0.2`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2802) [Compare Source](https://github.com/facebook/jest/compare/v28.0.1...v28.0.2) ##### Features - `[jest-worker]` Add `JestWorkerFarm` helper type ([#​12753](https://github.com/facebook/jest/pull/12753)) ##### Fixes - `[*]` Lower Node 16 requirement to 16.10 from 16.13 due to a [Node bug](https://github.com/nodejs/node/issues/40014) that causes memory and performance issues ([#​12754](https://github.com/facebook/jest/pull/12754)) ### [`v28.0.1`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2801) [Compare Source](https://github.com/facebook/jest/compare/v28.0.0...v28.0.1) ##### Features - `[jest-resolve]` Expose `ResolverOptions` type ([#​12736](https://github.com/facebook/jest/pull/12736)) ##### Fixes - `[expect]` Add missing dependency `jest-util` ([#​12744](https://github.com/facebook/jest/pull/12744)) - `[jest-circus]` Improve `test.concurrent` ([#​12748](https://github.com/facebook/jest/pull/12748)) - `[jest-resolve]` Correctly throw an error if `jsdom` test environment is used, but not installed ([#​12749](https://github.com/facebook/jest/pull/12749)) ##### Chore & Maintenance - `[jest-serializer]` Remove deprecated module from source tree ([#​12735](https://github.com/facebook/jest/pull/12735)) ### [`v28.0.0`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2800) [Compare Source](https://github.com/facebook/jest/compare/v27.5.1...v28.0.0) ##### Features - `[babel-jest]` Export `createTransformer` function ([#​12399](https://github.com/facebook/jest/pull/12399)) - `[expect]` Expose `AsymmetricMatchers`, `MatcherFunction` and `MatcherFunctionWithState` interfaces ([#​12363](https://github.com/facebook/jest/pull/12363), [#​12376](https://github.com/facebook/jest/pull/12376)) - `[jest-circus]` Support error logging before retry ([#​12201](https://github.com/facebook/jest/pull/12201)) - `[jest-circus, jest-jasmine2]` Allowed classes and functions as `describe` and `it`/`test` names ([#​12484](https://github.com/facebook/jest/pull/12484)) - `[jest-cli, jest-config]` \[**BREAKING**] Remove `testURL` config, use `testEnvironmentOptions.url` instead ([#​10797](https://github.com/facebook/jest/pull/10797)) - `[jest-cli, jest-core]` Add `--shard` parameter for distributed parallel test execution ([#​12546](https://github.com/facebook/jest/pull/12546)) - `[jest-cli]` \[**BREAKING**] Remove undocumented `--timers` option ([#​12572](https://github.com/facebook/jest/pull/12572)) - `[jest-config]` \[**BREAKING**] Stop shipping `jest-environment-jsdom` by default ([#​12354](https://github.com/facebook/jest/pull/12354)) - `[jest-config]` \[**BREAKING**] Stop shipping `jest-jasmine2` by default ([#​12355](https://github.com/facebook/jest/pull/12355)) - `[jest-config, @​jest/types]` Add `ci` to `GlobalConfig` ([#​12378](https://github.com/facebook/jest/pull/12378)) - `[jest-config]` \[**BREAKING**] Rename `moduleLoader` to `runtime` ([#​10817](https://github.com/facebook/jest/pull/10817)) - `[jest-config]` \[**BREAKING**] Rename `extraGlobals` to `sandboxInjectedGlobals` ([#​10817](https://github.com/facebook/jest/pull/10817)) - `[jest-config]` \[**BREAKING**] Throw an error instead of showing a warning if multiple configs are used ([#​12510](https://github.com/facebook/jest/pull/12510)) - `[jest-config]` \[**BREAKING**] Do not normalize long deprecated configuration options `preprocessorIgnorePatterns`, `scriptPreprocessor`, `setupTestFrameworkScriptFile` and `testPathDirs` ([#​12701](https://github.com/facebook/jest/pull/12701)) - `[jest-cli, jest-core]` Add `--ignoreProjects` CLI argument to ignore test suites by project name ([#​12620](https://github.com/facebook/jest/pull/12620)) - `[jest-core]` Pass project config to `globalSetup`/`globalTeardown` function as second argument ([#​12440](https://github.com/facebook/jest/pull/12440)) - `[jest-core]` Stabilize test runners with event emitters ([#​12641](https://github.com/facebook/jest/pull/12641)) - `[jest-core, jest-watcher]` \[**BREAKING**] Move `TestWatcher` class to `jest-watcher` package ([#​12652](https://github.com/facebook/jest/pull/12652)) - `[jest-core]` Allow using Summary Reporter as stand-alone reporter ([#​12687](https://github.com/facebook/jest/pull/12687)) - `[jest-environment-jsdom]` \[**BREAKING**] Upgrade jsdom to 19.0.0 ([#​12290](https://github.com/facebook/jest/pull/12290)) - `[jest-environment-jsdom]` \[**BREAKING**] Add default `browser` condition to `exportConditions` for `jsdom` environment ([#​11924](https://github.com/facebook/jest/pull/11924)) - `[jest-environment-jsdom]` \[**BREAKING**] Pass global config to Jest environment constructor for `jsdom` environment ([#​12461](https://github.com/facebook/jest/pull/12461)) - `[jest-environment-jsdom]` \[**BREAKING**] Second argument `context` to constructor is mandatory ([#​12469](https://github.com/facebook/jest/pull/12469)) - `[jest-environment-node]` \[**BREAKING**] Add default `node` and `node-addon` conditions to `exportConditions` for `node` environment ([#​11924](https://github.com/facebook/jest/pull/11924)) - `[jest-environment-node]` \[**BREAKING**] Pass global config to Jest environment constructor for `node` environment ([#​12461](https://github.com/facebook/jest/pull/12461)) - `[jest-environment-node]` \[**BREAKING**] Second argument `context` to constructor is mandatory ([#​12469](https://github.com/facebook/jest/pull/12469)) - `[jest-environment-node]` Add all available globals to test globals, not just explicit ones ([#​12642](https://github.com/facebook/jest/pull/12642), [#​12696](https://github.com/facebook/jest/pull/12696)) - `[@jest/expect]` New module which extends `expect` with `jest-snapshot` matchers ([#​12404](https://github.com/facebook/jest/pull/12404), [#​12410](https://github.com/facebook/jest/pull/12410), [#​12418](https://github.com/facebook/jest/pull/12418)) - `[@jest/expect-utils]` New module exporting utils for `expect` ([#​12323](https://github.com/facebook/jest/pull/12323)) - `[@jest/fake-timers]` \[**BREAKING**] Rename `timers` configuration option to `fakeTimers` ([#​12572](https://github.com/facebook/jest/pull/12572)) - `[@jest/fake-timers]` \[**BREAKING**] Allow `jest.useFakeTimers()` and `projectConfig.fakeTimers` to take an options bag ([#​12572](https://github.com/facebook/jest/pull/12572)) - `[jest-haste-map]` \[**BREAKING**] `HasteMap.create` now returns a promise ([#​12008](https://github.com/facebook/jest/pull/12008)) - `[jest-haste-map]` Add support for `dependencyExtractor` written in ESM ([#​12008](https://github.com/facebook/jest/pull/12008)) - `[jest-mock]` \[**BREAKING**] Rename exported utility types `ClassLike`, `FunctionLike`, `ConstructorLikeKeys`, `MethodLikeKeys`, `PropertyLikeKeys`; remove exports of utility types `ArgumentsOf`, `ArgsType`, `ConstructorArgumentsOf` - TS builtin utility types `ConstructorParameters` and `Parameters` should be used instead ([#​12435](https://github.com/facebook/jest/pull/12435), [#​12489](https://github.com/facebook/jest/pull/12489)) - `[jest-mock]` Improve `isMockFunction` to infer types of passed function ([#​12442](https://github.com/facebook/jest/pull/12442)) - `[jest-mock]` \[**BREAKING**] Improve the usage of `jest.fn` generic type argument ([#​12489](https://github.com/facebook/jest/pull/12489)) - `[jest-mock]` Add support for auto-mocking async generator functions ([#​11080](https://github.com/facebook/jest/pull/11080)) - `[jest-mock]` Add `contexts` member to mock functions ([#​12601](https://github.com/facebook/jest/pull/12601)) - `[@jest/reporters]` Add GitHub Actions reporter ([#​11320](https://github.com/facebook/jest/pull/11320), [#​12658](https://github.com/facebook/jest/pull/12658)) - `[@jest/reporters]` Pass `reporterContext` to custom reporter constructors as third argument ([#​12657](https://github.com/facebook/jest/pull/12657)) - `[jest-resolve]` \[**BREAKING**] Add support for `package.json` `exports` ([#​11961](https://github.com/facebook/jest/pull/11961), [#​12373](https://github.com/facebook/jest/pull/12373)) - `[jest-resolve]` Support package self-reference ([#​12682](https://github.com/facebook/jest/pull/12682)) - `[jest-resolve, jest-runtime]` Add support for `data:` URI import and mock ([#​12392](https://github.com/facebook/jest/pull/12392)) - `[jest-resolve, jest-runtime]` Add support for async resolver ([#​11540](https://github.com/facebook/jest/pull/11540)) - `[jest-resolve]` \[**BREAKING**] Remove `browser?: boolean` from resolver options, `conditions: ['browser']` should be used instead ([#​12707](https://github.com/facebook/jest/pull/12707)) - `[jest-resolve]` Expose `JestResolver`, `AsyncResolver`, `SyncResolver`, `PackageFilter`, `PathFilter` and `PackageJSON` types ([#​12707](https://github.com/facebook/jest/pull/12707), ([#​12712](https://github.com/facebook/jest/pull/12712)) - `[jest-runner]` Allow `setupFiles` module to export an async function ([#​12042](https://github.com/facebook/jest/pull/12042)) - `[jest-runner]` Allow passing `testEnvironmentOptions` via docblocks ([#​12470](https://github.com/facebook/jest/pull/12470)) - `[jest-runner]` Expose `CallbackTestRunner`, `EmittingTestRunner` abstract classes and `CallbackTestRunnerInterface`, `EmittingTestRunnerInterface` to help typing third party runners ([#​12646](https://github.com/facebook/jest/pull/12646), [#​12715](https://github.com/facebook/jest/pull/12715)) - `[jest-runner]` Lock version of `source-map-support` to 0.5.13 ([#​12720](https://github.com/facebook/jest/pull/12720)) - `[jest-runtime]` \[**BREAKING**] `Runtime.createHasteMap` now returns a promise ([#​12008](https://github.com/facebook/jest/pull/12008)) - `[jest-runtime]` Calling `jest.resetModules` function will clear FS and transform cache ([#​12531](https://github.com/facebook/jest/pull/12531)) - `[jest-runtime]` \[**BREAKING**] Remove `Context` type export, it must be imported from `@jest/test-result` ([#​12685](https://github.com/facebook/jest/pull/12685)) - `[jest-runtime]` Add `import.meta.jest` ([#​12698](https://github.com/facebook/jest/pull/12698)) - `[@jest/schemas]` New module for JSON schemas for Jest's config ([#​12384](https://github.com/facebook/jest/pull/12384)) - `[@jest/source-map]` Migrate from `source-map` to `@jridgewell/trace-mapping` ([#​12692](https://github.com/facebook/jest/pull/12692)) - `[jest-transform]` \[**BREAKING**] Make it required for `process()` and `processAsync()` methods to always return structured data ([#​12638](https://github.com/facebook/jest/pull/12638)) - `[jest-test-result]` Add duration property to JSON test output ([#​12518](https://github.com/facebook/jest/pull/12518)) - `[jest-watcher]` \[**BREAKING**] Make `PatternPrompt` class to take `entityName` as third constructor parameter instead of `this._entityName` ([#​12591](https://github.com/facebook/jest/pull/12591)) - `[jest-worker]` \[**BREAKING**] Allow only absolute `workerPath` ([#​12343](https://github.com/facebook/jest/pull/12343)) - `[jest-worker]` \[**BREAKING**] Default to advanced serialization when using child process workers ([#​10983](https://github.com/facebook/jest/pull/10983)) - `[pretty-format]` New `maxWidth` parameter ([#​12402](https://github.com/facebook/jest/pull/12402)) ##### Fixes - `[*]` Use `sha256` instead of `md5` as hashing algortihm for compatibility with FIPS systems ([#​12722](https://github.com/facebook/jest/pull/12722)) - `[babel-jest]` \[**BREAKING**] Pass `rootDir` as `root` in Babel's options ([#​12689](https://github.com/facebook/jest/pull/12689)) - `[expect]` Move typings of `.not`, `.rejects` and `.resolves` modifiers outside of `Matchers` interface ([#​12346](https://github.com/facebook/jest/pull/12346)) - `[expect]` Throw useful error if `expect.extend` is called with invalid matchers ([#​12488](https://github.com/facebook/jest/pull/12488)) - `[expect]` Fix `iterableEquality` ignores other properties ([#​8359](https://github.com/facebook/jest/pull/8359)) - `[expect]` Fix print for the `closeTo` matcher ([#​12626](https://github.com/facebook/jest/pull/12626)) - `[jest-changed-files]` Improve `changedFilesWithAncestor` pattern for Mercurial SCM ([#​12322](https://github.com/facebook/jest/pull/12322)) - `[jest-circus, @​jest/types]` Disallow undefined value in `TestContext` type ([#​12507](https://github.com/facebook/jest/pull/12507)) - `[jest-config]` Correctly detect CI environment and update snapshots accordingly ([#​12378](https://github.com/facebook/jest/pull/12378)) - `[jest-config]` Pass `moduleTypes` to `ts-node` to enforce CJS when transpiling ([#​12397](https://github.com/facebook/jest/pull/12397)) - `[jest-config]` \[**BREAKING**] Add `mjs` and `cjs` to default `moduleFileExtensions` config ([#​12578](https://github.com/facebook/jest/pull/12578)) - `[jest-config, jest-haste-map]` Allow searching for tests in `node_modules` by exposing `retainAllFiles` ([#​11084](https://github.com/facebook/jest/pull/11084)) - `[jest-core]` \[**BREAKING**] Exit with status `1` if no tests are found with `--findRelatedTests` flag ([#​12487](https://github.com/facebook/jest/pull/12487)) - `[jest-core]` Do not report unref-ed subprocesses as open handles ([#​12705](https://github.com/facebook/jest/pull/12705)) - `[jest-each]` `%#` is not replaced with index of the test case ([#​12517](https://github.com/facebook/jest/pull/12517)) - `[jest-each]` Fixes error message with incorrect count of missing arguments ([#​12464](https://github.com/facebook/jest/pull/12464)) - `[jest-environment-jsdom]` Make `jsdom` accessible to extending environments again ([#​12232](https://github.com/facebook/jest/pull/12232)) - `[jest-environment-jsdom]` Log JSDOM errors more cleanly ([#​12386](https://github.com/facebook/jest/pull/12386)) - `[jest-environment-node]` Add `MessageChannel`, `MessageEvent` to globals ([#​12553](https://github.com/facebook/jest/pull/12553)) - `[jest-environment-node]` Add `structuredClone` to globals ([#​12631](https://github.com/facebook/jest/pull/12631)) - `[@jest/expect-utils]` \[**BREAKING**] Fix false positives when looking for `undefined` prop ([#​8923](https://github.com/facebook/jest/pull/8923)) - `[jest-haste-map]` Don't use partial results if file crawl errors ([#​12420](https://github.com/facebook/jest/pull/12420)) - `[jest-haste-map]` Make watchman existence check lazy+async ([#​12675](https://github.com/facebook/jest/pull/12675)) - `[jest-jasmine2, jest-types]` \[**BREAKING**] Move all `jasmine` specific types from `@jest/types` to its own package ([#​12125](https://github.com/facebook/jest/pull/12125)) - `[jest-jasmine2]` Do not set `duration` to `0` for skipped tests ([#​12518](https://github.com/facebook/jest/pull/12518)) - `[jest-matcher-utils]` Pass maxWidth to `pretty-format` to avoid printing every element in arrays by default ([#​12402](https://github.com/facebook/jest/pull/12402)) - `[jest-mock]` Fix function overloads for `spyOn` to allow more correct type inference in complex object ([#​12442](https://github.com/facebook/jest/pull/12442)) - `[jest-mock]` Handle overridden `Function.name` property ([#​12674](https://github.com/facebook/jest/pull/12674)) - `[@jest/reporters]` Notifications generated by the `--notify` flag are no longer persistent in GNOME Shell. ([#​11733](https://github.com/facebook/jest/pull/11733)) - `[@jest/reporters]` Move missing icon file which is needed for `NotifyReporter` class. ([#​12593](https://github.com/facebook/jest/pull/12593)) - `[@jest/reporters]` Update `v8-to-istanbul` ([#​12697](https://github.com/facebook/jest/pull/12697)) - `[jest-resolver]` Call custom resolver with core node.js modules ([#​12654](https://github.com/facebook/jest/pull/12654)) - `[jest-runner]` Correctly resolve `source-map-support` ([#​12706](https://github.com/facebook/jest/pull/12706)) - `[jest-worker]` Fix `Farm` execution results memory leak ([#​12497](https://github.com/facebook/jest/pull/12497)) ##### Chore & Maintenance - `[*]` \[**BREAKING**] Drop support for Node v10 and v15 and target first LTS `16.13.0` ([#​12220](https://github.com/facebook/jest/pull/12220)) - `[*]` \[**BREAKING**] Drop support for `typescript@3.8`, minimum version is now `4.3` ([#​11142](https://github.com/facebook/jest/pull/11142), [#​12648](https://github.com/facebook/jest/pull/12648)) - `[*]` Bundle all `.d.ts` files into a single `index.d.ts` per module ([#​12345](https://github.com/facebook/jest/pull/12345)) - `[*]` Use `globalThis` instead of `global` ([#​12447](https://github.com/facebook/jest/pull/12447)) - `[babel-jest]` \[**BREAKING**] Only export `createTransformer` ([#​12407](https://github.com/facebook/jest/pull/12407)) - `[docs]` Add note about not mixing `done()` with Promises ([#​11077](https://github.com/facebook/jest/pull/11077)) - `[docs, examples]` Update React examples to match with the new React guidelines for code examples ([#​12217](https://github.com/facebook/jest/pull/12217)) - `[docs]` Add clarity for module factory hoisting limitations ([#​12453](https://github.com/facebook/jest/pull/12453)) - `[docs]` Add more information about how code transformers work ([#​12407](https://github.com/facebook/jest/pull/12407)) - `[docs]` Add upgrading guide ([#​12633](https://github.com/facebook/jest/pull/12633)) - `[expect]` \[**BREAKING**] Remove support for importing `build/utils` ([#​12323](https://github.com/facebook/jest/pull/12323)) - `[expect]` \[**BREAKING**] Migrate to ESM ([#​12344](https://github.com/facebook/jest/pull/12344)) - `[expect]` \[**BREAKING**] Snapshot matcher types are moved to `@jest/expect` ([#​12404](https://github.com/facebook/jest/pull/12404)) - `[jest-cli]` Update `yargs` to v17 ([#​12357](https://github.com/facebook/jest/pull/12357)) - `[jest-config]` \[**BREAKING**] Remove `getTestEnvironment` export ([#​12353](https://github.com/facebook/jest/pull/12353)) - `[jest-config]` \[**BREAKING**] Rename config option `name` to `id` ([#​11981](https://github.com/facebook/jest/pull/11981)) - `[jest-create-cache-key-function]` Added README.md file with basic usage instructions ([#​12492](https://github.com/facebook/jest/pull/12492)) - `[@jest/core]` Use `index.ts` instead of `jest.ts` as main export ([#​12329](https://github.com/facebook/jest/pull/12329)) - `[jest-environment-jsdom]` \[**BREAKING**] Migrate to ESM ([#​12340](https://github.com/facebook/jest/pull/12340)) - `[jest-environment-node]` \[**BREAKING**] Migrate to ESM ([#​12340](https://github.com/facebook/jest/pull/12340)) - `[jest-haste-map]` Remove legacy `isRegExpSupported` ([#​12676](https://github.com/facebook/jest/pull/12676)) - `[@jest/fake-timers]` Update `@sinonjs/fake_timers` to v9 ([#​12357](https://github.com/facebook/jest/pull/12357)) - `[jest-jasmine2, jest-runtime]` \[**BREAKING**] Use `Symbol` to pass `jest.setTimeout` value instead of `jasmine` specific logic ([#​12124](https://github.com/facebook/jest/pull/12124)) - `[jest-phabricator]` \[**BREAKING**] Migrate to ESM ([#​12341](https://github.com/facebook/jest/pull/12341)) - `[jest-resolve]` \[**BREAKING**] Make `requireResolveFunction` argument mandatory ([#​12353](https://github.com/facebook/jest/pull/12353)) - `[jest-runner]` \[**BREAKING**] Remove some type exports from `@jest/test-result` ([#​12353](https://github.com/facebook/jest/pull/12353)) - `[jest-runner]` \[**BREAKING**] Second argument to constructor (`Context`) is not optional ([#​12640](https://github.com/facebook/jest/pull/12640)) - `[jest-serializer]` \[**BREAKING**] Deprecate package in favour of using `v8` APIs directly ([#​12391](https://github.com/facebook/jest/pull/12391)) - `[jest-snapshot]` \[**BREAKING**] Migrate to ESM ([#​12342](https://github.com/facebook/jest/pull/12342)) - `[jest-transform]` Update `write-file-atomic` to v4 ([#​12357](https://github.com/facebook/jest/pull/12357)) - `[jest-types]` \[**BREAKING**] Remove `Config.Glob` and `Config.Path` ([#​12406](https://github.com/facebook/jest/pull/12406)) - `[jest]` Use `index.ts` instead of `jest.ts` as main export ([#​12329](https://github.com/facebook/jest/pull/12329)) ##### Performance - `[jest-haste-map]` \[**BREAKING**] Default to `node` crawler over shelling out to `find` if `watchman` is not enabled ([#​12320](https://github.com/facebook/jest/pull/12320)) ### [`v27.5.1`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2751) [Compare Source](https://github.com/facebook/jest/compare/v27.5.0...v27.5.1) ##### Features - `[jest-config]` Support comments in JSON config file ([#​12316](https://github.com/facebook/jest/pull/12316)) - `[pretty-format]` Expose `ConvertAnsi` plugin ([#​12308](https://github.com/facebook/jest/pull/12308)) ##### Fixes - `[expect]` Add type definitions for asymmetric `closeTo` matcher ([#​12304](https://github.com/facebook/jest/pull/12304)) - `[jest-cli]` Load binary via exported API ([#​12315](https://github.com/facebook/jest/pull/12315)) - `[jest-config]` Replace `jsonlint` with `parse-json` ([#​12316](https://github.com/facebook/jest/pull/12316)) - `[jest-repl]` Make module importable ([#​12311](https://github.com/facebook/jest/pull/12311) & [#​12315](https://github.com/facebook/jest/pull/12315)) ##### Chore & Maintenance - `[*]` Avoid anonymous default exports ([#​12313](https://github.com/facebook/jest/pull/12313)) ### [`v27.5.0`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2750) [Compare Source](https://github.com/facebook/jest/compare/v27.4.7...v27.5.0) ##### Features - `[expect]` Add asymmetric matcher `expect.closeTo` ([#​12243](https://github.com/facebook/jest/pull/12243)) - `[jest-mock]` Added `mockFn.mock.lastCall` to retrieve last argument ([#​12285](https://github.com/facebook/jest/pull/12285)) ##### Fixes - `[expect]` Add a fix for `.toHaveProperty('')` ([#​12251](https://github.com/facebook/jest/pull/12251)) - `[jest-each, @​jest/globals]` Allow passing `ReadonlyArray` type of a table to `describe.each` and `test.each` ([#​12297](https://github.com/facebook/jest/pull/12297)) - `[@jest/globals]` Add missing `options` argument to `jest.doMock` typing ([#​12292](https://github.com/facebook/jest/pull/12292)) - `[jest-environment-node]` Add `atob` and `btoa` ([#​12269](https://github.com/facebook/jest/pull/12269)) - `[jest-matcher-utils]` Correct diff for expected asymmetric matchers ([#​12264](https://github.com/facebook/jest/pull/12264)) - `[jest-message-util]` Fix `.getTopFrame()` (and `toMatchInlineSnapshot()`) with `mjs` files ([#​12277](https://github.com/facebook/jest/pull/12277)) ##### Chore & Maintenance - `[*]` Update `graceful-fs` to `^4.2.9` ([#​11749](https://github.com/facebook/jest/pull/11749)) ##### Performance - `[jest-resolve]` perf: skip error creation on not found `stat` calls ([#​11749](https://github.com/facebook/jest/pull/11749)) ### [`v27.4.7`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2747) [Compare Source](https://github.com/facebook/jest/compare/v27.4.6...v27.4.7) ##### Fixes - `jest-config` Add missing `@babel/core` dependency ([#​12216](https://github.com/facebook/jest/pull/12216)) ### [`v27.4.6`](https://github.com/facebook/jest/blob/HEAD/CHANGELOG.md#​2746) [Compare Source](https://github.com/facebook/jest/compare/v27.4.5...v27.4.6) ##### Fixes - `[jest-environment-node]` Add `AbortSignal` ([#​12157](https://github.com/facebook/jest/pull/12157)) - `[jest-environment-node]` Add Missing node global `performance` ([#​12002](https://github.com/facebook/jest/pull/12002)) - `[jest-runtime]` Handle missing `mocked` property ([#​12213](https://github.com/facebook/jest/pull/12213)) - `[@jest/transform]` Update dependency package `pirates` to 4.0.4 ([#​12002](https://github.com/facebook/jest/pull/12002)) ##### Performance - `jest-config` perf: only register ts-node once when loading TS config files ([#​12160](https://github.com/facebook/jest/pull/12160)) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/241 Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 4 +- yarn.lock | 1863 +++++++++++++++++++++++++------------------------- 2 files changed, 919 insertions(+), 948 deletions(-) diff --git a/package.json b/package.json index 03422eb..15debf1 100644 --- a/package.json +++ b/package.json @@ -26,12 +26,12 @@ "funding": "https://ko-fi.com/vylpes", "dependencies": { "@discordjs/rest": "^1.1.0", - "@types/jest": "^27.0.3", + "@types/jest": "^29.0.0", "@types/uuid": "^9.0.0", "discord.js": "^14.3.0", "dotenv": "^16.0.0", "emoji-regex": "^9.2.0", - "jest": "^27.4.5", + "jest": "^29.0.0", "jest-mock-extended": "^3.0.0", "minimatch": "7.4.3", "mysql": "^2.18.1", diff --git a/yarn.lock b/yarn.lock index 456f7ed..fbbdbb1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,21 @@ # yarn lockfile v1 +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" @@ -14,7 +29,33 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== -"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.7.5": +"@babel/compat-data@^7.20.5": + version "7.20.14" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.14.tgz#4106fc8b755f3e3ee0a0a7c27dde5de1d2b2baf8" + integrity sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw== + +"@babel/core@^7.11.6": + version "7.20.12" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.12.tgz#7930db57443c6714ad216953d1356dac0eb8496d" + integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.7" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-module-transforms" "^7.20.11" + "@babel/helpers" "^7.20.7" + "@babel/parser" "^7.20.7" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.12" + "@babel/types" "^7.20.7" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" + +"@babel/core@^7.12.3": version "7.16.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.5.tgz#924aa9e1ae56e1e55f7184c8bf073a50d8677f5c" integrity sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ== @@ -44,6 +85,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.20.7": + version "7.20.14" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.14.tgz#9fa772c9f86a46c6ac9b321039400712b96f64ce" + integrity sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg== + dependencies: + "@babel/types" "^7.20.7" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + "@babel/helper-compilation-targets@^7.16.3": version "7.16.3" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz#5b480cd13f68363df6ec4dc8ac8e2da11363cbf0" @@ -54,6 +104,17 @@ browserslist "^4.17.5" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb" + integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ== + dependencies: + "@babel/compat-data" "^7.20.5" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.21.3" + lru-cache "^5.1.1" + semver "^6.3.0" + "@babel/helper-environment-visitor@^7.16.5": version "7.16.5" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz#f6a7f38b3c6d8b07c88faea083c46c09ef5451b8" @@ -61,6 +122,11 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + "@babel/helper-function-name@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481" @@ -70,6 +136,14 @@ "@babel/template" "^7.16.0" "@babel/types" "^7.16.0" +"@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" + "@babel/helper-get-function-arity@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa" @@ -84,6 +158,13 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-module-imports@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3" @@ -91,6 +172,13 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-module-transforms@^7.16.5": version "7.16.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz#530ebf6ea87b500f60840578515adda2af470a29" @@ -105,11 +193,30 @@ "@babel/traverse" "^7.16.5" "@babel/types" "^7.16.0" +"@babel/helper-module-transforms@^7.20.11": + version "7.20.11" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz#df4c7af713c557938c50ea3ad0117a7944b2f1b0" + integrity sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.10" + "@babel/types" "^7.20.7" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.5", "@babel/helper-plugin-utils@^7.8.0": version "7.16.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz#afe37a45f39fce44a3d50a7958129ea5b1a5c074" integrity sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ== +"@babel/helper-plugin-utils@^7.18.6": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== + "@babel/helper-simple-access@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517" @@ -117,6 +224,13 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-simple-access@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" + integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== + dependencies: + "@babel/types" "^7.20.2" + "@babel/helper-split-export-declaration@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438" @@ -124,16 +238,38 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + "@babel/helper-validator-identifier@^7.15.7": version "7.15.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + "@babel/helper-validator-option@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + "@babel/helpers@^7.16.5": version "7.16.5" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.5.tgz#29a052d4b827846dd76ece16f565b9634c554ebd" @@ -143,6 +279,15 @@ "@babel/traverse" "^7.16.5" "@babel/types" "^7.16.0" +"@babel/helpers@^7.20.7": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.13.tgz#e3cb731fb70dc5337134cadc24cbbad31cc87ad2" + integrity sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg== + dependencies: + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.13" + "@babel/types" "^7.20.7" + "@babel/highlight@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a" @@ -152,11 +297,25 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.16.5", "@babel/parser@^7.7.2": +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.16.5": version "7.16.6" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.6.tgz#8f194828193e8fa79166f34a4b4e52f3e769a314" integrity sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ== +"@babel/parser@^7.20.13", "@babel/parser@^7.20.7": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.13.tgz#ddf1eb5a813588d2fb1692b70c6fce75b945c088" + integrity sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw== + "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -192,6 +351,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" @@ -257,7 +423,16 @@ "@babel/parser" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.16.5", "@babel/traverse@^7.7.2": +"@babel/template@^7.18.10", "@babel/template@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" + integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + +"@babel/traverse@^7.16.5", "@babel/traverse@^7.7.2": version "7.16.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.5.tgz#d7d400a8229c714a59b87624fc67b0f1fbd4b2b3" integrity sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ== @@ -273,6 +448,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.13": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.13.tgz#817c1ba13d11accca89478bd5481b2d168d07473" + integrity sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.7" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.13" + "@babel/types" "^7.20.7" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba" @@ -281,6 +472,15 @@ "@babel/helper-validator-identifier" "^7.15.7" to-fast-properties "^2.0.0" +"@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f" + integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -331,163 +531,185 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.4.2.tgz#7a95612d38c007ddb528ee446fe5e5e785e685ce" - integrity sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg== +"@jest/console@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.4.1.tgz#cbc31d73f6329f693b3d34b365124de797704fff" + integrity sha512-m+XpwKSi3PPM9znm5NGS8bBReeAJJpSkL1OuFCqaMaJL2YX9YXLkkI+MBchMPwu+ZuM2rynL51sgfkQteQ1CKQ== dependencies: - "@jest/types" "^27.4.2" + "@jest/types" "^29.4.1" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^27.4.2" - jest-util "^27.4.2" + jest-message-util "^29.4.1" + jest-util "^29.4.1" slash "^3.0.0" -"@jest/core@^27.4.5": - version "27.4.5" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.4.5.tgz#cae2dc34259782f4866c6606c3b480cce920ed4c" - integrity sha512-3tm/Pevmi8bDsgvo73nX8p/WPng6KWlCyScW10FPEoN1HU4pwI83tJ3TsFvi1FfzsjwUlMNEPowgb/rPau/LTQ== +"@jest/core@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.4.1.tgz#91371179b5959951e211dfaeea4277a01dcca14f" + integrity sha512-RXFTohpBqpaTebNdg5l3I5yadnKo9zLBajMT0I38D0tDhreVBYv3fA8kywthI00sWxPztWLD3yjiUkewwu/wKA== dependencies: - "@jest/console" "^27.4.2" - "@jest/reporters" "^27.4.5" - "@jest/test-result" "^27.4.2" - "@jest/transform" "^27.4.5" - "@jest/types" "^27.4.2" + "@jest/console" "^29.4.1" + "@jest/reporters" "^29.4.1" + "@jest/test-result" "^29.4.1" + "@jest/transform" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - emittery "^0.8.1" + ci-info "^3.2.0" exit "^0.1.2" - graceful-fs "^4.2.4" - jest-changed-files "^27.4.2" - jest-config "^27.4.5" - jest-haste-map "^27.4.5" - jest-message-util "^27.4.2" - jest-regex-util "^27.4.0" - jest-resolve "^27.4.5" - jest-resolve-dependencies "^27.4.5" - jest-runner "^27.4.5" - jest-runtime "^27.4.5" - jest-snapshot "^27.4.5" - jest-util "^27.4.2" - jest-validate "^27.4.2" - jest-watcher "^27.4.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.4.0" + jest-config "^29.4.1" + jest-haste-map "^29.4.1" + jest-message-util "^29.4.1" + jest-regex-util "^29.2.0" + jest-resolve "^29.4.1" + jest-resolve-dependencies "^29.4.1" + jest-runner "^29.4.1" + jest-runtime "^29.4.1" + jest-snapshot "^29.4.1" + jest-util "^29.4.1" + jest-validate "^29.4.1" + jest-watcher "^29.4.1" micromatch "^4.0.4" - rimraf "^3.0.0" + pretty-format "^29.4.1" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^27.4.4": - version "27.4.4" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.4.4.tgz#66ebebc79673d84aad29d2bb70a8c51e6c29bb4d" - integrity sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ== +"@jest/environment@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.4.1.tgz#52d232a85cdc995b407a940c89c86568f5a88ffe" + integrity sha512-pJ14dHGSQke7Q3mkL/UZR9ZtTOxqskZaC91NzamEH4dlKRt42W+maRBXiw/LWkdJe+P0f/zDR37+SPMplMRlPg== dependencies: - "@jest/fake-timers" "^27.4.2" - "@jest/types" "^27.4.2" + "@jest/fake-timers" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" - jest-mock "^27.4.2" + jest-mock "^29.4.1" -"@jest/fake-timers@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.4.2.tgz#d217f86c3ba2027bf29e0b731fd0cb761a72d093" - integrity sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg== +"@jest/expect-utils@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.4.1.tgz#105b9f3e2c48101f09cae2f0a4d79a1b3a419cbb" + integrity sha512-w6YJMn5DlzmxjO00i9wu2YSozUYRBhIoJ6nQwpMYcBMtiqMGJm1QBzOf6DDgRao8dbtpDoaqLg6iiQTvv0UHhQ== dependencies: - "@jest/types" "^27.4.2" - "@sinonjs/fake-timers" "^8.0.1" + jest-get-type "^29.2.0" + +"@jest/expect@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.4.1.tgz#3338fa20f547bb6e550c4be37d6f82711cc13c38" + integrity sha512-ZxKJP5DTUNF2XkpJeZIzvnzF1KkfrhEF6Rz0HGG69fHl6Bgx5/GoU3XyaeFYEjuuKSOOsbqD/k72wFvFxc3iTw== + dependencies: + expect "^29.4.1" + jest-snapshot "^29.4.1" + +"@jest/fake-timers@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.4.1.tgz#7b673131e8ea2a2045858f08241cace5d518b42b" + integrity sha512-/1joI6rfHFmmm39JxNfmNAO3Nwm6Y0VoL5fJDy7H1AtWrD1CgRtqJbN9Ld6rhAkGO76qqp4cwhhxJ9o9kYjQMw== + dependencies: + "@jest/types" "^29.4.1" + "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^27.4.2" - jest-mock "^27.4.2" - jest-util "^27.4.2" + jest-message-util "^29.4.1" + jest-mock "^29.4.1" + jest-util "^29.4.1" -"@jest/globals@^27.4.4": - version "27.4.4" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.4.4.tgz#fe501a80c23ea2dab585c42be2a519bb5e38530d" - integrity sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ== +"@jest/globals@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.4.1.tgz#3cd78c5567ab0249f09fbd81bf9f37a7328f4713" + integrity sha512-znoK2EuFytbHH0ZSf2mQK2K1xtIgmaw4Da21R2C/NE/+NnItm5mPEFQmn8gmF3f0rfOlmZ3Y3bIf7bFj7DHxAA== dependencies: - "@jest/environment" "^27.4.4" - "@jest/types" "^27.4.2" - expect "^27.4.2" + "@jest/environment" "^29.4.1" + "@jest/expect" "^29.4.1" + "@jest/types" "^29.4.1" + jest-mock "^29.4.1" -"@jest/reporters@^27.4.5": - version "27.4.5" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.4.5.tgz#e229acca48d18ea39e805540c1c322b075ae63ad" - integrity sha512-3orsG4vi8zXuBqEoy2LbnC1kuvkg1KQUgqNxmxpQgIOQEPeV0onvZu+qDQnEoX8qTQErtqn/xzcnbpeTuOLSiA== +"@jest/reporters@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.4.1.tgz#50d509c08575c75e3cd2176d72ec3786419d5e04" + integrity sha512-AISY5xpt2Xpxj9R6y0RF1+O6GRy9JsGa8+vK23Lmzdy1AYcpQn5ItX79wJSsTmfzPKSAcsY1LNt/8Y5Xe5LOSg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.4.2" - "@jest/test-result" "^27.4.2" - "@jest/transform" "^27.4.5" - "@jest/types" "^27.4.2" + "@jest/console" "^29.4.1" + "@jest/test-result" "^29.4.1" + "@jest/transform" "^29.4.1" + "@jest/types" "^29.4.1" + "@jridgewell/trace-mapping" "^0.3.15" "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.2.4" + glob "^7.1.3" + graceful-fs "^4.2.9" istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^4.0.3" + istanbul-lib-instrument "^5.1.0" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.2" - jest-haste-map "^27.4.5" - jest-resolve "^27.4.5" - jest-util "^27.4.2" - jest-worker "^27.4.5" + istanbul-reports "^3.1.3" + jest-message-util "^29.4.1" + jest-util "^29.4.1" + jest-worker "^29.4.1" slash "^3.0.0" - source-map "^0.6.0" string-length "^4.0.1" - terminal-link "^2.0.0" - v8-to-istanbul "^8.1.0" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" -"@jest/source-map@^27.4.0": - version "27.4.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.4.0.tgz#2f0385d0d884fb3e2554e8f71f8fa957af9a74b6" - integrity sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ== +"@jest/schemas@^29.4.0": + version "29.4.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.0.tgz#0d6ad358f295cc1deca0b643e6b4c86ebd539f17" + integrity sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ== dependencies: + "@sinclair/typebox" "^0.25.16" + +"@jest/source-map@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" + integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.15" callsites "^3.0.0" - graceful-fs "^4.2.4" - source-map "^0.6.0" + graceful-fs "^4.2.9" -"@jest/test-result@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.4.2.tgz#05fd4a5466ec502f3eae0b39dff2b93ea4d5d9ec" - integrity sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA== +"@jest/test-result@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.4.1.tgz#997f19695e13b34779ceb3c288a416bd26c3238d" + integrity sha512-WRt29Lwt+hEgfN8QDrXqXGgCTidq1rLyFqmZ4lmJOpVArC8daXrZWkWjiaijQvgd3aOUj2fM8INclKHsQW9YyQ== dependencies: - "@jest/console" "^27.4.2" - "@jest/types" "^27.4.2" + "@jest/console" "^29.4.1" + "@jest/types" "^29.4.1" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^27.4.5": - version "27.4.5" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.4.5.tgz#1d7e026844d343b60d2ca7fd82c579a17b445d7d" - integrity sha512-n5woIn/1v+FT+9hniymHPARA9upYUmfi5Pw9ewVwXCDlK4F5/Gkees9v8vdjGdAIJ2MPHLHodiajLpZZanWzEQ== +"@jest/test-sequencer@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.4.1.tgz#f7a006ec7058b194a10cf833c88282ef86d578fd" + integrity sha512-v5qLBNSsM0eHzWLXsQ5fiB65xi49A3ILPSFQKPXzGL4Vyux0DPZAIN7NAFJa9b4BiTDP9MBF/Zqc/QA1vuiJ0w== dependencies: - "@jest/test-result" "^27.4.2" - graceful-fs "^4.2.4" - jest-haste-map "^27.4.5" - jest-runtime "^27.4.5" - -"@jest/transform@^27.4.5": - version "27.4.5" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.4.5.tgz#3dfe2e3680cd4aa27356172bf25617ab5b94f195" - integrity sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^27.4.2" - babel-plugin-istanbul "^6.0.0" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^27.4.5" - jest-regex-util "^27.4.0" - jest-util "^27.4.2" - micromatch "^4.0.4" - pirates "^4.0.1" + "@jest/test-result" "^29.4.1" + graceful-fs "^4.2.9" + jest-haste-map "^29.4.1" slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" + +"@jest/transform@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.4.1.tgz#e4f517841bb795c7dcdee1ba896275e2c2d26d4a" + integrity sha512-5w6YJrVAtiAgr0phzKjYd83UPbCXsBRTeYI4BXokv9Er9CcrH9hfXL/crCvP2d2nGOcovPUnlYiLPFLZrkG5Hg== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.4.1" + "@jridgewell/trace-mapping" "^0.3.15" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.4.1" + jest-regex-util "^29.2.0" + jest-util "^29.4.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^5.0.0" "@jest/types@^27.4.2": version "27.4.2" @@ -500,6 +722,58 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@jest/types@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.4.1.tgz#f9f83d0916f50696661da72766132729dcb82ecb" + integrity sha512-zbrAXDUOnpJ+FMST2rV7QZOgec8rskg2zv8g2ajeqitp4tvZiyqTCYXANrKsM+ryj5o+LI+ZN2EgU9drrkiwSA== + dependencies: + "@jest/schemas" "^29.4.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + "@sapphire/async-queue@^1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.5.0.tgz#2f255a3f186635c4fb5a2381e375d3dfbc5312d8" @@ -518,24 +792,29 @@ resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.2.2.tgz#faacdc1b5f7c43145a71eddba917de2b707ef780" integrity sha512-ula2O0kpSZtX9rKXNeQMrHwNd7E4jPDJYUXmEGTFdMRfyfMw+FPyh04oKMjAiDuOi64bYgVkOV3MjK+loImFhQ== +"@sinclair/typebox@^0.25.16": + version "0.25.21" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.21.tgz#763b05a4b472c93a8db29b2c3e359d55b29ce272" + integrity sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g== + "@sindresorhus/is@^4.0.0": version "4.6.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== -"@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== +"@sinonjs/commons@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" + integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^8.0.1": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" - integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== +"@sinonjs/fake-timers@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c" + integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw== dependencies: - "@sinonjs/commons" "^1.7.0" + "@sinonjs/commons" "^2.0.0" "@sqltools/formatter@^1.2.2": version "1.2.3" @@ -554,12 +833,7 @@ resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": +"@types/babel__core@^7.1.14": version "7.1.17" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.17.tgz#f50ac9d20d64153b510578d84f9643f9a3afbe64" integrity sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A== @@ -585,7 +859,7 @@ "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": version "7.14.2" resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== @@ -602,10 +876,10 @@ "@types/node" "*" "@types/responselike" "*" -"@types/graceful-fs@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== +"@types/graceful-fs@^4.1.3": + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== dependencies: "@types/node" "*" @@ -633,13 +907,13 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^27.0.3": - version "27.0.3" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.3.tgz#0cf9dfe9009e467f70a342f0f94ead19842a783a" - integrity sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg== +"@types/jest@^29.0.0": + version "29.4.0" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.4.0.tgz#a8444ad1704493e84dbf07bb05990b275b3b9206" + integrity sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ== dependencies: - jest-diff "^27.0.0" - pretty-format "^27.0.0" + expect "^29.0.0" + pretty-format "^29.0.0" "@types/json-buffer@~3.0.0": version "3.0.0" @@ -704,46 +978,18 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^17.0.8": + version "17.0.20" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.20.tgz#107f0fcc13bd4a524e352b41c49fe88aab5c54d5" + integrity sha512-eknWrTHofQuPk2iuqDm1waA7V6xPlbgBoaaXEgYkClhLOnB0TtbW+srJaOToAgawPxPlHQzwypFA2bhZaUGP5A== + dependencies: + "@types/yargs-parser" "*" + "@types/zen-observable@0.8.3": version "0.8.3" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3" integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw== -abab@^2.0.3, abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== - -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== - dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" - -acorn-walk@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - -acorn@^7.1.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.2.4: - version "8.6.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" - integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -805,26 +1051,20 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -babel-jest@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.4.5.tgz#d38bd0be8ea71d8b97853a5fc9f76deeb095c709" - integrity sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA== +babel-jest@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.4.1.tgz#01fa167e27470b35c2d4a1b841d9586b1764da19" + integrity sha512-xBZa/pLSsF/1sNpkgsiT3CmY7zV1kAsZ9OxxtrFqYucnOuRftXAfcJqcDVyOPeN4lttWTwhLdu0T9f8uvoPEUg== dependencies: - "@jest/transform" "^27.4.5" - "@jest/types" "^27.4.2" + "@jest/transform" "^29.4.1" "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^27.4.0" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.4.0" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" slash "^3.0.0" -babel-plugin-istanbul@^6.0.0: +babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== @@ -835,14 +1075,14 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz#d7831fc0f93573788d80dee7e682482da4c730d6" - integrity sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw== +babel-plugin-jest-hoist@^29.4.0: + version "29.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.0.tgz#3fd3dfcedf645932df6d0c9fc3d9a704dd860248" + integrity sha512-a/sZRLQJEmsmejQ2rPEUe35nO1+C9dc9O1gplH1SXmJxveQSRUYdBk8yGZG/VOUuZs1u2aHZJusEGoRMbhhwCg== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" - "@types/babel__core" "^7.0.0" + "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" babel-preset-current-node-syntax@^1.0.0: @@ -863,12 +1103,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz#70d0e676a282ccb200fbabd7f415db5fdf393bca" - integrity sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg== +babel-preset-jest@^29.4.0: + version "29.4.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.4.0.tgz#c2b03c548b02dea0a18ae21d5759c136f9251ee4" + integrity sha512-fUB9vZflUSM3dO/6M2TCAepTzvA4VkOvl67PjErcrQMGt9Eve7uazaeyCZ2th3UtI7ljpiBJES0F7A1vBRsLZA== dependencies: - babel-plugin-jest-hoist "^27.4.0" + babel-plugin-jest-hoist "^29.4.0" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -908,11 +1148,6 @@ braces@^3.0.1: dependencies: fill-range "^7.0.1" -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - browserslist@^4.17.5: version "4.19.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" @@ -924,6 +1159,16 @@ browserslist@^4.17.5: node-releases "^2.0.1" picocolors "^1.0.0" +browserslist@^4.21.3: + version "4.21.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== + dependencies: + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" + bs-logger@0.x: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -989,6 +1234,11 @@ caniuse-lite@^1.0.30001286: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001291.tgz#08a8d2cfea0b2cf2e1d94dd795942d0daef6108c" integrity sha512-roMV5V0HNGgJ88s42eE70sstqGW/gwFndosYrikHthw98N5tLnOTxFqMLQjZVRxTWFlJ4rn+MsgXrR7MDPY4jA== +caniuse-lite@^1.0.30001400: + version "1.0.30001449" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001449.tgz#a8d11f6a814c75c9ce9d851dc53eb1d1dfbcd657" + integrity sha512-CPB+UL9XMT/Av+pJxCKGhdx+yg1hzplvFJQlJ2n68PyQGMz9L/E2zCyLdOL8uasbouTUgnPl+y0tccI/se+BEw== + chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -1042,6 +1292,15 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" @@ -1083,13 +1342,6 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - compress-brotli@^1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/compress-brotli/-/compress-brotli-1.3.8.tgz#0c0a60c97a989145314ec381e84e26682e7b38db" @@ -1103,13 +1355,18 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -1124,33 +1381,7 @@ cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -cssom@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== - -cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - -data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== - dependencies: - abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - -debug@4, debug@^4.1.0, debug@^4.3.1: +debug@^4.1.0, debug@^4.3.1: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== @@ -1164,11 +1395,6 @@ debug@^4.1.1: dependencies: ms "2.1.2" -decimal.js@^10.2.1: - version "10.3.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" - integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== - decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -1181,11 +1407,6 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= -deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - deepmerge@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" @@ -1196,20 +1417,15 @@ defer-to-connect@^2.0.0: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -diff-sequences@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" - integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== +diff-sequences@^29.3.1: + version "29.3.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e" + integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ== discord-api-types@^0.37.3: version "0.37.9" @@ -1233,13 +1449,6 @@ discord.js@^14.3.0: undici "^5.9.1" ws "^8.8.1" -domexception@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" - integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== - dependencies: - webidl-conversions "^5.0.0" - dotenv@^16.0.0: version "16.0.3" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" @@ -1255,10 +1464,15 @@ electron-to-chromium@^1.4.17: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.25.tgz#ce95e6678f8c6893ae892c7e95a5000e83f1957f" integrity sha512-bTwub9Y/76EiNmfaiJih+hAy6xn7Ns95S4KvI2NuKNOz8TEEKKQUu44xuy0PYMudjM9zdjKRS1bitsUvHTfuUg== -emittery@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" - integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== +electron-to-chromium@^1.4.251: + version "1.4.284" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" + integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== emoji-regex@^8.0.0: version "8.0.0" @@ -1277,6 +1491,13 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -1292,33 +1513,11 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== -escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -esprima@^4.0.0, esprima@^4.0.1: +esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -1339,33 +1538,27 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= -expect@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.4.2.tgz#4429b0f7e307771d176de9bdf23229b101db6ef6" - integrity sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg== +expect@^29.0.0, expect@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.1.tgz#58cfeea9cbf479b64ed081fd1e074ac8beb5a1fe" + integrity sha512-OKrGESHOaMxK3b6zxIq9SOW8kEXztKff/Dvg88j4xIJxur1hspEbedVkR3GpHe5LO+WB2Qw7OWN0RMTdp6as5A== dependencies: - "@jest/types" "^27.4.2" - ansi-styles "^5.0.0" - jest-get-type "^27.4.0" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-regex-util "^27.4.0" + "@jest/expect-utils" "^29.4.1" + jest-get-type "^29.2.0" + jest-matcher-utils "^29.4.1" + jest-message-util "^29.4.1" + jest-util "^29.4.1" fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - fb-watchman@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" @@ -1397,15 +1590,6 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1455,7 +1639,7 @@ glob-parent@^6.0.0: dependencies: is-glob "^4.0.3" -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -1494,6 +1678,11 @@ graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== +graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1516,13 +1705,6 @@ highlight.js@^10.7.1: resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== -html-encoding-sniffer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" - integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== - dependencies: - whatwg-encoding "^1.0.5" - html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -1533,15 +1715,6 @@ http-cache-semantics@^4.0.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - http2-wrapper@^1.0.0-beta.5.2: version "1.0.3" resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" @@ -1550,26 +1723,11 @@ http2-wrapper@^1.0.0-beta.5.2: quick-lru "^5.1.1" resolve-alpn "^1.0.0" -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -1601,6 +1759,11 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + is-core-module@^2.2.0: version "2.8.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" @@ -1635,21 +1798,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -1665,16 +1818,6 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-instrument@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== - dependencies: - "@babel/core" "^7.7.5" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" - semver "^6.3.0" - istanbul-lib-instrument@^5.0.4: version "5.1.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" @@ -1686,6 +1829,17 @@ istanbul-lib-instrument@^5.0.4: istanbul-lib-coverage "^3.2.0" semver "^6.3.0" +istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + istanbul-lib-report@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" @@ -1704,226 +1858,187 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.1.tgz#7085857f17d2441053c6ce5c3b8fdf6882289397" - integrity sha512-q1kvhAXWSsXfMjCdNHNPKZZv94OlspKnoGv+R9RGbnqOOQ0VbNfLFgQDVgi7hHenKsndGq3/o0OBdzDXthWcNw== +istanbul-reports@^3.1.3: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.4.2.tgz#da2547ea47c6e6a5f6ed336151bd2075736eb4a5" - integrity sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A== +jest-changed-files@^29.4.0: + version "29.4.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.4.0.tgz#ac2498bcd394228f7eddcadcf928b3583bf2779d" + integrity sha512-rnI1oPxgFghoz32Y8eZsGJMjW54UlqT17ycQeCEktcxxwqqKdlj9afl8LNeO0Pbu+h2JQHThQP0BzS67eTRx4w== dependencies: - "@jest/types" "^27.4.2" execa "^5.0.0" - throat "^6.0.1" + p-limit "^3.1.0" -jest-circus@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.4.5.tgz#70bfb78e0200cab9b84747bf274debacaa538467" - integrity sha512-eTNWa9wsvBwPykhMMShheafbwyakcdHZaEYh5iRrQ0PFJxkDP/e3U/FvzGuKWu2WpwUA3C3hPlfpuzvOdTVqnw== +jest-circus@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.4.1.tgz#ff1b63eb04c3b111cefea9489e8dbadd23ce49bd" + integrity sha512-v02NuL5crMNY4CGPHBEflLzl4v91NFb85a+dH9a1pUNx6Xjggrd8l9pPy4LZ1VYNRXlb+f65+7O/MSIbLir6pA== dependencies: - "@jest/environment" "^27.4.4" - "@jest/test-result" "^27.4.2" - "@jest/types" "^27.4.2" + "@jest/environment" "^29.4.1" + "@jest/expect" "^29.4.1" + "@jest/test-result" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" - expect "^27.4.2" is-generator-fn "^2.0.0" - jest-each "^27.4.2" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-runtime "^27.4.5" - jest-snapshot "^27.4.5" - jest-util "^27.4.2" - pretty-format "^27.4.2" + jest-each "^29.4.1" + jest-matcher-utils "^29.4.1" + jest-message-util "^29.4.1" + jest-runtime "^29.4.1" + jest-snapshot "^29.4.1" + jest-util "^29.4.1" + p-limit "^3.1.0" + pretty-format "^29.4.1" slash "^3.0.0" stack-utils "^2.0.3" - throat "^6.0.1" -jest-cli@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.4.5.tgz#8708f54c28d13681f3255ec9026a2b15b03d41e8" - integrity sha512-hrky3DSgE0u7sQxaCL7bdebEPHx5QzYmrGuUjaPLmPE8jx5adtvGuOlRspvMoVLTTDOHRnZDoRLYJuA+VCI7Hg== +jest-cli@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.4.1.tgz#7abef96944f300feb9b76f68b1eb2d68774fe553" + integrity sha512-jz7GDIhtxQ37M+9dlbv5K+/FVcIo1O/b1sX3cJgzlQUf/3VG25nvuWzlDC4F1FLLzUThJeWLu8I7JF9eWpuURQ== dependencies: - "@jest/core" "^27.4.5" - "@jest/test-result" "^27.4.2" - "@jest/types" "^27.4.2" + "@jest/core" "^29.4.1" + "@jest/test-result" "^29.4.1" + "@jest/types" "^29.4.1" chalk "^4.0.0" exit "^0.1.2" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^27.4.5" - jest-util "^27.4.2" - jest-validate "^27.4.2" + jest-config "^29.4.1" + jest-util "^29.4.1" + jest-validate "^29.4.1" prompts "^2.0.1" - yargs "^16.2.0" + yargs "^17.3.1" -jest-config@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.4.5.tgz#77ed7f2ba7bcfd7d740ade711d0d13512e08a59e" - integrity sha512-t+STVJtPt+fpqQ8GBw850NtSQbnDOw/UzdPfzDaHQ48/AylQlW7LHj3dH+ndxhC1UxJ0Q3qkq7IH+nM1skwTwA== +jest-config@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.4.1.tgz#e62670c6c980ec21d75941806ec4d0c0c6402728" + integrity sha512-g7p3q4NuXiM4hrS4XFATTkd+2z0Ml2RhFmFPM8c3WyKwVDNszbl4E7cV7WIx1YZeqqCtqbtTtZhGZWJlJqngzg== dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^27.4.5" - "@jest/types" "^27.4.2" - babel-jest "^27.4.5" + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.4.1" + "@jest/types" "^29.4.1" + babel-jest "^29.4.1" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" - glob "^7.1.1" - graceful-fs "^4.2.4" - jest-circus "^27.4.5" - jest-environment-jsdom "^27.4.4" - jest-environment-node "^27.4.4" - jest-get-type "^27.4.0" - jest-jasmine2 "^27.4.5" - jest-regex-util "^27.4.0" - jest-resolve "^27.4.5" - jest-runner "^27.4.5" - jest-util "^27.4.2" - jest-validate "^27.4.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.4.1" + jest-environment-node "^29.4.1" + jest-get-type "^29.2.0" + jest-regex-util "^29.2.0" + jest-resolve "^29.4.1" + jest-runner "^29.4.1" + jest-util "^29.4.1" + jest-validate "^29.4.1" micromatch "^4.0.4" - pretty-format "^27.4.2" + parse-json "^5.2.0" + pretty-format "^29.4.1" slash "^3.0.0" + strip-json-comments "^3.1.1" -jest-diff@^27.0.0, jest-diff@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.4.2.tgz#786b2a5211d854f848e2dcc1e324448e9481f36f" - integrity sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q== +jest-diff@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.1.tgz#9a6dc715037e1fa7a8a44554e7d272088c4029bd" + integrity sha512-uazdl2g331iY56CEyfbNA0Ut7Mn2ulAG5vUaEHXycf1L6IPyuImIxSz4F0VYBKi7LYIuxOwTZzK3wh5jHzASMw== dependencies: chalk "^4.0.0" - diff-sequences "^27.4.0" - jest-get-type "^27.4.0" - pretty-format "^27.4.2" + diff-sequences "^29.3.1" + jest-get-type "^29.2.0" + pretty-format "^29.4.1" -jest-docblock@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.4.0.tgz#06c78035ca93cbbb84faf8fce64deae79a59f69f" - integrity sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg== +jest-docblock@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" + integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A== dependencies: detect-newline "^3.0.0" -jest-each@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.4.2.tgz#19364c82a692d0d26557642098d1f4619c9ee7d3" - integrity sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg== +jest-each@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.4.1.tgz#05ce9979e7486dbd0f5d41895f49ccfdd0afce01" + integrity sha512-QlYFiX3llJMWUV0BtWht/esGEz9w+0i7BHwODKCze7YzZzizgExB9MOfiivF/vVT0GSQ8wXLhvHXh3x2fVD4QQ== dependencies: - "@jest/types" "^27.4.2" + "@jest/types" "^29.4.1" chalk "^4.0.0" - jest-get-type "^27.4.0" - jest-util "^27.4.2" - pretty-format "^27.4.2" + jest-get-type "^29.2.0" + jest-util "^29.4.1" + pretty-format "^29.4.1" -jest-environment-jsdom@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz#94f738e99514d7a880e8ed8e03e3a321d43b49db" - integrity sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA== +jest-environment-node@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.4.1.tgz#22550b7d0f8f0b16228639c9f88ca04bbf3c1974" + integrity sha512-x/H2kdVgxSkxWAIlIh9MfMuBa0hZySmfsC5lCsWmWr6tZySP44ediRKDUiNggX/eHLH7Cd5ZN10Rw+XF5tXsqg== dependencies: - "@jest/environment" "^27.4.4" - "@jest/fake-timers" "^27.4.2" - "@jest/types" "^27.4.2" + "@jest/environment" "^29.4.1" + "@jest/fake-timers" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" - jest-mock "^27.4.2" - jest-util "^27.4.2" - jsdom "^16.6.0" + jest-mock "^29.4.1" + jest-util "^29.4.1" -jest-environment-node@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.4.4.tgz#42fe5e3b224cb69b99811ebf6f5eaa5a59618514" - integrity sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA== +jest-get-type@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" + integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== + +jest-haste-map@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.4.1.tgz#b0579dc82d94b40ed9041af56ad25c2f80bedaeb" + integrity sha512-imTjcgfVVTvg02khXL11NNLTx9ZaofbAWhilrMg/G8dIkp+HYCswhxf0xxJwBkfhWb3e8dwbjuWburvxmcr58w== dependencies: - "@jest/environment" "^27.4.4" - "@jest/fake-timers" "^27.4.2" - "@jest/types" "^27.4.2" - "@types/node" "*" - jest-mock "^27.4.2" - jest-util "^27.4.2" - -jest-get-type@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" - integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== - -jest-haste-map@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.4.5.tgz#c2921224a59223f91e03ec15703905978ef0cc1a" - integrity sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q== - dependencies: - "@jest/types" "^27.4.2" - "@types/graceful-fs" "^4.1.2" + "@jest/types" "^29.4.1" + "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^27.4.0" - jest-serializer "^27.4.0" - jest-util "^27.4.2" - jest-worker "^27.4.5" + graceful-fs "^4.2.9" + jest-regex-util "^29.2.0" + jest-util "^29.4.1" + jest-worker "^29.4.1" micromatch "^4.0.4" - walker "^1.0.7" + walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-jasmine2@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.4.5.tgz#ff79d11561679ff6c89715b0cd6b1e8c0dfbc6dc" - integrity sha512-oUnvwhJDj2LhOiUB1kdnJjkx8C5PwgUZQb9urF77mELH9DGR4e2GqpWQKBOYXWs5+uTN9BGDqRz3Aeg5Wts7aw== +jest-leak-detector@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.4.1.tgz#632186c546e084da2b490b7496fee1a1c9929637" + integrity sha512-akpZv7TPyGMnH2RimOCgy+hPmWZf55EyFUvymQ4LMsQP8xSPlZumCPtXGoDhFNhUE2039RApZkTQDKU79p/FiQ== dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^27.4.4" - "@jest/source-map" "^27.4.0" - "@jest/test-result" "^27.4.2" - "@jest/types" "^27.4.2" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - expect "^27.4.2" - is-generator-fn "^2.0.0" - jest-each "^27.4.2" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-runtime "^27.4.5" - jest-snapshot "^27.4.5" - jest-util "^27.4.2" - pretty-format "^27.4.2" - throat "^6.0.1" + jest-get-type "^29.2.0" + pretty-format "^29.4.1" -jest-leak-detector@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz#7fc3120893a7a911c553f3f2bdff9faa4454abbb" - integrity sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw== - dependencies: - jest-get-type "^27.4.0" - pretty-format "^27.4.2" - -jest-matcher-utils@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz#d17c5038607978a255e0a9a5c32c24e984b6c60b" - integrity sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ== +jest-matcher-utils@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.4.1.tgz#73d834e305909c3b43285fbc76f78bf0ad7e1954" + integrity sha512-k5h0u8V4nAEy6lSACepxL/rw78FLDkBnXhZVgFneVpnJONhb2DhZj/Gv4eNe+1XqQ5IhgUcqj745UwH0HJmMnA== dependencies: chalk "^4.0.0" - jest-diff "^27.4.2" - jest-get-type "^27.4.0" - pretty-format "^27.4.2" + jest-diff "^29.4.1" + jest-get-type "^29.2.0" + pretty-format "^29.4.1" -jest-message-util@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.4.2.tgz#07f3f1bf207d69cf798ce830cc57f1a849f99388" - integrity sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w== +jest-message-util@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.4.1.tgz#522623aa1df9a36ebfdffb06495c7d9d19e8a845" + integrity sha512-H4/I0cXUaLeCw6FM+i4AwCnOwHRgitdaUFOdm49022YD5nfyr8C/DrbXOBEyJaj+w/y0gGJ57klssOaUiLLQGQ== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.4.2" + "@jest/types" "^29.4.1" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^27.4.2" + pretty-format "^29.4.1" slash "^3.0.0" stack-utils "^2.0.3" @@ -1934,148 +2049,135 @@ jest-mock-extended@^3.0.0: dependencies: ts-essentials "^7.0.3" -jest-mock@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.4.2.tgz#184ff197a25491bfe4570c286daa5d62eb760b88" - integrity sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA== +jest-mock@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.4.1.tgz#a218a2abf45c99c501d4665207748a6b9e29afbd" + integrity sha512-MwA4hQ7zBOcgVCVnsM8TzaFLVUD/pFWTfbkY953Y81L5ret3GFRZtmPmRFAjKQSdCKoJvvqOu6Bvfpqlwwb0dQ== dependencies: - "@jest/types" "^27.4.2" + "@jest/types" "^29.4.1" "@types/node" "*" + jest-util "^29.4.1" jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" - integrity sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg== +jest-regex-util@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b" + integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA== -jest-resolve-dependencies@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.5.tgz#9398af854bdb12d6a9e5a8a536ee401f889a3ecf" - integrity sha512-elEVvkvRK51y037NshtEkEnukMBWvlPzZHiL847OrIljJ8yIsujD2GXRPqDXC4rEVKbcdsy7W0FxoZb4WmEs7w== +jest-resolve-dependencies@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.1.tgz#02420a2e055da105e5fca8218c471d8b9553c904" + integrity sha512-Y3QG3M1ncAMxfjbYgtqNXC5B595zmB6e//p/qpA/58JkQXu/IpLDoLeOa8YoYfsSglBKQQzNUqtfGJJT/qLmJg== dependencies: - "@jest/types" "^27.4.2" - jest-regex-util "^27.4.0" - jest-snapshot "^27.4.5" + jest-regex-util "^29.2.0" + jest-snapshot "^29.4.1" -jest-resolve@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.4.5.tgz#8dc44f5065fb8d58944c20f932cb7b9fe9760cca" - integrity sha512-xU3z1BuOz/hUhVUL+918KqUgK+skqOuUsAi7A+iwoUldK6/+PW+utK8l8cxIWT9AW7IAhGNXjSAh1UYmjULZZw== +jest-resolve@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.4.1.tgz#4c6bf71a07b8f0b79c5fdf4f2a2cf47317694c5e" + integrity sha512-j/ZFNV2lm9IJ2wmlq1uYK0Y/1PiyDq9g4HEGsNTNr3viRbJdV+8Lf1SXIiLZXFvyiisu0qUyIXGBnw+OKWkJwQ== dependencies: - "@jest/types" "^27.4.2" chalk "^4.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^27.4.5" + graceful-fs "^4.2.9" + jest-haste-map "^29.4.1" jest-pnp-resolver "^1.2.2" - jest-util "^27.4.2" - jest-validate "^27.4.2" + jest-util "^29.4.1" + jest-validate "^29.4.1" resolve "^1.20.0" - resolve.exports "^1.1.0" + resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.4.5.tgz#daba2ba71c8f34137dc7ac45616add35370a681e" - integrity sha512-/irauncTfmY1WkTaRQGRWcyQLzK1g98GYG/8QvIPviHgO1Fqz1JYeEIsSfF+9mc/UTA6S+IIHFgKyvUrtiBIZg== +jest-runner@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.4.1.tgz#57460d9ebb0eea2e27eeddca1816cf8537469661" + integrity sha512-8d6XXXi7GtHmsHrnaqBKWxjKb166Eyj/ksSaUYdcBK09VbjPwIgWov1VwSmtupCIz8q1Xv4Qkzt/BTo3ZqiCeg== dependencies: - "@jest/console" "^27.4.2" - "@jest/environment" "^27.4.4" - "@jest/test-result" "^27.4.2" - "@jest/transform" "^27.4.5" - "@jest/types" "^27.4.2" + "@jest/console" "^29.4.1" + "@jest/environment" "^29.4.1" + "@jest/test-result" "^29.4.1" + "@jest/transform" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" chalk "^4.0.0" - emittery "^0.8.1" - exit "^0.1.2" - graceful-fs "^4.2.4" - jest-docblock "^27.4.0" - jest-environment-jsdom "^27.4.4" - jest-environment-node "^27.4.4" - jest-haste-map "^27.4.5" - jest-leak-detector "^27.4.2" - jest-message-util "^27.4.2" - jest-resolve "^27.4.5" - jest-runtime "^27.4.5" - jest-util "^27.4.2" - jest-worker "^27.4.5" - source-map-support "^0.5.6" - throat "^6.0.1" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.2.0" + jest-environment-node "^29.4.1" + jest-haste-map "^29.4.1" + jest-leak-detector "^29.4.1" + jest-message-util "^29.4.1" + jest-resolve "^29.4.1" + jest-runtime "^29.4.1" + jest-util "^29.4.1" + jest-watcher "^29.4.1" + jest-worker "^29.4.1" + p-limit "^3.1.0" + source-map-support "0.5.13" -jest-runtime@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.4.5.tgz#97703ad2a1799d4f50ab59049bd21a9ceaed2813" - integrity sha512-CIYqwuJQXHQtPd/idgrx4zgJ6iCb6uBjQq1RSAGQrw2S8XifDmoM1Ot8NRd80ooAm+ZNdHVwsktIMGlA1F1FAQ== +jest-runtime@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.4.1.tgz#9a50f9c69d3a391690897c01b0bfa8dc5dd45808" + integrity sha512-UXTMU9uKu2GjYwTtoAw5rn4STxWw/nadOfW7v1sx6LaJYa3V/iymdCLQM6xy3+7C6mY8GfX22vKpgxY171UIoA== dependencies: - "@jest/console" "^27.4.2" - "@jest/environment" "^27.4.4" - "@jest/globals" "^27.4.4" - "@jest/source-map" "^27.4.0" - "@jest/test-result" "^27.4.2" - "@jest/transform" "^27.4.5" - "@jest/types" "^27.4.2" - "@types/yargs" "^16.0.0" + "@jest/environment" "^29.4.1" + "@jest/fake-timers" "^29.4.1" + "@jest/globals" "^29.4.1" + "@jest/source-map" "^29.2.0" + "@jest/test-result" "^29.4.1" + "@jest/transform" "^29.4.1" + "@jest/types" "^29.4.1" + "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" - execa "^5.0.0" - exit "^0.1.2" glob "^7.1.3" - graceful-fs "^4.2.4" - jest-haste-map "^27.4.5" - jest-message-util "^27.4.2" - jest-mock "^27.4.2" - jest-regex-util "^27.4.0" - jest-resolve "^27.4.5" - jest-snapshot "^27.4.5" - jest-util "^27.4.2" - jest-validate "^27.4.2" + graceful-fs "^4.2.9" + jest-haste-map "^29.4.1" + jest-message-util "^29.4.1" + jest-mock "^29.4.1" + jest-regex-util "^29.2.0" + jest-resolve "^29.4.1" + jest-snapshot "^29.4.1" + jest-util "^29.4.1" + semver "^7.3.5" slash "^3.0.0" strip-bom "^4.0.0" - yargs "^16.2.0" -jest-serializer@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.4.0.tgz#34866586e1cae2388b7d12ffa2c7819edef5958a" - integrity sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ== +jest-snapshot@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.4.1.tgz#5692210b3690c94f19317913d4082b123bd83dd9" + integrity sha512-l4iV8EjGgQWVz3ee/LR9sULDk2pCkqb71bjvlqn+qp90lFwpnulHj4ZBT8nm1hA1C5wowXLc7MGnw321u0tsYA== dependencies: - "@types/node" "*" - graceful-fs "^4.2.4" - -jest-snapshot@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.4.5.tgz#2ea909b20aac0fe62504bc161331f730b8a7ecc7" - integrity sha512-eCi/iM1YJFrJWiT9de4+RpWWWBqsHiYxFG9V9o/n0WXs6GpW4lUt4FAHAgFPTLPqCUVzrMQmSmTZSgQzwqR7IQ== - dependencies: - "@babel/core" "^7.7.2" + "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" - "@babel/parser" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" - "@babel/types" "^7.0.0" - "@jest/transform" "^27.4.5" - "@jest/types" "^27.4.2" - "@types/babel__traverse" "^7.0.4" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.4.1" + "@jest/transform" "^29.4.1" + "@jest/types" "^29.4.1" + "@types/babel__traverse" "^7.0.6" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^27.4.2" - graceful-fs "^4.2.4" - jest-diff "^27.4.2" - jest-get-type "^27.4.0" - jest-haste-map "^27.4.5" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-resolve "^27.4.5" - jest-util "^27.4.2" + expect "^29.4.1" + graceful-fs "^4.2.9" + jest-diff "^29.4.1" + jest-get-type "^29.2.0" + jest-haste-map "^29.4.1" + jest-matcher-utils "^29.4.1" + jest-message-util "^29.4.1" + jest-util "^29.4.1" natural-compare "^1.4.0" - pretty-format "^27.4.2" - semver "^7.3.2" + pretty-format "^29.4.1" + semver "^7.3.5" -jest-util@^27.0.0, jest-util@^27.4.2: +jest-util@^27.0.0: version "27.4.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.4.2.tgz#ed95b05b1adfd761e2cda47e0144c6a58e05a621" integrity sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA== @@ -2087,48 +2189,63 @@ jest-util@^27.0.0, jest-util@^27.4.2: graceful-fs "^4.2.4" picomatch "^2.2.3" -jest-validate@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.4.2.tgz#eecfcc1b1c9429aa007da08a2bae4e32a81bbbc3" - integrity sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A== +jest-util@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.4.1.tgz#2eeed98ff4563b441b5a656ed1a786e3abc3e4c4" + integrity sha512-bQy9FPGxVutgpN4VRc0hk6w7Hx/m6L53QxpDreTZgJd9gfx/AV2MjyPde9tGyZRINAUrSv57p2inGBu2dRLmkQ== dependencies: - "@jest/types" "^27.4.2" + "@jest/types" "^29.4.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.4.1.tgz#0d5174510415083ec329d4f981bf6779211f17e9" + integrity sha512-qNZXcZQdIQx4SfUB/atWnI4/I2HUvhz8ajOSYUu40CSmf9U5emil8EDHgE7M+3j9/pavtk3knlZBDsgFvv/SWw== + dependencies: + "@jest/types" "^29.4.1" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^27.4.0" + jest-get-type "^29.2.0" leven "^3.1.0" - pretty-format "^27.4.2" + pretty-format "^29.4.1" -jest-watcher@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.4.2.tgz#c9037edfd80354c9fe90de4b6f8b6e2b8e736744" - integrity sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg== +jest-watcher@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.4.1.tgz#6e3e2486918bd778849d4d6e67fd77b814f3e6ed" + integrity sha512-vFOzflGFs27nU6h8dpnVRER3O2rFtL+VMEwnG0H3KLHcllLsU8y9DchSh0AL/Rg5nN1/wSiQ+P4ByMGpuybaVw== dependencies: - "@jest/test-result" "^27.4.2" - "@jest/types" "^27.4.2" + "@jest/test-result" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^27.4.2" + emittery "^0.13.1" + jest-util "^29.4.1" string-length "^4.0.1" -jest-worker@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.5.tgz#d696e3e46ae0f24cff3fa7195ffba22889262242" - integrity sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg== +jest-worker@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.4.1.tgz#7cb4a99a38975679600305650f86f4807460aab1" + integrity sha512-O9doU/S1EBe+yp/mstQ0VpPwpv0Clgn68TkNwGxL6/usX/KUW9Arnn4ag8C3jc6qHcXznhsT5Na1liYzAsuAbQ== dependencies: "@types/node" "*" + jest-util "^29.4.1" merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^27.4.5: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.4.5.tgz#66e45acba44137fac26be9d3cc5bb031e136dc0f" - integrity sha512-uT5MiVN3Jppt314kidCk47MYIRilJjA/l2mxwiuzzxGUeJIvA8/pDaJOAX5KWvjAo7SCydcW0/4WEtgbLMiJkg== +jest@^29.0.0: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.4.1.tgz#bb34baca8e05901b49c02c62f1183a6182ea1785" + integrity sha512-cknimw7gAXPDOmj0QqztlxVtBVCw2lYY9CeIE5N6kD+kET1H4H79HSNISJmijb1HF+qk+G+ploJgiDi5k/fRlg== dependencies: - "@jest/core" "^27.4.5" + "@jest/core" "^29.4.1" + "@jest/types" "^29.4.1" import-local "^3.0.2" - jest-cli "^27.4.5" + jest-cli "^29.4.1" js-tokens@^4.0.0: version "4.0.0" @@ -2150,39 +2267,6 @@ js-yaml@^4.0.0: dependencies: argparse "^2.0.1" -jsdom@^16.6.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" - integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== - dependencies: - abab "^2.0.5" - acorn "^8.2.4" - acorn-globals "^6.0.0" - cssom "^0.4.4" - cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" - escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.6" - xml-name-validator "^3.0.0" - jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -2193,11 +2277,21 @@ json-buffer@3.0.1, json-buffer@~3.0.1: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json5@2.x, json5@^2.1.2: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== +json5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + keyv@^4.0.0: version "4.3.2" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.3.2.tgz#e839df676a0c7ee594c8835e7c1c83742558e5c2" @@ -2216,13 +2310,10 @@ leven@^3.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== linqts@^1.14.4: version "1.14.4" @@ -2251,16 +2342,18 @@ lodash.uniqwith@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz#7a0cbf65f43b5928625a9d4d0dc54b18cadc7ef3" integrity sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q== -lodash@^4.7.0: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - lowercase-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -2300,18 +2393,6 @@ micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" -mime-db@1.51.0: - version "1.51.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" - integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== - -mime-types@^2.1.12: - version "2.1.34" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" - integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== - dependencies: - mime-db "1.51.0" - mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -2385,6 +2466,11 @@ node-releases@^2.0.1: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== +node-releases@^2.0.6: + version "2.0.8" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.8.tgz#0f349cdc8fcfa39a92ac0be9bc48b7706292b9ae" + integrity sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A== + normalize-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -2402,11 +2488,6 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -nwsapi@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== - object-assign@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2426,18 +2507,6 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - p-cancelable@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" @@ -2450,6 +2519,13 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -2462,6 +2538,16 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + parse5-htmlparser2-tree-adapter@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" @@ -2469,16 +2555,16 @@ parse5-htmlparser2-tree-adapter@^6.0.0: dependencies: parse5 "^6.0.1" -parse5@6.0.1, parse5@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - parse5@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== +parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -2514,10 +2600,10 @@ picomatch@^2.0.4, picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== -pirates@^4.0.1: - version "4.0.4" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.4.tgz#07df81e61028e402735cdd49db701e4885b4e6e6" - integrity sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw== +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== pkg-dir@^4.2.0: version "4.2.0" @@ -2526,20 +2612,14 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -pretty-format@^27.0.0, pretty-format@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.4.2.tgz#e4ce92ad66c3888423d332b40477c87d1dac1fb8" - integrity sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw== +pretty-format@^29.0.0, pretty-format@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.1.tgz#0da99b532559097b8254298da7c75a0785b1751c" + integrity sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg== dependencies: - "@jest/types" "^27.4.2" - ansi-regex "^5.0.1" + "@jest/schemas" "^29.4.0" ansi-styles "^5.0.0" - react-is "^17.0.1" + react-is "^18.0.0" process-nextick-args@~2.0.0: version "2.0.1" @@ -2554,11 +2634,6 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -psl@^1.1.33: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -2567,11 +2642,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" @@ -2586,10 +2656,10 @@ random-bunny@^2.0.5: got "^11.8.3" linqts "^1.14.4" -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== readable-stream@2.3.7: version "2.3.7" @@ -2647,10 +2717,10 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== +resolve.exports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.0.tgz#c1a0028c2d166ec2fbf7d0644584927e76e7400e" + integrity sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg== resolve@^1.20.0: version "1.20.0" @@ -2667,13 +2737,6 @@ responselike@^2.0.0: dependencies: lowercase-keys "^2.0.0" -rimraf@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -2684,24 +2747,12 @@ safe-buffer@^5.0.1, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - sax@>=0.6.0: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" - integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== - dependencies: - xmlchars "^2.2.0" - -semver@7.x, semver@^7.3.2: +semver@7.x: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -2713,6 +2764,13 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.3.5: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + sha.js@^2.4.11: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" @@ -2733,11 +2791,16 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@^3.0.2, signal-exit@^3.0.3: +signal-exit@^3.0.3: version "3.0.6" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== +signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -2748,10 +2811,10 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -source-map-support@^0.5.6: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -2761,16 +2824,11 @@ source-map@^0.5.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -2836,6 +2894,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + strtok3@^7.0.0-alpha.9: version "7.0.0" resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0.tgz#868c428b4ade64a8fd8fee7364256001c1a4cbe5" @@ -2851,7 +2914,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -2865,27 +2928,6 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" -supports-hyperlinks@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" - integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - -symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -2909,11 +2951,6 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" -throat@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" - integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== - tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -2939,22 +2976,6 @@ token-types@^5.0.0-alpha.2: "@tokenizer/token" "^0.3.0" ieee754 "^1.2.1" -tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.1.2" - -tr46@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" - integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== - dependencies: - punycode "^2.1.1" - ts-essentials@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" @@ -2989,13 +3010,6 @@ tslib@^2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - type-detect@4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -3006,13 +3020,6 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - typeorm@^0.2.44: version "0.2.44" resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.44.tgz#4cc07eb1eb7a0e7f3ec9e65ded9eb3c3aedbb3e1" @@ -3046,10 +3053,13 @@ undici@^5.9.1: resolved "https://registry.yarnpkg.com/undici/-/undici-5.10.0.tgz#dd9391087a90ccfbd007568db458674232ebf014" integrity sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g== -universalify@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +update-browserslist-db@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" @@ -3066,67 +3076,22 @@ uuid@^9.0.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== -v8-to-istanbul@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz#0aeb763894f1a0a1676adf8a8b7612a38902446c" - integrity sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA== +v8-to-istanbul@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" + integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== dependencies: + "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" - source-map "^0.7.3" -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -w3c-xmlserializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" - integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== - dependencies: - xml-name-validator "^3.0.0" - -walker@^1.0.7: +walker@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: makeerror "1.0.12" -webidl-conversions@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" - integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== - -webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - -whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - -whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - -whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" - integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== - dependencies: - lodash "^4.7.0" - tr46 "^2.1.0" - webidl-conversions "^6.1.0" - which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -3134,11 +3099,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -3153,31 +3113,19 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== +write-file-atomic@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.0.tgz#54303f117e109bf3d540261125c8ea5a7320fab0" + integrity sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w== dependencies: imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -ws@^7.4.6: - version "7.5.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" - integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== + signal-exit "^3.0.7" ws@^8.8.1: version "8.8.1" resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - xml2js@^0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" @@ -3191,16 +3139,16 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== -xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" @@ -3216,7 +3164,12 @@ yargs-parser@^21.0.0: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== -yargs@^16.0.0, yargs@^16.2.0: +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^16.0.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== @@ -3242,6 +3195,24 @@ yargs@^17.0.1: y18n "^5.0.5" yargs-parser "^21.0.0" +yargs@^17.3.1: + version "17.6.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" + integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + zen-observable-ts@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz#2d1aa9d79b87058e9b75698b92791c1838551f83" From c12644d5373ae13e5eec02536dc7ca16b1b677f0 Mon Sep 17 00:00:00 2001 From: Ethan Lane <ethan@vylpes.com> Date: Mon, 8 May 2023 18:37:51 +0100 Subject: [PATCH 38/56] Fix build errors from merge --- src/commands/ignore.ts | 11 ++++++++--- src/entity/Audit.ts | 8 ++++---- src/entity/IgnoredChannel.ts | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/commands/ignore.ts b/src/commands/ignore.ts index 2367762..4a57d83 100644 --- a/src/commands/ignore.ts +++ b/src/commands/ignore.ts @@ -14,12 +14,17 @@ export default class Ignore extends Command { public override async execute(interaction: CommandInteraction) { if (!interaction.guildId) return; - + const isChannelIgnored = await IgnoredChannel.IsChannelIgnored(interaction.guildId); - + if (isChannelIgnored) { const entity = await IgnoredChannel.FetchOneById(IgnoredChannel, interaction.guildId); - + + if (!entity) { + await interaction.reply('Unable to find channel.'); + return; + } + await IgnoredChannel.Remove(IgnoredChannel, entity); await interaction.reply('This channel will start being logged again.'); diff --git a/src/entity/Audit.ts b/src/entity/Audit.ts index 448913d..8577f0f 100644 --- a/src/entity/Audit.ts +++ b/src/entity/Audit.ts @@ -34,22 +34,22 @@ export default class Audit extends BaseEntity { @Column() ServerId: string; - public static async FetchAuditsByUserId(userId: string, serverId: string): Promise<Audit[] | undefined> { + public static async FetchAuditsByUserId(userId: string, serverId: string): Promise<Audit[] | null> { const connection = getConnection(); const repository = connection.getRepository(Audit); - const all = await repository.find({ UserId: userId, ServerId: serverId }); + const all = await repository.find({ where: { UserId: userId, ServerId: serverId } }); return all; } - public static async FetchAuditByAuditId(auditId: string, serverId: string): Promise<Audit | undefined> { + public static async FetchAuditByAuditId(auditId: string, serverId: string): Promise<Audit | null> { const connection = getConnection(); const repository = connection.getRepository(Audit); - const single = await repository.findOne({ AuditId: auditId, ServerId: serverId }); + const single = await repository.findOne({ where: { AuditId: auditId, ServerId: serverId } }); return single; } diff --git a/src/entity/IgnoredChannel.ts b/src/entity/IgnoredChannel.ts index cd38dd5..ccb573c 100644 --- a/src/entity/IgnoredChannel.ts +++ b/src/entity/IgnoredChannel.ts @@ -14,7 +14,7 @@ export default class IgnoredChannel extends BaseEntity { const repository = connection.getRepository(IgnoredChannel); - const single = await repository.findOne(channelId); + const single = await repository.findOne({ where: { Id: channelId } }); return single != undefined; } From 6fb448fc2849c416c4d705a10acbb2d90dab8c57 Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 15 May 2023 18:19:12 +0100 Subject: [PATCH 39/56] Update dependency emoji-regex to v10 (#240) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [emoji-regex](https://mths.be/emoji-regex) ([source](https://github.com/mathiasbynens/emoji-regex)) | dependencies | major | [`^9.2.0` -> `^10.0.0`](https://renovatebot.com/diffs/npm/emoji-regex/9.2.2/10.2.1) | --- ### Release Notes <details> <summary>mathiasbynens/emoji-regex</summary> ### [`v10.2.1`](https://github.com/mathiasbynens/emoji-regex/compare/v10.2.0...v10.2.1) [Compare Source](https://github.com/mathiasbynens/emoji-regex/compare/v10.2.0...v10.2.1) ### [`v10.2.0`](https://github.com/mathiasbynens/emoji-regex/compare/v10.1.0...v10.2.0) [Compare Source](https://github.com/mathiasbynens/emoji-regex/compare/v10.1.0...v10.2.0) ### [`v10.1.0`](https://github.com/mathiasbynens/emoji-regex/compare/v10.0.1...v10.1.0) [Compare Source](https://github.com/mathiasbynens/emoji-regex/compare/v10.0.1...v10.1.0) ### [`v10.0.1`](https://github.com/mathiasbynens/emoji-regex/compare/v10.0.0...v10.0.1) [Compare Source](https://github.com/mathiasbynens/emoji-regex/compare/v10.0.0...v10.0.1) ### [`v10.0.0`](https://github.com/mathiasbynens/emoji-regex/compare/v9.2.2...v10.0.0) [Compare Source](https://github.com/mathiasbynens/emoji-regex/compare/v9.2.2...v10.0.0) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/240 Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 1353458..6450d6b 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@types/uuid": "^9.0.0", "discord.js": "^14.3.0", "dotenv": "^16.0.0", - "emoji-regex": "^9.2.0", + "emoji-regex": "^10.0.0", "jest": "^29.0.0", "jest-mock-extended": "^3.0.0", "minimatch": "7.4.3", diff --git a/yarn.lock b/yarn.lock index 107becc..c424739 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1249,16 +1249,16 @@ emittery@^0.13.1: resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== +emoji-regex@^10.0.0: + version "10.2.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.2.1.tgz#a41c330d957191efd3d9dfe6e1e8e1e9ab048b3f" + integrity sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.0: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" From 14a1981b94663e0a1c48f51350546831c22627f0 Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 15 May 2023 18:20:36 +0100 Subject: [PATCH 40/56] Update dependency ts-jest to v29 (#244) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [ts-jest](https://kulshekhar.github.io/ts-jest) ([source](https://github.com/kulshekhar/ts-jest)) | dependencies | major | [`^27.1.2` -> `^29.0.0`](https://renovatebot.com/diffs/npm/ts-jest/27.1.5/29.1.0) | --- ### Release Notes <details> <summary>kulshekhar/ts-jest</summary> ### [`v29.1.0`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2910-httpsgithubcomkulshekharts-jestcomparev2905v2910-2023-03-26) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.0.5...v29.1.0) ##### Features - Support TypeScript 5.x ([#​4064](https://github.com/kulshekhar/ts-jest/issues/4064)) ([db98cc9](https://github.com/kulshekhar/ts-jest/commit/87f27821db99be411288b50a4f9baa7bedb98cc9)), closes [#​4048](https://github.com/kulshekhar/ts-jest/issues/4048) #### [29.0.5](https://github.com/kulshekhar/ts-jest/compare/v29.0.4...v29.0.5) (2023-01-13) ##### Reverts - Revert "fix(transformer): don't use cache when `tsJestConfig` is different ([#​3966](https://github.com/kulshekhar/ts-jest/issues/3966))" ([185eb18](https://github.com/kulshekhar/ts-jest/commit/185eb189d7076c717a107066817d2d6959a8fe39)), closes [#​3966](https://github.com/kulshekhar/ts-jest/issues/3966) #### [29.0.4](https://github.com/kulshekhar/ts-jest/compare/v29.0.3...v29.0.4) (2023-01-10) ##### Bug Fixes - **transformer:** don't use cache when `tsJestConfig` is different ([#​3966](https://github.com/kulshekhar/ts-jest/issues/3966)) ([a445638](https://github.com/kulshekhar/ts-jest/commit/a445638ca631911e8ab1a896ffdfcd21506ce71a)) - bump `json5` to `2.2.3` ([#​3976](https://github.com/kulshekhar/ts-jest/pull/3976))([b9f7809](https://github.com/kulshekhar/ts-jest/commit/b9f7809948309f92534aeba63f3ffb01cb7dc536)) #### [29.0.3](https://github.com/kulshekhar/ts-jest/compare/v29.0.2...v29.0.3) (2022-09-28) ##### Bug Fixes - merge config from `globals` with transformer config correctly ([#​3842](https://github.com/kulshekhar/ts-jest/issues/3842)) ([9c9fd60](https://github.com/kulshekhar/ts-jest/commit/9c9fd6097aea36a6e8b06b0e8841df22896f9121)), closes [#​3841](https://github.com/kulshekhar/ts-jest/issues/3841) - **presets:** allow merging transform config when using presets ([#​3833](https://github.com/kulshekhar/ts-jest/issues/3833)) ([afc6a94](https://github.com/kulshekhar/ts-jest/commit/afc6a948b17c2dc22be51b1a9475a0f6ecbbc372)) ##### Features - add `useESM` option to `pathsToModuleNameMapper` options ([#​3792](https://github.com/kulshekhar/ts-jest/issues/3792)) ([eabe906](https://github.com/kulshekhar/ts-jest/commit/eabe906e1dd6b132a7b0d05ffc13172cd8a6b73b)) #### [29.0.2](https://github.com/kulshekhar/ts-jest/compare/v29.0.1...v29.0.2) (2022-09-23) ##### Bug Fixes - mark `ts-jest` as optional in `ConfigGlobals` ([#​3816](https://github.com/kulshekhar/ts-jest/issues/3816)) ([cbb88bb](https://github.com/kulshekhar/ts-jest/commit/cbb88bba34dbb852d8f4013be6e020769feb306d)), closes [#​3815](https://github.com/kulshekhar/ts-jest/issues/3815) - use correct typings for `config:init` command ([#​3825](https://github.com/kulshekhar/ts-jest/issues/3825)) ([21b94db](https://github.com/kulshekhar/ts-jest/commit/21b94dbca25b762f79e63b92dea12d830f444570)) #### [29.0.2](https://github.com/kulshekhar/ts-jest/compare/v29.0.1...v29.0.2) (2022-09-22) ##### Bug Fixes - mark `ts-jest` as optional in `ConfigGlobals` ([#​3816](https://github.com/kulshekhar/ts-jest/issues/3816)) ([cbb88bb](https://github.com/kulshekhar/ts-jest/commit/cbb88bba34dbb852d8f4013be6e020769feb306d)), closes [#​3815](https://github.com/kulshekhar/ts-jest/issues/3815) #### [29.0.1](https://github.com/kulshekhar/ts-jest/compare/v29.0.0...v29.0.1) (2022-09-13) ##### Bug Fixes - **legacy:** include existing globals config in cached config ([#​3803](https://github.com/kulshekhar/ts-jest/issues/3803)) ([e79be47](https://github.com/kulshekhar/ts-jest/commit/e79be47d2b81a677d0dd39d84328a38ca0f0ffc6)) ##### Features - add typings for `ts-jest` options via `transform` config ([#​3805](https://github.com/kulshekhar/ts-jest/issues/3805)) ([664b0f2](https://github.com/kulshekhar/ts-jest/commit/664b0f2b446a36dd7661f4840ca3dd7722f1f6ff)) ### [`v29.0.5`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2905-httpsgithubcomkulshekharts-jestcomparev2904v2905-2023-01-13) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.0.4...v29.0.5) ##### Reverts - Revert "fix(transformer): don't use cache when `tsJestConfig` is different ([#​3966](https://github.com/kulshekhar/ts-jest/issues/3966))" ([185eb18](https://github.com/kulshekhar/ts-jest/commit/185eb189d7076c717a107066817d2d6959a8fe39)), closes [#​3966](https://github.com/kulshekhar/ts-jest/issues/3966) ### [`v29.0.4`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2904-httpsgithubcomkulshekharts-jestcomparev2903v2904-2023-01-10) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.0.3...v29.0.4) ##### Bug Fixes - **transformer:** don't use cache when `tsJestConfig` is different ([#​3966](https://github.com/kulshekhar/ts-jest/issues/3966)) ([a445638](https://github.com/kulshekhar/ts-jest/commit/a445638ca631911e8ab1a896ffdfcd21506ce71a)) - bump `json5` to `2.2.3` ([#​3976](https://github.com/kulshekhar/ts-jest/pull/3976))([b9f7809](https://github.com/kulshekhar/ts-jest/commit/b9f7809948309f92534aeba63f3ffb01cb7dc536)) ### [`v29.0.3`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2903-httpsgithubcomkulshekharts-jestcomparev2902v2903-2022-09-28) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.0.2...v29.0.3) ##### Bug Fixes - merge config from `globals` with transformer config correctly ([#​3842](https://github.com/kulshekhar/ts-jest/issues/3842)) ([9c9fd60](https://github.com/kulshekhar/ts-jest/commit/9c9fd6097aea36a6e8b06b0e8841df22896f9121)), closes [#​3841](https://github.com/kulshekhar/ts-jest/issues/3841) - **presets:** allow merging transform config when using presets ([#​3833](https://github.com/kulshekhar/ts-jest/issues/3833)) ([afc6a94](https://github.com/kulshekhar/ts-jest/commit/afc6a948b17c2dc22be51b1a9475a0f6ecbbc372)) ##### Features - add `useESM` option to `pathsToModuleNameMapper` options ([#​3792](https://github.com/kulshekhar/ts-jest/issues/3792)) ([eabe906](https://github.com/kulshekhar/ts-jest/commit/eabe906e1dd6b132a7b0d05ffc13172cd8a6b73b)) ### [`v29.0.2`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2902-httpsgithubcomkulshekharts-jestcomparev2901v2902-2022-09-23) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.0.1...v29.0.2) ##### Bug Fixes - mark `ts-jest` as optional in `ConfigGlobals` ([#​3816](https://github.com/kulshekhar/ts-jest/issues/3816)) ([cbb88bb](https://github.com/kulshekhar/ts-jest/commit/cbb88bba34dbb852d8f4013be6e020769feb306d)), closes [#​3815](https://github.com/kulshekhar/ts-jest/issues/3815) - use correct typings for `config:init` command ([#​3825](https://github.com/kulshekhar/ts-jest/issues/3825)) ([21b94db](https://github.com/kulshekhar/ts-jest/commit/21b94dbca25b762f79e63b92dea12d830f444570)) ### [`v29.0.1`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2901-httpsgithubcomkulshekharts-jestcomparev2900v2901-2022-09-13) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.0.0...v29.0.1) ##### Bug Fixes - **legacy:** include existing globals config in cached config ([#​3803](https://github.com/kulshekhar/ts-jest/issues/3803)) ([e79be47](https://github.com/kulshekhar/ts-jest/commit/e79be47d2b81a677d0dd39d84328a38ca0f0ffc6)) ##### Features - add typings for `ts-jest` options via `transform` config ([#​3805](https://github.com/kulshekhar/ts-jest/issues/3805)) ([664b0f2](https://github.com/kulshekhar/ts-jest/commit/664b0f2b446a36dd7661f4840ca3dd7722f1f6ff)) ### [`v29.0.0`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2900-httpsgithubcomkulshekharts-jestcomparev2900-next1v2900-2022-09-08) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v28.0.8...v29.0.0) ##### Features - drop Node 12 and Node 17 support ([#​3787](https://github.com/kulshekhar/ts-jest/issues/3787)) ([0f1de16](https://github.com/kulshekhar/ts-jest/commit/0f1de16608dcc7a8ab00bf7fd6a01ebcec6a210a)) - migrate globals config to transformer config ([#​3780](https://github.com/kulshekhar/ts-jest/issues/3780)) ([31e5843](https://github.com/kulshekhar/ts-jest/commit/31e584355434c4fc96022f9e8b41f04c11d24343)) - support Jest 29 ([#​3767](https://github.com/kulshekhar/ts-jest/issues/3767)) ([94b553b](https://github.com/kulshekhar/ts-jest/commit/94b553ba085c52db60f7a7078e3a74d9a02121b1)) ##### DEPRECATIONS - Define `ts-jest` config under `globals` is now deprecated. Please define the config via transformer config instead. ##### BREAKING CHANGES - Only Node 14, 16 and 18 are supported - **Jest 29** is required. ### [`v28.0.8`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2808-httpsgithubcomkulshekharts-jestcomparev2807v2808-2022-08-14) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v28.0.7...v28.0.8) ##### Bug Fixes - allow `.mts` to be processed ([#​3713](https://github.com/kulshekhar/ts-jest/issues/3713)) ([effae71](https://github.com/kulshekhar/ts-jest/commit/effae717369860e16cb0ccbf24027651493b9bf1)), closes [#​3702](https://github.com/kulshekhar/ts-jest/issues/3702) ### [`v28.0.7`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2807-httpsgithubcomkulshekharts-jestcomparev2806v2807-2022-07-15) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v28.0.6...v28.0.7) ##### Bug Fixes - update `@jest/types` to be an optional peer dependency ([#​3690](https://github.com/kulshekhar/ts-jest/issues/3690)) ([8a8c3fa](https://github.com/kulshekhar/ts-jest/commit/8a8c3fafecffd19380171c661e94246024cae2ff)), closes [#​3689](https://github.com/kulshekhar/ts-jest/issues/3689) ### [`v28.0.6`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2806-httpsgithubcomkulshekharts-jestcomparev2805v2806-2022-07-13) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v28.0.5...v28.0.6) ##### Bug Fixes - **config:** don't show diagnostics warning with `diagnostics: false` ([#​3647](https://github.com/kulshekhar/ts-jest/issues/3647)) ([9a9bc02](https://github.com/kulshekhar/ts-jest/commit/9a9bc02935968fb5eb9fd3614a1f7cce019b80d8)), closes [#​3638](https://github.com/kulshekhar/ts-jest/issues/3638) - **legacy:** add `useCaseSensitiveFileNames` wherever needed ([#​3683](https://github.com/kulshekhar/ts-jest/issues/3683)) ([c40bc34](https://github.com/kulshekhar/ts-jest/commit/c40bc34625d63cccc0db7296e616af27868fe1fe)), closes [#​3665](https://github.com/kulshekhar/ts-jest/issues/3665) - set `@jest/types` as peer dependency ([#​3633](https://github.com/kulshekhar/ts-jest/issues/3633)) ([24567e1](https://github.com/kulshekhar/ts-jest/commit/24567e13d2780ad8a11c7ff35f9151ec53f8c211)) ### [`v28.0.5`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2805-httpsgithubcomkulshekharts-jestcomparev2804v2805-2022-06-11) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v28.0.4...v28.0.5) ##### Bug Fixes - **legacy:** throw type check error in ESM mode with `reject` ([#​3618](https://github.com/kulshekhar/ts-jest/issues/3618)) ([7dd01ff](https://github.com/kulshekhar/ts-jest/commit/7dd01ffe0c7ad3add87b11227964544f2586355a)), closes [#​3507](https://github.com/kulshekhar/ts-jest/issues/3507) ### [`v28.0.4`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2804-httpsgithubcomkulshekharts-jestcomparev2803v2804-2022-06-02) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v28.0.3...v28.0.4) ##### Bug Fixes - remove `@types/jest` from peer deps ([#​3592](https://github.com/kulshekhar/ts-jest/issues/3592)) ([b66b656](https://github.com/kulshekhar/ts-jest/commit/b66b656e0f29eea9234a4d1e883c6d249437f03c)) ### [`v28.0.3`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2803-httpsgithubcomkulshekharts-jestcomparev2802v2803-2022-05-23) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v28.0.2...v28.0.3) ##### Bug Fixes - **security:** update version of `json5` ([#​3528](https://github.com/kulshekhar/ts-jest/issues/3528)) ([b31f5ba](https://github.com/kulshekhar/ts-jest/commit/b31f5bab142466fd8b6157ec03eff7316584e51d)) ### [`v28.0.2`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2802-httpsgithubcomkulshekharts-jestcomparev2801v2802-2022-05-07) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v28.0.1...v28.0.2) ##### Bug Fixes - **transformers:** use `Array.sort` in hoisting transformer ([#​3498](https://github.com/kulshekhar/ts-jest/issues/3498)) ([e400a6e](https://github.com/kulshekhar/ts-jest/commit/e400a6ec0e4706f606ae9b1e2897b0bb1cff6343)), closes [#​3476](https://github.com/kulshekhar/ts-jest/issues/3476) ### [`v28.0.1`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2801-httpsgithubcomkulshekharts-jestcomparev2800v2801-2022-05-03) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v28.0.0...v28.0.1) ##### Bug Fixes - lower the required node version to ^16.10 ([#​3495](https://github.com/kulshekhar/ts-jest/issues/3495)) ([3a4e48a](https://github.com/kulshekhar/ts-jest/commit/3a4e48afffa56f76efb98f48ad3e07a92731748e)), closes [#​3494](https://github.com/kulshekhar/ts-jest/issues/3494) ### [`v28.0.0`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#​2800-httpsgithubcomkulshekharts-jestcomparev2800-next3v2800-2022-05-02) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v27.1.5...v28.0.0) ##### Bug Fixes - **legacy** invoke Babel `processAsync` for `babel-jest` in ESM mode instead of `process` ([#​3430](https://github.com/kulshekhar/ts-jest/issues/3430)) ([0d7356c](https://github.com/kulshekhar/ts-jest/commit/0d7356cd767a924e5b57e3a93679eef4ca8fae51)) ##### Features - **presets:** add presets for legacy mode ([#​3465](https://github.com/kulshekhar/ts-jest/issues/3465)) ([543b4ad](https://github.com/kulshekhar/ts-jest/commit/543b4ad729d20fbd46a2de5cd4660dc50b94ebe7)) - mark `ConfigSet` as legacy ([#​3456](https://github.com/kulshekhar/ts-jest/issues/3456)) ([a986729](https://github.com/kulshekhar/ts-jest/commit/a98672977a679d1ed882605a3e71ed405432ffdc)) - mark `TsCompiler` and `TsJestCompiler` as legacy ([#​3457](https://github.com/kulshekhar/ts-jest/issues/3457)) ([0f2fe30](https://github.com/kulshekhar/ts-jest/commit/0f2fe306762d8549bd29737becd4aed14a650427)) - remove `path-mapping` AST transformer ([#​3455](https://github.com/kulshekhar/ts-jest/issues/3455)) ([f566869](https://github.com/kulshekhar/ts-jest/commit/f5668698f8fab78b3008d936aa5001f134f530e2)) - set Jest peer dependencies to v28 ([#​3454](https://github.com/kulshekhar/ts-jest/issues/3454)) ([1e880ff](https://github.com/kulshekhar/ts-jest/commit/1e880fffe82bca231d1d23f6508f4ab4bc31e03e)) - **core:** drop support for Node.js 10 ([#​3332](https://github.com/kulshekhar/ts-jest/issues/3332)) ([7a9aa61](https://github.com/kulshekhar/ts-jest/commit/7a9aa615ea0be881105676a17d5bd655afdc27f5)) - **core:** remove `mocked` testing util ([#​3333](https://github.com/kulshekhar/ts-jest/issues/3333)) ([2d9017d](https://github.com/kulshekhar/ts-jest/commit/2d9017ddfea39f45aa991876b314d1dbe4a36aad)) - **core:** remove `ts-jest/utils` sub path export ([#​3334](https://github.com/kulshekhar/ts-jest/issues/3334)) ([9f253d3](https://github.com/kulshekhar/ts-jest/commit/9f253d31dfcefa35ae00049d0d2dc4a3fe1b2f34)) - mark `TsJestTransformer` as legacy ([#​3451](https://github.com/kulshekhar/ts-jest/issues/3451)) ([b090179](https://github.com/kulshekhar/ts-jest/commit/b0901799adc519959a954dba5e7b8fc8b97a9665)) ##### BREAKING CHANGES - `path-mapping` AST transformer is no longer shipped in `ts-jest` v28. Please use an alternative one like https://github.com/LeDDGroup/typescript-transform-paths instead. - Any imports `ts-jest/dist/compiler/ts-compiler` should change to `ts-jest/dist/legacy/compiler/ts-compiler` - Any imports `ts-jest/dist/compiler/ts-jest-compiler` should change to `ts-jest/dist/legacy/compiler/ts-jest-compiler` - Any imports `ts-jest/dist/config/config-set` should change to `ts-jest/dist/legacy/config/config-set` - Minimum support `TypeScript` version is now **4.3** since Jest 28 requires it. - **Jest 28** is required. - **core:** Any imports `ts-jest/utils` should be replaced with `ts-jest`. - **core:** Starting from Jest 27.4, `mocked` has been integrated into Jest repo. - **core:** Support for Node.js v10 has been removed as Jest drops support for it. #### [27.1.5](https://github.com/kulshekhar/ts-jest/compare/v27.1.3...v27.1.4) (2022-05-17) ##### Bug Fixes - **transformers** use `Array.sort` in hoisting transformer ([#​3498](https://github.com/kulshekhar/ts-jest/pull/3498)) ([e400a6e](https://github.com/kulshekhar/ts-jest/commit/e400a6ec0e4706f606ae9b1e2897b0bb1cff6343)), fixes [#​3476](https://github.com/kulshekhar/ts-jest/issues/3476) #### [27.1.4](https://github.com/kulshekhar/ts-jest/compare/v27.1.3...v27.1.4) (2022-03-24) ##### Bug Fixes - **compiler:** revert [#​3194](https://github.com/kulshekhar/ts-jest/issues/3194) ([#​3362](https://github.com/kulshekhar/ts-jest/issues/3362)) ([2b7dffe](https://github.com/kulshekhar/ts-jest/commit/2b7dffeac940f779922c43cefba3f741a3911b49)), closes [#​3272](https://github.com/kulshekhar/ts-jest/issues/3272) - remove `esbuild` from peer dependency ([#​3360](https://github.com/kulshekhar/ts-jest/issues/3360)) ([8c8c1ca](https://github.com/kulshekhar/ts-jest/commit/8c8c1ca615b1edeedc9f4282557c28e82acee543)), closes [#​3346](https://github.com/kulshekhar/ts-jest/issues/3346) - support Babel config file with `.cjs` extension ([#​3361](https://github.com/kulshekhar/ts-jest/issues/3361)) ([5e5ac4a](https://github.com/kulshekhar/ts-jest/commit/5e5ac4ac286bdcce157d0bdc31f3a57202fdbdfe)), closes [#​3335](https://github.com/kulshekhar/ts-jest/issues/3335) #### [27.1.3](https://github.com/kulshekhar/ts-jest/compare/v27.1.2...v27.1.3) (2022-01-14) ##### Bug Fixes - **compiler:** update memory cache for compiler using received file content ([#​3194](https://github.com/kulshekhar/ts-jest/issues/3194)) ([e4d9541](https://github.com/kulshekhar/ts-jest/commit/e4d9541f262ca14cb25563c757c0f2345dbf5c51)) #### [27.1.2](https://github.com/kulshekhar/ts-jest/compare/v27.1.1...v27.1.2) (2021-12-15) ##### Bug Fixes - stimulate `esbuild` type to avoid importing `esbuild` directly ([#​3147](https://github.com/kulshekhar/ts-jest/issues/3147)) ([9ace0a9](https://github.com/kulshekhar/ts-jest/commit/9ace0a9991da8bcb0f04a2e603f7601d6fb630e7)) #### [27.1.1](https://github.com/kulshekhar/ts-jest/compare/v27.1.0...v27.1.1) (2021-12-07) ##### Bug Fixes - bring back `afterProcess` hook ([#​3132](https://github.com/kulshekhar/ts-jest/issues/3132)) ([2b6b86e](https://github.com/kulshekhar/ts-jest/commit/2b6b86e01dcd3d9d9906f24fe3db5cadb799146a)) - make `esbuild` as optional peer dependency ([#​3129](https://github.com/kulshekhar/ts-jest/pull/3129)) ([20258de](https://github.com/kulshekhar/ts-jest/commit/20258de54c9c10f8d2495bda174f9865a3cebc91)) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/244 Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 52 +++++++++++----------------------------------------- 2 files changed, 12 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index 6450d6b..36e6f96 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "minimatch": "7.4.3", "mysql": "^2.18.1", "random-bunny": "^2.0.5", - "ts-jest": "^27.1.2", + "ts-jest": "^29.0.0", "typeorm": "0.3.14" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index c424739..ed70e3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -554,17 +554,6 @@ slash "^3.0.0" write-file-atomic "^4.0.2" -"@jest/types@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" - integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - "@jest/types@^29.5.0": version "29.5.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" @@ -784,13 +773,6 @@ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== -"@types/yargs@^16.0.0": - version "16.0.5" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" - integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== - dependencies: - "@types/yargs-parser" "*" - "@types/yargs@^17.0.8": version "17.0.24" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" @@ -1952,19 +1934,7 @@ jest-snapshot@^29.5.0: pretty-format "^29.5.0" semver "^7.3.5" -jest-util@^27.0.0: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" - integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-util@^29.5.0: +jest-util@^29.0.0, jest-util@^29.5.0: version "29.5.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== @@ -2050,7 +2020,7 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json5@2.x, json5@^2.2.2: +json5@^2.2.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -2739,19 +2709,19 @@ ts-essentials@^7.0.3: resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== -ts-jest@^27.1.2: - version "27.1.5" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.5.tgz#0ddf1b163fbaae3d5b7504a1e65c914a95cff297" - integrity sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA== +ts-jest@^29.0.0: + version "29.1.0" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.0.tgz#4a9db4104a49b76d2b368ea775b6c9535c603891" + integrity sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA== dependencies: bs-logger "0.x" fast-json-stable-stringify "2.x" - jest-util "^27.0.0" - json5 "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" lodash.memoize "4.x" make-error "1.x" semver "7.x" - yargs-parser "20.x" + yargs-parser "^21.0.1" ts-mixer@^6.0.3: version "6.0.3" @@ -2888,12 +2858,12 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@20.x, yargs-parser@^20.2.2: +yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-parser@^21.1.1: +yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== From 40182c8777c94f7d318be80ae5cbc45917030b24 Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 15 May 2023 18:23:54 +0100 Subject: [PATCH 41/56] Update dependency minimatch to v7.4.6 (#284) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [minimatch](https://github.com/isaacs/minimatch) | dependencies | patch | [`7.4.3` -> `7.4.6`](https://renovatebot.com/diffs/npm/minimatch/7.4.3/7.4.6) | --- ### Release Notes <details> <summary>isaacs/minimatch</summary> ### [`v7.4.6`](https://github.com/isaacs/minimatch/compare/v7.4.5...v7.4.6) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.4.5...v7.4.6) ### [`v7.4.5`](https://github.com/isaacs/minimatch/compare/v7.4.4...v7.4.5) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.4.4...v7.4.5) ### [`v7.4.4`](https://github.com/isaacs/minimatch/compare/v7.4.3...v7.4.4) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.4.3...v7.4.4) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/284 Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 36e6f96..8961322 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "emoji-regex": "^10.0.0", "jest": "^29.0.0", "jest-mock-extended": "^3.0.0", - "minimatch": "7.4.3", + "minimatch": "7.4.6", "mysql": "^2.18.1", "random-bunny": "^2.0.5", "ts-jest": "^29.0.0", diff --git a/yarn.lock b/yarn.lock index ed70e3d..17e0541 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2140,10 +2140,10 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -minimatch@7.4.3: - version "7.4.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.3.tgz#012cbf110a65134bb354ae9773b55256cdb045a2" - integrity sha512-5UB4yYusDtkRPbRiy1cqZ1IpGNcJCGlEMG17RKzPddpyiPKoCdwohbED8g4QXT0ewCt8LTkQXuljsUfQ3FKM4A== +minimatch@7.4.6: + version "7.4.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb" + integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw== dependencies: brace-expansion "^2.0.1" From 61633277efb159472f09362e15afbcb77e710989 Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 15 May 2023 18:24:57 +0100 Subject: [PATCH 42/56] Update dependency @types/node to v20 (#294) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped)) | devDependencies | major | [`^18.0.0` -> `^20.0.0`](https://renovatebot.com/diffs/npm/@types%2fnode/18.16.5/20.1.4) | --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/294 Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 8961322..2da981a 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "typeorm": "0.3.14" }, "devDependencies": { - "@types/node": "^18.0.0", + "@types/node": "^20.0.0", "typescript": "^5.0.0" } } diff --git a/yarn.lock b/yarn.lock index 17e0541..6efde4e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -734,10 +734,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.1.0.tgz#258805edc37c327cf706e64c6957f241ca4c4c20" integrity sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A== -"@types/node@^18.0.0": - version "18.16.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.5.tgz#bf64e42719dc2e74da24709a2e1c0b50a966120a" - integrity sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA== +"@types/node@^20.0.0": + version "20.1.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.1.4.tgz#83f148d2d1f5fe6add4c53358ba00d97fc4cdb71" + integrity sha512-At4pvmIOki8yuwLtd7BNHl3CiWNbtclUbNtScGx4OHfBd4/oWoJC8KRCIxXwkdndzhxOsPXihrsOoydxBjlE9Q== "@types/prettier@^2.1.5": version "2.7.2" From c2418381ea07fd2d4e7fffab42e8de25b208714d Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 22 May 2023 18:07:24 +0100 Subject: [PATCH 43/56] Update dependency minimatch to v9 (#286) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [minimatch](https://github.com/isaacs/minimatch) | dependencies | major | [`7.4.6` -> `9.0.1`](https://renovatebot.com/diffs/npm/minimatch/7.4.6/9.0.1) | --- ### Release Notes <details> <summary>isaacs/minimatch</summary> ### [`v9.0.1`](https://github.com/isaacs/minimatch/compare/v9.0.0...v9.0.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v9.0.0...v9.0.1) ### [`v9.0.0`](https://github.com/isaacs/minimatch/compare/v8.0.4...v9.0.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v8.0.4...v9.0.0) ### [`v8.0.4`](https://github.com/isaacs/minimatch/compare/v8.0.3...v8.0.4) [Compare Source](https://github.com/isaacs/minimatch/compare/v8.0.3...v8.0.4) ### [`v8.0.3`](https://github.com/isaacs/minimatch/compare/v8.0.2...v8.0.3) [Compare Source](https://github.com/isaacs/minimatch/compare/v8.0.2...v8.0.3) ### [`v8.0.2`](https://github.com/isaacs/minimatch/compare/v8.0.1...v8.0.2) [Compare Source](https://github.com/isaacs/minimatch/compare/v8.0.1...v8.0.2) ### [`v8.0.1`](https://github.com/isaacs/minimatch/compare/v8.0.0...v8.0.1) [Compare Source](https://github.com/isaacs/minimatch/compare/v8.0.0...v8.0.1) ### [`v8.0.0`](https://github.com/isaacs/minimatch/compare/v7.4.6...v8.0.0) [Compare Source](https://github.com/isaacs/minimatch/compare/v7.4.6...v8.0.0) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/286 Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 2da981a..ca4ddfd 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "emoji-regex": "^10.0.0", "jest": "^29.0.0", "jest-mock-extended": "^3.0.0", - "minimatch": "7.4.6", + "minimatch": "9.0.1", "mysql": "^2.18.1", "random-bunny": "^2.0.5", "ts-jest": "^29.0.0", diff --git a/yarn.lock b/yarn.lock index 6efde4e..db16c26 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2140,10 +2140,10 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -minimatch@7.4.6: - version "7.4.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb" - integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw== +minimatch@9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" + integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== dependencies: brace-expansion "^2.0.1" From e6c845e3b255083576b3772735669a5b6008f4b3 Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 26 May 2023 17:59:22 +0100 Subject: [PATCH 44/56] Switch to TypeORM's DataSource API (#299) - Switch to TypeORM's DataSource API, rather than using the now deprecated ormconfig.json - This will fix stage deployment not knowing how to deploy the database migrations #297 > **NOTE:** This change requires the deployment scripts to be updated, please update them on the server before merging Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/299 --- .dev.env | 8 ++++++ .prod.env | 8 ++++++ .stage.env | 8 ++++++ ormconfig.dev.json | 24 ----------------- ormconfig.prod.json | 24 ----------------- ormconfig.stage.json | 24 ----------------- package.json | 4 +-- scripts/deploy_prod.sh | 1 - scripts/deploy_stage.sh | 1 - src/client/client.ts | 10 +++---- src/commands/501231711271780357/Lobby/add.ts | 2 +- src/commands/501231711271780357/Lobby/list.ts | 2 +- .../501231711271780357/Lobby/lobby.ts | 4 +-- .../501231711271780357/Lobby/remove.ts | 4 +-- src/commands/Role/config.ts | 8 +++--- src/commands/Role/role.ts | 4 +-- src/commands/audits.ts | 12 ++++----- src/commands/ban.ts | 2 +- src/commands/config.ts | 6 ++--- src/commands/ignore.ts | 2 +- src/commands/kick.ts | 4 +-- src/commands/mute.ts | 2 +- src/commands/setup.ts | 2 +- src/commands/warn.ts | 2 +- src/contracts/BaseEntity.ts | 23 +++++----------- src/database/dataSources/appDataSource.ts | 26 +++++++++++++++++++ .../entities}/501231711271780357/Lobby.ts | 9 +++---- src/{entity => database/entities}/Audit.ts | 17 +++++------- .../entities}/IgnoredChannel.ts | 9 +++---- src/{entity => database/entities}/Role.ts | 13 ++++------ src/{entity => database/entities}/Server.ts | 2 +- src/{entity => database/entities}/Setting.ts | 9 +++---- .../3.1/1662399171315-CreateBase.ts | 2 +- src/events/MessageEvents/MessageDelete.ts | 2 +- src/events/MessageEvents/MessageUpdate.ts | 2 +- src/helpers/SettingsHelper.ts | 4 +-- src/vylbot.ts | 6 +++++ 37 files changed, 128 insertions(+), 164 deletions(-) delete mode 100644 ormconfig.dev.json delete mode 100644 ormconfig.prod.json delete mode 100644 ormconfig.stage.json create mode 100644 src/database/dataSources/appDataSource.ts rename src/{entity => database/entities}/501231711271780357/Lobby.ts (79%) rename src/{entity => database/entities}/Audit.ts (72%) rename src/{entity => database/entities}/IgnoredChannel.ts (62%) rename src/{entity => database/entities}/Role.ts (72%) rename src/{entity => database/entities}/Server.ts (91%) rename src/{entity => database/entities}/Setting.ts (75%) rename src/{migration => database/migrations}/3.1/1662399171315-CreateBase.ts (92%) diff --git a/.dev.env b/.dev.env index 964667c..bb123f5 100644 --- a/.dev.env +++ b/.dev.env @@ -15,3 +15,11 @@ BOT_CLIENTID=682942374040961060 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app + +DB_HOST=127.0.0.1 +DB_PORT=3101 +DB_NAME=vylbot +DB_AUTH_USER=dev +DB_AUTH_PASS=dev +DB_SYNC=true +DB_LOGGING=true \ No newline at end of file diff --git a/.prod.env b/.prod.env index f0c75d5..25cac3d 100644 --- a/.prod.env +++ b/.prod.env @@ -14,3 +14,11 @@ BOT_CLIENTID=680083120896081954 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app + +DB_HOST=127.0.0.1 +DB_PORT=3121 +DB_NAME=vylbot +DB_AUTH_USER=prod +DB_AUTH_PASS=prod +DB_SYNC=false +DB_LOGGING=false \ No newline at end of file diff --git a/.stage.env b/.stage.env index 9b90831..383569a 100644 --- a/.stage.env +++ b/.stage.env @@ -14,3 +14,11 @@ BOT_CLIENTID=1016767908740857949 ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app + +DB_HOST=127.0.0.1 +DB_PORT=3111 +DB_NAME=vylbot +DB_AUTH_USER=stage +DB_AUTH_PASS=stage +DB_SYNC=false +DB_LOGGING=false \ No newline at end of file diff --git a/ormconfig.dev.json b/ormconfig.dev.json deleted file mode 100644 index f6f80c1..0000000 --- a/ormconfig.dev.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": "mysql", - "host": "localhost", - "port": 3101, - "username": "dev", - "password": "dev", - "database": "vylbot", - "synchronize": false, - "logging": false, - "entities": [ - "dist/entity/**/*.js" - ], - "migrations": [ - "dist/migration/**/*.js" - ], - "subscribers": [ - "dist/subscriber/**/*.js" - ], - "cli": { - "entitiesDir": "dist/entity", - "migrationsDir": "dist/migration", - "subscribersDir": "dist/subscriber" - } -} \ No newline at end of file diff --git a/ormconfig.prod.json b/ormconfig.prod.json deleted file mode 100644 index 300cfe2..0000000 --- a/ormconfig.prod.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": "mysql", - "host": "localhost", - "port": 3121, - "username": "prod", - "password": "prod", - "database": "vylbot", - "synchronize": false, - "logging": false, - "entities": [ - "dist/entity/**/*.js" - ], - "migrations": [ - "dist/migration/**/*.js" - ], - "subscribers": [ - "dist/subscriber/**/*.js" - ], - "cli": { - "entitiesDir": "dist/entity", - "migrationsDir": "dist/migration", - "subscribersDir": "dist/subscriber" - } -} \ No newline at end of file diff --git a/ormconfig.stage.json b/ormconfig.stage.json deleted file mode 100644 index a038f64..0000000 --- a/ormconfig.stage.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": "mysql", - "host": "localhost", - "port": 3111, - "username": "stage", - "password": "stage", - "database": "vylbot", - "synchronize": false, - "logging": false, - "entities": [ - "dist/entity/**/*.js" - ], - "migrations": [ - "dist/migration/**/*.js" - ], - "subscribers": [ - "dist/subscriber/**/*.js" - ], - "cli": { - "entitiesDir": "dist/entity", - "migrationsDir": "dist/migration", - "subscribersDir": "dist/subscriber" - } -} \ No newline at end of file diff --git a/package.json b/package.json index ca4ddfd..bf99a86 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "build": "tsc", "start": "node ./dist/vylbot", "test": "jest", - "db:up": "typeorm migration:run", - "db:down": "typeorm migration:revert" + "db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js", + "db:down": "typeorm migration:revert -d dist/database/dataSources/appDataSource.js" }, "repository": { "type": "git", diff --git a/scripts/deploy_prod.sh b/scripts/deploy_prod.sh index d9d5296..7adef0a 100644 --- a/scripts/deploy_prod.sh +++ b/scripts/deploy_prod.sh @@ -13,7 +13,6 @@ cd ~/apps/vylbot/vylbot_prod \ && (pm2 stop vylbot_prod || true) \ && (pm2 delete vylbot_prod || true) \ && cp .prod.env .env \ -&& cp ormconfig.prod.json ormconfig.json \ && yarn clean \ && yarn install --frozen-lockfile \ && yarn build \ diff --git a/scripts/deploy_stage.sh b/scripts/deploy_stage.sh index a6c8c92..d12a421 100644 --- a/scripts/deploy_stage.sh +++ b/scripts/deploy_stage.sh @@ -13,7 +13,6 @@ cd ~/apps/vylbot/vylbot_stage \ && (pm2 stop vylbot_stage || true) \ && (pm2 delete vylbot_stage || true) \ && cp .stage.env .env \ -&& cp ormconfig.stage.json ormconfig.json \ && yarn clean \ && yarn install --frozen-lockfile \ && yarn build \ diff --git a/src/client/client.ts b/src/client/client.ts index 75e06fb..d544ec7 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -8,11 +8,12 @@ import { Command } from "../type/command"; import { Events } from "./events"; import { Util } from "./util"; +import AppDataSource from "../database/dataSources/appDataSource"; export class CoreClient extends Client { private static _commandItems: ICommandItem[]; private static _eventItems: IEventItem[]; - + private _events: Events; private _util: Util; @@ -41,10 +42,9 @@ export class CoreClient extends Client { return; } - await createConnection().catch(e => { - console.error(e); - return; - }); + await AppDataSource.initialize() + .then(() => console.log("Data Source Initialized")) + .catch((err) => console.error("Error Initialising Data Source", err)); super.on("interactionCreate", this._events.onInteractionCreate); super.on("ready", this._events.onReady); diff --git a/src/commands/501231711271780357/Lobby/add.ts b/src/commands/501231711271780357/Lobby/add.ts index 16a38d2..0bc3ca0 100644 --- a/src/commands/501231711271780357/Lobby/add.ts +++ b/src/commands/501231711271780357/Lobby/add.ts @@ -1,6 +1,6 @@ import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { Command } from "../../../type/command"; -import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; +import { default as eLobby } from "../../../database/entities/501231711271780357/Lobby"; export default class AddRole extends Command { constructor() { diff --git a/src/commands/501231711271780357/Lobby/list.ts b/src/commands/501231711271780357/Lobby/list.ts index ccf0766..41bc4a3 100644 --- a/src/commands/501231711271780357/Lobby/list.ts +++ b/src/commands/501231711271780357/Lobby/list.ts @@ -1,6 +1,6 @@ import { CacheType, CommandInteraction, EmbedBuilder, GuildBasedChannel, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { Command } from "../../../type/command"; -import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; +import { default as eLobby } from "../../../database/entities/501231711271780357/Lobby"; import EmbedColours from "../../../constants/EmbedColours"; export default class ListLobby extends Command { diff --git a/src/commands/501231711271780357/Lobby/lobby.ts b/src/commands/501231711271780357/Lobby/lobby.ts index d7f0d42..83849a6 100644 --- a/src/commands/501231711271780357/Lobby/lobby.ts +++ b/src/commands/501231711271780357/Lobby/lobby.ts @@ -1,6 +1,6 @@ import { CommandInteraction, SlashCommandBuilder } from "discord.js"; import { Command } from "../../../type/command"; -import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; +import { default as eLobby } from "../../../database/entities/501231711271780357/Lobby"; export default class Lobby extends Command { constructor() { @@ -13,7 +13,7 @@ export default class Lobby extends Command { public override async execute(interaction: CommandInteraction) { if (!interaction.channelId) return; - + const lobby = await eLobby.FetchOneByChannelId(interaction.channelId); if (!lobby) { diff --git a/src/commands/501231711271780357/Lobby/remove.ts b/src/commands/501231711271780357/Lobby/remove.ts index b350316..2f241d2 100644 --- a/src/commands/501231711271780357/Lobby/remove.ts +++ b/src/commands/501231711271780357/Lobby/remove.ts @@ -1,6 +1,6 @@ import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { Command } from "../../../type/command"; -import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; +import { default as eLobby } from "../../../database/entities/501231711271780357/Lobby"; import BaseEntity from "../../../contracts/BaseEntity"; export default class RemoveLobby extends Command { @@ -32,7 +32,7 @@ export default class RemoveLobby extends Command { await interaction.reply('Channel not found.'); return; } - + await BaseEntity.Remove<eLobby>(eLobby, entity); await interaction.reply(`Removed <#${channel.channel.id}> from the list of lobby channels`); diff --git a/src/commands/Role/config.ts b/src/commands/Role/config.ts index 93d6891..aeb5c67 100644 --- a/src/commands/Role/config.ts +++ b/src/commands/Role/config.ts @@ -1,7 +1,7 @@ import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { Command } from "../../type/command"; -import { default as eRole } from "../../entity/Role"; -import Server from "../../entity/Server"; +import { default as eRole } from "../../database/entities/Role"; +import Server from "../../database/entities/Server"; export default class ConfigRole extends Command { constructor() { @@ -33,7 +33,7 @@ export default class ConfigRole extends Command { if (existingRole) { await eRole.Remove(eRole, existingRole); - + await interaction.reply('Removed role from configuration.'); } else { const server = await Server.FetchOneById(Server, interaction.guildId); @@ -45,7 +45,7 @@ export default class ConfigRole extends Command { const newRole = new eRole(role.role.id); newRole.SetServer(server); - + await newRole.Save(eRole, newRole); await interaction.reply('Added role to configuration.'); diff --git a/src/commands/Role/role.ts b/src/commands/Role/role.ts index 85b0abf..296b98f 100644 --- a/src/commands/Role/role.ts +++ b/src/commands/Role/role.ts @@ -1,6 +1,6 @@ import { CommandInteraction, EmbedBuilder, GuildMemberRoleManager, SlashCommandBuilder } from "discord.js"; import { Command } from "../../type/command"; -import { default as eRole } from "../../entity/Role"; +import { default as eRole } from "../../database/entities/Role"; import EmbedColours from "../../constants/EmbedColours"; export default class Role extends Command { @@ -47,7 +47,7 @@ export default class Role extends Command { .setColor(EmbedColours.Ok) .setTitle("Roles") .setDescription(`Roles: ${roles.length}\n\n${roles.join("\n")}`); - + await interaction.reply({ embeds: [ embed ]}); } diff --git a/src/commands/audits.ts b/src/commands/audits.ts index 3dabe26..c6c2366 100644 --- a/src/commands/audits.ts +++ b/src/commands/audits.ts @@ -1,4 +1,4 @@ -import Audit from "../entity/Audit"; +import Audit from "../database/entities/Audit"; import AuditTools from "../helpers/AuditTools"; import { Command } from "../type/command"; import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js"; @@ -13,7 +13,7 @@ export default class Audits extends Command { .setName("audits") .setDescription("View audits of a particular user in the server") .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) - .addSubcommand(subcommand => + .addSubcommand(subcommand => subcommand .setName('user') .setDescription('View all audits done against a user') @@ -66,7 +66,7 @@ export default class Audits extends Command { option .setName('reason') .setDescription('The reason'))); - + } public override async execute(interaction: CommandInteraction) { @@ -188,13 +188,13 @@ export default class Audits extends Command { await interaction.reply("Audit cleared."); } - private async AddAudit(interaction: CommandInteraction) { + private async AddAudit(interaction: CommandInteraction) { if (!interaction.guildId) return; const user = interaction.options.getUser('target'); const auditType = interaction.options.get('type'); const reasonInput = interaction.options.get('reason'); - + if (!user || !auditType || !auditType.value) { await interaction.reply("Invalid input."); return; @@ -206,7 +206,7 @@ export default class Audits extends Command { const audit = new Audit(user.id, type, reason, interaction.user.id, interaction.guildId); await audit.Save(Audit, audit); - + await interaction.reply(`Created new audit with ID \`${audit.AuditId}\``); } } \ No newline at end of file diff --git a/src/commands/ban.ts b/src/commands/ban.ts index a7f2d99..219a078 100644 --- a/src/commands/ban.ts +++ b/src/commands/ban.ts @@ -1,5 +1,5 @@ import { Command } from "../type/command"; -import Audit from "../entity/Audit"; +import Audit from "../database/entities/Audit"; import { AuditType } from "../constants/AuditType"; import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import EmbedColours from "../constants/EmbedColours"; diff --git a/src/commands/config.ts b/src/commands/config.ts index a370f27..d86c7e3 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -2,8 +2,8 @@ import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuil import { readFileSync } from "fs"; import DefaultValues from "../constants/DefaultValues"; import EmbedColours from "../constants/EmbedColours"; -import Server from "../entity/Server"; -import Setting from "../entity/Setting"; +import Server from "../database/entities/Server"; +import Setting from "../database/entities/Setting"; import { Command } from "../type/command"; export default class Config extends Command { @@ -124,7 +124,7 @@ export default class Config extends Command { private async ResetValue(interaction: CommandInteraction) { if (!interaction.guildId) return; - + const key = interaction.options.get('key'); if (!key || !key.value) { diff --git a/src/commands/ignore.ts b/src/commands/ignore.ts index 4a57d83..a93e801 100644 --- a/src/commands/ignore.ts +++ b/src/commands/ignore.ts @@ -1,5 +1,5 @@ import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; -import IgnoredChannel from "../entity/IgnoredChannel"; +import IgnoredChannel from "../database/entities/IgnoredChannel"; import { Command } from "../type/command"; export default class Ignore extends Command { diff --git a/src/commands/kick.ts b/src/commands/kick.ts index 6ddee0c..0008589 100644 --- a/src/commands/kick.ts +++ b/src/commands/kick.ts @@ -1,5 +1,5 @@ import { Command } from "../type/command"; -import Audit from "../entity/Audit"; +import Audit from "../database/entities/Audit"; import { AuditType } from "../constants/AuditType"; import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import EmbedColours from "../constants/EmbedColours"; @@ -54,7 +54,7 @@ export default class Kick extends Command { value: reason, }, ]); - + if (!member.kickable) { await interaction.reply('Insufficient permissions. Please contact a moderator.'); return; diff --git a/src/commands/mute.ts b/src/commands/mute.ts index d3b1493..137aace 100644 --- a/src/commands/mute.ts +++ b/src/commands/mute.ts @@ -1,7 +1,7 @@ import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { AuditType } from "../constants/AuditType"; import EmbedColours from "../constants/EmbedColours"; -import Audit from "../entity/Audit"; +import Audit from "../database/entities/Audit"; import SettingsHelper from "../helpers/SettingsHelper"; import { Command } from "../type/command"; diff --git a/src/commands/setup.ts b/src/commands/setup.ts index 6676ef8..5b1e3fc 100644 --- a/src/commands/setup.ts +++ b/src/commands/setup.ts @@ -1,5 +1,5 @@ import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; -import Server from "../entity/Server"; +import Server from "../database/entities/Server"; import { Command } from "../type/command"; export default class Setup extends Command { diff --git a/src/commands/warn.ts b/src/commands/warn.ts index 5a41985..5044912 100644 --- a/src/commands/warn.ts +++ b/src/commands/warn.ts @@ -1,7 +1,7 @@ import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { AuditType } from "../constants/AuditType"; import EmbedColours from "../constants/EmbedColours"; -import Audit from "../entity/Audit"; +import Audit from "../database/entities/Audit"; import SettingsHelper from "../helpers/SettingsHelper"; import { Command } from "../type/command"; diff --git a/src/contracts/BaseEntity.ts b/src/contracts/BaseEntity.ts index bb4d550..941ba6f 100644 --- a/src/contracts/BaseEntity.ts +++ b/src/contracts/BaseEntity.ts @@ -1,5 +1,6 @@ -import { Column, DeepPartial, EntityTarget, getConnection, PrimaryColumn, ObjectLiteral, FindOptionsWhere } from "typeorm"; +import { Column, DeepPartial, EntityTarget, PrimaryColumn, ObjectLiteral, FindOptionsWhere } from "typeorm"; import { v4 } from "uuid"; +import AppDataSource from "../database/dataSources/appDataSource"; export default class BaseEntity { constructor() { @@ -21,25 +22,19 @@ export default class BaseEntity { public async Save<T extends BaseEntity>(target: EntityTarget<T>, entity: DeepPartial<T>): Promise<void> { this.WhenUpdated = new Date(); - const connection = getConnection(); - - const repository = connection.getRepository<T>(target); + const repository = AppDataSource.getRepository<T>(target); await repository.save(entity); } public static async Remove<T extends BaseEntity>(target: EntityTarget<T>, entity: T): Promise<void> { - const connection = getConnection(); - - const repository = connection.getRepository<T>(target); + const repository = AppDataSource.getRepository<T>(target); await repository.remove(entity); } public static async FetchAll<T extends BaseEntity>(target: EntityTarget<T>, relations?: string[]): Promise<T[]> { - const connection = getConnection(); - - const repository = connection.getRepository<T>(target); + const repository = AppDataSource.getRepository<T>(target); const all = await repository.find({ relations: relations || [] }); @@ -47,9 +42,7 @@ export default class BaseEntity { } public static async FetchOneById<T extends BaseEntity>(target: EntityTarget<T>, id: string, relations?: string[]): Promise<T | null> { - const connection = getConnection(); - - const repository = connection.getRepository<T>(target); + const repository = AppDataSource.getRepository<T>(target); const single = await repository.findOne({ where: ({ Id: id } as FindOptionsWhere<T>), relations: relations || {} }); @@ -57,9 +50,7 @@ export default class BaseEntity { } public static async Any<T extends ObjectLiteral>(target: EntityTarget<T>): Promise<boolean> { - const connection = getConnection(); - - const repository = connection.getRepository<T>(target); + const repository = AppDataSource.getRepository<T>(target); const any = await repository.find(); diff --git a/src/database/dataSources/appDataSource.ts b/src/database/dataSources/appDataSource.ts new file mode 100644 index 0000000..89cd27f --- /dev/null +++ b/src/database/dataSources/appDataSource.ts @@ -0,0 +1,26 @@ +import { DataSource } from "typeorm"; +import * as dotenv from "dotenv"; + +dotenv.config(); + +const AppDataSource = new DataSource({ + type: "mysql", + host: process.env.DB_HOST, + port: Number(process.env.DB_PORT), + username: process.env.DB_AUTH_USER, + password: process.env.DB_AUTH_PASS, + database: process.env.DB_NAME, + synchronize: process.env.DB_SYNC == "true", + logging: process.env.DB_LOGGING == "true", + entities: [ + "dist/database/entities/**/*.js", + ], + migrations: [ + "dist/database/migrations/**/*.js", + ], + subscribers: [ + "dist/database/subscribers/**/*.js", + ], +}); + +export default AppDataSource; \ No newline at end of file diff --git a/src/entity/501231711271780357/Lobby.ts b/src/database/entities/501231711271780357/Lobby.ts similarity index 79% rename from src/entity/501231711271780357/Lobby.ts rename to src/database/entities/501231711271780357/Lobby.ts index b9f588b..95eafc8 100644 --- a/src/entity/501231711271780357/Lobby.ts +++ b/src/database/entities/501231711271780357/Lobby.ts @@ -1,5 +1,6 @@ -import { Column, Entity, getConnection } from "typeorm"; -import BaseEntity from "../../contracts/BaseEntity"; +import { Column, Entity } from "typeorm"; +import BaseEntity from "../../../contracts/BaseEntity"; +import AppDataSource from "../../dataSources/appDataSource"; @Entity() export default class Lobby extends BaseEntity { @@ -34,9 +35,7 @@ export default class Lobby extends BaseEntity { } public static async FetchOneByChannelId(channelId: string, relations?: string[]): Promise<Lobby | null> { - const connection = getConnection(); - - const repository = connection.getRepository(Lobby); + const repository = AppDataSource.getRepository(Lobby); const single = await repository.findOne({ where: { ChannelId: channelId }, relations: relations || [] }); diff --git a/src/entity/Audit.ts b/src/database/entities/Audit.ts similarity index 72% rename from src/entity/Audit.ts rename to src/database/entities/Audit.ts index 8577f0f..af4b1a5 100644 --- a/src/entity/Audit.ts +++ b/src/database/entities/Audit.ts @@ -1,7 +1,8 @@ -import { Column, Entity, getConnection } from "typeorm"; -import { AuditType } from "../constants/AuditType"; -import BaseEntity from "../contracts/BaseEntity"; -import StringTools from "../helpers/StringTools"; +import { Column, Entity } from "typeorm"; +import { AuditType } from "../../constants/AuditType"; +import BaseEntity from "../../contracts/BaseEntity"; +import StringTools from "../../helpers/StringTools"; +import AppDataSource from "../dataSources/appDataSource"; @Entity() export default class Audit extends BaseEntity { @@ -35,9 +36,7 @@ export default class Audit extends BaseEntity { ServerId: string; public static async FetchAuditsByUserId(userId: string, serverId: string): Promise<Audit[] | null> { - const connection = getConnection(); - - const repository = connection.getRepository(Audit); + const repository = AppDataSource.getRepository(Audit); const all = await repository.find({ where: { UserId: userId, ServerId: serverId } }); @@ -45,9 +44,7 @@ export default class Audit extends BaseEntity { } public static async FetchAuditByAuditId(auditId: string, serverId: string): Promise<Audit | null> { - const connection = getConnection(); - - const repository = connection.getRepository(Audit); + const repository = AppDataSource.getRepository(Audit); const single = await repository.findOne({ where: { AuditId: auditId, ServerId: serverId } }); diff --git a/src/entity/IgnoredChannel.ts b/src/database/entities/IgnoredChannel.ts similarity index 62% rename from src/entity/IgnoredChannel.ts rename to src/database/entities/IgnoredChannel.ts index ccb573c..7b40be7 100644 --- a/src/entity/IgnoredChannel.ts +++ b/src/database/entities/IgnoredChannel.ts @@ -1,5 +1,6 @@ -import { Entity, getConnection } from "typeorm"; -import BaseEntity from "../contracts/BaseEntity"; +import { Entity } from "typeorm"; +import BaseEntity from "../../contracts/BaseEntity"; +import AppDataSource from "../dataSources/appDataSource"; @Entity() export default class IgnoredChannel extends BaseEntity { @@ -10,9 +11,7 @@ export default class IgnoredChannel extends BaseEntity { } public static async IsChannelIgnored(channelId: string): Promise<boolean> { - const connection = getConnection(); - - const repository = connection.getRepository(IgnoredChannel); + const repository = AppDataSource.getRepository(IgnoredChannel); const single = await repository.findOne({ where: { Id: channelId } }); diff --git a/src/entity/Role.ts b/src/database/entities/Role.ts similarity index 72% rename from src/entity/Role.ts rename to src/database/entities/Role.ts index 8bbd0d2..6f83bf5 100644 --- a/src/entity/Role.ts +++ b/src/database/entities/Role.ts @@ -1,6 +1,7 @@ -import { Column, Entity, getConnection, ManyToOne } from "typeorm"; -import BaseEntity from "../contracts/BaseEntity" +import { Column, Entity, ManyToOne } from "typeorm"; +import BaseEntity from "../../contracts/BaseEntity" import Server from "./Server"; +import AppDataSource from "../dataSources/appDataSource"; @Entity() export default class Role extends BaseEntity { @@ -21,9 +22,7 @@ export default class Role extends BaseEntity { } public static async FetchOneByRoleId(roleId: string, relations?: string[]): Promise<Role | null> { - const connection = getConnection(); - - const repository = connection.getRepository(Role); + const repository = AppDataSource.getRepository(Role); const single = await repository.findOne({ where: { RoleId: roleId }, relations: relations || []}); @@ -31,9 +30,7 @@ export default class Role extends BaseEntity { } public static async FetchAllByServerId(serverId: string): Promise<Role[]> { - const connection = getConnection(); - - const repository = connection.getRepository(Server); + const repository = AppDataSource.getRepository(Server); const all = await repository.findOne({ where: { Id: serverId }, relations: [ "Roles", diff --git a/src/entity/Server.ts b/src/database/entities/Server.ts similarity index 91% rename from src/entity/Server.ts rename to src/database/entities/Server.ts index f669e58..211ea9c 100644 --- a/src/entity/Server.ts +++ b/src/database/entities/Server.ts @@ -1,5 +1,5 @@ import { Entity, OneToMany } from "typeorm"; -import BaseEntity from "../contracts/BaseEntity"; +import BaseEntity from "../../contracts/BaseEntity"; import Role from "./Role"; import Setting from "./Setting"; diff --git a/src/entity/Setting.ts b/src/database/entities/Setting.ts similarity index 75% rename from src/entity/Setting.ts rename to src/database/entities/Setting.ts index 813accf..e7b27d1 100644 --- a/src/entity/Setting.ts +++ b/src/database/entities/Setting.ts @@ -1,6 +1,7 @@ -import { Column, Entity, getConnection, ManyToOne } from "typeorm"; -import BaseEntity from "../contracts/BaseEntity"; +import { Column, Entity, ManyToOne } from "typeorm"; +import BaseEntity from "../../contracts/BaseEntity"; import Server from "./Server"; +import AppDataSource from "../dataSources/appDataSource"; @Entity() export default class Setting extends BaseEntity { @@ -26,9 +27,7 @@ export default class Setting extends BaseEntity { } public static async FetchOneByKey(key: string, relations?: string[]): Promise<Setting | null> { - const connection = getConnection(); - - const repository = connection.getRepository(Setting); + const repository = AppDataSource.getRepository(Setting); const single = await repository.findOne({ where: { Key: key }, relations: relations || {} }); diff --git a/src/migration/3.1/1662399171315-CreateBase.ts b/src/database/migrations/3.1/1662399171315-CreateBase.ts similarity index 92% rename from src/migration/3.1/1662399171315-CreateBase.ts rename to src/database/migrations/3.1/1662399171315-CreateBase.ts index cd4e696..b05aee7 100644 --- a/src/migration/3.1/1662399171315-CreateBase.ts +++ b/src/database/migrations/3.1/1662399171315-CreateBase.ts @@ -1,5 +1,5 @@ import { MigrationInterface, QueryRunner } from "typeorm" -import MigrationHelper from "../../helpers/MigrationHelper" +import MigrationHelper from "../../../helpers/MigrationHelper" export class vylbot1662399171315 implements MigrationInterface { diff --git a/src/events/MessageEvents/MessageDelete.ts b/src/events/MessageEvents/MessageDelete.ts index 8d0d40e..4bb9199 100644 --- a/src/events/MessageEvents/MessageDelete.ts +++ b/src/events/MessageEvents/MessageDelete.ts @@ -1,6 +1,6 @@ import { EmbedBuilder, Message, TextChannel } from "discord.js"; import EmbedColours from "../../constants/EmbedColours"; -import IgnoredChannel from "../../entity/IgnoredChannel"; +import IgnoredChannel from "../../database/entities/IgnoredChannel"; import SettingsHelper from "../../helpers/SettingsHelper"; export default async function MessageDelete(message: Message) { diff --git a/src/events/MessageEvents/MessageUpdate.ts b/src/events/MessageEvents/MessageUpdate.ts index 2ccd737..7564a2f 100644 --- a/src/events/MessageEvents/MessageUpdate.ts +++ b/src/events/MessageEvents/MessageUpdate.ts @@ -1,6 +1,6 @@ import { EmbedBuilder, Message, TextChannel } from "discord.js"; import EmbedColours from "../../constants/EmbedColours"; -import IgnoredChannel from "../../entity/IgnoredChannel"; +import IgnoredChannel from "../../database/entities/IgnoredChannel"; import SettingsHelper from "../../helpers/SettingsHelper"; export default async function MessageUpdate(oldMessage: Message, newMessage: Message) { diff --git a/src/helpers/SettingsHelper.ts b/src/helpers/SettingsHelper.ts index 1c6fd6a..66c92a8 100644 --- a/src/helpers/SettingsHelper.ts +++ b/src/helpers/SettingsHelper.ts @@ -1,6 +1,6 @@ import DefaultValues from "../constants/DefaultValues"; -import Server from "../entity/Server"; -import Setting from "../entity/Setting"; +import Server from "../database/entities/Server"; +import Setting from "../database/entities/Setting"; export default class SettingsHelper { public static async GetSetting(key: string, serverId: string): Promise<string | undefined> { diff --git a/src/vylbot.ts b/src/vylbot.ts index 16589c2..c1d2997 100644 --- a/src/vylbot.ts +++ b/src/vylbot.ts @@ -11,6 +11,12 @@ const requiredConfigs: string[] = [ "BOT_AUTHOR", "BOT_OWNERID", "BOT_CLIENTID", + "DB_HOST", + "DB_PORT", + "DB_AUTH_USER", + "DB_AUTH_PASS", + "DB_SYNC", + "DB_LOGGING", ]; requiredConfigs.forEach(config => { From 6c334cea81c735f25e5eebdc05c2887ae4b8dc78 Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 12 Jun 2023 17:19:58 +0100 Subject: [PATCH 45/56] Update dependency typeorm to v0.3.16 (#237) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [typeorm](https://typeorm.io) ([source](https://github.com/typeorm/typeorm)) | dependencies | patch | [`0.3.14` -> `0.3.16`](https://renovatebot.com/diffs/npm/typeorm/0.3.14/0.3.16) | --- ### Release Notes <details> <summary>typeorm/typeorm</summary> ### [`v0.3.16`](https://github.com/typeorm/typeorm/blob/HEAD/CHANGELOG.md#​0316-httpsgithubcomtypeormtypeormcompare03150316-2023-05-09) [Compare Source](https://github.com/typeorm/typeorm/compare/0.3.15...0.3.16) ##### Bug Fixes - add `trustServerCertificate` option to `SqlServerConnectionOptions` ([#​9985](https://github.com/typeorm/typeorm/issues/9985)) ([0305805](https://github.com/typeorm/typeorm/commit/03058055df78034a4544e52cfd277ed1c0cbdcb2)), closes [#​8093](https://github.com/typeorm/typeorm/issues/8093) - add directConnection options to MongoDB connection ([#​9955](https://github.com/typeorm/typeorm/issues/9955)) ([e0165e7](https://github.com/typeorm/typeorm/commit/e0165e75ee818c759b51a7fa3b0b3adc6befa347)) - add onDelete option validation for oracle ([#​9786](https://github.com/typeorm/typeorm/issues/9786)) ([938f94b](https://github.com/typeorm/typeorm/commit/938f94bded92b272bdcecc04534ffb879186dc44)), closes [#​9189](https://github.com/typeorm/typeorm/issues/9189) - added instanceName to options ([#​9968](https://github.com/typeorm/typeorm/issues/9968)) ([7c5627f](https://github.com/typeorm/typeorm/commit/7c5627f2728500bb45a2586a3bfd34ab39d46fad)) - added transaction retry logic in cockroachdb ([#​10032](https://github.com/typeorm/typeorm/issues/10032)) ([607d6f9](https://github.com/typeorm/typeorm/commit/607d6f959525b7c01bad5fe14364e4af82d878bb)) - allow json as alias for longtext mariadb ([#​10018](https://github.com/typeorm/typeorm/issues/10018)) ([2a2bb4b](https://github.com/typeorm/typeorm/commit/2a2bb4bdc11915966a65dc144189b33d410d9d57)) - convert the join table ID to the referenceColumn ID type ([#​9887](https://github.com/typeorm/typeorm/issues/9887)) ([9460296](https://github.com/typeorm/typeorm/commit/9460296147b8117e414ca311828615d87f5ab283)) - correct encode mongodb auth credentials ([#​10024](https://github.com/typeorm/typeorm/issues/10024)) ([96b7ee4](https://github.com/typeorm/typeorm/commit/96b7ee44b2538f65c77c7d168e4f10316cc123fa)), closes [#​9885](https://github.com/typeorm/typeorm/issues/9885) - create correct children during cascade saving entities with STI ([#​9034](https://github.com/typeorm/typeorm/issues/9034)) ([06c1e98](https://github.com/typeorm/typeorm/commit/06c1e98ae20cf516f4f5afc53fec4df91209f121)), closes [#​7758](https://github.com/typeorm/typeorm/issues/7758) [#​7758](https://github.com/typeorm/typeorm/issues/7758) [#​9033](https://github.com/typeorm/typeorm/issues/9033) [#​9033](https://github.com/typeorm/typeorm/issues/9033) [#​7758](https://github.com/typeorm/typeorm/issues/7758) [#​7758](https://github.com/typeorm/typeorm/issues/7758) - express option bug in init command ([#​10022](https://github.com/typeorm/typeorm/issues/10022)) ([5be20e2](https://github.com/typeorm/typeorm/commit/5be20e2bcd18431e457090a63a99dc06f9c2d3d2)) - for running cli-ts-node-esm use exit code from child process ([#​10030](https://github.com/typeorm/typeorm/issues/10030)) ([a188b1d](https://github.com/typeorm/typeorm/commit/a188b1d9f4cc0bdc36a30be1380104e5f38ccb24)), closes [#​10029](https://github.com/typeorm/typeorm/issues/10029) - mongodb typings breaks the browser version ([#​9962](https://github.com/typeorm/typeorm/issues/9962)) ([99bef49](https://github.com/typeorm/typeorm/commit/99bef491280aedb6b337a14e6723b33e67b048d0)), closes [#​9959](https://github.com/typeorm/typeorm/issues/9959) - RelationIdLoader has access to queryPlanner when wrapped in transaction ([#​9990](https://github.com/typeorm/typeorm/issues/9990)) ([21a9d67](https://github.com/typeorm/typeorm/commit/21a9d67fcf294e805c416d55394d55b238860b7d)), closes [#​9988](https://github.com/typeorm/typeorm/issues/9988) - resolve duplicate subscriber updated columns ([#​9958](https://github.com/typeorm/typeorm/issues/9958)) ([3d67901](https://github.com/typeorm/typeorm/commit/3d67901fde2750a8c10521bedc3eee3d57065b43)), closes [#​9948](https://github.com/typeorm/typeorm/issues/9948) - select + addOrderBy broke in 0.3.14 ([#​9961](https://github.com/typeorm/typeorm/issues/9961)) ([0e56f0f](https://github.com/typeorm/typeorm/commit/0e56f0fcf8ec3f2ec37fee92f75ba09262801655)), closes [#​9960](https://github.com/typeorm/typeorm/issues/9960) - support More/LessThanOrEqual in relations ([#​9978](https://github.com/typeorm/typeorm/issues/9978)) ([8795c86](https://github.com/typeorm/typeorm/commit/8795c864e835a875e78577b5737da42d78e19247)) ##### Features - mariadb uuid inet4 inet6 column data type support ([#​9845](https://github.com/typeorm/typeorm/issues/9845)) ([d8a2e37](https://github.com/typeorm/typeorm/commit/d8a2e3730f12bb2b8e521635e176a284594121f3)) ##### Reverts - "refactor: remove date-fns package ([#​9634](https://github.com/typeorm/typeorm/issues/9634))" ([54f4f89](https://github.com/typeorm/typeorm/commit/54f4f8986adf197eb96ec0bc6d9d5a44d6552bcc)) ### [`v0.3.15`](https://github.com/typeorm/typeorm/blob/HEAD/CHANGELOG.md#​0315-httpsgithubcomtypeormtypeormcompare03140315-2023-04-15) [Compare Source](https://github.com/typeorm/typeorm/compare/0.3.14...0.3.15) ##### Bug Fixes - make cache optional fields optional ([#​9942](https://github.com/typeorm/typeorm/issues/9942)) ([159c60a](https://github.com/typeorm/typeorm/commit/159c60a6e8cedbd32766fdca9694ec28cde9f6f7)) - prevent unique index identical to primary key (all sql dialects) ([#​9940](https://github.com/typeorm/typeorm/issues/9940)) ([51eecc2](https://github.com/typeorm/typeorm/commit/51eecc2aa07bfe3cfdd649fefadea3d719436d5e)) - SelectQueryBuilder builds incorrectly escaped alias in Oracle when used on entity with composite key ([#​9668](https://github.com/typeorm/typeorm/issues/9668)) ([83c6c0e](https://github.com/typeorm/typeorm/commit/83c6c0ed803f72c872fa40a740eb6fabe2102cbb)) ##### Features - support for the latest mongodb v5 ([#​9925](https://github.com/typeorm/typeorm/issues/9925)) ([f6a3ce7](https://github.com/typeorm/typeorm/commit/f6a3ce732d86fd01807fc13c049ab51df785d772)), closes [#​7907](https://github.com/typeorm/typeorm/issues/7907) [#​7907](https://github.com/typeorm/typeorm/issues/7907) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/237 Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 28 ++++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index bf99a86..988a97d 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "mysql": "^2.18.1", "random-bunny": "^2.0.5", "ts-jest": "^29.0.0", - "typeorm": "0.3.14" + "typeorm": "0.3.16" }, "devDependencies": { "@types/node": "^20.0.0", diff --git a/yarn.lock b/yarn.lock index db16c26..617ce5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -260,6 +260,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.20.2" +"@babel/runtime@^7.21.0": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" + integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/template@^7.20.7", "@babel/template@^7.3.3": version "7.20.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" @@ -1152,6 +1159,13 @@ cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +date-fns@^2.29.3: + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" + debug@^4.1.0, debug@^4.1.1, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -2434,6 +2448,11 @@ reflect-metadata@^0.1.13: resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -2743,16 +2762,17 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typeorm@0.3.14: - version "0.3.14" - resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.14.tgz#d46bc685aa92d0caf910849f22753ef319822327" - integrity sha512-tEPEN8qmA2a2wmjkaDcWBZ6LsECHofJW2vaCQMklYs+4JRJMAJ5FfbPIWMbhJ3ANJGMtLAmU1GfC8rLFIpbWsg== +typeorm@0.3.16: + version "0.3.16" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.16.tgz#a001d77b36cfaaf9ff495e15805dd17883116b7b" + integrity sha512-wJ4Qy1oqRKNDdZiBTTaVMqwo/XxC52Q7uNPTjltPgLhvIW173bL6Iad0lhptMOsFlpixFPaUu3PNziaRBwX2Zw== dependencies: "@sqltools/formatter" "^1.2.5" app-root-path "^3.1.0" buffer "^6.0.3" chalk "^4.1.2" cli-highlight "^2.1.11" + date-fns "^2.29.3" debug "^4.3.4" dotenv "^16.0.3" glob "^8.1.0" From 3f34ff15dd7fdcef1379498ef35b5470a4354d2c Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 16 Jun 2023 17:56:37 +0100 Subject: [PATCH 46/56] Add licence (#304) - Add licence file #249 Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/304 --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5b5a4b9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Vylpes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 46226d37a72ce8e09d57a987d92b4a81ed3ef08e Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 16 Jun 2023 17:58:49 +0100 Subject: [PATCH 47/56] Add PR and Issue templates (#303) - Add PR and Issue templates #250 Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/303 --- .gitea/ISSUE_TEMPLATE.md | 18 ++++++++++++++++++ .gitea/PULL_REQUEST_TEMPLATE.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 .gitea/ISSUE_TEMPLATE.md create mode 100644 .gitea/PULL_REQUEST_TEMPLATE.md diff --git a/.gitea/ISSUE_TEMPLATE.md b/.gitea/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..090d6b3 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE.md @@ -0,0 +1,18 @@ +Epic: \ +Story Points: + +--- + +*No description* + +## Acceptance Criteria + +*No acceptance criteria* + +## Subtasks + +*No subtasks* + +## Notes + +*No notes* \ No newline at end of file diff --git a/.gitea/PULL_REQUEST_TEMPLATE.md b/.gitea/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..698d07e --- /dev/null +++ b/.gitea/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,29 @@ +# Description + +Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. + +Fixes # (issue) + +## Type of change + +Please delete options that are not relevant. + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +# How Has This Been Tested? + +Please describe the tests that you ran to verify the changes. Provide instructions so we can reproduce. Please also list any relevant details to your test configuration. + +# Checklist + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that provde my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes +- [ ] Any dependent changes have been merged and published in downstream modules \ No newline at end of file From 4f2c1862443915f0dedb584d11d790d241fe887a Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 16 Jun 2023 18:01:45 +0100 Subject: [PATCH 48/56] Create timeout command (#302) - Create timeout command #98 Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/302 --- src/commands/timeout.ts | 151 +++++++ src/constants/AuditType.ts | 1 + src/helpers/AuditTools.ts | 4 + src/helpers/TimeLengthInput.ts | 119 ++++++ src/registry.ts | 6 +- tests/commands/timeout.test.ts | 729 +++++++++++++++++++++++++++++++++ yarn.lock | 35 +- 7 files changed, 1036 insertions(+), 9 deletions(-) create mode 100644 src/commands/timeout.ts create mode 100644 src/helpers/TimeLengthInput.ts create mode 100644 tests/commands/timeout.test.ts diff --git a/src/commands/timeout.ts b/src/commands/timeout.ts new file mode 100644 index 0000000..65e3ba0 --- /dev/null +++ b/src/commands/timeout.ts @@ -0,0 +1,151 @@ +import { CacheType, CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; +import { AuditType } from "../constants/AuditType"; +import EmbedColours from "../constants/EmbedColours"; +import Audit from "../database/entities/Audit"; +import SettingsHelper from "../helpers/SettingsHelper"; +import TimeLengthInput from "../helpers/TimeLengthInput"; +import { Command } from "../type/command"; + +export default class Timeout extends Command { + constructor() { + super(); + + super.CommandBuilder = new SlashCommandBuilder() + .setName("timeout") + .setDescription("Timeouts a user out, sending them a DM with the reason if possible") + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) + .addUserOption(option => + option + .setName('target') + .setDescription('The user') + .setRequired(true)) + .addStringOption(option => + option + .setName("length") + .setDescription("How long to timeout for? (Example: 24h, 60m)") + .setRequired(true)) + .addStringOption(option => + option + .setName('reason') + .setDescription('The reason')); + } + + public override async execute(interaction: CommandInteraction<CacheType>) { + if (!interaction.guild || !interaction.guildId) return; + + // Interaction Inputs + const targetUser = interaction.options.get('target'); + const lengthInput = interaction.options.get('length'); + const reasonInput = interaction.options.get('reason'); + + // Validation + if (!targetUser || !targetUser.user || !targetUser.member) { + await interaction.reply('Fields are required.'); + return; + } + + if (!lengthInput || !lengthInput.value) { + await interaction.reply('Fields are required.'); + return; + } + + // General Variables + const targetMember = targetUser.member as GuildMember; + const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : null; + + const timeLength = new TimeLengthInput(lengthInput.value.toString()); + + const logEmbed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Member Timed Out") + .setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``) + .addFields([ + { + name: "Moderator", + value: `<@${interaction.user.id}>`, + }, + { + name: "Reason", + value: reason || "*none*", + }, + { + name: "Length", + value: timeLength.GetLengthShort(), + }, + { + name: "Until", + value: timeLength.GetDateFromNow().toString(), + }, + ]); + + // Bot Permissions Check + if (!targetMember.manageable) { + await interaction.reply('Insufficient bot permissions. Please contact a moderator.'); + return; + } + + // Execute Timeout + await targetMember.timeout(timeLength.GetMilliseconds(), reason || ""); + + // Log Embed To Channel + const channelName = await SettingsHelper.GetSetting('channels.logs.mod', interaction.guildId); + + if (!channelName) return; + + const channel = interaction.guild.channels.cache.find(x => x.name == channelName) as TextChannel; + + if (channel) { + await channel.send({ embeds: [ logEmbed ]}); + } + + // Create Audit + const audit = new Audit(targetUser.user.id, AuditType.Timeout, reason || "*none*", interaction.user.id, interaction.guildId); + await audit.Save(Audit, audit); + + // DM User, if possible + const resultEmbed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setDescription(`<@${targetUser.user.id}> has been timed out`); + + const dmEmbed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setDescription(`You have been timed out in ${interaction.guild.name}`) + .addFields([ + { + name: "Reason", + value: reason || "*none*" + }, + { + name: "Length", + value: timeLength.GetLengthShort(), + }, + { + name: "Until", + value: timeLength.GetDateFromNow().toString(), + }, + ]); + + try { + const dmChannel = await targetUser.user.createDM(); + + await dmChannel.send({ embeds: [ dmEmbed ]}); + + resultEmbed.addFields([ + { + name: "DM Sent", + value: "true", + }, + ]); + } catch { + resultEmbed.addFields([ + { + name: "DM Sent", + value: "false", + }, + ]); + } + + // Success Reply + await interaction.reply({ embeds: [ resultEmbed ]}); + } +} \ No newline at end of file diff --git a/src/constants/AuditType.ts b/src/constants/AuditType.ts index 4ad8df6..0fd7325 100644 --- a/src/constants/AuditType.ts +++ b/src/constants/AuditType.ts @@ -4,4 +4,5 @@ export enum AuditType { Mute, Kick, Ban, + Timeout, } \ No newline at end of file diff --git a/src/helpers/AuditTools.ts b/src/helpers/AuditTools.ts index fa06c43..9833a3c 100644 --- a/src/helpers/AuditTools.ts +++ b/src/helpers/AuditTools.ts @@ -13,6 +13,8 @@ export default class AuditTools { return "Kick"; case AuditType.Ban: return "Ban"; + case AuditType.Timeout: + return "Timeout"; default: return "Other"; } @@ -30,6 +32,8 @@ export default class AuditTools { return AuditType.Kick; case "ban": return AuditType.Ban; + case "timeout": + return AuditType.Timeout; default: return AuditType.General; } diff --git a/src/helpers/TimeLengthInput.ts b/src/helpers/TimeLengthInput.ts new file mode 100644 index 0000000..7c167d2 --- /dev/null +++ b/src/helpers/TimeLengthInput.ts @@ -0,0 +1,119 @@ +export default class TimeLengthInput { + public readonly value: string; + + constructor(input: string) { + this.value = input; + } + + public GetDays(): number { + return this.GetValue('d'); + } + + public GetHours(): number { + return this.GetValue('h'); + } + + public GetMinutes(): number { + return this.GetValue('m'); + } + + public GetSeconds(): number { + return this.GetValue('s'); + } + + public GetMilliseconds(): number { + const days = this.GetDays(); + const hours = this.GetHours(); + const minutes = this.GetMinutes(); + const seconds = this.GetSeconds(); + + let milliseconds = 0; + + milliseconds += seconds * 1000; + milliseconds += minutes * 60 * 1000; + milliseconds += hours * 60 * 60 * 1000; + milliseconds += days * 24 * 60 * 60 * 1000; + + return milliseconds; + } + + public GetDateFromNow(): Date { + const now = Date.now(); + + const dateFromNow = now + + (1000 * this.GetSeconds()) + + (1000 * 60 * this.GetMinutes()) + + (1000 * 60 * 60 * this.GetHours()) + + (1000 * 60 * 60 * 24 * this.GetDays()); + + return new Date(dateFromNow); + } + + public GetLength(): string { + const days = this.GetDays(); + const hours = this.GetHours(); + const minutes = this.GetMinutes(); + const seconds = this.GetSeconds(); + + const value = []; + + if (days) { + value.push(`${days} days`); + } + + if (hours) { + value.push(`${hours} hours`); + } + + if (minutes) { + value.push(`${minutes} minutes`); + } + + if (seconds) { + value.push(`${seconds} seconds`); + } + + return value.join(", "); + } + + public GetLengthShort(): string { + const days = this.GetDays(); + const hours = this.GetHours(); + const minutes = this.GetMinutes(); + const seconds = this.GetSeconds(); + + const value = []; + + if (days) { + value.push(`${days}d`); + } + + if (hours) { + value.push(`${hours}h`); + } + + if (minutes) { + value.push(`${minutes}m`); + } + + if (seconds) { + value.push(`${seconds}s`); + } + + return value.join(" "); + } + + private GetValue(designation: string): number { + const valueSplit = this.value.split(' '); + + const desString = valueSplit.find(x => x.charAt(x.length - 1) == designation); + + if (!desString) return 0; + + const desNumber = Number(desString.substring(0, desString.length - 1)); + + if (!desNumber) return 0; + + return desNumber; + } +} \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index a86ce96..50beeab 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -17,6 +17,7 @@ import Role from "./commands/Role/role"; import ConfigRole from "./commands/Role/config"; import Rules from "./commands/rules"; import Setup from "./commands/setup"; +import Timeout from "./commands/timeout"; import Unmute from "./commands/unmute"; import Warn from "./commands/warn"; @@ -38,6 +39,7 @@ import MessageCreate from "./events/MessageEvents/MessageCreate"; export default class Registry { public static RegisterCommands() { CoreClient.RegisterCommand("about", new About()); + CoreClient.RegisterCommand("audits", new Audits()); CoreClient.RegisterCommand("ban", new Ban()); CoreClient.RegisterCommand("bunny", new Bunny()); CoreClient.RegisterCommand("clear", new Clear()); @@ -48,10 +50,10 @@ export default class Registry { CoreClient.RegisterCommand("kick", new Kick()); CoreClient.RegisterCommand("mute", new Mute()); CoreClient.RegisterCommand("rules", new Rules()); + CoreClient.RegisterCommand("setup", new Setup()); + CoreClient.RegisterCommand("timeout", new Timeout()); CoreClient.RegisterCommand("unmute", new Unmute()); CoreClient.RegisterCommand("warn", new Warn()); - CoreClient.RegisterCommand("setup", new Setup()); - CoreClient.RegisterCommand("audits", new Audits()); CoreClient.RegisterCommand("role", new Role()); CoreClient.RegisterCommand("configrole", new ConfigRole()); diff --git a/tests/commands/timeout.test.ts b/tests/commands/timeout.test.ts new file mode 100644 index 0000000..c64ceb5 --- /dev/null +++ b/tests/commands/timeout.test.ts @@ -0,0 +1,729 @@ +import { APIEmbed, CacheType, CommandInteraction, CommandInteractionOption, DMChannel, Embed, EmbedBuilder, EmbedField, Guild, GuildChannel, GuildMember, InteractionReplyOptions, JSONEncodable, Message, MessageCreateOptions, MessagePayload, SlashCommandBuilder, TextChannel, User } from "discord.js"; +import { mock } from "jest-mock-extended"; +import Timeout from "../../src/commands/timeout"; +import SettingsHelper from "../../src/helpers/SettingsHelper"; +import Audit from "../../src/database/entities/Audit"; +import EmbedColours from "../../src/constants/EmbedColours"; +import { DeepPartial, EntityTarget } from "typeorm"; +import BaseEntity from "../../src/contracts/BaseEntity"; +import { AuditType } from "../../src/constants/AuditType"; + +describe('Constructor', () => { + test('EXPECT CommandBuilder to be configured', () => { + const command = new Timeout(); + + expect(command.CommandBuilder).toBeDefined(); + + const commandBuilder = command.CommandBuilder as SlashCommandBuilder; + + expect(commandBuilder.name).toBe("timeout"); + expect(commandBuilder.description).toBe("Timeouts a user out, sending them a DM with the reason if possible"); + expect(commandBuilder.options.length).toBe(3); + }); +}); + +describe('execute', () => { + // Happy flow + test('GIVEN all checks have passed, EXPECT user to be timed out', async () => { + let embeds: APIEmbed[] | undefined; + + const command = new Timeout(); + + const interactionReply = jest.fn((options: InteractionReplyOptions) => { + embeds = options.embeds as APIEmbed[]; + }); + + let savedAudit: DeepPartial<Audit> | undefined; + + const getSetting = jest.spyOn(SettingsHelper, 'GetSetting').mockResolvedValue('mod-logs'); + const auditSave = jest.spyOn(Audit.prototype, 'Save').mockImplementation((target: EntityTarget<BaseEntity>, entity: DeepPartial<BaseEntity>): Promise<void> => { + savedAudit = entity; + + return Promise.resolve(); + }); + + const timeoutFunc = jest.fn(); + + let dmChannelSentEmbeds: (APIEmbed | JSONEncodable<APIEmbed>)[] | undefined; + let logsChannelSentEmbeds: (APIEmbed | JSONEncodable<APIEmbed>)[] | undefined; + + const dmChannel = { + send: jest.fn().mockImplementation((options: MessageCreateOptions) => { + dmChannelSentEmbeds = options.embeds; + }), + } as unknown as DMChannel; + + const userInput = { + user: { + id: 'userId', + tag: 'userTag', + createDM: jest.fn().mockResolvedValue(dmChannel), + } as unknown as User, + member: { + manageable: true, + timeout: timeoutFunc, + } as unknown as GuildMember, + } as CommandInteractionOption; + + const lengthInput = { + value: '1s', + } as CommandInteractionOption; + + const reasonInput = { + value: 'Test reason', + } as CommandInteractionOption; + + const logsChannel = { + name: 'mod-logs', + send: jest.fn().mockImplementation((options: MessageCreateOptions) => { + logsChannelSentEmbeds = options.embeds; + }), + } as unknown as TextChannel; + + const interaction = { + guild: { + channels: { + cache: { + find: jest.fn() + .mockReturnValue(logsChannel), + } + }, + name: "Test Guild", + } as unknown as Guild, + guildId: 'guildId', + reply: interactionReply, + options: { + get: jest.fn() + .mockReturnValueOnce(userInput) + .mockReturnValueOnce(lengthInput) + .mockReturnValue(reasonInput), + }, + user: { + id: 'moderatorId' + } + } as unknown as CommandInteraction; + + await command.execute(interaction); + + // EXPECT user to be timed out + expect(timeoutFunc).toBeCalledWith(1000, 'Test reason'); + + // EXPECT embeds to be sent + expect(embeds).toBeDefined(); + expect(embeds!.length).toBe(1); + + // EXPECT resultEmbed to be correctly configured + const resultEmbed = embeds![0] as EmbedBuilder; + + expect(resultEmbed.data.description).toBe('<@userId> has been timed out'); + expect(resultEmbed.data.fields).toBeDefined(); + expect(resultEmbed.data.fields!.length).toBe(1); + + // EXPECT DM field to be configured + const resultEmbedDMField = resultEmbed.data.fields![0]; + + expect(resultEmbedDMField.name).toBe("DM Sent"); + expect(resultEmbedDMField.value).toBe("true"); + + // EXPECT user to be DM's with embed + expect(dmChannel.send).toBeCalled(); + expect(dmChannelSentEmbeds).toBeDefined(); + expect(dmChannelSentEmbeds?.length).toBe(1); + + const dmChannelSentEmbed = (dmChannelSentEmbeds![0] as any).data; + + expect(dmChannelSentEmbed.color).toBe(EmbedColours.Ok); + expect(dmChannelSentEmbed.description).toBe("You have been timed out in Test Guild"); + expect(dmChannelSentEmbed.fields?.length).toBe(3); + + expect(dmChannelSentEmbed.fields![0].name).toBe("Reason"); + expect(dmChannelSentEmbed.fields![0].value).toBe("Test reason"); + + expect(dmChannelSentEmbed.fields![1].name).toBe("Length"); + expect(dmChannelSentEmbed.fields![1].value).toBe("1s"); + + expect(dmChannelSentEmbed.fields![2].name).toBe("Until"); + expect(dmChannelSentEmbed.fields![2].value).toBeDefined(); + + // EXPECT log embed to be sent + expect(logsChannel.send).toBeCalled(); + expect(logsChannelSentEmbeds).toBeDefined(); + expect(logsChannelSentEmbeds?.length).toBe(1); + + const logsChannelSentEmbed = (logsChannelSentEmbeds![0] as any).data; + + expect(logsChannelSentEmbed.color).toBe(EmbedColours.Ok); + expect(logsChannelSentEmbed.title).toBe("Member Timed Out"); + expect(logsChannelSentEmbed.description).toBe("<@userId> `userTag`"); + expect(logsChannelSentEmbed.fields?.length).toBe(4); + + expect(logsChannelSentEmbed.fields![0].name).toBe("Moderator"); + expect(logsChannelSentEmbed.fields![0].value).toBe("<@moderatorId>"); + + expect(logsChannelSentEmbed.fields![1].name).toBe("Reason"); + expect(logsChannelSentEmbed.fields![1].value).toBe("Test reason"); + + expect(logsChannelSentEmbed.fields![2].name).toBe("Length"); + expect(logsChannelSentEmbed.fields![2].value).toBe("1s"); + + expect(logsChannelSentEmbed.fields![3].name).toBe("Until"); + expect(logsChannelSentEmbed.fields![3].value).toBeDefined(); + + // EXPECT Audit to be saved + expect(auditSave).toBeCalled(); + + expect(savedAudit).toBeDefined(); + expect(savedAudit?.UserId).toBe('userId'); + expect(savedAudit?.AuditType).toBe(AuditType.Timeout); + expect(savedAudit?.Reason).toBe("Test reason"); + expect(savedAudit?.ModeratorId).toBe('moderatorId'); + expect(savedAudit?.ServerId).toBe('guildId'); + }); + + // Null checks + test('GIVEN interaction.guild IS NULL, EXPECT nothing to happen', async () => { + const command = new Timeout(); + + const interaction = { + guild: null, + reply: jest.fn(), + } as unknown as CommandInteraction; + + await command.execute(interaction); + + expect(interaction.reply).not.toBeCalled(); + }); + + test('GIVEN interaction.guildId IS NULL, EXPECT nothing to happen', async () => { + const command = new Timeout(); + + const interaction = { + guild: mock<Guild>(), + guildId: null, + reply: jest.fn(), + } as unknown as CommandInteraction; + + await command.execute(interaction); + + expect(interaction.reply).not.toBeCalled(); + }); + + // Validation + test('GIVEN targetUser IS NULL, EXPECT validation error', async () => { + const command = new Timeout(); + + const interaction = { + reply: jest.fn(), + guild: mock<Guild>(), + guildId: 'guildId', + options: { + get: jest.fn().mockReturnValue(undefined), + } + } as unknown as CommandInteraction; + + await command.execute(interaction); + + expect(interaction.reply).toBeCalledWith('Fields are required.'); + }); + + test('GIVEN targetUser.user IS NULL, EXPECT validation error', async () => { + const command = new Timeout(); + + const interaction = { + reply: jest.fn(), + guild: mock<Guild>(), + guildId: 'guildId', + options: { + get: jest.fn((value: string): CommandInteractionOption<CacheType> | null => { + switch (value) { + case 'target': + return {} as CommandInteractionOption; + case 'length': + return { + value: '1m', + } as CommandInteractionOption; + case 'reason': + return { + value: 'Test reason', + } as CommandInteractionOption; + default: + return null; + } + }), + } + } as unknown as CommandInteraction; + + await command.execute(interaction); + + expect(interaction.reply).toBeCalledWith('Fields are required.'); + }); + + test('GIVEN targetUser.member IS NULL, EXPECT validation error', async () => { + const command = new Timeout(); + + const interaction = { + reply: jest.fn(), + guild: mock<Guild>(), + guildId: 'guildId', + options: { + get: jest.fn((value: string): CommandInteractionOption<CacheType> | null => { + switch (value) { + case 'target': + return { + user: {} as User, + } as CommandInteractionOption; + case 'length': + return { + value: '1m', + } as CommandInteractionOption; + case 'reason': + return { + value: 'Test reason', + } as CommandInteractionOption; + default: + return null; + } + }), + } + } as unknown as CommandInteraction; + + await command.execute(interaction); + + expect(interaction.reply).toBeCalledWith('Fields are required.'); + }); + + test('GIVEN lengthInput IS NULL, EXPECT validation error', async () => { + const command = new Timeout(); + + const interaction = { + reply: jest.fn(), + guild: mock<Guild>(), + guildId: 'guildId', + options: { + get: jest.fn((value: string): CommandInteractionOption<CacheType> | null => { + switch (value) { + case 'target': + return { + user: {} as User, + member: {} as GuildMember + } as CommandInteractionOption; + case 'length': + return null; + case 'reason': + return { + value: 'Test reason', + } as CommandInteractionOption; + default: + return null; + } + }), + } + } as unknown as CommandInteraction; + + await command.execute(interaction); + + expect(interaction.reply).toBeCalledWith('Fields are required.'); + }); + + test('GIVEN lengthInput.value IS NULL, EXPECT validation error', async () => { + const command = new Timeout(); + + const interaction = { + reply: jest.fn(), + guild: mock<Guild>(), + guildId: 'guildId', + options: { + get: jest.fn((value: string): CommandInteractionOption<CacheType> | null => { + switch (value) { + case 'target': + return { + user: {} as User, + member: {} as GuildMember + } as CommandInteractionOption; + case 'length': + return { + value: undefined, + } as CommandInteractionOption; + case 'reason': + return { + value: 'Test reason', + } as CommandInteractionOption; + default: + return null; + } + }), + } + } as unknown as CommandInteraction; + + await command.execute(interaction); + + expect(interaction.reply).toBeCalledWith('Fields are required.'); + }); + + test('GIVEN targetMember IS NOT manageable by the bot, EXPECT insufficient permissions error', async () => { + const command = new Timeout(); + + const interaction = { + reply: jest.fn(), + guild: mock<Guild>(), + guildId: 'guildId', + user: { + id: 'moderatorId', + }, + options: { + get: jest.fn((value: string): CommandInteractionOption<CacheType> | null => { + switch (value) { + case 'target': + return { + user: { + id: 'userId', + tag: 'userTag', + } as User, + member: { + manageable: false, + } as GuildMember + } as CommandInteractionOption; + case 'length': + return { + value: '1m', + } as CommandInteractionOption; + case 'reason': + return { + value: 'Test reason', + } as CommandInteractionOption; + default: + return null; + } + }), + } + } as unknown as CommandInteraction; + + await command.execute(interaction); + + expect(interaction.reply).toBeCalledWith('Insufficient bot permissions. Please contact a moderator.'); + }); + + // Reason variable + test('GIVEN reason IS NULL, EXPECT to be ran with empty string', async () => { + const command = new Timeout(); + + let savedAudit: DeepPartial<Audit> | undefined; + + const auditSave = jest.spyOn(Audit.prototype, 'Save').mockImplementation((target: EntityTarget<BaseEntity>, entity: DeepPartial<BaseEntity>): Promise<void> => { + savedAudit = entity; + + return Promise.resolve(); + }); + + const timeoutFunc = jest.fn(); + + const sentEmbeds: EmbedBuilder[] = []; + + const interaction = { + reply: jest.fn(), + guild: { + channels: { + cache: { + find: jest.fn().mockReturnValue(mock<TextChannel>()), + } + } + }, + guildId: 'guildId', + user: { + id: 'moderatorId', + }, + options: { + get: jest.fn((value: string): CommandInteractionOption<CacheType> | null => { + switch (value) { + case 'target': + return { + user: { + id: 'userId', + tag: 'userTag', + createDM: jest.fn().mockReturnValue({ + send: jest.fn(async (options: MessageCreateOptions): Promise<Message<false>> => { + sentEmbeds.push(options.embeds![0] as EmbedBuilder); + + return mock<Message<false>>(); + }) + }) as unknown as DMChannel, + } as unknown as User, + member: { + manageable: true, + timeout: timeoutFunc, + } as unknown as GuildMember + } as CommandInteractionOption; + case 'length': + return { + value: '1m' + } as CommandInteractionOption; + case 'reason': + return { + value: undefined, + } as CommandInteractionOption; + default: + return null; + } + }), + } + } as unknown as CommandInteraction; + + + await command.execute(interaction); + + expect(timeoutFunc).toBeCalledWith(1000 * 60 * 1, ""); + expect(savedAudit?.Reason).toBe("*none*"); + + const dmEmbed = (sentEmbeds[0] as any).data; + const dmEmbedReasonField = dmEmbed.fields![0] as EmbedField; + + expect(dmEmbedReasonField.value).toBe("*none*"); + }); + + // Log embed + test('GIVEN channelName IS NULL, EXPECT execution to return', async () => { + const command = new Timeout(); + + let savedAudit: DeepPartial<Audit> | undefined; + + const auditSave = jest.spyOn(Audit.prototype, 'Save').mockImplementation((target: EntityTarget<BaseEntity>, entity: DeepPartial<BaseEntity>): Promise<void> => { + savedAudit = entity; + + return Promise.resolve(); + }); + + const settingsGet = jest.spyOn(SettingsHelper, 'GetSetting').mockResolvedValue(undefined); + + const timeoutFunc = jest.fn(); + + const sentEmbeds: EmbedBuilder[] = []; + + const logChannelSendFunc = jest.fn(); + + const interaction = { + reply: jest.fn(), + guild: { + channels: { + cache: { + find: jest.fn().mockReturnValue({ + send: logChannelSendFunc, + } as unknown as TextChannel), + } + } + }, + guildId: 'guildId', + user: { + id: 'moderatorId', + }, + options: { + get: jest.fn((value: string): CommandInteractionOption<CacheType> | null => { + switch (value) { + case 'target': + return { + user: { + id: 'userId', + tag: 'userTag', + createDM: jest.fn().mockReturnValue({ + send: jest.fn(async (options: MessageCreateOptions): Promise<Message<false>> => { + sentEmbeds.push(options.embeds![0] as EmbedBuilder); + + return mock<Message<false>>(); + }) + }) as unknown as DMChannel, + } as unknown as User, + member: { + manageable: true, + timeout: timeoutFunc, + } as unknown as GuildMember + } as CommandInteractionOption; + case 'length': + return { + value: '1m' + } as CommandInteractionOption; + case 'reason': + return { + value: 'Test reason', + } as CommandInteractionOption; + default: + return null; + } + }), + } + } as unknown as CommandInteraction; + + + await command.execute(interaction); + + expect(timeoutFunc).toBeCalled(); + expect(sentEmbeds.length).toBe(0); + expect(logChannelSendFunc).not.toBeCalled(); + }); + + test('GIVEN channel IS NULL, EXPECT embed to not be sent', async () => { + const command = new Timeout(); + + let savedAudit: DeepPartial<Audit> | undefined; + + const auditSave = jest.spyOn(Audit.prototype, 'Save').mockImplementation((target: EntityTarget<BaseEntity>, entity: DeepPartial<BaseEntity>): Promise<void> => { + savedAudit = entity; + + return Promise.resolve(); + }); + + const settingsGet = jest.spyOn(SettingsHelper, 'GetSetting').mockResolvedValue('mod-logs'); + + const timeoutFunc = jest.fn(); + + const sentEmbeds: EmbedBuilder[] = []; + + const interaction = { + reply: jest.fn(), + guild: { + channels: { + cache: { + find: jest.fn().mockReturnValue(undefined), + } + } + }, + guildId: 'guildId', + user: { + id: 'moderatorId', + }, + options: { + get: jest.fn((value: string): CommandInteractionOption<CacheType> | null => { + switch (value) { + case 'target': + return { + user: { + id: 'userId', + tag: 'userTag', + createDM: jest.fn().mockReturnValue({ + send: jest.fn(async (options: MessageCreateOptions): Promise<Message<false>> => { + sentEmbeds.push(options.embeds![0] as EmbedBuilder); + + return mock<Message<false>>(); + }) + }) as unknown as DMChannel, + } as unknown as User, + member: { + manageable: true, + timeout: timeoutFunc, + } as unknown as GuildMember + } as CommandInteractionOption; + case 'length': + return { + value: '1m' + } as CommandInteractionOption; + case 'reason': + return { + value: 'Test reason', + } as CommandInteractionOption; + default: + return null; + } + }), + } + } as unknown as CommandInteraction; + + + await command.execute(interaction); + + expect(timeoutFunc).toBeCalled(); + expect(sentEmbeds.length).toBeGreaterThan(0); + }); + + // DM user + test('GIVEN user can NOT be messaged, EXPECT resultEmbed to contain "DM Sent = false"', async () => { + let embeds: APIEmbed[] | undefined; + + const command = new Timeout(); + + const interactionReply = jest.fn((options: InteractionReplyOptions) => { + embeds = options.embeds as APIEmbed[]; + }); + + let savedAudit: DeepPartial<Audit> | undefined; + + const getSetting = jest.spyOn(SettingsHelper, 'GetSetting').mockResolvedValue('mod-logs'); + const auditSave = jest.spyOn(Audit.prototype, 'Save').mockImplementation((target: EntityTarget<BaseEntity>, entity: DeepPartial<BaseEntity>): Promise<void> => { + savedAudit = entity; + + return Promise.resolve(); + }); + + const timeoutFunc = jest.fn(); + + let dmChannelSentEmbeds: (APIEmbed | JSONEncodable<APIEmbed>)[] | undefined; + let logsChannelSentEmbeds: (APIEmbed | JSONEncodable<APIEmbed>)[] | undefined; + + const dmChannel = { + send: jest.fn().mockImplementation((options: MessageCreateOptions) => { + dmChannelSentEmbeds = options.embeds; + }), + } as unknown as DMChannel; + + const userInput = { + user: { + id: 'userId', + tag: 'userTag', + createDM: jest.fn().mockRejectedValue(undefined), + } as unknown as User, + member: { + manageable: true, + timeout: timeoutFunc, + } as unknown as GuildMember, + } as CommandInteractionOption; + + const lengthInput = { + value: '1s', + } as CommandInteractionOption; + + const reasonInput = { + value: 'Test reason', + } as CommandInteractionOption; + + const logsChannel = { + name: 'mod-logs', + send: jest.fn().mockImplementation((options: MessageCreateOptions) => { + logsChannelSentEmbeds = options.embeds; + }), + } as unknown as TextChannel; + + const interaction = { + guild: { + channels: { + cache: { + find: jest.fn() + .mockReturnValue(logsChannel), + } + }, + name: "Test Guild", + } as unknown as Guild, + guildId: 'guildId', + reply: interactionReply, + options: { + get: jest.fn() + .mockReturnValueOnce(userInput) + .mockReturnValueOnce(lengthInput) + .mockReturnValue(reasonInput), + }, + user: { + id: 'moderatorId' + } + } as unknown as CommandInteraction; + + await command.execute(interaction); + + // EXPECT embeds to be sent + expect(embeds).toBeDefined(); + expect(embeds!.length).toBe(1); + + const resultEmbed = embeds![0] as EmbedBuilder; + + // EXPECT DM field to be configured + const resultEmbedDMField = resultEmbed.data.fields![0]; + + expect(resultEmbedDMField.name).toBe("DM Sent"); + expect(resultEmbedDMField.value).toBe("false"); + }); +}); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 617ce5d..54ec5c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -124,7 +124,7 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-string-parser@^7.21.5": +"@babel/helper-string-parser@^7.19.4", "@babel/helper-string-parser@^7.21.5": version "7.21.5" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz#2b3eea65443c6bdc31c22d037c65f6d323b6b2bd" integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w== @@ -157,11 +157,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.5", "@babel/parser@^7.21.8": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.21.5", "@babel/parser@^7.21.8": version "7.21.8" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.8.tgz#642af7d0333eab9c0ad70b14ac5e76dbde7bfdf8" integrity sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA== +"@babel/parser@^7.20.7": + version "7.21.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.3.tgz#1d285d67a19162ff9daa358d4cb41d50c06220b3" + integrity sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ== + "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -292,7 +297,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.4", "@babel/types@^7.21.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3": +"@babel/types@^7.0.0", "@babel/types@^7.21.4", "@babel/types@^7.21.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3": version "7.21.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.5.tgz#18dfbd47c39d3904d5db3d3dc2cc80bedb60e5b6" integrity sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q== @@ -301,6 +306,15 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" +"@babel/types@^7.18.6", "@babel/types@^7.20.7", "@babel/types@^7.21.0": + version "7.21.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.3.tgz#4865a5357ce40f64e3400b0f3b737dc6d4f64d05" + integrity sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1023,9 +1037,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001449: - version "1.0.30001486" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001486.tgz#56a08885228edf62cbe1ac8980f2b5dae159997e" - integrity sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg== + version "1.0.30001469" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001469.tgz#3dd505430c8522fdc9f94b4a19518e330f5c945a" + integrity sha512-Rcp7221ScNqQPP3W+lVOYDyjdR6dC+neEQCttoNr5bAyz54AboB4iwpnWgyi8P4YUsPybVzT4LgWiBbI3drL4g== chalk@^2.0.0: version "2.4.2" @@ -2506,7 +2520,7 @@ safe-buffer@^5.0.1, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -semver@7.x, semver@^7.3.5: +semver@7.x: version "7.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== @@ -2518,6 +2532,13 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.3.5: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + sha.js@^2.4.11: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" From a56076e118746d0c441be56e06a12ab6951c0acc Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 23 Jun 2023 17:37:31 +0100 Subject: [PATCH 49/56] Update rules for Vylpes' Den with gitea link (#307) - Update rules file with: - Gitea link - Short url for server invite - New youtube link - Remove old vylbot core link as deprecated - Remove blog site as deprecated #234 Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/307 --- data/rules/290149509969739776.json | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/data/rules/290149509969739776.json b/data/rules/290149509969739776.json index 9fa7a1e..a01ef0c 100644 --- a/data/rules/290149509969739776.json +++ b/data/rules/290149509969739776.json @@ -6,7 +6,7 @@ "title": "Vylpes' Den", "description": [ "Welcome to Vylpes' Den! Make sure to say hi!", - "Invite link: https://discord.gg/UyAhAVp" + "Invite link: https://go.vylpes.xyz/A6HcA" ] }, { @@ -70,19 +70,17 @@ "description": [ "This server uses a bot made by me, VylBot, to help moderate the server.", "For more information on it, see the GitHub repositories:", - "https://github.com/Vylpes/vylbot-core", - "https://github.com/Vylpes/vylbot-app" + "https://gitea.vylpes.xyz/rabbitlabs/vylbot-app" ] }, { "title": "Links", "description": [ - "YouTube: https://www.youtube.com/channel/UCwPlzKwCmP5Q9bCX3fHk2BA", + "YouTube: https://www.youtube.com/@vylpes", "Patreon: https://www.patreon.com/vylpes", "Twitch: https://www.twitch.tv/vylpes_", - "Twitter: https://twitter.com/vylpes", - "Blog: https://vylpes.xyz" + "Twitter: https://twitter.com/vylpes" ], - "footer": "Last updated 01/02/2022" + "footer": "Last updated 20/06/2023" } ] \ No newline at end of file From 915efc226e723193060d584b4f300cf6b8f40831 Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 23 Jun 2023 17:39:40 +0100 Subject: [PATCH 50/56] Remove github workflows (#308) Removing the github action workflows. This is because we no longer use github, and this just causes unnecessary compute minutes being used over on github. #251 Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/308 --- .github/workflows/deployment.yml | 27 --------------------------- .github/workflows/integration.yml | 20 -------------------- .github/workflows/staging.yml | 27 --------------------------- 3 files changed, 74 deletions(-) delete mode 100644 .github/workflows/deployment.yml delete mode 100644 .github/workflows/integration.yml delete mode 100644 .github/workflows/staging.yml diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml deleted file mode 100644 index 53e7f47..0000000 --- a/.github/workflows/deployment.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: deployment - -on: - push: - branches: - - main - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build and Test - uses: actions/setup-node@v1 - with: - node-version: 16.x - - run: yarn install --frozen-lockfile - - run: yarn build - - name: Deploy Production - uses: D3rHase/ssh-command-action@v0.2.1 - with: - HOST: ${{secrets.HOST}} - PORT: ${{secrets.PORT}} - USER: ${{secrets.USER}} - PRIVATE_SSH_KEY: ${{secrets.PRIVATE_SSH_KEY}} - COMMAND: ${{secrets.PROD_COMMAND}} \ No newline at end of file diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml deleted file mode 100644 index d74e7aa..0000000 --- a/.github/workflows/integration.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: integration - -on: - push: - branches: - - feature/* - - hotfix/* - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build and Test - uses: actions/setup-node@v1 - with: - node-version: 16.x - - run: yarn install --frozen-lockfile - - run: yarn build - - run: yarn test \ No newline at end of file diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml deleted file mode 100644 index 5cff552..0000000 --- a/.github/workflows/staging.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: staging - -on: - push: - branches: - - develop - workflow_dispatch: - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build and Test - uses: actions/setup-node@v1 - with: - node-version: 16.x - - run: yarn install --frozen-lockfile - - run: yarn build - - name: Deploy Staging - uses: D3rHase/ssh-command-action@v0.2.1 - with: - HOST: ${{secrets.HOST}} - PORT: ${{secrets.PORT}} - USER: ${{secrets.USER}} - PRIVATE_SSH_KEY: ${{secrets.PRIVATE_SSH_KEY}} - COMMAND: ${{secrets.STAGE_COMMAND}} \ No newline at end of file From a23028b40cd84b6ae3eff6fdd8a423529fab0f33 Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 26 Jun 2023 17:51:49 +0100 Subject: [PATCH 51/56] Update dependency minimatch to v9.0.2 (#309) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [minimatch](https://github.com/isaacs/minimatch) | dependencies | patch | [`9.0.1` -> `9.0.2`](https://renovatebot.com/diffs/npm/minimatch/9.0.1/9.0.2) | --- ### Release Notes <details> <summary>isaacs/minimatch</summary> ### [`v9.0.2`](https://github.com/isaacs/minimatch/compare/v9.0.1...v9.0.2) [Compare Source](https://github.com/isaacs/minimatch/compare/v9.0.1...v9.0.2) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/309 Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 988a97d..95cdaaf 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "emoji-regex": "^10.0.0", "jest": "^29.0.0", "jest-mock-extended": "^3.0.0", - "minimatch": "9.0.1", + "minimatch": "9.0.2", "mysql": "^2.18.1", "random-bunny": "^2.0.5", "ts-jest": "^29.0.0", diff --git a/yarn.lock b/yarn.lock index 54ec5c2..cfed787 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2168,10 +2168,10 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -minimatch@9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" - integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== +minimatch@9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.2.tgz#397e387fff22f6795844d00badc903a3d5de7057" + integrity sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg== dependencies: brace-expansion "^2.0.1" From e84f871329ab222e54764c0274f7e3642a2bbe07 Mon Sep 17 00:00:00 2001 From: RenovateBot <renovate@vylpes.com> Date: Mon, 26 Jun 2023 17:58:24 +0100 Subject: [PATCH 52/56] Update dependency typeorm to v0.3.17 (#310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [typeorm](https://typeorm.io) ([source](https://github.com/typeorm/typeorm)) | dependencies | patch | [`0.3.16` -> `0.3.17`](https://renovatebot.com/diffs/npm/typeorm/0.3.16/0.3.17) | --- ### Release Notes <details> <summary>typeorm/typeorm</summary> ### [`v0.3.17`](https://github.com/typeorm/typeorm/releases/tag/0.3.17) [Compare Source](https://github.com/typeorm/typeorm/compare/0.3.16...0.3.17) ##### Bug Fixes - [#​10040](https://github.com/typeorm/typeorm/issues/10040) TypeORM synchronize database even if it is up to date ([#​10041](https://github.com/typeorm/typeorm/issues/10041)) ([b1a3a39](https://github.com/typeorm/typeorm/commit/b1a3a395049052f3f031e9fd27b99769b03b9011)) - add missing await ([#​10084](https://github.com/typeorm/typeorm/issues/10084)) ([f5d4397](https://github.com/typeorm/typeorm/commit/f5d43975dbbf02d0e40d64d01265105d4018cf7a)) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: Renovate Bot <renovate@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/310 Co-authored-by: RenovateBot <renovate@vylpes.com> Co-committed-by: RenovateBot <renovate@vylpes.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 95cdaaf..4aa91b7 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "mysql": "^2.18.1", "random-bunny": "^2.0.5", "ts-jest": "^29.0.0", - "typeorm": "0.3.16" + "typeorm": "0.3.17" }, "devDependencies": { "@types/node": "^20.0.0", diff --git a/yarn.lock b/yarn.lock index cfed787..fe4eccd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2783,10 +2783,10 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typeorm@0.3.16: - version "0.3.16" - resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.16.tgz#a001d77b36cfaaf9ff495e15805dd17883116b7b" - integrity sha512-wJ4Qy1oqRKNDdZiBTTaVMqwo/XxC52Q7uNPTjltPgLhvIW173bL6Iad0lhptMOsFlpixFPaUu3PNziaRBwX2Zw== +typeorm@0.3.17: + version "0.3.17" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.17.tgz#a73c121a52e4fbe419b596b244777be4e4b57949" + integrity sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig== dependencies: "@sqltools/formatter" "^1.2.5" app-root-path "^3.1.0" From 9749f9c9c917dd284258b608324d915e033d3293 Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 30 Jun 2023 17:16:46 +0100 Subject: [PATCH 53/56] Update drone deployment script to only deploy when a tag is created (#313) - Update drone deployment script to only deploy when a tag is created #292 Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/313 --- .drone.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.drone.yml b/.drone.yml index 4584051..ae31a87 100644 --- a/.drone.yml +++ b/.drone.yml @@ -16,10 +16,8 @@ steps: - sh /home/vylpes/scripts/vylbot/deploy_prod.sh trigger: - branch: - - main event: - - promote + - tag --- @@ -71,4 +69,4 @@ trigger: - renovate/* event: - push - - pull_request \ No newline at end of file + - pull_request From eb774aa2804b3905c8f0376b365f82c9d18b2448 Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 30 Jun 2023 17:19:40 +0100 Subject: [PATCH 54/56] Fix bot not replying to the interaction on warn (#312) - Fix bot not replying to the interaction when warning a user #301 Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/312 --- src/commands/warn.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/commands/warn.ts b/src/commands/warn.ts index 5044912..618118b 100644 --- a/src/commands/warn.ts +++ b/src/commands/warn.ts @@ -1,4 +1,4 @@ -import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; +import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { AuditType } from "../constants/AuditType"; import EmbedColours from "../constants/EmbedColours"; import Audit from "../database/entities/Audit"; @@ -35,7 +35,6 @@ export default class Warn extends Command { return; } - const targetMember = targetUser.member as GuildMember; const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : "*none*"; const logEmbed = new EmbedBuilder() @@ -65,5 +64,7 @@ export default class Warn extends Command { const audit = new Audit(targetUser.user.id, AuditType.Warn, reason, interaction.user.id, interaction.guildId); await audit.Save(Audit, audit); + + await interaction.reply('Successfully warned user.'); } } \ No newline at end of file From 400b4de304b39d944c397ca36c0432174b221800 Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 30 Jun 2023 17:33:04 +0100 Subject: [PATCH 55/56] feature/98-timeout-command-2 (#306) - Prevent user from trying to time out a bot - Update time length input to ignore commas #98 Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/306 --- src/commands/timeout.ts | 5 +++++ src/helpers/StringTools.ts | 4 ++++ src/helpers/TimeLengthInput.ts | 4 +++- src/vylbot.ts | 2 +- tests/commands/timeout.test.ts | 37 ++++++++++++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/commands/timeout.ts b/src/commands/timeout.ts index 65e3ba0..52fe1e7 100644 --- a/src/commands/timeout.ts +++ b/src/commands/timeout.ts @@ -49,6 +49,11 @@ export default class Timeout extends Command { return; } + if (targetUser.user.bot) { + await interaction.reply('Cannot timeout bots.'); + return; + } + // General Variables const targetMember = targetUser.member as GuildMember; const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : null; diff --git a/src/helpers/StringTools.ts b/src/helpers/StringTools.ts index 5119f94..0254dc5 100644 --- a/src/helpers/StringTools.ts +++ b/src/helpers/StringTools.ts @@ -35,4 +35,8 @@ export default class StringTools { return result; } + + public static ReplaceAll(str: string, find: string, replace: string) { + return str.replace(new RegExp(find, 'g'), replace); + } } \ No newline at end of file diff --git a/src/helpers/TimeLengthInput.ts b/src/helpers/TimeLengthInput.ts index 7c167d2..95befa6 100644 --- a/src/helpers/TimeLengthInput.ts +++ b/src/helpers/TimeLengthInput.ts @@ -1,8 +1,10 @@ +import StringTools from "./StringTools"; + export default class TimeLengthInput { public readonly value: string; constructor(input: string) { - this.value = input; + this.value = StringTools.ReplaceAll(input, ',', ''); } public GetDays(): number { diff --git a/src/vylbot.ts b/src/vylbot.ts index c1d2997..668c8e5 100644 --- a/src/vylbot.ts +++ b/src/vylbot.ts @@ -35,4 +35,4 @@ const client = new CoreClient([ registry.RegisterCommands(); registry.RegisterEvents(); -client.start(); \ No newline at end of file +client.start(); diff --git a/tests/commands/timeout.test.ts b/tests/commands/timeout.test.ts index c64ceb5..1646734 100644 --- a/tests/commands/timeout.test.ts +++ b/tests/commands/timeout.test.ts @@ -360,6 +360,43 @@ describe('execute', () => { expect(interaction.reply).toBeCalledWith('Fields are required.'); }); + test('GIVEN targetUser is a bot, EXPECT error', async () => { + const interaction = { + reply: jest.fn(), + guild: mock<Guild>(), + guildId: 'guildId', + options: { + get: jest.fn((value: string): CommandInteractionOption<CacheType> | null => { + switch (value) { + case 'target': + return { + user: { + bot: true, + } as User, + member: {} as GuildMember + } as CommandInteractionOption; + case 'length': + return { + value: '1m', + } as CommandInteractionOption; + case 'reason': + return { + value: 'Test reason', + } as CommandInteractionOption; + default: + return null; + } + }), + } + } as unknown as CommandInteraction; + + const command = new Timeout(); + + await command.execute(interaction); + + expect(interaction.reply).toBeCalledWith('Cannot timeout bots.'); + }); + test('GIVEN targetMember IS NOT manageable by the bot, EXPECT insufficient permissions error', async () => { const command = new Timeout(); From 995564cb5bcab0bfaa181b62b2b7e6059528742a Mon Sep 17 00:00:00 2001 From: Vylpes <ethan@vylpes.com> Date: Fri, 7 Jul 2023 12:28:06 +0100 Subject: [PATCH 56/56] Deprecate mute and unmute commands (#314) - Add a deprecation message to the mute and unmute commands #252 Co-authored-by: Ethan Lane <ethan@vylpes.com> Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/314 --- src/commands/mute.ts | 4 +++- src/commands/unmute.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/commands/mute.ts b/src/commands/mute.ts index 137aace..3e92231 100644 --- a/src/commands/mute.ts +++ b/src/commands/mute.ts @@ -11,7 +11,7 @@ export default class Mute extends Command { super.CommandBuilder = new SlashCommandBuilder() .setName("mute") - .setDescription("Mute a member in the server with an optional reason") + .setDescription("(DEPRECATED) Mute a member in the server with an optional reason") .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) .addUserOption(option => option @@ -79,5 +79,7 @@ export default class Mute extends Command { const audit = new Audit(targetUser.user.id, AuditType.Mute, reason, interaction.user.id, interaction.guildId); await audit.Save(Audit, audit); + + await interaction.reply("Please note the mute and unmute commands have been deprecated and will be removed in a future update. Please use timeout instead"); } } \ No newline at end of file diff --git a/src/commands/unmute.ts b/src/commands/unmute.ts index 59817f8..1a3bf95 100644 --- a/src/commands/unmute.ts +++ b/src/commands/unmute.ts @@ -9,7 +9,7 @@ export default class Unmute extends Command { super.CommandBuilder = new SlashCommandBuilder() .setName("unmute") - .setDescription("Unmute a member in the server with an optional reason") + .setDescription("(DEPRECATED) Unmute a member in the server with an optional reason") .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) .addUserOption(option => option @@ -74,5 +74,7 @@ export default class Unmute extends Command { if (channel) { await channel.send({ embeds: [ logEmbed ]}); } + + await interaction.reply("Please note the mute and unmute commands have been deprecated and will be removed in a future update. Please use timeout instead"); } } \ No newline at end of file