diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..918eb12 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +color=always \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 373dbb9..64f7e91 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,13 +16,6 @@ "terminal.integrated.tabs.defaultColor": "terminal.ansiRed", "terminal.integrated.cursorStyle": "underline", - // Formatting - "editor.defaultFormatter": "rvest.vs-code-prettier-eslint", - "files.autoSave": "onFocusChange", - "editor.formatOnSave": true, - "editor.formatOnSaveMode": "file", - "javascript.format.semicolons": "ignore", - // Better Comments "better-comments.tags": [ { diff --git a/CHANGELOG.md b/CHANGELOG.md index e611fb8..24fc81d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,107 @@ All notable changes to this project will be documented in this file. +## [1.4.0] - 2024-10-19 + +### ๐Ÿš€ Features + +- V1.0.1 +- Moderation +- Mongodb +- Cases moderator / user +- Moderation - warn +- Custom-emojis +- Automoderation [base] +- Automoderation - invite-links +- [lib] 0.0.1 +- [lib] 0.0.2 Generic Type +- [lib] 0.0.3 default to true +- [lib] 0.0.5 setRunType() +- [scripts] 0.0.1 TS +- 1.0.3 +- *(/member whois)* Basic command logic +- GetCases() fix: createCase() +- NeetButton +- Welcome! +- Added farewell +- Neet-canvas + +### ๐Ÿ› Bug Fixes + +- Emoji() +- /settings welcome fix + +### ๐ŸŽจ Styling + +- Simpler logged + +### โš™๏ธ Miscellaneous Tasks + +- .ignore +- [lib] 0.0.6 Types & Enums +- Ignore test files. +- [lib] 0.0.7 Type Fixes +- *(neet)* Release neet@1.1.0 +- *(neet)* Release neet@1.1.1 +- Require -> import +- *(neet)* Release neet@1.2.0 +- Prettier +- Vscode / scripts +- *(neet)* Release neet@1.3.0 +- Moved settings separate +- Moderation Case Edits +- *(neet)* Release neet@1.3.1 +- Style โœจ +- Fix my stupidity +- Welcome uodate +- Migrate to Typegoose +- Type fixes / style + +### Auto-Moderation + +- Invites + +### Schema + +- Type string -> boolean + +### [mongoose] + +- Fixes + +### [scripts] + +- 0.03 + +### Add + +- (/whois): Cases + +### Break + +- 1.0.3 Changed to Typescript + +### Dev + +- Scripts + +### Helper + +- Emoji() + +### New + +- /automod settings + +### Rm + +- Config +- Settings + +### Utils + +- Matching for third party links. + ## [1.3.1] - 2024-10-13 ### ๐Ÿ› Bug Fixes diff --git a/SECURITY.md b/SECURITY.md index bd093e2..6fc4fa6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,8 +7,9 @@ currently being supported with security updates. | Version | Supported | | ------- | ------------------ | -| 1.0.2 | :white_check_mark: | -| 1.0.1 | :white_check_mark: | +| 1.4.1 | โœ… | +| 1.0.2 | :x: | +| 1.0.1 | :x: | | 0.x.x | :x: | ## Reporting a Vulnerability diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..23d69a0 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,7 @@ +# Documentation + +| Neet | ChangeLogs | Development | +| ---------- | ---------- | ---------------------------------------- | +| [@LTS](/) | [1.4.1](/) | [Code Style](./development/codestyle.md) | +| [@next](/) | +| [1.4.1](/) | diff --git a/docs/changelogs/1*/1.4.1.md b/docs/changelogs/1*/1.4.1.md new file mode 100644 index 0000000..a806a72 --- /dev/null +++ b/docs/changelogs/1*/1.4.1.md @@ -0,0 +1 @@ +# Changelog For V1.4.1 diff --git a/docs/changelogs/@next.md b/docs/changelogs/@next.md new file mode 100644 index 0000000..fcf730d --- /dev/null +++ b/docs/changelogs/@next.md @@ -0,0 +1 @@ +# Next Version (PLN) diff --git a/docs/development/codestyle.md b/docs/development/codestyle.md new file mode 100644 index 0000000..eac23dc --- /dev/null +++ b/docs/development/codestyle.md @@ -0,0 +1,30 @@ +# Code Style + +## Variables + +_A variable name should be **CamelCase**._ + +```js +const ThisVariable = "smile"; // IsOkay(): true +const Variable = "i guess!"; // IsOkay(): true +const variableHappy = "NO!"; // IsOkay(): false +const ISSMILING = true; // IsOkay(): false +const GAME_POINTS = 2591; // IsOkay(): false +``` + +## Functions + +_Function names need to be **CamelCase**._ + +```js +function sum(a, b) { + const result = a + b; + return result; +} // IsOkay(): true + +function CheckEmoji(name) { + const emojis = new Emojis({ useApp: true }); + if (!emojis[name]) return false; + return emojis[name]; +} // IsOkay(): true +``` diff --git a/icons.json b/icons.json new file mode 100644 index 0000000..dfbd9f6 --- /dev/null +++ b/icons.json @@ -0,0 +1,57 @@ +[ + { + "id": "1283480421543317607", + "name": "left_arrow", + "animated": false + }, + { + "id": "1283480432272343081", + "name": "right_arrow", + "animated": false + }, + { + "id": "1283727603638992929", + "name": "plus", + "animated": false + }, + { + "id": "1283727619258450012", + "name": "minus", + "animated": false + }, + { + "id": "1283761136982032450", + "name": "on", + "animated": false + }, + { + "id": "1283761153285165149", + "name": "off", + "animated": false + }, + { + "id": "1283761169810853949", + "name": "checkmark", + "animated": false + }, + { + "id": "1283761191159857237", + "name": "xmark", + "animated": false + }, + { + "id": "1283764031043276800", + "name": "member", + "animated": false + }, + { + "id": "1283833956877471798", + "name": "line", + "animated": false + }, + { + "id": "1283834008773329021", + "name": "dash", + "animated": false + } +] \ No newline at end of file diff --git a/lib/Client/NeetButton/NeetButton.ts b/lib/Client/NeetButton/NeetButton.ts deleted file mode 100644 index 5f2a808..0000000 --- a/lib/Client/NeetButton/NeetButton.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { ButtonInteraction } from "discord.js"; -import { NeetButtonParameters } from "./NeetButtonParameters"; - -export interface IParameter { - name: string; - value: string; -} - -interface IParseId { - identifiers: { - id: string; - subId: string | undefined; - }; - - _parameters: IParameter[]; - parameters: NeetButtonParameters; -} - -export class NeetButton { - interaction: ButtonInteraction; - - public constructor(interaction: ButtonInteraction) { - this.interaction = interaction; - } - - /** - * @example - * setCustomId("{identifier}/{sub-id}={arg_1},{arg_2}") - * setCustomId("moderation/viewcase=(userId:1234),(number:0)") - */ - public parseId(customId?: string): IParseId { - if (!customId) customId = this.interaction.customId; - - const identifier = customId.split("/"); // => name/sub=...(k:v); - const args = customId.split("=").at(1); // => ...(k:v) - const values = []; - - let id = identifier.at(0); - const subId = identifier.at(1)?.split("=").at(0); - if (!id) id = this.interaction.customId; - - if (args) { - for (const arg of args.split(",")) { - const argument = arg.replace("(", "").replace(")", ""); - const name = argument.split(":").at(0); - const value = argument.split(":").at(1); - if (name && value) values.push({ name, value }); - } - } - - return { - identifiers: { - id, - subId, - }, - - _parameters: values, - parameters: new NeetButtonParameters(values), - }; - } - - /** - * @example - * this.generateId("this/that", [ - * { name: "name", value: "value" } - * ]); - * - * // Usable example - * this.generateId([ - * { name: "user_nickname", value: "xyz" }, - * { name: "user_id", value: "100000000000000000" } - * ], "whois", "user") - */ - static generateId(id: string, sub?: string) { - let finalId: string = `${id}${sub ? `/${sub}` : ""}`; - - return { - generatedId: finalId, - - setParameters: (parameters: IParameter[]) => { - let i: number = 0; - for (const parameter of parameters) { - i++; - finalId += `${i === 1 ? "=" : ""}(${parameter.name}:${parameter.value})${i > 0 ? "," : ""}`; - } - - return finalId; - }, - }; - } -} diff --git a/lib/Client/NeetButton/NeetButtonParameters.ts b/lib/Client/NeetButton/NeetButtonParameters.ts deleted file mode 100644 index 0723dc8..0000000 --- a/lib/Client/NeetButton/NeetButtonParameters.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { IParameter } from "./NeetButton"; - -export class NeetButtonParameters { - param: IParameter[]; - - public constructor(parameters: IParameter[]) { - this.param = parameters; - } - - public get(name: string) { - const param = this.param.find((v) => v.name === name); - if (!param) return null; - return param.value; - } - - public boolean(name: string, required?: boolean) { - const value = this.get(name); - if (!value) { - if (required) - throw new Error("NeetButton, option is requirer but got null"); - - return null; - } - - return value === "true" ? true : false; - } -} diff --git a/lib/Client/utils/NeetComponents.ts b/lib/Client/utils/NeetComponents.ts new file mode 100644 index 0000000..12df0a3 --- /dev/null +++ b/lib/Client/utils/NeetComponents.ts @@ -0,0 +1,113 @@ +/** + * Utility methods for components (buttons, modals & selectMenu) + */ + +import { RestOrArray, normalizeArray } from "discord.js"; + +/** + * ### Parse the customId passed to AnyComponentBuilder + * + * customId should be formatted in a special way (for any component) + * @example + * .setCustomId("id/sub-id=(username:xyz)") + */ +export function parseId(id: string): ParsedResult { + const identifiers = id.split("/"); + const main = identifiers[0]; + const sub = identifiers[1].split("=")[0]; + const args = id.split("=")[1]; + const params = []; + + if (args != undefined) { + for (const arg of args.split("ยป")) { + const argument = arg.replace("(", "").replace(")", ""); + const name = argument.split(":").at(0); + const value = argument.split(":").at(1); + if (name && value) params.push({ name, value }); + } + } + + return { + id: main, + sub_id: sub, + args: params, + }; +} + +/** + * ### Create a customId that can be used in ANY component with this function + * **NOTE:** A customId cannot contain more than 100 chars + * will throw an error if it does. + * + * @example + * // Without arguments. + * customId("main", "sub"); + * + * // With arguments. + * customId("main", "sub", [{ name: "username", value: "0sapphy" }]); + */ +export function customId( + main: string, + sub: string, + args?: RestOrArray, +) { + if (args != undefined) { + let id = `${main}/${sub}=`; + let i = 0; + for (const arg of normalizeArray(args)) { + i++; + id += `(${arg.name}:${arg.value})${i > 0 && i != args.length ? "ยป" : ""}`; + } + + if (id.length > 100) + throw Error("An customId cannot contain MORE than 100 chars."); + return id; + } + + return `${main}/${sub}`; +} + +export function componentGetOption( + result: Arguments[], + name: string, + required?: boolean, +) { + if (required === undefined) required = false; + const arg = result.find((i) => i.name === name); + if (!arg?.value) { + if (required) + throw Error("Required componentGetString(): but got no value."); + return null; + } + + return arg; +} + +export function componentGetString( + result: Arguments[], + name: string, + required?: boolean, +) { + const res = componentGetOption(result, name, required); + return res?.value.toString(); +} + +export function componentGetBoolean( + result: Arguments[], + name: string, + required?: boolean, +) { + const res = componentGetOption(result, name, required); + return Boolean(res?.value); +} + +export interface Arguments { + name: string; + value: string | boolean | number; +} + +interface ParsedResult { + id: string; + sub_id: string; + args: Arguments[] | never[]; +} diff --git a/lib/Parser/index.components.ts b/lib/Parser/index.components.ts new file mode 100644 index 0000000..70a23a9 --- /dev/null +++ b/lib/Parser/index.components.ts @@ -0,0 +1,33 @@ +import parser from "qs"; + +/** + * ID - The main identifier, this is required. Prefix = I: + * [I]=member* + * + * SUBID - This is not required: Prefix = S: + * *[S]=0* - No SUBID ; *[S]=whois WITH SUBID + * + * ARGS - This is not required: Prefix = A: + * *A[username]=0sapphy&A[command]=whois + * + * How id arguments string should be formatted: + * + * @example + * new Builder() + * .setCustomId("[I]=member&[S]=whois&A[userId]=1234") // With ID, SUBID & ARGS + * .setCustomId("[I]=member&[S]=whois") // With ID & SUBID + * .setCustomId("[I]=member&A[username]=0sapphy&A[command]=whois") // With ID & MULTI-ARGS + */ +export function Parse(id: string) { + return parser.parse(id) as { I: string; S?: string; A?: object } +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function CompileArguments(A: any) { + const args = {}; + for (const ARG of Object.keys(A)) { + Object.assign(args, { [ARG]: A[ARG] }) + } + + return args; +} \ No newline at end of file diff --git a/lib/index.ts b/lib/index.ts index dcad81d..fc999e0 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,5 +1,7 @@ +/** CLIENT HELPERS */ export * from "./Client/Neet"; export * from "./Client/Event"; export * from "./Client/CommandBuilder"; -export * from "./Client/NeetButton/NeetButton" -export * from "./Client/NeetButton/NeetButtonParameters" + +/** UTILITY HELPERS */ +export * from "./Client/utils/NeetComponents"; diff --git a/package.json b/package.json index 5da4bce..5f31e1b 100644 --- a/package.json +++ b/package.json @@ -1,30 +1,54 @@ { "name": "neet", - "version": "1.3.1", + "version": "1.4.1", "description": "Neet, a utility based moderation bot.", "main": "dist/src/bot.js", "scripts": { "start": "rm -rf dist && tsc && node .", "dev": "tsc && node .", - "test": "tsc && node dist/src/__test.js" + "dev:emoji": "node dist/scripts/emojis", + "test": "" }, "author": "0sapphy", "license": "MIT", "dependencies": { + "@napi-rs/canvas": "^0.1.56", + "@typegoose/typegoose": "^12.8.0", + "axios": "^1.7.7", "chalk": "^4.1.0", "discord.js": "^14.16.1", "moment": "^2.30.1", "moment-timezone": "^0.5.45", - "mongoose": "^8.6.1" + "mongoose": "^8.7.2", + "neet-canvas.js": "^0.0.2", + "prompts": "^2.4.2", + "qs": "^6.13.0", + "signale": "^1.4.0" }, "devDependencies": { "@eslint/js": "^9.12.0", "@favware/cliff-jumper": "^4.1.0", - "eslint": "^8.57.1", + "@types/prompts": "^2.4.9", + "@types/qs": "^6.9.16", + "@types/signale": "^1.4.7", + "eslint": "^9.13.0", "globals": "^15.10.0", "prettier": "^3.3.3", "prettier-eslint": "^16.3.0", "typescript": "^5.6.2", "typescript-eslint": "^8.8.0" + }, + "signale": { + "displayScope": true, + "displayBadge": true, + "displayDate": true, + "displayFilename": false, + "displayLabel": true, + "displayTimestamp": false, + "underlineLabel": true, + "underlineMessage": false, + "underlinePrefix": true, + "underlineSuffix": false, + "uppercaseLabel": false } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..0c87a6f --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2968 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@napi-rs/canvas': + specifier: ^0.1.56 + version: 0.1.58 + '@typegoose/typegoose': + specifier: ^12.8.0 + version: 12.8.0(mongoose@8.7.2) + axios: + specifier: ^1.7.7 + version: 1.7.7 + chalk: + specifier: ^4.1.0 + version: 4.1.2 + discord.js: + specifier: ^14.16.1 + version: 14.16.3 + moment: + specifier: ^2.30.1 + version: 2.30.1 + moment-timezone: + specifier: ^0.5.45 + version: 0.5.46 + mongoose: + specifier: ^8.7.2 + version: 8.7.2 + neet-canvas.js: + specifier: ^0.0.2 + version: 0.0.2 + prompts: + specifier: ^2.4.2 + version: 2.4.2 + qs: + specifier: ^6.13.0 + version: 6.13.0 + signale: + specifier: ^1.4.0 + version: 1.4.0 + devDependencies: + '@eslint/js': + specifier: ^9.12.0 + version: 9.13.0 + '@favware/cliff-jumper': + specifier: ^4.1.0 + version: 4.1.0 + '@types/prompts': + specifier: ^2.4.9 + version: 2.4.9 + '@types/qs': + specifier: ^6.9.16 + version: 6.9.16 + '@types/signale': + specifier: ^1.4.7 + version: 1.4.7 + eslint: + specifier: ^9.13.0 + version: 9.13.0 + globals: + specifier: ^15.10.0 + version: 15.11.0 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + prettier-eslint: + specifier: ^16.3.0 + version: 16.3.0 + typescript: + specifier: ^5.6.2 + version: 5.6.3 + typescript-eslint: + specifier: ^8.8.0 + version: 8.11.0(eslint@9.13.0)(typescript@5.6.3) + +packages: + + '@conventional-changelog/git-client@1.0.1': + resolution: {integrity: sha512-PJEqBwAleffCMETaVm/fUgHldzBE35JFk3/9LL6NUA5EXa3qednu+UT6M7E5iBu3zIQZCULYIiZ90fBYHt6xUw==} + engines: {node: '>=18'} + peerDependencies: + conventional-commits-filter: ^5.0.0 + conventional-commits-parser: ^6.0.0 + peerDependenciesMeta: + conventional-commits-filter: + optional: true + conventional-commits-parser: + optional: true + + '@discordjs/builders@1.9.0': + resolution: {integrity: sha512-0zx8DePNVvQibh5ly5kCEei5wtPBIUbSoE9n+91Rlladz4tgtFbJ36PZMxxZrTEOQ7AHMZ/b0crT/0fCy6FTKg==} + engines: {node: '>=18'} + + '@discordjs/collection@1.5.3': + resolution: {integrity: sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@2.1.1': + resolution: {integrity: sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==} + engines: {node: '>=18'} + + '@discordjs/formatters@0.5.0': + resolution: {integrity: sha512-98b3i+Y19RFq1Xke4NkVY46x8KjJQjldHUuEbCqMvp1F5Iq9HgnGpu91jOi/Ufazhty32eRsKnnzS8n4c+L93g==} + engines: {node: '>=18'} + + '@discordjs/rest@2.4.0': + resolution: {integrity: sha512-Xb2irDqNcq+O8F0/k/NaDp7+t091p+acb51iA4bCKfIn+WFWd6HrNvcsSbMMxIR9NjcMZS6NReTKygqiQN+ntw==} + engines: {node: '>=18'} + + '@discordjs/util@1.1.1': + resolution: {integrity: sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==} + engines: {node: '>=18'} + + '@discordjs/ws@1.1.1': + resolution: {integrity: sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==} + engines: {node: '>=16.11.0'} + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.11.1': + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.7.0': + resolution: {integrity: sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@9.13.0': + resolution: {integrity: sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.1': + resolution: {integrity: sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@favware/cliff-jumper@4.1.0': + resolution: {integrity: sha512-z8U6XecZr3F7nkq2d+dg+QXaHcBh+DugUuVQGwIEo2vpAPOFkZ0Xnz3YbnTu0zPlr9lDEWL/rbnGEr0lwCaGOA==} + engines: {node: '>=v18'} + hasBin: true + + '@favware/colorette-spinner@1.0.1': + resolution: {integrity: sha512-PPYtcLzhSafdylp8NBOxMCYIcLqTUMNiQc7ciBoAIvxNG2egM+P7e2nNPui5+Svyk89Q+Tnbrp139ZRIIBw3IA==} + engines: {node: '>=v16'} + + '@humanfs/core@0.19.0': + resolution: {integrity: sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.5': + resolution: {integrity: sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@mongodb-js/saslprep@1.1.9': + resolution: {integrity: sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==} + + '@napi-rs/canvas-android-arm64@0.1.58': + resolution: {integrity: sha512-0bwURPP2jNTRoZ++sLbUubYS8MQdoJrEp8T1Z5QNu6Msf2DZXYSyfNrzeA/I+3TfNmJ5r3kQueSxHA89e7CLUQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@napi-rs/canvas-darwin-arm64@0.1.58': + resolution: {integrity: sha512-3AetouQtGTDldvIV9t7iZ6eZlwnn1r32GLr6zxmJmjDFQs5Ey1LYC7hYRYzRHx2fgU/slvwfMhgQjlH+T+vrlw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@napi-rs/canvas-darwin-x64@0.1.58': + resolution: {integrity: sha512-JwF2yTqzlvBAon4/GvzQf5RpCpcy4vusi4GZA35B0UI66+6DJv0J83E+tCuMJgCywk9GqUNEH9ozXqZsSMc7hw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.58': + resolution: {integrity: sha512-I0perR7XYeUFCASZJ3eMoCJz690PpZcq+9/kItOfqzH2+EO2I+MTn194p2YPHENzC+kybTUUucl9jyQDzRuZUg==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@napi-rs/canvas-linux-arm64-gnu@0.1.58': + resolution: {integrity: sha512-9U/T2N2aVOQ2OcIxWxOP3GXXuBZkNFtvZFVW+Uiov6qRiTeu3xjqrvAP+CSWhpVIW+GhR3rhlcYZY73rlVcJjQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@napi-rs/canvas-linux-arm64-musl@0.1.58': + resolution: {integrity: sha512-CyPvv0CoZLn64t3zhgNy5Jd8QE5lKy+dcbkP/CT2XRNAJ8eulO1qr5gcKZBOhXkPFSHHjYcLHWuHK/6/KvggcQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@napi-rs/canvas-linux-x64-gnu@0.1.58': + resolution: {integrity: sha512-lt1KsWrdB0SJ1fhxGW1y1aLv+Xy+7/qQ/80oh+nbstqLqziMRUYkLOmsIKiMlqvv3zETa6VUPofi8dZmCbNUOQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@napi-rs/canvas-linux-x64-musl@0.1.58': + resolution: {integrity: sha512-YCQwtulayB1Y+lJi9p3vLGs5q9udRsx9cRDY1fnyPAQnsGO5Snub/MZltYgEKUDlUlJxAcnVJlMUKPWT/zIR+w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@napi-rs/canvas-win32-x64-msvc@0.1.58': + resolution: {integrity: sha512-qyRhuEqyoSQTBRHLKvShfjueqVWWtsG2U3yaxAE9Yhkg0sx6lunH7fPPrFcIKxbQ4k8pAbmWebhi9xPVf6mYPQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@napi-rs/canvas@0.1.58': + resolution: {integrity: sha512-XDeVEFbXfiiXeB9816rlbSZyOysJPaQTKYG7u/wL3GQhg4YznZkjq8vEsNvK6C+bJx29OV8INu9bmfXPaE4Drw==} + engines: {node: '>= 10'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@octokit/auth-token@5.1.1': + resolution: {integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==} + engines: {node: '>= 18'} + + '@octokit/core@6.1.2': + resolution: {integrity: sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==} + engines: {node: '>= 18'} + + '@octokit/endpoint@10.1.1': + resolution: {integrity: sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==} + engines: {node: '>= 18'} + + '@octokit/graphql@8.1.1': + resolution: {integrity: sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==} + engines: {node: '>= 18'} + + '@octokit/openapi-types@22.2.0': + resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==} + + '@octokit/plugin-retry@7.1.2': + resolution: {integrity: sha512-XOWnPpH2kJ5VTwozsxGurw+svB2e61aWlmk5EVIYZPwFK5F9h4cyPyj9CIKRyMXMHSwpIsI3mPOdpMmrRhe7UQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/request-error@6.1.5': + resolution: {integrity: sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==} + engines: {node: '>= 18'} + + '@octokit/request@9.1.3': + resolution: {integrity: sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==} + engines: {node: '>= 18'} + + '@octokit/types@13.6.1': + resolution: {integrity: sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==} + + '@sapphire/async-queue@1.5.3': + resolution: {integrity: sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@sapphire/result@2.6.6': + resolution: {integrity: sha512-QCjj7X/QlY0QUCeAaZQmnrsMH/b2BMQYee3F1Y5iF17JagUQqO3KZlG7vfXWQU3SRAJX5OgZZynBjixUH+nNGg==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@sapphire/shapeshift@4.0.0': + resolution: {integrity: sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==} + engines: {node: '>=v16'} + + '@sapphire/snowflake@3.5.3': + resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@sapphire/utilities@3.17.0': + resolution: {integrity: sha512-bbqjnKKrCgyT0C3+KOjIBzE6z6/v764EFuV7Uxw9WeIdkqGhwepl6tuNEzgiek/JdtEcODaPeX0K1aCt53yCcA==} + engines: {node: '>=v14.0.0'} + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@typegoose/typegoose@12.8.0': + resolution: {integrity: sha512-YCeYYH0joT4n48WRUfofPq3KBg6OQw1zR6wB4WKflkFYf9SC4P29hf0PlmsiA+hAbubd3Qn51KmkjiUJetJmFQ==} + engines: {node: '>=16.20.1'} + peerDependencies: + mongoose: ~8.7.0 + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@22.7.9': + resolution: {integrity: sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==} + + '@types/prompts@2.4.9': + resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} + + '@types/qs@6.9.16': + resolution: {integrity: sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==} + + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + + '@types/signale@1.4.7': + resolution: {integrity: sha512-nc0j37QupTT7OcYeH3gRE1ZfzUalEUsDKJsJ3IsJr0pjjFZTjtrX1Bsn6Kv56YXI/H9rNSwAkIPRxNlZI8GyQw==} + + '@types/webidl-conversions@7.0.3': + resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==} + + '@types/whatwg-url@11.0.5': + resolution: {integrity: sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==} + + '@types/ws@8.5.12': + resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} + + '@typescript-eslint/eslint-plugin@8.11.0': + resolution: {integrity: sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@6.21.0': + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@8.11.0': + resolution: {integrity: sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@6.21.0': + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/scope-manager@8.11.0': + resolution: {integrity: sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.11.0': + resolution: {integrity: sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@6.21.0': + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/types@8.11.0': + resolution: {integrity: sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@6.21.0': + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/typescript-estree@8.11.0': + resolution: {integrity: sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@8.11.0': + resolution: {integrity: sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + '@typescript-eslint/visitor-keys@6.21.0': + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/visitor-keys@8.11.0': + resolution: {integrity: sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@vladfrangu/async_event_emitter@2.4.6': + resolution: {integrity: sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.13.0: + resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@2.2.1: + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} + engines: {node: '>=0.10.0'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + before-after-hook@3.0.2: + resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} + + bottleneck@2.19.5: + resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + bson@6.9.0: + resolution: {integrity: sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==} + engines: {node: '>=16.20.1'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chalk@1.1.3: + resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} + engines: {node: '>=0.10.0'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + common-tags@1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + conventional-changelog-preset-loader@5.0.0: + resolution: {integrity: sha512-SetDSntXLk8Jh1NOAl1Gu5uLiCNSYenB5tm0YVeZKePRIgDW9lQImromTwLa3c/Gae298tsgOM+/CYT9XAl0NA==} + engines: {node: '>=18'} + + conventional-commits-filter@5.0.0: + resolution: {integrity: sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==} + engines: {node: '>=18'} + + conventional-commits-parser@6.0.0: + resolution: {integrity: sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==} + engines: {node: '>=18'} + hasBin: true + + conventional-recommended-bump@10.0.0: + resolution: {integrity: sha512-RK/fUnc2btot0oEVtrj3p2doImDSs7iiz/bftFCDzels0Qs1mxLghp+DFHMaOC0qiCI6sWzlTDyBFSYuot6pRA==} + engines: {node: '>=18'} + hasBin: true + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + discord-api-types@0.37.100: + resolution: {integrity: sha512-a8zvUI0GYYwDtScfRd/TtaNBDTXwP5DiDVX7K5OmE+DRT57gBqKnwtOC5Ol8z0mRW8KQfETIgiB8U0YZ9NXiCA==} + + discord-api-types@0.37.83: + resolution: {integrity: sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==} + + discord-api-types@0.37.97: + resolution: {integrity: sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA==} + + discord.js@14.16.3: + resolution: {integrity: sha512-EPCWE9OkA9DnFFNrO7Kl1WHHDYFXu3CNVFJg63bfU7hVtjZGyhShwZtSBImINQRWxWP2tgo2XI+QhdXx28r0aA==} + engines: {node: '>=18'} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-scope@8.1.0: + resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.1.0: + resolution: {integrity: sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + eslint@9.13.0: + resolution: {integrity: sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.2.0: + resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} + engines: {node: ^18.19.0 || >=20.5.0} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + figures@2.0.0: + resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} + engines: {node: '>=4'} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + git-cliff-darwin-arm64@2.6.1: + resolution: {integrity: sha512-uzLlHGXgOf6gzBaloWdfBCfqQFKTcitT65IgtdH1mEX03SLgRFJUhlw4tYbTXVwdPgfWSoP1LGO+b+D4/s8X9g==} + cpu: [arm64] + os: [darwin] + + git-cliff-darwin-x64@2.6.1: + resolution: {integrity: sha512-sx8ppi6Lb0rd96gT6GBKtZlssCm1GbpNsI+vUO1quMyRMSpfI/6TtIQNiLO59M2LNqzGXemC7ULyX0ENAh9QWA==} + cpu: [x64] + os: [darwin] + + git-cliff-linux-arm64@2.6.1: + resolution: {integrity: sha512-T2Y7K4kBdGyD5GIZGYRLgbl0uRYVyBhWfQYj8emnt1XSvF/XaLGhi6hNPJuNCB+394HuhMtb2vV3G3S4uTumxg==} + cpu: [arm64] + os: [linux] + + git-cliff-linux-x64@2.6.1: + resolution: {integrity: sha512-4Y+kEM8JYT7HPgt++DEaqWW/SDxJ9iotork15sTP3fOiRMZi8p58ifjHEfPYVUup/hLpTmH2aiX72HNKa4gwRA==} + cpu: [x64] + os: [linux] + + git-cliff-windows-arm64@2.6.1: + resolution: {integrity: sha512-6xx3AWYeJ00Y/KZb78j9QX0sG+mMav9q/FCexuf89aTs5QjGJfXWtEB7DijvH/m4FDYqVjWcXyt9+ST9eBx0eg==} + cpu: [arm64] + os: [win32] + + git-cliff-windows-x64@2.6.1: + resolution: {integrity: sha512-hRsOv0kVU/cKt9rglWYPuv84ZI1MflhhzQrycz99xF7heGbob4RRgcuN0JXnYPf3q8ATnMgsVlMccaIRXuJFGg==} + cpu: [x64] + os: [win32] + + git-cliff@2.6.1: + resolution: {integrity: sha512-dxquXEx+dRWbggtxQzH2GpgCr6F+HjuY/jZA5QCc1AdvWfq010BxlRElrH7mgS2fHvvybY9gSw7qQEBk3tSM4Q==} + engines: {node: '>=18.19 || >=20.6 || >=21'} + hasBin: true + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.11.0: + resolution: {integrity: sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==} + engines: {node: '>=18'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-ansi@2.0.0: + resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} + engines: {node: '>=0.10.0'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + human-signals@8.0.0: + resolution: {integrity: sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==} + engines: {node: '>=18.18.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + kareem@2.6.3: + resolution: {integrity: sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==} + engines: {node: '>=12.0.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + loglevel-colored-level-prefix@1.0.0: + resolution: {integrity: sha512-u45Wcxxc+SdAlh4yeF/uKlC1SPUPCy0gullSNKXod5I4bmifzk+Q4lSLExNEVn19tGaJipbZ4V4jbFn79/6mVA==} + + loglevel@1.9.2: + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} + engines: {node: '>= 0.6.0'} + + magic-bytes.js@1.10.0: + resolution: {integrity: sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==} + + memory-pager@1.5.0: + resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} + + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} + engines: {node: '>=18'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + moment-timezone@0.5.46: + resolution: {integrity: sha512-ZXm9b36esbe7OmdABqIWJuBBiLLwAjrN7CE+7sYdCCx82Nabt1wHDj8TVseS59QIlfFPbOoiBPm6ca9BioG4hw==} + + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + + mongodb-connection-string-url@3.0.1: + resolution: {integrity: sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==} + + mongodb@6.9.0: + resolution: {integrity: sha512-UMopBVx1LmEUbW/QE0Hw18u583PEDVQmUmVzzBRH0o/xtE9DBRA5ZYLOjpLIa03i8FXjzvQECJcqoMvCXftTUA==} + engines: {node: '>=16.20.1'} + peerDependencies: + '@aws-sdk/credential-providers': ^3.188.0 + '@mongodb-js/zstd': ^1.1.0 + gcp-metadata: ^5.2.0 + kerberos: ^2.0.1 + mongodb-client-encryption: '>=6.0.0 <7' + snappy: ^7.2.2 + socks: ^2.7.1 + peerDependenciesMeta: + '@aws-sdk/credential-providers': + optional: true + '@mongodb-js/zstd': + optional: true + gcp-metadata: + optional: true + kerberos: + optional: true + mongodb-client-encryption: + optional: true + snappy: + optional: true + socks: + optional: true + + mongoose@8.7.2: + resolution: {integrity: sha512-Ok4VzMds9p5G3ZSUhmvBm1GdxanbzhS29jpSn02SPj+IXEVFnIdfwAlHHXWkyNscZKlcn8GuMi68FH++jo0flg==} + engines: {node: '>=16.20.1'} + + mpath@0.9.0: + resolution: {integrity: sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==} + engines: {node: '>=4.0.0'} + + mquery@5.0.0: + resolution: {integrity: sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==} + engines: {node: '>=14.0.0'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + neet-canvas.js@0.0.2: + resolution: {integrity: sha512-hmX6RcLsViZDz1HGcSXlpYggo8m2Hf2vHhlwfYqVp4y11QEkxOf3i/BXLA53zb5tmX7c79rZEGpgLGG91h8KGQ==} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pkg-conf@2.1.0: + resolution: {integrity: sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==} + engines: {node: '>=4'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-eslint@16.3.0: + resolution: {integrity: sha512-Lh102TIFCr11PJKUMQ2kwNmxGhTsv/KzUg9QYF2Gkw259g/kPgndZDWavk7/ycbRvj2oz4BPZ1gCU8bhfZH/Xg==} + engines: {node: '>=16.10.0'} + peerDependencies: + prettier-plugin-svelte: ^3.0.0 + svelte-eslint-parser: '*' + peerDependenciesMeta: + prettier-plugin-svelte: + optional: true + svelte-eslint-parser: + optional: true + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + pretty-ms@9.1.0: + resolution: {integrity: sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==} + engines: {node: '>=18'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + require-relative@0.8.7: + resolution: {integrity: sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + sift@17.1.3: + resolution: {integrity: sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + signale@1.4.0: + resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==} + engines: {node: '>=6'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + smol-toml@1.3.0: + resolution: {integrity: sha512-tWpi2TsODPScmi48b/OQZGi2lgUmBCHy6SZrhi/FdnnHiU1GwebbCfuQuxsC3nHaLwtYeJGPrDZDIeodDOc4pA==} + engines: {node: '>= 18'} + + sparse-bitfield@3.0.3: + resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} + + strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@2.0.0: + resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} + engines: {node: '>=0.8.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tr46@4.1.1: + resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} + engines: {node: '>=14'} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-mixer@6.0.4: + resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} + + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + typescript-eslint@8.11.0: + resolution: {integrity: sha512-cBRGnW3FSlxaYwU8KfAewxFK5uzeOAp0l2KebIlPDOT5olVi65KDG/yjBooPBG0kGW/HLkoz1c/iuBFehcS3IA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + undici@6.19.8: + resolution: {integrity: sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==} + engines: {node: '>=18.17'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + universal-user-agent@7.0.2: + resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-url@13.0.0: + resolution: {integrity: sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==} + engines: {node: '>=16'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + +snapshots: + + '@conventional-changelog/git-client@1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)': + dependencies: + '@types/semver': 7.5.8 + semver: 7.6.3 + optionalDependencies: + conventional-commits-filter: 5.0.0 + conventional-commits-parser: 6.0.0 + + '@discordjs/builders@1.9.0': + dependencies: + '@discordjs/formatters': 0.5.0 + '@discordjs/util': 1.1.1 + '@sapphire/shapeshift': 4.0.0 + discord-api-types: 0.37.97 + fast-deep-equal: 3.1.3 + ts-mixer: 6.0.4 + tslib: 2.8.0 + + '@discordjs/collection@1.5.3': {} + + '@discordjs/collection@2.1.1': {} + + '@discordjs/formatters@0.5.0': + dependencies: + discord-api-types: 0.37.97 + + '@discordjs/rest@2.4.0': + dependencies: + '@discordjs/collection': 2.1.1 + '@discordjs/util': 1.1.1 + '@sapphire/async-queue': 1.5.3 + '@sapphire/snowflake': 3.5.3 + '@vladfrangu/async_event_emitter': 2.4.6 + discord-api-types: 0.37.97 + magic-bytes.js: 1.10.0 + tslib: 2.8.0 + undici: 6.19.8 + + '@discordjs/util@1.1.1': {} + + '@discordjs/ws@1.1.1': + dependencies: + '@discordjs/collection': 2.1.1 + '@discordjs/rest': 2.4.0 + '@discordjs/util': 1.1.1 + '@sapphire/async-queue': 1.5.3 + '@types/ws': 8.5.12 + '@vladfrangu/async_event_emitter': 2.4.6 + discord-api-types: 0.37.83 + tslib: 2.8.0 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.4.0(eslint@9.13.0)': + dependencies: + eslint: 9.13.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.11.1': {} + + '@eslint/config-array@0.18.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.7.0': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.3.7 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/eslintrc@3.1.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.7 + espree: 10.2.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@eslint/js@9.13.0': {} + + '@eslint/object-schema@2.1.4': {} + + '@eslint/plugin-kit@0.2.1': + dependencies: + levn: 0.4.1 + + '@favware/cliff-jumper@4.1.0': + dependencies: + '@favware/colorette-spinner': 1.0.1 + '@octokit/auth-token': 5.1.1 + '@octokit/core': 6.1.2 + '@octokit/plugin-retry': 7.1.2(@octokit/core@6.1.2) + '@sapphire/result': 2.6.6 + '@sapphire/utilities': 3.17.0 + colorette: 2.0.20 + commander: 12.1.0 + conventional-recommended-bump: 10.0.0 + execa: 9.4.1 + git-cliff: 2.6.1 + js-yaml: 4.1.0 + semver: 7.6.3 + smol-toml: 1.3.0 + + '@favware/colorette-spinner@1.0.1': + dependencies: + colorette: 2.0.20 + + '@humanfs/core@0.19.0': {} + + '@humanfs/node@0.16.5': + dependencies: + '@humanfs/core': 0.19.0 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@mongodb-js/saslprep@1.1.9': + dependencies: + sparse-bitfield: 3.0.3 + + '@napi-rs/canvas-android-arm64@0.1.58': + optional: true + + '@napi-rs/canvas-darwin-arm64@0.1.58': + optional: true + + '@napi-rs/canvas-darwin-x64@0.1.58': + optional: true + + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.58': + optional: true + + '@napi-rs/canvas-linux-arm64-gnu@0.1.58': + optional: true + + '@napi-rs/canvas-linux-arm64-musl@0.1.58': + optional: true + + '@napi-rs/canvas-linux-x64-gnu@0.1.58': + optional: true + + '@napi-rs/canvas-linux-x64-musl@0.1.58': + optional: true + + '@napi-rs/canvas-win32-x64-msvc@0.1.58': + optional: true + + '@napi-rs/canvas@0.1.58': + optionalDependencies: + '@napi-rs/canvas-android-arm64': 0.1.58 + '@napi-rs/canvas-darwin-arm64': 0.1.58 + '@napi-rs/canvas-darwin-x64': 0.1.58 + '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.58 + '@napi-rs/canvas-linux-arm64-gnu': 0.1.58 + '@napi-rs/canvas-linux-arm64-musl': 0.1.58 + '@napi-rs/canvas-linux-x64-gnu': 0.1.58 + '@napi-rs/canvas-linux-x64-musl': 0.1.58 + '@napi-rs/canvas-win32-x64-msvc': 0.1.58 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@octokit/auth-token@5.1.1': {} + + '@octokit/core@6.1.2': + dependencies: + '@octokit/auth-token': 5.1.1 + '@octokit/graphql': 8.1.1 + '@octokit/request': 9.1.3 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + before-after-hook: 3.0.2 + universal-user-agent: 7.0.2 + + '@octokit/endpoint@10.1.1': + dependencies: + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/graphql@8.1.1': + dependencies: + '@octokit/request': 9.1.3 + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/openapi-types@22.2.0': {} + + '@octokit/plugin-retry@7.1.2(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + bottleneck: 2.19.5 + + '@octokit/request-error@6.1.5': + dependencies: + '@octokit/types': 13.6.1 + + '@octokit/request@9.1.3': + dependencies: + '@octokit/endpoint': 10.1.1 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/types@13.6.1': + dependencies: + '@octokit/openapi-types': 22.2.0 + + '@sapphire/async-queue@1.5.3': {} + + '@sapphire/result@2.6.6': {} + + '@sapphire/shapeshift@4.0.0': + dependencies: + fast-deep-equal: 3.1.3 + lodash: 4.17.21 + + '@sapphire/snowflake@3.5.3': {} + + '@sapphire/utilities@3.17.0': {} + + '@sec-ant/readable-stream@0.4.1': {} + + '@sinclair/typebox@0.27.8': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@typegoose/typegoose@12.8.0(mongoose@8.7.2)': + dependencies: + lodash: 4.17.21 + loglevel: 1.9.2 + mongoose: 8.7.2 + reflect-metadata: 0.2.2 + semver: 7.6.3 + tslib: 2.8.0 + + '@types/estree@1.0.6': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@22.7.9': + dependencies: + undici-types: 6.19.8 + + '@types/prompts@2.4.9': + dependencies: + '@types/node': 22.7.9 + kleur: 3.0.3 + + '@types/qs@6.9.16': {} + + '@types/semver@7.5.8': {} + + '@types/signale@1.4.7': + dependencies: + '@types/node': 22.7.9 + + '@types/webidl-conversions@7.0.3': {} + + '@types/whatwg-url@11.0.5': + dependencies: + '@types/webidl-conversions': 7.0.3 + + '@types/ws@8.5.12': + dependencies: + '@types/node': 22.7.9 + + '@typescript-eslint/eslint-plugin@8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0)(typescript@5.6.3))(eslint@9.13.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 8.11.0(eslint@9.13.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/type-utils': 8.11.0(eslint@9.13.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.11.0 + eslint: 9.13.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.7 + eslint: 8.57.1 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.11.0(eslint@9.13.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/typescript-estree': 8.11.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.11.0 + debug: 4.3.7 + eslint: 9.13.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@6.21.0': + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + + '@typescript-eslint/scope-manager@8.11.0': + dependencies: + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/visitor-keys': 8.11.0 + + '@typescript-eslint/type-utils@8.11.0(eslint@9.13.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.11.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0)(typescript@5.6.3) + debug: 4.3.7 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - eslint + - supports-color + + '@typescript-eslint/types@6.21.0': {} + + '@typescript-eslint/types@8.11.0': {} + + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.6.3)': + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.7 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@8.11.0(typescript@5.6.3)': + dependencies: + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/visitor-keys': 8.11.0 + debug: 4.3.7 + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.11.0(eslint@9.13.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/typescript-estree': 8.11.0(typescript@5.6.3) + eslint: 9.13.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@6.21.0': + dependencies: + '@typescript-eslint/types': 6.21.0 + eslint-visitor-keys: 3.4.3 + + '@typescript-eslint/visitor-keys@8.11.0': + dependencies: + '@typescript-eslint/types': 8.11.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + + '@vladfrangu/async_event_emitter@2.4.6': {} + + acorn-jsx@5.3.2(acorn@8.13.0): + dependencies: + acorn: 8.13.0 + + acorn@8.13.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@2.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-styles@2.2.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + argparse@2.0.1: {} + + array-union@2.1.0: {} + + asynckit@0.4.0: {} + + axios@1.7.7: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + before-after-hook@3.0.2: {} + + bottleneck@2.19.5: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + bson@6.9.0: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + callsites@3.1.0: {} + + chalk@1.1.3: + dependencies: + ansi-styles: 2.2.1 + escape-string-regexp: 1.0.5 + has-ansi: 2.0.0 + strip-ansi: 3.0.1 + supports-color: 2.0.0 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@12.1.0: {} + + common-tags@1.8.2: {} + + concat-map@0.0.1: {} + + conventional-changelog-preset-loader@5.0.0: {} + + conventional-commits-filter@5.0.0: {} + + conventional-commits-parser@6.0.0: + dependencies: + meow: 13.2.0 + + conventional-recommended-bump@10.0.0: + dependencies: + '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0) + conventional-changelog-preset-loader: 5.0.0 + conventional-commits-filter: 5.0.0 + conventional-commits-parser: 6.0.0 + meow: 13.2.0 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + delayed-stream@1.0.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + discord-api-types@0.37.100: {} + + discord-api-types@0.37.83: {} + + discord-api-types@0.37.97: {} + + discord.js@14.16.3: + dependencies: + '@discordjs/builders': 1.9.0 + '@discordjs/collection': 1.5.3 + '@discordjs/formatters': 0.5.0 + '@discordjs/rest': 2.4.0 + '@discordjs/util': 1.1.1 + '@discordjs/ws': 1.1.1 + '@sapphire/snowflake': 3.5.3 + discord-api-types: 0.37.100 + fast-deep-equal: 3.1.3 + lodash.snakecase: 4.1.1 + tslib: 2.8.0 + undici: 6.19.8 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + dlv@1.1.3: {} + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-scope@8.1.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.1.0: {} + + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.11.1 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.7 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + eslint@9.13.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0) + '@eslint-community/regexpp': 4.11.1 + '@eslint/config-array': 0.18.0 + '@eslint/core': 0.7.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.13.0 + '@eslint/plugin-kit': 0.2.1 + '@humanfs/node': 0.16.5 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.7 + escape-string-regexp: 4.0.0 + eslint-scope: 8.1.0 + eslint-visitor-keys: 4.1.0 + espree: 10.2.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@10.2.0: + dependencies: + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) + eslint-visitor-keys: 4.1.0 + + espree@9.6.1: + dependencies: + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) + eslint-visitor-keys: 3.4.3 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + execa@9.4.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.3 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.1.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.1 + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + figures@2.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@2.1.0: + dependencies: + locate-path: 2.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + + flatted@3.3.1: {} + + follow-redirects@1.15.9: {} + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fs.realpath@1.0.0: {} + + function-bind@1.1.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-stream@8.0.1: {} + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + git-cliff-darwin-arm64@2.6.1: + optional: true + + git-cliff-darwin-x64@2.6.1: + optional: true + + git-cliff-linux-arm64@2.6.1: + optional: true + + git-cliff-linux-x64@2.6.1: + optional: true + + git-cliff-windows-arm64@2.6.1: + optional: true + + git-cliff-windows-x64@2.6.1: + optional: true + + git-cliff@2.6.1: + dependencies: + execa: 8.0.1 + optionalDependencies: + git-cliff-darwin-arm64: 2.6.1 + git-cliff-darwin-x64: 2.6.1 + git-cliff-linux-arm64: 2.6.1 + git-cliff-linux-x64: 2.6.1 + git-cliff-windows-arm64: 2.6.1 + git-cliff-windows-x64: 2.6.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globals@14.0.0: {} + + globals@15.11.0: {} + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-ansi@2.0.0: + dependencies: + ansi-regex: 2.1.1 + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + human-signals@5.0.0: {} + + human-signals@8.0.0: {} + + ignore@5.3.2: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-arrayish@0.2.1: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@4.1.0: {} + + is-stream@3.0.0: {} + + is-stream@4.0.1: {} + + is-unicode-supported@2.1.0: {} + + isexe@2.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-parse-better-errors@1.0.2: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + kareem@2.6.3: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@3.0.3: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + load-json-file@4.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + + locate-path@2.0.0: + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash.snakecase@4.1.1: {} + + lodash@4.17.21: {} + + loglevel-colored-level-prefix@1.0.0: + dependencies: + chalk: 1.1.3 + loglevel: 1.9.2 + + loglevel@1.9.2: {} + + magic-bytes.js@1.10.0: {} + + memory-pager@1.5.0: {} + + meow@13.2.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@4.0.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.3: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + moment-timezone@0.5.46: + dependencies: + moment: 2.30.1 + + moment@2.30.1: {} + + mongodb-connection-string-url@3.0.1: + dependencies: + '@types/whatwg-url': 11.0.5 + whatwg-url: 13.0.0 + + mongodb@6.9.0: + dependencies: + '@mongodb-js/saslprep': 1.1.9 + bson: 6.9.0 + mongodb-connection-string-url: 3.0.1 + + mongoose@8.7.2: + dependencies: + bson: 6.9.0 + kareem: 2.6.3 + mongodb: 6.9.0 + mpath: 0.9.0 + mquery: 5.0.0 + ms: 2.1.3 + sift: 17.1.3 + transitivePeerDependencies: + - '@aws-sdk/credential-providers' + - '@mongodb-js/zstd' + - gcp-metadata + - kerberos + - mongodb-client-encryption + - snappy + - socks + - supports-color + + mpath@0.9.0: {} + + mquery@5.0.0: + dependencies: + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + ms@2.1.3: {} + + natural-compare@1.4.0: {} + + neet-canvas.js@0.0.2: + dependencies: + '@napi-rs/canvas': 0.1.58 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + object-inspect@1.13.2: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@1.3.0: + dependencies: + p-try: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@2.0.0: + dependencies: + p-limit: 1.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-try@1.0.0: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@4.0.0: + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + + parse-ms@4.0.0: {} + + path-exists@3.0.0: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-type@4.0.0: {} + + picomatch@2.3.1: {} + + pify@3.0.0: {} + + pkg-conf@2.1.0: + dependencies: + find-up: 2.1.0 + load-json-file: 4.0.0 + + prelude-ls@1.2.1: {} + + prettier-eslint@16.3.0: + dependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.3) + common-tags: 1.8.2 + dlv: 1.1.3 + eslint: 8.57.1 + indent-string: 4.0.0 + lodash.merge: 4.6.2 + loglevel-colored-level-prefix: 1.0.0 + prettier: 3.3.3 + pretty-format: 29.7.0 + require-relative: 0.8.7 + typescript: 5.6.3 + vue-eslint-parser: 9.4.3(eslint@8.57.1) + transitivePeerDependencies: + - supports-color + + prettier@3.3.3: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + pretty-ms@9.1.0: + dependencies: + parse-ms: 4.0.0 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + qs@6.13.0: + dependencies: + side-channel: 1.0.6 + + queue-microtask@1.2.3: {} + + react-is@18.3.1: {} + + reflect-metadata@0.2.2: {} + + require-relative@0.8.7: {} + + resolve-from@4.0.0: {} + + reusify@1.0.4: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + semver@7.6.3: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + sift@17.1.3: {} + + signal-exit@4.1.0: {} + + signale@1.4.0: + dependencies: + chalk: 2.4.2 + figures: 2.0.0 + pkg-conf: 2.1.0 + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + smol-toml@1.3.0: {} + + sparse-bitfield@3.0.3: + dependencies: + memory-pager: 1.5.0 + + strip-ansi@3.0.1: + dependencies: + ansi-regex: 2.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-final-newline@4.0.0: {} + + strip-json-comments@3.1.1: {} + + supports-color@2.0.0: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + text-table@0.2.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tr46@4.1.1: + dependencies: + punycode: 2.3.1 + + ts-api-utils@1.3.0(typescript@5.6.3): + dependencies: + typescript: 5.6.3 + + ts-mixer@6.0.4: {} + + tslib@2.8.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + typescript-eslint@8.11.0(eslint@9.13.0)(typescript@5.6.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0)(typescript@5.6.3))(eslint@9.13.0)(typescript@5.6.3) + '@typescript-eslint/parser': 8.11.0(eslint@9.13.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0)(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - eslint + - supports-color + + typescript@5.6.3: {} + + undici-types@6.19.8: {} + + undici@6.19.8: {} + + unicorn-magic@0.3.0: {} + + universal-user-agent@7.0.2: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vue-eslint-parser@9.4.3(eslint@8.57.1): + dependencies: + debug: 4.3.7 + eslint: 8.57.1 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + lodash: 4.17.21 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + + webidl-conversions@7.0.0: {} + + whatwg-url@13.0.0: + dependencies: + tr46: 4.1.1 + webidl-conversions: 7.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrappy@1.0.2: {} + + ws@8.18.0: {} + + yocto-queue@0.1.0: {} + + yoctocolors@2.1.1: {} diff --git a/scripts/dev/discord.ts b/scripts/dev/discord.ts deleted file mode 100644 index 889f891..0000000 --- a/scripts/dev/discord.ts +++ /dev/null @@ -1,40 +0,0 @@ -export default { - official: - /(?:^|\b)discord(?:(?:app)?\.com\/invite|\.gg(?:\/invite)?)\/(?[\w-]{2,255})(?:$|\b)/gi, - - sources: [ - { - location: "discordservers.com", - redirect: "https://discordservers.com/server", - regexp: - /(?:^|\b)discordservers\.com\/server\/(?[\w-]{2,225})(?:$|\b)/gi, - }, - { - location: "disc.gg", - redirect: "https://disc.gg/", - regexp: /(?:^|\b)disc\.gg\/(?[\w-]{2,225})(?:$|\b)/gi, - }, - { - location: "disboard.org", - redirect: "https://disboard.org/server/join/", - regexp: - /(?:^|\b)disboard\.org\/server\/join\/(?[\d-]{18,22})(?:$|\b)/gi, - }, - { - location: "discadia.com", - redirect: "https://discadia.com/", - regexp: /(?:^|\b)discadia\.com\/(?[\w-]{2,225})(?:$|\b)/gi, - }, - { - location: "discords.com", - redirect: "https://discords.com/servers/", - regexp: - /(?:^|\b)discords\.com\/servers\/(?[\w-]{2,225})(?:$|\b)/gi, - }, - { - location: "discordfy.com", - redirect: "https://discordfy.com/", - regexp: /(?:^|\b)discordfy\.com\/(?[\w-]{2,225})(?:$|\b)/gi, - }, - ], -}; diff --git a/scripts/dev/emojis.json b/scripts/dev/emojis.json deleted file mode 100644 index c8be379..0000000 --- a/scripts/dev/emojis.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "Checkmark": { - "id": "1264544804365271070", - "name": "Checkmark", - "user": { - "id": "500658624109084682", - "username": "Emoji.gg", - "avatar": "a_16a7cdaa16344295c20f3d4cdd69995c", - "discriminator": "7083", - "public_flags": 65536, - "flags": 65536, - "bot": true, - "banner": null, - "accent_color": null, - "global_name": null, - "avatar_decoration_data": null, - "banner_color": null, - "clan": null - }, - "roles": [], - "require_colons": true, - "managed": false, - "animated": false, - "available": true - }, - "Xmark": { - "id": "1264683663430516868", - "name": "Xmark", - "user": { - "id": "500658624109084682", - "username": "Emoji.gg", - "avatar": "a_16a7cdaa16344295c20f3d4cdd69995c", - "discriminator": "7083", - "public_flags": 65536, - "flags": 65536, - "bot": true, - "banner": null, - "accent_color": null, - "global_name": null, - "avatar_decoration_data": null, - "banner_color": null, - "clan": null - }, - "roles": [], - "require_colons": true, - "managed": false, - "animated": false, - "available": true - }, - "Toggle_on": { - "id": "1266687420473282625", - "name": "Toggle_on", - "user": { - "id": "500658624109084682", - "username": "Emoji.gg", - "avatar": "a_16a7cdaa16344295c20f3d4cdd69995c", - "discriminator": "7083", - "public_flags": 65536, - "flags": 65536, - "bot": true, - "banner": null, - "accent_color": null, - "global_name": null, - "avatar_decoration_data": null, - "banner_color": null, - "clan": null - }, - "roles": [], - "require_colons": true, - "managed": false, - "animated": false, - "available": true - }, - "Toggle_OFF": { - "id": "1266687467080253441", - "name": "Toggle_OFF", - "user": { - "id": "500658624109084682", - "username": "Emoji.gg", - "avatar": "a_16a7cdaa16344295c20f3d4cdd69995c", - "discriminator": "7083", - "public_flags": 65536, - "flags": 65536, - "bot": true, - "banner": null, - "accent_color": null, - "global_name": null, - "avatar_decoration_data": null, - "banner_color": null, - "clan": null - }, - "roles": [], - "require_colons": true, - "managed": false, - "animated": false, - "available": true - } -} diff --git a/scripts/emojis.js b/scripts/emojis.js deleted file mode 100644 index 79fe476..0000000 --- a/scripts/emojis.js +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-disable @typescript-eslint/no-require-imports */ -process.loadEnvFile(".env"); - -(async () => { - console.info("[NEET]: Loading..."); - - const discord_api = "https://discord.com/api"; - - console.info("[NEET]: Fetching emojis in dev guild."); - - const res = await fetch( - `${discord_api}/guilds/${process.env.GUILD_ID}/emojis`, - { - method: "GET", - headers: { - Authorization: `Bot ${process.env.TOKEN}`, - }, - }, - ); - - console.info("[NEET]: Fetched emojis..."); - - const data = await res.json(); - - console.info(`[NEET]: Loaded ${data.length} emojis.`); - - const file_data = {}; - - console.info("[NEET]: Assign emoji data..."); - - for (const emoji of data) { - console.info(`[NEET]: Assigning ${emoji.name}...`); - - Object.assign(file_data, { - [emoji.name]: emoji, - }); - } - - console.info(`[NEET]: Saving emoji data to emojis.json`); - - require("node:fs/promises") - .writeFile("../scripts/dev/emojis.json", JSON.stringify(file_data, null, 1)) - .then(() => { - console.info(`[NEET]: Saved ${data.length} emojis to emojis.json`); - }) - .catch((_) => { - console.error(`[NEET]: Error saving emojis to emojis.json`, _); - }); -})(); diff --git a/scripts/emojis.ts b/scripts/emojis.ts new file mode 100644 index 0000000..b34510f --- /dev/null +++ b/scripts/emojis.ts @@ -0,0 +1,65 @@ +process.loadEnvFile(".env"); + +import Prompts from "prompts"; +import signale from "signale"; +import axios from "axios"; +import { writeFileSync } from "node:fs" + +const questions: Prompts.PromptObject = { + type: "confirm", + name: "confirm-sync", + message: "Are you sure you want to SYNC emojis?" +}; + +(async() => { + Prompts(questions, { + onCancel() { + signale.star({ prefix: `[SCRIPTS]`, message: `Okay, stopped prompt.` }); + }, + + async onSubmit(prompt, A) { + if (A != true) { + signale.star({ prefix: `[SCRIPTS]`, message: `Cancelled emoji SYNC.` }); + return false; + } + + const data = await fetch(); + writeFile(data); + } + }); +})(); + +function writeFile(data: unknown[]) { + signale.complete({ prefix: "[SYNC]", message: `Writing formatted data to icons.json` }); + + return writeFileSync("./icons.json", JSON.stringify(data, undefined, 5)); +} + +async function fetch() { + signale.start({ prefix: "[SYNC]", message: `Fetching emojis from https://discord.com/api` }); + const data = await axios(`https://discord.com/api/applications/${process.env.CLIENT_ID}/emojis`, { + method: "GET", + headers: { + Authorization: `Bot ${process.env.TOKEN}` + } + }); + + signale.warn({ prefix: "[SYNC]", message: `Fetched ${data.data.items.length} emojis. Formatting data...` }); + + const formatted = FormatData(data.data); + return formatted; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function FormatData(data: any) { + const AllEmojisFormatted = []; + for (const E of data.items) { + AllEmojisFormatted.push({ + id: E.id, + name: E.name, + animated: E.animated + }); + }; + + return AllEmojisFormatted; +} \ No newline at end of file diff --git a/scripts/exe.sh b/scripts/exe.sh deleted file mode 100644 index ba9010c..0000000 --- a/scripts/exe.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -read -p "Script: " script - -if [ "$script" == "dev:esync" ]; - then - - node syncEmojis.js - -elif [ "$script" == "start" ]; - then - npm run start - -fi - -bash exe.sh \ No newline at end of file diff --git a/src/application/buttons/welcome/status.ts b/src/application/buttons/settings/farewell.ts similarity index 62% rename from src/application/buttons/welcome/status.ts rename to src/application/buttons/settings/farewell.ts index f4db939..5fe1b49 100644 --- a/src/application/buttons/welcome/status.ts +++ b/src/application/buttons/settings/farewell.ts @@ -1,3 +1,7 @@ +/** + * CHANGE THE STATUS FOR "settings.farewell" + */ + import { ActionRowBuilder, APIButtonComponent, @@ -9,32 +13,40 @@ import { ChannelSelectMenuBuilder, EmbedBuilder, } from "discord.js"; -import { NeetButton, NeetButtonParameters } from "../../../../lib"; -import { updateWelcome } from "../../../helpers/database"; -import { emoji, reverse, status as Status } from "../../../helpers/utils"; +import { Arguments, componentGetBoolean, customId } from "../../../../lib"; +import { + isCommandUser, + emoji, + reverse, + status as Status, +} from "../../../helpers/utils"; +import { Setting } from "../../../models/Settings"; export async function run( interaction: ButtonInteraction<"cached">, - parameters: NeetButtonParameters, + parameters: Arguments[], ) { + if (!isCommandUser(interaction)) return; + const { guildId, message: { embeds, components }, } = interaction; await interaction.deferReply({ ephemeral: true }); - const status = parameters.boolean("to"); - if (status === null) return; + const status = componentGetBoolean(parameters, "to"); + if (status === null) return; // WNE* - const data = await updateWelcome(guildId, { - enabled: status, - }); + const data = await Setting.UpdateFarewell( + guildId, + status ? { enabled: status } : { enabled: status, channelId: null }, + ); const embed = EmbedBuilder.from(embeds[0]) .setDescription( `**ยป** **Status ยปยปยป** ${Status(status)}\n**ยป** **Channel ยปยปยป** ${data?.channelId ? channelMention(data.channelId) : "None"}`, ) - .setColor(data?.enabled ? "Blurple" : "Orange"); + .setColor(status ? "Blurple" : "Orange"); const channelSelect = ActionRowBuilder.from(components[0]).setComponents( ChannelSelectMenuBuilder.from( @@ -42,8 +54,8 @@ export async function run( ).setDisabled(reverse(status)), ) as ActionRowBuilder; - const buttonId = NeetButton.generateId("welcome", "status").setParameters([ - { name: "to", value: `${reverse(data?.enabled)}` }, + const buttonId = customId("settings", "farewell", [ + { name: "to", value: reverse(status) }, ]); const statusButton = ActionRowBuilder.from(components[1]).setComponents( @@ -51,6 +63,10 @@ export async function run( .setCustomId(buttonId) .setLabel(Status(status, true)) .setStyle(status ? ButtonStyle.Danger : ButtonStyle.Success), + + ButtonBuilder.from( + components[1].components[1] as APIButtonComponent, + ).setDisabled(reverse(status)), ) as ActionRowBuilder; await interaction.message.edit({ @@ -58,5 +74,5 @@ export async function run( components: [channelSelect, statusButton], }); - return await interaction.editReply(`${emoji("Checkmark")} | Saved Settings!`); + return await interaction.editReply(`${emoji("Checkmark")} | Saved Settings.`); } diff --git a/src/application/buttons/settings/message.ts b/src/application/buttons/settings/message.ts new file mode 100644 index 0000000..b51241b --- /dev/null +++ b/src/application/buttons/settings/message.ts @@ -0,0 +1,71 @@ +/** + * SHOW A MODAL FOR UPDATING MESSAGE COMPONENTS ("settings.(welcome,farewell)") + */ + +import { + ActionRowBuilder, + ButtonInteraction, + ModalBuilder, + TextInputBuilder, + TextInputStyle, +} from "discord.js"; +import { Arguments, componentGetString, customId } from "../../../../lib"; +import { isCommandUser } from "../../../helpers/utils"; +import { Setting } from "../../../models/Settings"; + +export async function run(interaction: ButtonInteraction, args: Arguments[]) { + if (!isCommandUser(interaction)) return; + + const module = componentGetString(args, "for"); + if (!module) return; // WNE* + + const data = await Setting.findOne({ guildId: interaction.guildId }); + if (!data) return; // WNE* + const values = data[module === "welcome" ? "welcome" : "farewell"]?.options; + + const AuthorNameField = new TextInputBuilder() + .setCustomId("author_name") + .setLabel("Embec Author Name Field") + .setStyle(TextInputStyle.Short) + .setRequired(false); + if (values?.author?.name) AuthorNameField.setValue(values.author.name); + + const AuthorIconField = new TextInputBuilder() + .setCustomId("author_icon") + .setLabel("Embded Author Icon Field") + .setStyle(TextInputStyle.Short) + .setRequired(false); + if (values?.author?.iconURL) AuthorIconField.setValue(values.author.iconURL); + + const DescriptionField = new TextInputBuilder() + .setCustomId("description") + .setLabel("Embed Description Field") + .setStyle(TextInputStyle.Short) + .setRequired(false); + if (values?.description) DescriptionField.setValue(values.description); + + const MessageModal = new ModalBuilder() + .setCustomId( + customId("message", "E", [ + { name: "use>id", value: true }, + { name: "for", value: module }, + ]), + ) + .setTitle(`Message Settings: ${module}`) + .addComponents( + new ActionRowBuilder().setComponents( + new TextInputBuilder() + .setCustomId("content") + .setLabel("Content") + .setStyle(TextInputStyle.Paragraph) + .setValue(values?.content ? values.content : "**Welcome!** {mention}") + .setRequired(true), + ), + + new ActionRowBuilder().setComponents(AuthorNameField), + new ActionRowBuilder().setComponents(AuthorIconField), + new ActionRowBuilder().setComponents(DescriptionField), + ); + + await interaction.showModal(MessageModal); +} diff --git a/src/application/buttons/settings/welcome.ts b/src/application/buttons/settings/welcome.ts new file mode 100644 index 0000000..90211ed --- /dev/null +++ b/src/application/buttons/settings/welcome.ts @@ -0,0 +1,82 @@ +/** + * CHANGE THE STATUS FOR "settings.welcome" + */ + +import { + ActionRowBuilder, + APIButtonComponent, + APIChannelSelectComponent, + ButtonBuilder, + ButtonInteraction, + ButtonStyle, + channelMention, + ChannelSelectMenuBuilder, + EmbedBuilder, +} from "discord.js"; +import { Arguments, componentGetBoolean, customId } from "../../../../lib"; +import { + isCommandUser, + emoji, + reverse, + status as Status, +} from "../../../helpers/utils"; +import { Setting } from "../../../models/Settings"; + +export async function run( + interaction: ButtonInteraction<"cached">, + parameters: Arguments[], +) { + if (!isCommandUser(interaction)) return; + + const { + guildId, + message: { embeds, components }, + } = interaction; + await interaction.deferReply({ ephemeral: true }); + + const status = componentGetBoolean(parameters, "to"); + if (status === null) return; + + const data = await Setting.UpdateWelcome( + guildId, + status + ? { + enabled: status, + } + : { enabled: status, channelId: null }, + ); + + const embed = EmbedBuilder.from(embeds[0]) + .setDescription( + `**ยป** **Status ยปยปยป** ${Status(status)}\n**ยป** **Channel ยปยปยป** ${data?.channelId ? channelMention(data.channelId) : "None"}`, + ) + .setColor(data?.enabled ? "Blurple" : "Orange"); + + const channelSelect = ActionRowBuilder.from(components[0]).setComponents( + ChannelSelectMenuBuilder.from( + components[0].components[0] as unknown as APIChannelSelectComponent, + ).setDisabled(reverse(status)), + ) as ActionRowBuilder; + + const buttonId = customId("settings", "welcome", [ + { name: "to", value: reverse(data?.enabled) }, + ]); + + const settingButtons = ActionRowBuilder.from(components[1]).setComponents( + ButtonBuilder.from(components[1].components[0] as APIButtonComponent) + .setCustomId(buttonId) + .setLabel(Status(status, true)) + .setStyle(status ? ButtonStyle.Danger : ButtonStyle.Success), + + ButtonBuilder.from( + components[1].components[1] as APIButtonComponent, + ).setDisabled(reverse(data?.enabled)), + ) as ActionRowBuilder; + + await interaction.message.edit({ + embeds: [embed], + components: [channelSelect, settingButtons], + }); + + return await interaction.editReply(`${emoji("Checkmark")} | Saved Settings!`); +} diff --git a/src/application/buttons/whois/display_cases.ts b/src/application/buttons/whois/display_cases.ts index 7a8b2c5..95305e7 100644 --- a/src/application/buttons/whois/display_cases.ts +++ b/src/application/buttons/whois/display_cases.ts @@ -1,11 +1,10 @@ import { ButtonInteraction, EmbedBuilder } from "discord.js"; -import { NeetButtonParameters } from "../../../../lib"; -import { getCases } from "../../../helpers/database"; -import { EnumModerationCaseFilterProperties } from "../../../models/Guilds"; +import { Arguments, componentGetString } from "../../../../lib"; +import { Guild } from "../../../models/Guilds"; export async function run( interaction: ButtonInteraction<"cached">, - parameters: NeetButtonParameters, + parameters: Arguments[], ) { if (!interaction.member.permissions.has("ModerateMembers")) { return interaction.reply({ @@ -20,14 +19,10 @@ export async function run( await interaction.deferReply({ ephemeral: true }); - const userId = parameters.get("user"); - if (!userId) return; // This will never get executed. + const userId = componentGetString(parameters, "userId"); + if (!userId) return; // WNE* - const data = await getCases( - interaction.guildId, - EnumModerationCaseFilterProperties.userId, - userId, - ); + const data = await Guild.getUserCases(interaction.guildId, userId); if (!data) { return interaction.editReply({ diff --git a/src/application/commands/ban.ts b/src/application/commands/ban.ts index 4d9bf69..1bc9aa0 100644 --- a/src/application/commands/ban.ts +++ b/src/application/commands/ban.ts @@ -8,9 +8,8 @@ import { import { NeetCommandBuilder } from "../../../lib"; import { CommandMode, CommandRunType } from "../../../lib/Types/enum"; import { emoji } from "../../helpers/utils"; -import { writeError, writeWarn } from "../../helpers/logger"; -import { createCase } from "../../helpers/database"; -import { ActionTypes } from "../../../lib/Types/database"; +import { Guild, ModerationCaseActions } from "../../models/Guilds"; +import signale from "signale"; export async function run(interaction: ChatInputCommandInteraction<"cached">) { const { options } = interaction; @@ -100,24 +99,21 @@ async function BanMember( await member .send({ embeds: [DMEmbed] }) - .catch((reason) => writeWarn("BanMember Warn", reason.rawError.message)); + .catch((reason) => signale.warn(reason.rawError.message)); try { await interaction.guild.bans.create(member, { reason: options.reason, }); - await createCase( - { guildId: interaction.guildId }, - { - userId: member.id, - moderatorId: interaction.user.id, - actionType: ActionTypes.BAN, - reason: options.reason, - }, - ); + await Guild.createCase(interaction.guildId, { + userId: member.id, + moderatorId: interaction.user.id, + actionType: ModerationCaseActions.Ban, + reason: options.reason, + }); } catch (error) { - writeError("BanMember Error", error); + signale.error("BanMember error", error); } finally { const embed = new EmbedBuilder() .setDescription( diff --git a/src/application/commands/kick.ts b/src/application/commands/kick.ts index 0ba914f..c7cdfd1 100644 --- a/src/application/commands/kick.ts +++ b/src/application/commands/kick.ts @@ -6,9 +6,8 @@ import { import { NeetCommandBuilder } from "../../../lib"; import { CommandMode, CommandRunType } from "../../../lib/Types/enum"; import { emoji } from "../../helpers/utils"; -import { writeError, writeWarn } from "../../helpers/logger"; -import { createCase } from "../../helpers/database"; -import { ActionTypes } from "../../../lib/Types/database"; +import { Guild, ModerationCaseActions } from "../../models/Guilds"; +import signale from "signale"; export async function run(interaction: ChatInputCommandInteraction<"cached">) { const { options } = interaction; @@ -67,22 +66,19 @@ export async function run(interaction: ChatInputCommandInteraction<"cached">) { await member .send({ embeds: [DMEmbed] }) - .catch((warn) => writeWarn("KickMember Warn", warn.rawError.message)); + .catch((warn) => signale.warn(warn.rawError.message)); try { await member.kick(reason); - await createCase( - { guildId: interaction.guildId }, - { - userId: member.id, - moderatorId: interaction.user.id, - actionType: ActionTypes.KICK, - reason, - }, - ); + await Guild.createCase(interaction.guildId, { + userId: member.id, + moderatorId: interaction.user.id, + actionType: ModerationCaseActions.Kick, + reason, + }); } catch (error) { - writeError("KickMember Error", error); + signale.error("KickMember error", error); } finally { const embed = new EmbedBuilder() .setDescription(`${emoji("Checkmark")} | Kicked ${member} | ${reason}`) diff --git a/src/application/modals/message.ts b/src/application/modals/message.ts new file mode 100644 index 0000000..11e12ef --- /dev/null +++ b/src/application/modals/message.ts @@ -0,0 +1,61 @@ +import { EmbedBuilder, ModalSubmitInteraction } from "discord.js"; +import { Setting, UpdateQueryAnyGreeting } from "../../models/Settings"; +import { Arguments, componentGetString } from "../../../lib"; +import { emoji } from "../../helpers/utils"; + +export async function run( + interaction: ModalSubmitInteraction<"cached">, + args: Arguments[], +) { + const { fields, user } = interaction; + const module = componentGetString(args, "for"); + + const content = fields.getTextInputValue("content"); + + const authorName = nullIfEmptyString(fields.getTextInputValue("author_name")); + + const authorIcon = nullIfEmptyString(fields.getTextInputValue("author_icon")); + + const description = nullIfEmptyString( + fields.getTextInputValue("description"), + ); + + // Validate author options. + if ((authorName && !authorIcon) || (authorIcon && !authorName)) { + return interaction.reply({ + content: `**Author Fields** are not formatted correctly.`, + ephemeral: true, + }); + } + + await interaction.deferReply({ ephemeral: true }); + + const data: UpdateQueryAnyGreeting = { + options: { + content: content, + description: description, + + author: { + name: authorName, + iconURL: authorIcon, + }, + }, + }; + + await Setting[module === "welcome" ? "UpdateWelcome" : "UpdateFarewell"]( + interaction.guildId, + data, + ); + + const embed = new EmbedBuilder() + .setAuthor({ name: user.username, iconURL: user.displayAvatarURL() }) + .setTitle(`${emoji("Checkmark")} Saved Message Options: ${module}`) + .setColor("Blurple") + .setTimestamp(); + + return await interaction.editReply({ embeds: [embed] }); +} + +function nullIfEmptyString(str: string) { + return str.length === 0 ? null : str; +} diff --git a/src/application/selectMenu/channel/settings/farewell.ts b/src/application/selectMenu/channel/settings/farewell.ts new file mode 100644 index 0000000..51e4b38 --- /dev/null +++ b/src/application/selectMenu/channel/settings/farewell.ts @@ -0,0 +1,55 @@ +import { + ActionRowBuilder, + APIButtonComponent, + APIChannelSelectComponent, + ButtonBuilder, + channelMention, + ChannelSelectMenuBuilder, + ChannelSelectMenuInteraction, + EmbedBuilder, +} from "discord.js"; +import { + isCommandUser, + emoji, + reverse, + status, +} from "../../../../helpers/utils"; +import { Setting } from "../../../../models/Settings"; + +export async function run(interaction: ChannelSelectMenuInteraction<"cached">) { + if (!isCommandUser(interaction)) return; + + const { + guildId, + values, + message: { embeds, components }, + } = interaction; + await interaction.deferReply({ ephemeral: true }); + + const channelId = values[0]; + const data = await Setting.UpdateFarewell(guildId, { channelId }); + + const embed = EmbedBuilder.from(embeds[0]).setDescription( + `**ยป** **Status ยปยปยป** ${status(data?.enabled)}\n**ยป** **Channel ยปยปยป** ${data?.channelId ? channelMention(data.channelId) : "None"}`, + ); + + const channelSelect = ActionRowBuilder.from(components[0]).setComponents( + ChannelSelectMenuBuilder.from( + components[0].components[0] as unknown as APIChannelSelectComponent, + ) + .setDisabled(reverse(data?.enabled)) + .setDefaultChannels([channelId]), + ) as ActionRowBuilder; + + const statusButton = ActionRowBuilder.from(components[1]).setComponents( + ButtonBuilder.from(components[1].components[0] as APIButtonComponent), + ButtonBuilder.from(components[1].components[1] as APIButtonComponent), + ) as ActionRowBuilder; + + await interaction.message.edit({ + embeds: [embed], + components: [channelSelect, statusButton], + }); + + return await interaction.editReply(`${emoji("Checkmark")} | Saved Settings.`); +} diff --git a/src/application/selectMenu/channel/welcome/channel.ts b/src/application/selectMenu/channel/settings/welcome.ts similarity index 74% rename from src/application/selectMenu/channel/welcome/channel.ts rename to src/application/selectMenu/channel/settings/welcome.ts index ab56711..d88a203 100644 --- a/src/application/selectMenu/channel/welcome/channel.ts +++ b/src/application/selectMenu/channel/settings/welcome.ts @@ -8,10 +8,17 @@ import { ButtonBuilder, APIButtonComponent, } from "discord.js"; -import { updateWelcome } from "../../../../helpers/database"; -import { emoji, reverse, status } from "../../../../helpers/utils"; +import { + isCommandUser, + emoji, + reverse, + status, +} from "../../../../helpers/utils"; +import { Setting } from "../../../../models/Settings"; export async function run(interaction: ChannelSelectMenuInteraction<"cached">) { + if (!isCommandUser(interaction)) return; + const { guildId, values, @@ -20,7 +27,7 @@ export async function run(interaction: ChannelSelectMenuInteraction<"cached">) { await interaction.deferReply({ ephemeral: true }); const channelId = values[0]; - const data = await updateWelcome(guildId, { channelId }); + const data = await Setting.UpdateWelcome(guildId, { channelId }); const embed = EmbedBuilder.from(embeds[0]) .setDescription( @@ -36,13 +43,14 @@ export async function run(interaction: ChannelSelectMenuInteraction<"cached">) { .addDefaultChannels([channelId]), ) as ActionRowBuilder; - const statusButton = ActionRowBuilder.from(components[1]).setComponents( + const settingButtons = ActionRowBuilder.from(components[1]).setComponents( ButtonBuilder.from(components[1].components[0] as APIButtonComponent), + ButtonBuilder.from(components[1].components[1] as APIButtonComponent), ) as ActionRowBuilder; await interaction.message.edit({ embeds: [embed], - components: [channelSelect, statusButton], + components: [channelSelect, settingButtons], }); return await interaction.editReply(`${emoji("Checkmark")} | Saved Settings!`); diff --git a/src/application/selectMenu/string/v8.ts b/src/application/selectMenu/string/v8.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/bot.ts b/src/bot.ts index add0221..df95b74 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -1,37 +1,38 @@ -import process from "node:process"; -import { Neet } from "../lib"; -import { writeError } from "./helpers/logger"; - process.loadEnvFile(".env"); +import { Neet } from "../lib"; import { Database } from "./helpers/databaseHandler"; import { Event } from "./helpers/eventHandler"; import { Command } from "./helpers/commandHandler"; +import signale from "signale"; const client = new Neet({ intents: ["Guilds", "GuildMembers", "GuildMessages", "MessageContent"], - shards: "auto", + shards: "auto" }); -process.on("unhandledRejection", (reason, promise) => { - writeError("handledRejection", promise); +process.on("unhandledRejection", ($, promise) => { + signale.error("unhandledRejection", promise); }); process.on("uncaughtException", (error) => { - writeError("caughtException", error); + signale.error("uncaughtException", error); }); -async function main() { +async function Main() { try { + signale.start({ prefix: "[HANDLERS]", message: `Loading ALL the handlers.` }); + + // Load all the handlers. Database(); Event(client); Command(client); await client.login(process.env.TOKEN); } catch (error) { - writeError("Client Login Error", error); + signale.error(`Login / Handler error`, error); await client.destroy(); } } -void main(); +void Main(); diff --git a/src/commands/member/whois.ts b/src/commands/member/whois.ts index 5664e89..09249fe 100644 --- a/src/commands/member/whois.ts +++ b/src/commands/member/whois.ts @@ -6,9 +6,8 @@ import { EmbedBuilder, } from "discord.js"; import { emoji } from "../../helpers/utils"; -import { getCases } from "../../helpers/database"; -import { NeetButton } from "../../../lib"; -import { EnumModerationCaseFilterProperties } from "../../models/Guilds"; +import { customId } from "../../../lib"; +import { Guild } from "../../models/Guilds"; export async function run(interaction: ChatInputCommandInteraction<"cached">) { await interaction.deferReply(); @@ -52,34 +51,27 @@ export async function run(interaction: ChatInputCommandInteraction<"cached">) { ack = true; } - const cases = await getCases( - interaction.guildId, - EnumModerationCaseFilterProperties.userId, - user.id, - ); + if (interaction.member.permissions.has("ModerateMembers")) { + const cases = await Guild.getUserCases(interaction.guildId, user.id); - if ( - cases != false && - cases.length > 0 && - interaction.member.permissions.has("ModerateMembers") - ) { - const customId = NeetButton.generateId( - "whois", - "display_cases", - ).setParameters([{ name: "user", value: user.id }]); + if (cases != false && cases.length > 0) { + const caseBTNId = customId("whois", "display_cases", [ + { name: "user", value: user.id }, + ]); - const CaseButtonActionRow = - new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId(customId) - .setLabel("Moderation Cases") - .setStyle(ButtonStyle.Danger), - ); + const CaseButtonActionRow = + new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setCustomId(caseBTNId) + .setLabel("Moderation Cases") + .setStyle(ButtonStyle.Danger), + ); - return interaction.editReply({ - embeds: [embed], - components: [CaseButtonActionRow], - }); + return interaction.editReply({ + embeds: [embed], + components: [CaseButtonActionRow], + }); + } } return interaction.editReply({ embeds: [embed] }); diff --git a/src/commands/settings/farewell.ts b/src/commands/settings/farewell.ts new file mode 100644 index 0000000..02b522f --- /dev/null +++ b/src/commands/settings/farewell.ts @@ -0,0 +1,69 @@ +import { + ActionRowBuilder, + ButtonBuilder, + ButtonStyle, + channelMention, + ChannelSelectMenuBuilder, + ChannelType, + ChatInputCommandInteraction, + EmbedBuilder, +} from "discord.js"; +import { Setting } from "../../models/Settings"; +import { reverse, status } from "../../helpers/utils"; +import { customId } from "../../../lib"; + +export async function run(interaction: ChatInputCommandInteraction<"cached">) { + const { guildId, guild } = interaction; + await interaction.deferReply(); + + let data; + data = await Setting.findOne({ guildId }); + if (!data) { + data = await Setting.create({ guildId }); + await data.save(); + } + + const embed = new EmbedBuilder() + .setAuthor({ name: guild.name, iconURL: guild.iconURL()! }) + .setTitle("Configure Farewell Settings") + .setDescription( + `**ยป** **Status ยปยปยป** ${status(data.farewell?.enabled)}\n**ยป** **Channel ยปยปยป** ${data.farewell?.channelId ? channelMention(data.farewell.channelId) : "None"}`, + ) + .setColor("Blurple") + .setTimestamp(); + + const channelSelect = + new ActionRowBuilder().addComponents( + new ChannelSelectMenuBuilder() + .setCustomId(customId("settings", "farewell")) + .setChannelTypes([ChannelType.GuildText]) + .setDisabled(reverse(data.farewell?.enabled)) + .setMaxValues(1), + ); + + const buttonId = customId("settings", "farewell", [ + { name: "to", value: `${reverse(data.farewell?.enabled)}` }, + ]); + + const statusButton = new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setCustomId(buttonId) + .setLabel(status(data.farewell?.enabled, true)) + .setStyle( + data.farewell?.enabled ? ButtonStyle.Danger : ButtonStyle.Success, + ), + + new ButtonBuilder() + .setCustomId( + customId("settings", "message", [{ name: "for", value: "farewell" }]), + ) + .setLabel("Message Options") + .setStyle(ButtonStyle.Primary) + .setDisabled(reverse(data.farewell?.enabled)), + ); + + return await interaction.editReply({ + embeds: [embed], + components: [channelSelect, statusButton], + }); +} diff --git a/src/commands/settings/welcome.ts b/src/commands/settings/welcome.ts index edbadbd..e3926d7 100644 --- a/src/commands/settings/welcome.ts +++ b/src/commands/settings/welcome.ts @@ -8,18 +8,17 @@ import { ChatInputCommandInteraction, EmbedBuilder, } from "discord.js"; -import Settings from "../../models/Settings"; -import { createDefaults } from "../../helpers/database"; +import { Setting } from "../../models/Settings"; import { reverse, status } from "../../helpers/utils"; -import { NeetButton } from "../../../lib"; +import { customId } from "../../../lib"; export async function run(interaction: ChatInputCommandInteraction<"cached">) { const { guildId, guild } = interaction; await interaction.deferReply(); - let data = await Settings.findOne({ guildId: guildId }); + let data = await Setting.findOne({ guildId: guildId }); if (!data) { - data = await Settings.create(createDefaults("setting", { guildId })); + data = await Setting.create({ guildId }); data.save(); } @@ -39,27 +38,35 @@ export async function run(interaction: ChatInputCommandInteraction<"cached">) { const channelSelect = new ActionRowBuilder().addComponents( new ChannelSelectMenuBuilder() - .setCustomId(NeetButton.generateId("welcome", "channel").generatedId) + .setCustomId(customId("settings", "welcome")) .setChannelTypes([ChannelType.GuildText]) .setMaxValues(1) .setDisabled(reverse(data.welcome?.enabled)), ); - const buttonId = NeetButton.generateId("welcome", "status").setParameters([ + const buttonId = customId("settings", "welcome", [ { name: "to", value: `${reverse(data.welcome?.enabled)}` }, ]); - const statusButton = new ActionRowBuilder().addComponents( + const settingButtons = new ActionRowBuilder().addComponents( new ButtonBuilder() .setCustomId(buttonId) .setLabel(status(data.welcome?.enabled, true)) .setStyle( data.welcome?.enabled ? ButtonStyle.Danger : ButtonStyle.Success, ), + + new ButtonBuilder() + .setCustomId( + customId("settings", "message", [{ name: "for", value: "welcome" }]), + ) + .setLabel("Message Options") + .setStyle(ButtonStyle.Primary) + .setDisabled(reverse(data.welcome?.enabled)), ); return await interaction.editReply({ embeds: [embed], - components: [channelSelect, statusButton], + components: [channelSelect, settingButtons], }); } diff --git a/src/events/@template.ts b/src/events/@template.ts deleted file mode 100644 index f915693..0000000 --- a/src/events/@template.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Events } from "discord.js"; -import { NeetEvent } from "../../lib"; -import { writeInfo } from '../helpers/logger' - -/* new NeetEvent - * ^^^ > The event name, used for args. - * new NeetEvent(options) - * ^^^^^^^ > { name: typeof Events, once?: boolean, run: (...args: ClientEvents[N]) => {} } - */ -export default new NeetEvent<"ready">({ - name: Events.ClientReady, - once: true, - run: (client) => { - writeInfo(client.user.username); - }, -}); diff --git a/src/events/ButtonCreate.ts b/src/events/ButtonCreate.ts index 4186814..6f1b4fa 100644 --- a/src/events/ButtonCreate.ts +++ b/src/events/ButtonCreate.ts @@ -1,7 +1,7 @@ import { Events } from "discord.js"; import { NeetEvent, Neet } from "../../lib"; -import { NeetButton } from "../../lib/Client/NeetButton/NeetButton"; -import { writeError } from "../helpers/logger"; +import { parseId } from "../../lib"; +import signale from "signale"; export default new NeetEvent<"interactionCreate">({ name: Events.InteractionCreate, @@ -9,33 +9,15 @@ export default new NeetEvent<"interactionCreate">({ run: async (interaction) => { if (!interaction.isButton()) return; const client = interaction.client as Neet; - client.emit("cl-debug", `Received a button interaction.`); + const parsed = parseId(interaction.customId) - const button = new NeetButton(interaction); - const parsed = button.parseId(); - - client.emit( - "cl-debug", - `Received button interaction: ${parsed.identifiers.id}/${parsed.identifiers.subId}`, - ); + client.emit("cl-debug", `[INTERACTION] Button >> (${parsed.id}/${parsed.sub_id}).`); try { - client.emit("cl-debug", `Handing button interaction.`); - - if (parsed.identifiers.subId) { - ( - await import( - `../application/buttons/${parsed.identifiers.id}/${parsed.identifiers.subId}` - ) - ).run(interaction, parsed.parameters); - } else { - (await import(`../application/buttons/${parsed.identifiers.id}`)).run( - interaction, - parsed.parameters, - ); - } + (await import(`../application/buttons/${parsed.id}/${parsed.sub_id}`)) + .run(interaction, parsed.args); } catch (error) { - writeError("ButtonCreate", error); + signale.error("ButtonCreate error", error); } }, }); diff --git a/src/events/CommandCreate.ts b/src/events/CommandCreate.ts index a589329..55be270 100644 --- a/src/events/CommandCreate.ts +++ b/src/events/CommandCreate.ts @@ -1,8 +1,8 @@ -/* eslint-disable @typescript-eslint/no-require-imports */ -import { EmbedBuilder, Events } from "discord.js"; +import { Events } from "discord.js"; import { Neet, NeetEvent } from "../../lib"; import { CommandRunType } from "../../lib/Types/enum"; -import { writeWarn } from "../helpers/logger"; +import { createWarningEmbed } from "../helpers/utils"; +import signale from "signale"; export default new NeetEvent<"interactionCreate">({ name: Events.InteractionCreate, @@ -10,36 +10,21 @@ export default new NeetEvent<"interactionCreate">({ run: async (interaction) => { if (!interaction.isChatInputCommand()) return; + const { options } = interaction; const client = interaction.client as Neet; const context = client.commands.get(interaction.commandName); if (!context) return; - client.emit("ci-debug", `Received command: ${context.data.name}`); + client.emit("ci-debug", `[INTERACTION] >> Command (${context.data.name}).`); - // Check if the interaction command was ran in a Guild. if (interaction.inCachedGuild()) { if (context.handler.user_permissions) { - // Check if interaction member has the required permissions. - if ( - !interaction.member.permissions.has( - context.handler.user_permissions.required, - ) - ) { - const required_permissions = - context.handler.user_permissions.required.join(", "); - - return interaction.reply({ - embeds: [ - WarningEmbed( - "You don't have enough permissions", - optional( - context.handler.user_permissions.message, - `You need these permissions to run this command.\n> ${required_permissions}`, - ), - ), - ], - ephemeral: true, + if (!interaction.member.permissions.has(context.handler.user_permissions.required)) { + const requiredPermissions = context.handler.user_permissions.required.join(", "); + return interaction.reply({ + embeds: [createWarningEmbed("You don't have enough permissions", optional(context.handler.user_permissions.message, `You need these permissions to run this command.\n> ${requiredPermissions}`))], + ephemeral: true }); } } @@ -50,19 +35,9 @@ export default new NeetEvent<"interactionCreate">({ : await interaction.guild.members.fetchMe(); if (!me.permissions.has(context.handler.client_permissions.required)) { - const required_permissions = - context.handler.client_permissions.required.join(", "); - + const requiredPermissions = context.handler.client_permissions.required.join(", "); return interaction.reply({ - embeds: [ - WarningEmbed( - `I don't have enough permissions`, - optional( - context.handler.client_permissions.message, - `I need these permissions to execute this command.\n> ${required_permissions}`, - ), - ), - ], + embeds: [createWarningEmbed(`I don't have enough permissions`, optional(context.handler.client_permissions.message, `I need these permissions to execute this command.\n> ${requiredPermissions}`))], ephemeral: true, }); } @@ -70,41 +45,24 @@ export default new NeetEvent<"interactionCreate">({ } if (context.handler.run_type === CommandRunType.HANDLE) { - client.emit("cl-debug", `Handling ${context.data.name} command.`); - - if (interaction.options.getSubcommandGroup()) { - ( - await import( - `../commands/${interaction.commandName}/${interaction.options.getSubcommandGroup()}/${interaction.options.getSubcommand()}` - ) - ).run(interaction); - return; - } else if ( - !interaction.options.getSubcommandGroup() && - interaction.options.getSubcommand() - ) { - ( - await import( - `../commands/${interaction.commandName}/${interaction.options.getSubcommand()}` - ) - ).run(interaction); - return; + if (options.getSubcommandGroup()) { + (await import(`../commands/${interaction.commandName}/${options.getSubcommandGroup()}/${options.getSubcommand()}`)) + .run(interaction); + } else if (!options.getSubcommandGroup() && options.getSubcommand()) { + (await import(`../commands/${interaction.commandName}/${options.getSubcommand()}`)) + .run(interaction); } else { - (await import(`../commands/${interaction.commandName}`)).run( - interaction, - ); - return; + (await import(`../commands/${interaction.commandName}`)) + .run(interaction); } } if (context.handler.run_type === CommandRunType.THIS) { if (!context.run) { - writeWarn(`Missing "run" at command: ${context.data.name}`); + signale.warn(`Missing "run" at command: ${context.data.name}`); return; } - client.emit("cl-debug", `Running ${context.data.name} command.`); - context.run(interaction); } }, @@ -112,12 +70,4 @@ export default new NeetEvent<"interactionCreate">({ function optional(thing: T, _else: TT) { return thing ? thing : _else; -} - -function WarningEmbed(title: string, description: string): EmbedBuilder { - return new EmbedBuilder() - .setTitle(title) - .setDescription(description) - .setColor("Blurple") - .setTimestamp(); -} +} \ No newline at end of file diff --git a/src/events/GuildMemberAdd.ts b/src/events/GuildMemberAdd.ts new file mode 100644 index 0000000..008acac --- /dev/null +++ b/src/events/GuildMemberAdd.ts @@ -0,0 +1,39 @@ +import { AttachmentBuilder, EmbedBuilder, Events } from "discord.js"; +import { NeetEvent } from "../../lib"; +import { CanvaBuilder, Templates } from "neet-canvas.js"; +import { Setting } from "../models/Settings"; + +export default new NeetEvent<"guildMemberAdd">({ + name: Events.GuildMemberAdd, + once: false, + run: async (member) => { + const { guild, user } = member; + const data = await Setting.findOne({ guildId: guild.id }); + if (!data || data.welcome?.enabled != true || typeof data.welcome?.channelId != "string") return; + + const image = new CanvaBuilder({ template: Templates.WelcomeDefault }).set({ + username: user.username, + members: guild.memberCount, + avatarURL: user.displayAvatarURL(), + }); + + const ctx = await image.draw(image.canvas); + + const attachment = new AttachmentBuilder(ctx, { + name: "welcome.jpeg", + description: "Neet: Generated Welcome Image.", + }); + + const embed = new EmbedBuilder() + .setAuthor({ name: user.username }) + .setThumbnail(guild.iconURL()) + .setDescription(`**${user.username}** joined **${guild.name}**.`) + .setImage("attachment://welcome.jpeg") + .setTimestamp() + .setColor("Blurple"); + + const channel = await guild.channels.fetch(data.welcome?.channelId); + if (!channel || !channel.isSendable()) return; + channel.send({ embeds: [embed], files: [attachment] }); + }, +}); diff --git a/src/events/GuildMemberRemove.ts b/src/events/GuildMemberRemove.ts new file mode 100644 index 0000000..97f12c7 --- /dev/null +++ b/src/events/GuildMemberRemove.ts @@ -0,0 +1,41 @@ +import { AttachmentBuilder, EmbedBuilder, Events } from "discord.js"; +import { NeetEvent } from "../../lib"; +import { Setting } from "../models/Settings"; +import { CanvaBuilder, Templates } from "neet-canvas.js"; + +export default new NeetEvent<"guildMemberRemove">({ + name: Events.GuildMemberRemove, + once: false, + run: async (member) => { + const { guild, user } = member; + const data = await Setting.findOne({ guildId: guild.id }); + if (!data || data.farewell?.enabled != true || typeof data.farewell.channelId != "string") return; + + const image = new CanvaBuilder({ template: Templates.FarewellDefault }).set( + { + username: user.username, + members: guild.memberCount, + avatarURL: user.displayAvatarURL(), + }, + ); + + const buffer = await image.draw(image.canvas); + + const attachment = new AttachmentBuilder(buffer, { + name: "farewell.jpeg", + description: "Neet: Farewell Image", + }); + + const embed = new EmbedBuilder() + .setAuthor({ name: user.username }) + .setThumbnail(guild.iconURL()) + .setImage("attachment://farewell.jpeg") + .setDescription(`**${user.username}** left **${guild.name}**`) + .setColor("Orange") + .setTimestamp(); + + const channel = guild.channels.cache.get(data.farewell.channelId); + if (!channel?.isSendable()) return; + channel.send({ embeds: [embed], files: [attachment] }); + }, +}); diff --git a/src/events/ModalCreate.ts b/src/events/ModalCreate.ts new file mode 100644 index 0000000..77527ff --- /dev/null +++ b/src/events/ModalCreate.ts @@ -0,0 +1,22 @@ +import { Events } from "discord.js"; +import { componentGetBoolean, Neet, NeetEvent, parseId } from "../../lib"; + +export default new NeetEvent<"interactionCreate">({ + name: Events.InteractionCreate, + once: false, + run: async (interaction) => { + if (!interaction.isModalSubmit()) return; + const client = interaction.client as Neet; + const parsed = parseId(interaction.customId); + + client.emit("cl-debug", `[INTERACTION] >> ModalSubmit (${parsed.id}).`) + + if (componentGetBoolean(parsed.args, "use>id") === true) { + (await import(`../application/modals/${parsed.id}`)) + .run(interaction, parsed.args); + } + + (await import(`../application/modals/${parsed.id}/${parsed.sub_id}`)) + .run(interaction, parsed.args); + }, +}); diff --git a/src/events/Ready.ts b/src/events/Ready.ts index 4b51069..c8fe4c5 100644 --- a/src/events/Ready.ts +++ b/src/events/Ready.ts @@ -1,9 +1,9 @@ import { Events } from "discord.js"; import { Neet, NeetEvent } from "../../lib"; -import { writeInfo } from "../helpers/logger"; // eslint-disable-next-line @typescript-eslint/no-unused-vars import { Deploy } from "../../scripts/deploy"; +import signale from "signale"; export default new NeetEvent<"ready">({ name: Events.ClientReady, @@ -11,7 +11,7 @@ export default new NeetEvent<"ready">({ //@ts-expect-error Type Error run: async (client: Neet) => { - writeInfo(`${client.user.username} is ready!`); + signale.success({ prefix: "[NEET]", message: `${client.user.username} is ready!` }); //await Deploy(); }, diff --git a/src/events/SelectMenuCreate.ts b/src/events/SelectMenuCreate.ts index 1586a2c..66bea99 100644 --- a/src/events/SelectMenuCreate.ts +++ b/src/events/SelectMenuCreate.ts @@ -1,35 +1,21 @@ import { Events } from "discord.js"; -import { Neet, NeetButton, NeetEvent } from "../../lib"; -import { writeError } from "../helpers/logger"; +import { Neet, NeetEvent, parseId } from "../../lib"; +import signale from "signale"; export default new NeetEvent<"interactionCreate">({ name: Events.InteractionCreate, once: false, run: async (interaction) => { - const client = interaction.client as Neet; - client.emit("cl-debug", "Recieved selectMenu interaction."); - if (interaction.isChannelSelectMenu()) { - const parsed = NeetButton.prototype.parseId(interaction.customId); + const client = interaction.client as Neet; + const parsed = parseId(interaction.customId); try { - client.emit("cl-debug", `Handing channelSelectMenu interaction.`); - - if (parsed.identifiers.subId) { - ( - await import( - `../application/selectMenu/channel/${parsed.identifiers.id}/${parsed.identifiers.subId}` - ) - ).run(interaction, parsed.parameters); - } else { - ( - await import( - `../application/selectMenu/channel/${parsed.identifiers.id}` - ) - ).run(interaction, parsed.parameters); - } + client.emit("cl-debug", `[INTERACTION] >> ChannelSelectMenu (${parsed.id}).`); + (await import(`../application/selectMenu/channel/${parsed.id}/${parsed.sub_id}`)) + .run(interaction, parsed.args); } catch (error) { - writeError("ChannelSelect", error); + signale.error("ChannelSelect error", error); } } }, diff --git a/src/events/cl-debug.ts b/src/events/cl-debug.ts index 410dc71..6525e58 100644 --- a/src/events/cl-debug.ts +++ b/src/events/cl-debug.ts @@ -1,10 +1,8 @@ +import signale from "signale"; import { NeetEvent } from "../../lib"; -import { writeDebug } from "../helpers/logger"; export default new NeetEvent<"debug">({ name: "cl-debug", once: false, - run: (message, ...args: unknown[]) => { - writeDebug(message, args ? args : undefined); - }, + run: (message) => signale.debug({ prefix: `[PROGRAM]`, message }) }); diff --git a/src/events/debug.ts b/src/events/debug.ts new file mode 100644 index 0000000..f5c4068 --- /dev/null +++ b/src/events/debug.ts @@ -0,0 +1,9 @@ +import { Events } from "discord.js"; +import { NeetEvent } from "../../lib"; +import signale from "signale"; + +export default new NeetEvent<"debug">({ + name: Events.Debug, + once: false, + run: (message) => signale.debug({ prefix: "[DiscordJS]", message }) +}); diff --git a/src/helpers/commandHandler.ts b/src/helpers/commandHandler.ts index 8766b35..6cd1af1 100644 --- a/src/helpers/commandHandler.ts +++ b/src/helpers/commandHandler.ts @@ -1,8 +1,8 @@ import { Neet } from "../../lib"; import { readdir } from "node:fs/promises"; -import { writeInfo } from "./logger"; import { INeetCommand } from "../../lib/Types/neet"; import { CommandRunType } from "../../lib/Types/enum"; +import signale from "signale"; export async function Command(client: Neet) { const files = await readdir("./src/application/commands/"); @@ -28,5 +28,5 @@ export async function Command(client: Neet) { amount++; } - writeInfo(`Loaded ${amount} commands.`); + signale.complete({ prefix: "[HANDLERS]", message: `Loaded ${amount} commands.` }); } diff --git a/src/helpers/database.ts b/src/helpers/database.ts deleted file mode 100644 index ecb0eb1..0000000 --- a/src/helpers/database.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { IFilterProperties } from "../../lib/Types/database"; -import Guilds, { - IModerationCase, - EnumModerationCaseFilterProperties, -} from "../models/Guilds"; -import Settings, { ISetWelcome } from "../models/Settings"; -import { writeError } from "./logger"; - -/* (**GUILD SETTING HELPERS**) (2024.10.13) */ - -export async function updateWelcome(guildId: string, update: ISetWelcome) { - try { - const updateObj = {}; - if (update.enabled != undefined) - Object.assign(updateObj, { "welcome.enabled": update.enabled }); - if (update.channelId != undefined) - Object.assign(updateObj, { "welcome.channelId": update.channelId }); - - const data = await Settings.findOneAndUpdate({ guildId }, updateObj, { - upsert: true, - new: true, - }); - - return data.welcome; - } catch (error) { - writeError("updateWelcome", error); - } -} - -/* (**DB HELPER FUNCTIONS**) (2024.10.13) */ - -export function createDefaults(type: string, filter: IFilterProperties) { - if (type === "guild") { - const object = { - guildId: "r-v", - cases: [], - }; - - return replaceDefaultFilters(filter, object); - } else if (type === "setting") { - const object = { - guildId: "r-v", - welcome: { enabled: false, channelId: null }, - }; - - return replaceDefaultFilters(filter, object); - } -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function replaceDefaultFilters(filter: IFilterProperties, obj: any) { - if (filter.guildId && obj.guildId) { - return Object.assign(obj, { guildId: filter.guildId }); - } - - if (filter.userId && obj.userId) { - return Object.assign(obj, { userId: filter.userId }); - } -} - -/* (**CASE HELPER FUNCTIONS**) (**2024.10.13**) */ - -export async function getCases( - guildId: string, - filterBy: EnumModerationCaseFilterProperties, - equalsTo: string, -): Promise { - const cases: IModerationCase[] = []; - const data = await Guilds.findOne({ guildId }); - - // * If no case in guild return false; - if (!data?.cases) return false; - - // * If no cases for this user return false; - if (data.cases.filter(($) => $[filterBy] === equalsTo).length < 1) - return false; - - for (const _case of data.cases.filter(($) => $[filterBy] === equalsTo)) { - cases.push(_case); - } - - return cases; -} - -export async function createCase( - filter: IFilterProperties, - options: IModerationCase, -) { - Object.assign(options, { caseId: crypto.randomUUID() }); - return await Guilds.findOneAndUpdate( - filter, - { $push: { cases: options } }, - { upsert: true, new: true }, - ); -} diff --git a/src/helpers/databaseHandler.ts b/src/helpers/databaseHandler.ts index 5d7edd9..81e82fb 100644 --- a/src/helpers/databaseHandler.ts +++ b/src/helpers/databaseHandler.ts @@ -1,15 +1,9 @@ import mongoose from "mongoose"; -import { writeInfo, writeError } from "./logger"; +import signale from "signale"; export function Database() { - writeInfo("Connecting to MongoDB..."); - - try { - mongoose - .connect(process.env.DATABASE) - .then(() => writeInfo("Connected to MongoDB.")) - .catch((_r: Error) => writeError("Error connecting to MongoDB", _r)); - } catch (error) { - writeError("MongoDB Error", error); - } + mongoose + .connect(process.env.DATABASE) + .then(() => signale.complete({ prefix: "[HANDLERS]", message: "Connected to mongodb." })) + .catch((_r: Error) => signale.error({ prefix: "[HANDLERS]", message: `Error handling mongodb connection. ${_r}` })); } diff --git a/src/helpers/eventHandler.ts b/src/helpers/eventHandler.ts index 4d40391..8ce6a71 100644 --- a/src/helpers/eventHandler.ts +++ b/src/helpers/eventHandler.ts @@ -1,25 +1,22 @@ import { Neet } from "../../lib"; -import { writeInfo } from "./logger"; import { readdir } from "node:fs/promises"; import { INeetEvent } from "../../lib/Types/neet"; +import signale from "signale"; export async function Event(client: Neet) { - const files = (await readdir("./src/events/")).filter( - (file) => file != "@template.ts", - ); - + const files = await readdir("./src/events/"); let amount = 0; for (const file of files) { - const event: INeetEvent = require(`../events/${file.replace(".ts", "")}`) - .default?.options; + const event: INeetEvent = (await import(`../events/${file.replace(".ts", "")}`)) + .default?.options; - client[event.once ? "once" : "on"](event.name!, (...args) => + client[event.once ? "once" : "on"](event.name, (...args) => event.run(...args), ); amount++; } - writeInfo(`Loaded ${amount} events.`); + signale.complete({ prefix: "[HANDLERS]", message: `Loaded ${amount} events.` }); } diff --git a/src/helpers/logger.ts b/src/helpers/logger.ts index 8fead2f..d87d9b9 100644 --- a/src/helpers/logger.ts +++ b/src/helpers/logger.ts @@ -36,7 +36,7 @@ export function writeWarn(message: string, ...args: unknown[]) { ); } -export function writeError(message: string, error: Error | any) { +export function writeError(message: string, error: Error | unknown) { console.error( style.white(getDate()), style.bold(style.red("[ERROR]")), diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts index b794f60..54d6d92 100644 --- a/src/helpers/utils.ts +++ b/src/helpers/utils.ts @@ -1,18 +1,37 @@ -import emojis from "../../scripts/dev/emojis.json"; -import { formatEmoji } from "discord.js"; +import emojis from "../../icons.json"; +import { + AnySelectMenuInteraction, + ButtonInteraction, + ColorResolvable, + EmbedBuilder, + formatEmoji, + ModalSubmitInteraction, +} from "discord.js"; +/* (**UTILITY FUNCTIONS**) (2024.10.22) */ + +/** + * Get an emoji from emojis.json. + * Returns a string or an ApplicationEmoji Object. + */ export function emoji( - name: keyof typeof emojis, + name: string, raw = false, ): string | typeof emoji { - const emoji = emojis[name]; - return raw ? emoji : formatEmoji(emoji.id, emoji.animated); + const emoji = emojis.find(E => E.name === name); + return raw ? emoji : formatEmoji(emoji!.id, emoji!.animated); } +/** + * Reverse a boolean + */ export function reverse(V: boolean | undefined | null): boolean { return V ? false : true; } +/** + * Turn a boolean into an Enable(d) / Disable(d) string + */ export function status( V: boolean | null | undefined, component?: boolean, @@ -20,3 +39,44 @@ export function status( if (component) return V ? "Disable" : "Enable"; return V ? "Enabled" : "Disabled"; } + +/* (COMMAND UTILITY FUNCTIONS) (2024.10.22) */ + +/** + * Check if the interaction.user / userId equals to the original command user. + * Returns false if its not the original user. + */ +export function isCommandUser( + int: ButtonInteraction | AnySelectMenuInteraction | ModalSubmitInteraction, + userId?: string, +) { + if (userId === undefined) userId = int.user.id; + if (int.message?.interactionMetadata?.user.id === userId) return true; + + const payload = { + embeds: [ + createWarningEmbed( + `${emoji("Xmark")} You can't use this interaction`, + "Hiya, this interaction is not for you!", + "Random", + ), + ], + }; + + if (int.deferred) int.editReply(payload); + else int.reply(Object.assign(payload, { ephemeral: true })); + + return false; +} + +export function createWarningEmbed( + title: string, + description: string, + color?: ColorResolvable, +) { + return new EmbedBuilder() + .setTitle(title) + .setDescription(description) + .setColor(color ?? "Orange") + .setTimestamp(); +} diff --git a/src/models/Guilds.ts b/src/models/Guilds.ts index a2149fc..76336a5 100644 --- a/src/models/Guilds.ts +++ b/src/models/Guilds.ts @@ -1,64 +1,100 @@ -import mongoose from "mongoose"; -import { ActionTypes } from "../../lib/Types/database"; +import { getModelForClass, prop, ReturnModelType } from "@typegoose/typegoose"; +import { FilterOutFunctionKeys } from "@typegoose/typegoose/lib/types"; +import { randomUUID } from "node:crypto"; -const GuildCases = new mongoose.Schema({ - userId: { - type: mongoose.SchemaTypes.String, - required: true, - }, +export class GuildClass { + @prop({ required: true }) + public guildId!: string; - moderatorId: { - type: mongoose.SchemaTypes.String, - required: true, - }, + @prop({ type: () => [ModerationCaseClass] }) + cases?: ModerationCaseClass[]; - caseId: { - type: mongoose.SchemaTypes.String, - required: true, - }, + public static async deleteAndCreate( + this: ReturnModelType, + guildId: string, + create?: boolean, + ) { + if (create === undefined) create = true; + let data; + data = await this.deleteOne({ guildId }); + if (data.acknowledged && create === true) { + data = await this.create({ guildId }); + await data.save(); + } + return data; + } - actionType: { - type: mongoose.SchemaTypes.Number, - required: true, - }, + public static async createCase( + this: ReturnModelType, + guildId: string, + caseInfo: FilterOutFunctionKeys, + upsert?: boolean, + ) { + if (upsert === undefined) upsert = false; + return this.findOneAndUpdate( + { guildId }, + { $push: { cases: [caseInfo] } }, + { upsert, new: true }, + ); + } - reason: { - type: mongoose.SchemaTypes.String, - default: "No Reason Provided", - }, -}); + public static async getUserCases( + this: ReturnModelType, + guildId: string, + userId: string, + ): Promise { + const guild = await this.findOne({ guildId }); + if (!guild || !guild.cases) return false; + const cases = guild.cases.filter((_case) => _case.userId === userId); + if (cases === undefined) return false; + return cases; + } + + public static async getCases( + this: ReturnModelType, + guildId: string, + filterBy: string, + eqto: ModerationCaseFilters, + ): Promise { + const guild = await this.findOne({ guildId }); + if (!guild || !guild.cases) return false; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const cases = guild.cases.filter(($: any) => $[filterBy] === eqto); + if (cases === undefined) return false; + return cases; + } +} + +export class ModerationCaseClass { + @prop({ required: true }) + public userId!: string; -export default mongoose.model( - "Guilds", - new mongoose.Schema({ - guildId: { - type: mongoose.SchemaTypes.String, - unique: true, - required: true, - }, + @prop({ required: true }) + public moderatorId!: string; - cases: { - type: [GuildCases], - default: [], - }, - }), -); + @prop({ default: randomUUID() }) + public caseId?: string; -export interface IGuild { - guildId: string; - cases: IModerationCase[] | never[]; + @prop({ type: () => String, required: true }) + public actionType!: string; + + @prop({ default: "No Reason Provided." }) + public reason?: string; } -export interface IModerationCase { - userId: string; - moderatorId: string; - caseId?: string; - actionType: ActionTypes; - reason?: string; +export enum ModerationCaseActions { + Ban = "ban", + Kick = "kick", + Warn = "warn", } -export enum EnumModerationCaseFilterProperties { +enum ModerationCaseFilters { userId = "userId", moderatorId = "moderatorId", caseId = "caseId", } + +export const Guild = getModelForClass(GuildClass, { + options: { customName: "Guild" }, + schemaOptions: { validateBeforeSave: true }, +}); diff --git a/src/models/Settings.ts b/src/models/Settings.ts index 884a789..72fc98a 100644 --- a/src/models/Settings.ts +++ b/src/models/Settings.ts @@ -1,21 +1,116 @@ -import mongoose from "mongoose"; - -export default mongoose.model( - "Settings", - new mongoose.Schema({ - guildId: { - type: mongoose.SchemaTypes.String, - required: true, - }, - - welcome: { - enabled: mongoose.SchemaTypes.Boolean, - channelId: mongoose.SchemaTypes.String, - }, - }), -); - -export interface ISetWelcome { +import { + getModelForClass, + modelOptions, + Passthrough, + prop, + ReturnModelType, + Severity, +} from "@typegoose/typegoose"; +import { QueryOptions } from "mongoose"; + +export function MakeUpdateable(object: UpdateQueryAnyGreeting) { + const makeProperty = (prop: string): string => `${object.prefix}.${prop}`; + + const data = {}; + + if (object.channelId != undefined) + Object.assign(data, { [makeProperty("channelId")]: object.channelId }); + if (object.enabled != undefined) + Object.assign(data, { [makeProperty("enabled")]: object.enabled }); + + if (object.options != undefined) { + for (const key of Object.keys(object.options)) { + Object.assign(data, { + //@ts-expect-error Index Type Error + [makeProperty(`options.${key}`)]: object.options[key], + }); + } + } + + return data; +} + +@modelOptions({ options: { allowMixed: Severity.ALLOW } }) +export class SettingSchema { + @prop({ required: true }) + public guildId!: string; + + @prop({ default: { enabled: false, channelId: null } }) + public welcome?: { + enabled: boolean; + channelId: string; + options: MessageOptionSchema; + }; + + @prop({ default: { enabled: false, channelId: null } }) + public farewell?: { + enabled: boolean; + channelId: string; + options: MessageOptionSchema; + }; + + static async UpdateFarewell( + this: ReturnModelType, + guildId: string, + update: UpdateQueryAnyGreeting, + options?: QueryOptions, + ) { + options ??= { upsert: true, new: true }; + update.prefix = "farewell"; + return ( + await this.findOneAndUpdate({ guildId }, MakeUpdateable(update), options) + )?.farewell; + } + + static async UpdateWelcome( + this: ReturnModelType, + guildId: string, + update: UpdateQueryAnyGreeting, + options?: QueryOptions, + ) { + options ??= { upsert: true, new: true }; + update.prefix = "welcome"; + return ( + await this.findOneAndUpdate({ guildId }, MakeUpdateable(update), options) + )?.welcome; + } +} + +export class MessageOptionSchema { + @prop({ type: () => String, default: null }) + public content?: string; + + @prop({ + type: () => new Passthrough({ name: String, iconURL: String }, true), + default: { name: null, iconURL: null }, + }) + public author?: { + name: string; + iconURL: string; + }; + + @prop({ type: () => String }) + public title?: string; + + @prop({ type: () => String }) + public description?: string; +} + +export interface UpdateQueryAnyGreeting { enabled?: boolean; - channelId?: string; + channelId?: string | null; + options?: UpdateQueryMessageOption; + prefix?: string; } + +export interface UpdateQueryMessageOption { + content: string; + title?: string | null; + description?: string | null; + author?: { name?: string | null; iconURL?: string | null }; +} + +export const Setting = getModelForClass(SettingSchema, { + options: { customName: "Settings" }, + schemaOptions: { validateBeforeSave: true }, +}); diff --git a/tsconfig.json b/tsconfig.json index 1a37785..d3bd1b3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,8 +16,8 @@ "target": "ES2018" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + "experimentalDecorators": true /* Enable experimental support for legacy experimental decorators. */, + "emitDecoratorMetadata": true /* Emit design-type metadata for decorated declarations in source files. */, // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */