diff --git a/#.env b/#.env index 5506fde..a201a5f 100644 --- a/#.env +++ b/#.env @@ -5,4 +5,5 @@ POSTGRES_PASSWORD= DATABASE_PORT=5432 DATABASE_HOST=localhost NODE_ENV=development -SENDGRID_API_KEY= +SMTP_USER= +SMTP_PASS= diff --git a/config.development.json b/config.development.json index 9377126..a713267 100644 --- a/config.development.json +++ b/config.development.json @@ -144,9 +144,13 @@ "emote": "📢" }, "communicationServiceOptions": { - "mailData": { - "from": "mdpdevti@henallux.be", - "templateId": "d-c8892944b4f2417bafece2d7a5b73d1f" - } + "from": "noreply-discord@henallux.be", + "port": 587, + "host": "smtp.office365.com", + "tls": { + "rejectUnauthorized": false + }, + "debug": true, + "logger": true } } diff --git a/config.production.json b/config.production.json index ed82b8f..ba4ef4d 100644 --- a/config.production.json +++ b/config.production.json @@ -152,9 +152,11 @@ "emote": "📢" }, "communicationServiceOptions": { - "mailData": { - "from": "mdpdevti@henallux.be", - "templateId": "d-ae8dfdd7cc9c49f1af6e016ecbb4d856" + "from": "noreply-discord@henallux.be", + "port": 587, + "host": "smtp.office365.com", + "tls": { + "rejectUnauthorized": false } } } diff --git a/package.json b/package.json index 6ae7ef5..728a949 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "datadrop", - "version": "2.0.0", + "version": "2.0.1", "type": "module", "main": "./build/index.js", "scripts": { @@ -26,15 +26,16 @@ "@hunteroi/discord-selfrole": "^4.0.4", "@hunteroi/discord-temp-channels": "^3.3.0", "@hunteroi/discord-verification": "^1.5.0", - "@sendgrid/mail": "8.1.3", "discord-sync-commands": "^0.3.0", "discord.js": "^14.16.2", "dotenv": "^16.4.5", + "nodemailer": "^6.9.1", "ts-postgres": "1.3.0" }, "devDependencies": { "@biomejs/biome": "^1.9.4", "@types/node": "^20.12.7", + "@types/nodemailer": "^6.4.7", "typescript": "^5.4.4" } } diff --git a/scripts/deploy-commands.cjs b/scripts/deploy-commands.cjs index 813b411..30932ab 100644 --- a/scripts/deploy-commands.cjs +++ b/scripts/deploy-commands.cjs @@ -3,6 +3,7 @@ const { Client, Collection, REST, Routes } = require("discord.js"); const path = require("node:path"); const fsp = require("node:fs/promises"); const synchronizeSlashCommands = require("discord-sync-commands"); + const { botId: botProdId } = require("../config.production.json"); const { guildId, botId: botDevId } = require("../config.development.json"); diff --git a/src/commands/admins/announce.ts b/src/commands/admins/announce.ts index 4dbeb43..64f1fba 100644 --- a/src/commands/admins/announce.ts +++ b/src/commands/admins/announce.ts @@ -13,7 +13,7 @@ import { } from "discord.js"; import type { DatadropClient } from "../../datadrop.js"; -import type { Command } from "../../models/Command.js"; +import type { Command } from "../../models/index.js"; export default { data: new SlashCommandBuilder() diff --git a/src/commands/others/link.ts b/src/commands/others/link.ts index 87cf6ad..c1bf6a3 100644 --- a/src/commands/others/link.ts +++ b/src/commands/others/link.ts @@ -7,7 +7,7 @@ import { } from "discord.js"; import type { DatadropClient } from "../../datadrop.js"; -import type { Command } from "../../models/Command.js"; +import type { Command } from "../../models/index.js"; export default { data: new SlashCommandBuilder() diff --git a/src/commands/others/pin.ts b/src/commands/others/pin.ts index 37b28be..b712a4d 100644 --- a/src/commands/others/pin.ts +++ b/src/commands/others/pin.ts @@ -6,7 +6,7 @@ import { } from "discord.js"; import type { DatadropClient } from "../../datadrop.js"; -import type { Command } from "../../models/Command.js"; +import type { Command } from "../../models/index.js"; export default { data: new ContextMenuCommandBuilder() diff --git a/src/commands/owner/eval.ts b/src/commands/owner/eval.ts index ab808e2..21cdaf9 100644 --- a/src/commands/owner/eval.ts +++ b/src/commands/owner/eval.ts @@ -7,7 +7,7 @@ import type { DatadropClient } from "../../datadrop.js"; import { clean } from "../../helpers.js"; -import type { Command } from "../../models/Command.js"; +import type { Command } from "../../models/index.js"; export default { data: new SlashCommandBuilder() diff --git a/src/commands/owner/reload.ts b/src/commands/owner/reload.ts index 86a0d84..18e3fe3 100644 --- a/src/commands/owner/reload.ts +++ b/src/commands/owner/reload.ts @@ -5,7 +5,7 @@ import { } from "discord.js"; import type { DatadropClient } from "../../datadrop.js"; -import type { Command } from "../../models/Command.js"; +import type { Command } from "../../models/index.js"; export default { data: new SlashCommandBuilder() diff --git a/src/commands/owner/restart.ts b/src/commands/owner/restart.ts index aaa8110..14923fc 100644 --- a/src/commands/owner/restart.ts +++ b/src/commands/owner/restart.ts @@ -5,7 +5,7 @@ } from "discord.js"; import type { DatadropClient } from "../../datadrop.js"; -import type { Command } from "../../models/Command.js"; +import type { Command } from "../../models/index.js"; export default { data: new SlashCommandBuilder() diff --git a/src/commands/utility/email.ts b/src/commands/utility/email.ts index cc75166..8b9c887 100644 --- a/src/commands/utility/email.ts +++ b/src/commands/utility/email.ts @@ -5,7 +5,7 @@ import { } from "discord.js"; import type { DatadropClient } from "../../datadrop.js"; -import type { Command } from "../../models/Command.js"; +import type { Command } from "../../models/index.js"; const people = [ { diff --git a/src/commands/utility/ping.ts b/src/commands/utility/ping.ts index 2ec41f7..c493719 100644 --- a/src/commands/utility/ping.ts +++ b/src/commands/utility/ping.ts @@ -4,7 +4,7 @@ import { } from "discord.js"; import type { DatadropClient } from "../../datadrop.js"; -import type { Command } from "../../models/Command.js"; +import type { Command } from "../../models/index.js"; export default { data: new SlashCommandBuilder().setName("ping").setDescription("Pong!"), diff --git a/src/config.ts b/src/config.ts index b0f9515..0bce769 100644 --- a/src/config.ts +++ b/src/config.ts @@ -29,8 +29,10 @@ const defaultConfig: Configuration = { tutor: { roleid: "", emote: "" }, announce: { roleid: "", emote: "", channelid: "" }, communicationServiceOptions: { - apiKey: "", - mailData: { from: "", templateId: "" }, + auth: { user: "", pass: "" }, + from: "", + port: 587, + host: "", }, }; @@ -51,8 +53,10 @@ export async function readConfig(): Promise { ...json, version: `${environment}-v${packageInfo.version}`, }; - config.communicationServiceOptions.apiKey = - process.env.SENDGRID_API_KEY; + config.communicationServiceOptions.auth = { + user: process.env.SMTP_USER, + pass: process.env.SMTP_PASS, + }; return config; } catch (err: unknown) { diff --git a/src/datadrop.ts b/src/datadrop.ts index d660d8f..9960f37 100644 --- a/src/datadrop.ts +++ b/src/datadrop.ts @@ -34,16 +34,17 @@ import { VerificationManager, VerificationManagerEvents, } from "@hunteroi/discord-verification"; -import { SendGridService } from "@hunteroi/discord-verification/lib/services/SendGridService.js"; import { readConfig } from "./config.js"; import { getErrorMessage, readFilesFrom } from "./helpers.js"; -import type { Command } from "./models/Command.js"; -import type { Configuration } from "./models/Configuration.js"; -import type { Event } from "./models/Event.js"; -import type { IDatabaseService } from "./models/IDatabaseService.js"; -import type { User } from "./models/User.js"; -import PostgresDatabaseService from "./services/PostgresDatabaseService.js"; +import type { + Command, + Configuration, + Event, + IDatabaseService, + User, +} from "./models/index.js"; +import { PostgresDatabaseService, SMTPService } from "./services/index.js"; export class DatadropClient extends Client { #config: Configuration; @@ -75,7 +76,7 @@ export class DatadropClient extends Client { this.tempChannelsManager = new TempChannelsManager(this); this.database = new PostgresDatabaseService(this.logger); - const communicationService = new SendGridService( + const communicationService = new SMTPService( config.communicationServiceOptions, ); this.verificationManager = new VerificationManager( diff --git a/src/events/error.ts b/src/events/error.ts new file mode 100644 index 0000000..31bb220 --- /dev/null +++ b/src/events/error.ts @@ -0,0 +1,7 @@ +import type { DatadropClient } from "../datadrop.js"; + +export default async function error(client: DatadropClient, error: Error) { + client.logger.error( + `${error.name}: ${error.message}\n${error.cause}\n${error.stack}`, + ); +} diff --git a/src/events/guildMemberAdd.ts b/src/events/guildMemberAdd.ts index ed73f95..9052554 100644 --- a/src/events/guildMemberAdd.ts +++ b/src/events/guildMemberAdd.ts @@ -8,8 +8,7 @@ import { } from "discord.js"; import type { DatadropClient } from "../datadrop.js"; -import type { AnnounceConfiguration } from "../models/Configuration.js"; -import type { Event } from "../models/Event.js"; +import type { AnnounceConfiguration, Event } from "../models/index.js"; export default { name: Events.GuildMemberAdd, diff --git a/src/events/guildMemberRemove.ts b/src/events/guildMemberRemove.ts index bddf2e4..1d8f2dd 100644 --- a/src/events/guildMemberRemove.ts +++ b/src/events/guildMemberRemove.ts @@ -1,7 +1,7 @@ import { Events, type GuildMember } from "discord.js"; import type { DatadropClient } from "../datadrop.js"; -import type { Event } from "../models/Event.js"; +import type { Event } from "../models/index.js"; export default { name: Events.GuildMemberRemove, diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts index 97caa8c..e4f9d07 100644 --- a/src/events/interactionCreate.ts +++ b/src/events/interactionCreate.ts @@ -16,7 +16,7 @@ import { } from "discord.js"; import type { DatadropClient } from "../datadrop.js"; -import type { Event } from "../models/Event.js"; +import type { Event } from "../models/index.js"; import { CommandHandler } from "../services/CommandHandler.js"; export default { diff --git a/src/events/ready.ts b/src/events/ready.ts index 034e605..6b838fa 100644 --- a/src/events/ready.ts +++ b/src/events/ready.ts @@ -3,8 +3,7 @@ import { ButtonStyle, Events, Role, bold, roleMention } from "discord.js"; import type { RoleToEmojiData } from "@hunteroi/discord-selfrole"; import type { DatadropClient } from "../datadrop.js"; -import type { Configuration } from "../models/Configuration.js"; -import type { Event } from "../models/Event.js"; +import type { Configuration, Event } from "../models/index.js"; export default { name: Events.ClientReady, diff --git a/src/helpers.ts b/src/helpers.ts index d9d331e..4949273 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,5 +1,6 @@ import * as fsp from "node:fs/promises"; import * as path from "node:path"; + import { ConsoleLogger, type DefaultLogger } from "@hunteroi/advanced-logger"; const console = new ConsoleLogger(); diff --git a/src/models/Configuration.ts b/src/models/Configuration.ts index 5c70eb2..7f36040 100644 --- a/src/models/Configuration.ts +++ b/src/models/Configuration.ts @@ -1,6 +1,6 @@ import type { Snowflake } from "discord.js"; -import type { SendGridOptions } from "@hunteroi/discord-verification/lib/services/SendGridService.js"; +import type { SMTPServiceOptions } from "../services/SMTPService.js"; export interface SpecialRoleConfiguration { roleid: Snowflake; @@ -59,5 +59,5 @@ export interface Configuration { announce: AnnounceConfiguration; - communicationServiceOptions: SendGridOptions; + communicationServiceOptions: SMTPServiceOptions; } diff --git a/src/models/Event.ts b/src/models/Event.ts index a9511a8..a23d49a 100644 --- a/src/models/Event.ts +++ b/src/models/Event.ts @@ -1,4 +1,5 @@ import type { ClientEvents } from "discord.js"; + import type { DatadropClient } from "../datadrop.js"; export interface Event { diff --git a/src/models/index.ts b/src/models/index.ts new file mode 100644 index 0000000..9677c71 --- /dev/null +++ b/src/models/index.ts @@ -0,0 +1,23 @@ +import { Command } from "./Command.js"; +import { + AnnounceConfiguration, + Configuration, + GroupConfiguration, + SpecialRoleConfiguration, + YearConfiguration, +} from "./Configuration.js"; +import { Event } from "./Event.js"; +import { IDatabaseService } from "./IDatabaseService.js"; +import { User } from "./User.js"; + +export { + Command, + SpecialRoleConfiguration, + GroupConfiguration, + YearConfiguration, + AnnounceConfiguration, + Configuration, + Event, + IDatabaseService, + User, +}; diff --git a/src/services/PostgresDatabaseService.ts b/src/services/PostgresDatabaseService.ts index cee8ada..f148073 100644 --- a/src/services/PostgresDatabaseService.ts +++ b/src/services/PostgresDatabaseService.ts @@ -8,8 +8,7 @@ import { import type { ConsoleLogger } from "@hunteroi/advanced-logger"; -import type { IDatabaseService } from "../models/IDatabaseService.js"; -import type { User } from "../models/User.js"; +import type { IDatabaseService, User } from "../models/index.js"; export default class PostgresDatabaseService implements IDatabaseService { readonly #logger: ConsoleLogger; @@ -206,7 +205,7 @@ export default class PostgresDatabaseService implements IDatabaseService { async #runMigrations(): Promise { await this.#runMigration("User soft delete", async () => { await this.#database.query( - "ALTER TABLE Users ADD IF NOT EXISTS isDeleted timestamp;", + "ALTER TABLE Users ADD COLUMN IF NOT EXISTS isDeleted timestamp;", ); }); } @@ -216,8 +215,10 @@ export default class PostgresDatabaseService implements IDatabaseService { "SELECT * FROM Migrations WHERE name = $1", [name], ); - const migration = [...result].pop(); - if (!migration) { + this.#logger.verbose( + `Running migration "${name}" with pre-query returning ${JSON.stringify(result)}`, + ); + if (result && result.rows.length === 0) { await this.#database.query( "INSERT INTO Migrations (name) VALUES($1);", [name], diff --git a/src/services/SMTPService.ts b/src/services/SMTPService.ts new file mode 100644 index 0000000..03a0177 --- /dev/null +++ b/src/services/SMTPService.ts @@ -0,0 +1,26 @@ +import { createTransport } from "nodemailer"; +import type SMTPTransport from "nodemailer/lib/smtp-transport"; + +import type { ISenderAPI, SenderAPIData } from "@hunteroi/discord-verification"; + +export type SMTPServiceOptions = SMTPTransport.Options; + +export default class SMTPService implements ISenderAPI { + #options: SMTPServiceOptions; + + constructor(options: SMTPServiceOptions) { + this.#options = options; + } + + async send({ name, code, ...data }: SenderAPIData): Promise { + const transporter = createTransport(this.#options); + await transporter.verify(); + await transporter.sendMail({ + from: this.#options.from, + to: data.to, + subject: "Code d'Authentification Discord", + text: `Hello ${name}! Ton code est ${code}. A plus tard o/`, + html: `

Hello ${name}!

Ton code est ${code}.

A plus tard o/

`, + }); + } +} diff --git a/src/services/index.ts b/src/services/index.ts new file mode 100644 index 0000000..d259ec6 --- /dev/null +++ b/src/services/index.ts @@ -0,0 +1,4 @@ +import PostgresDatabaseService from "./PostgresDatabaseService.js"; +import SMTPService from "./SMTPService.js"; + +export { PostgresDatabaseService, SMTPService }; diff --git a/yarn.lock b/yarn.lock index 80aecab..07d9d0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -187,48 +187,32 @@ resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.5.3.tgz#0c102aa2ec5b34f806e9bc8625fc6a5e1d0a0c6a" integrity sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ== -"@sendgrid/client@^8.1.3": - version "8.1.3" - resolved "https://registry.yarnpkg.com/@sendgrid/client/-/client-8.1.3.tgz#51fd4a318627c4b615ff98e35609e98486a3bd6f" - integrity sha512-mRwTticRZIdUTsnyzvlK6dMu3jni9ci9J+dW/6fMMFpGRAJdCJlivFVYQvqk8kRS3RnFzS7sf6BSmhLl1ldDhA== - dependencies: - "@sendgrid/helpers" "^8.0.0" - axios "^1.6.8" - -"@sendgrid/helpers@^8.0.0": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@sendgrid/helpers/-/helpers-8.0.0.tgz#f74bf9743bacafe4c8573be46166130c604c0fc1" - integrity sha512-Ze7WuW2Xzy5GT5WRx+yEv89fsg/pgy3T1E3FS0QEx0/VvRmigMZ5qyVGhJz4SxomegDkzXv/i0aFPpHKN8qdAA== - dependencies: - deepmerge "^4.2.2" - -"@sendgrid/mail@8.1.3": - version "8.1.3" - resolved "https://registry.yarnpkg.com/@sendgrid/mail/-/mail-8.1.3.tgz#d371cbddcd2e8ca9469a68d1ed0c6b3a5c365e5e" - integrity sha512-Wg5iKSUOER83/cfY6rbPa+o3ChnYzWwv1OcsR8gCV8SKi+sUPIMroildimlnb72DBkQxcbylxng1W7f0RIX7MQ== - dependencies: - "@sendgrid/client" "^8.1.3" - "@sendgrid/helpers" "^8.0.0" - "@sindresorhus/is@^4.0.1": 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== "@types/node@*": - version "22.5.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.5.tgz#52f939dd0f65fc552a4ad0b392f3c466cc5d7a44" - integrity sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA== + version "22.8.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.8.4.tgz#ab754f7ac52e1fe74174f761c5b03acaf06da0dc" + integrity sha512-SpNNxkftTJOPk0oN+y2bIqurEXHTA2AOZ3EJDDKeJ5VzkvvORSvmQXGQarcOzWV1ac7DCaPBEdMDxBsM+d8jWw== dependencies: - undici-types "~6.19.2" + undici-types "~6.19.8" "@types/node@^20.12.7": - version "20.16.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.5.tgz#d43c7f973b32ffdf9aa7bd4f80e1072310fd7a53" - integrity sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA== + version "20.17.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.3.tgz#1ad87177c53fa2b237e79a4929fd37932f779f0c" + integrity sha512-tSQrmKKatLDGnG92h40GD7FzUt0MjahaHwOME4VAFeeA/Xopayq5qLyQRy7Jg/pjgKIFBXuKcGhJo+UdYG55jQ== dependencies: undici-types "~6.19.2" +"@types/nodemailer@^6.4.7": + version "6.4.16" + resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.16.tgz#db006abcb1e1c8e6ea2fb53b27fefec3c03eaa6c" + integrity sha512-uz6hN6Pp0upXMcilM61CoKyjT7sskBoOWpptkjjJp8jIMlTdc3xG01U7proKkXzruMS4hS0zqtHNkNPFB20rKQ== + dependencies: + "@types/node" "*" + "@types/ws@^7.4.7": version "7.4.7" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" @@ -260,15 +244,6 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -axios@^1.6.8: - version "1.7.7" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" - integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== - dependencies: - follow-redirects "^1.15.6" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - callsites@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -301,16 +276,16 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -deepmerge@^4.2.2: - version "4.3.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" - integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +discord-api-types@0.37.100: + version "0.37.100" + resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.100.tgz#5979892d39511bc7f1dbb9660d2d2cad698b3de7" + integrity sha512-a8zvUI0GYYwDtScfRd/TtaNBDTXwP5DiDVX7K5OmE+DRT57gBqKnwtOC5Ol8z0mRW8KQfETIgiB8U0YZ9NXiCA== + discord-api-types@0.37.83: version "0.37.83" resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.83.tgz#a22a799729ceded8176ea747157837ddf4708b1f" @@ -334,9 +309,9 @@ discord-sync-commands@^0.3.0: discord.js discordjs/discord.js#refs/pull/6414/head discord.js@^14.16.2: - version "14.16.2" - resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.16.2.tgz#c878977b5a377cf41eaed0b1901115f8faec9852" - integrity sha512-VGNi9WE2dZIxYM8/r/iatQQ+3LT8STW4hhczJOwm+DBeHq66vsKDCk8trChNCB01sMO9crslYuEMeZl2d7r3xw== + version "14.16.3" + resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.16.3.tgz#9553366953c992469f47a55af2a11c2054a9babe" + integrity sha512-EPCWE9OkA9DnFFNrO7Kl1WHHDYFXu3CNVFJg63bfU7hVtjZGyhShwZtSBImINQRWxWP2tgo2XI+QhdXx28r0aA== dependencies: "@discordjs/builders" "^1.9.0" "@discordjs/collection" "1.5.3" @@ -345,7 +320,7 @@ discord.js@^14.16.2: "@discordjs/util" "^1.1.1" "@discordjs/ws" "1.1.1" "@sapphire/snowflake" "3.5.3" - discord-api-types "0.37.97" + discord-api-types "0.37.100" fast-deep-equal "3.1.3" lodash.snakecase "4.1.1" tslib "^2.6.3" @@ -381,20 +356,6 @@ fast-deep-equal@3.1.3, fast-deep-equal@^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== -follow-redirects@^1.15.6: - version "1.15.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" - integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== - -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" - has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -449,6 +410,11 @@ node-fetch@^2.6.1: dependencies: whatwg-url "^5.0.0" +nodemailer@^6.9.1: + version "6.9.16" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.16.tgz#3ebdf6c6f477c571c0facb0727b33892635e0b8b" + integrity sha512-psAuZdTIRN08HKVd/E8ObdV6NO7NTBY3KsC30F7M4H1OnmLCUNaS56FpYxyb26zWLSyYF9Ozch9KYHhHegsiOQ== + ow@^0.27.0: version "0.27.0" resolved "https://registry.yarnpkg.com/ow/-/ow-0.27.0.tgz#d44da088e8184fa11de64b5813206f9f86ab68d0" @@ -461,11 +427,6 @@ ow@^0.27.0: type-fest "^1.2.1" vali-date "^1.0.0" -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -495,27 +456,22 @@ ts-typed-events@^3.0.0: resolved "https://registry.yarnpkg.com/ts-typed-events/-/ts-typed-events-3.0.0.tgz#2f9d96ff962edfc936402c859370337373880faa" integrity sha512-+2FZ0XPX+UPR7PO8ZQjuvnuDMYRhzrDaCRaNHaBG1xSL//0oPa3XMU5yxgDTzW67VzkE33fQpx1YxWBdkaF7Zw== -tslib@^2.3.0: +tslib@^2.3.0, tslib@^2.6.2, tslib@^2.6.3: version "2.8.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b" integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA== -tslib@^2.6.2, tslib@^2.6.3: - version "2.7.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" - integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== - type-fest@^1.2.1: version "1.4.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== typescript@^5.4.4: - version "5.6.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" - integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== + version "5.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" + integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== -undici-types@~6.19.2: +undici-types@~6.19.2, undici-types@~6.19.8: version "6.19.8" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==