From 71270e6d72eefb245dfefdad1196f86cf4f993b3 Mon Sep 17 00:00:00 2001 From: Ioannis Tsiakkas Date: Thu, 23 Jan 2025 00:31:31 +0200 Subject: [PATCH] Transition to deno2 (#845) * Successful transition to deno2 * Fix build errors * Remove dotenv and node process * Remove node-fetch * Remove node-fetch * Fix wrong music url * Fix voice joining * Minor improvement to music library * Code quality updates * Move to version 2.0.0 and update action to deno * Fix portal channel type check * With 2.1.4 LTS Deno2 works fine with discordjs * Update discordjs version and some minor updates * Update dockerfile to latest deno version * Updated readme --- .env_example | 25 + .eslintignore | 3 - .eslintrc.json | 37 - .github/dependabot.yml | 55 - .github/workflows/deno.yml | 18 + .github/workflows/nodejs.yml | 20 - .gitignore | 4 + .prettierrc.json | 14 - .prettierrcignore | 20 - .vscode/settings.json | 5 +- dasu.response | 23 + deno.json | 48 + deno.lock | 1387 +++++ docker-compose.yaml | 6 +- docker/Dockerfile | 24 +- docs/CONTRIBUTING.md | 146 +- docs/README.md | 44 +- package-lock.json | 5240 ----------------- package.json | 68 - src/Interpreter/attribute.functions.ts | 130 +- src/Interpreter/pipe.functions.ts | 14 +- src/Interpreter/structure.functions.ts | 9 +- src/Interpreter/variable.functions.ts | 21 +- src/app.ts | 102 +- src/assets/lists/countryCodesISO.static.ts | 966 +-- src/assets/lists/gameNames.static.ts | 1100 ++-- src/assets/lists/profaneWords.static.ts | 984 ++-- src/assets/lists/programNames.static.ts | 90 +- src/blueprints/attribute.blueprint.ts | 1025 ++-- src/blueprints/pipe.blueprint.ts | 251 +- src/blueprints/structure.blueprint.ts | 10 +- src/blueprints/variable.blueprint.ts | 238 +- src/commands/auth/announcement.ts | 107 +- src/commands/auth/ban.ts | 81 +- src/commands/auth/delete_messages.ts | 83 +- src/commands/auth/force.ts | 143 +- src/commands/auth/ignore.ts | 46 +- src/commands/auth/index.ts | 26 +- src/commands/auth/invite.ts | 85 +- src/commands/auth/kick.ts | 81 +- src/commands/auth/music.ts | 78 +- src/commands/auth/portal.ts | 87 +- src/commands/auth/set.ts | 107 +- src/commands/auth/set_ranks.ts | 81 +- src/commands/auth/url.ts | 60 +- src/commands/auth/vendor.ts | 134 +- src/commands/noAuth/about.ts | 54 +- src/commands/noAuth/announce.ts | 68 +- src/commands/noAuth/bet.ts | 118 +- src/commands/noAuth/corona.ts | 150 +- src/commands/noAuth/crypto.ts | 113 +- src/commands/noAuth/focus.ts | 350 +- src/commands/noAuth/help.ts | 474 +- .../noAuth/help/AttributeDocumentation.ts | 120 +- .../noAuth/help/CommandDocumentation.ts | 68 +- src/commands/noAuth/help/PipeDocumentation.ts | 95 +- .../noAuth/help/StructureDocumentation.ts | 142 +- .../noAuth/help/VariableDocumentation.ts | 136 +- src/commands/noAuth/index.ts | 40 +- src/commands/noAuth/join.ts | 77 +- src/commands/noAuth/leaderboard.ts | 85 +- src/commands/noAuth/leave.ts | 43 +- src/commands/noAuth/level.ts | 44 +- src/commands/noAuth/ping.ts | 81 +- src/commands/noAuth/poll.ts | 121 +- src/commands/noAuth/ranks.ts | 52 +- src/commands/noAuth/roll.ts | 77 +- src/commands/noAuth/run.ts | 94 +- src/commands/noAuth/spam_rules.ts | 73 +- src/commands/noAuth/state.ts | 193 +- src/commands/noAuth/stock.ts | 92 +- src/commands/noAuth/weather.ts | 124 +- src/commands/noAuth/whoami.ts | 50 +- src/events/channelDelete.event.ts | 37 +- src/events/guildCreate.event.ts | 10 +- src/events/guildDelete.event.ts | 6 +- src/events/guildMemberAdd.event.ts | 53 +- src/events/guildMemberRemove.event.ts | 51 +- src/events/index.ts | 21 +- src/events/interactionCreate.event.ts | 115 +- src/events/messageCreate.event.ts | 154 + src/events/messageDelete.event.ts | 178 +- src/events/messageReactionAdd.event.ts | 14 +- src/events/ready.event.ts | 95 +- src/events/voiceStateUpdate.event.ts | 246 +- src/handlers/command.handler.ts | 62 +- src/handlers/discord.handler.ts | 17 +- src/handlers/event.handler.ts | 75 +- src/handlers/mongo.handler.ts | 18 +- src/libraries/adapter.library.ts | 25 +- src/libraries/guild.library.ts | 457 +- src/libraries/help.library.ts | 494 +- src/libraries/http.library.ts | 100 +- src/libraries/localisation.library.ts | 160 +- src/libraries/mod.library.ts | 144 +- src/libraries/mongo.library.ts | 312 +- src/libraries/music.library.ts | 13 +- src/libraries/music.library2.ts | 573 ++ src/libraries/preprocessor.library.ts | 106 +- src/libraries/status.library.ts | 34 +- src/libraries/user.library.ts | 111 +- src/libraries/voice.library.ts | 58 + src/types/Command.ts | 14 +- src/types/classes/PGiveRole.class.ts | 2 +- src/types/classes/PGuild.class.ts | 23 +- src/types/classes/PMember.class.ts | 4 +- src/types/classes/PPoll.class.ts | 2 +- src/types/classes/PPortalChannel.class.ts | 4 +- src/types/classes/PTypes.interface.ts | 104 +- src/types/classes/PVoiceChannel.class.ts | 4 +- src/types/enums/Admin.enum.ts | 10 +- src/types/enums/Locales.enum.ts | 2 +- src/types/enums/OpapGames.enum.ts | 10 +- src/types/enums/Prefix.enum.ts | 8 +- src/types/enums/ProfanityLevel.enum.ts | 2 +- src/types/enums/RankSpeed.enum.ts | 2 +- src/types/enums/TextChannelType.enum.ts | 8 + src/types/models/PGuild.model.ts | 22 +- src/types/models/schemas/PGiveRole.schema.ts | 10 +- src/types/models/schemas/PMember.schema.ts | 6 +- src/types/models/schemas/PPoll.schema.ts | 6 +- .../models/schemas/PPortalChannel.schema.ts | 6 +- .../models/schemas/PVoiceChannel.schema.ts | 6 +- src/utilities/log.utility.test.ts | 81 + src/utilities/log.utility.ts | 74 +- tsconfig.eslint.json | 3 - tsconfig.json | 21 - 127 files changed, 10003 insertions(+), 10630 deletions(-) create mode 100644 .env_example delete mode 100644 .eslintignore delete mode 100644 .eslintrc.json delete mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/deno.yml delete mode 100644 .github/workflows/nodejs.yml delete mode 100644 .prettierrc.json delete mode 100644 .prettierrcignore create mode 100644 dasu.response create mode 100644 deno.json create mode 100644 deno.lock delete mode 100644 package-lock.json delete mode 100644 package.json create mode 100644 src/events/messageCreate.event.ts create mode 100644 src/libraries/music.library2.ts create mode 100644 src/libraries/voice.library.ts create mode 100644 src/types/enums/TextChannelType.enum.ts create mode 100644 src/utilities/log.utility.test.ts delete mode 100644 tsconfig.eslint.json delete mode 100644 tsconfig.json diff --git a/.env_example b/.env_example new file mode 100644 index 00000000..466b7b0a --- /dev/null +++ b/.env_example @@ -0,0 +1,25 @@ +# current version +VERSION= +# your Discord-API-Token +DISCORD_TOKEN= +# mongoDB url +# without docker: mongodb://localhost:27017/portal +# with docker: mongodb://mongo/portal?compressors +MONGO_URL= +# owner ID may be used throughout Portal +OWNER_ID= +CLIENT_ID= +# API KEYS +OPENWEATHERMAP= +COVID_193= +LYRICS= +COINGECKO= +FOOTBALL_DATA= +YAHOO_FINANCE= +NEW_YORK_TIMES= +TRANSLATE_ENGINE= +# how long after message sent, will it be deleted +TRANSLATE_KEY= +# log files in ../logs directory on host +DEBUG= +LOG= diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 0e796c3f..00000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -dist -build \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index bd4a3771..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended" - ], - "ignorePatterns": ["**/*.d.ts"], - "parserOptions": { - "ecmaVersion": 8, - "sourceType": "module" - }, - "env": { - "node": true, - "jest": true, - "commonjs": true, - "mongo": true - }, - "rules": { - "no-console": 1, - "indent": ["error", 2], - "global-require": ["error"], - "handle-callback-err": ["error"], - "quotes": ["error", "single", { - "allowTemplateLiterals": true - }], - "no-template-curly-in-string": ["error"], - "no-restricted-syntax": [ - "error", - { - "selector": "TemplateLiteral:not([quasis.length > 1])", - "message": "Template literals with a single expression should use string concatenation instead" - } - ] - } -} diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 604d4ef2..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,55 +0,0 @@ -version: 2 -updates: - - package-ecosystem: npm - directory: '/' - schedule: - interval: daily - time: '03:00' - open-pull-requests-limit: 10 - ignore: - - dependency-name: '@types/node' - versions: - - 14.14.37 - - 14.14.39 - - 14.14.41 - - 15.0.0 - - dependency-name: mongoose - versions: - - 5.12.2 - - 5.12.3 - - 5.12.5 - - dependency-name: '@typescript-eslint/parser' - versions: - - 4.21.0 - - 4.22.0 - - dependency-name: '@typescript-eslint/eslint-plugin' - versions: - - 4.21.0 - - 4.22.0 - - dependency-name: eslint - versions: - - 7.23.0 - - 7.24.0 - - dependency-name: cheerio - versions: - - 1.0.0-rc.6 - - dependency-name: typescript - versions: - - 4.2.4 - - dependency-name: '@types/node-fetch' - versions: - - 2.5.10 - - 2.5.9 - - dependency-name: discord.js - versions: - - 12.5.2 - - 12.5.3 - - dependency-name: '@types/ws' - versions: - - 7.4.1 - - dependency-name: ffmpeg-static - versions: - - 4.3.0 - - dependency-name: yt-search - versions: - - 2.7.6 diff --git a/.github/workflows/deno.yml b/.github/workflows/deno.yml new file mode 100644 index 00000000..656c9945 --- /dev/null +++ b/.github/workflows/deno.yml @@ -0,0 +1,18 @@ +name: deno + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + node_test: + runs-on: ubuntu-latest + steps: + - uses: denoland/setup-deno@v2 + with: + deno-version: v2.0.0 + - run: deno lint + - run: deno fmt + - run: deno test diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml deleted file mode 100644 index a770dda1..00000000 --- a/.github/workflows/nodejs.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: nodejs - -on: - push: - branches: [master] - pull_request: - branches: [master] - -jobs: - node_test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: setup node - uses: actions/setup-node@v3 - with: - node-version: '14' - check-latest: true - - run: npm ci - - run: npm run build diff --git a/.gitignore b/.gitignore index a01adba5..01ddd278 100644 --- a/.gitignore +++ b/.gitignore @@ -107,6 +107,7 @@ dist # Stores VSCode versions used for testing VSCode extensions .vscode-test +.vscode/* # yarn v2 .yarn/cache @@ -119,3 +120,6 @@ build/* # Ignore IDE configuration files .idea/ + +# Executable files +*.exe diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 173d020a..00000000 --- a/.prettierrc.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/prettierrc.json", - "semi": true, - "tabWidth": 2, - "singleQuote": true, - "printWidth": 120, - "trailingComma": "all", - "endOfLine": "lf", - "arrowParens": "always", - "plugins": [ - "prettier-plugin-organize-imports" - ], - "useTabs": false -} diff --git a/.prettierrcignore b/.prettierrcignore deleted file mode 100644 index 09da13d3..00000000 --- a/.prettierrcignore +++ /dev/null @@ -1,20 +0,0 @@ -dist/ - -node_modules/ - -*.config.js - -.env -.env.* - -package-lock.json - -*.log - -*.png -*.jpg -*.jpeg -*.gif -*.svg - -coverage/ diff --git a/.vscode/settings.json b/.vscode/settings.json index 9e96f3e7..160c61e4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,8 @@ { "compile-hero.disable-compile-files-on-did-save-code": true, "git-blame.gitWebUrl": "", - "git.ignoreLimitWarning": true + "git.ignoreLimitWarning": true, + "cSpell.words": [ + "decapitalize" + ] } diff --git a/dasu.response b/dasu.response new file mode 100644 index 00000000..549a1d76 --- /dev/null +++ b/dasu.response @@ -0,0 +1,23 @@ +
AboutPressCopyrightContact usCreatorsAdvertiseDevelopersTermsPrivacyPolicy & SafetyHow YouTube worksTest new features
\ No newline at end of file diff --git a/deno.json b/deno.json new file mode 100644 index 00000000..da038441 --- /dev/null +++ b/deno.json @@ -0,0 +1,48 @@ +{ + "name": "Portal", + "version": "0.8.0", + "exports": { + ".": "./src/app.ts" + }, + "nodeModulesDir": "auto", + "tasks": { + "start": "deno run --allow-sys --allow-net --allow-read --allow-write --allow-env --allow-ffi --allow-run src/app.ts", + "dev": "deno run --watch --allow-net --allow-read --allow-write --allow-env --allow-ffi --allow-run src/app.ts", + "lint": "deno lint", + "fmt": "deno fmt" + }, + "imports": { + "@discordjs/builders": "npm:@discordjs/builders@1.9.0", + "@discordjs/opus": "npm:@discordjs/opus@0.9.0", + "@discordjs/rest": "npm:@discordjs/rest@^2.4.0", + "@discordjs/voice": "npm:@discordjs/voice@0.17.0", + "@discordjs/ws": "npm:@discordjs/ws@^2.0.0", + "@distube/ytdl-core": "npm:@distube/ytdl-core@^4.15.1", + "@std/dotenv": "jsr:@std/dotenv@^0.225.2", + "@std/expect": "jsr:@std/expect@^1.0.7", + "cheerio": "npm:cheerio@1.0.0-rc.12", + "dayjs": "npm:dayjs@1.11.13", + "discord-api-types": "npm:discord-api-types@0.37.0", + "discord-ytdl-core": "npm:discord-ytdl-core@5.0.4", + "discord.js": "npm:discord.js@14.17.2", + "ffmpeg-static": "npm:ffmpeg-static@5.2.0", + "jsonfile": "npm:jsonfile@6.1.0", + "libsodium-wrappers": "npm:libsodium-wrappers@0.7.15", + "mongoose": "npm:mongoose@8.8.0", + "opusscript": "npm:opusscript@0.1.1", + "play-dl": "npm:play-dl@^1.9.7", + "roll": "npm:roll@1.3.2", + "voca": "npm:voca@1.4.1", + "winston": "npm:winston@3.16.0", + "yt-search": "npm:yt-search@2.12.1", + "ytdl-core": "npm:ytdl-core@4.11.5" + }, + "compilerOptions": { + "lib": [ + "deno.window", + "deno.ns", + "dom" + ], + "strict": true + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 00000000..bd5844a3 --- /dev/null +++ b/deno.lock @@ -0,0 +1,1387 @@ +{ + "version": "4", + "specifiers": { + "jsr:@std/assert@^1.0.8": "1.0.8", + "jsr:@std/dotenv@~0.225.2": "0.225.2", + "jsr:@std/expect@^1.0.7": "1.0.8", + "jsr:@std/internal@^1.0.5": "1.0.5", + "npm:@discordjs/builders@1.9.0": "1.9.0", + "npm:@discordjs/opus@0.9.0": "0.9.0", + "npm:@discordjs/rest@^2.4.0": "2.4.0", + "npm:@discordjs/voice@*": "0.17.0_@discordjs+opus@0.9.0_ffmpeg-static@5.2.0", + "npm:@discordjs/voice@0.17.0": "0.17.0_@discordjs+opus@0.9.0_ffmpeg-static@5.2.0", + "npm:@discordjs/ws@2": "2.0.0", + "npm:@distube/ytdl-core@^4.15.1": "4.15.1_tough-cookie@4.1.4_undici@5.28.4", + "npm:cheerio@*": "1.0.0", + "npm:cheerio@1.0.0-rc.12": "1.0.0-rc.12", + "npm:dayjs@*": "1.11.13", + "npm:dayjs@1.11.13": "1.11.13", + "npm:discord-api-types@0.37.0": "0.37.0", + "npm:discord-ytdl-core@5.0.4": "5.0.4_@discordjs+opus@0.9.0_ffmpeg-static@5.2.0", + "npm:discord.js@*": "14.17.2", + "npm:discord.js@14.17.2": "14.17.2", + "npm:ffmpeg-static@5.2.0": "5.2.0", + "npm:jsonfile@6.1.0": "6.1.0", + "npm:libsodium-wrappers@0.7.15": "0.7.15", + "npm:mongoose@*": "8.8.0", + "npm:mongoose@8.8.0": "8.8.0", + "npm:opusscript@0.1.1": "0.1.1", + "npm:play-dl@^1.9.7": "1.9.7", + "npm:roll@1.3.2": "1.3.2", + "npm:voca@*": "1.4.1", + "npm:voca@1.4.1": "1.4.1", + "npm:winston@*": "3.16.0", + "npm:winston@3.16.0": "3.16.0", + "npm:yt-search@*": "2.12.1", + "npm:yt-search@2.12.1": "2.12.1", + "npm:ytdl-core@4.11.5": "4.11.5" + }, + "jsr": { + "@std/assert@1.0.8": { + "integrity": "ebe0bd7eb488ee39686f77003992f389a06c3da1bbd8022184804852b2fa641b", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/dotenv@0.225.2": { + "integrity": "e2025dce4de6c7bca21dece8baddd4262b09d5187217e231b033e088e0c4dd23" + }, + "@std/expect@1.0.8": { + "integrity": "27e40d8f3aefb372fc6a703fb0b69e34560e72a2f78705178babdffa00119a5f", + "dependencies": [ + "jsr:@std/assert", + "jsr:@std/internal" + ] + }, + "@std/internal@1.0.5": { + "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" + } + }, + "npm": { + "@colors/colors@1.6.0": { + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==" + }, + "@dabh/diagnostics@2.0.3": { + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": [ + "colorspace", + "enabled", + "kuler" + ] + }, + "@derhuerst/http-basic@8.2.4": { + "integrity": "sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==", + "dependencies": [ + "caseless", + "concat-stream", + "http-response-object", + "parse-cache-control" + ] + }, + "@discordjs/builders@1.10.0": { + "integrity": "sha512-ikVZsZP+3shmVJ5S1oM+7SveUCK3L9fTyfA8aJ7uD9cNQlTqF+3Irbk2Y22KXTb3C3RNUahRkSInClJMkHrINg==", + "dependencies": [ + "@discordjs/formatters@0.6.0", + "@discordjs/util", + "@sapphire/shapeshift", + "discord-api-types@0.37.115", + "fast-deep-equal", + "ts-mixer", + "tslib" + ] + }, + "@discordjs/builders@1.9.0": { + "integrity": "sha512-0zx8DePNVvQibh5ly5kCEei5wtPBIUbSoE9n+91Rlladz4tgtFbJ36PZMxxZrTEOQ7AHMZ/b0crT/0fCy6FTKg==", + "dependencies": [ + "@discordjs/formatters@0.5.0", + "@discordjs/util", + "@sapphire/shapeshift", + "discord-api-types@0.37.97", + "fast-deep-equal", + "ts-mixer", + "tslib" + ] + }, + "@discordjs/collection@1.5.3": { + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==" + }, + "@discordjs/collection@2.1.1": { + "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==" + }, + "@discordjs/formatters@0.5.0": { + "integrity": "sha512-98b3i+Y19RFq1Xke4NkVY46x8KjJQjldHUuEbCqMvp1F5Iq9HgnGpu91jOi/Ufazhty32eRsKnnzS8n4c+L93g==", + "dependencies": [ + "discord-api-types@0.37.97" + ] + }, + "@discordjs/formatters@0.6.0": { + "integrity": "sha512-YIruKw4UILt/ivO4uISmrGq2GdMY6EkoTtD0oS0GvkJFRZbTSdPhzYiUILbJ/QslsvC9H9nTgGgnarnIl4jMfw==", + "dependencies": [ + "discord-api-types@0.37.115" + ] + }, + "@discordjs/node-pre-gyp@0.4.5": { + "integrity": "sha512-YJOVVZ545x24mHzANfYoy0BJX5PDyeZlpiJjDkUBM/V/Ao7TFX9lcUvCN4nr0tbr5ubeaXxtEBILUrHtTphVeQ==", + "dependencies": [ + "detect-libc", + "https-proxy-agent", + "make-dir", + "node-fetch", + "nopt", + "npmlog", + "rimraf", + "semver@7.6.3", + "tar" + ] + }, + "@discordjs/opus@0.9.0": { + "integrity": "sha512-NEE76A96FtQ5YuoAVlOlB3ryMPrkXbUCTQICHGKb8ShtjXyubGicjRMouHtP1RpuDdm16cDa+oI3aAMo1zQRUQ==", + "dependencies": [ + "@discordjs/node-pre-gyp", + "node-addon-api" + ] + }, + "@discordjs/rest@2.4.0": { + "integrity": "sha512-Xb2irDqNcq+O8F0/k/NaDp7+t091p+acb51iA4bCKfIn+WFWd6HrNvcsSbMMxIR9NjcMZS6NReTKygqiQN+ntw==", + "dependencies": [ + "@discordjs/collection@2.1.1", + "@discordjs/util", + "@sapphire/async-queue", + "@sapphire/snowflake@3.5.5", + "@vladfrangu/async_event_emitter", + "discord-api-types@0.37.97", + "magic-bytes.js", + "tslib", + "undici@6.19.8" + ] + }, + "@discordjs/rest@2.4.2": { + "integrity": "sha512-9bOvXYLQd5IBg/kKGuEFq3cstVxAMJ6wMxO2U3wjrgO+lHv8oNCT+BBRpuzVQh7BoXKvk/gpajceGvQUiRoJ8g==", + "dependencies": [ + "@discordjs/collection@2.1.1", + "@discordjs/util", + "@sapphire/async-queue", + "@sapphire/snowflake@3.5.5", + "@vladfrangu/async_event_emitter", + "discord-api-types@0.37.115", + "magic-bytes.js", + "tslib", + "undici@6.19.8" + ] + }, + "@discordjs/util@1.1.1": { + "integrity": "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==" + }, + "@discordjs/voice@0.17.0_@discordjs+opus@0.9.0_ffmpeg-static@5.2.0": { + "integrity": "sha512-hArn9FF5ZYi1IkxdJEVnJi+OxlwLV0NJYWpKXsmNOojtGtAZHxmsELA+MZlu2KW1F/K1/nt7lFOfcMXNYweq9w==", + "dependencies": [ + "@types/ws", + "discord-api-types@0.37.83", + "prism-media", + "tslib", + "ws" + ] + }, + "@discordjs/ws@1.2.0": { + "integrity": "sha512-QH5CAFe3wHDiedbO+EI3OOiyipwWd+Q6BdoFZUw/Wf2fw5Cv2fgU/9UEtJRmJa9RecI+TAhdGPadMaEIur5yJg==", + "dependencies": [ + "@discordjs/collection@2.1.1", + "@discordjs/rest@2.4.2", + "@discordjs/util", + "@sapphire/async-queue", + "@types/ws", + "@vladfrangu/async_event_emitter", + "discord-api-types@0.37.115", + "tslib", + "ws" + ] + }, + "@discordjs/ws@2.0.0": { + "integrity": "sha512-VSVFMOFE+G9bp/2+4e/lFySIU+urxW8NPRXPsKLbP9AUl1MvQxoUVIUfPjZkUP23jjQh+AvWWm6vaA0A5Rb2Rg==", + "dependencies": [ + "@discordjs/collection@2.1.1", + "@discordjs/rest@2.4.0", + "@discordjs/util", + "@sapphire/async-queue", + "@types/ws", + "@vladfrangu/async_event_emitter", + "discord-api-types@0.37.97", + "tslib", + "ws" + ] + }, + "@distube/ytdl-core@4.15.1_tough-cookie@4.1.4_undici@5.28.4": { + "integrity": "sha512-10voV+ixUVQgam4/GMhjNTX/ipk9odkPnPoRaUESs5E/EW0JujwPDc815z53D86mSRlVc8esH1eiuzFnxLJKcA==", + "dependencies": [ + "http-cookie-agent", + "m3u8stream", + "miniget", + "sax", + "tough-cookie", + "undici@5.28.4" + ] + }, + "@fastify/busboy@2.1.1": { + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==" + }, + "@mongodb-js/saslprep@1.1.9": { + "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", + "dependencies": [ + "sparse-bitfield" + ] + }, + "@sapphire/async-queue@1.5.5": { + "integrity": "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==" + }, + "@sapphire/shapeshift@4.0.0": { + "integrity": "sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==", + "dependencies": [ + "fast-deep-equal", + "lodash" + ] + }, + "@sapphire/snowflake@3.5.3": { + "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==" + }, + "@sapphire/snowflake@3.5.5": { + "integrity": "sha512-xzvBr1Q1c4lCe7i6sRnrofxeO1QTP/LKQ6A6qy0iB4x5yfiSfARMEQEghojzTNALDTcv8En04qYNIco9/K9eZQ==" + }, + "@types/node@10.17.60": { + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "@types/node@22.5.4": { + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "dependencies": [ + "undici-types" + ] + }, + "@types/triple-beam@1.3.5": { + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, + "@types/webidl-conversions@7.0.3": { + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + }, + "@types/whatwg-url@11.0.5": { + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "dependencies": [ + "@types/webidl-conversions" + ] + }, + "@types/ws@8.5.13": { + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "dependencies": [ + "@types/node@22.5.4" + ] + }, + "@vladfrangu/async_event_emitter@2.4.6": { + "integrity": "sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==" + }, + "abbrev@1.1.1": { + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "agent-base@6.0.2": { + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": [ + "debug" + ] + }, + "agent-base@7.1.1": { + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": [ + "debug" + ] + }, + "ansi-regex@2.1.1": { + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" + }, + "ansi-regex@3.0.1": { + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==" + }, + "ansi-regex@5.0.1": { + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "aproba@2.0.0": { + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "are-we-there-yet@2.0.0": { + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": [ + "delegates", + "readable-stream" + ] + }, + "async.parallellimit@0.5.2": { + "integrity": "sha512-4Di2nFsb3jL7aUIICvRSvtw/oynpMIx0JrwYn5hqJI661Dd+mYBi2ElOukOQgRHihU1SCTapb86Vx/Snva5M1w==", + "dependencies": [ + "async.util.eachoflimit", + "async.util.parallel" + ] + }, + "async.util.eachoflimit@0.5.2": { + "integrity": "sha512-oZksH0sBW0AEOJKgBCQ79io9DZruoRBLTAea/Ik36pejR7pDpByvtXeuJsoZdPwSVslsrQcsUfucbUaiXYBnAQ==", + "dependencies": [ + "async.util.keyiterator", + "async.util.noop", + "async.util.once", + "async.util.onlyonce" + ] + }, + "async.util.isarray@0.5.2": { + "integrity": "sha512-wbUzlrwON8RUgi+v/rhF0U99Ce8Osjcn+JP/mFNg6ymvShcobAOvE6cvLajSY5dPqKCOE1xfdhefgBif11zZgw==" + }, + "async.util.isarraylike@0.5.2": { + "integrity": "sha512-DbFpsz3ZFNkohAW8IpGTlm8gotU32zpqe3Y2XkEA/G3XNO6rmUTKPpo7XgXUruoI+AsGi8+0zWpJHe7t1sLiAg==", + "dependencies": [ + "async.util.isarray" + ] + }, + "async.util.keyiterator@0.5.2": { + "integrity": "sha512-cktrETawCwgu13y3KZs2uMGFnNHc+IjKPZsavtRaoCjLELkePb2co4zrr+ghPvEqLXZIJPTKqC2HFZgJTssMVw==", + "dependencies": [ + "async.util.isarraylike", + "async.util.keys" + ] + }, + "async.util.keys@0.5.2": { + "integrity": "sha512-umCOCRCRYwIC2Ho3fbuhKwIIe7OhQsVoVKGoF5GoQiGJUmjP4TG0Bmmcdpm7yW/znoIGKpnjKzVQz0niH4tfqw==" + }, + "async.util.noop@0.5.2": { + "integrity": "sha512-AdwShXwE0KoskgqVJAck8zcM32nIHj3AC8ZN62ZaR5srhrY235Nw18vOJZWxcOfhxdVM0hRVKM8kMx7lcl7cCQ==" + }, + "async.util.once@0.5.2": { + "integrity": "sha512-YQ5WPzDTt2jlblUDkq2I5RV/KiAJErJ4/0cEFhYPaZzqIuF/xDzdGvnEKe7UeuoMszsVPeajzcpKgkbwdb9MUA==" + }, + "async.util.onlyonce@0.5.2": { + "integrity": "sha512-UgQvkU9JZ+I0Cm1f56XyGXcII+J3d/5XWUuHpcevlItuA3WFSJcqZrsyAUck2FkRSD8BwYQX1zUTDp3SJMVESg==" + }, + "async.util.parallel@0.5.2": { + "integrity": "sha512-0bEvwmQ8fxsTYNwacw5iq0i3PvGryRkXxZ01Rvox21izdMdls9IH2rAZjfunbgI8j6nFRyIdCmMINQ9kka99ow==", + "dependencies": [ + "async.util.isarraylike", + "async.util.noop", + "async.util.restparam" + ] + }, + "async.util.restparam@0.5.2": { + "integrity": "sha512-Q9Z+zgmtMxFX5i7CnBvNOkgrL5hptztCqwarQluyNudUUk4iCmyjmsQl8MuQEjNh3gGqP5ayvDaextL1VXXgIg==" + }, + "async@3.2.6": { + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" + }, + "balanced-match@1.0.2": { + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "boolbase@1.0.0": { + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "boolstring@1.0.2": { + "integrity": "sha512-0JLNSmZUv1m/O8sVayFm2t0naiOXwQ9O2Gq9u1eoIkhvu6U5NQER/e3k4BGpjZ33G775lWMT7TzJ7r5VtmEnbQ==" + }, + "brace-expansion@1.1.11": { + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": [ + "balanced-match", + "concat-map" + ] + }, + "bson@6.9.0": { + "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==" + }, + "buffer-from@1.1.2": { + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "caseless@0.12.0": { + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "cheerio-select@2.1.0": { + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dependencies": [ + "boolbase", + "css-select", + "css-what", + "domelementtype", + "domhandler", + "domutils" + ] + }, + "cheerio@1.0.0": { + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "dependencies": [ + "cheerio-select", + "dom-serializer", + "domhandler", + "domutils", + "encoding-sniffer", + "htmlparser2@9.1.0", + "parse5", + "parse5-htmlparser2-tree-adapter", + "parse5-parser-stream", + "undici@6.19.8", + "whatwg-mimetype" + ] + }, + "cheerio@1.0.0-rc.12": { + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dependencies": [ + "cheerio-select", + "dom-serializer", + "domhandler", + "domutils", + "htmlparser2@8.0.2", + "parse5", + "parse5-htmlparser2-tree-adapter" + ] + }, + "chownr@2.0.0": { + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "cli-color@1.2.0": { + "integrity": "sha512-AqfwItf/UqGif3FBErI3NHX04v5ywJtGYlL5z4OqWR50u7g+Fz3Xw2qcCIbKVPrqtJCBwSOkDgnSlHbcpwDKHw==", + "dependencies": [ + "ansi-regex@2.1.1", + "d", + "es5-ext", + "es6-iterator", + "memoizee", + "timers-ext" + ] + }, + "color-convert@1.9.3": { + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": [ + "color-name" + ] + }, + "color-name@1.1.3": { + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "color-string@1.9.1": { + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": [ + "color-name", + "simple-swizzle" + ] + }, + "color-support@1.1.3": { + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, + "color@3.2.1": { + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": [ + "color-convert", + "color-string" + ] + }, + "colorspace@1.1.4": { + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": [ + "color", + "text-hex" + ] + }, + "concat-map@0.0.1": { + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "concat-stream@2.0.0": { + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dependencies": [ + "buffer-from", + "inherits", + "readable-stream", + "typedarray" + ] + }, + "console-control-strings@1.1.0": { + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, + "css-select@5.1.0": { + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dependencies": [ + "boolbase", + "css-what", + "domhandler", + "domutils", + "nth-check" + ] + }, + "css-what@6.1.0": { + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + }, + "d@1.0.2": { + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dependencies": [ + "es5-ext", + "type" + ] + }, + "dasu@0.4.3": { + "integrity": "sha512-AFwspl5k7V8MW8H7tyIGJ0gtOauUg7JC+DgiRFUIXvPNNDFXTMtvnCkZY0macN6JLGqBjNP38WVnQN7Iv3RSlg==" + }, + "dayjs@1.11.13": { + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" + }, + "debug@4.3.7": { + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": [ + "ms" + ] + }, + "delegates@1.0.0": { + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, + "detect-libc@2.0.3": { + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==" + }, + "discord-api-types@0.37.0": { + "integrity": "sha512-6LlL0xceiZs/kQ5PeKe5inkcjR73vagt3oACsP/C5IWKjXfzLGKrXn6yRYgiHIeJyFZ1xVPRJYE4W/u8UTT4ig==" + }, + "discord-api-types@0.37.115": { + "integrity": "sha512-ivPnJotSMrXW8HLjFu+0iCVs8zP6KSliMelhr7HgcB2ki1QzpORkb26m71l1pzSnnGfm7gb5n/VtRTtpw8kXFA==" + }, + "discord-api-types@0.37.83": { + "integrity": "sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==" + }, + "discord-api-types@0.37.97": { + "integrity": "sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA==" + }, + "discord-ytdl-core@5.0.4_@discordjs+opus@0.9.0_ffmpeg-static@5.2.0": { + "integrity": "sha512-O+G9wuCw5TERR9iHZFMYnYQbs/ZGudDc9cxa1OKSV5TdcBYrHGS1JqvE90ZvSQ6SmS4XvqtOf/Okls6yiGJ3sg==", + "dependencies": [ + "prism-media" + ] + }, + "discord.js@14.17.2": { + "integrity": "sha512-mrH6ziLVtNtId4bV4bsaUt5jE6NUaiHMPqO5VsSw1VVhFnjFi9duD8ctlo90/6cUH+8uyKBkoq9mSJ35SuuZ7Q==", + "dependencies": [ + "@discordjs/builders@1.10.0", + "@discordjs/collection@1.5.3", + "@discordjs/formatters@0.6.0", + "@discordjs/rest@2.4.2", + "@discordjs/util", + "@discordjs/ws@1.2.0", + "@sapphire/snowflake@3.5.3", + "discord-api-types@0.37.115", + "fast-deep-equal", + "lodash.snakecase", + "tslib", + "undici@6.19.8" + ] + }, + "dom-serializer@2.0.0": { + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": [ + "domelementtype", + "domhandler", + "entities" + ] + }, + "domelementtype@2.3.0": { + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domhandler@5.0.3": { + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": [ + "domelementtype" + ] + }, + "domutils@3.1.0": { + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dependencies": [ + "dom-serializer", + "domelementtype", + "domhandler" + ] + }, + "emoji-regex@8.0.0": { + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "enabled@2.0.0": { + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, + "encoding-sniffer@0.2.0": { + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "dependencies": [ + "iconv-lite", + "whatwg-encoding" + ] + }, + "entities@4.5.0": { + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "env-paths@2.2.1": { + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + }, + "es5-ext@0.10.64": { + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "dependencies": [ + "es6-iterator", + "es6-symbol", + "esniff", + "next-tick" + ] + }, + "es6-iterator@2.0.3": { + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": [ + "d", + "es5-ext", + "es6-symbol" + ] + }, + "es6-symbol@3.1.4": { + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dependencies": [ + "d", + "ext" + ] + }, + "es6-weak-map@2.0.3": { + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dependencies": [ + "d", + "es5-ext", + "es6-iterator", + "es6-symbol" + ] + }, + "esniff@2.0.1": { + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dependencies": [ + "d", + "es5-ext", + "event-emitter", + "type" + ] + }, + "event-emitter@0.3.5": { + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": [ + "d", + "es5-ext" + ] + }, + "ext@1.7.0": { + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": [ + "type" + ] + }, + "fast-deep-equal@3.1.3": { + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fecha@4.2.3": { + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, + "ffmpeg-static@5.2.0": { + "integrity": "sha512-WrM7kLW+do9HLr+H6tk7LzQ7kPqbAgLjdzNE32+u3Ff11gXt9Kkkd2nusGFrlWMIe+XaA97t+I8JS7sZIrvRgA==", + "dependencies": [ + "@derhuerst/http-basic", + "env-paths", + "https-proxy-agent", + "progress" + ] + }, + "fn.name@1.1.0": { + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, + "fs-minipass@2.1.0": { + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": [ + "minipass@3.3.6" + ] + }, + "fs.realpath@1.0.0": { + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "gauge@3.0.2": { + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": [ + "aproba", + "color-support", + "console-control-strings", + "has-unicode", + "object-assign", + "signal-exit", + "string-width@4.2.3", + "strip-ansi@6.0.1", + "wide-align" + ] + }, + "glob@7.2.3": { + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": [ + "fs.realpath", + "inflight", + "inherits", + "minimatch@3.1.2", + "once", + "path-is-absolute" + ] + }, + "graceful-fs@4.2.11": { + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "has-unicode@2.0.1": { + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "htmlparser2@8.0.2": { + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dependencies": [ + "domelementtype", + "domhandler", + "domutils", + "entities" + ] + }, + "htmlparser2@9.1.0": { + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dependencies": [ + "domelementtype", + "domhandler", + "domutils", + "entities" + ] + }, + "http-cookie-agent@6.0.6_tough-cookie@4.1.4_undici@5.28.4": { + "integrity": "sha512-XkwhYUWo0yhiHBWqLmAe2kIBymVY70ewi9sKmy6YBHpNU3BCH4nipKrtY5/effAxj0qneQ9ziZG5TXgaKLfYgg==", + "dependencies": [ + "agent-base@7.1.1", + "tough-cookie", + "undici@5.28.4" + ] + }, + "http-response-object@3.0.2": { + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dependencies": [ + "@types/node@10.17.60" + ] + }, + "https-proxy-agent@5.0.1": { + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": [ + "agent-base@6.0.2", + "debug" + ] + }, + "human-time@0.0.2": { + "integrity": "sha512-sbYI90YhYmstslPTb70BLGjy6mdESa0lxL7uDR4fIVAx9Iobz8fLEqi7FqF4Q/6vblrzZALg//MsYJlIPBU8SA==" + }, + "iconv-lite@0.6.3": { + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": [ + "safer-buffer" + ] + }, + "inflight@1.0.6": { + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": [ + "once", + "wrappy" + ] + }, + "inherits@2.0.4": { + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-arrayish@0.3.2": { + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "is-fullwidth-code-point@2.0.0": { + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" + }, + "is-fullwidth-code-point@3.0.0": { + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-promise@2.2.2": { + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "is-stream@2.0.1": { + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "jsonfile@6.1.0": { + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": [ + "graceful-fs", + "universalify@2.0.1" + ] + }, + "jsonpath-plus@5.0.7": { + "integrity": "sha512-7TS6wsiw1s2UMK/A6nA4n0aUJuirCVhJ87nWX5je5MPOl0z5VTr2qs7nMP8NZ2ed3rlt6kePTqddgVPE9F0i0w==" + }, + "kareem@2.6.3": { + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==" + }, + "keypress@0.2.1": { + "integrity": "sha512-HjorDJFNhnM4SicvaUXac0X77NiskggxJdesG72+O5zBKpSqKFCrqmndKVqpu3pFqkla0St6uGk8Ju0sCurrmg==" + }, + "kuler@2.0.0": { + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, + "libsodium-wrappers@0.7.15": { + "integrity": "sha512-E4anqJQwcfiC6+Yrl01C1m8p99wEhLmJSs0VQqST66SbQXXBoaJY0pF4BNjRYa/sOQAxx6lXAaAFIlx+15tXJQ==", + "dependencies": [ + "libsodium" + ] + }, + "libsodium@0.7.15": { + "integrity": "sha512-sZwRknt/tUpE2AwzHq3jEyUU5uvIZHtSssktXq7owd++3CSgn8RGrv6UZJJBpP7+iBghBqe7Z06/2M31rI2NKw==" + }, + "lodash.snakecase@4.1.1": { + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" + }, + "lodash@4.17.21": { + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "logform@2.7.0": { + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", + "dependencies": [ + "@colors/colors", + "@types/triple-beam", + "fecha", + "ms", + "safe-stable-stringify", + "triple-beam" + ] + }, + "lru-queue@0.1.0": { + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dependencies": [ + "es5-ext" + ] + }, + "m3u8stream@0.8.6": { + "integrity": "sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==", + "dependencies": [ + "miniget", + "sax" + ] + }, + "magic-bytes.js@1.10.0": { + "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==" + }, + "make-dir@3.1.0": { + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": [ + "semver@6.3.1" + ] + }, + "memoizee@0.4.17": { + "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", + "dependencies": [ + "d", + "es5-ext", + "es6-weak-map", + "event-emitter", + "is-promise", + "lru-queue", + "next-tick", + "timers-ext" + ] + }, + "memory-pager@1.5.0": { + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, + "miniget@4.2.3": { + "integrity": "sha512-SjbDPDICJ1zT+ZvQwK0hUcRY4wxlhhNpHL9nJOB2MEAXRGagTljsO8MEDzQMTFf0Q8g4QNi8P9lEm/g7e+qgzA==" + }, + "minimatch@3.0.8": { + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dependencies": [ + "brace-expansion" + ] + }, + "minimatch@3.1.2": { + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": [ + "brace-expansion" + ] + }, + "minimist@1.2.8": { + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + }, + "minipass@3.3.6": { + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": [ + "yallist" + ] + }, + "minipass@5.0.0": { + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" + }, + "minizlib@2.1.2": { + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": [ + "minipass@3.3.6", + "yallist" + ] + }, + "mkdirp@1.0.4": { + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "mongodb-connection-string-url@3.0.1": { + "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "dependencies": [ + "@types/whatwg-url", + "whatwg-url@13.0.0" + ] + }, + "mongodb@6.10.0": { + "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==", + "dependencies": [ + "@mongodb-js/saslprep", + "bson", + "mongodb-connection-string-url" + ] + }, + "mongoose@8.8.0": { + "integrity": "sha512-KluvgwnQB1GPOYZZXUHJRjS1TW6xxwTlf/YgjWExuuNanIe3W7VcR7dDXQVCIRk8L7NYge8EnoTcu2grWtN+XQ==", + "dependencies": [ + "bson", + "kareem", + "mongodb", + "mpath", + "mquery", + "ms", + "sift" + ] + }, + "mpath@0.9.0": { + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==" + }, + "mquery@5.0.0": { + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": [ + "debug" + ] + }, + "ms@2.1.3": { + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "next-tick@1.1.0": { + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node-addon-api@5.1.0": { + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, + "node-fetch@2.7.0": { + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": [ + "whatwg-url@5.0.0" + ] + }, + "node-fzf@0.5.3": { + "integrity": "sha512-crN8rRfApu/GUrtKq+zJ6LueUyNAOJpFHxoT2Ru1Q+OYRa/F/H7CXvzcMrFc7D964yakYZEZ9XR3YbdSHXgyCw==", + "dependencies": [ + "cli-color", + "keypress", + "minimist", + "redstar", + "string-width@2.1.1", + "ttys" + ] + }, + "nopt@5.0.0": { + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": [ + "abbrev" + ] + }, + "npmlog@5.0.1": { + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": [ + "are-we-there-yet", + "console-control-strings", + "gauge", + "set-blocking" + ] + }, + "nth-check@2.1.1": { + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": [ + "boolbase" + ] + }, + "object-assign@4.1.1": { + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "once@1.4.0": { + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": [ + "wrappy" + ] + }, + "one-time@1.0.0": { + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": [ + "fn.name" + ] + }, + "opusscript@0.1.1": { + "integrity": "sha512-mL0fZZOUnXdZ78woRXp18lApwpp0lF5tozJOD1Wut0dgrA9WuQTgSels/CSmFleaAZrJi/nci5KOVtbuxeWoQA==" + }, + "parse-cache-control@1.0.1": { + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" + }, + "parse5-htmlparser2-tree-adapter@7.1.0": { + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dependencies": [ + "domhandler", + "parse5" + ] + }, + "parse5-parser-stream@7.1.2": { + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dependencies": [ + "parse5" + ] + }, + "parse5@7.2.1": { + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dependencies": [ + "entities" + ] + }, + "path-is-absolute@1.0.1": { + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "play-audio@0.5.2": { + "integrity": "sha512-ZAqHUKkQLix2Iga7pPbsf1LpUoBjcpwU93F1l3qBIfxYddQLhxS6GKmS0d3jV8kSVaUbr6NnOEcEMFvuX93SWQ==" + }, + "play-dl@1.9.7": { + "integrity": "sha512-KpgerWxUCY4s9Mhze2qdqPhiqd8Ve6HufpH9mBH3FN+vux55qSh6WJKDabfie8IBHN7lnrAlYcT/UdGax58c2A==", + "dependencies": [ + "play-audio" + ] + }, + "prism-media@1.3.5_@discordjs+opus@0.9.0_ffmpeg-static@5.2.0": { + "integrity": "sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==", + "dependencies": [ + "@discordjs/opus", + "ffmpeg-static" + ] + }, + "progress@2.0.3": { + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "psl@1.10.0": { + "integrity": "sha512-KSKHEbjAnpUuAUserOq0FxGXCUrzC3WniuSJhvdbs102rL55266ZcHBqLWOsG30spQMlPdpy7icATiAQehg/iA==", + "dependencies": [ + "punycode" + ] + }, + "punycode@2.3.1": { + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" + }, + "querystringify@2.2.0": { + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "readable-stream@3.6.2": { + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": [ + "inherits", + "string_decoder", + "util-deprecate" + ] + }, + "redstar@0.0.2": { + "integrity": "sha512-VNvLaLxMJMYiAasJX5Q/GC+Os7FXL0yPWFDuTodhR7Na9wqzrXsePPWC+EtIv4t3q5DyAK00w423xi5mQN2fqg==", + "dependencies": [ + "minimatch@3.0.8" + ] + }, + "requires-port@1.0.0": { + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "rimraf@3.0.2": { + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": [ + "glob" + ] + }, + "roll@1.3.2": { + "integrity": "sha512-93C3mjFTbnVuS79sdcRYqj4+AVidLwnwMMqeX16E8umZ3kTunnW9knrctHy8YcWvFFppvzs2SlMjevzg6tctYg==", + "dependencies": [ + "minimist" + ] + }, + "safe-buffer@5.2.1": { + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-stable-stringify@2.5.0": { + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==" + }, + "safer-buffer@2.1.2": { + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax@1.4.1": { + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" + }, + "semver@6.3.1": { + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "semver@7.6.3": { + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" + }, + "set-blocking@2.0.0": { + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, + "sift@17.1.3": { + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==" + }, + "signal-exit@3.0.7": { + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "simple-swizzle@0.2.2": { + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": [ + "is-arrayish" + ] + }, + "sparse-bitfield@3.0.3": { + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": [ + "memory-pager" + ] + }, + "stack-trace@0.0.10": { + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" + }, + "string-width@2.1.1": { + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dependencies": [ + "is-fullwidth-code-point@2.0.0", + "strip-ansi@4.0.0" + ] + }, + "string-width@4.2.3": { + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": [ + "emoji-regex", + "is-fullwidth-code-point@3.0.0", + "strip-ansi@6.0.1" + ] + }, + "string_decoder@1.3.0": { + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": [ + "safe-buffer" + ] + }, + "strip-ansi@4.0.0": { + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dependencies": [ + "ansi-regex@3.0.1" + ] + }, + "strip-ansi@6.0.1": { + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": [ + "ansi-regex@5.0.1" + ] + }, + "tar@6.2.1": { + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dependencies": [ + "chownr", + "fs-minipass", + "minipass@5.0.0", + "minizlib", + "mkdirp", + "yallist" + ] + }, + "text-hex@1.0.0": { + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, + "timers-ext@0.1.8": { + "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", + "dependencies": [ + "es5-ext", + "next-tick" + ] + }, + "tough-cookie@4.1.4": { + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dependencies": [ + "psl", + "punycode", + "universalify@0.2.0", + "url-parse" + ] + }, + "tr46@0.0.3": { + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "tr46@4.1.1": { + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dependencies": [ + "punycode" + ] + }, + "triple-beam@1.4.1": { + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==" + }, + "ts-mixer@6.0.4": { + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==" + }, + "tslib@2.8.1": { + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "ttys@0.0.3": { + "integrity": "sha512-UCqXRZS2S7U4aVB7Salj3ChPRSsb57ogJpJ1eMCvyowxFOBGsaHKcRU8bovcDwajX1mRbv0IpUnYkoG7Ieo5Zg==" + }, + "type@2.7.3": { + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==" + }, + "typedarray@0.0.6": { + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "undici-types@6.19.8": { + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, + "undici@5.28.4": { + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dependencies": [ + "@fastify/busboy" + ] + }, + "undici@6.19.8": { + "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==" + }, + "universalify@0.2.0": { + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" + }, + "universalify@2.0.1": { + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" + }, + "url-parse@1.5.10": { + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": [ + "querystringify", + "requires-port" + ] + }, + "util-deprecate@1.0.2": { + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "voca@1.4.1": { + "integrity": "sha512-NJC/BzESaHT1p4B5k4JykxedeltmNbau4cummStd4RjFojgq/kLew5TzYge9N2geeWyI2w8T30wUET5v+F7ZHA==" + }, + "webidl-conversions@3.0.1": { + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "webidl-conversions@7.0.0": { + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "whatwg-encoding@3.1.1": { + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dependencies": [ + "iconv-lite" + ] + }, + "whatwg-mimetype@4.0.0": { + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" + }, + "whatwg-url@13.0.0": { + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "dependencies": [ + "tr46@4.1.1", + "webidl-conversions@7.0.0" + ] + }, + "whatwg-url@5.0.0": { + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": [ + "tr46@0.0.3", + "webidl-conversions@3.0.1" + ] + }, + "wide-align@1.1.5": { + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": [ + "string-width@4.2.3" + ] + }, + "winston-transport@4.9.0": { + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "dependencies": [ + "logform", + "readable-stream", + "triple-beam" + ] + }, + "winston@3.16.0": { + "integrity": "sha512-xz7+cyGN5M+4CmmD4Npq1/4T+UZaz7HaeTlAruFUTjk79CNMq+P6H30vlE4z0qfqJ01VHYQwd7OZo03nYm/+lg==", + "dependencies": [ + "@colors/colors", + "@dabh/diagnostics", + "async", + "is-stream", + "logform", + "one-time", + "readable-stream", + "safe-stable-stringify", + "stack-trace", + "triple-beam", + "winston-transport" + ] + }, + "wrappy@1.0.2": { + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "ws@8.18.0": { + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==" + }, + "yallist@4.0.0": { + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yt-search@2.12.1": { + "integrity": "sha512-suEbEGqIDa7OBuZQSNabPKS4sZrHrocak7JhxSw3gagCUxPgHqyEDqyWEruvLYax2uCIQ7UhQoDVqQGOFn+jrQ==", + "dependencies": [ + "async.parallellimit", + "boolstring", + "cheerio@1.0.0-rc.12", + "dasu", + "human-time", + "jsonpath-plus", + "minimist", + "node-fzf" + ] + }, + "ytdl-core@4.11.5": { + "integrity": "sha512-27LwsW4n4nyNviRCO1hmr8Wr5J1wLLMawHCQvH8Fk0hiRqrxuIu028WzbJetiYH28K8XDbeinYW4/wcHQD1EXA==", + "dependencies": [ + "m3u8stream", + "miniget", + "sax" + ] + } + }, + "workspace": { + "dependencies": [ + "jsr:@std/dotenv@~0.225.2", + "jsr:@std/expect@^1.0.7", + "npm:@discordjs/builders@1.9.0", + "npm:@discordjs/opus@0.9.0", + "npm:@discordjs/rest@^2.4.0", + "npm:@discordjs/voice@0.17.0", + "npm:@discordjs/ws@2", + "npm:@distube/ytdl-core@^4.15.1", + "npm:cheerio@1.0.0-rc.12", + "npm:dayjs@1.11.13", + "npm:discord-api-types@0.37.0", + "npm:discord-ytdl-core@5.0.4", + "npm:discord.js@14.17.2", + "npm:ffmpeg-static@5.2.0", + "npm:jsonfile@6.1.0", + "npm:libsodium-wrappers@0.7.15", + "npm:mongoose@8.8.0", + "npm:opusscript@0.1.1", + "npm:play-dl@^1.9.7", + "npm:roll@1.3.2", + "npm:voca@1.4.1", + "npm:winston@3.16.0", + "npm:yt-search@2.12.1", + "npm:ytdl-core@4.11.5" + ] + } +} diff --git a/docker-compose.yaml b/docker-compose.yaml index 6857d1bf..f9571ff7 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,4 +1,4 @@ -version: '3.9' +version: "3.9" services: portal: @@ -26,9 +26,9 @@ services: restart: always image: mongo:5.0 logging: - driver: 'none' + driver: "none" ports: - - '27017:27017' + - "27017:27017" volumes: - type: bind source: ../mongo/data/db diff --git a/docker/Dockerfile b/docker/Dockerfile index 29eeb6f9..dd43ce0a 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,20 +1,14 @@ -FROM node:18 +# Use the official Deno image +FROM denoland/deno:2.1.7 -# Create app directory -RUN mkdir -p /usr/src/portal -# Make app working directory +# Set the working directory WORKDIR /usr/src/portal -COPY package*.json ./ -COPY tsconfig*.json ./ - -# If you are building your code for production -# RUN npm ci --only=production else RUN npm install -RUN npm ci --only=production -RUN npm install typescript --save-dev - -# Bundle app source +# Copy the necessary files to the container COPY . . -RUN npm run build -CMD [ "node", "build/app.js" ] +# Cache and install dependencies +RUN deno cache src/app.ts + +# Run the application with necessary permissions +CMD ["run", "--allow-net", "--allow-read", "--allow-env", "--allow-write", "--allow-ffi", "--allow-run", "--allow-sys", "src/app.ts"] diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index a01f7aca..a2bf3986 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -6,91 +6,118 @@ Contributing to the portal Project # 1. Introduction -We welcome any help, for example contributing feature implementations, bug fixes and bug reports. +We welcome any help, for example contributing feature implementations, bug fixes +and bug reports. Our Pledge -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of +experience, nationality, personal appearance, race, religion, or sexual identity +and orientation. # 2. Contributing code via GitHub -Code contributions can be performed via _pull requests_ (PR) exclusively. -As a rule-of-thumb: +Code contributions can be performed via _pull requests_ (PR) exclusively. As a +rule-of-thumb: - PRs should be kept at a manageable size. -- Try to focus on just one goal per PR. If you find yourself doing several things in a PR that were not expected, - then try to split the different tasks into different PRs. -- Commits should always change a _single_ logical unit so that cherry-picking & reverting is simple. -- Commit messages should be as informative and concise as possible. The first line of the commit message should be < 80 characters and - describe the commit briefly. If the 80 characters are too short for a summary, then consider splitting the commit. - Optionally, add one blank line below the short summary and write a more detailed explanation if necessary. - -Below we outline the recommended steps in the code contribution workflow. We use `your-username` to refer to your username on GitHub, `portal_upstream` is used when we -set the upstream remote repository for Portal (we could have picked any name but try to avoid already used names like, in particular, `origin` and `master`), and -we use the name `my-new-feature` for the branch that we create (e.g., the branch name should reflect the code change being made, keybraker-updating-music-player). - -**Important**: If your PR lives for a long time, then don't press the button _Update branch_ in the Pull Request view, instead follow the steps below, as +- Try to focus on just one goal per PR. If you find yourself doing several + things in a PR that were not expected, then try to split the different tasks + into different PRs. +- Commits should always change a _single_ logical unit so that cherry-picking & + reverting is simple. +- Commit messages should be as informative and concise as possible. The first + line of the commit message should be < 80 characters and describe the commit + briefly. If the 80 characters are too short for a summary, then consider + splitting the commit. Optionally, add one blank line below the short summary + and write a more detailed explanation if necessary. + +Below we outline the recommended steps in the code contribution workflow. We use +`your-username` to refer to your username on GitHub, `portal_upstream` is used +when we set the upstream remote repository for Portal (we could have picked any +name but try to avoid already used names like, in particular, `origin` and +`master`), and we use the name `my-new-feature` for the branch that we create +(e.g., the branch name should reflect the code change being made, +keybraker-updating-music-player). + +**Important**: If your PR lives for a long time, then don't press the button +_Update branch_ in the Pull Request view, instead follow the steps below, as that avoids additional merge commits. Once you have a GitHub login: -1. Fork Portal git repository to your GitHub account by pressing the _Fork_ button at: [https://github.com/keybraker/portal](https://github.com/keybraker/portal) +1. Fork Portal git repository to your GitHub account by pressing the _Fork_ + button at: + [https://github.com/keybraker/portal](https://github.com/keybraker/portal) -2. Then start a terminal (or use your favorite git GUI app) and clone your fork of Portal: +2. Then start a terminal (or use your favorite git GUI app) and clone your fork + of Portal: - $ git clone https://github.com:your-username/portal.git - $ cd porrtal + $ git clone https://github.com:your-username/portal.git + $ cd porrtal -3. Add a new remote pointing to master Portal repository: +3. Add a new remote pointing to master Portal repository: - $ git remote add portal_upstream https://github.com/keybraker/portal.git + $ git remote add portal_upstream https://github.com/keybraker/portal.git - and verify that you have the two remotes configured correctly: + and verify that you have the two remotes configured correctly: - $ git remote -v - portal_upstream https://github.com/keybraker/portal.git (fetch) - portal_upstream https://github.com/keybraker/portal.git (push) - origin https://github.com/your-username/portal.git (fetch) - origin https://github.com/your-username/portal.git (push) + $ git remote -v + portal_upstream https://github.com/keybraker/portal.git (fetch) + portal_upstream https://github.com/keybraker/portal.git (push) + origin https://github.com/your-username/portal.git (fetch) + origin https://github.com/your-username/portal.git (push) -4. Next, create a branch for your PR from `portal_upstream/master` (which we also need to fetch first): +4. Next, create a branch for your PR from `portal_upstream/master` (which we + also need to fetch first): - $ git fetch portal_upstream master - $ git checkout -b my-new-feature portal_upstream/master --no-track + $ git fetch portal_upstream master + $ git checkout -b my-new-feature portal_upstream/master --no-track - NB: This is an important step to avoid draging in old commits! + NB: This is an important step to avoid draging in old commits! -5. Configure the project and check that it builds (if not, please report a bug): +5. Configure the project and check that it builds (if not, please report a bug): - $ npm install + $ npm install -6. Now, make your change(s), add tests for your changes, and commit each change: +6. Now, make your change(s), add tests for your changes, and commit each change: - ... + ... - $ git commit -m "Commit message 1" + $ git commit -m "Commit message 1" - ... + ... - $ git commit -m "Commit message 2" + $ git commit -m "Commit message 2" -7. If your feature or update is event-free add testing for your changes to corresponding test file or a new file (if necessary) +7. If your feature or update is event-free add testing for your changes to + corresponding test file or a new file (if necessary) -8. Make sure all tests pass +8. Make sure all tests pass - $ npm test + $ npm test -9. Push the changes to your fork on GitHub: +9. Push the changes to your fork on GitHub: - $ git push origin my-new-feature + $ git push origin my-new-feature -10. Create the PR by pressing the _New pull request_ button on: `https://github.com/your-username/portal`. - Please select the option "Allow edits from maintainers" as outlined [here](https://help.github.com/en/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork). +10. Create the PR by pressing the _New pull request_ button on: + `https://github.com/your-username/portal`. Please select the option "Allow + edits from maintainers" as outlined + [here](https://help.github.com/en/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork). -11. Now wait for a portal project member(s) to respond to your PR. Follow the discussion on your PR at [GitHub](https://github.com/keybraker/portal/pulls). - You may have to do some updates to your PR until it gets accepted. If you are inactive for more than three days the pull request is rejected. +11. Now wait for a portal project member(s) to respond to your PR. Follow the + discussion on your PR at + [GitHub](https://github.com/keybraker/portal/pulls). You may have to do some + updates to your PR until it gets accepted. If you are inactive for more than + three days the pull request is rejected. -12. After the PR has been reviewed you must _rebase_ your repo copy or merge with dev since there may have been several changes to the upstream repository. +12. After the PR has been reviewed you must _rebase_ your repo copy or merge + with dev since there may have been several changes to the upstream + repository. Switch to your branch again @@ -100,12 +127,13 @@ Once you have a GitHub login: $ git pull --rebase portal_upstream master - When you perform a rebase the commit history is rewritten and, therefore, the next time you try to push your branch to your fork repository you will need to use - the `--force-with-lease` option: + When you perform a rebase the commit history is rewritten and, therefore, + the next time you try to push your branch to your fork repository you will + need to use the `--force-with-lease` option: $ git push --force-with-lease - *** + --- Alternatively you can merge master to your local branch @@ -116,14 +144,16 @@ Once you have a GitHub login: $ git merge origin/master - > ensuring your changes are in sync with remote master is mandatory for your commit to pass - > be aware that conflicts may apear which you must solve before creating a pull request + > ensuring your changes are in sync with remote master is mandatory for your + > commit to pass be aware that conflicts may apear which you must solve + > before creating a pull request # 3. Reporting Bugs Bugs should be reported by creating Issues on GitHub. -> before reporting a bug first check the issue list if the bug is already known
-> If you cannot find any previous bug report, create a new Issue. When reporting a bug -> try to describe the problem in as much detail as possible and if the bug is triggered -> by an input file then attach that file to the GitHub issue if possible. +> before reporting a bug first check the issue list if the bug is already +> known
If you cannot find any previous bug report, create a new Issue. When +> reporting a bug try to describe the problem in as much detail as possible and +> if the bug is triggered by an input file then attach that file to the GitHub +> issue if possible. diff --git a/docs/README.md b/docs/README.md index 22c265cf..a41db465 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,5 @@

- Disclaimer: The transition to Discord.js v14 is ongoing. Some features may not work as expected until the transition is complete. (Expected Q1 2025) + BIG NEWS: Transitioned to deno2 from nodejs has been completed!

@@ -36,12 +36,20 @@ ## Documentation -- **[Commands](https://portal-bot.xyz/docs/commands/description)**, a list of all Portal commands with descriptions, arguments and how to use them. -- **[Text Interpreter](https://portal-bot.xyz/docs/interpreter/description)** is a program used by Portal to generate a channel's name _with four types of data_ - 1. **[Variables](https://portal-bot.xyz/docs/interpreter/objects/variables/description)**, are immutable and live data, that return information. - 2. **[Attributes](https://portal-bot.xyz/docs/interpreter/objects/attributes/description)**, are mutable options that can be manipulated by whomever has clearance. - 3. **[Pipes](https://portal-bot.xyz/docs/interpreter/objects/pipes/description)**, are mini functions you can pass text variables or attributes to, that manipulate their outcome. - 4. **[Structures](https://portal-bot.xyz/docs/interpreter/objects/structures/description)**, are conditional flow manipulators. +- **[Commands](https://portal-bot.xyz/docs/commands/description)**, a list of + all Portal commands with descriptions, arguments and how to use them. +- **[Text Interpreter](https://portal-bot.xyz/docs/interpreter/description)** is + a program used by Portal to generate a channel's name _with four types of + data_ + 1. **[Variables](https://portal-bot.xyz/docs/interpreter/objects/variables/description)**, + are immutable and live data, that return information. + 2. **[Attributes](https://portal-bot.xyz/docs/interpreter/objects/attributes/description)**, + are mutable options that can be manipulated by whomever has clearance. + 3. **[Pipes](https://portal-bot.xyz/docs/interpreter/objects/pipes/description)**, + are mini functions you can pass text variables or attributes to, that + manipulate their outcome. + 4. **[Structures](https://portal-bot.xyz/docs/interpreter/objects/structures/description)**, + are conditional flow manipulators. ## Changelog @@ -49,25 +57,29 @@ ## More -1. For frequently asked questions (FAQ) with their answers click _[here](https://portal-bot.xyz/help/#faq)_. -2. If you want to host Portal on your own system you can either follow _[standard](https://portal-bot.xyz/hosting/standard/prerequisites)_ or _[docker](https://portal-bot.xyz/hosting/docker/prerequisites)_ guides. -3. Portal is an open source project you can contribute too. There are guidelines for how to properly do it _[here](https://github.com/keybraker/portal/blob/master/docs/CONTRIBUTING.md)_. +1. For frequently asked questions (FAQ) with their answers click + _[here](https://portal-bot.xyz/help/#faq)_. +2. If you want to host Portal on your own system you can either follow + _[standard](https://portal-bot.xyz/hosting/standard/prerequisites)_ or + _[docker](https://portal-bot.xyz/hosting/docker/prerequisites)_ guides. +3. Portal is an open source project you can contribute too. There are guidelines + for how to properly do it + _[here](https://github.com/keybraker/portal/blob/master/docs/CONTRIBUTING.md)_. 4. To read the release history, click _[here](https://portal-bot.xyz/blog)_. #### Disclaimers > - Portal will never record conversations or store anything you type > - Discord updated their server rate limit to twice per 10 minutes.
-> - The new rate limit for channel name and topic updates is 2 updates per 10 minutes, per channel _[more here](https://github.com/discordjs/discord.js/issues/4327)_ +> - The new rate limit for channel name and topic updates is 2 updates per 10 +> minutes, per channel +> _[more here](https://github.com/discordjs/discord.js/issues/4327)_

- nodejs - npm - npm
- nodejs - eslint + deno2 + npm

diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 648c783f..00000000 --- a/package-lock.json +++ /dev/null @@ -1,5240 +0,0 @@ -{ - "name": "portal", - "version": "0.7.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "portal", - "version": "0.7.0", - "dependencies": { - "@discordjs/builders": "^1.9.0", - "@discordjs/opus": "0.9.0", - "@discordjs/voice": "0.17.0", - "@types/jsonfile": "6.1.4", - "cheerio": "1.0.0-rc.12", - "core-util-is": "1.0.3", - "dayjs": "1.11.13", - "discord-ytdl-core": "5.0.4", - "discord.js": "14.16.3", - "dotenv": "16.4.5", - "ffmpeg-static": "5.2.0", - "jsonfile": "6.1.0", - "libsodium-wrappers": "^0.7.15", - "lodash": "4.17.21", - "mongoose": "8.8.0", - "optionator": "0.9.4", - "opusscript": "0.1.1", - "roll": "1.3.2", - "voca": "1.4.1", - "winston": "3.16.0", - "yt-search": "2.12.1", - "ytdl-core": "4.11.5" - }, - "devDependencies": { - "@types/lodash": "4.14.197", - "@types/node": "20.5.7", - "@types/node-fetch": "2.6.11", - "@types/roll": "1.2.3", - "@types/voca": "1.4.6", - "@types/ws": "8.5.13", - "@types/yt-search": "2.10.3", - "@typescript-eslint/eslint-plugin": "^6.21.0", - "@typescript-eslint/parser": "^6.21.0", - "eslint": "^8.57.1", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "5.2.1", - "husky": "8.0.3", - "lint-staged": "14.0.1", - "nodemon": "3.1.7", - "prettier-plugin-organize-imports": "^3.0.0", - "tsconfig-paths": "^4.2.0", - "typescript": "5.6.3" - }, - "optionalDependencies": { - "fsevents": "2.3.3" - } - }, - "node_modules/@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "license": "MIT", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "license": "MIT", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@derhuerst/http-basic": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.4.tgz", - "integrity": "sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==", - "license": "MIT", - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^2.0.0", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@discordjs/builders": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.9.0.tgz", - "integrity": "sha512-0zx8DePNVvQibh5ly5kCEei5wtPBIUbSoE9n+91Rlladz4tgtFbJ36PZMxxZrTEOQ7AHMZ/b0crT/0fCy6FTKg==", - "license": "Apache-2.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.6.3" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/discordjs/discord.js?sponsor" - } - }, - "node_modules/@discordjs/collection": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", - "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=16.11.0" - } - }, - "node_modules/@discordjs/formatters": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.5.0.tgz", - "integrity": "sha512-98b3i+Y19RFq1Xke4NkVY46x8KjJQjldHUuEbCqMvp1F5Iq9HgnGpu91jOi/Ufazhty32eRsKnnzS8n4c+L93g==", - "license": "Apache-2.0", - "dependencies": { - "discord-api-types": "0.37.97" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/discordjs/discord.js?sponsor" - } - }, - "node_modules/@discordjs/node-pre-gyp": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@discordjs/node-pre-gyp/-/node-pre-gyp-0.4.5.tgz", - "integrity": "sha512-YJOVVZ545x24mHzANfYoy0BJX5PDyeZlpiJjDkUBM/V/Ao7TFX9lcUvCN4nr0tbr5ubeaXxtEBILUrHtTphVeQ==", - "license": "BSD-3-Clause", - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@discordjs/opus": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@discordjs/opus/-/opus-0.9.0.tgz", - "integrity": "sha512-NEE76A96FtQ5YuoAVlOlB3ryMPrkXbUCTQICHGKb8ShtjXyubGicjRMouHtP1RpuDdm16cDa+oI3aAMo1zQRUQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@discordjs/node-pre-gyp": "^0.4.5", - "node-addon-api": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@discordjs/rest": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.4.0.tgz", - "integrity": "sha512-Xb2irDqNcq+O8F0/k/NaDp7+t091p+acb51iA4bCKfIn+WFWd6HrNvcsSbMMxIR9NjcMZS6NReTKygqiQN+ntw==", - "license": "Apache-2.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.6.3", - "undici": "6.19.8" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/discordjs/discord.js?sponsor" - } - }, - "node_modules/@discordjs/rest/node_modules/@discordjs/collection": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", - "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", - "license": "Apache-2.0", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/discordjs/discord.js?sponsor" - } - }, - "node_modules/@discordjs/util": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.1.1.tgz", - "integrity": "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==", - "license": "Apache-2.0", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/discordjs/discord.js?sponsor" - } - }, - "node_modules/@discordjs/voice": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.17.0.tgz", - "integrity": "sha512-hArn9FF5ZYi1IkxdJEVnJi+OxlwLV0NJYWpKXsmNOojtGtAZHxmsELA+MZlu2KW1F/K1/nt7lFOfcMXNYweq9w==", - "license": "Apache-2.0", - "dependencies": { - "@types/ws": "^8.5.10", - "discord-api-types": "0.37.83", - "prism-media": "^1.3.5", - "tslib": "^2.6.2", - "ws": "^8.16.0" - }, - "engines": { - "node": ">=16.11.0" - }, - "funding": { - "url": "https://github.com/discordjs/discord.js?sponsor" - } - }, - "node_modules/@discordjs/voice/node_modules/discord-api-types": { - "version": "0.37.83", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.83.tgz", - "integrity": "sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==", - "license": "MIT" - }, - "node_modules/@discordjs/voice/node_modules/opusscript": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.8.tgz", - "integrity": "sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/@discordjs/voice/node_modules/prism-media": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.3.5.tgz", - "integrity": "sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==", - "license": "Apache-2.0", - "peerDependencies": { - "@discordjs/opus": ">=0.8.0 <1.0.0", - "ffmpeg-static": "^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0", - "node-opus": "^0.3.3", - "opusscript": "^0.0.8" - }, - "peerDependenciesMeta": { - "@discordjs/opus": { - "optional": true - }, - "ffmpeg-static": { - "optional": true - }, - "node-opus": { - "optional": true - }, - "opusscript": { - "optional": true - } - } - }, - "node_modules/@discordjs/ws": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.1.1.tgz", - "integrity": "sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==", - "license": "Apache-2.0", - "dependencies": { - "@discordjs/collection": "^2.1.0", - "@discordjs/rest": "^2.3.0", - "@discordjs/util": "^1.1.0", - "@sapphire/async-queue": "^1.5.2", - "@types/ws": "^8.5.10", - "@vladfrangu/async_event_emitter": "^2.2.4", - "discord-api-types": "0.37.83", - "tslib": "^2.6.2", - "ws": "^8.16.0" - }, - "engines": { - "node": ">=16.11.0" - }, - "funding": { - "url": "https://github.com/discordjs/discord.js?sponsor" - } - }, - "node_modules/@discordjs/ws/node_modules/@discordjs/collection": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", - "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", - "license": "Apache-2.0", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/discordjs/discord.js?sponsor" - } - }, - "node_modules/@discordjs/ws/node_modules/discord-api-types": { - "version": "0.37.83", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.83.tgz", - "integrity": "sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==", - "license": "MIT" - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@mongodb-js/saslprep": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", - "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", - "license": "MIT", - "dependencies": { - "sparse-bitfield": "^3.0.3" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@sapphire/async-queue": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.4.tgz", - "integrity": "sha512-id65RxAx34DCk8KAVTPWwcephJSkStiS9M15F87+zvK2gK47wf7yeRIo8WiuKeXQS6bsyo/uQ/t0QW1cLmSb+A==", - "license": "MIT", - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@sapphire/shapeshift": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-4.0.0.tgz", - "integrity": "sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "lodash": "^4.17.21" - }, - "engines": { - "node": ">=v16" - } - }, - "node_modules/@sapphire/snowflake": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz", - "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==", - "license": "MIT", - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/jsonfile": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", - "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/lodash": { - "version": "4.14.197", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.197.tgz", - "integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", - "license": "MIT" - }, - "node_modules/@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, - "node_modules/@types/roll": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/roll/-/roll-1.2.3.tgz", - "integrity": "sha512-Ywq1nj1C0d//W9BEGqgZVAaK+HQ6fIweM+5adsY9PsxeVSOmwDrS1c/YzePX1C+UJ9fC7gOFLTkfGyJ/aJaZYA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/triple-beam": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", - "license": "MIT" - }, - "node_modules/@types/voca": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@types/voca/-/voca-1.4.6.tgz", - "integrity": "sha512-ubfCfFxlTOhBBUP2v8lzD8AQVKKu9erZ2t9/8hLpuYHYib3CM/lOwTII3mi527j5UeRDaVjIiAx+iTIWgVCWKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/webidl-conversions": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", - "license": "MIT" - }, - "node_modules/@types/whatwg-url": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", - "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", - "license": "MIT", - "dependencies": { - "@types/webidl-conversions": "*" - } - }, - "node_modules/@types/ws": { - "version": "8.5.13", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", - "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yt-search": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yt-search/-/yt-search-2.10.3.tgz", - "integrity": "sha512-kH4Yzs/edH9/s/Wj58WhV73qpiRedWeNy5V202BqpXPd+xUFM8M3ASLdUMYUbzzlUDoGorDm4JpeN6iNx3sOjw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/type-utils": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@vladfrangu/async_event_emitter": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.6.tgz", - "integrity": "sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==", - "license": "MIT", - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "license": "ISC" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-escapes": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", - "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^1.0.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "license": "ISC" - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "license": "MIT" - }, - "node_modules/async.parallellimit": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.parallellimit/-/async.parallellimit-0.5.2.tgz", - "integrity": "sha512-4Di2nFsb3jL7aUIICvRSvtw/oynpMIx0JrwYn5hqJI661Dd+mYBi2ElOukOQgRHihU1SCTapb86Vx/Snva5M1w==", - "license": "MIT", - "dependencies": { - "async.util.eachoflimit": "0.5.2", - "async.util.parallel": "0.5.2" - } - }, - "node_modules/async.util.eachoflimit": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.eachoflimit/-/async.util.eachoflimit-0.5.2.tgz", - "integrity": "sha512-oZksH0sBW0AEOJKgBCQ79io9DZruoRBLTAea/Ik36pejR7pDpByvtXeuJsoZdPwSVslsrQcsUfucbUaiXYBnAQ==", - "license": "MIT", - "dependencies": { - "async.util.keyiterator": "0.5.2", - "async.util.noop": "0.5.2", - "async.util.once": "0.5.2", - "async.util.onlyonce": "0.5.2" - } - }, - "node_modules/async.util.isarray": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz", - "integrity": "sha512-wbUzlrwON8RUgi+v/rhF0U99Ce8Osjcn+JP/mFNg6ymvShcobAOvE6cvLajSY5dPqKCOE1xfdhefgBif11zZgw==", - "license": "MIT" - }, - "node_modules/async.util.isarraylike": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.isarraylike/-/async.util.isarraylike-0.5.2.tgz", - "integrity": "sha512-DbFpsz3ZFNkohAW8IpGTlm8gotU32zpqe3Y2XkEA/G3XNO6rmUTKPpo7XgXUruoI+AsGi8+0zWpJHe7t1sLiAg==", - "license": "MIT", - "dependencies": { - "async.util.isarray": "0.5.2" - } - }, - "node_modules/async.util.keyiterator": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.keyiterator/-/async.util.keyiterator-0.5.2.tgz", - "integrity": "sha512-cktrETawCwgu13y3KZs2uMGFnNHc+IjKPZsavtRaoCjLELkePb2co4zrr+ghPvEqLXZIJPTKqC2HFZgJTssMVw==", - "license": "MIT", - "dependencies": { - "async.util.isarraylike": "0.5.2", - "async.util.keys": "0.5.2" - } - }, - "node_modules/async.util.keys": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.keys/-/async.util.keys-0.5.2.tgz", - "integrity": "sha512-umCOCRCRYwIC2Ho3fbuhKwIIe7OhQsVoVKGoF5GoQiGJUmjP4TG0Bmmcdpm7yW/znoIGKpnjKzVQz0niH4tfqw==", - "license": "MIT" - }, - "node_modules/async.util.noop": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz", - "integrity": "sha512-AdwShXwE0KoskgqVJAck8zcM32nIHj3AC8ZN62ZaR5srhrY235Nw18vOJZWxcOfhxdVM0hRVKM8kMx7lcl7cCQ==", - "license": "MIT" - }, - "node_modules/async.util.once": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.once/-/async.util.once-0.5.2.tgz", - "integrity": "sha512-YQ5WPzDTt2jlblUDkq2I5RV/KiAJErJ4/0cEFhYPaZzqIuF/xDzdGvnEKe7UeuoMszsVPeajzcpKgkbwdb9MUA==", - "license": "MIT" - }, - "node_modules/async.util.onlyonce": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz", - "integrity": "sha512-UgQvkU9JZ+I0Cm1f56XyGXcII+J3d/5XWUuHpcevlItuA3WFSJcqZrsyAUck2FkRSD8BwYQX1zUTDp3SJMVESg==", - "license": "MIT" - }, - "node_modules/async.util.parallel": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.parallel/-/async.util.parallel-0.5.2.tgz", - "integrity": "sha512-0bEvwmQ8fxsTYNwacw5iq0i3PvGryRkXxZ01Rvox21izdMdls9IH2rAZjfunbgI8j6nFRyIdCmMINQ9kka99ow==", - "license": "MIT", - "dependencies": { - "async.util.isarraylike": "0.5.2", - "async.util.noop": "0.5.2", - "async.util.restparam": "0.5.2" - } - }, - "node_modules/async.util.restparam": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.restparam/-/async.util.restparam-0.5.2.tgz", - "integrity": "sha512-Q9Z+zgmtMxFX5i7CnBvNOkgrL5hptztCqwarQluyNudUUk4iCmyjmsQl8MuQEjNh3gGqP5ayvDaextL1VXXgIg==", - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/boolstring": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/boolstring/-/boolstring-1.0.2.tgz", - "integrity": "sha512-0JLNSmZUv1m/O8sVayFm2t0naiOXwQ9O2Gq9u1eoIkhvu6U5NQER/e3k4BGpjZ33G775lWMT7TzJ7r5VtmEnbQ==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/bson": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz", - "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==", - "license": "Apache-2.0", - "engines": { - "node": ">=16.20.1" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "license": "Apache-2.0" - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/cli-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-1.2.0.tgz", - "integrity": "sha512-AqfwItf/UqGif3FBErI3NHX04v5ywJtGYlL5z4OqWR50u7g+Fz3Xw2qcCIbKVPrqtJCBwSOkDgnSlHbcpwDKHw==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.1.1", - "d": "1", - "es5-ext": "^0.10.12", - "es6-iterator": "2", - "memoizee": "^0.4.3", - "timers-ext": "0.1" - } - }, - "node_modules/cli-color/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "license": "MIT", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "license": "MIT", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", - "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "engines": [ - "node >= 6.0" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "license": "ISC" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", - "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/d": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", - "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", - "license": "ISC", - "dependencies": { - "es5-ext": "^0.10.64", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/dasu": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/dasu/-/dasu-0.4.3.tgz", - "integrity": "sha512-AFwspl5k7V8MW8H7tyIGJ0gtOauUg7JC+DgiRFUIXvPNNDFXTMtvnCkZY0macN6JLGqBjNP38WVnQN7Iv3RSlg==", - "license": "MIT" - }, - "node_modules/dayjs": { - "version": "1.11.13", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", - "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "license": "MIT" - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "license": "MIT" - }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/discord-api-types": { - "version": "0.37.97", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.97.tgz", - "integrity": "sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA==", - "license": "MIT" - }, - "node_modules/discord-ytdl-core": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/discord-ytdl-core/-/discord-ytdl-core-5.0.4.tgz", - "integrity": "sha512-O+G9wuCw5TERR9iHZFMYnYQbs/ZGudDc9cxa1OKSV5TdcBYrHGS1JqvE90ZvSQ6SmS4XvqtOf/Okls6yiGJ3sg==", - "license": "ISC", - "dependencies": { - "prism-media": "^1.2.9" - }, - "funding": { - "type": "individual", - "url": "https://paypal.me/devsnowflake" - } - }, - "node_modules/discord-ytdl-core/node_modules/opusscript": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.8.tgz", - "integrity": "sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/discord-ytdl-core/node_modules/prism-media": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.3.5.tgz", - "integrity": "sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==", - "license": "Apache-2.0", - "peerDependencies": { - "@discordjs/opus": ">=0.8.0 <1.0.0", - "ffmpeg-static": "^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0", - "node-opus": "^0.3.3", - "opusscript": "^0.0.8" - }, - "peerDependenciesMeta": { - "@discordjs/opus": { - "optional": true - }, - "ffmpeg-static": { - "optional": true - }, - "node-opus": { - "optional": true - }, - "opusscript": { - "optional": true - } - } - }, - "node_modules/discord.js": { - "version": "14.16.3", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.16.3.tgz", - "integrity": "sha512-EPCWE9OkA9DnFFNrO7Kl1WHHDYFXu3CNVFJg63bfU7hVtjZGyhShwZtSBImINQRWxWP2tgo2XI+QhdXx28r0aA==", - "license": "Apache-2.0", - "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.6.3", - "undici": "6.19.8" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/discordjs/discord.js?sponsor" - } - }, - "node_modules/discord.js/node_modules/discord-api-types": { - "version": "0.37.100", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.100.tgz", - "integrity": "sha512-a8zvUI0GYYwDtScfRd/TtaNBDTXwP5DiDVX7K5OmE+DRT57gBqKnwtOC5Ol8z0mRW8KQfETIgiB8U0YZ9NXiCA==", - "license": "MIT" - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", - "license": "MIT" - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/es5-ext": { - "version": "0.10.64", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", - "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", - "hasInstallScript": true, - "license": "ISC", - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "esniff": "^2.0.1", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "license": "MIT", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", - "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", - "license": "ISC", - "dependencies": { - "d": "^1.0.2", - "ext": "^1.7.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "license": "ISC", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.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.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", - "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/esniff": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", - "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", - "license": "ISC", - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.62", - "event-emitter": "^0.3.5", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "license": "MIT", - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true, - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "license": "ISC", - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", - "license": "MIT" - }, - "node_modules/ffmpeg-static": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-5.2.0.tgz", - "integrity": "sha512-WrM7kLW+do9HLr+H6tk7LzQ7kPqbAgLjdzNE32+u3Ff11gXt9Kkkd2nusGFrlWMIe+XaA97t+I8JS7sZIrvRgA==", - "hasInstallScript": true, - "license": "GPL-3.0-or-later", - "dependencies": { - "@derhuerst/http-basic": "^8.2.0", - "env-paths": "^2.2.0", - "https-proxy-agent": "^5.0.0", - "progress": "^2.0.3" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", - "license": "MIT" - }, - "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gauge/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC", - "optional": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "license": "ISC" - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "license": "MIT", - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/http-response-object/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "license": "MIT" - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/human-time": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/human-time/-/human-time-0.0.2.tgz", - "integrity": "sha512-sbYI90YhYmstslPTb70BLGjy6mdESa0lxL7uDR4fIVAx9Iobz8fLEqi7FqF4Q/6vblrzZALg//MsYJlIPBU8SA==", - "license": "MIT" - }, - "node_modules/husky": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", - "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", - "dev": true, - "license": "MIT", - "bin": { - "husky": "lib/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true, - "license": "ISC" - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "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.", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "license": "MIT" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "license": "MIT" - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonpath-plus": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-5.0.7.tgz", - "integrity": "sha512-7TS6wsiw1s2UMK/A6nA4n0aUJuirCVhJ87nWX5je5MPOl0z5VTr2qs7nMP8NZ2ed3rlt6kePTqddgVPE9F0i0w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/kareem": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", - "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/keypress": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", - "integrity": "sha512-HjorDJFNhnM4SicvaUXac0X77NiskggxJdesG72+O5zBKpSqKFCrqmndKVqpu3pFqkla0St6uGk8Ju0sCurrmg==", - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", - "license": "MIT" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/libsodium": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.15.tgz", - "integrity": "sha512-sZwRknt/tUpE2AwzHq3jEyUU5uvIZHtSssktXq7owd++3CSgn8RGrv6UZJJBpP7+iBghBqe7Z06/2M31rI2NKw==", - "license": "ISC" - }, - "node_modules/libsodium-wrappers": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.15.tgz", - "integrity": "sha512-E4anqJQwcfiC6+Yrl01C1m8p99wEhLmJSs0VQqST66SbQXXBoaJY0pF4BNjRYa/sOQAxx6lXAaAFIlx+15tXJQ==", - "license": "ISC", - "dependencies": { - "libsodium": "^0.7.15" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/lint-staged": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-14.0.1.tgz", - "integrity": "sha512-Mw0cL6HXnHN1ag0mN/Dg4g6sr8uf8sn98w2Oc1ECtFto9tvRF7nkXGJRbx8gPlHyoR0pLyBr2lQHbWwmUHe1Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "5.3.0", - "commander": "11.0.0", - "debug": "4.3.4", - "execa": "7.2.0", - "lilconfig": "2.1.0", - "listr2": "6.6.1", - "micromatch": "4.0.5", - "pidtree": "0.6.0", - "string-argv": "0.3.2", - "yaml": "2.3.1" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" - } - }, - "node_modules/lint-staged/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/lint-staged/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/lint-staged/node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/lint-staged/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/listr2": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-6.6.1.tgz", - "integrity": "sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^5.0.1", - "rfdc": "^1.3.0", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", - "license": "MIT" - }, - "node_modules/log-update": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", - "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^5.0.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^5.0.0", - "strip-ansi": "^7.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/log-update/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/logform": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz", - "integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==", - "license": "MIT", - "dependencies": { - "@colors/colors": "1.6.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "license": "MIT", - "dependencies": { - "es5-ext": "~0.10.2" - } - }, - "node_modules/m3u8stream": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.8.6.tgz", - "integrity": "sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==", - "license": "MIT", - "dependencies": { - "miniget": "^4.2.2", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/magic-bytes.js": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz", - "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==", - "license": "MIT" - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/memoizee": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", - "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", - "license": "ISC", - "dependencies": { - "d": "^1.0.2", - "es5-ext": "^0.10.64", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/memory-pager": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "license": "MIT" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/miniget": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/miniget/-/miniget-4.2.3.tgz", - "integrity": "sha512-SjbDPDICJ1zT+ZvQwK0hUcRY4wxlhhNpHL9nJOB2MEAXRGagTljsO8MEDzQMTFf0Q8g4QNi8P9lEm/g7e+qgzA==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mongodb": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz", - "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==", - "license": "Apache-2.0", - "dependencies": { - "@mongodb-js/saslprep": "^1.1.5", - "bson": "^6.7.0", - "mongodb-connection-string-url": "^3.0.0" - }, - "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 - } - } - }, - "node_modules/mongodb-connection-string-url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", - "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", - "license": "Apache-2.0", - "dependencies": { - "@types/whatwg-url": "^11.0.2", - "whatwg-url": "^13.0.0" - } - }, - "node_modules/mongoose": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.0.tgz", - "integrity": "sha512-KluvgwnQB1GPOYZZXUHJRjS1TW6xxwTlf/YgjWExuuNanIe3W7VcR7dDXQVCIRk8L7NYge8EnoTcu2grWtN+XQ==", - "license": "MIT", - "dependencies": { - "bson": "^6.7.0", - "kareem": "2.6.3", - "mongodb": "~6.10.0", - "mpath": "0.9.0", - "mquery": "5.0.0", - "ms": "2.1.3", - "sift": "17.1.3" - }, - "engines": { - "node": ">=16.20.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mongoose" - } - }, - "node_modules/mpath": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", - "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mquery": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", - "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", - "license": "MIT", - "dependencies": { - "debug": "4.x" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "license": "ISC" - }, - "node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "license": "MIT" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/node-fzf": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/node-fzf/-/node-fzf-0.5.3.tgz", - "integrity": "sha512-crN8rRfApu/GUrtKq+zJ6LueUyNAOJpFHxoT2Ru1Q+OYRa/F/H7CXvzcMrFc7D964yakYZEZ9XR3YbdSHXgyCw==", - "license": "MIT", - "dependencies": { - "cli-color": "~1.2.0", - "keypress": "~0.2.1", - "minimist": "~1.2.0", - "redstar": "0.0.2", - "string-width": "~2.1.1", - "ttys": "0.0.3" - }, - "bin": { - "nfzf": "bin/cli.js" - } - }, - "node_modules/node-fzf/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/node-fzf/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/node-fzf/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "license": "MIT", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/node-fzf/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", - "integrity": "sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^4", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "license": "MIT", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/opusscript": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.1.1.tgz", - "integrity": "sha512-mL0fZZOUnXdZ78woRXp18lApwpp0lF5tozJOD1Wut0dgrA9WuQTgSels/CSmFleaAZrJi/nci5KOVtbuxeWoQA==", - "license": "MIT" - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" - }, - "node_modules/parse5": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", - "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", - "license": "MIT", - "dependencies": { - "entities": "^4.5.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.3", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pidtree": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", - "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", - "dev": true, - "license": "MIT", - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/prettier-plugin-organize-imports": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz", - "integrity": "sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@volar/vue-language-plugin-pug": "^1.0.4", - "@volar/vue-typescript": "^1.0.4", - "prettier": ">=2.0", - "typescript": ">=2.9" - }, - "peerDependenciesMeta": { - "@volar/vue-language-plugin-pug": { - "optional": true - }, - "@volar/vue-typescript": { - "optional": true - } - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true, - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/redstar": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/redstar/-/redstar-0.0.2.tgz", - "integrity": "sha512-VNvLaLxMJMYiAasJX5Q/GC+Os7FXL0yPWFDuTodhR7Na9wqzrXsePPWC+EtIv4t3q5DyAK00w423xi5mQN2fqg==", - "license": "MIT", - "dependencies": { - "minimatch": "~3.0.4" - } - }, - "node_modules/redstar/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/redstar/node_modules/minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/roll": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/roll/-/roll-1.3.2.tgz", - "integrity": "sha512-93C3mjFTbnVuS79sdcRYqj4+AVidLwnwMMqeX16E8umZ3kTunnW9knrctHy8YcWvFFppvzs2SlMjevzg6tctYg==", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.8" - }, - "bin": { - "roll": "bin/roll" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safe-stable-stringify": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "license": "ISC" - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "license": "ISC" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/sift": { - "version": "17.1.3", - "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", - "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", - "license": "MIT" - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "license": "MIT", - "dependencies": { - "memory-pager": "^1.0.2" - } - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/synckit": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", - "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", - "license": "MIT" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/timers-ext": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", - "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", - "license": "ISC", - "dependencies": { - "es5-ext": "^0.10.64", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/touch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", - "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", - "dev": true, - "license": "ISC", - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", - "license": "MIT", - "dependencies": { - "punycode": "^2.3.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/triple-beam": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/ts-api-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", - "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-mixer": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", - "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", - "license": "MIT" - }, - "node_modules/tsconfig-paths": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/ttys": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/ttys/-/ttys-0.0.3.tgz", - "integrity": "sha512-UCqXRZS2S7U4aVB7Salj3ChPRSsb57ogJpJ1eMCvyowxFOBGsaHKcRU8bovcDwajX1mRbv0IpUnYkoG7Ieo5Zg==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/type": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", - "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", - "license": "ISC" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "license": "MIT" - }, - "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true, - "license": "MIT" - }, - "node_modules/undici": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", - "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/voca": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/voca/-/voca-1.4.1.tgz", - "integrity": "sha512-NJC/BzESaHT1p4B5k4JykxedeltmNbau4cummStd4RjFojgq/kLew5TzYge9N2geeWyI2w8T30wUET5v+F7ZHA==", - "license": "MIT" - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-url": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", - "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", - "license": "MIT", - "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wide-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/winston": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.16.0.tgz", - "integrity": "sha512-xz7+cyGN5M+4CmmD4Npq1/4T+UZaz7HaeTlAruFUTjk79CNMq+P6H30vlE4z0qfqJ01VHYQwd7OZo03nYm/+lg==", - "license": "MIT", - "dependencies": { - "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", - "async": "^3.2.3", - "is-stream": "^2.0.0", - "logform": "^2.6.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "safe-stable-stringify": "^2.3.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-transport": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.8.0.tgz", - "integrity": "sha512-qxSTKswC6llEMZKgCQdaWgDuMJQnhuvF5f2Nk3SNXc4byfQ+voo2mX1Px9dkNOuR8p0KAjfPG29PuYUSIb+vSA==", - "license": "MIT", - "dependencies": { - "logform": "^2.6.1", - "readable-stream": "^4.5.2", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/winston-transport/node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/winston/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "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 - } - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/yaml": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", - "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 14" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yt-search": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/yt-search/-/yt-search-2.12.1.tgz", - "integrity": "sha512-suEbEGqIDa7OBuZQSNabPKS4sZrHrocak7JhxSw3gagCUxPgHqyEDqyWEruvLYax2uCIQ7UhQoDVqQGOFn+jrQ==", - "license": "MIT", - "dependencies": { - "async.parallellimit": "~0.5.2", - "boolstring": "~1.0.2", - "cheerio": "^1.0.0-rc.10", - "dasu": "~0.4.3", - "human-time": "0.0.2", - "jsonpath-plus": "~5.0.2", - "minimist": "~1.2.5", - "node-fzf": "~0.5.1" - }, - "bin": { - "yt-search": "bin/cli.js", - "yt-search-audio": "bin/mpv_audio.sh", - "yt-search-video": "bin/mpv_video.sh" - } - }, - "node_modules/ytdl-core": { - "version": "4.11.5", - "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.11.5.tgz", - "integrity": "sha512-27LwsW4n4nyNviRCO1hmr8Wr5J1wLLMawHCQvH8Fk0hiRqrxuIu028WzbJetiYH28K8XDbeinYW4/wcHQD1EXA==", - "license": "MIT", - "dependencies": { - "m3u8stream": "^0.8.6", - "miniget": "^4.2.2", - "sax": "^1.1.3" - }, - "engines": { - "node": ">=12" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 96bb2dc0..00000000 --- a/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "portal", - "author": "Ioannis Tsiakkas", - "version": "0.7.0", - "type": "module", - "private": true, - "main": "src/app.ts", - "scripts": { - "build": "npx tsc", - "start": "node build/app.js", - "build-start": "npx tsc && node build/app.js", - "lint": "eslint --ext .ts .", - "lint-fix": "npm run lint -- --fix", - "dev": "tsc --watch" - }, - "husky": { - "hooks": { - "pre-push": "npm run lint" - } - }, - "dependencies": { - "@discordjs/builders": "^1.9.0", - "@discordjs/opus": "0.9.0", - "@discordjs/voice": "0.17.0", - "@types/jsonfile": "6.1.4", - "cheerio": "1.0.0-rc.12", - "core-util-is": "1.0.3", - "dayjs": "1.11.13", - "discord-ytdl-core": "5.0.4", - "discord.js": "14.16.3", - "dotenv": "16.4.5", - "ffmpeg-static": "5.2.0", - "jsonfile": "6.1.0", - "libsodium-wrappers": "^0.7.15", - "lodash": "4.17.21", - "mongoose": "8.8.0", - "optionator": "0.9.4", - "opusscript": "0.1.1", - "roll": "1.3.2", - "voca": "1.4.1", - "winston": "3.16.0", - "yt-search": "2.12.1", - "ytdl-core": "4.11.5" - }, - "devDependencies": { - "@types/lodash": "4.14.197", - "@types/node": "20.5.7", - "@types/node-fetch": "2.6.11", - "@types/roll": "1.2.3", - "@types/voca": "1.4.6", - "@types/ws": "8.5.13", - "@types/yt-search": "2.10.3", - "@typescript-eslint/eslint-plugin": "^6.21.0", - "@typescript-eslint/parser": "^6.21.0", - "eslint": "^8.57.1", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "5.2.1", - "husky": "8.0.3", - "lint-staged": "14.0.1", - "nodemon": "3.1.7", - "prettier-plugin-organize-imports": "^3.0.0", - "tsconfig-paths": "^4.2.0", - "typescript": "5.6.3" - }, - "optionalDependencies": { - "fsevents": "2.3.3" - } -} diff --git a/src/Interpreter/attribute.functions.ts b/src/Interpreter/attribute.functions.ts index 01b9b1a2..ef0afbf7 100644 --- a/src/Interpreter/attribute.functions.ts +++ b/src/Interpreter/attribute.functions.ts @@ -1,23 +1,32 @@ -import { ChatInputCommandInteraction, Guild, GuildMember, Role, VoiceChannel } from 'discord.js'; - -import { AttributeBlueprints } from '../blueprints/attribute.blueprint.js'; -import { isUserAuthorised } from '../libraries/help.library.js'; -import { PGuild } from '../types/classes/PGuild.class.js'; -import { PChannel } from '../types/classes/PPortalChannel.class.js'; -import { ReturnPromise } from '../types/classes/PTypes.interface.js'; -import { PVoiceChannel } from '../types/classes/PVoiceChannel.class.js'; -import { AuthType } from '../types/enums/Admin.enum.js'; +import type { + ChatInputCommandInteraction, + Guild, + GuildMember, + Role, + VoiceChannel, +} from "npm:discord.js"; + +import { AttributeBlueprints } from "../blueprints/attribute.blueprint.ts"; +import { isUserAuthorised } from "../libraries/help.library.ts"; +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import type { PChannel } from "../types/classes/PPortalChannel.class.ts"; +import type { ReturnPromise } from "../types/classes/PTypes.interface.ts"; +import type { PVoiceChannel } from "../types/classes/PVoiceChannel.class.ts"; +import { AuthType } from "../types/enums/Admin.enum.ts"; export function isAttribute(candidate: string): string { for (let i = 0; i < AttributeBlueprints.length; i++) { - const subStr = String(candidate).substring(1, String(AttributeBlueprints[i].name).length + 1); + const subStr = String(candidate).substring( + 1, + String(AttributeBlueprints[i].name).length + 1, + ); if (subStr == AttributeBlueprints[i].name) { return AttributeBlueprints[i].name; } } - return ''; + return ""; } export function getAttribute( @@ -57,61 +66,70 @@ export async function setAttribute( for (let l = 0; l < AttributeBlueprints.length; l++) { if (candidate === AttributeBlueprints[l].name) { switch (AttributeBlueprints[l].auth) { - case AuthType.admin: - if (!isUserAuthorised(member)) { - return { - result: false, - value: `attribute ${candidate} can only be **set by an administrator**`, - }; - } - - break; - case AuthType.none: - // passes through no checks needed - break; - default: - if (!voiceChannel) { - return { - result: false, - value: 'you must be in a channel handled by Portal', - }; - } - - for (let i = 0; i < pGuild.pChannels.length; i++) { - for (let j = 0; j < pGuild.pChannels[i].pVoiceChannels.length; j++) { - if (pGuild.pChannels[i].pVoiceChannels[j].id === voiceChannel.id) { - pChannel = pGuild.pChannels[i]; - pVoiceChannel = pGuild.pChannels[i].pVoiceChannels[j]; - - break; - } + case AuthType.ADMIN: + if (!isUserAuthorised(member)) { + return { + result: false, + value: + `attribute ${candidate} can only be **set by an administrator**`, + }; } - } - - if (!pChannel || !pVoiceChannel) { - return { - result: false, - value: 'you must be in a channel handled by Portal', - }; - } - if (AttributeBlueprints[l].auth === AuthType.portal) { - if (pChannel.creatorId !== member.id) { + break; + case AuthType.NONE: + // passes through no checks needed + break; + default: + if (!voiceChannel) { return { result: false, - value: `attribute ${candidate} can only be **set by the portal creator**`, + value: "you must be in a channel handled by Portal", }; } - } else if (AttributeBlueprints[l].auth === AuthType.voice) { - if (pVoiceChannel.creatorId !== member.id) { + + for (let i = 0; i < pGuild.pChannels.length; i++) { + for ( + let j = 0; + j < pGuild.pChannels[i].pVoiceChannels.length; + j++ + ) { + if ( + pGuild.pChannels[i].pVoiceChannels[j].id === voiceChannel.id + ) { + pChannel = pGuild.pChannels[i]; + pVoiceChannel = pGuild.pChannels[i].pVoiceChannels[j]; + + break; + } + } + } + + if (!pChannel || !pVoiceChannel) { return { result: false, - value: `attribute ${candidate} can only be **set by the voice creator**`, + value: "you must be in a channel handled by Portal", }; } - } - break; + if (AttributeBlueprints[l].auth === AuthType.PORTAL) { + if (pChannel.creatorId !== member.id) { + return { + result: false, + value: + `attribute ${candidate} can only be **set by the portal creator**`, + }; + } + } else if (AttributeBlueprints[l].auth === AuthType.VOICE) { + if (pVoiceChannel.creatorId !== member.id) { + return { + result: false, + value: + `attribute ${candidate} can only be **set by the voice creator**`, + }; + } + } + + break; } const pMember = pGuild.pMembers.find((m) => m.id === member.id); @@ -144,6 +162,6 @@ export async function setAttribute( return { result: false, - value: 'fail', + value: "fail", }; } diff --git a/src/Interpreter/pipe.functions.ts b/src/Interpreter/pipe.functions.ts index 28a86fda..f1dfc1ea 100644 --- a/src/Interpreter/pipe.functions.ts +++ b/src/Interpreter/pipe.functions.ts @@ -1,18 +1,24 @@ -import { PipeBlueprints } from '../blueprints/pipe.blueprint.js'; +import { PipeBlueprints } from "../blueprints/pipe.blueprint.ts"; export function isPipe(candidate: string): string { for (let i = 0; i < PipeBlueprints.length; i++) { - const subString = String(candidate).substring(1, String(PipeBlueprints[i].name).length + 1); + const subString = String(candidate).substring( + 1, + String(PipeBlueprints[i].name).length + 1, + ); if (subString == PipeBlueprints[i].name) { return PipeBlueprints[i].name; } } - return ''; + return ""; } -export function getPipe(string: string | string[], pipe: string): string | number { +export function getPipe( + string: string | string[], + pipe: string, +): string | number { for (let l = 0; l < PipeBlueprints.length; l++) { if (pipe === PipeBlueprints[l].name) { return PipeBlueprints[l].get({ string }) as string | number; diff --git a/src/Interpreter/structure.functions.ts b/src/Interpreter/structure.functions.ts index b4b66997..13d23d1c 100644 --- a/src/Interpreter/structure.functions.ts +++ b/src/Interpreter/structure.functions.ts @@ -1,13 +1,16 @@ -import { StructureBlueprint } from '../blueprints/structure.blueprint.js'; +import { StructureBlueprint } from "../blueprints/structure.blueprint.ts"; export function isStructure(candidate: string): string { for (let i = 0; i < StructureBlueprint.length; i++) { - const subString = String(candidate).substring(1, String(StructureBlueprint[i].name).length + 1); + const subString = String(candidate).substring( + 1, + String(StructureBlueprint[i].name).length + 1, + ); if (subString == StructureBlueprint[i].name) { return StructureBlueprint[i].name; } } - return ''; + return ""; } diff --git a/src/Interpreter/variable.functions.ts b/src/Interpreter/variable.functions.ts index cfb5e387..6e310710 100644 --- a/src/Interpreter/variable.functions.ts +++ b/src/Interpreter/variable.functions.ts @@ -1,20 +1,23 @@ -import { VoiceChannel, Guild } from 'discord.js'; +import type { Guild, VoiceChannel } from "npm:discord.js"; -import { VariableBlueprints } from '../blueprints/variable.blueprint.js'; -import { PGuild } from '../types/classes/PGuild.class.js'; -import { PChannel } from '../types/classes/PPortalChannel.class.js'; -import { PVoiceChannel } from '../types/classes/PVoiceChannel.class.js'; +import { VariableBlueprints } from "../blueprints/variable.blueprint.ts"; +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import type { PChannel } from "../types/classes/PPortalChannel.class.ts"; +import type { PVoiceChannel } from "../types/classes/PVoiceChannel.class.ts"; export function isVariable(candidate: string): string { for (let i = 0; i < VariableBlueprints.length; i++) { - const subString = String(candidate).substring(1, String(VariableBlueprints[i].name).length + 1); + const subString = String(candidate).substring( + 1, + String(VariableBlueprints[i].name).length + 1, + ); if (subString === VariableBlueprints[i].name) { return VariableBlueprints[i].name; } } - return ''; + return ""; } export function getVariable( @@ -23,7 +26,7 @@ export function getVariable( pChannels: PChannel[], pGuild: PGuild, guild: Guild, - variable: string + variable: string, ) { let variableIndex = -1; for (let l = 0; l < VariableBlueprints.length; l++) { @@ -42,6 +45,6 @@ export function getVariable( pVoiceChannel, pChannels, pGuild, - guild + guild, }); } diff --git a/src/app.ts b/src/app.ts index 4e0efe39..aa8fe1c6 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,60 +1,81 @@ -import { REST } from '@discordjs/rest'; -import { Routes } from 'discord-api-types/v9'; -import dotenv from 'dotenv'; -import { transports } from 'winston'; - -import * as auth from './commands/auth/index.js'; -import * as noAuth from './commands/noAuth/index.js'; -import { clientHandler, connectToDiscord } from './handlers/discord.handler.js'; -import { eventHandler } from './handlers/event.handler.js'; -import { mongoHandler } from './handlers/mongo.handler.js'; -import { ActiveCooldowns } from './types/classes/PTypes.interface.js'; -import logger from './utilities/log.utility.js'; - -dotenv.config(); +import { REST } from "@discordjs/rest"; +import "@std/dotenv/load"; +import { Routes } from "discord-api-types/v9"; +import { transports } from "npm:winston"; + +import * as auth from "./commands/auth/index.ts"; +import * as noAuth from "./commands/noAuth/index.ts"; +import { clientHandler, connectToDiscord } from "./handlers/discord.handler.ts"; +import { eventHandler } from "./handlers/event.handler.ts"; +import { mongoHandler } from "./handlers/mongo.handler.ts"; +import type { ActiveCooldowns } from "./types/classes/PTypes.interface.ts"; +import logger from "./utilities/log.utility.ts"; (async () => { - if (process.env.LOG) { - logger.add(new transports.File({ filename: '/logs/portal-error.log.json', level: 'error' })); - logger.add(new transports.File({ filename: '/logs/portal-info.log.json', level: 'info', silent: true })); - logger.add(new transports.File({ filename: '/logs/portal-all.log.json', silent: true })); + const LOG = Deno.env.get("LOG") === "true"; + + if (LOG) { + logger.add( + new transports.File({ + filename: "/logs/portal-error.log.json", + level: "error", + }), + ); + logger.add( + new transports.File({ + filename: "/logs/portal-info.log.json", + level: "info", + silent: true, + }), + ); + logger.add( + new transports.File({ + filename: "/logs/portal-all.log.json", + silent: true, + }), + ); } - if (!process.env.TOKEN) { - logger.error('Discord token is not defined'); - process.exit(1); + const DISCORD_TOKEN = Deno.env.get("DISCORD_TOKEN"); + if (!DISCORD_TOKEN) { + logger.error("Discord token is not defined"); + Deno.exit(1); } - if (!process.env.MONGO_URL) { - logger.error('mongo url is not defined'); - process.exit(2); + const MONGO_URL = Deno.env.get("MONGO_URL"); + if (!MONGO_URL) { + logger.error("mongo url is not defined"); + Deno.exit(2); } - if (!process.env.CLIENT_ID) { - logger.error('Discord client id is not defined'); - process.exit(4); + const CLIENT_ID = Deno.env.get("CLIENT_ID"); + if (!CLIENT_ID) { + logger.error("Discord client id is not defined"); + Deno.exit(4); } try { - logger.info('started refreshing application slash commands'); - const rest = new REST({ version: '10' }).setToken(process.env.TOKEN); - await rest.put(Routes.applicationCommands(process.env.CLIENT_ID), { - body: [...Object.values(auth), ...Object.values(noAuth)].map((command) => command.slashCommand.toJSON()), + logger.info("started refreshing application slash commands"); + const rest = new REST({ version: "10" }).setToken(DISCORD_TOKEN); + await rest.put(Routes.applicationCommands(CLIENT_ID), { + body: [...Object.values(auth), ...Object.values(noAuth)].map((command) => + command.slashCommand.toJSON() + ), }); - logger.info('successfully reloaded application slash commands'); + logger.info("successfully reloaded application slash commands"); } catch (error) { logger.error(error); } - const mongo = await mongoHandler(process.env.MONGO_URL); + const mongo = await mongoHandler(MONGO_URL); if (!mongo) { - logger.error('failed to connect to database'); - process.exit(2); + logger.error("failed to connect to database"); + Deno.exit(2); } - logger.info('connected to database'); + logger.info("connected to database"); const active_cooldowns: ActiveCooldowns = { guild: [], member: [] }; // const spam_cache: SpamCache[] = []; @@ -62,12 +83,11 @@ dotenv.config(); const client = clientHandler(); await eventHandler(client, active_cooldowns); - const discord = await connectToDiscord(client, process.env.TOKEN); - + const discord = await connectToDiscord(client, DISCORD_TOKEN); if (!discord) { - logger.error('failed to connect to discord'); - process.exit(1); + logger.error("failed to connect to discord"); + Deno.exit(1); } - logger.info('portal bot is running'); + logger.info("Portal bot is running"); })(); diff --git a/src/assets/lists/countryCodesISO.static.ts b/src/assets/lists/countryCodesISO.static.ts index c25ea424..e36ef1e8 100644 --- a/src/assets/lists/countryCodesISO.static.ts +++ b/src/assets/lists/countryCodesISO.static.ts @@ -1,974 +1,974 @@ export const CountryCodes = [ { - name: 'Afghanistan', - code: 'AF', + name: "Afghanistan", + code: "AF", }, { - name: 'Åland Islands', - code: 'AX', + name: "Åland Islands", + code: "AX", }, { - name: 'Albania', - code: 'AL', + name: "Albania", + code: "AL", }, { - name: 'Algeria', - code: 'DZ', + name: "Algeria", + code: "DZ", }, { - name: 'American Samoa', - code: 'AS', + name: "American Samoa", + code: "AS", }, { - name: 'AndorrA', - code: 'AD', + name: "AndorrA", + code: "AD", }, { - name: 'Angola', - code: 'AO', + name: "Angola", + code: "AO", }, { - name: 'Anguilla', - code: 'AI', + name: "Anguilla", + code: "AI", }, { - name: 'Antarctica', - code: 'AQ', + name: "Antarctica", + code: "AQ", }, { - name: 'Antigua and Barbuda', - code: 'AG', + name: "Antigua and Barbuda", + code: "AG", }, { - name: 'Argentina', - code: 'AR', + name: "Argentina", + code: "AR", }, { - name: 'Armenia', - code: 'AM', + name: "Armenia", + code: "AM", }, { - name: 'Aruba', - code: 'AW', + name: "Aruba", + code: "AW", }, { - name: 'Australia', - code: 'AU', + name: "Australia", + code: "AU", }, { - name: 'Austria', - code: 'AT', + name: "Austria", + code: "AT", }, { - name: 'Azerbaijan', - code: 'AZ', + name: "Azerbaijan", + code: "AZ", }, { - name: 'Bahamas', - code: 'BS', + name: "Bahamas", + code: "BS", }, { - name: 'Bahrain', - code: 'BH', + name: "Bahrain", + code: "BH", }, { - name: 'Bangladesh', - code: 'BD', + name: "Bangladesh", + code: "BD", }, { - name: 'Barbados', - code: 'BB', + name: "Barbados", + code: "BB", }, { - name: 'Belarus', - code: 'BY', + name: "Belarus", + code: "BY", }, { - name: 'Belgium', - code: 'BE', + name: "Belgium", + code: "BE", }, { - name: 'Belize', - code: 'BZ', + name: "Belize", + code: "BZ", }, { - name: 'Benin', - code: 'BJ', + name: "Benin", + code: "BJ", }, { - name: 'Bermuda', - code: 'BM', + name: "Bermuda", + code: "BM", }, { - name: 'Bhutan', - code: 'BT', + name: "Bhutan", + code: "BT", }, { - name: 'Bolivia', - code: 'BO', + name: "Bolivia", + code: "BO", }, { - name: 'Bosnia and Herzegovina', - code: 'BA', + name: "Bosnia and Herzegovina", + code: "BA", }, { - name: 'Botswana', - code: 'BW', + name: "Botswana", + code: "BW", }, { - name: 'Bouvet Island', - code: 'BV', + name: "Bouvet Island", + code: "BV", }, { - name: 'Brazil', - code: 'BR', + name: "Brazil", + code: "BR", }, { - name: 'British Indian Ocean Territory', - code: 'IO', + name: "British Indian Ocean Territory", + code: "IO", }, { - name: 'Brunei Darussalam', - code: 'BN', + name: "Brunei Darussalam", + code: "BN", }, { - name: 'Bulgaria', - code: 'BG', + name: "Bulgaria", + code: "BG", }, { - name: 'Burkina Faso', - code: 'BF', + name: "Burkina Faso", + code: "BF", }, { - name: 'Burundi', - code: 'BI', + name: "Burundi", + code: "BI", }, { - name: 'Cambodia', - code: 'KH', + name: "Cambodia", + code: "KH", }, { - name: 'Cameroon', - code: 'CM', + name: "Cameroon", + code: "CM", }, { - name: 'Canada', - code: 'CA', + name: "Canada", + code: "CA", }, { - name: 'Cape Verde', - code: 'CV', + name: "Cape Verde", + code: "CV", }, { - name: 'Cayman Islands', - code: 'KY', + name: "Cayman Islands", + code: "KY", }, { - name: 'Central African Republic', - code: 'CF', + name: "Central African Republic", + code: "CF", }, { - name: 'Chad', - code: 'TD', + name: "Chad", + code: "TD", }, { - name: 'Chile', - code: 'CL', + name: "Chile", + code: "CL", }, { - name: 'China', - code: 'CN', + name: "China", + code: "CN", }, { - name: 'Christmas Island', - code: 'CX', + name: "Christmas Island", + code: "CX", }, { - name: 'Cocos (Keeling) Islands', - code: 'CC', + name: "Cocos (Keeling) Islands", + code: "CC", }, { - name: 'Colombia', - code: 'CO', + name: "Colombia", + code: "CO", }, { - name: 'Comoros', - code: 'KM', + name: "Comoros", + code: "KM", }, { - name: 'Congo', - code: 'CG', + name: "Congo", + code: "CG", }, { - name: 'Congo, The Democratic Republic of the', - code: 'CD', + name: "Congo, The Democratic Republic of the", + code: "CD", }, { - name: 'Cook Islands', - code: 'CK', + name: "Cook Islands", + code: "CK", }, { - name: 'Costa Rica', - code: 'CR', + name: "Costa Rica", + code: "CR", }, { name: 'Cote D"Ivoire', - code: 'CI', + code: "CI", }, { - name: 'Croatia', - code: 'HR', + name: "Croatia", + code: "HR", }, { - name: 'Cuba', - code: 'CU', + name: "Cuba", + code: "CU", }, { - name: 'Cyprus', - code: 'CY', + name: "Cyprus", + code: "CY", }, { - name: 'Czech Republic', - code: 'CZ', + name: "Czech Republic", + code: "CZ", }, { - name: 'Denmark', - code: 'DK', + name: "Denmark", + code: "DK", }, { - name: 'Djibouti', - code: 'DJ', + name: "Djibouti", + code: "DJ", }, { - name: 'Dominica', - code: 'DM', + name: "Dominica", + code: "DM", }, { - name: 'Dominican Republic', - code: 'DO', + name: "Dominican Republic", + code: "DO", }, { - name: 'Ecuador', - code: 'EC', + name: "Ecuador", + code: "EC", }, { - name: 'Egypt', - code: 'EG', + name: "Egypt", + code: "EG", }, { - name: 'El Salvador', - code: 'SV', + name: "El Salvador", + code: "SV", }, { - name: 'Equatorial Guinea', - code: 'GQ', + name: "Equatorial Guinea", + code: "GQ", }, { - name: 'Eritrea', - code: 'ER', + name: "Eritrea", + code: "ER", }, { - name: 'Estonia', - code: 'EE', + name: "Estonia", + code: "EE", }, { - name: 'Ethiopia', - code: 'ET', + name: "Ethiopia", + code: "ET", }, { - name: 'Falkland Islands (Malvinas)', - code: 'FK', + name: "Falkland Islands (Malvinas)", + code: "FK", }, { - name: 'Faroe Islands', - code: 'FO', + name: "Faroe Islands", + code: "FO", }, { - name: 'Fiji', - code: 'FJ', + name: "Fiji", + code: "FJ", }, { - name: 'Finland', - code: 'FI', + name: "Finland", + code: "FI", }, { - name: 'France', - code: 'FR', + name: "France", + code: "FR", }, { - name: 'French Guiana', - code: 'GF', + name: "French Guiana", + code: "GF", }, { - name: 'French Polynesia', - code: 'PF', + name: "French Polynesia", + code: "PF", }, { - name: 'French Southern Territories', - code: 'TF', + name: "French Southern Territories", + code: "TF", }, { - name: 'Gabon', - code: 'GA', + name: "Gabon", + code: "GA", }, { - name: 'Gambia', - code: 'GM', + name: "Gambia", + code: "GM", }, { - name: 'Georgia', - code: 'GE', + name: "Georgia", + code: "GE", }, { - name: 'Germany', - code: 'DE', + name: "Germany", + code: "DE", }, { - name: 'Ghana', - code: 'GH', + name: "Ghana", + code: "GH", }, { - name: 'Gibraltar', - code: 'GI', + name: "Gibraltar", + code: "GI", }, { - name: 'Greece', - code: 'GR', + name: "Greece", + code: "GR", }, { - name: 'Greenland', - code: 'GL', + name: "Greenland", + code: "GL", }, { - name: 'Grenada', - code: 'GD', + name: "Grenada", + code: "GD", }, { - name: 'Guadeloupe', - code: 'GP', + name: "Guadeloupe", + code: "GP", }, { - name: 'Guam', - code: 'GU', + name: "Guam", + code: "GU", }, { - name: 'Guatemala', - code: 'GT', + name: "Guatemala", + code: "GT", }, { - name: 'Guernsey', - code: 'GG', + name: "Guernsey", + code: "GG", }, { - name: 'Guinea', - code: 'GN', + name: "Guinea", + code: "GN", }, { - name: 'Guinea-Bissau', - code: 'GW', + name: "Guinea-Bissau", + code: "GW", }, { - name: 'Guyana', - code: 'GY', + name: "Guyana", + code: "GY", }, { - name: 'Haiti', - code: 'HT', + name: "Haiti", + code: "HT", }, { - name: 'Heard Island and Mcdonald Islands', - code: 'HM', + name: "Heard Island and Mcdonald Islands", + code: "HM", }, { - name: 'Holy See (Vatican City State)', - code: 'VA', + name: "Holy See (Vatican City State)", + code: "VA", }, { - name: 'Honduras', - code: 'HN', + name: "Honduras", + code: "HN", }, { - name: 'Hong Kong', - code: 'HK', + name: "Hong Kong", + code: "HK", }, { - name: 'Hungary', - code: 'HU', + name: "Hungary", + code: "HU", }, { - name: 'Iceland', - code: 'IS', + name: "Iceland", + code: "IS", }, { - name: 'India', - code: 'IN', + name: "India", + code: "IN", }, { - name: 'Indonesia', - code: 'ID', + name: "Indonesia", + code: "ID", }, { - name: 'Iran, Islamic Republic Of', - code: 'IR', + name: "Iran, Islamic Republic Of", + code: "IR", }, { - name: 'Iraq', - code: 'IQ', + name: "Iraq", + code: "IQ", }, { - name: 'Ireland', - code: 'IE', + name: "Ireland", + code: "IE", }, { - name: 'Isle of Man', - code: 'IM', + name: "Isle of Man", + code: "IM", }, { - name: 'Israel', - code: 'IL', + name: "Israel", + code: "IL", }, { - name: 'Italy', - code: 'IT', + name: "Italy", + code: "IT", }, { - name: 'Jamaica', - code: 'JM', + name: "Jamaica", + code: "JM", }, { - name: 'Japan', - code: 'JP', + name: "Japan", + code: "JP", }, { - name: 'Jersey', - code: 'JE', + name: "Jersey", + code: "JE", }, { - name: 'Jordan', - code: 'JO', + name: "Jordan", + code: "JO", }, { - name: 'Kazakhstan', - code: 'KZ', + name: "Kazakhstan", + code: "KZ", }, { - name: 'Kenya', - code: 'KE', + name: "Kenya", + code: "KE", }, { - name: 'Kiribati', - code: 'KI', + name: "Kiribati", + code: "KI", }, { name: 'Korea, Democratic People"S Republic of', - code: 'KP', + code: "KP", }, { - name: 'Korea, Republic of', - code: 'KR', + name: "Korea, Republic of", + code: "KR", }, { - name: 'Kuwait', - code: 'KW', + name: "Kuwait", + code: "KW", }, { - name: 'Kyrgyzstan', - code: 'KG', + name: "Kyrgyzstan", + code: "KG", }, { name: 'Lao People"S Democratic Republic', - code: 'LA', + code: "LA", }, { - name: 'Latvia', - code: 'LV', + name: "Latvia", + code: "LV", }, { - name: 'Lebanon', - code: 'LB', + name: "Lebanon", + code: "LB", }, { - name: 'Lesotho', - code: 'LS', + name: "Lesotho", + code: "LS", }, { - name: 'Liberia', - code: 'LR', + name: "Liberia", + code: "LR", }, { - name: 'Libyan Arab Jamahiriya', - code: 'LY', + name: "Libyan Arab Jamahiriya", + code: "LY", }, { - name: 'Liechtenstein', - code: 'LI', + name: "Liechtenstein", + code: "LI", }, { - name: 'Lithuania', - code: 'LT', + name: "Lithuania", + code: "LT", }, { - name: 'Luxembourg', - code: 'LU', + name: "Luxembourg", + code: "LU", }, { - name: 'Macao', - code: 'MO', + name: "Macao", + code: "MO", }, { - name: 'Macedonia, The Former Yugoslav Republic of', - code: 'MK', + name: "Macedonia, The Former Yugoslav Republic of", + code: "MK", }, { - name: 'Madagascar', - code: 'MG', + name: "Madagascar", + code: "MG", }, { - name: 'Malawi', - code: 'MW', + name: "Malawi", + code: "MW", }, { - name: 'Malaysia', - code: 'MY', + name: "Malaysia", + code: "MY", }, { - name: 'Maldives', - code: 'MV', + name: "Maldives", + code: "MV", }, { - name: 'Mali', - code: 'ML', + name: "Mali", + code: "ML", }, { - name: 'Malta', - code: 'MT', + name: "Malta", + code: "MT", }, { - name: 'Marshall Islands', - code: 'MH', + name: "Marshall Islands", + code: "MH", }, { - name: 'Martinique', - code: 'MQ', + name: "Martinique", + code: "MQ", }, { - name: 'Mauritania', - code: 'MR', + name: "Mauritania", + code: "MR", }, { - name: 'Mauritius', - code: 'MU', + name: "Mauritius", + code: "MU", }, { - name: 'Mayotte', - code: 'YT', + name: "Mayotte", + code: "YT", }, { - name: 'Mexico', - code: 'MX', + name: "Mexico", + code: "MX", }, { - name: 'Micronesia, Federated States of', - code: 'FM', + name: "Micronesia, Federated States of", + code: "FM", }, { - name: 'Moldova, Republic of', - code: 'MD', + name: "Moldova, Republic of", + code: "MD", }, { - name: 'Monaco', - code: 'MC', + name: "Monaco", + code: "MC", }, { - name: 'Mongolia', - code: 'MN', + name: "Mongolia", + code: "MN", }, { - name: 'Montserrat', - code: 'MS', + name: "Montserrat", + code: "MS", }, { - name: 'Morocco', - code: 'MA', + name: "Morocco", + code: "MA", }, { - name: 'Mozambique', - code: 'MZ', + name: "Mozambique", + code: "MZ", }, { - name: 'Myanmar', - code: 'MM', + name: "Myanmar", + code: "MM", }, { - name: 'Namibia', - code: 'NA', + name: "Namibia", + code: "NA", }, { - name: 'Nauru', - code: 'NR', + name: "Nauru", + code: "NR", }, { - name: 'Nepal', - code: 'NP', + name: "Nepal", + code: "NP", }, { - name: 'Netherlands', - code: 'NL', + name: "Netherlands", + code: "NL", }, { - name: 'Netherlands Antilles', - code: 'AN', + name: "Netherlands Antilles", + code: "AN", }, { - name: 'New Caledonia', - code: 'NC', + name: "New Caledonia", + code: "NC", }, { - name: 'New Zealand', - code: 'NZ', + name: "New Zealand", + code: "NZ", }, { - name: 'Nicaragua', - code: 'NI', + name: "Nicaragua", + code: "NI", }, { - name: 'Niger', - code: 'NE', + name: "Niger", + code: "NE", }, { - name: 'Nigeria', - code: 'NG', + name: "Nigeria", + code: "NG", }, { - name: 'Niue', - code: 'NU', + name: "Niue", + code: "NU", }, { - name: 'Norfolk Island', - code: 'NF', + name: "Norfolk Island", + code: "NF", }, { - name: 'Northern Mariana Islands', - code: 'MP', + name: "Northern Mariana Islands", + code: "MP", }, { - name: 'Norway', - code: 'NO', + name: "Norway", + code: "NO", }, { - name: 'Oman', - code: 'OM', + name: "Oman", + code: "OM", }, { - name: 'Pakistan', - code: 'PK', + name: "Pakistan", + code: "PK", }, { - name: 'Palau', - code: 'PW', + name: "Palau", + code: "PW", }, { - name: 'Palestinian Territory, Occupied', - code: 'PS', + name: "Palestinian Territory, Occupied", + code: "PS", }, { - name: 'Panama', - code: 'PA', + name: "Panama", + code: "PA", }, { - name: 'Papua New Guinea', - code: 'PG', + name: "Papua New Guinea", + code: "PG", }, { - name: 'Paraguay', - code: 'PY', + name: "Paraguay", + code: "PY", }, { - name: 'Peru', - code: 'PE', + name: "Peru", + code: "PE", }, { - name: 'Philippines', - code: 'PH', + name: "Philippines", + code: "PH", }, { - name: 'Pitcairn', - code: 'PN', + name: "Pitcairn", + code: "PN", }, { - name: 'Poland', - code: 'PL', + name: "Poland", + code: "PL", }, { - name: 'Portugal', - code: 'PT', + name: "Portugal", + code: "PT", }, { - name: 'Puerto Rico', - code: 'PR', + name: "Puerto Rico", + code: "PR", }, { - name: 'Qatar', - code: 'QA', + name: "Qatar", + code: "QA", }, { - name: 'Reunion', - code: 'RE', + name: "Reunion", + code: "RE", }, { - name: 'Romania', - code: 'RO', + name: "Romania", + code: "RO", }, { - name: 'Russian Federation', - code: 'RU', + name: "Russian Federation", + code: "RU", }, { - name: 'RWANDA', - code: 'RW', + name: "RWANDA", + code: "RW", }, { - name: 'Saint Helena', - code: 'SH', + name: "Saint Helena", + code: "SH", }, { - name: 'Saint Kitts and Nevis', - code: 'KN', + name: "Saint Kitts and Nevis", + code: "KN", }, { - name: 'Saint Lucia', - code: 'LC', + name: "Saint Lucia", + code: "LC", }, { - name: 'Saint Pierre and Miquelon', - code: 'PM', + name: "Saint Pierre and Miquelon", + code: "PM", }, { - name: 'Saint Vincent and the Grenadines', - code: 'VC', + name: "Saint Vincent and the Grenadines", + code: "VC", }, { - name: 'Samoa', - code: 'WS', + name: "Samoa", + code: "WS", }, { - name: 'San Marino', - code: 'SM', + name: "San Marino", + code: "SM", }, { - name: 'Sao Tome and Principe', - code: 'ST', + name: "Sao Tome and Principe", + code: "ST", }, { - name: 'Saudi Arabia', - code: 'SA', + name: "Saudi Arabia", + code: "SA", }, { - name: 'Senegal', - code: 'SN', + name: "Senegal", + code: "SN", }, { - name: 'Serbia and Montenegro', - code: 'CS', + name: "Serbia and Montenegro", + code: "CS", }, { - name: 'Seychelles', - code: 'SC', + name: "Seychelles", + code: "SC", }, { - name: 'Sierra Leone', - code: 'SL', + name: "Sierra Leone", + code: "SL", }, { - name: 'Singapore', - code: 'SG', + name: "Singapore", + code: "SG", }, { - name: 'Slovakia', - code: 'SK', + name: "Slovakia", + code: "SK", }, { - name: 'Slovenia', - code: 'SI', + name: "Slovenia", + code: "SI", }, { - name: 'Solomon Islands', - code: 'SB', + name: "Solomon Islands", + code: "SB", }, { - name: 'Somalia', - code: 'SO', + name: "Somalia", + code: "SO", }, { - name: 'South Africa', - code: 'ZA', + name: "South Africa", + code: "ZA", }, { - name: 'South Georgia and the South Sandwich Islands', - code: 'GS', + name: "South Georgia and the South Sandwich Islands", + code: "GS", }, { - name: 'Spain', - code: 'ES', + name: "Spain", + code: "ES", }, { - name: 'Sri Lanka', - code: 'LK', + name: "Sri Lanka", + code: "LK", }, { - name: 'Sudan', - code: 'SD', + name: "Sudan", + code: "SD", }, { - name: 'Suriname', - code: 'SR', + name: "Suriname", + code: "SR", }, { - name: 'Svalbard and Jan Mayen', - code: 'SJ', + name: "Svalbard and Jan Mayen", + code: "SJ", }, { - name: 'Swaziland', - code: 'SZ', + name: "Swaziland", + code: "SZ", }, { - name: 'Sweden', - code: 'SE', + name: "Sweden", + code: "SE", }, { - name: 'Switzerland', - code: 'CH', + name: "Switzerland", + code: "CH", }, { - name: 'Syrian Arab Republic', - code: 'SY', + name: "Syrian Arab Republic", + code: "SY", }, { - name: 'Taiwan, Province of China', - code: 'TW', + name: "Taiwan, Province of China", + code: "TW", }, { - name: 'Tajikistan', - code: 'TJ', + name: "Tajikistan", + code: "TJ", }, { - name: 'Tanzania, United Republic of', - code: 'TZ', + name: "Tanzania, United Republic of", + code: "TZ", }, { - name: 'Thailand', - code: 'TH', + name: "Thailand", + code: "TH", }, { - name: 'Timor-Leste', - code: 'TL', + name: "Timor-Leste", + code: "TL", }, { - name: 'Togo', - code: 'TG', + name: "Togo", + code: "TG", }, { - name: 'Tokelau', - code: 'TK', + name: "Tokelau", + code: "TK", }, { - name: 'Tonga', - code: 'TO', + name: "Tonga", + code: "TO", }, { - name: 'Trinidad and Tobago', - code: 'TT', + name: "Trinidad and Tobago", + code: "TT", }, { - name: 'Tunisia', - code: 'TN', + name: "Tunisia", + code: "TN", }, { - name: 'Turkey', - code: 'TR', + name: "Turkey", + code: "TR", }, { - name: 'Turkmenistan', - code: 'TM', + name: "Turkmenistan", + code: "TM", }, { - name: 'Turks and Caicos Islands', - code: 'TC', + name: "Turks and Caicos Islands", + code: "TC", }, { - name: 'Tuvalu', - code: 'TV', + name: "Tuvalu", + code: "TV", }, { - name: 'Uganda', - code: 'UG', + name: "Uganda", + code: "UG", }, { - name: 'Ukraine', - code: 'UA', + name: "Ukraine", + code: "UA", }, { - name: 'United Arab Emirates', - code: 'AE', + name: "United Arab Emirates", + code: "AE", }, { - name: 'United Kingdom', - code: 'GB', + name: "United Kingdom", + code: "GB", }, { - name: 'United States', - code: 'US', + name: "United States", + code: "US", }, { - name: 'United States Minor Outlying Islands', - code: 'UM', + name: "United States Minor Outlying Islands", + code: "UM", }, { - name: 'Uruguay', - code: 'UY', + name: "Uruguay", + code: "UY", }, { - name: 'Uzbekistan', - code: 'UZ', + name: "Uzbekistan", + code: "UZ", }, { - name: 'Vanuatu', - code: 'VU', + name: "Vanuatu", + code: "VU", }, { - name: 'Venezuela', - code: 'VE', + name: "Venezuela", + code: "VE", }, { - name: 'Viet Nam', - code: 'VN', + name: "Viet Nam", + code: "VN", }, { - name: 'Virgin Islands, British', - code: 'VG', + name: "Virgin Islands, British", + code: "VG", }, { - name: 'Virgin Islands, U.S.', - code: 'VI', + name: "Virgin Islands, U.S.", + code: "VI", }, { - name: 'Wallis and Futuna', - code: 'WF', + name: "Wallis and Futuna", + code: "WF", }, { - name: 'Western Sahara', - code: 'EH', + name: "Western Sahara", + code: "EH", }, { - name: 'Yemen', - code: 'YE', + name: "Yemen", + code: "YE", }, { - name: 'Zambia', - code: 'ZM', + name: "Zambia", + code: "ZM", }, { - name: 'Zimbabwe', - code: 'ZW', + name: "Zimbabwe", + code: "ZW", }, ]; diff --git a/src/assets/lists/gameNames.static.ts b/src/assets/lists/gameNames.static.ts index 25f3e60f..4f9f2799 100644 --- a/src/assets/lists/gameNames.static.ts +++ b/src/assets/lists/gameNames.static.ts @@ -1,993 +1,993 @@ export const GameNames = { gameAttributes: [ { - status: 'Among Us', - type: 'game', + status: "Among Us", + type: "game", locale: { - en: 'Among Us', - de: 'Among Us', - gr: 'Μεταξύ Μας', + en: "Among Us", + de: "Among Us", + gr: "Μεταξύ Μας", }, }, { - status: 'EA SPORTS™ FIFA 21', - type: 'game', + status: "EA SPORTS™ FIFA 21", + type: "game", locale: { - en: 'FIFA 21', - de: 'FIFA 21', - gr: 'FIFA 21', + en: "FIFA 21", + de: "FIFA 21", + gr: "FIFA 21", }, }, { - status: 'EA SPORTS™ FIFA 21 ', - type: 'game', + status: "EA SPORTS™ FIFA 21 ", + type: "game", locale: { - en: 'FIFA 21', - de: 'FIFA 21', - gr: 'FIFA 21', + en: "FIFA 21", + de: "FIFA 21", + gr: "FIFA 21", }, }, { - status: 'STAR WARS™ Battlefront™ II', - type: 'game', + status: "STAR WARS™ Battlefront™ II", + type: "game", locale: { - en: 'STAR WARS BTLF II', - de: 'STAR WARS BTLF II', - gr: 'STAR WARS BTLF II', + en: "STAR WARS BTLF II", + de: "STAR WARS BTLF II", + gr: "STAR WARS BTLF II", }, }, { - status: 'StarCraft II', - type: 'game', + status: "StarCraft II", + type: "game", locale: { - en: 'StarCraft II', - de: 'StarCraft II', - gr: 'StarCraft II', + en: "StarCraft II", + de: "StarCraft II", + gr: "StarCraft II", }, }, { - status: 'League of Legends', - type: 'game', + status: "League of Legends", + type: "game", locale: { - en: 'League of Legends', - de: 'League of Legends', - gr: 'League of Legends', + en: "League of Legends", + de: "League of Legends", + gr: "League of Legends", }, }, { - status: 'Heroes of the Storm', - type: 'game', + status: "Heroes of the Storm", + type: "game", locale: { - en: 'Heroes of the Storm', - de: 'Heroes of the Storm', - gr: 'Heroes of the Storm', + en: "Heroes of the Storm", + de: "Heroes of the Storm", + gr: "Heroes of the Storm", }, }, { - status: 'Hearthstone', - type: 'game', + status: "Hearthstone", + type: "game", locale: { - en: 'Hearthstone', - de: 'Hearthstone', - gr: 'Hearthstone', + en: "Hearthstone", + de: "Hearthstone", + gr: "Hearthstone", }, }, { - status: 'Apex Legends', - type: 'game', + status: "Apex Legends", + type: "game", locale: { - en: 'Apex Legends', - de: 'Apex Legends', - gr: 'Apex Legends', + en: "Apex Legends", + de: "Apex Legends", + gr: "Apex Legends", }, }, { - status: 'Minecraft', - type: 'game', + status: "Minecraft", + type: "game", locale: { - en: 'Minecraft', - de: 'Minecraft', - gr: 'Minecraft', + en: "Minecraft", + de: "Minecraft", + gr: "Minecraft", }, }, { - status: 'Fortnite', - type: 'game', + status: "Fortnite", + type: "game", locale: { - en: 'Fortnite', - de: 'Fortnite', - gr: 'Φορτνάιτ', + en: "Fortnite", + de: "Fortnite", + gr: "Φορτνάιτ", }, }, { - status: 'Don\'t Starve Together', - type: 'game', + status: "Don't Starve Together", + type: "game", locale: { - en: 'Don\'t Starve Together', - de: 'Don\'t Starve Together', - gr: 'Don\'t Starve Together', + en: "Don't Starve Together", + de: "Don't Starve Together", + gr: "Don't Starve Together", }, }, { - status: 'Overwatch', - type: 'game', + status: "Overwatch", + type: "game", locale: { - en: 'Overwatch', - de: 'Overwatch', - gr: 'Overwatch', + en: "Overwatch", + de: "Overwatch", + gr: "Overwatch", }, }, { - status: 'The Mean Greens - Plastic Warfare', - type: 'game', + status: "The Mean Greens - Plastic Warfare", + type: "game", locale: { - en: 'The Mean Greens', - de: 'The Mean Greens', - gr: 'Οι Κακοί Πράσινο', + en: "The Mean Greens", + de: "The Mean Greens", + gr: "Οι Κακοί Πράσινο", }, }, { - status: 'Valorant', - type: 'game', + status: "Valorant", + type: "game", locale: { - en: 'Valorant', - de: 'Valorant', - gr: 'Valorant', + en: "Valorant", + de: "Valorant", + gr: "Valorant", }, }, { - status: '7 Days to Die', - type: 'game', + status: "7 Days to Die", + type: "game", locale: { - en: '7 Days to Die', - de: '7 Days to Die', - gr: '7 Μέρες να Πεθάνεις', + en: "7 Days to Die", + de: "7 Days to Die", + gr: "7 Μέρες να Πεθάνεις", }, }, { - status: 'A Plague Tale: Innocence', - type: 'game', + status: "A Plague Tale: Innocence", + type: "game", locale: { - en: 'A Plague Tale', - de: 'A Plague Tale', - gr: 'Ιστορία Πανούκλας', + en: "A Plague Tale", + de: "A Plague Tale", + gr: "Ιστορία Πανούκλας", }, }, { - status: 'Age of Empires II: Definitive Edition', - type: 'game', + status: "Age of Empires II: Definitive Edition", + type: "game", locale: { - en: 'Age of Empires II', - de: 'Age of Empires II', - gr: 'Age of Empires II', + en: "Age of Empires II", + de: "Age of Empires II", + gr: "Age of Empires II", }, }, { - status: 'Age of Empires II: HD Edition', - type: 'game', + status: "Age of Empires II: HD Edition", + type: "game", locale: { - en: 'Age of Empires II', - de: 'Age of Empires II', - gr: 'Age of Empires II', + en: "Age of Empires II", + de: "Age of Empires II", + gr: "Age of Empires II", }, }, { - status: 'Age of Empires II (2013)', - type: 'game', + status: "Age of Empires II (2013)", + type: "game", locale: { - en: 'Age of Empires II', - de: 'Age of Empires II', - gr: 'Age of Empires II', + en: "Age of Empires II", + de: "Age of Empires II", + gr: "Age of Empires II", }, }, { - status: 'ARK: Survival Evolved', - type: 'game', + status: "ARK: Survival Evolved", + type: "game", locale: { - en: 'ARK', - de: 'ARK', - gr: 'ΑΡΚ', + en: "ARK", + de: "ARK", + gr: "ΑΡΚ", }, }, { - status: 'Arma 3', - type: 'game', + status: "Arma 3", + type: "game", locale: { - en: 'Arma 3', - de: 'Arma 3', - gr: 'Άρμα 3', + en: "Arma 3", + de: "Arma 3", + gr: "Άρμα 3", }, }, { - status: 'Assassin\'s Creed® Odyssey', - type: 'game', + status: "Assassin's Creed® Odyssey", + type: "game", locale: { - en: 'Assassin\'s Creed Odyssey', - de: 'Assassin\'s Creed Odyssey', - gr: 'Δολοφονικό Θρήσκευμα: Οδύσσεια', + en: "Assassin's Creed Odyssey", + de: "Assassin's Creed Odyssey", + gr: "Δολοφονικό Θρήσκευμα: Οδύσσεια", }, }, { - status: 'BATTLETECH', - type: 'game', + status: "BATTLETECH", + type: "game", locale: { - en: 'BATTLETECH', - de: 'BATTLETECH', - gr: 'Πολεμική Τεχνολογία', + en: "BATTLETECH", + de: "BATTLETECH", + gr: "Πολεμική Τεχνολογία", }, }, { - status: 'Beat Saber', - type: 'game', + status: "Beat Saber", + type: "game", locale: { - en: 'Beat Saber', - de: 'Beat Saber', - gr: 'Σέιπερ Νίκης', + en: "Beat Saber", + de: "Beat Saber", + gr: "Σέιπερ Νίκης", }, }, { - status: 'Black Desert Online', - type: 'game', + status: "Black Desert Online", + type: "game", locale: { - en: 'Black Desert', - de: 'Black Desert', - gr: 'Μαύρη Έρημος', + en: "Black Desert", + de: "Black Desert", + gr: "Μαύρη Έρημος", }, }, { - status: 'BONEWORKS', - type: 'game', + status: "BONEWORKS", + type: "game", locale: { - en: 'BONEWORKS', - de: 'BONEWORKS', - gr: 'ΚΟΚΑΛΟΕΡΓΑΣΙΕΣ', + en: "BONEWORKS", + de: "BONEWORKS", + gr: "ΚΟΚΑΛΟΕΡΓΑΣΙΕΣ", }, }, { - status: 'Call of Duty®: Black Ops II', - type: 'game', + status: "Call of Duty®: Black Ops II", + type: "game", locale: { - en: 'Call of Duty: Black Ops 2', - de: 'Call of Duty: Black Ops 2', - gr: 'Κάλεσμα του Καθήκοντος: Μαύρος Χειριστής 2', + en: "Call of Duty: Black Ops 2", + de: "Call of Duty: Black Ops 2", + gr: "Κάλεσμα του Καθήκοντος: Μαύρος Χειριστής 2", }, }, { - status: 'Call of Duty®: Black Ops III', - type: 'game', + status: "Call of Duty®: Black Ops III", + type: "game", locale: { - en: 'Call of Duty: Black Ops 3', - de: 'Call of Duty: Black Ops 3', - gr: 'Κάλεσμα του Καθήκοντος Μαύρος Χειριστής 3', + en: "Call of Duty: Black Ops 3", + de: "Call of Duty: Black Ops 3", + gr: "Κάλεσμα του Καθήκοντος Μαύρος Χειριστής 3", }, }, { - status: 'CODE VEIN', - type: 'game', + status: "CODE VEIN", + type: "game", locale: { - en: 'CODE VEIN', - de: 'CODE VEIN', - gr: 'ΚΩΔΙΚΑΣ ΦΛΕΒΑΣ', + en: "CODE VEIN", + de: "CODE VEIN", + gr: "ΚΩΔΙΚΑΣ ΦΛΕΒΑΣ", }, }, { - status: 'Conan Exiles', - type: 'game', + status: "Conan Exiles", + type: "game", locale: { - en: 'Conan Exile', - de: 'Conan Exile', - gr: 'Conan Εξορία', + en: "Conan Exile", + de: "Conan Exile", + gr: "Conan Εξορία", }, }, { - status: 'Counter-Strike: Global Offensive', - type: 'game', + status: "Counter-Strike: Global Offensive", + type: "game", locale: { - en: 'CS:GO', - de: 'CS:GO', - gr: 'CS:GO', + en: "CS:GO", + de: "CS:GO", + gr: "CS:GO", }, }, { - status: 'DARK SOULS™ III', - type: 'game', + status: "DARK SOULS™ III", + type: "game", locale: { - en: 'DARK SOULS III', - de: 'DARK SOULS III', - gr: 'Μαύρες Ψυχές III', + en: "DARK SOULS III", + de: "DARK SOULS III", + gr: "Μαύρες Ψυχές III", }, }, { - status: 'DARK SOULS III', - type: 'game', + status: "DARK SOULS III", + type: "game", locale: { - en: 'DARK SOULS III', - de: 'DARK SOULS III', - gr: 'Μαύρες Ψυχές III', + en: "DARK SOULS III", + de: "DARK SOULS III", + gr: "Μαύρες Ψυχές III", }, }, { - status: 'DARK SOULS™ II', - type: 'game', + status: "DARK SOULS™ II", + type: "game", locale: { - en: 'DARK SOULS II', - de: 'DARK SOULS II', - gr: 'Μαύρες Ψυχές II', + en: "DARK SOULS II", + de: "DARK SOULS II", + gr: "Μαύρες Ψυχές II", }, }, { - status: 'DARK SOULS II', - type: 'game', + status: "DARK SOULS II", + type: "game", locale: { - en: 'DARK SOULS II', - de: 'DARK SOULS II', - gr: 'Μαύρες Ψυχές II', + en: "DARK SOULS II", + de: "DARK SOULS II", + gr: "Μαύρες Ψυχές II", }, }, { - status: 'DayZ', - type: 'game', + status: "DayZ", + type: "game", locale: { - en: 'DayZ', - de: 'DayZ', - gr: 'ΜέρεςΖ', + en: "DayZ", + de: "DayZ", + gr: "ΜέρεςΖ", }, }, { - status: 'Dead by Daylight', - type: 'game', + status: "Dead by Daylight", + type: "game", locale: { - en: 'Dead by Dayligh', - de: 'Dead by Dayligh', - gr: 'Νεκρός με το Ξημέρωμα', + en: "Dead by Dayligh", + de: "Dead by Dayligh", + gr: "Νεκρός με το Ξημέρωμα", }, }, { - status: 'Deep Rock Galactic', - type: 'game', + status: "Deep Rock Galactic", + type: "game", locale: { - en: 'Deep Rock Galactic', - de: 'Deep Rock Galactic', - gr: 'Βαθύς Γαλαξιακός Βράχος', + en: "Deep Rock Galactic", + de: "Deep Rock Galactic", + gr: "Βαθύς Γαλαξιακός Βράχος", }, }, { - status: 'Destiny 2', - type: 'game', + status: "Destiny 2", + type: "game", locale: { - en: 'Destiny 2', - de: 'Destiny 2', - gr: 'Πεπρωμένο 2 ', + en: "Destiny 2", + de: "Destiny 2", + gr: "Πεπρωμένο 2 ", }, }, { - status: 'Devil May Cry 5', - type: 'game', + status: "Devil May Cry 5", + type: "game", locale: { - en: 'Devil May Cry 5', - de: 'Devil May Cry 5', - gr: 'Διάβολος Μπορεί να Κλάψει 5', + en: "Devil May Cry 5", + de: "Devil May Cry 5", + gr: "Διάβολος Μπορεί να Κλάψει 5", }, }, { - status: 'Dishonored 2', - type: 'game', + status: "Dishonored 2", + type: "game", locale: { - en: 'Dishonored 2', - de: 'Dishonored 2', - gr: 'Ατιμωμένος 2', + en: "Dishonored 2", + de: "Dishonored 2", + gr: "Ατιμωμένος 2", }, }, { - status: 'DOOM', - type: 'game', + status: "DOOM", + type: "game", locale: { - en: 'DOOM', - de: 'DOOM', - gr: 'Καταδίκη', + en: "DOOM", + de: "DOOM", + gr: "Καταδίκη", }, }, { - status: 'DOOM Eternal', - type: 'game', + status: "DOOM Eternal", + type: "game", locale: { - en: 'DOOM Eternal', - de: 'DOOM Eternal', - gr: 'Αιώνια Καταδίκη', + en: "DOOM Eternal", + de: "DOOM Eternal", + gr: "Αιώνια Καταδίκη", }, }, { - status: 'Dota 2', - type: 'game', + status: "Dota 2", + type: "game", locale: { - en: 'Dota 2', - de: 'Dota 2', - gr: 'Ντότα 2 ', + en: "Dota 2", + de: "Dota 2", + gr: "Ντότα 2 ", }, }, { - status: 'DRAGON BALL FighterZ', - type: 'game', + status: "DRAGON BALL FighterZ", + type: "game", locale: { - en: 'DRAGON BALL FighterZ', - de: 'DRAGON BALL FighterZ', - gr: 'Δρακόν Μπάλα ΠολεμιστήςΖ', + en: "DRAGON BALL FighterZ", + de: "DRAGON BALL FighterZ", + gr: "Δρακόν Μπάλα ΠολεμιστήςΖ", }, }, { - status: 'Dying Light', - type: 'game', + status: "Dying Light", + type: "game", locale: { - en: 'Dying Light', - de: 'Dying Light', - gr: 'Φως θανάτου', + en: "Dying Light", + de: "Dying Light", + gr: "Φως θανάτου", }, }, { - status: 'The Elder Scrolls V: Skyrim Special Edition', - type: 'game', + status: "The Elder Scrolls V: Skyrim Special Edition", + type: "game", locale: { - en: 'Skyrim V', - de: 'Skyrim V', - gr: 'Σκάιριμ V', + en: "Skyrim V", + de: "Skyrim V", + gr: "Σκάιριμ V", }, }, { - status: 'The Elder Scrolls® Online', - type: 'game', + status: "The Elder Scrolls® Online", + type: "game", locale: { - en: 'Elder Scrolls Online', - de: 'Elder Scrolls Online', - gr: 'Γεροντικοί Κύλινδροι στο διαδίκτυο', + en: "Elder Scrolls Online", + de: "Elder Scrolls Online", + gr: "Γεροντικοί Κύλινδροι στο διαδίκτυο", }, }, { - status: 'Fallout 4', - type: 'game', + status: "Fallout 4", + type: "game", locale: { - en: 'Fallout 4', - de: 'Fallout 4', - gr: 'Επιπτώσεις 4', + en: "Fallout 4", + de: "Fallout 4", + gr: "Επιπτώσεις 4", }, }, { - status: 'Far Cry® 5', - type: 'game', + status: "Far Cry® 5", + type: "game", locale: { - en: 'Far Cry 5', - de: 'Far Cry 5', - gr: 'Πολύ Μακρυά 5', + en: "Far Cry 5", + de: "Far Cry 5", + gr: "Πολύ Μακρυά 5", }, }, { - status: 'FINAL FANTASY XIV Online', - type: 'game', + status: "FINAL FANTASY XIV Online", + type: "game", locale: { - en: 'FINAL FANTASY XIV', - de: 'FINAL FANTASY XIV', - gr: 'Τελική Φαντασία', + en: "FINAL FANTASY XIV", + de: "FINAL FANTASY XIV", + gr: "Τελική Φαντασία", }, }, { - status: 'The Forest', - type: 'game', + status: "The Forest", + type: "game", locale: { - en: 'The Forest', - de: 'The Forest', - gr: 'Το Δάσος', + en: "The Forest", + de: "The Forest", + gr: "Το Δάσος", }, }, { - status: 'Garry\'s Mod', - type: 'game', + status: "Garry's Mod", + type: "game", locale: { - en: 'Garry\'s Mod', - de: 'Garry\'s Mod', - gr: 'Η Μόντα του Γκάρι', + en: "Garry's Mod", + de: "Garry's Mod", + gr: "Η Μόντα του Γκάρι", }, }, { - status: 'Grand Theft Auto V', - type: 'game', + status: "Grand Theft Auto V", + type: "game", locale: { - en: 'Grand Theft Auto 5', - de: 'Grand Theft Auto 5', - gr: 'Μεγάλη Κλοπή Αυτοκινήτων 5', + en: "Grand Theft Auto 5", + de: "Grand Theft Auto 5", + gr: "Μεγάλη Κλοπή Αυτοκινήτων 5", }, }, { - status: 'GreedFall', - type: 'game', + status: "GreedFall", + type: "game", locale: { - en: 'GreedFall', - de: 'GreedFall', - gr: 'Πτώση Απληστίας', + en: "GreedFall", + de: "GreedFall", + gr: "Πτώση Απληστίας", }, }, { - status: 'Grim Dawn', - type: 'game', + status: "Grim Dawn", + type: "game", locale: { - en: 'Grim Daw', - de: 'Grim Daw', - gr: 'Απαίσια Αυγή', + en: "Grim Daw", + de: "Grim Daw", + gr: "Απαίσια Αυγή", }, }, { - status: 'GTFO', - type: 'game', + status: "GTFO", + type: "game", locale: { - en: 'Get The Fuck Out', - de: 'Get The Fuck Out', - gr: 'ΒΓΑΕ', + en: "Get The Fuck Out", + de: "Get The Fuck Out", + gr: "ΒΓΑΕ", }, }, { - status: 'Hades', - type: 'game', + status: "Hades", + type: "game", locale: { - en: 'Hade', - de: 'Hade', - gr: 'Άδης', + en: "Hade", + de: "Hade", + gr: "Άδης", }, }, { - status: 'Rocket League', - type: 'game', + status: "Rocket League", + type: "game", locale: { - en: 'Rocket League', - de: 'Rocket League', - gr: 'Rocket League', + en: "Rocket League", + de: "Rocket League", + gr: "Rocket League", }, }, { - status: 'Rocket League®', - type: 'game', + status: "Rocket League®", + type: "game", locale: { - en: 'Rocket League', - de: 'Rocket League', - gr: 'Rocket League', + en: "Rocket League", + de: "Rocket League", + gr: "Rocket League", }, }, { - status: 'Halo: The Master Chief Collection', - type: 'game', + status: "Halo: The Master Chief Collection", + type: "game", locale: { - en: 'Halo: Master Chief', - de: 'Halo: Master Chief', - gr: 'Halo: Master Chief', + en: "Halo: Master Chief", + de: "Halo: Master Chief", + gr: "Halo: Master Chief", }, }, { - status: 'Half-Life', - type: 'game', + status: "Half-Life", + type: "game", locale: { - en: 'Half Life', - de: 'Half Life', - gr: 'Μισή Ζωή', + en: "Half Life", + de: "Half Life", + gr: "Μισή Ζωή", }, }, { - status: 'Half-Life 2', - type: 'game', + status: "Half-Life 2", + type: "game", locale: { - en: 'Half Life 2', - de: 'Half Life 2', - gr: 'Μισή Ζωή 2', + en: "Half Life 2", + de: "Half Life 2", + gr: "Μισή Ζωή 2", }, }, { - status: 'Half-Life 2: Episode One', - type: 'game', + status: "Half-Life 2: Episode One", + type: "game", locale: { - en: 'Half Life 2: Episode On', - de: 'Half Life 2: Episode On', - gr: 'Μισή Ζωή 2: Επεισόδιο Ένα', + en: "Half Life 2: Episode On", + de: "Half Life 2: Episode On", + gr: "Μισή Ζωή 2: Επεισόδιο Ένα", }, }, { - status: 'Half-Life 2: Episode Two', - type: 'game', + status: "Half-Life 2: Episode Two", + type: "game", locale: { - en: 'Half Life 2: Episode Two', - de: 'Half Life 2: Episode Two', - gr: 'Μισή Ζωή 2: Επεισόδιο Δύο', + en: "Half Life 2: Episode Two", + de: "Half Life 2: Episode Two", + gr: "Μισή Ζωή 2: Επεισόδιο Δύο", }, }, { - status: 'Half-Life 2: Lost Coast', - type: 'game', + status: "Half-Life 2: Lost Coast", + type: "game", locale: { - en: 'Half Life 2: Lost Coast', - de: 'Half Life 2: Lost Coast', - gr: 'Μισή Ζωή 2: Χαμένη Ακτή', + en: "Half Life 2: Lost Coast", + de: "Half Life 2: Lost Coast", + gr: "Μισή Ζωή 2: Χαμένη Ακτή", }, }, { - status: 'Half-Life: Blue Shift', - type: 'game', + status: "Half-Life: Blue Shift", + type: "game", locale: { - en: 'Half Life: Blue Shif', - de: 'Half Life: Blue Shif', - gr: 'Μισή Ζωή: Μπλε Μετατόπιση', + en: "Half Life: Blue Shif", + de: "Half Life: Blue Shif", + gr: "Μισή Ζωή: Μπλε Μετατόπιση", }, }, { - status: 'Half-Life: Opposing Force', - type: 'game', + status: "Half-Life: Opposing Force", + type: "game", locale: { - en: 'Half Life: Opposing Force', - de: 'Half Life: Opposing Force', - gr: 'Μισή Ζωή: Αντίθετη Δύναμη', + en: "Half Life: Opposing Force", + de: "Half Life: Opposing Force", + gr: "Μισή Ζωή: Αντίθετη Δύναμη", }, }, { - status: 'HITMAN™ 2', - type: 'game', + status: "HITMAN™ 2", + type: "game", locale: { - en: 'HITMAN 2', - de: 'HITMAN 2', - gr: 'Πληρωμένος Δολοφόνος', + en: "HITMAN 2", + de: "HITMAN 2", + gr: "Πληρωμένος Δολοφόνος", }, }, { - status: 'Hollow Knight', - type: 'game', + status: "Hollow Knight", + type: "game", locale: { - en: 'Hollow Knigh', - de: 'Hollow Knigh', - gr: 'Κούφιος Ιππότης', + en: "Hollow Knigh", + de: "Hollow Knigh", + gr: "Κούφιος Ιππότης", }, }, { - status: 'Hunt: Showdown', - type: 'game', + status: "Hunt: Showdown", + type: "game", locale: { - en: 'Hunt: Showdown', - de: 'Hunt: Showdown', - gr: 'Κυνήγι: Αναμέτρηση', + en: "Hunt: Showdown", + de: "Hunt: Showdown", + gr: "Κυνήγι: Αναμέτρηση", }, }, { - status: 'theHunter: Call of the Wild™', - type: 'game', + status: "theHunter: Call of the Wild™", + type: "game", locale: { - en: 'theHunter: Call of the Wild', - de: 'theHunter: Call of the Wild', - gr: 'ΟΚυνηγός: Κάλεσμα της Φύσης', + en: "theHunter: Call of the Wild", + de: "theHunter: Call of the Wild", + gr: "ΟΚυνηγός: Κάλεσμα της Φύσης", }, }, { - status: 'Insurgency: Sandstorm', - type: 'game', + status: "Insurgency: Sandstorm", + type: "game", locale: { - en: 'Insurgency: Sandstorm', - de: 'Insurgency: Sandstorm', - gr: 'Εξέγερση: Αμμοθύελλα', + en: "Insurgency: Sandstorm", + de: "Insurgency: Sandstorm", + gr: "Εξέγερση: Αμμοθύελλα", }, }, { - status: 'World of Tanks', - type: 'game', + status: "World of Tanks", + type: "game", locale: { - en: 'World of Tanks', - de: 'World of Tanks', - gr: 'Κόσμος των Τάνκ', + en: "World of Tanks", + de: "World of Tanks", + gr: "Κόσμος των Τάνκ", }, }, { - status: 'Jurassic World Evolution', - type: 'game', + status: "Jurassic World Evolution", + type: "game", locale: { - en: 'Jurassic World Evolution', - de: 'Jurassic World Evolution', - gr: 'Ιουρασικός Κόσμος Εξέλιξη', + en: "Jurassic World Evolution", + de: "Jurassic World Evolution", + gr: "Ιουρασικός Κόσμος Εξέλιξη", }, }, { - status: 'Middle-earth™: Shadow of War™', - type: 'game', + status: "Middle-earth™: Shadow of War™", + type: "game", locale: { - en: 'Middle Earth: Shadow of War', - de: 'Middle Earth: Shadow of War', - gr: 'Μέση Γη: Σκιά του Πολέμου', + en: "Middle Earth: Shadow of War", + de: "Middle Earth: Shadow of War", + gr: "Μέση Γη: Σκιά του Πολέμου", }, }, { - status: 'MONSTER HUNTER: WORLD', - type: 'game', + status: "MONSTER HUNTER: WORLD", + type: "game", locale: { - en: 'MONSTER HUNTER: WORLD', - de: 'MONSTER HUNTER: WORLD', - gr: 'ΚΥΝΗΓΟΣ ΤΕΡΑΤΩΝ: ΚΟΣΜΟΣ', + en: "MONSTER HUNTER: WORLD", + de: "MONSTER HUNTER: WORLD", + gr: "ΚΥΝΗΓΟΣ ΤΕΡΑΤΩΝ: ΚΟΣΜΟΣ", }, }, { - status: 'MORDHAU', - type: 'game', + status: "MORDHAU", + type: "game", locale: { - en: 'MORDHAU', - de: 'MORDHAU', - gr: 'MORDHAU', + en: "MORDHAU", + de: "MORDHAU", + gr: "MORDHAU", }, }, { - status: 'Wargame: Red Dragon', - type: 'game', + status: "Wargame: Red Dragon", + type: "game", locale: { - en: 'Wargame', - de: 'Wargame', - gr: 'Πολεμοπαίχνιδο', + en: "Wargame", + de: "Wargame", + gr: "Πολεμοπαίχνιδο", }, }, { - status: 'Path of Exile', - type: 'game', + status: "Path of Exile", + type: "game", locale: { - en: 'Path of Exile', - de: 'Path of Exile', - gr: 'Μονοπάτι της Εξορίας', + en: "Path of Exile", + de: "Path of Exile", + gr: "Μονοπάτι της Εξορίας", }, }, { - status: 'PAYDAY 2', - type: 'game', + status: "PAYDAY 2", + type: "game", locale: { - en: 'PAYDAY 2', - de: 'PAYDAY 2', - gr: 'ΗΜΕΡΑ ΠΛΗΡΩΜΗΣ 2', + en: "PAYDAY 2", + de: "PAYDAY 2", + gr: "ΗΜΕΡΑ ΠΛΗΡΩΜΗΣ 2", }, }, { - status: 'PLAYERUNKNOWN\'S BATTLEGROUNDS', - type: 'game', + status: "PLAYERUNKNOWN'S BATTLEGROUNDS", + type: "game", locale: { - en: 'PUBG', - de: 'PUBG', - gr: 'PUBG', + en: "PUBG", + de: "PUBG", + gr: "PUBG", }, }, { - status: 'Portal', - type: 'game', + status: "Portal", + type: "game", locale: { - en: 'Portal', - de: 'Portal', - gr: 'Πύλη', + en: "Portal", + de: "Portal", + gr: "Πύλη", }, }, { - status: 'Portal 2', - type: 'game', + status: "Portal 2", + type: "game", locale: { - en: 'Portal 2', - de: 'Portal 2', - gr: 'Πύλη 2', + en: "Portal 2", + de: "Portal 2", + gr: "Πύλη 2", }, }, { - status: 'Pummel Party', - type: 'game', + status: "Pummel Party", + type: "game", locale: { - en: 'Pummel Party', - de: 'Pummel Party', - gr: 'Pummel Party', + en: "Pummel Party", + de: "Pummel Party", + gr: "Pummel Party", }, }, { - status: 'Red Dead Redemption 2', - type: 'game', + status: "Red Dead Redemption 2", + type: "game", locale: { - en: 'Red Dead Redemption 2', - de: 'Red Dead Redemption 2', - gr: 'Κόκκινο Νεκρή Εξαργύρωση 2', + en: "Red Dead Redemption 2", + de: "Red Dead Redemption 2", + gr: "Κόκκινο Νεκρή Εξαργύρωση 2", }, }, { - status: 'Remnant: From the Ashes', - type: 'game', + status: "Remnant: From the Ashes", + type: "game", locale: { - en: 'Remnant: From the Ashes', - de: 'Remnant: From the Ashes', - gr: 'Υπόλοιπο: Από τις Στάχτες', + en: "Remnant: From the Ashes", + de: "Remnant: From the Ashes", + gr: "Υπόλοιπο: Από τις Στάχτες", }, }, { - status: 'RESIDENT EVIL 2', - type: 'game', + status: "RESIDENT EVIL 2", + type: "game", locale: { - en: 'RESIDENT EVIL 2', - de: 'RESIDENT EVIL 2', - gr: 'ΚΑΤΟΙΚΟΣ ΚΑΚΟΥ 2', + en: "RESIDENT EVIL 2", + de: "RESIDENT EVIL 2", + gr: "ΚΑΤΟΙΚΟΣ ΚΑΚΟΥ 2", }, }, { - status: 'Risk of Rain 2', - type: 'game', + status: "Risk of Rain 2", + type: "game", locale: { - en: 'Risk of Rain 2', - de: 'Risk of Rain 2', - gr: 'Κίνδυνος βροχής 2', + en: "Risk of Rain 2", + de: "Risk of Rain 2", + gr: "Κίνδυνος βροχής 2", }, }, { - status: 'Rust', - type: 'game', + status: "Rust", + type: "game", locale: { - en: 'Rust', - de: 'Rust', - gr: 'Σκουριά', + en: "Rust", + de: "Rust", + gr: "Σκουριά", }, }, { - status: 'Sekiro™: Shadows Die Twice', - type: 'game', + status: "Sekiro™: Shadows Die Twice", + type: "game", locale: { - en: 'Sekiro: Shadows Die Twic', - de: 'Sekiro: Shadows Die Twic', - gr: 'Σεκίρο: Οι σκιές πεθαίνουν δύο φορές', + en: "Sekiro: Shadows Die Twic", + de: "Sekiro: Shadows Die Twic", + gr: "Σεκίρο: Οι σκιές πεθαίνουν δύο φορές", }, }, { - status: 'Shadow of the Tomb Raider: Definitive Edition', - type: 'game', + status: "Shadow of the Tomb Raider: Definitive Edition", + type: "game", locale: { - en: 'Shadow of the Tomb Raider', - de: 'Shadow of the Tomb Raider', - gr: 'Shadow of the Tomb Raider', + en: "Shadow of the Tomb Raider", + de: "Shadow of the Tomb Raider", + gr: "Shadow of the Tomb Raider", }, }, { - status: 'SMITE®', - type: 'game', + status: "SMITE®", + type: "game", locale: { - en: 'SMITΕ', - de: 'SMITΕ', - gr: 'SMITΕ', + en: "SMITΕ", + de: "SMITΕ", + gr: "SMITΕ", }, }, { - status: 'STAR WARS Jedi: Fallen Order™', - type: 'game', + status: "STAR WARS Jedi: Fallen Order™", + type: "game", locale: { - en: 'STAR WARS: Fallen Order', - de: 'STAR WARS: Fallen Order', - gr: 'STAR WARS: Fallen Order', + en: "STAR WARS: Fallen Order", + de: "STAR WARS: Fallen Order", + gr: "STAR WARS: Fallen Order", }, }, { - status: 'Team Fortress 2', - type: 'game', + status: "Team Fortress 2", + type: "game", locale: { - en: 'Team Fortress 2', - de: 'Team Fortress 2', - gr: 'Ομαδικό Φρούριο 2', + en: "Team Fortress 2", + de: "Team Fortress 2", + gr: "Ομαδικό Φρούριο 2", }, }, { - status: 'TEKKEN 7', - type: 'game', + status: "TEKKEN 7", + type: "game", locale: { - en: 'TEKKEN 7', - de: 'TEKKEN 7', - gr: 'TEKKEN 7', + en: "TEKKEN 7", + de: "TEKKEN 7", + gr: "TEKKEN 7", }, }, { - status: 'Terraria', - type: 'game', + status: "Terraria", + type: "game", locale: { - en: 'Terraria', - de: 'Terraria', - gr: 'Terraria', + en: "Terraria", + de: "Terraria", + gr: "Terraria", }, }, { - status: 'Tom Clancy\'s Rainbow Six® Siege', - type: 'game', + status: "Tom Clancy's Rainbow Six® Siege", + type: "game", locale: { - en: 'Rainbow Six Siege', - de: 'Rainbow Six Siege', - gr: 'ΟυράνιοΤόξο Έξι Πολιορκία', + en: "Rainbow Six Siege", + de: "Rainbow Six Siege", + gr: "ΟυράνιοΤόξο Έξι Πολιορκία", }, }, { - status: 'Total War: THREE KINGDOMS', - type: 'game', + status: "Total War: THREE KINGDOMS", + type: "game", locale: { - en: 'Total War: THREE KINGDOM', - de: 'Total War: THREE KINGDOM', - gr: 'Απόλυτος πόλεμος: ΤΡΙΑ ΒΑΣΙΛΕΙΑ', + en: "Total War: THREE KINGDOM", + de: "Total War: THREE KINGDOM", + gr: "Απόλυτος πόλεμος: ΤΡΙΑ ΒΑΣΙΛΕΙΑ", }, }, { - status: 'Total War: WARHAMMER', - type: 'game', + status: "Total War: WARHAMMER", + type: "game", locale: { - en: 'Total War: WARHAMMER', - de: 'Total War: WARHAMMER', - gr: 'Απόλυτος πόλεμος: ΠΟΛΕΜΟΣΦΥΡΙ', + en: "Total War: WARHAMMER", + de: "Total War: WARHAMMER", + gr: "Απόλυτος πόλεμος: ΠΟΛΕΜΟΣΦΥΡΙ", }, }, { - status: 'Total War: WARHAMMER II', - type: 'game', + status: "Total War: WARHAMMER II", + type: "game", locale: { - en: 'Total War: WARHAMMER II', - de: 'Total War: WARHAMMER II', - gr: 'Απόλυτος πόλεμος: ΠΟΛΕΜΟΣΦΥΡΙ 2', + en: "Total War: WARHAMMER II", + de: "Total War: WARHAMMER II", + gr: "Απόλυτος πόλεμος: ΠΟΛΕΜΟΣΦΥΡΙ 2", }, }, { - status: 'Totally Accurate Battle Simulator', - type: 'game', + status: "Totally Accurate Battle Simulator", + type: "game", locale: { - en: 'Totally Accurate Battle Simulator', - de: 'Totally Accurate Battle Simulator', - gr: 'Πλήρως Ακριβής Προσομοιωτής Μάχης', + en: "Totally Accurate Battle Simulator", + de: "Totally Accurate Battle Simulator", + gr: "Πλήρως Ακριβής Προσομοιωτής Μάχης", }, }, { - status: 'Warframe', - type: 'game', + status: "Warframe", + type: "game", locale: { - en: 'Warframe', - de: 'Warframe', - gr: 'Πολεμικό Πλαίσιο', + en: "Warframe", + de: "Warframe", + gr: "Πολεμικό Πλαίσιο", }, }, { - status: 'Warhammer: Vermintide 2', - type: 'game', + status: "Warhammer: Vermintide 2", + type: "game", locale: { - en: 'Warhammer: Vermintide 2', - de: 'Warhammer: Vermintide 2', - gr: 'Πολεμοσφύρι: Βερμιντίδη 2', + en: "Warhammer: Vermintide 2", + de: "Warhammer: Vermintide 2", + gr: "Πολεμοσφύρι: Βερμιντίδη 2", }, }, { - status: 'War Thunder', - type: 'game', + status: "War Thunder", + type: "game", locale: { - en: 'War Thunder', - de: 'War Thunder', - gr: 'Κεραυνός του πολέμου', + en: "War Thunder", + de: "War Thunder", + gr: "Κεραυνός του πολέμου", }, }, { - status: 'The Witcher 3: Wild Hunt', - type: 'game', + status: "The Witcher 3: Wild Hunt", + type: "game", locale: { - en: 'Witcher 3', - de: 'Witcher 3', - gr: 'Γητευτής 3', + en: "Witcher 3", + de: "Witcher 3", + gr: "Γητευτής 3", }, }, { - status: 'The Witcher® 3: Wild Hunt', - type: 'game', + status: "The Witcher® 3: Wild Hunt", + type: "game", locale: { - en: 'Witcher 3', - de: 'Witcher 3', - gr: 'Γητευτής 3', + en: "Witcher 3", + de: "Witcher 3", + gr: "Γητευτής 3", }, }, { - status: 'The Witcher 2: Assassins of Kings Enhanced Edition', - type: 'game', + status: "The Witcher 2: Assassins of Kings Enhanced Edition", + type: "game", locale: { - en: 'Witcher 2', - de: 'Witcher 2', - gr: 'Γητευτής 2', + en: "Witcher 2", + de: "Witcher 2", + gr: "Γητευτής 2", }, }, { - status: 'The Witcher 2: Assassins of Kings', - type: 'game', + status: "The Witcher 2: Assassins of Kings", + type: "game", locale: { - en: 'Witcher 2', - de: 'Witcher 2', - gr: 'Γητευτής 2', + en: "Witcher 2", + de: "Witcher 2", + gr: "Γητευτής 2", }, }, ], diff --git a/src/assets/lists/profaneWords.static.ts b/src/assets/lists/profaneWords.static.ts index c2f7b951..18de9821 100644 --- a/src/assets/lists/profaneWords.static.ts +++ b/src/assets/lists/profaneWords.static.ts @@ -1,499 +1,499 @@ export const ProfaneWords = { gr: [ - 'γαμώ', - 'γαμω', - 'γαμημένε', - 'γαμημενε', - 'μουνό', - 'μουνο', - 'μουνί', - 'μουνι', - 'μαλάκα', - 'μαλακα', - 'πούτσα', - 'πουτσα', - 'πουτάνα', - 'πουτανα', - 'πούτσο', - 'πουτσο', - 'πούτσος', - 'πουτσος', - 'πούστρα', - 'πουστρα', - 'παπάρι', - 'παπαρι', - 'πίπα', - 'πιπα', - 'γλυφομούνι', - 'γλυφομουνι', - 'αδερφάρα', - 'αδερφαρα', - 'γαμόμανο', - 'γαμομανο', - 'γαμημένε', - 'γαμημενε', - 'γαμιώλη', - 'γαμιωλη', - 'γαμιώλης', - 'γαμιωλης', - 'μαλακοπίτουρο', - 'μαλακοπιτουρο', - 'βούλωσε το', - 'βουλωσε το', - 'καργιόλης', - 'καργιολης', - 'καργιόλα', - 'καργιολα', - 'γρόθο', - 'γροθο', + "γαμώ", + "γαμω", + "γαμημένε", + "γαμημενε", + "μουνό", + "μουνο", + "μουνί", + "μουνι", + "μαλάκα", + "μαλακα", + "πούτσα", + "πουτσα", + "πουτάνα", + "πουτανα", + "πούτσο", + "πουτσο", + "πούτσος", + "πουτσος", + "πούστρα", + "πουστρα", + "παπάρι", + "παπαρι", + "πίπα", + "πιπα", + "γλυφομούνι", + "γλυφομουνι", + "αδερφάρα", + "αδερφαρα", + "γαμόμανο", + "γαμομανο", + "γαμημένε", + "γαμημενε", + "γαμιώλη", + "γαμιωλη", + "γαμιώλης", + "γαμιωλης", + "μαλακοπίτουρο", + "μαλακοπιτουρο", + "βούλωσε το", + "βουλωσε το", + "καργιόλης", + "καργιολης", + "καργιόλα", + "καργιολα", + "γρόθο", + "γροθο", ], de: [], en: [ - 'ahole', - 'anus', - 'ash0le', - 'ash0les', - 'asholes', - 'ass', - 'Ass Monkey', - 'Assface', - 'assh0le', - 'assh0lez', - 'asshole', - 'assholes', - 'assholz', - 'asswipe', - 'azzhole', - 'bassterds', - 'bastard', - 'bastards', - 'bastardz', - 'basterds', - 'basterdz', - 'Biatch', - 'bitch', - 'bitches', - 'Blow Job', - 'boffing', - 'butthole', - 'buttwipe', - 'c0ck', - 'c0cks', - 'c0k', - 'Carpet Muncher', - 'cawk', - 'cawks', - 'Clit', - 'cnts', - 'cntz', - 'cock', - 'cockhead', - 'cock-head', - 'cocks', - 'CockSucker', - 'cock-sucker', - 'crap', - 'cum', - 'cunt', - 'cunts', - 'cuntz', - 'dick', - 'dild0', - 'dild0s', - 'dildo', - 'dildos', - 'dilld0', - 'dilld0s', - 'dominatricks', - 'dominatrics', - 'dominatrix', - 'dyke', - 'enema', - 'f u c k', - 'f u c k e r', - 'fag', - 'fag1t', - 'faget', - 'fagg1t', - 'faggit', - 'faggot', - 'fagg0t', - 'fagit', - 'fags', - 'fagz', - 'faig', - 'faigs', - 'fart', - 'flipping the bird', - 'fuck', - 'fucker', - 'fuckin', - 'fucking', - 'fucks', - 'Fudge Packer', - 'fuk', - 'Fukah', - 'Fuken', - 'fuker', - 'Fukin', - 'Fukk', - 'Fukkah', - 'Fukken', - 'Fukker', - 'Fukkin', - 'g00k', - 'God-damned', - 'h00r', - 'h0ar', - 'h0re', - 'hells', - 'hoar', - 'hoor', - 'hoore', - 'jackoff', - 'jap', - 'japs', - 'jerk-off', - 'jisim', - 'jiss', - 'jizm', - 'jizz', - 'knob', - 'knobs', - 'knobz', - 'kunt', - 'kunts', - 'kuntz', - 'Lezzian', - 'Lipshits', - 'Lipshitz', - 'masochist', - 'masokist', - 'massterbait', - 'masstrbait', - 'masstrbate', - 'masterbaiter', - 'masterbate', - 'masterbates', - 'Motha Fucker', - 'Motha Fuker', - 'Motha Fukkah', - 'Motha Fukker', - 'Mother Fucker', - 'Mother Fukah', - 'Mother Fuker', - 'Mother Fukkah', - 'Mother Fukker', - 'mother-fucker', - 'Mutha Fucker', - 'Mutha Fukah', - 'Mutha Fuker', - 'Mutha Fukkah', - 'Mutha Fukker', - 'n1gr', - 'nastt', - 'nigger;', - 'nigur;', - 'niiger;', - 'niigr;', - 'orafis', - 'orgasim;', - 'orgasm', - 'orgasum', - 'oriface', - 'orifice', - 'orifiss', - 'packi', - 'packie', - 'packy', - 'paki', - 'pakie', - 'paky', - 'pecker', - 'peeenus', - 'peeenusss', - 'peenus', - 'peinus', - 'pen1s', - 'penas', - 'penis', - 'penis-breath', - 'penus', - 'penuus', - 'Phuc', - 'Phuck', - 'Phuk', - 'Phuker', - 'Phukker', - 'polac', - 'polack', - 'polak', - 'Poonani', - 'pr1c', - 'pr1ck', - 'pr1k', - 'pusse', - 'pussee', - 'pussy', - 'puuke', - 'puuker', - 'qweir', - 'recktum', - 'rectum', - 'retard', - 'sadist', - 'scank', - 'schlong', - 'screwing', - 'semen', - 'sex', - 'sexy', - 'Sh!t', - 'sh1t', - 'sh1ter', - 'sh1ts', - 'sh1tter', - 'sh1tz', - 'shit', - 'shits', - 'shitter', - 'Shitty', - 'Shity', - 'shitz', - 'Shyt', - 'Shyte', - 'Shytty', - 'Shyty', - 'skanck', - 'skank', - 'skankee', - 'skankey', - 'skanks', - 'Skanky', - 'slag', - 'slut', - 'sluts', - 'Slutty', - 'slutz', - 'son-of-a-bitch', - 'tit', - 'turd', - 'va1jina', - 'vag1na', - 'vagiina', - 'vagina', - 'vaj1na', - 'vajina', - 'vullva', - 'vulva', - 'w0p', - 'wh00r', - 'wh0re', - 'whore', - 'xrated', - 'xxx', - 'b!+ch', - 'bitch', - 'blowjob', - 'clit', - 'arschloch', - 'fuck', - 'shit', - 'ass', - 'asshole', - 'b!tch', - 'b17ch', - 'b1tch', - 'bastard', - 'bi+ch', - 'boiolas', - 'buceta', - 'c0ck', - 'cawk', - 'chink', - 'cipa', - 'clits', - 'cock', - 'cum', - 'cunt', - 'dildo', - 'dirsa', - 'ejakulate', - 'fatass', - 'fcuk', - 'fuk', - 'fux0r', - 'hoer', - 'hore', - 'jism', - 'kawk', - 'l3itch', - 'l3i+ch', - 'masturbate', - 'masterbat', - 'masterbat3', - 'motherfucker', - 's.o.b.', - 'mofo', - 'nazi', - 'nigga', - 'nigger', - 'nutsack', - 'phuck', - 'pimpis', - 'pusse', - 'pussy', - 'scrotum', - 'sh!t', - 'shemale', - 'shi+', - 'sh!+', - 'slut', - 'smut', - 'teets', - 'tits', - 'boobs', - 'b00bs', - 'teez', - 'testical', - 'testicle', - 'titt', - 'w00se', - 'jackoff', - 'wank', - 'whoar', - 'whore', - 'damn', - 'dyke', - 'fuck', - 'shit', - '@$$', - 'amcik', - 'andskota', - 'arse', - 'assrammer', - 'ayir', - 'bi7ch', - 'bitch', - 'bollock', - 'breasts', - 'butt-pirate', - 'cabron', - 'cazzo', - 'chraa', - 'chuj', - 'Cock', - 'cunt', - 'd4mn', - 'daygo', - 'dego', - 'dick', - 'dike', - 'dupa', - 'dziwka', - 'ejackulate', - 'Ekrem', - 'Ekto', - 'enculer', - 'faen', - 'fag', - 'fanculo', - 'fanny', - 'feces', - 'feg', - 'Felcher', - 'ficken', - 'fitt', - 'Flikker', - 'foreskin', - 'Fotze', - 'Fu', - 'fuk', - 'futkretzn', - 'gook', - 'guiena', - 'h0r', - 'h4x0r', - 'helvete', - 'hoer', - 'honkey', - 'Huevon', - 'hui', - 'injun', - 'jizz', - 'kanker', - 'kike', - 'klootzak', - 'kraut', - 'knulle', - 'kuk', - 'kuksuger', - 'Kurac', - 'kurwa', - 'kusi', - 'kyrpa', - 'lesbo', - 'mamhoon', - 'masturbat', - 'merd', - 'mibun', - 'monkleigh', - 'mouliewop', - 'muie', - 'mulkku', - 'muschi', - 'nazis', - 'nepesaurio', - 'nigger', - 'orospu', - 'paska', - 'perse', - 'picka', - 'pierdol', - 'pillu', - 'pimmel', - 'piss', - 'pizda', - 'poontsee', - 'poop', - 'porn', - 'p0rn', - 'pr0n', - 'preteen', - 'pula', - 'pule', - 'puta', - 'puto', - 'qahbeh', - 'queef', - 'rautenberg', - 'schaffer', - 'scheiss', - 'schlampe', - 'schmuck', - 'screw', - 'sh!t', - 'sharmuta', - 'sharmute', - 'shipal', - 'shiz', - 'skribz', - 'skurwysyn', - 'sphencter', - 'spic', - 'spierdalaj', - 'splooge', - 'suka', - 'b00b', - 'testicle', - 'titt', - 'twat', - 'vittu', - 'wank', - 'wetback', - 'wichser', - 'wop', - 'yed', - 'zabourah', + "ahole", + "anus", + "ash0le", + "ash0les", + "asholes", + "ass", + "Ass Monkey", + "Assface", + "assh0le", + "assh0lez", + "asshole", + "assholes", + "assholz", + "asswipe", + "azzhole", + "bassterds", + "bastard", + "bastards", + "bastardz", + "basterds", + "basterdz", + "Biatch", + "bitch", + "bitches", + "Blow Job", + "boffing", + "butthole", + "buttwipe", + "c0ck", + "c0cks", + "c0k", + "Carpet Muncher", + "cawk", + "cawks", + "Clit", + "cnts", + "cntz", + "cock", + "cockhead", + "cock-head", + "cocks", + "CockSucker", + "cock-sucker", + "crap", + "cum", + "cunt", + "cunts", + "cuntz", + "dick", + "dild0", + "dild0s", + "dildo", + "dildos", + "dilld0", + "dilld0s", + "dominatricks", + "dominatrics", + "dominatrix", + "dyke", + "enema", + "f u c k", + "f u c k e r", + "fag", + "fag1t", + "faget", + "fagg1t", + "faggit", + "faggot", + "fagg0t", + "fagit", + "fags", + "fagz", + "faig", + "faigs", + "fart", + "flipping the bird", + "fuck", + "fucker", + "fuckin", + "fucking", + "fucks", + "Fudge Packer", + "fuk", + "Fukah", + "Fuken", + "fuker", + "Fukin", + "Fukk", + "Fukkah", + "Fukken", + "Fukker", + "Fukkin", + "g00k", + "God-damned", + "h00r", + "h0ar", + "h0re", + "hells", + "hoar", + "hoor", + "hoore", + "jackoff", + "jap", + "japs", + "jerk-off", + "jisim", + "jiss", + "jizm", + "jizz", + "knob", + "knobs", + "knobz", + "kunt", + "kunts", + "kuntz", + "Lezzian", + "Lipshits", + "Lipshitz", + "masochist", + "masokist", + "massterbait", + "masstrbait", + "masstrbate", + "masterbaiter", + "masterbate", + "masterbates", + "Motha Fucker", + "Motha Fuker", + "Motha Fukkah", + "Motha Fukker", + "Mother Fucker", + "Mother Fukah", + "Mother Fuker", + "Mother Fukkah", + "Mother Fukker", + "mother-fucker", + "Mutha Fucker", + "Mutha Fukah", + "Mutha Fuker", + "Mutha Fukkah", + "Mutha Fukker", + "n1gr", + "nastt", + "nigger;", + "nigur;", + "niiger;", + "niigr;", + "orafis", + "orgasim;", + "orgasm", + "orgasum", + "oriface", + "orifice", + "orifiss", + "packi", + "packie", + "packy", + "paki", + "pakie", + "paky", + "pecker", + "peeenus", + "peeenusss", + "peenus", + "peinus", + "pen1s", + "penas", + "penis", + "penis-breath", + "penus", + "penuus", + "Phuc", + "Phuck", + "Phuk", + "Phuker", + "Phukker", + "polac", + "polack", + "polak", + "Poonani", + "pr1c", + "pr1ck", + "pr1k", + "pusse", + "pussee", + "pussy", + "puuke", + "puuker", + "qweir", + "recktum", + "rectum", + "retard", + "sadist", + "scank", + "schlong", + "screwing", + "semen", + "sex", + "sexy", + "Sh!t", + "sh1t", + "sh1ter", + "sh1ts", + "sh1tter", + "sh1tz", + "shit", + "shits", + "shitter", + "Shitty", + "Shity", + "shitz", + "Shyt", + "Shyte", + "Shytty", + "Shyty", + "skanck", + "skank", + "skankee", + "skankey", + "skanks", + "Skanky", + "slag", + "slut", + "sluts", + "Slutty", + "slutz", + "son-of-a-bitch", + "tit", + "turd", + "va1jina", + "vag1na", + "vagiina", + "vagina", + "vaj1na", + "vajina", + "vullva", + "vulva", + "w0p", + "wh00r", + "wh0re", + "whore", + "xrated", + "xxx", + "b!+ch", + "bitch", + "blowjob", + "clit", + "arschloch", + "fuck", + "shit", + "ass", + "asshole", + "b!tch", + "b17ch", + "b1tch", + "bastard", + "bi+ch", + "boiolas", + "buceta", + "c0ck", + "cawk", + "chink", + "cipa", + "clits", + "cock", + "cum", + "cunt", + "dildo", + "dirsa", + "ejakulate", + "fatass", + "fcuk", + "fuk", + "fux0r", + "hoer", + "hore", + "jism", + "kawk", + "l3itch", + "l3i+ch", + "masturbate", + "masterbat", + "masterbat3", + "motherfucker", + "s.o.b.", + "mofo", + "nazi", + "nigga", + "nigger", + "nutsack", + "phuck", + "pimpis", + "pusse", + "pussy", + "scrotum", + "sh!t", + "shemale", + "shi+", + "sh!+", + "slut", + "smut", + "teets", + "tits", + "boobs", + "b00bs", + "teez", + "testical", + "testicle", + "titt", + "w00se", + "jackoff", + "wank", + "whoar", + "whore", + "damn", + "dyke", + "fuck", + "shit", + "@$$", + "amcik", + "andskota", + "arse", + "assrammer", + "ayir", + "bi7ch", + "bitch", + "bollock", + "breasts", + "butt-pirate", + "cabron", + "cazzo", + "chraa", + "chuj", + "Cock", + "cunt", + "d4mn", + "daygo", + "dego", + "dick", + "dike", + "dupa", + "dziwka", + "ejackulate", + "Ekrem", + "Ekto", + "enculer", + "faen", + "fag", + "fanculo", + "fanny", + "feces", + "feg", + "Felcher", + "ficken", + "fitt", + "Flikker", + "foreskin", + "Fotze", + "Fu", + "fuk", + "futkretzn", + "gook", + "guiena", + "h0r", + "h4x0r", + "helvete", + "hoer", + "honkey", + "Huevon", + "hui", + "injun", + "jizz", + "kanker", + "kike", + "klootzak", + "kraut", + "knulle", + "kuk", + "kuksuger", + "Kurac", + "kurwa", + "kusi", + "kyrpa", + "lesbo", + "mamhoon", + "masturbat", + "merd", + "mibun", + "monkleigh", + "mouliewop", + "muie", + "mulkku", + "muschi", + "nazis", + "nepesaurio", + "nigger", + "orospu", + "paska", + "perse", + "picka", + "pierdol", + "pillu", + "pimmel", + "piss", + "pizda", + "poontsee", + "poop", + "porn", + "p0rn", + "pr0n", + "preteen", + "pula", + "pule", + "puta", + "puto", + "qahbeh", + "queef", + "rautenberg", + "schaffer", + "scheiss", + "schlampe", + "schmuck", + "screw", + "sh!t", + "sharmuta", + "sharmute", + "shipal", + "shiz", + "skribz", + "skurwysyn", + "sphencter", + "spic", + "spierdalaj", + "splooge", + "suka", + "b00b", + "testicle", + "titt", + "twat", + "vittu", + "wank", + "wetback", + "wichser", + "wop", + "yed", + "zabourah", ], }; diff --git a/src/assets/lists/programNames.static.ts b/src/assets/lists/programNames.static.ts index 92e5bf82..72553a8f 100644 --- a/src/assets/lists/programNames.static.ts +++ b/src/assets/lists/programNames.static.ts @@ -1,84 +1,84 @@ export const ProgramNames = { programAttributes: [ { - status: 'Google Chrome', - type: 'browser', + status: "Google Chrome", + type: "browser", locale: { - en: 'Chrome', - de: 'Chrome', - gr: 'Κρόουμ', + en: "Chrome", + de: "Chrome", + gr: "Κρόουμ", }, }, { - status: 'Spotify', - type: 'music', + status: "Spotify", + type: "music", locale: { - en: '♫', - de: '♫', - gr: '♫', + en: "♫", + de: "♫", + gr: "♫", }, }, { - status: 'Visual Studio Code', - type: 'code', + status: "Visual Studio Code", + type: "code", locale: { - en: 'VSCode', - de: 'VSCode', - gr: 'VSCode', + en: "VSCode", + de: "VSCode", + gr: "VSCode", }, }, { - status: 'Code', - type: 'code', + status: "Code", + type: "code", locale: { - en: 'VSCode', - de: 'VSCode', - gr: 'VSCode', + en: "VSCode", + de: "VSCode", + gr: "VSCode", }, }, { - status: 'VSCode', - type: 'code', + status: "VSCode", + type: "code", locale: { - en: 'VSCode', - de: 'VSCode', - gr: 'VSCode', + en: "VSCode", + de: "VSCode", + gr: "VSCode", }, }, { - status: 'IntelliJ IDEA', - type: 'code', + status: "IntelliJ IDEA", + type: "code", locale: { - en: 'IntelliJ IDEA', - de: 'IntelliJ IDEA', - gr: 'ΈξυπνοΤζει ΙΔΕΑ', + en: "IntelliJ IDEA", + de: "IntelliJ IDEA", + gr: "ΈξυπνοΤζει ΙΔΕΑ", }, }, { - status: 'Sublime Text', - type: 'code', + status: "Sublime Text", + type: "code", locale: { - en: 'Sublime Tex', - de: 'Sublime Tex', - gr: 'Πανέμορφο Κείμενο', + en: "Sublime Tex", + de: "Sublime Tex", + gr: "Πανέμορφο Κείμενο", }, }, { - status: 'Mozilla Firefox', - type: 'code', + status: "Mozilla Firefox", + type: "code", locale: { - en: 'Firefox', - de: 'Firefox', - gr: 'Πυραλεπού', + en: "Firefox", + de: "Firefox", + gr: "Πυραλεπού", }, }, { - status: 'Discord', - type: 'chat', + status: "Discord", + type: "chat", locale: { - en: 'Discord', - de: 'Discord', - gr: 'Ντίσκορντ', + en: "Discord", + de: "Discord", + gr: "Ντίσκορντ", }, }, ], diff --git a/src/blueprints/attribute.blueprint.ts b/src/blueprints/attribute.blueprint.ts index d7bff594..72fc363f 100644 --- a/src/blueprints/attribute.blueprint.ts +++ b/src/blueprints/attribute.blueprint.ts @@ -1,21 +1,46 @@ -import { BaseGuildTextChannel, GuildMember, OverwriteType, Role } from 'discord.js'; - -import { getKeyFromEnum, isMod } from '../libraries/help.library.js'; -import { updateGuild, updateMember, updatePortal, updateVoice } from '../libraries/mongo.library.js'; -import { PGuild } from '../types/classes/PGuild.class.js'; -import { PMember } from '../types/classes/PMember.class.js'; -import { PChannel } from '../types/classes/PPortalChannel.class.js'; -import { Blueprint, ReturnPromise } from '../types/classes/PTypes.interface.js'; -import { PVoiceChannel } from '../types/classes/PVoiceChannel.class.js'; -import { AuthType } from '../types/enums/Admin.enum.js'; -import { Locale, LocaleList } from '../types/enums/Locales.enum.js'; -import { ProfanityLevel, ProfanityLevelList } from '../types/enums/ProfanityLevel.enum.js'; -import { RankSpeed } from '../types/enums/RankSpeed.enum.js'; - -function getResponse(response: boolean, category: string[], attribute: string, value: string | number) { +import { + type BaseGuildTextChannel, + type GuildMember, + OverwriteType, + Role, +} from "npm:discord.js"; + +import { getKeyFromEnum, isMod } from "../libraries/help.library.ts"; +import { + updateGuild, + updateMember, + updatePortal, + updateVoice, +} from "../libraries/mongo.library.ts"; +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import type { PMember } from "../types/classes/PMember.class.ts"; +import type { PChannel } from "../types/classes/PPortalChannel.class.ts"; +import type { + Blueprint, + ReturnPromise, +} from "../types/classes/PTypes.interface.ts"; +import type { PVoiceChannel } from "../types/classes/PVoiceChannel.class.ts"; +import { AuthType } from "../types/enums/Admin.enum.ts"; +import { Locale, LocaleList } from "../types/enums/Locales.enum.ts"; +import { + ProfanityLevel, + ProfanityLevelList, +} from "../types/enums/ProfanityLevel.enum.ts"; +import { RankSpeed } from "../types/enums/RankSpeed.enum.ts"; + +function getResponse( + response: boolean, + category: string[], + attribute: string, + value: string | number, +) { const responseValue = response - ? `attribute ${category.join('.') + '.' + attribute} set successfully to \`${value}\`` - : `attribute ${category.join('.') + '.' + attribute} failed to be set to \`${value}\``; + ? `attribute ${ + category.join(".") + "." + attribute + } set successfully to \`${value}\`` + : `attribute ${ + category.join(".") + "." + attribute + } failed to be set to \`${value}\``; return { result: response, @@ -24,34 +49,53 @@ function getResponse(response: boolean, category: string[], attribute: string, v } async function updatePortalChannelAttribute( - pGuildId: PGuild['id'], - pChannelIdl: PChannel['id'], + pGuildId: PGuild["id"], + pChannelIdl: PChannel["id"], category: string[], attribute: string, value: string | number, ) { - const sanitisedValue = value === 'true' ? true : value === 'false' ? false : value; - const response = await updatePortal(pGuildId, pChannelIdl, attribute, sanitisedValue); + const sanitisedValue = value === "true" + ? true + : value === "false" + ? false + : value; + const response = await updatePortal( + pGuildId, + pChannelIdl, + attribute, + sanitisedValue, + ); return getResponse(response, category, attribute, value); } async function updateVoiceChannelAttribute( - pGuildId: PGuild['id'], - pChannelId: PChannel['id'], - pVoiceChannelId: PVoiceChannel['id'], + pGuildId: PGuild["id"], + pChannelId: PChannel["id"], + pVoiceChannelId: PVoiceChannel["id"], category: string[], attribute: string, value: string, ) { - const sanitisedValue = value === 'true' ? true : value === 'false' ? false : value; - const response = await updateVoice(pGuildId, pChannelId, pVoiceChannelId, attribute, sanitisedValue); + const sanitisedValue = value === "true" + ? true + : value === "false" + ? false + : value; + const response = await updateVoice( + pGuildId, + pChannelId, + pVoiceChannelId, + attribute, + sanitisedValue, + ); return getResponse(response, category, attribute, value); } async function updateGuildAttribute( - pGuildId: PGuild['id'], + pGuildId: PGuild["id"], category: string[], attribute: keyof PGuild, value: string | number, @@ -62,8 +106,8 @@ async function updateGuildAttribute( } async function updateMemberAttribute( - pGuildId: PGuild['id'], - pMemberId: PMember['id'], + pGuildId: PGuild["id"], + pMemberId: PMember["id"], category: string[], attribute: string, value: string | number, @@ -75,183 +119,238 @@ async function updateMemberAttribute( export const AttributeBlueprints: Blueprint[] = [ { - name: 'p.annAnnounce', - hover: 'if voice channels spawned by portal channel will make announcements', + name: "p.annAnnounce", + hover: + "if voice channels spawned by portal channel will make announcements", get: ({ pVoiceChannel, pChannels }): boolean | string => { if (!pVoiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } for (let i = 0; i < pChannels.length; i++) { - if (pChannels[i].pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)) { + if ( + pChannels[i].pVoiceChannels.some((voice) => + voice.id === pVoiceChannel.id + ) + ) { return pChannels[i].annAnnounce; } } - return 'N/A'; + return "N/A"; }, set: async ({ pChannel, pGuild }, value): Promise => { - const category = ['p']; - const attribute = 'annAnnounce'; + const category = ["p"]; + const attribute = "annAnnounce"; if (!pGuild || !pChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, value); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.portal, + auth: AuthType.PORTAL, }, { - name: 'v.annAnnounce', - hover: 'if voice channel will make announcements', + name: "v.annAnnounce", + hover: "if voice channel will make announcements", get: ({ pVoiceChannel }): boolean | string => { if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } return pVoiceChannel.annAnnounce; }, - set: async ({ pVoiceChannel, pChannel, pGuild }, value): Promise => { - const category = ['v']; - const attribute = 'annAnnounce'; + set: async ( + { pVoiceChannel, pChannel, pGuild }, + value, + ): Promise => { + const category = ["v"]; + const attribute = "annAnnounce"; if (!pGuild || !pChannel || !pVoiceChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updateVoiceChannelAttribute(pGuild.id, pChannel.id, pVoiceChannel.id, category, attribute, value); + return await updateVoiceChannelAttribute( + pGuild.id, + pChannel.id, + pVoiceChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, { - name: 'p.noBots', - hover: 'if bots can join voice channels spawned by portal channel', + name: "p.noBots", + hover: "if bots can join voice channels spawned by portal channel", get: ({ pVoiceChannel, pChannels }): boolean | string => { if (!pVoiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } for (const pChannel of pChannels) { - const voiceChannel = pChannel.pVoiceChannels.find((voice) => voice.id === pVoiceChannel.id); + const voiceChannel = pChannel.pVoiceChannels.find((voice) => + voice.id === pVoiceChannel.id + ); if (voiceChannel) { return voiceChannel.noBots; } } - return 'N/A'; + return "N/A"; }, set: async ({ pChannel, pGuild }, value): Promise => { - const category = ['p']; - const attribute = 'noBots'; + const category = ["p"]; + const attribute = "noBots"; if (!pGuild || !pChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, value); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.portal, + auth: AuthType.PORTAL, }, { - name: 'v.noBots', - hover: 'if bots can join voice channel', + name: "v.noBots", + hover: "if bots can join voice channel", get: ({ pVoiceChannel }): boolean | string => { if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } return pVoiceChannel?.noBots ?? false; }, - set: async ({ pVoiceChannel, pChannel, pGuild }, value): Promise => { - const category = ['v']; - const attribute = 'noBots'; + set: async ( + { pVoiceChannel, pChannel, pGuild }, + value, + ): Promise => { + const category = ["v"]; + const attribute = "noBots"; if (!pGuild || !pChannel || !pVoiceChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updateVoiceChannelAttribute(pGuild.id, pChannel.id, pVoiceChannel.id, category, attribute, value); + return await updateVoiceChannelAttribute( + pGuild.id, + pChannel.id, + pVoiceChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, { - name: 'p.allowedRoles', - hover: 'the role allowed to create a voice channel', + name: "p.allowedRoles", + hover: "the role allowed to create a voice channel", get: ({ voiceChannel, pVoiceChannel, pChannels }): string[] | string => { if (!pVoiceChannel || !voiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel) { - const channel = voiceChannel.guild.channels.cache.find((c) => c.id === pChannel.id) as BaseGuildTextChannel; + const channel = voiceChannel.guild.channels.cache.find( + (c) => c.id === pChannel.id, + ) as BaseGuildTextChannel; if (channel && channel.permissionOverwrites.cache.size > 0) { - return `${channel.permissionOverwrites.cache - .filter((p) => p.type === OverwriteType.Role) - .filter((p) => p.allow.bitfield === BigInt(1048576)) - .map((p) => { - const role = voiceChannel.guild.roles.cache.find((r) => r.id === p.id); - - if (role) { - return `${role.name}`; - } else { - return 'N/A'; - } - }) - .join(', ')}`; + return `${ + channel.permissionOverwrites.cache + .filter((p) => p.type === OverwriteType.Role) + .filter((p) => p.allow.bitfield === BigInt(1048576)) + .map((p) => { + const role = voiceChannel.guild.roles.cache.find((r) => + r.id === p.id + ); + + if (role) { + return `${role.name}`; + } else { + return "N/A"; + } + }) + .join(", ") + }`; } } - return '@everyone'; + return "@everyone"; }, - set: async (): Promise => { - return { + set: (): Promise => { + return Promise.resolve({ result: false, - value: 'not yet implemented', - }; + value: "not yet implemented", + }); // const category = ['p']; // const attribute = 'allowedRoles'; @@ -331,17 +430,19 @@ export const AttributeBlueprints: Blueprint[] = [ // value: `attribute ${category.join('.') + '.' + attribute} can only be one or more roles`, // }); }, - auth: AuthType.portal, + auth: AuthType.PORTAL, }, { - name: 'p.v.allowedRoles', - hover: 'the role given to the spawned voice channels', + name: "p.v.allowedRoles", + hover: "the role given to the spawned voice channels", get: ({ voiceChannel, pVoiceChannel, pChannels }): string[] | string => { if (!pVoiceChannel || !voiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel && pChannel.allowedRoles) { const allowedRoles = voiceChannel.guild.roles.cache.filter((r) => { @@ -353,18 +454,18 @@ export const AttributeBlueprints: Blueprint[] = [ }); if (allowedRoles) { - return `${allowedRoles.map((r) => r.name).join(', ')}`; + return `${allowedRoles.map((r) => r.name).join(", ")}`; } else { - return 'N/A'; + return "N/A"; } } - return '@everyone'; + return "@everyone"; }, set: async (): Promise => { return { result: false, - value: 'not yet implemented', + value: "not yet implemented", }; // const category = ['p', 'v']; @@ -424,38 +525,45 @@ export const AttributeBlueprints: Blueprint[] = [ // } // }); }, - auth: AuthType.portal, + auth: AuthType.PORTAL, }, { - name: 'v.allowedRoles', - hover: 'the role allowed join the voice channel', + name: "v.allowedRoles", + hover: "the role allowed join the voice channel", get: ({ voiceChannel, pVoiceChannel }): string[] | string => { if (!pVoiceChannel || !voiceChannel) { - return 'N/A'; + return "N/A"; } - if (!pVoiceChannel || !voiceChannel || voiceChannel.permissionOverwrites.cache.size > 0) { - return `${voiceChannel.permissionOverwrites.cache - .filter((p) => p.type === OverwriteType.Role) - .filter((p) => p.allow.bitfield === BigInt(1048576)) - .map((p) => { - const role = voiceChannel.guild.roles.cache.find((r) => r.id === p.id); + if ( + !pVoiceChannel || !voiceChannel || + voiceChannel.permissionOverwrites.cache.size > 0 + ) { + return `${ + voiceChannel.permissionOverwrites.cache + .filter((p) => p.type === OverwriteType.Role) + .filter((p) => p.allow.bitfield === BigInt(1048576)) + .map((p) => { + const role = voiceChannel.guild.roles.cache.find((r) => + r.id === p.id + ); - if (role) { - return `${role.name}`; - } else { - return 'N/A'; - } - }) - .join(', ')}`; + if (role) { + return `${role.name}`; + } else { + return "N/A"; + } + }) + .join(", ") + }`; } - return '@everyone'; + return "@everyone"; }, set: async (): Promise => { return { result: false, - value: 'not yet implemented', + value: "not yet implemented", }; // const category = ['v']; @@ -525,163 +633,207 @@ export const AttributeBlueprints: Blueprint[] = [ // value: `attribute ${category.join('.') + '.' + attribute} can only be one or more roles`, // }); }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, { - name: 'p.render', - hover: 'if voice channels spawned by portal channel will use the text interpreter', + name: "p.render", + hover: + "if voice channels spawned by portal channel will use the text interpreter", get: ({ pVoiceChannel, pChannels }): boolean | string => { if (!pVoiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel) { return pChannel.render; } - return 'N/A'; + return "N/A"; }, set: async ({ pChannel, pGuild }, value): Promise => { - const category = ['p']; - const attribute = 'render'; + const category = ["p"]; + const attribute = "render"; if (!pGuild || !pChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, value); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.portal, + auth: AuthType.PORTAL, }, { - name: 'v.render', - hover: 'if voice channel will use the text interpreter', + name: "v.render", + hover: "if voice channel will use the text interpreter", get: ({ pVoiceChannel }): boolean | string => { if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } return pVoiceChannel.render; }, - set: async ({ pVoiceChannel, pChannel, pGuild }, value): Promise => { - const category = ['v']; - const attribute = 'render'; + set: async ( + { pVoiceChannel, pChannel, pGuild }, + value, + ): Promise => { + const category = ["v"]; + const attribute = "render"; if (!pGuild || !pChannel || !pVoiceChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, value); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, { - name: 'p.annUser', - hover: 'if voice channels spawned by portal channel will make join/leave announcements', + name: "p.annUser", + hover: + "if voice channels spawned by portal channel will make join/leave announcements", get: ({ pVoiceChannel, pChannels }): boolean | string => { if (!pVoiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel) { return pChannel.annUser; } - return 'N/A'; + return "N/A"; }, set: async ({ pChannel, pGuild }, value): Promise => { - const category = ['p']; - const attribute = 'annUser'; + const category = ["p"]; + const attribute = "annUser"; if (!pGuild || !pChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, value); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.portal, + auth: AuthType.PORTAL, }, { - name: 'v.annUser', - hover: 'if voice channel will make join/leave announcements', + name: "v.annUser", + hover: "if voice channel will make join/leave announcements", get: ({ pVoiceChannel }): boolean | string => { if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } return pVoiceChannel.annUser; }, - set: async ({ pVoiceChannel, pChannel, pGuild }, value): Promise => { - const category = ['v']; - const attribute = 'annUser'; + set: async ( + { pVoiceChannel, pChannel, pGuild }, + value, + ): Promise => { + const category = ["v"]; + const attribute = "annUser"; if (!pGuild || !pChannel || !pVoiceChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, value); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, { - name: 'v.bitrate', - hover: 'voice channels bitrate', + name: "v.bitrate", + hover: "voice channels bitrate", get: ({ voiceChannel }): number => { return voiceChannel?.bitrate ?? 96000; }, set: async ({ voiceChannel }, value): Promise => { - const category = ['v']; - const attribute = 'bitrate'; + const category = ["v"]; + const attribute = "bitrate"; const newBitrate = Number(value); if (!voiceChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } @@ -689,14 +841,18 @@ export const AttributeBlueprints: Blueprint[] = [ if (isNaN(newBitrate)) { return resolve({ result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **a number**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **a number**`, }); } if (newBitrate < 8000) { return resolve({ result: false, - value: `attribute ${category.join('.') + '.' + attribute} must be greater or equal to 8000`, + value: `attribute ${ + category.join(".") + "." + attribute + } must be greater or equal to 8000`, }); } @@ -705,100 +861,121 @@ export const AttributeBlueprints: Blueprint[] = [ .then((r) => { return resolve({ result: r.bitrate === newBitrate, - value: - r.bitrate === newBitrate - ? `attribute ${category.join('.') + '.' + attribute} set successfully to \`${value}\`` - : `attribute ${ - category.join('.') + '.' + attribute - } failed to be set to\`${value}\` to ${value} (is ${r.bitrate})`, + value: r.bitrate === newBitrate + ? `attribute ${ + category.join(".") + "." + attribute + } set successfully to \`${value}\`` + : `attribute ${ + category.join(".") + "." + attribute + } failed to be set to\`${value}\` to ${value} (is ${r.bitrate})`, }); }) .catch((e) => { return resolve({ result: false, - value: `attribute ${category.join('.') + '.' + attribute} failed to be set: ${e}`, + value: `attribute ${ + category.join(".") + "." + attribute + } failed to be set: ${e}`, }); }); }); }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, { - name: 'g.kickAfter', - hover: 'Portals kickAfter', + name: "g.kickAfter", + hover: "Portals kickAfter", get: ({ pGuild }): number => { return pGuild?.kickAfter ?? 1; }, set: async ({ pGuild, interaction }, value): Promise => { - const category = ['g']; - const attribute = 'kickAfter'; + const category = ["g"]; + const attribute = "kickAfter"; if (!pGuild || !interaction) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } if (!isMod(interaction.member as GuildMember | null)) { return { result: false, - value: `you must be a Portal moderator to set attribute ${category.join('.') + '.' + attribute}`, + value: `you must be a Portal moderator to set attribute ${ + category.join(".") + "." + attribute + }`, }; } if (isNaN(Number(value))) { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} has to be a number`, + value: `attribute ${ + category.join(".") + "." + attribute + } has to be a number`, }; } - return await updateGuildAttribute(pGuild.id, category, attribute, Number(value)); + return await updateGuildAttribute( + pGuild.id, + category, + attribute, + Number(value), + ); }, - auth: AuthType.admin, + auth: AuthType.ADMIN, }, { - name: 'g.banAfter', - hover: 'Portals banAfter', + name: "g.banAfter", + hover: "Portals banAfter", get: ({ pGuild }): number => { return pGuild?.banAfter ?? 1; }, set: async ({ pGuild, interaction }, value): Promise => { - const category = ['g']; - const attribute = 'banAfter'; + const category = ["g"]; + const attribute = "banAfter"; if (!pGuild || !interaction) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } if (!isMod(interaction.member as GuildMember | null)) { return { result: false, - value: `you must be a Portal moderator to set attribute ${category.join('.') + '.' + attribute}`, + value: `you must be a Portal moderator to set attribute ${ + category.join(".") + "." + attribute + }`, }; } if (isNaN(Number(value))) { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} has to be a number`, + value: `attribute ${ + category.join(".") + "." + attribute + } has to be a number`, }; } - return await updateGuildAttribute(pGuild.id, category, attribute, Number(value)); + return await updateGuildAttribute( + pGuild.id, + category, + attribute, + Number(value), + ); }, - auth: AuthType.admin, + auth: AuthType.ADMIN, }, { - name: 'g.muteRole', - hover: 'role given to muted members', + name: "g.muteRole", + hover: "role given to muted members", get: ({ guild, pGuild }): string => { if (!guild) { - return 'N/A'; + return "N/A"; } const muteRole = guild.roles.cache.find((r) => r.id === pGuild?.muteRole); @@ -807,51 +984,56 @@ export const AttributeBlueprints: Blueprint[] = [ return muteRole.name; } - return 'N/A'; + return "N/A"; }, set: async ({ pGuild, interaction }, value): Promise => { - const category = ['g']; - const attribute = 'muteRole'; + const category = ["g"]; + const attribute = "muteRole"; if (!pGuild || !interaction) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } if (!(value instanceof Role)) { return Promise.resolve({ result: false, - value: 'value must be Role', + value: "value must be Role", }); } - return await updateGuildAttribute(pGuild.id, category, attribute, value.id); + return await updateGuildAttribute( + pGuild.id, + category, + attribute, + value.id, + ); }, - auth: AuthType.admin, + auth: AuthType.ADMIN, }, { - name: 'g.rankSpeed', - hover: 'leveling speed of members', + name: "g.rankSpeed", + hover: "leveling speed of members", get: ({ pGuild }): string => { return RankSpeed[pGuild?.rankSpeed ?? 1]; }, set: async ({ pGuild }, value): Promise => { - const category = ['g']; - const attribute = 'rankSpeed'; + const category = ["g"]; + const attribute = "rankSpeed"; if (!pGuild) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } if (value instanceof Role) { return Promise.resolve({ result: false, - value: 'value cannot be Role', + value: "value cannot be Role", }); } @@ -860,35 +1042,35 @@ export const AttributeBlueprints: Blueprint[] = [ if (!speed) { return Promise.resolve({ result: false, - value: 'value can not be assigned to rank a valid ranking speed', + value: "value can not be assigned to rank a valid ranking speed", }); } return await updateGuildAttribute(pGuild.id, category, attribute, speed); }, - auth: AuthType.admin, + auth: AuthType.ADMIN, }, { - name: 'g.profanityLevel', - hover: 'how harsh Portal will be flagging members for use of profanities', + name: "g.profanityLevel", + hover: "how harsh Portal will be flagging members for use of profanities", get: ({ pGuild }): string => { return ProfanityLevel[pGuild?.profanityLevel ?? 1]; }, set: async ({ pGuild }, value): Promise => { - const category = ['g']; - const attribute = 'profanityLevel'; + const category = ["g"]; + const attribute = "profanityLevel"; if (!pGuild) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } if (value instanceof Role) { return Promise.resolve({ result: false, - value: 'value cannot be Role', + value: "value cannot be Role", }); } @@ -897,20 +1079,22 @@ export const AttributeBlueprints: Blueprint[] = [ if (level === undefined) { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **${ProfanityLevelList.join(', ')}**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **${ProfanityLevelList.join(", ")}**`, }; } return await updateGuildAttribute(pGuild.id, category, attribute, level); }, - auth: AuthType.admin, + auth: AuthType.ADMIN, }, { - name: 'g.initialRole', - hover: 'role given to new members', + name: "g.initialRole", + hover: "role given to new members", get: ({ pGuild, guild }): string => { - if (!pGuild?.initialRole || pGuild.initialRole === 'null') { - return 'initial role has not been set yet 1'; + if (!pGuild?.initialRole || pGuild.initialRole === "null") { + return "initial role has not been set yet 1"; } const role = guild?.roles.cache.find((r) => r.id === pGuild.initialRole); @@ -918,17 +1102,17 @@ export const AttributeBlueprints: Blueprint[] = [ if (role) { return `@${role.name}`; } else { - return 'initial role has not been set yet 2'; + return "initial role has not been set yet 2"; } }, set: async ({ pGuild, interaction }, value): Promise => { - const category = ['g']; - const attribute = 'initialRole'; + const category = ["g"]; + const attribute = "initialRole"; if (!pGuild || !interaction) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } @@ -936,7 +1120,7 @@ export const AttributeBlueprints: Blueprint[] = [ return { result: false, value: `attribute ${ - category.join('.') + '.' + attribute + category.join(".") + "." + attribute } failed to be set as user guild could not be fetched`, }; } @@ -944,35 +1128,40 @@ export const AttributeBlueprints: Blueprint[] = [ if (!(value instanceof Role)) { return Promise.resolve({ result: false, - value: 'value must be Role', + value: "value must be Role", }); } - return await updateGuildAttribute(pGuild.id, category, attribute, value.id); + return await updateGuildAttribute( + pGuild.id, + category, + attribute, + value.id, + ); }, - auth: AuthType.admin, + auth: AuthType.ADMIN, }, { - name: 'g.locale', - hover: 'Portals locale', + name: "g.locale", + hover: "Portals locale", get: ({ pGuild }): string => { return Locale[pGuild?.locale ?? 1]; }, set: async ({ pGuild }, value): Promise => { - const category = ['g']; - const attribute = 'locale'; + const category = ["g"]; + const attribute = "locale"; if (value instanceof Role) { return Promise.resolve({ result: false, - value: 'value cannot be Role', + value: "value cannot be Role", }); } if (!pGuild) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } @@ -981,45 +1170,53 @@ export const AttributeBlueprints: Blueprint[] = [ if (locale === undefined) { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **${LocaleList.join(', ')}**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **${ + LocaleList.join( + ", ", + ) + }**`, }; } return await updateGuildAttribute(pGuild.id, category, attribute, locale); }, - auth: AuthType.admin, + auth: AuthType.ADMIN, }, { - name: 'p.locale', - hover: 'portal channels locale', + name: "p.locale", + hover: "portal channels locale", get: ({ pVoiceChannel, pChannels }): string => { if (!pVoiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel) { return Locale[pChannel.locale]; } - return 'N/A'; + return "N/A"; }, set: async ({ pChannel, pGuild }, value): Promise => { - const category = ['p']; - const attribute = 'locale'; + const category = ["p"]; + const attribute = "locale"; if (value instanceof Role) { return Promise.resolve({ result: false, - value: 'value cannot be Role', + value: "value cannot be Role", }); } if (!pGuild || !pChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } @@ -1028,39 +1225,54 @@ export const AttributeBlueprints: Blueprint[] = [ if (locale === undefined) { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **${LocaleList.join(', ')}**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **${ + LocaleList.join( + ", ", + ) + }**`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, locale); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + locale, + ); }, - auth: AuthType.portal, + auth: AuthType.PORTAL, }, { - name: 'v.locale', - hover: 'voice channels locale', + name: "v.locale", + hover: "voice channels locale", get: ({ pVoiceChannel }): string => { if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } return Locale[pVoiceChannel?.locale ?? 1]; }, - set: async ({ pVoiceChannel, pChannel, pGuild }, value): Promise => { - const category = ['v']; - const attribute = 'locale'; + set: async ( + { pVoiceChannel, pChannel, pGuild }, + value, + ): Promise => { + const category = ["v"]; + const attribute = "locale"; if (value instanceof Role) { return Promise.resolve({ result: false, - value: 'value cannot be Role', + value: "value cannot be Role", }); } if (!pGuild || !pChannel || !pVoiceChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } @@ -1069,262 +1281,322 @@ export const AttributeBlueprints: Blueprint[] = [ if (locale === undefined) { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **${LocaleList.join(', ')}**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **${ + LocaleList.join( + ", ", + ) + }**`, }; } return await updateGuildAttribute(pGuild.id, category, attribute, locale); }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, { - name: 'v.position', - hover: 'voice channels position in Discord', + name: "v.position", + hover: "voice channels position in Discord", get: ({ voiceChannel }): number | string => { if (!voiceChannel) { - return 'N/A'; + return "N/A"; } return voiceChannel.position; }, set: async ({ voiceChannel }, value): Promise => { - const category = ['v']; - const attribute = 'position'; + const category = ["v"]; + const attribute = "position"; if (!voiceChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } if (isNaN(Number(value))) { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **a number**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **a number**`, }; } - const updatedVoiceChannel = await voiceChannel.edit({ position: Number(value) }); + const updatedVoiceChannel = await voiceChannel.edit({ + position: Number(value), + }); return { result: updatedVoiceChannel.position === Number(value), - value: - updatedVoiceChannel.position === Number(value) - ? `attribute ${category.join('.') + '.' + attribute} set successfully to \`${value}\`` - : `attribute ${ - category.join('.') + '.' + attribute - } failed to be set to\`${value}\` to ${value} (is ${updatedVoiceChannel.position})`, + value: updatedVoiceChannel.position === Number(value) + ? `attribute ${ + category.join(".") + "." + attribute + } set successfully to \`${value}\`` + : `attribute ${ + category.join(".") + "." + attribute + } failed to be set to\`${value}\` to ${value} (is ${updatedVoiceChannel.position})`, }; }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, { - name: 'p.regexOverwrite', - hover: 'whether voice channels spawned from portal channel will let users use their own regex', + name: "p.regexOverwrite", + hover: + "whether voice channels spawned from portal channel will let users use their own regex", get: ({ pVoiceChannel, pChannels }): boolean | string => { if (!pVoiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel) { return pChannel.regexOverwrite; } - return 'N/A'; + return "N/A"; }, set: async ({ pChannel, pGuild }, value): Promise => { - const category = ['p']; - const attribute = 'regexOverwrite'; + const category = ["p"]; + const attribute = "regexOverwrite"; if (!pGuild || !pChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, value); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, { - name: 'p.regex', - hover: 'portal channels regex', + name: "p.regex", + hover: "portal channels regex", get: ({ pVoiceChannel, pChannels }): string => { if (!pVoiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel) { return pChannel.regexPortal; } - return 'N/A'; + return "N/A"; }, set: async ({ pChannel, pGuild }, value): Promise => { - const category = ['p']; - const attribute = 'regexPortal'; + const category = ["p"]; + const attribute = "regexPortal"; if (!pGuild || !pChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, value); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.portal, + auth: AuthType.PORTAL, }, { - name: 'p.v.regex', - hover: 'voice channels spawned by portal channel regex', + name: "p.v.regex", + hover: "voice channels spawned by portal channel regex", get: ({ pVoiceChannel, pChannels }): string => { if (!pVoiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel) { return pChannel.regexVoice; } - return 'N/A'; + return "N/A"; }, set: async ({ pChannel, pGuild }, value): Promise => { - const category = ['p', 'v']; - const attribute = 'regexVoice'; + const category = ["p", "v"]; + const attribute = "regexVoice"; if (!pGuild || !pChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } - if (value !== 'true' && value !== 'false') { + if (value !== "true" && value !== "false") { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can only be **true or false**`, + value: `attribute ${ + category.join(".") + "." + attribute + } can only be **true or false**`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, value); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.portal, + auth: AuthType.PORTAL, }, { - name: 'v.regex', - hover: 'voice channels regex', + name: "v.regex", + hover: "voice channels regex", get: ({ pVoiceChannel }): string => { if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } return pVoiceChannel.regex; }, - set: async ({ pVoiceChannel, pChannel, pGuild }, value): Promise => { - const category = ['v']; - const attribute = 'regex'; + set: async ( + { pVoiceChannel, pChannel, pGuild }, + value, + ): Promise => { + const category = ["v"]; + const attribute = "regex"; if (!pGuild || !pChannel || !pVoiceChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } if (value instanceof Role) { return Promise.resolve({ result: false, - value: 'value cannot be Role', + value: "value cannot be Role", }); } - return await updateVoiceChannelAttribute(pGuild.id, pChannel.id, pVoiceChannel.id, category, attribute, value); + return await updateVoiceChannelAttribute( + pGuild.id, + pChannel.id, + pVoiceChannel.id, + category, + attribute, + value, + ); }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, { - name: 'm.regex', - hover: 'members regex', + name: "m.regex", + hover: "members regex", get: ({ pMember }): string => { - return pMember && pMember.regex ? pMember.regex : 'not-set'; + return pMember && pMember.regex ? pMember.regex : "not-set"; }, set: async ({ pGuild, pMember }, value): Promise => { - const category = ['m']; - const attribute = 'regex'; + const category = ["m"]; + const attribute = "regex"; if (!pGuild) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } if (!pMember) { return { result: false, - value: 'could not find member', + value: "could not find member", }; } if (value instanceof Role) { return Promise.resolve({ result: false, - value: 'value cannot be Role', + value: "value cannot be Role", }); } - return await updateMemberAttribute(pGuild.id, pMember.id, category, attribute, value); + return await updateMemberAttribute( + pGuild.id, + pMember.id, + category, + attribute, + value, + ); }, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'p.userLimit', - hover: 'voice channels spawned by portal channel user limit', + name: "p.userLimit", + hover: "voice channels spawned by portal channel user limit", get: ({ pVoiceChannel, pChannels }): number | string => { if (!pVoiceChannel || !pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel) { return pChannel.userLimitPortal; } - return 'N/A'; + return "N/A"; }, set: async ({ pChannel, pGuild }, value): Promise => { - const category = ['p']; - const attribute = 'userLimitPortal'; + const category = ["p"]; + const attribute = "userLimitPortal"; const newUserLimit = Number(value); if (!pGuild || !pChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } @@ -1332,7 +1604,7 @@ export const AttributeBlueprints: Blueprint[] = [ return { result: false, value: `attribute ${ - category.join('.') + '.' + attribute + category.join(".") + "." + attribute } can only be **a number from 0-99 (0 means unlimited)**`, }; } @@ -1340,33 +1612,41 @@ export const AttributeBlueprints: Blueprint[] = [ if (newUserLimit < 0) { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} can be a number from 0-n (0 means unlimited)`, + value: `attribute ${ + category.join(".") + "." + attribute + } can be a number from 0-n (0 means unlimited)`, }; } - return await updatePortalChannelAttribute(pGuild.id, pChannel.id, category, attribute, newUserLimit); + return await updatePortalChannelAttribute( + pGuild.id, + pChannel.id, + category, + attribute, + newUserLimit, + ); }, - auth: AuthType.portal, + auth: AuthType.PORTAL, }, { - name: 'v.userLimit', - hover: 'voice channels user limit', + name: "v.userLimit", + hover: "voice channels user limit", get: ({ voiceChannel }): number | string => { if (!voiceChannel) { - return 'N/A'; + return "N/A"; } return voiceChannel.userLimit; }, set: async ({ voiceChannel }, value): Promise => { - const category = ['v']; - const attribute = 'userLimit'; + const category = ["v"]; + const attribute = "userLimit"; const newUserLimit = Number(value); if (!voiceChannel) { return { result: false, - value: 'values are missing from request', + value: "values are missing from request", }; } @@ -1374,7 +1654,7 @@ export const AttributeBlueprints: Blueprint[] = [ return { result: false, value: `attribute ${ - category.join('.') + '.' + attribute + category.join(".") + "." + attribute } can only be **a number from 0-n (0 means unlimited)**`, }; } @@ -1384,18 +1664,23 @@ export const AttributeBlueprints: Blueprint[] = [ if (!updatedVoiceChannel) { return { result: false, - value: `attribute ${category.join('.') + '.' + attribute} failed to be set`, + value: `attribute ${ + category.join(".") + "." + attribute + } failed to be set`, }; } return { result: updatedVoiceChannel.userLimit === newUserLimit, - value: - updatedVoiceChannel.userLimit === newUserLimit - ? `attribute ${category.join('.') + '.' + attribute} set successfully to \`${value}\`` - : `attribute ${category.join('.') + '.' + attribute} failed to be set to \`${value}\``, + value: updatedVoiceChannel.userLimit === newUserLimit + ? `attribute ${ + category.join(".") + "." + attribute + } set successfully to \`${value}\`` + : `attribute ${ + category.join(".") + "." + attribute + } failed to be set to \`${value}\``, }; }, - auth: AuthType.voice, + auth: AuthType.VOICE, }, ]; diff --git a/src/blueprints/pipe.blueprint.ts b/src/blueprints/pipe.blueprint.ts index fae45d8c..026c5393 100644 --- a/src/blueprints/pipe.blueprint.ts +++ b/src/blueprints/pipe.blueprint.ts @@ -1,210 +1,223 @@ -import voca from 'voca'; -import { Blueprint } from '../types/classes/PTypes.interface.js'; -import { AuthType } from '../types/enums/Admin.enum.js'; +import voca from "npm:voca"; +import type { Blueprint } from "../types/classes/PTypes.interface.ts"; +import { AuthType } from "../types/enums/Admin.enum.ts"; export const PipeBlueprints: Blueprint[] = [ { - name: 'acronym', - hover: 'make acronym', + name: "acronym", + hover: "make acronym", get: ({ string: str }): string => { - return typeof str === 'string' - ? isAcronym(str) - ? str - : str - .replace(/[-_,.:*=+]/g, ' ') - .split(' ') - .map((s) => s[0]) - .join('') - : typeof str === 'object' - ? str - .map((s) => - s - .replace(/[-_,.:*=+]/g, ' ') - .split(' ') - .map((sm) => (isAcronym(sm) ? sm : sm[0])) - .join(''), - ) - .join(',') - : (str ?? ''); + return typeof str === "string" + ? isAcronym(str) ? str : str + .replace(/[-_,.:*=+]/g, " ") + .split(" ") + .map((s) => s[0]) + .join("") + : typeof str === "object" + ? str + .map((s) => + s + .replace(/[-_,.:*=+]/g, " ") + .split(" ") + .map((sm) => (isAcronym(sm) ? sm : sm[0])) + .join("") + ) + .join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'vowels', - hover: 'keep only vowels', + name: "vowels", + hover: "keep only vowels", get: ({ string: str }): string => { - return typeof str === 'string' - ? getVowels(str).join('') - : typeof str === 'object' - ? str.map((s) => getVowels(s).join('')).join(',') - : (str ?? ''); + return typeof str === "string" + ? getVowels(str).join("") + : typeof str === "object" + ? str.map((s) => getVowels(s).join("")).join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'consonants', - hover: 'keep only consonants', + name: "consonants", + hover: "keep only consonants", get: ({ string: str }): string => { - return typeof str === 'string' - ? getConstants(str).join('') - : typeof str === 'object' - ? str.map((s) => getConstants(s).join('')).join(',') - : (str ?? ''); + return typeof str === "string" + ? getConstants(str).join("") + : typeof str === "object" + ? str.map((s) => getConstants(s).join("")).join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'camelCase', - hover: 'make to camel Case', + name: "camelCase", + hover: "make to camel Case", get: ({ string: str }): string => { - return typeof str === 'string' + return typeof str === "string" ? voca.camelCase(str) - : typeof str === 'object' - ? str.map((s) => voca.camelCase(s)).join(',') - : (str ?? ''); + : typeof str === "object" + ? str.map((s) => voca.camelCase(s)).join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'capitalise', - hover: 'make first characters upper case', + name: "capitalise", + hover: "make first characters upper case", get: ({ string: str }): string => { - return typeof str === 'string' + return typeof str === "string" ? voca.capitalize(str) - : typeof str === 'object' - ? str.map((s) => voca.capitalize(s)).join(',') - : (str ?? ''); + : typeof str === "object" + ? str.map((s) => voca.capitalize(s)).join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'decapitalise', - hover: 'make first characters lower case', + name: "decapitalise", + hover: "make first characters lower case", get: ({ string: str }): string => { - return typeof str === 'string' + return typeof str === "string" ? voca.decapitalize(str) - : typeof str === 'object' - ? str.map((s) => voca.decapitalize(s)).join(',') - : (str ?? ''); + : typeof str === "object" + ? str.map((s) => voca.decapitalize(s)).join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'lowerCase', - hover: 'make all characters lower case', + name: "lowerCase", + hover: "make all characters lower case", get: ({ string: str }): string => { - return typeof str === 'string' + return typeof str === "string" ? voca.lowerCase(str) - : typeof str === 'object' - ? str.map((s) => voca.lowerCase(s)).join(',') - : (str ?? ''); + : typeof str === "object" + ? str.map((s) => voca.lowerCase(s)).join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'upperCase', - hover: 'make all characters upper case', + name: "upperCase", + hover: "make all characters upper case", get: ({ string: str }): string => { - return typeof str === 'string' + return typeof str === "string" ? voca.upperCase(str) - : typeof str === 'object' - ? str.map((s) => voca.upperCase(s)).join(',') - : (str ?? ''); + : typeof str === "object" + ? str.map((s) => voca.upperCase(s)).join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'populous_count', - hover: 'frequency of most popular item', + name: "populous_count", + hover: "frequency of most popular item", get: ({ string: str }): number => { - return typeof str === 'string' ? 1 : typeof str === 'object' ? mostFrequent(str, true) : (str ?? 0); + return typeof str === "string" + ? 1 + : typeof str === "object" + ? mostFrequent(str, true) + : (str ?? 0); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'populous', - hover: 'most popular item', + name: "populous", + hover: "most popular item", get: ({ string: str }): string => { - return typeof str === 'string' ? str : typeof str === 'object' ? mostFrequent(str, false) : (str ?? ''); + return typeof str === "string" + ? str + : typeof str === "object" + ? mostFrequent(str, false) + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'snakeCase', - hover: 'replace space with _', + name: "snakeCase", + hover: "replace space with _", get: ({ string: str }): string => { - return typeof str === 'string' + return typeof str === "string" ? voca.snakeCase(str) - : typeof str === 'object' - ? str.map((s) => voca.snakeCase(s)).join(',') - : (str ?? ''); + : typeof str === "object" + ? str.map((s) => voca.snakeCase(s)).join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'souvlakiCase', - hover: 'replace space with -', + name: "souvlakiCase", + hover: "replace space with -", get: ({ string: str }): string => { - return typeof str === 'string' + return typeof str === "string" ? voca.kebabCase(str) - : typeof str === 'object' - ? str.map((s) => voca.kebabCase(s)).join(',') - : (str ?? ''); + : typeof str === "object" + ? str.map((s) => voca.kebabCase(s)).join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'words', - hover: 'get the number of words', + name: "words", + hover: "get the number of words", get: ({ string: str }): number => { - return typeof str === 'string' + return typeof str === "string" ? voca.words(str).length - : typeof str === 'object' - ? voca.words(str.join(' ')).length - : (str ?? 0); + : typeof str === "object" + ? voca.words(str.join(" ")).length + : (str ?? 0); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'titleCase', - hover: 'make the first letter upper case and rest lower', + name: "titleCase", + hover: "make the first letter upper case and rest lower", get: ({ string: str }): string => { - return typeof str === 'string' + return typeof str === "string" ? voca.titleCase(str) - : typeof str === 'object' - ? str.map((s) => voca.titleCase(s)).join(',') - : (str ?? ''); + : typeof str === "object" + ? str.map((s) => voca.titleCase(s)).join(",") + : (str ?? ""); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'length', - hover: 'get length', + name: "length", + hover: "get length", get: ({ string: str }): number => { - return typeof str === 'string' ? str.length : typeof str === 'object' ? str.join(',').length : (str ?? 0); + return typeof str === "string" + ? str.length + : typeof str === "object" + ? str.join(",").length + : (str ?? 0); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, ]; -function mostFrequent(array: string[], return_number: boolean): string | number { +function mostFrequent( + array: string[], + return_number: boolean, +): string | number { if (array.length == 0) { - return 'no statuses'; + return "no statuses"; } const modeMap: { [key: string]: number } = {}; @@ -231,7 +244,7 @@ function mostFrequent(array: string[], return_number: boolean): string | number } function isAcronym(candidate: string): boolean { - const word_exp = new RegExp('\\b[A-Z]*[a-z]*[A-Z]s?\\d*[A-Z]*[\\-\\w+]\\b'); + const word_exp = new RegExp("\\b[A-Z]*[a-z]*[A-Z]s?\\d*[A-Z]*[\\-\\w+]\\b"); return word_exp.test(candidate); } diff --git a/src/blueprints/structure.blueprint.ts b/src/blueprints/structure.blueprint.ts index cc1da748..53c1597d 100644 --- a/src/blueprints/structure.blueprint.ts +++ b/src/blueprints/structure.blueprint.ts @@ -1,11 +1,11 @@ -import { Blueprint } from '../types/classes/PTypes.interface.js'; -import { AuthType } from '../types/enums/Admin.enum.js'; +import type { Blueprint } from "../types/classes/PTypes.interface.ts"; +import { AuthType } from "../types/enums/Admin.enum.ts"; export const StructureBlueprint: Blueprint[] = [ { - name: 'if', - hover: 'if statement flow control', - auth: AuthType.none, + name: "if", + hover: "if statement flow control", + auth: AuthType.NONE, get: () => undefined, set: () => undefined, }, diff --git a/src/blueprints/variable.blueprint.ts b/src/blueprints/variable.blueprint.ts index 5e09ce3f..8994f5a3 100644 --- a/src/blueprints/variable.blueprint.ts +++ b/src/blueprints/variable.blueprint.ts @@ -1,23 +1,25 @@ -import dayjs from 'dayjs'; -import calendar from 'dayjs/plugin/calendar.js'; +import dayjs from "npm:dayjs"; +import calendar from "dayjs/plugin/calendar.js"; -import { getStatusList } from '../libraries/status.library.js'; -import { Blueprint } from '../types/classes/PTypes.interface.js'; -import { AuthType } from '../types/enums/Admin.enum.js'; +import { getStatusList } from "../libraries/status.library.ts"; +import type { Blueprint } from "../types/classes/PTypes.interface.ts"; +import { AuthType } from "../types/enums/Admin.enum.ts"; export const VariableBlueprints: Blueprint[] = [ { - name: '##', - hover: 'number of voice channel with #', + name: "##", + hover: "number of voice channel with #", get: ({ pVoiceChannel, pChannels }) => { if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } if (!pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel !== undefined) { let i = 0; @@ -27,23 +29,25 @@ export const VariableBlueprints: Blueprint[] = [ }); return `#${i}`; } - return '#-'; + return "#-"; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: '#', - hover: 'number of voice channel', + name: "#", + hover: "number of voice channel", get: ({ pVoiceChannel, pChannels }) => { if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } if (!pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel !== undefined) { let i = 0; @@ -53,64 +57,66 @@ export const VariableBlueprints: Blueprint[] = [ }); return `${i}`; } - return '-'; + return "-"; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'creatorPortal', - hover: 'creator of portal channel', + name: "creatorPortal", + hover: "creator of portal channel", get: ({ pVoiceChannel, pChannels }) => { if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } if (!pChannels) { - return 'N/A'; + return "N/A"; } - const pChannel = pChannels.find((portal) => portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id)); + const pChannel = pChannels.find((portal) => + portal.pVoiceChannels.some((voice) => voice.id === pVoiceChannel.id) + ); if (pChannel !== undefined) { - return '' + pChannel.creatorId; + return "" + pChannel.creatorId; } - return '?'; + return "?"; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'creatorVoice', - hover: 'creator of voice channel', + name: "creatorVoice", + hover: "creator of voice channel", get: ({ pVoiceChannel }) => { if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } return pVoiceChannel.creatorId; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'date', - hover: 'current date', + name: "date", + hover: "current date", get: ({ pVoiceChannel }) => { dayjs.extend(calendar); if (!pVoiceChannel) { - return dayjs().subtract(10, 'days').calendar(); + return dayjs().subtract(10, "days").calendar(); } - return dayjs().subtract(10, 'days').calendar(); + return dayjs().subtract(10, "days").calendar(); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'dayNumber', - hover: 'current day in number format', + name: "dayNumber", + hover: "current day in number format", get: ({ pVoiceChannel }) => { if (!pVoiceChannel) { return dayjs().date(); @@ -119,109 +125,109 @@ export const VariableBlueprints: Blueprint[] = [ return dayjs().date(); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'dayName', - hover: 'current day in text format', + name: "dayName", + hover: "current day in text format", get: ({ pVoiceChannel }) => { if (!pVoiceChannel) { - return dayjs().format('dddd'); + return dayjs().format("dddd"); } - return dayjs().format('dddd'); + return dayjs().format("dddd"); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'monthNumber', - hover: 'current month in number format', + name: "monthNumber", + hover: "current month in number format", get: ({ pVoiceChannel }) => { if (!pVoiceChannel) { - return dayjs().format('M'); + return dayjs().format("M"); } - return dayjs().format('M'); + return dayjs().format("M"); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'monthName', - hover: 'current month in text format', + name: "monthName", + hover: "current month in text format", get: ({ pVoiceChannel }) => { if (!pVoiceChannel) { - return dayjs().startOf('month').format('MMMM'); + return dayjs().startOf("month").format("MMMM"); } - return dayjs().startOf('month').format('MMMM'); + return dayjs().startOf("month").format("MMMM"); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'year', - hover: 'current year', + name: "year", + hover: "current year", get: ({ pVoiceChannel }) => { if (!pVoiceChannel) { - return dayjs().format('yyyy'); + return dayjs().format("yyyy"); } - return dayjs().format('yyyy'); + return dayjs().format("yyyy"); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'time', - hover: 'current time', + name: "time", + hover: "current time", get: ({ pVoiceChannel }) => { if (!pVoiceChannel) { - return dayjs().format('hh:mm:ss'); + return dayjs().format("hh:mm:ss"); } - return dayjs().format('hh:mm:ss'); + return dayjs().format("hh:mm:ss"); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'hour', - hover: 'current hour', + name: "hour", + hover: "current hour", get: ({ pVoiceChannel }) => { if (!pVoiceChannel) { - return dayjs().format('hh'); + return dayjs().format("hh"); } - return dayjs().format('hh'); + return dayjs().format("hh"); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'minute', - hover: 'current minute', + name: "minute", + hover: "current minute", get: ({ pVoiceChannel }) => { if (!pVoiceChannel) { - return dayjs().format('mm'); + return dayjs().format("mm"); } - return dayjs().format('mm'); + return dayjs().format("mm"); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'second', - hover: 'current second', + name: "second", + hover: "current second", get: ({ pVoiceChannel }) => { if (!pVoiceChannel) { - return dayjs().format('ss'); + return dayjs().format("ss"); } - return dayjs().format('ss'); + return dayjs().format("ss"); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'memberActiveCount', - hover: 'number of members with status', + name: "memberActiveCount", + hover: "number of members with status", get: ({ voiceChannel }) => { - if (!voiceChannel) return 'N/A'; + if (!voiceChannel) return "N/A"; let cnt = 0; voiceChannel.members.forEach((member) => { if (member.presence?.activities !== null && !member.user.bot) { @@ -232,13 +238,13 @@ export const VariableBlueprints: Blueprint[] = [ return cnt; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'memberCount', - hover: 'number of members in channel', + name: "memberCount", + hover: "number of members in channel", get: ({ voiceChannel }) => { - if (!voiceChannel) return 'N/A'; + if (!voiceChannel) return "N/A"; let cnt = 0; voiceChannel.members.forEach((member) => { if (!member.user.bot) { @@ -249,25 +255,24 @@ export const VariableBlueprints: Blueprint[] = [ return cnt; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'memberHistory', - hover: 'all members to ever pass through channel', - get: () => - // voiceChannel: VoiceChannel | undefined | null, pVoiceChannel: PVoiceChannel | undefined | null, + name: "memberHistory", + hover: "all members to ever pass through channel", + get: () => // voiceChannel: VoiceChannel | undefined | null, pVoiceChannel: PVoiceChannel | undefined | null, // pChannels: PChannel[] | undefined | null, pGuild, guild: Guild { - return 'noYetImplemented'; + return "noYetImplemented"; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'pMembers', - hover: 'current members names', + name: "pMembers", + hover: "current members names", get: ({ voiceChannel }) => { - if (!voiceChannel) return 'N/A'; + if (!voiceChannel) return "N/A"; const pMembers: string[] = []; voiceChannel.members.forEach((member) => { pMembers.push(member.displayName); @@ -276,13 +281,13 @@ export const VariableBlueprints: Blueprint[] = [ return pMembers; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'memberWithStatus', - hover: 'names of members with statuses', + name: "memberWithStatus", + hover: "names of members with statuses", get: ({ voiceChannel }) => { - if (!voiceChannel) return 'N/A'; + if (!voiceChannel) return "N/A"; const pMembers: string[] = []; voiceChannel.members.forEach((member) => { if (member.presence?.activities !== null) { @@ -293,17 +298,17 @@ export const VariableBlueprints: Blueprint[] = [ return pMembers; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'statusCount', - hover: 'number of unique statuses', + name: "statusCount", + hover: "number of unique statuses", get: ({ voiceChannel, pVoiceChannel }) => { if (!voiceChannel) { - return 'N/A'; + return "N/A"; } if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } // can be faster @@ -312,34 +317,33 @@ export const VariableBlueprints: Blueprint[] = [ return statusList.length; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'statusHistory', - hover: 'all statuses from start', - get: () => - // voiceChannel: VoiceChannel | undefined | null, pVoiceChannel: PVoiceChannel | undefined | null, + name: "statusHistory", + hover: "all statuses from start", + get: () => // voiceChannel: VoiceChannel | undefined | null, pVoiceChannel: PVoiceChannel | undefined | null, // pChannels: PChannel[] | undefined | null, pGuild, guild: Guild { - return 'noYetImplemented'; + return "noYetImplemented"; }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, { - name: 'statusList', - hover: 'all statuses names', + name: "statusList", + hover: "all statuses names", get: ({ voiceChannel, pVoiceChannel }) => { if (!voiceChannel) { - return 'N/A'; + return "N/A"; } if (!pVoiceChannel) { - return 'N/A'; + return "N/A"; } return getStatusList(voiceChannel, pVoiceChannel); }, set: () => undefined, - auth: AuthType.none, + auth: AuthType.NONE, }, ]; diff --git a/src/commands/auth/announcement.ts b/src/commands/auth/announcement.ts index 093c9da4..3e3ad092 100644 --- a/src/commands/auth/announcement.ts +++ b/src/commands/auth/announcement.ts @@ -1,16 +1,31 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, InteractionContextType, NewsChannel, VoiceChannel } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + type ChatInputCommandInteraction, + InteractionContextType, + NewsChannel, + type VoiceChannel, +} from "npm:discord.js"; -import { deleteChannel, doesChannelHaveUsage } from '../../libraries/guild.library.js'; -import { messageHelp } from '../../libraries/help.library.js'; -import { updateGuild } from '../../libraries/mongo.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; -import { PortalChannelType } from '../../types/enums/PortalChannel.enum.js'; +import { + deleteChannel, + getChannelTypeById, +} from "../../libraries/guild.library.ts"; +import { messageHelp } from "../../libraries/help.library.ts"; +import { updateGuild } from "../../libraries/mongo.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import { PortalChannelType } from "../../types/enums/PortalChannel.enum.ts"; +import { + TextChannelType, + TextChannelTypeList, +} from "../../types/enums/TextChannelType.enum.ts"; -const COMMAND_NAME = 'announcement'; -const DESCRIPTION = 'make an announcement to the announcements channel'; +const COMMAND_NAME = "announcement"; +const DESCRIPTION = "set an announcements channel"; export default { time: 0, @@ -23,47 +38,69 @@ export default { .setDescription(DESCRIPTION) .addChannelOption((option) => option - .setName('announcement_channel') - .setDescription('the channel you want to make the announcement channel') - .setRequired(true), + .setName("announcement_channel") + .setDescription("the channel you want to make the announcement channel") + .setRequired(true) ) - .addChannelOption((option) => + .addBooleanOption((option) => option - .setName('delete_previous') - .setDescription('whether or not to delete the previous announcement channel') - .setRequired(false), + .setName("delete_previous") + .setDescription( + "whether or not to delete the previous announcement channel", + ) + .setRequired(false) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { - const announcementChannel = interaction.options.getChannel('announcement_channel'); - const deletePreviousAnnouncementChannel = interaction.options.getChannel('delete_previous'); + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + const announcementChannel = interaction.options.getChannel( + "announcement_channel", + ); + const deletePreviousAnnouncementChannel = interaction.options.getChannel( + "delete_previous", + ); if (!announcementChannel) { return { result: false, - value: messageHelp('commands', 'announcement'), + value: messageHelp("commands", "announcement"), }; } if (!(announcementChannel instanceof NewsChannel)) { return { result: false, - value: messageHelp('commands', 'announcement', 'channel must be news channel'), + value: messageHelp( + "commands", + "announcement", + "channel must be news channel", + ), }; } if (!announcementChannel.isTextBased()) { return { result: false, - value: messageHelp('commands', 'announcement', 'channel must be text channel'), + value: messageHelp( + "commands", + "announcement", + "channel must be text channel", + ), }; } - const channelHasUsage = await doesChannelHaveUsage(announcementChannel.id, pGuild); - if (channelHasUsage.result) { + const channelType = await getChannelTypeById( + announcementChannel.id, + pGuild, + ); + if (channelType !== TextChannelType.NONE) { return { result: false, - value: channelHasUsage.value, + value: `selected channel is already in use as ${ + TextChannelTypeList[channelType] + } channel`, }; } @@ -73,15 +110,25 @@ export default { ) as VoiceChannel; if (announcement) { - deleteChannel(PortalChannelType.announcement, announcement, interaction); + deleteChannel( + PortalChannelType.announcement, + announcement, + interaction, + ); } } - const response = await updateGuild(pGuild.id, 'announcement', announcementChannel.id); + const response = await updateGuild( + pGuild.id, + "announcement", + announcementChannel.id, + ); return { result: response, - value: response ? 'new announcement channel set successfully' : 'failed to set new announcement channel', + value: response + ? `**${announcementChannel.name}** set to Announcement channel.` + : "failed to set new Announcement channel ", }; }, } as Command; diff --git a/src/commands/auth/ban.ts b/src/commands/auth/ban.ts index 92ba8846..95a4eb30 100644 --- a/src/commands/auth/ban.ts +++ b/src/commands/auth/ban.ts @@ -1,13 +1,27 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { BanOptions, ButtonStyle, ChatInputCommandInteraction, GuildMember, InteractionContextType } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + type BanOptions, + ButtonStyle, + type ChatInputCommandInteraction, + type GuildMember, + InteractionContextType, +} from "npm:discord.js"; -import { askForApproval, isMod, messageHelp } from '../../libraries/help.library.js'; -import { ban } from '../../libraries/user.library.js'; -import { Command } from '../../types/Command.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { + askForApprovalByInteraction, + isMod, + messageHelp, +} from "../../libraries/help.library.ts"; +import { ban } from "../../libraries/user.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import logger from "../../utilities/log.utility.ts"; -const COMMAND_NAME = 'ban'; -const DESCRIPTION = 'ban a user'; +const COMMAND_NAME = "ban"; +const DESCRIPTION = "ban a user"; export default { time: 1, @@ -18,54 +32,69 @@ export default { slashCommand: new SlashCommandBuilder() .setName(COMMAND_NAME) .setDescription(DESCRIPTION) - .addUserOption((option) => option.setName('user_to_ban').setDescription('user to ban').setRequired(true)) - .addNumberOption((option) => option.setName('ban_days').setDescription('days to ban user for').setRequired(true)) - .addStringOption((option) => option.setName('ban_reason').setDescription('ban reason').setRequired(false)) + .addUserOption((option) => + option.setName("user_to_ban").setDescription("user to ban").setRequired( + true, + ) + ) + .addNumberOption((option) => + option.setName("ban_days").setDescription("days to ban user for") + .setRequired(true) + ) + .addStringOption((option) => + option.setName("ban_reason").setDescription("ban reason").setRequired( + false, + ) + ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction): Promise { - const memberToBan = interaction.options.getMember('user_to_ban') as GuildMember; - const banDays = interaction.options.getNumber('ban_days'); - const banReason = interaction.options.getString('ban_reason'); + async execute( + interaction: ChatInputCommandInteraction, + ): Promise { + const memberToBan = interaction.options.getMember( + "user_to_ban", + ) as GuildMember; + const banDays = interaction.options.getNumber("ban_days"); + const banReason = interaction.options.getString("ban_reason"); if (!memberToBan) { return { result: false, - value: messageHelp('commands', 'ban', 'user must be provided'), + value: messageHelp("commands", "ban", "user must be provided"), }; } if (!banDays) { return { result: false, - value: messageHelp('commands', 'ban', 'days to ban must be provided'), + value: messageHelp("commands", "ban", "days to ban must be provided"), }; } if (!interaction.member) { return { result: false, - value: 'message author could not be fetched', + value: "message author could not be fetched", }; } if (!isMod(interaction.member as GuildMember)) { return { result: false, - value: 'you must be a Portal moderator to ban users', + value: "you must be a Portal moderator to ban users", }; } if (!interaction.guild) { return { result: false, - value: 'user guild could not be fetched', + value: "user guild could not be fetched", }; } const deleteMessageDays = banDays ?? 1; - const reason = banReason ?? 'banned by admin'; + const reason = banReason ?? "banned by admin"; - const response = await askForApproval( + const response = await askForApprovalByInteraction( interaction, `*${interaction.user}, are you sure you want to ban **${memberToBan.displayName}** for **${deleteMessageDays}** days*?`, ButtonStyle.Danger, @@ -74,7 +103,7 @@ export default { if (!response) { return { result: false, - value: 'Ban approval not received', + value: "Ban approval not received", }; } @@ -93,7 +122,11 @@ export default { : `User ${memberToBan.displayName} could not be banned`, }; } catch (e) { - await interaction.editReply({ content: 'Confirmation not received within 1 minute, cancelling', components: [] }); + logger.error(`Error while banning: ${e}`); + await interaction.editReply({ + content: "Confirmation not received within 1 minute, cancelling", + components: [], + }); return { result: false, diff --git a/src/commands/auth/delete_messages.ts b/src/commands/auth/delete_messages.ts index f02b7583..eb9d7964 100644 --- a/src/commands/auth/delete_messages.ts +++ b/src/commands/auth/delete_messages.ts @@ -1,12 +1,29 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + ButtonStyle, + type ChatInputCommandInteraction, + InteractionContextType, + type TextChannel, +} from "npm:discord.js"; -import { ButtonStyle, ChatInputCommandInteraction, InteractionContextType, TextChannel } from 'discord.js'; -import { askForApproval, messageHelp } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { getChannelTypeById } from "../../libraries/guild.library.ts"; +import { + askForApprovalByInteraction, + messageHelp, +} from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import { + TextChannelType, + TextChannelTypeList, +} from "../../types/enums/TextChannelType.enum.ts"; -const COMMAND_NAME = 'delete_messages'; -const DESCRIPTION = 'delete n messages'; +const COMMAND_NAME = "delete_messages"; +const DESCRIPTION = "delete n messages"; export default { time: 1, @@ -18,34 +35,60 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .addNumberOption((option) => - option.setName('message_number').setDescription('number of messages to delete').setRequired(true), + option.setName("message_number").setDescription( + "number of messages to delete", + ).setRequired(true) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction): Promise { - const bulkDeleteLength = interaction.options.getNumber('message_number'); + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + const bulkDeleteLength = interaction.options.getNumber("message_number"); if (!bulkDeleteLength) { return { result: false, - value: messageHelp('commands', 'delete_messages', 'deleteLength must be provided'), + value: messageHelp( + "commands", + "delete_messages", + "deleteLength must be provided", + ), }; } if (bulkDeleteLength <= 0 || bulkDeleteLength > 97) { return { result: false, - value: messageHelp('commands', 'delete_messages', 'you can delete one, up-to 97 messages'), + value: messageHelp( + "commands", + "delete_messages", + "you can delete one, up-to 97 messages", + ), }; } if (!interaction.member) { return { result: false, - value: 'message author could not be fetched', + value: "message author could not be fetched", }; } - const result = await askForApproval( + const channelType = await getChannelTypeById( + interaction.channelId, + pGuild, + ); + if (channelType !== TextChannelType.NONE) { + return { + result: false, + value: `it is not allowed to delete in ${ + TextChannelTypeList[channelType] + } channels`, + }; + } + + const result = await askForApprovalByInteraction( interaction, `*${interaction.user}, are you sure you want to delete **${bulkDeleteLength}** messages*?`, ButtonStyle.Success, @@ -54,22 +97,26 @@ export default { if (!result) { return { result: false, - value: 'failed to get approval', + value: "failed to get approval", }; } - const messages = await (interaction.channel).bulkDelete(bulkDeleteLength + 1); + const messages = await ( interaction.channel).bulkDelete( + bulkDeleteLength + 1, + ); if (!messages) { return { result: false, - value: 'error while bulk delete', + value: "error while bulk delete", }; } return { result: true, - value: `User ${interaction.user.displayName}, deleted ${messages.size - 1} messages`, + value: `User ${interaction.user.displayName}, deleted ${ + messages.size - 1 + } messages`, }; }, } as Command; diff --git a/src/commands/auth/force.ts b/src/commands/auth/force.ts index b7e01e46..970ae21e 100644 --- a/src/commands/auth/force.ts +++ b/src/commands/auth/force.ts @@ -1,23 +1,41 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, GuildMember, VoiceChannel } from 'discord.js'; -import { deleteChannel, includedInVoiceList, regexInterpreter } from '../../libraries/guild.library.js'; -import { messageHelp } from '../../libraries/help.library.js'; -import { updateVoice } from '../../libraries/mongo.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { PChannel } from '../../types/classes/PPortalChannel.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; -import { PVoiceChannel } from '../../types/classes/PVoiceChannel.class.js'; -import { PortalChannelType } from '../../types/enums/PortalChannel.enum.js'; - -const COMMAND_NAME = 'force'; -const DESCRIPTION = 'force refresh your portal channel'; - -function isUserInHandledVoiceChannel(member: GuildMember, pGuild: PGuild): boolean { - return !!member.voice.channel && includedInVoiceList(member.voice.channel.id, pGuild.pChannels); +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { + ChatInputCommandInteraction, + GuildMember, + VoiceChannel, +} from "npm:discord.js"; +import { + deleteChannel, + includedInVoiceList, + regexInterpreter, +} from "../../libraries/guild.library.ts"; +import { messageHelp } from "../../libraries/help.library.ts"; +import { updateVoice } from "../../libraries/mongo.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import type { PChannel } from "../../types/classes/PPortalChannel.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import type { PVoiceChannel } from "../../types/classes/PVoiceChannel.class.ts"; +import { PortalChannelType } from "../../types/enums/PortalChannel.enum.ts"; + +const COMMAND_NAME = "force"; +const DESCRIPTION = "force refresh your portal channel"; + +function isUserInHandledVoiceChannel( + member: GuildMember, + pGuild: PGuild, +): boolean { + return !!member.voice.channel && + includedInVoiceList(member.voice.channel.id, pGuild.pChannels); } -function isChannelCreator(member: GuildMember, pVoiceChannel: PVoiceChannel): boolean { +function isChannelCreator( + member: GuildMember, + pVoiceChannel: PVoiceChannel, +): boolean { return pVoiceChannel.creatorId === member.id; } @@ -40,25 +58,43 @@ async function cloneAndUpdateVoiceChannel( const currentVoiceClone = await currentVoice.clone({ name: updatedName }); if (!currentVoiceClone) { - return { result: false, value: 'Error while cloning channel' }; + return { result: false, value: "Error while cloning channel" }; } for (const member of currentVoice.members.values()) { - member.voice?.setChannel(currentVoiceClone, 'portal force update').catch(() => { - return { result: false, value: `Failed to move user ${member.displayName}` }; - }); + member.voice?.setChannel(currentVoiceClone, "portal force update").catch( + () => { + return { + result: false, + value: `Failed to move user ${member.displayName}`, + }; + }, + ); } - const updatedVoice = await updateVoice(pGuild.id, pChannel.id, currentVoice.id, 'id', currentVoiceClone.id); + const updatedVoice = await updateVoice( + pGuild.id, + pChannel.id, + currentVoice.id, + "id", + currentVoiceClone.id, + ); if (!updatedVoice) { - return { result: false, value: 'Failed to force update channel' }; + return { result: false, value: "Failed to force update channel" }; } - await deleteChannel(PortalChannelType.voice, currentVoice, interaction, true).catch((e) => { - return { result: false, value: `Failed to delete channel: ${e}` }; - }); + const result = await deleteChannel( + PortalChannelType.voice, + currentVoice, + interaction, + true, + ); - return { result: true, value: 'Force updated voice' }; + if (!result) { + return { result: false, value: `Failed to delete channel` }; + } + + return { result: true, value: "Force updated voice" }; } export default { @@ -67,29 +103,53 @@ export default { ephemeral: true, auth: true, scopeLimit: ScopeLimit.MEMBER, - slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription(DESCRIPTION), - - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { + slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription( + DESCRIPTION, + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { const member = interaction.member as GuildMember; - if (!member) return { result: false, value: 'Member could not be fetched' }; - if (!isUserInHandledVoiceChannel(member, pGuild)) + if (!member) return { result: false, value: "Member could not be fetched" }; + if (!isUserInHandledVoiceChannel(member, pGuild)) { return { result: false, - value: messageHelp('commands', 'force', 'The channel you are in is not handled by Portal'), + value: messageHelp( + "commands", + "force", + "The channel you are in is not handled by Portal", + ), }; - if ((member.voice.channel as VoiceChannel).members.size > 10) + } + if ((member.voice.channel as VoiceChannel).members.size > 10) { return { result: false, - value: messageHelp('commands', 'force', 'You can only force a channel with up-to 10 members'), + value: messageHelp( + "commands", + "force", + "You can only force a channel with up-to 10 members", + ), }; + } for (const pChannel of pGuild.pChannels) { for (const pVoiceChannel of pChannel.pVoiceChannels) { - if (pVoiceChannel.id !== member.voice.channel!.id) continue; - if (!isChannelCreator(member, pVoiceChannel)) - return { result: false, value: 'You are not the creator of the channel' }; - if (!interaction.guild) return { result: false, value: 'Could not fetch message\'s guild' }; + if (pVoiceChannel.id !== member.voice.channel!.id) { + continue; + } + + if (!isChannelCreator(member, pVoiceChannel)) { + return { + result: false, + value: "You are not the creator of the channel", + }; + } + + if (!interaction.guild) { + return { result: false, value: "Could not fetch message's guild" }; + } return cloneAndUpdateVoiceChannel( member.voice.channel as VoiceChannel, @@ -100,6 +160,7 @@ export default { ); } } - return { result: false, value: 'Force failed' }; + + return { result: false, value: "Force failed" }; }, } as Command; diff --git a/src/commands/auth/ignore.ts b/src/commands/auth/ignore.ts index cf27149c..8da4c337 100644 --- a/src/commands/auth/ignore.ts +++ b/src/commands/auth/ignore.ts @@ -1,13 +1,16 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction } from 'discord.js'; -import { includedInPIgnores } from '../../libraries/guild.library.js'; -import { insertIgnore, removeIgnore } from '../../libraries/mongo.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { ChatInputCommandInteraction } from "npm:discord.js"; +import { includedInPIgnores } from "../../libraries/guild.library.ts"; +import { insertIgnore, removeIgnore } from "../../libraries/mongo.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'ignore'; -const DESCRIPTION = 'ignore user or channel from spam'; +const COMMAND_NAME = "ignore"; +const DESCRIPTION = "ignore user or channel from spam"; export default { time: 0, @@ -15,12 +18,17 @@ export default { ephemeral: true, auth: true, scopeLimit: ScopeLimit.NONE, - slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription(DESCRIPTION), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { + slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription( + DESCRIPTION, + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { if (!interaction.guild) { return { result: false, - value: 'guild could not be fetched', + value: "guild could not be fetched", }; } @@ -29,7 +37,7 @@ export default { if (!channelId) { return { result: false, - value: 'could not fetch channel', + value: "could not fetch channel", }; } @@ -40,12 +48,14 @@ export default { if (response) { return { result: response, - value: response ? 'successfully removed ignore channel' : 'failed to remove ignore channel', + value: response + ? "successfully removed ignore channel" + : "failed to remove ignore channel", }; } else { return { result: false, - value: 'failed to remove ignore channel', + value: "failed to remove ignore channel", }; } } else { @@ -54,12 +64,14 @@ export default { if (response) { return { result: response, - value: response ? 'set as an ignore channel successfully' : 'failed to set as an ignore channel', + value: response + ? "set as an ignore channel successfully" + : "failed to set as an ignore channel", }; } else { return { result: false, - value: 'failed to set as an ignore channel', + value: "failed to set as an ignore channel", }; } } diff --git a/src/commands/auth/index.ts b/src/commands/auth/index.ts index 5abf7427..880df432 100644 --- a/src/commands/auth/index.ts +++ b/src/commands/auth/index.ts @@ -1,13 +1,13 @@ -export { default as announcement } from './announcement.js'; -export { default as ban } from './ban.js'; -export { default as delete_messages } from './delete_messages.js'; -export { default as force } from './force.js'; -export { default as ignore } from './ignore.js'; -export { default as invite } from './invite.js'; -export { default as kick } from './kick.js'; -export { default as music } from './music.js'; -export { default as portal } from './portal.js'; -export { default as set } from './set.js'; -export { default as set_ranks } from './set_ranks.js'; -export { default as url } from './url.js'; -export { default as vendor } from './vendor.js'; +export { default as announcement } from "./announcement.ts"; +export { default as ban } from "./ban.ts"; +export { default as delete_messages } from "./delete_messages.ts"; +export { default as force } from "./force.ts"; +export { default as ignore } from "./ignore.ts"; +export { default as invite } from "./invite.ts"; +export { default as kick } from "./kick.ts"; +export { default as music } from "./music.ts"; +export { default as portal } from "./portal.ts"; +export { default as set } from "./set.ts"; +export { default as set_ranks } from "./set_ranks.ts"; +export { default as url } from "./url.ts"; +export { default as vendor } from "./vendor.ts"; diff --git a/src/commands/auth/invite.ts b/src/commands/auth/invite.ts index 55f4dee4..211510f4 100644 --- a/src/commands/auth/invite.ts +++ b/src/commands/auth/invite.ts @@ -1,17 +1,20 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; +import { SlashCommandBuilder } from "@discordjs/builders"; import { - ChatInputCommandInteraction, - GuildMember, + type ChatInputCommandInteraction, + type GuildMember, InteractionContextType, - InviteCreateOptions, - TextChannel, -} from 'discord.js'; -import { isMod, messageHelp } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; + type InviteCreateOptions, + type TextChannel, +} from "npm:discord.js"; +import { isMod, messageHelp } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'invite'; -const DESCRIPTION = 'generate an invite link'; +const COMMAND_NAME = "invite"; +const DESCRIPTION = "generate an invite link"; export default { time: 1, @@ -23,50 +26,67 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .addBooleanOption((option) => - option.setName('temporary').setDescription('should invite be temporary').setRequired(false), + option.setName("temporary").setDescription("should invite be temporary") + .setRequired(false) + ) + .addNumberOption((option) => + option.setName("max_age").setDescription( + "what the maximum age of the invitee shall be", + ).setRequired(false) ) .addNumberOption((option) => - option.setName('max_age').setDescription('what the maximum age of the invitee shall be').setRequired(false), + option.setName("max_uses").setDescription("maximum usages").setRequired( + false, + ) + ) + .addBooleanOption((option) => + option.setName("unique").setDescription("should invite be unique") + .setRequired(false) ) - .addNumberOption((option) => option.setName('max_uses').setDescription('maximum usages').setRequired(false)) - .addBooleanOption((option) => option.setName('unique').setDescription('should invite be unique').setRequired(false)) .addStringOption((option) => - option.setName('reason').setDescription('the reason for the invite').setRequired(false), + option.setName("reason").setDescription("the reason for the invite") + .setRequired(false) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction): Promise { + async execute( + interaction: ChatInputCommandInteraction, + ): Promise { const member = interaction.member as GuildMember; if (!interaction.guild) { return { result: false, - value: 'guild could not be fetched', + value: "guild could not be fetched", }; } if (!member) { return { result: false, - value: 'member could not be fetched', + value: "member could not be fetched", }; } if (!isMod(member)) { return { result: false, - value: 'you must be a Portal moderator to invite users', + value: "you must be a Portal moderator to invite users", }; } - const temporary = interaction.options.getBoolean('temporary'); - const maxAge = interaction.options.getNumber('max_age'); - const maxUses = interaction.options.getNumber('max_uses'); - const unique = interaction.options.getBoolean('unique'); - const reason = interaction.options.getString('reason'); + const temporary = interaction.options.getBoolean("temporary"); + const maxAge = interaction.options.getNumber("max_age"); + const maxUses = interaction.options.getNumber("max_uses"); + const unique = interaction.options.getBoolean("unique"); + const reason = interaction.options.getString("reason"); if (!(temporary && maxAge && maxUses && unique && reason)) { return { result: false, - value: messageHelp('commands', 'invite', 'all invite options are required'), + value: messageHelp( + "commands", + "invite", + "all invite options are required", + ), }; } @@ -78,27 +98,30 @@ export default { reason, }; - const createdInvite = await (interaction.channel).createInvite(inviteCreationOptions); + const createdInvite = await ( interaction.channel) + .createInvite(inviteCreationOptions); if (!createdInvite) { return { result: false, - value: 'failed to remove ignore channel', + value: "failed to remove ignore channel", }; } - const sentMessage = await member?.send(`https://discord.gg/${createdInvite.code}`); + const sentMessage = await member?.send( + `https://discord.gg/${createdInvite.code}`, + ); if (!sentMessage) { return { result: false, - value: 'failed to remove ignore channel', + value: "failed to remove ignore channel", }; } return { result: true, - value: 'I sent you an invite as a private message', + value: "I sent you an invite as a private message", }; }, } as Command; diff --git a/src/commands/auth/kick.ts b/src/commands/auth/kick.ts index 51190c6e..ec63645d 100644 --- a/src/commands/auth/kick.ts +++ b/src/commands/auth/kick.ts @@ -1,13 +1,27 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { BanOptions, ButtonStyle, ChatInputCommandInteraction, GuildMember, InteractionContextType } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + type BanOptions, + ButtonStyle, + type ChatInputCommandInteraction, + type GuildMember, + InteractionContextType, +} from "npm:discord.js"; -import { askForApproval, isMod, messageHelp } from '../../libraries/help.library.js'; -import { ban } from '../../libraries/user.library.js'; -import { Command } from '../../types/Command.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { + askForApprovalByInteraction, + isMod, + messageHelp, +} from "../../libraries/help.library.ts"; +import { ban } from "../../libraries/user.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import logger from "../../utilities/log.utility.ts"; -const COMMAND_NAME = 'kick'; -const DESCRIPTION = 'kick a user'; +const COMMAND_NAME = "kick"; +const DESCRIPTION = "kick a user"; export default { time: 1, @@ -18,54 +32,69 @@ export default { slashCommand: new SlashCommandBuilder() .setName(COMMAND_NAME) .setDescription(DESCRIPTION) - .addUserOption((option) => option.setName('user_to_kick').setDescription('user to kick').setRequired(true)) - .addNumberOption((option) => option.setName('kick_days').setDescription('days to kick user for').setRequired(true)) - .addStringOption((option) => option.setName('kick_reason').setDescription('kick reason').setRequired(false)) + .addUserOption((option) => + option.setName("user_to_kick").setDescription("user to kick").setRequired( + true, + ) + ) + .addNumberOption((option) => + option.setName("kick_days").setDescription("days to kick user for") + .setRequired(true) + ) + .addStringOption((option) => + option.setName("kick_reason").setDescription("kick reason").setRequired( + false, + ) + ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction): Promise { - const memberToBan = interaction.options.getMember('user_to_kick') as GuildMember; - const kickDays = interaction.options.getNumber('kick_days'); - const kickReason = interaction.options.getString('kick_reason'); + async execute( + interaction: ChatInputCommandInteraction, + ): Promise { + const memberToBan = interaction.options.getMember( + "user_to_kick", + ) as GuildMember; + const kickDays = interaction.options.getNumber("kick_days"); + const kickReason = interaction.options.getString("kick_reason"); if (!memberToBan) { return { result: false, - value: messageHelp('commands', 'kick', 'user must be provided'), + value: messageHelp("commands", "kick", "user must be provided"), }; } if (!kickDays) { return { result: false, - value: messageHelp('commands', 'kick', 'days to kick must be provided'), + value: messageHelp("commands", "kick", "days to kick must be provided"), }; } if (!interaction.member) { return { result: false, - value: 'message author could not be fetched', + value: "message author could not be fetched", }; } if (!isMod(interaction.member as GuildMember)) { return { result: false, - value: 'you must be a Portal moderator to kick users', + value: "you must be a Portal moderator to kick users", }; } if (!interaction.guild) { return { result: false, - value: 'user guild could not be fetched', + value: "user guild could not be fetched", }; } const deleteMessageDays = kickDays ?? 1; - const reason = kickReason ?? 'kicked by admin'; + const reason = kickReason ?? "kicked by admin"; - const response = await askForApproval( + const response = await askForApprovalByInteraction( interaction, `*${interaction.user}, are you sure you want to kick **${memberToBan.displayName}** for **${deleteMessageDays}** days*?`, ButtonStyle.Danger, @@ -74,7 +103,7 @@ export default { if (!response) { return { result: false, - value: 'kick approval not received', + value: "kick approval not received", }; } @@ -93,7 +122,11 @@ export default { : `User ${memberToBan.displayName} could not be kicked`, }; } catch (e) { - await interaction.editReply({ content: 'Confirmation not received within 1 minute, cancelling', components: [] }); + logger.error(`Error while kicking: ${e}`); + await interaction.editReply({ + content: "Confirmation not received within 1 minute, cancelling", + components: [], + }); return { result: false, diff --git a/src/commands/auth/music.ts b/src/commands/auth/music.ts index 44998c9c..1546d9e1 100644 --- a/src/commands/auth/music.ts +++ b/src/commands/auth/music.ts @@ -1,15 +1,34 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, InteractionContextType, TextChannel, VoiceChannel } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + type ChatInputCommandInteraction, + InteractionContextType, + TextChannel, + type VoiceChannel, +} from "npm:discord.js"; -import { deleteChannel, doesChannelHaveUsage } from '../../libraries/guild.library.js'; -import { createMusicLyricsMessage, createMusicMessage, messageHelp } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; -import { PortalChannelType } from '../../types/enums/PortalChannel.enum.js'; +import { + deleteChannel, + getChannelTypeById, +} from "../../libraries/guild.library.ts"; +import { + createMusicLyricsMessage, + createMusicMessage, + messageHelp, +} from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import { PortalChannelType } from "../../types/enums/PortalChannel.enum.ts"; +import { + TextChannelType, + TextChannelTypeList, +} from "../../types/enums/TextChannelType.enum.ts"; -const COMMAND_NAME = 'music'; -const DESCRIPTION = 'set a music channel'; +const COMMAND_NAME = "music"; +const DESCRIPTION = "set a music channel"; export default { time: 0, @@ -22,47 +41,54 @@ export default { .setDescription(DESCRIPTION) .addChannelOption((option) => option - .setName('music_channel') - .setDescription('the channel you want to make the music channel') - .setRequired(true), + .setName("music_channel") + .setDescription("the channel you want to make the music channel") + .setRequired(true) ) .addChannelOption((option) => option - .setName('delete_previous') - .setDescription('whether or not to delete the previous music channel') - .setRequired(false), + .setName("delete_previous") + .setDescription("whether or not to delete the previous music channel") + .setRequired(false) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { - const musicChannel = interaction.options.getChannel('music_channel'); - const deletePreviousMusicChannel = interaction.options.getChannel('delete_previous'); + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + const musicChannel = interaction.options.getChannel("music_channel"); + const deletePreviousMusicChannel = interaction.options.getChannel( + "delete_previous", + ); if (!musicChannel) { return { result: false, - value: messageHelp('commands', 'music'), + value: messageHelp("commands", "music"), }; } if (!(musicChannel instanceof TextChannel)) { return { result: false, - value: messageHelp('commands', 'music', 'channel must be text channel'), + value: messageHelp("commands", "music", "channel must be text channel"), }; } if (!musicChannel.isTextBased) { return { result: false, - value: messageHelp('commands', 'music', 'channel must be text channel'), + value: messageHelp("commands", "music", "channel must be text channel"), }; } - const channelHasUsage = await doesChannelHaveUsage(musicChannel.id, pGuild); - if (channelHasUsage.result) { + const channelType = await getChannelTypeById(musicChannel.id, pGuild); + if (channelType !== TextChannelType.NONE) { return { result: false, - value: channelHasUsage.value, + value: `selected channel is already in use as ${ + TextChannelTypeList[channelType] + } channel`, }; } @@ -81,7 +107,7 @@ export default { return { result: true, - value: 'new music channel set successfully', + value: `**${musicChannel.name}** set to Music channel.`, }; }, } as Command; diff --git a/src/commands/auth/portal.ts b/src/commands/auth/portal.ts index 08485cfd..bbcd7bbd 100644 --- a/src/commands/auth/portal.ts +++ b/src/commands/auth/portal.ts @@ -1,15 +1,26 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, GuildMember, InteractionContextType, VoiceChannel } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + type ChatInputCommandInteraction, + type GuildMember, + InteractionContextType, + VoiceChannel, +} from "npm:discord.js"; -import { messageHelp } from '../../libraries/help.library.js'; -import { insertPortal } from '../../libraries/mongo.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { IPChannel, PChannel } from '../../types/classes/PPortalChannel.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { messageHelp } from "../../libraries/help.library.ts"; +import { insertPortal } from "../../libraries/mongo.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type IPChannel, + PChannel, +} from "../../types/classes/PPortalChannel.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'portal'; -const DESCRIPTION = 'set a portal channel'; +const COMMAND_NAME = "portal"; +const DESCRIPTION = "set a portal channel"; export default { time: 0, @@ -22,39 +33,52 @@ export default { .setDescription(DESCRIPTION) .addChannelOption((option) => option - .setName('portal_channel_name') - .setDescription('the name of the portal channel you want to create') - .setRequired(true), + .setName("portal_channel_name") + .setDescription("the name of the portal channel you want to create") + .setRequired(true) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { - const newPortalChannel = interaction.options.getChannel('portal_channel_name'); + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + const portalChannel = interaction.options.getChannel( + "portal_channel_name", + ); - if (!newPortalChannel) { + if (!portalChannel) { return { result: false, - value: messageHelp('commands', 'portal', 'portal channel name is required'), + value: messageHelp( + "commands", + "portal", + "portal channel name is required", + ), }; } - if (!(newPortalChannel instanceof VoiceChannel)) { + if (!(portalChannel instanceof VoiceChannel)) { return { result: false, - value: messageHelp('commands', 'portal', 'channel must be voice channel'), + value: messageHelp( + "commands", + "portal", + "channel must be voice channel", + ), }; } if (!interaction.guild) { return { result: true, - value: 'guild could not be fetched', + value: "guild could not be fetched", }; } if (!interaction.member) { return { result: true, - value: 'member could not be fetched', + value: "member could not be fetched", }; } @@ -70,9 +94,9 @@ export default { // }; const voiceRegex = pGuild.premium - ? // ? 'G$#-P$memberCount | $statusList' - '$#:$memberCount {{"if": "$statusCount", "is": "===", "with": "1","yes": "$statusList", "no": "$statusList|acronym"}}' - : 'Channel $#'; + // ? 'G$#-P$memberCount | $statusList' + ? '$#:$memberCount {{"if": "$statusCount", "is": "===", "with": "1","yes": "$statusList", "no": "$statusList|acronym"}}' + : "Channel $#"; // const newPortalChannelId = await createChannel(currentGuild, portalChannelName, portalOptions, portalChannelCategoryName); @@ -84,10 +108,10 @@ export default { // } const pChannel = new PChannel( - newPortalChannel.id, + portalChannel.id, currentMember.id, true, - 'portal', + "portal", voiceRegex, [], false, @@ -99,15 +123,16 @@ export default { false, ); - const portalInserted = await insertPortal(pGuild.id, pChannel as unknown as IPChannel); + const portalInserted = await insertPortal( + pGuild.id, + pChannel as unknown as IPChannel, + ); return { result: !!portalInserted, value: portalInserted - ? 'Portal channel has been created.\n' + - 'Keep in mind that due to Discord\'s limitations,\n' + - 'channel names will be updated on a five minute interval' - : 'portal channel failed to be created', + ? `**${portalChannel.name}** set to Portal channel.` + : "failed to set new Portal channel ", }; }, } as Command; diff --git a/src/commands/auth/set.ts b/src/commands/auth/set.ts index 6082eed4..8a80a1fd 100644 --- a/src/commands/auth/set.ts +++ b/src/commands/auth/set.ts @@ -1,14 +1,22 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, GuildMember, Role, VoiceChannel } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { + ChatInputCommandInteraction, + GuildMember, + Role, + VoiceChannel, +} from "npm:discord.js"; -import { setAttribute } from '../../Interpreter/attribute.functions.js'; -import { messageHelp } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { setAttribute } from "../../Interpreter/attribute.functions.ts"; +import { messageHelp } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'set'; -const DESCRIPTION = 'set the value of an attribute'; +const COMMAND_NAME = "set"; +const DESCRIPTION = "set the value of an attribute"; export default { time: 0, @@ -21,54 +29,63 @@ export default { .setDescription(DESCRIPTION) .addStringOption((option) => option - .setName('attribute') - .setDescription('Attribute\'s name to set') + .setName("attribute") + .setDescription("Attribute's name to set") .addChoices( - { name: 'p.annAnnounce', value: 'p.annAnnounce' }, - { name: 'v.annAnnounce', value: 'v.annAnnounce' }, - { name: 'p.noBots', value: 'p.noBots' }, - { name: 'v.noBots', value: 'v.noBots' }, - { name: 'p.allowedRoles', value: 'p.allowedRoles' }, - { name: 'p.v.allowedRoles', value: 'p.v.allowedRoles' }, - { name: 'v.allowedRoles', value: 'v.allowedRoles' }, - { name: 'p.render', value: 'p.render' }, - { name: 'v.render', value: 'v.render' }, - { name: 'p.annUser', value: 'p.annUser' }, - { name: 'v.annUser', value: 'v.annUser' }, - { name: 'v.bitrate', value: 'v.bitrate' }, - { name: 'g.kickAfter', value: 'g.kickAfter' }, - { name: 'g.banAfter', value: 'g.banAfter' }, - { name: 'g.muteRole', value: 'g.muteRole' }, - { name: 'g.rankSpeed', value: 'g.rankSpeed' }, - { name: 'g.profanityLevel', value: 'g.profanityLevel' }, - { name: 'g.initialRole', value: 'g.initialRole' }, - { name: 'g.locale', value: 'g.locale' }, - { name: 'p.locale', value: 'p.locale' }, - { name: 'v.locale', value: 'v.locale' }, - { name: 'v.position', value: 'v.position' }, - { name: 'p.userLimit', value: 'p.userLimit' }, - { name: 'v.userLimit', value: 'v.userLimit' }, + { name: "p.annAnnounce", value: "p.annAnnounce" }, + { name: "v.annAnnounce", value: "v.annAnnounce" }, + { name: "p.noBots", value: "p.noBots" }, + { name: "v.noBots", value: "v.noBots" }, + { name: "p.allowedRoles", value: "p.allowedRoles" }, + { name: "p.v.allowedRoles", value: "p.v.allowedRoles" }, + { name: "v.allowedRoles", value: "v.allowedRoles" }, + { name: "p.render", value: "p.render" }, + { name: "v.render", value: "v.render" }, + { name: "p.annUser", value: "p.annUser" }, + { name: "v.annUser", value: "v.annUser" }, + { name: "v.bitrate", value: "v.bitrate" }, + { name: "g.kickAfter", value: "g.kickAfter" }, + { name: "g.banAfter", value: "g.banAfter" }, + { name: "g.muteRole", value: "g.muteRole" }, + { name: "g.rankSpeed", value: "g.rankSpeed" }, + { name: "g.profanityLevel", value: "g.profanityLevel" }, + { name: "g.initialRole", value: "g.initialRole" }, + { name: "g.locale", value: "g.locale" }, + { name: "p.locale", value: "p.locale" }, + { name: "v.locale", value: "v.locale" }, + { name: "v.position", value: "v.position" }, + { name: "p.userLimit", value: "p.userLimit" }, + { name: "v.userLimit", value: "v.userLimit" }, ) - .setRequired(true), + .setRequired(true) ) - .addStringOption((option) => option.setName('value').setDescription('Value to set attribute to').setRequired(false)) - .addRoleOption((option) => option.setName('role').setDescription('Value to set attribute to').setRequired(false)), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { - const attribute = interaction.options.getString('attribute'); - const value = interaction.options.getString('value'); - const role = interaction.options.getRole('role'); + .addStringOption((option) => + option.setName("value").setDescription("Value to set attribute to") + .setRequired(false) + ) + .addRoleOption((option) => + option.setName("role").setDescription("Value to set attribute to") + .setRequired(false) + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + const attribute = interaction.options.getString("attribute"); + const value = interaction.options.getString("value"); + const role = interaction.options.getRole("role"); if (!attribute || (!value && !role)) { return { result: false, - value: messageHelp('commands', 'set'), + value: messageHelp("commands", "set"), }; } if (!interaction.guild) { return { result: true, - value: 'guild could not be fetched', + value: "guild could not be fetched", }; } @@ -76,7 +93,7 @@ export default { if (!member) { return { result: true, - value: 'member could not be fetched', + value: "member could not be fetched", }; } diff --git a/src/commands/auth/set_ranks.ts b/src/commands/auth/set_ranks.ts index f5a02597..9d89ff60 100644 --- a/src/commands/auth/set_ranks.ts +++ b/src/commands/auth/set_ranks.ts @@ -1,13 +1,24 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, InteractionContextType, Role } from 'discord.js'; -import { getJSONFromString, messageHelp } from '../../libraries/help.library.js'; -import { setRanks } from '../../libraries/mongo.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { Rank, ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + type ChatInputCommandInteraction, + InteractionContextType, + type Role, +} from "npm:discord.js"; +import { + getJSONFromString, + messageHelp, +} from "../../libraries/help.library.ts"; +import { setRanks } from "../../libraries/mongo.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type Rank, + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'set_ranks'; -const DESCRIPTION = 'set ranks for server'; +const COMMAND_NAME = "set_ranks"; +const DESCRIPTION = "set ranks for server"; export default { time: 0, @@ -19,22 +30,32 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .addStringOption((option) => - option.setName('rank_string').setDescription('JSON string of ranks to set (even for one rank)').setRequired(true), + option.setName("rank_string").setDescription( + "JSON string of ranks to set (even for one rank)", + ).setRequired(true) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { - if (!interaction.guild) + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + if (!interaction.guild) { return { result: true, - value: 'guild could not be fetched', + value: "guild could not be fetched", }; + } - const rankString = interaction.options.getString('rank_string'); + const rankString = interaction.options.getString("rank_string"); if (!rankString) { return { result: false, - value: messageHelp('commands', 'set_ranks', 'rank string must be provided'), + value: messageHelp( + "commands", + "set_ranks", + "rank string must be provided", + ), }; } @@ -44,30 +65,46 @@ export default { if (!newRanksJSON || !Array.isArray(newRanksJSON)) { return { result: false, - value: messageHelp('commands', 'set_ranks', 'ranking must be an array in JSON format (even for one role)'), + value: messageHelp( + "commands", + "set_ranks", + "ranking must be an array in JSON format (even for one role)", + ), }; } - const newRanks = newRanksJSON; + const newRanks = newRanksJSON; if (!newRanks.every((r) => r.level && r.role)) { return { result: false, - value: messageHelp('commands', 'set_ranks', 'JSON syntax has spelling errors`'), + value: messageHelp( + "commands", + "set_ranks", + "JSON syntax has spelling errors`", + ), }; } if (!newRanks.every(isRank)) { return { result: false, - value: messageHelp('commands', 'set_ranks', 'rankings must be a key-pair from level and role'), + value: messageHelp( + "commands", + "set_ranks", + "rankings must be a key-pair from level and role", + ), }; } if (!newRanks.every((r) => isRole(r, roles))) { return { result: false, - value: messageHelp('commands', 'set_ranks', 'a role given does not exist in server'), + value: messageHelp( + "commands", + "set_ranks", + "a role given does not exist in server", + ), }; } @@ -81,7 +118,9 @@ export default { return { result: response, - value: response ? 'set new ranks successfully' : 'failed to set new ranks', + value: response + ? "set new ranks successfully" + : "failed to set new ranks", }; }, } as Command; diff --git a/src/commands/auth/url.ts b/src/commands/auth/url.ts index a3d339b1..fdfee223 100644 --- a/src/commands/auth/url.ts +++ b/src/commands/auth/url.ts @@ -1,15 +1,26 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, InteractionContextType, NewsChannel } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + type ChatInputCommandInteraction, + InteractionContextType, + NewsChannel, +} from "npm:discord.js"; -import { doesChannelHaveUsage } from '../../libraries/guild.library.js'; -import { messageHelp } from '../../libraries/help.library.js'; -import { insertURL } from '../../libraries/mongo.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { getChannelTypeById } from "../../libraries/guild.library.ts"; +import { messageHelp } from "../../libraries/help.library.ts"; +import { insertURL } from "../../libraries/mongo.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import { + TextChannelType, + TextChannelTypeList, +} from "../../types/enums/TextChannelType.enum.ts"; -const COMMAND_NAME = 'url'; -const DESCRIPTION = 'set a channel to URL only'; +const COMMAND_NAME = "url"; +const DESCRIPTION = "set a channel to URL only"; export default { time: 0, @@ -21,38 +32,45 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .addChannelOption((option) => - option.setName('url_channel').setDescription('the channel you want to make the url channel').setRequired(true), + option.setName("url_channel").setDescription( + "the channel you want to make the url channel", + ).setRequired(true) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { - const urlChannel = interaction.options.getChannel('url_channel'); + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + const urlChannel = interaction.options.getChannel("url_channel"); if (!urlChannel) { return { result: false, - value: messageHelp('commands', 'url'), + value: messageHelp("commands", "url"), }; } if (!(urlChannel instanceof NewsChannel)) { return { result: false, - value: messageHelp('commands', 'url', 'channel must be news channel'), + value: messageHelp("commands", "url", "channel must be news channel"), }; } if (!urlChannel.isTextBased()) { return { result: false, - value: messageHelp('commands', 'url', 'channel must be text channel'), + value: messageHelp("commands", "url", "channel must be text channel"), }; } - const channelHasUsage = await doesChannelHaveUsage(urlChannel.id, pGuild); - if (channelHasUsage.result) { + const channelType = await getChannelTypeById(urlChannel.id, pGuild); + if (channelType !== TextChannelType.NONE) { return { result: false, - value: channelHasUsage.value, + value: `selected channel is already in use as ${ + TextChannelTypeList[channelType] + } channel`, }; } @@ -60,7 +78,9 @@ export default { return { result: response, - value: response ? 'new url channel set successfully' : 'failed to set new url channel', + value: response + ? `**${urlChannel.name}** set to URL channel.` + : "failed to set new URL channel ", }; }, } as Command; diff --git a/src/commands/auth/vendor.ts b/src/commands/auth/vendor.ts index b87f3772..792d2350 100644 --- a/src/commands/auth/vendor.ts +++ b/src/commands/auth/vendor.ts @@ -1,16 +1,32 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, ColorResolvable, InteractionContextType, TextChannel } from 'discord.js'; - -import { getRole } from '../../libraries/guild.library.js'; -import { createEmbed, getJSONFromString, messageHelp } from '../../libraries/help.library.js'; -import { insertVendor } from '../../libraries/mongo.library.js'; -import { Command } from '../../types/Command.js'; -import { GiveRole, PGiveRole } from '../../types/classes/PGiveRole.class.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { Field, ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; - -const COMMAND_NAME = 'vendor'; -const DESCRIPTION = 'create a vendor message'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + type ChatInputCommandInteraction, + type ColorResolvable, + InteractionContextType, + type TextChannel, +} from "npm:discord.js"; + +import { getRole } from "../../libraries/guild.library.ts"; +import { + createEmbed, + getJSONFromString, + messageHelp, +} from "../../libraries/help.library.ts"; +import { insertVendor } from "../../libraries/mongo.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type GiveRole, + PGiveRole, +} from "../../types/classes/PGiveRole.class.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + Field, + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; + +const COMMAND_NAME = "vendor"; +const DESCRIPTION = "create a vendor message"; export default { time: 0, @@ -22,23 +38,32 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .addStringOption((option) => - option.setName('vendor_string').setDescription('JSON string of vendor roles').setRequired(true), + option.setName("vendor_string").setDescription( + "JSON string of vendor roles", + ).setRequired(true) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { if (!interaction.guild) { return { result: true, - value: 'guild could not be fetched', + value: "guild could not be fetched", }; } - const vendorString = interaction.options.getString('vendor_string'); + const vendorString = interaction.options.getString("vendor_string"); if (!vendorString) { return { result: false, - value: messageHelp('commands', 'vendor', 'vendor string must be provided'), + value: messageHelp( + "commands", + "vendor", + "vendor string must be provided", + ), }; } @@ -47,29 +72,45 @@ export default { if (!roleMapJson) { return { result: false, - value: messageHelp('commands', 'vendor', 'must be an array in JSON format (even for one role)'), + value: messageHelp( + "commands", + "vendor", + "must be an array in JSON format (even for one role)", + ), }; } - const roleMap = roleMapJson; + const roleMap = roleMapJson; if (!Array.isArray(roleMap)) { return { result: false, - value: messageHelp('commands', 'vendor', 'must be an array in JSON format (even for one role)'), + value: messageHelp( + "commands", + "vendor", + "must be an array in JSON format (even for one role)", + ), }; } if (multipleSameEmote(roleMap)) { return { result: false, - value: messageHelp('commands', 'vendor', 'can not have the same emote for multiple actions'), + value: messageHelp( + "commands", + "vendor", + "can not have the same emote for multiple actions", + ), }; } if (!roleMap.every((rm) => rm.emote && rm.role)) { return { result: false, - value: messageHelp('commands', 'vendor', 'JSON syntax has spelling errors'), + value: messageHelp( + "commands", + "vendor", + "JSON syntax has spelling errors", + ), }; } @@ -80,26 +121,31 @@ export default { const roleEmbDisplay: Field[] = []; - let returnValue = ''; + let returnValue = ""; // give roles const failed = roleMap.some((r) => { if (interaction.guild) { - const roleFetched = r.role.map((role) => getRole(interaction.guild, role)); + const roleFetched = r.role.map((role) => + getRole(interaction.guild, role) + ); if (roleFetched.some((role) => !role)) { - returnValue = 'some of the given roles do not exist'; + returnValue = "some of the given roles do not exist"; return true; } roleEmbDisplay.push( new Field( r.emote, - `\`\`\`${roleFetched.map((role) => `@${role ? role.name : 'undefined'}`).join(', ')}\`\`\``, + `\`\`\`${ + roleFetched.map((role) => `@${role ? role.name : "undefined"}`) + .join(", ") + }\`\`\``, true, ), ); } else { - returnValue = 'could not fetch guild of message'; + returnValue = "could not fetch guild of message"; return true; } }); @@ -112,11 +158,11 @@ export default { } const roleMessage = await createRoleMessage( - interaction.channel, + interaction.channel, pGuild, - 'Role Assigner', - 'React with emote to get or remove mentioned role', - '#FF7F00', + "Role Assigner", + "React with emote to get or remove mentioned role", + "#FF7F00", roleEmbDisplay, roleMap, ); @@ -124,7 +170,7 @@ export default { if (!roleMessage || !roleMessage.result) { return { result: false, - value: 'an error occurred while creating role message', + value: "an error occurred while creating role message", }; } @@ -142,7 +188,17 @@ function createRoleMessage( roleMap: GiveRole[], ): Promise { return new Promise((resolve) => { - const roleMessageEmb = createEmbed(title, desc, colour, roleEmb, null, null, null, null, null); + const roleMessageEmb = createEmbed( + title, + desc, + colour, + roleEmb, + null, + null, + null, + null, + null, + ); channel .send({ embeds: [roleMessageEmb] }) @@ -161,22 +217,22 @@ function createRoleMessage( return resolve({ result: r, value: r - ? 'Keep in mind that Portal role must be over any role you wish it to be able to distribute.\n' + - 'In order to change it, please head to your servers settings and put Portal role above them' - : 'failed to set new ranks', + ? "Keep in mind that Portal role must be over any role you wish it to be able to distribute.\n" + + "In order to change it, please head to your servers settings and put Portal role above them" + : "failed to set new ranks", }); }) .catch(() => { return resolve({ result: false, - value: 'failed to set new ranks', + value: "failed to set new ranks", }); }); }) .catch(() => { return resolve({ result: false, - value: 'failed to create role assigner message', + value: "failed to create role assigner message", }); }); }); diff --git a/src/commands/noAuth/about.ts b/src/commands/noAuth/about.ts index 6bc0d2b0..1c8bd0d1 100644 --- a/src/commands/noAuth/about.ts +++ b/src/commands/noAuth/about.ts @@ -1,10 +1,15 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { createEmbed } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import "@std/dotenv/load"; -const COMMAND_NAME = 'about'; -const DESCRIPTION = 'returns information on Portal'; +import { createEmbed } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; + +const COMMAND_NAME = "about"; +const DESCRIPTION = "returns information on Portal"; export default { time: 0, @@ -12,42 +17,47 @@ export default { ephemeral: true, auth: false, scopeLimit: ScopeLimit.NONE, - slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription(DESCRIPTION), + slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription( + DESCRIPTION, + ), async execute(): Promise { const aboutMessage = [ createEmbed( - 'About', - 'A fully fledged and feature rich bot for Discord', - '#1DB954', + "About", + "A fully fledged and feature rich bot for Discord", + "#1DB954", [ { - emote: 'Website', - role: '[portal-bot.xyz](https://portal-bot.xyz)', + emote: "Website", + role: "[portal-bot.xyz](https://portal-bot.xyz)", inline: true, }, { - emote: 'Creator', - role: '[Keybraker](https://github.com/keybraker/Portal)', + emote: "Creator", + role: "[Keybraker](https://github.com/keybraker/Portal)", inline: true, }, { - emote: 'Version', - role: `[${process.env.VERSION}](https://portal-bot.xyz/blog/${process.env.VERSION})`, + emote: "Version", + role: `[${Deno.env.get("VERSION")}](https://portal-bot.xyz/blog/${ + Deno.env.get("VERSION") + })`, inline: true, }, { - emote: 'Official Server', - role: '[Portal Official](https://discord.gg/WrMUzJYyzJ)', + emote: "Official Server", + role: "[Portal Official](https://discord.gg/WrMUzJYyzJ)", inline: true, }, { - emote: 'Github', - role: '[keybraker/Portal](https://www.github.com/keybraker/Portal)', + emote: "Github", + role: "[keybraker/Portal](https://www.github.com/keybraker/Portal)", inline: true, }, { - emote: 'Upvote', - role: '[Top.gg](https://top.gg/bot/704400876860735569) | [Bot.gg](https://discord.bots.gg/bots/704400876860735569)', + emote: "Upvote", + role: + "[Top.gg](https://top.gg/bot/704400876860735569) | [Bot.gg](https://discord.bots.gg/bots/704400876860735569)", inline: true, }, ], diff --git a/src/commands/noAuth/announce.ts b/src/commands/noAuth/announce.ts index 46758546..53a71471 100644 --- a/src/commands/noAuth/announce.ts +++ b/src/commands/noAuth/announce.ts @@ -1,13 +1,20 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, GuildMember, TextChannel } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { + ChatInputCommandInteraction, + GuildMember, + TextChannel, +} from "npm:discord.js"; -import { createEmbed, messageHelp } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { createEmbed, messageHelp } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'announce'; -const DESCRIPTION = 'send an announcement to the announcement channel'; +const COMMAND_NAME = "announce"; +const DESCRIPTION = "make an announcement to the announcement channel"; export default { time: 2, @@ -18,30 +25,45 @@ export default { slashCommand: new SlashCommandBuilder() .setName(COMMAND_NAME) .setDescription(DESCRIPTION) - .addStringOption((option) => option.setName('title').setDescription('Announcement title').setRequired(true)) - .addStringOption((option) => option.setName('body').setDescription('Announcement body').setRequired(true)), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { - const title = interaction.options.getString('title'); - const body = interaction.options.getString('body'); + .addStringOption((option) => + option.setName("title").setDescription("Announcement title").setRequired( + true, + ) + ) + .addStringOption((option) => + option.setName("body").setDescription("Announcement body").setRequired( + true, + ) + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + const title = interaction.options.getString("title"); + const body = interaction.options.getString("body"); if (!title || !body) { return { result: false, - value: messageHelp('commands', 'announce'), + value: messageHelp("commands", "announce"), }; } - if (pGuild.announcement === '' || pGuild.announcement === 'null') { + if (pGuild.announcement === "" || pGuild.announcement === "null") { return { result: false, - value: messageHelp('commands', 'announce', 'there is no announcement channel'), + value: messageHelp( + "commands", + "announce", + "there is no announcement channel", + ), }; } if (!interaction.guild) { return { result: false, - value: 'message\'s guild could not be fetched', + value: "message's guild could not be fetched", }; } @@ -52,14 +74,18 @@ export default { if (!announcementChannel) { return { result: false, - value: messageHelp('commands', 'announce', 'announcements channel does not exist'), + value: messageHelp( + "commands", + "announce", + "announcements channel does not exist", + ), }; } const richMessage = createEmbed( title, `@here ${body}`, - '#022E4E', + "#022E4E", [], null, interaction.member as GuildMember, @@ -72,7 +98,9 @@ export default { return { result: !!outcome, - value: outcome ? 'announcement was sent successfully' : 'could not send message', + value: outcome + ? "announcement was sent successfully" + : "could not send message", }; }, } as Command; diff --git a/src/commands/noAuth/bet.ts b/src/commands/noAuth/bet.ts index d00fe159..56d9ffe4 100644 --- a/src/commands/noAuth/bet.ts +++ b/src/commands/noAuth/bet.ts @@ -1,15 +1,17 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import dayjs from 'dayjs'; -import { ChatInputCommandInteraction } from 'discord.js'; -import { RequestOptions } from 'https'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import dayjs from "npm:dayjs"; +import type { ChatInputCommandInteraction } from "npm:discord.js"; -import { createEmbed, getJSONFromString, messageHelp } from '../../libraries/help.library.js'; -import { httpsFetch } from '../../libraries/http.library.js'; -import { Command } from '../../types/Command.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { createEmbed, messageHelp } from "../../libraries/help.library.ts"; +import { httpsFetch } from "../../libraries/http.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'bet'; -const DESCRIPTION = 'returns betting data'; +const COMMAND_NAME = "bet"; +const DESCRIPTION = "returns betting data"; export default { time: 0, @@ -22,108 +24,108 @@ export default { .setDescription(DESCRIPTION) .addStringOption((option) => option - .setName('provider') - .setDescription('betting provider') + .setName("provider") + .setDescription("betting provider") .setRequired(true) - .addChoices({ name: 'OPAP', value: 'opap' }), + .addChoices({ name: "OPAP", value: "opap" }) ) .addNumberOption((option) => option - .setName('game') - .setDescription('betting game') + .setName("game") + .setDescription("betting game") .setRequired(true) .addChoices( - { name: 'KINO', value: 1100 }, - { name: 'PowerSpin', value: 1110 }, - { name: 'Super3', value: 2100 }, - { name: 'PROTO', value: 2101 }, - { name: 'LOTTO', value: 5103 }, - { name: 'Tzoker', value: 5104 }, - { name: 'extra5', value: 5106 }, - ), + { name: "KINO", value: 1100 }, + { name: "PowerSpin", value: 1110 }, + { name: "Super3", value: 2100 }, + { name: "PROTO", value: 2101 }, + { name: "LOTTO", value: 5103 }, + { name: "Tzoker", value: 5104 }, + { name: "extra5", value: 5106 }, + ) ), - async execute(interaction: ChatInputCommandInteraction): Promise { - const provider = interaction.options.getString('provider'); - const gameCode = interaction.options.getNumber('game'); + async execute( + interaction: ChatInputCommandInteraction, + ): Promise { + const provider = interaction.options.getString("provider"); + const gameCode = interaction.options.getNumber("game"); if (!provider) { return { result: false, - value: messageHelp('commands', 'bet', 'provider must be provided'), + value: messageHelp("commands", "bet", "provider must be provided"), }; } if (!gameCode) { return { result: false, - value: messageHelp('commands', 'bet', 'gameCode must be provided'), + value: messageHelp("commands", "bet", "gameCode must be provided"), }; } - const options: RequestOptions = { - method: 'GET', - hostname: 'api.opap.gr', - port: undefined, - path: `/draws/v3.0/${gameCode}/last-result-and-active`, + const url = new URL( + `https://api.opap.gr/draws/v3.0/${gameCode}/last-result-and-active`, + ); + + const response = await httpsFetch(url, { + method: "GET", headers: { - 'x-opap-host': 'api.opap.gr', - useQueryString: 1, + "x-opap-host": "api.opap.gr", + useQueryString: "1", }, - }; - - const response = await httpsFetch(options); - - if (!response) { - return { - result: false, - value: 'could not fetch data from OpenAPI', - }; - } + }); - const json = getJSONFromString(response.toString().substring(response.toString().indexOf('{'))); + const json = await response.json(); - if (json === null) { + if (!json) { return { result: false, - value: 'data from source is corrupted', + value: "could not parse data from OpenAPI", }; } const outcome = await interaction.reply({ embeds: [ createEmbed( - `${gameCode} from ${provider} | ${dayjs(json.last.drawTime).format('DD/MM/YY')}`, + `${gameCode} from ${provider} | ${ + dayjs(json.last.drawTime).format("DD/MM/YY") + }`, `powered by ${provider}`, - '#0384fc', + "#0384fc", [ { - emote: 'Winning Numbers', + emote: "Winning Numbers", // eslint-disable-next-line @typescript-eslint/no-unsafe-call - role: `${json.last.winningNumbers.list.map((n: number) => n).join(', ')}`, + role: `${ + json.last.winningNumbers.list.map((n: number) => n).join(", ") + }`, inline: true, }, { - emote: 'Tzoker', + emote: "Tzoker", role: `${json.last.winningNumbers.bonus}`, inline: true, }, { - emote: `${json.last.prizeCategories[0].winners > 1 ? 'Winners' : 'Winner'}`, + emote: `${ + json.last.prizeCategories[0].winners > 1 ? "Winners" : "Winner" + }`, role: `${json.last.prizeCategories[0].winners}`, inline: true, }, { - emote: 'Draw Number', + emote: "Draw Number", role: `${json.last.drawId}`, inline: true, }, { - emote: 'Columns Cast', + emote: "Columns Cast", role: `${json.last.wagerStatistics.columns}`, inline: true, }, { - emote: 'Wagers', + emote: "Wagers", role: `${json.last.wagerStatistics.wagers}`, inline: true, }, @@ -139,7 +141,7 @@ export default { return { result: !!outcome, - value: outcome ? '' : 'failed to send message', + value: outcome ? "" : "failed to send message", }; }, } as Command; diff --git a/src/commands/noAuth/corona.ts b/src/commands/noAuth/corona.ts index 01e438e7..0949d7c7 100644 --- a/src/commands/noAuth/corona.ts +++ b/src/commands/noAuth/corona.ts @@ -1,17 +1,27 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import dayjs from 'dayjs'; -import { ChatInputCommandInteraction, InteractionContextType } from 'discord.js'; -import { RequestOptions } from 'https'; -import voca from 'voca'; - -import { CountryCodes } from '../../assets/lists/countryCodesISO.static.js'; -import { createEmbed, getJSONFromString, messageHelp } from '../../libraries/help.library.js'; -import { httpsFetch } from '../../libraries/http.library.js'; -import { Command } from '../../types/Command.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; - -const COMMAND_NAME = 'corona'; -const DESCRIPTION = 'returns data on COVID19'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import "@std/dotenv/load"; +import dayjs from "npm:dayjs"; +import { + type ChatInputCommandInteraction, + InteractionContextType, +} from "npm:discord.js"; +import voca from "npm:voca"; + +import { CountryCodes } from "../../assets/lists/countryCodesISO.static.ts"; +import { + createEmbed, + getJSONFromString, + messageHelp, +} from "../../libraries/help.library.ts"; +import { httpsFetch } from "../../libraries/http.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; + +const COMMAND_NAME = "corona"; +const DESCRIPTION = "returns data on COVID19"; export default { time: 0, @@ -23,24 +33,28 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .addStringOption((option) => - option.setName('country').setDescription('The country you want to get corona data for').setRequired(true), + option.setName("country").setDescription( + "The country you want to get corona data for", + ).setRequired(true) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction): Promise { - if (!process.env.COVID_193) { + async execute( + interaction: ChatInputCommandInteraction, + ): Promise { + if (!Deno.env.get("COVID_193")) { return { result: false, - value: 'COVID_193 API key is not set up', + value: "COVID_193 API key is not set up", }; } let code: string | null = null; - const country = interaction.options.getString('country'); + const country = interaction.options.getString("country"); if (!country) { return { result: false, - value: messageHelp('commands', 'corona', 'country must be provided'), + value: messageHelp("commands", "corona", "country must be provided"), }; } @@ -49,34 +63,37 @@ export default { if (!code) { return { result: false, - value: messageHelp('commands', 'corona', `could not fetch code for country ${country}`), + value: messageHelp( + "commands", + "corona", + `could not fetch code for country ${country}`, + ), }; } - const options: RequestOptions = { - method: 'GET', - hostname: 'covid-193.p.rapidapi.com', - port: undefined, - path: '/statistics', + const url = new URL("https://covid-193.p.rapidapi.com/statistics"); + + const response = await httpsFetch(url, { + method: "GET", headers: { - 'x-rapidapi-host': 'covid-193.p.rapidapi.com', - 'x-rapidapi-key': process.env.COVID_193, - useQueryString: 1, + "x-rapidapi-host": "covid-193.p.rapidapi.com", + "x-rapidapi-key": Deno.env.get("COVID_193") || "", + "Accept": "application/json", }, - }; - - const response = await httpsFetch(options); + }); if (!response) { return { result: false, - value: 'could not fetch data from source', + value: "could not fetch data from source", }; } - const json = getJSONFromString(response.toString().substring(response.toString().indexOf('{'))); + const json = getJSONFromString( + response.toString().substring(response.toString().indexOf("{")), + ); - if (json.message === 'You are not subscribed to this API.') { + if (json.message === "You are not subscribed to this API.") { return { result: false, value: json.message, @@ -86,25 +103,27 @@ export default { if (!json) { return { result: false, - value: 'data from source was corrupted', + value: "data from source was corrupted", }; } if (json.errors && json.errors.length !== 0) { return { result: false, - value: 'source responded with errors', + value: "source responded with errors", }; } if (!json.response) { return { result: false, - value: 'source responded without data', + value: "source responded without data", }; } - const countryData = json.response.find((data: { country: string }) => data.country === code); + const countryData = json.response.find((data: { country: string }) => + data.country === code + ); if (!countryData) { return { @@ -116,52 +135,62 @@ export default { const outcome = await interaction.reply({ embeds: [ createEmbed( - `${countryData.country} | ${dayjs(countryData.time).format('DD/MM/YY')}`, - 'Covid19 stats by covid-193', - '#FF0000', + `${countryData.country} | ${ + dayjs(countryData.time).format("DD/MM/YY") + }`, + "Covid19 stats by covid-193", + "#FF0000", [ { - emote: 'NEW cases', - role: `${countryData.cases.new ? countryData.cases.new : 'N/A'}`, + emote: "NEW cases", + role: `${countryData.cases.new ? countryData.cases.new : "N/A"}`, inline: true, }, { - emote: 'NEW deaths', - role: `${countryData.deaths.new ? countryData.deaths.new : 'N/A'}`, + emote: "NEW deaths", + role: `${ + countryData.deaths.new ? countryData.deaths.new : "N/A" + }`, inline: true, }, { - emote: 'Tests P1M', - role: `${countryData.tests['1M_pop']}`, + emote: "Tests P1M", + role: `${countryData.tests["1M_pop"]}`, inline: true, }, { - emote: 'Cases', + emote: "Cases", role: `${countryData.cases.total}`, inline: true, }, { - emote: 'Deaths', + emote: "Deaths", role: `${countryData.deaths.total}`, inline: true, }, { - emote: 'Recovered', + emote: "Recovered", role: `${countryData.cases.recovered}`, inline: true, }, { - emote: '%Recovered', - role: `${((countryData.cases.recovered / countryData.cases.total) * 100).toFixed(2)}%`, + emote: "%Recovered", + role: `${ + ((countryData.cases.recovered / countryData.cases.total) * 100) + .toFixed(2) + }%`, inline: true, }, { - emote: '%Diseased', - role: `${((countryData.deaths.total / countryData.cases.total) * 100).toFixed(2)}%`, + emote: "%Diseased", + role: `${ + ((countryData.deaths.total / countryData.cases.total) * 100) + .toFixed(2) + }%`, inline: true, }, { - emote: 'Critical', + emote: "Critical", role: `${countryData.cases.critical}`, inline: true, }, @@ -177,7 +206,7 @@ export default { return { result: false, - value: outcome ? '' : 'failed to send message', + value: outcome ? "" : "failed to send message", }; }, } as Command; @@ -186,8 +215,11 @@ const countryCodes: { name: string; code: string }[] = CountryCodes; const getCountryCode = function (country: string): string | null { for (let i = 0; i < countryCodes.length; i++) { - if (voca.lowerCase(countryCodes[i].name) === voca.lowerCase(country)) return countryCodes[i].name; - else if (voca.lowerCase(countryCodes[i].code) === voca.lowerCase(country)) return countryCodes[i].name; + if (voca.lowerCase(countryCodes[i].name) === voca.lowerCase(country)) { + return countryCodes[i].name; + } else if ( + voca.lowerCase(countryCodes[i].code) === voca.lowerCase(country) + ) return countryCodes[i].name; } return null; diff --git a/src/commands/noAuth/crypto.ts b/src/commands/noAuth/crypto.ts index 0e69cfe1..b5d482c1 100644 --- a/src/commands/noAuth/crypto.ts +++ b/src/commands/noAuth/crypto.ts @@ -1,14 +1,25 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, InteractionContextType } from 'discord.js'; -import { RequestOptions } from 'https'; -import voca from 'voca'; -import { createEmbed, getJSONFromString, messageHelp } from '../../libraries/help.library.js'; -import { httpsFetch } from '../../libraries/http.library.js'; -import { Command } from '../../types/Command.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import "@std/dotenv/load"; +import { + type ChatInputCommandInteraction, + InteractionContextType, +} from "npm:discord.js"; +import voca from "npm:voca"; -const COMMAND_NAME = 'crypto'; -const DESCRIPTION = 'returns information about crypto currencies'; +import { + createEmbed, + getJSONFromString, + messageHelp, +} from "../../libraries/help.library.ts"; +import { httpsFetch } from "../../libraries/http.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; + +const COMMAND_NAME = "crypto"; +const DESCRIPTION = "returns information about crypto currencies"; export default { time: 0, @@ -20,74 +31,98 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .addStringOption((option) => - option.setName('crypto_name').setDescription('The `name of the crypto currency`').setRequired(true), + option.setName("crypto_name").setDescription( + "The `name of the crypto currency`", + ).setRequired(true) ) .addStringOption((option) => - option.setName('currency_name').setDescription('The name of the fiat currency to compare to').setRequired(true), + option.setName("currency_name").setDescription( + "The name of the fiat currency to compare to", + ).setRequired(true) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction): Promise { - if (!process.env.COIN_GECKO) { + async execute( + interaction: ChatInputCommandInteraction, + ): Promise { + if (!Deno.env.get("COIN_GECKO")) { return { result: false, - value: 'COIN_GECKO API key is not set up', + value: "COIN_GECKO API key is not set up", }; } - const cryptoName = interaction.options.getString('crypto_name'); - const currencyName = interaction.options.getString('currency_name'); + const cryptoName = interaction.options.getString("crypto_name"); + const currencyName = interaction.options.getString("currency_name"); if (!cryptoName || !currencyName) { return { result: false, - value: messageHelp('commands', 'crypto', 'crypto and fiat name must be provided'), + value: messageHelp( + "commands", + "crypto", + "crypto and fiat name must be provided", + ), }; } - const options: RequestOptions = { - method: 'GET', - hostname: 'coingecko.p.rapidapi.com', - port: undefined, - path: `/simple/price?ids=${cryptoName}&vs_currencies=${currencyName}`, + const url = new URL("https://coingecko.p.rapidapi.com/simple/price"); + url.searchParams.append("ids", cryptoName); + url.searchParams.append("vs_currencies", currencyName); + + const response = await httpsFetch(url, { + method: "GET", headers: { - 'x-rapidapi-host': 'coingecko.p.rapidapi.com', - 'x-rapidapi-key': process.env.COIN_GECKO, - useQueryString: 1, + "x-rapidapi-host": "coingecko.p.rapidapi.com", + "x-rapidapi-key": Deno.env.get("COIN_GECKO") || "", + "Accept": "application/json", }, - }; - - const response = await httpsFetch(options); + }); if (!response) { return { result: false, - value: 'could not fetch data from source', + value: "could not fetch data from source", }; } - const json = getJSONFromString(response.toString().substring(response.toString().indexOf('{'))); + const json = getJSONFromString( + response.toString().substring(response.toString().indexOf("{")), + ); if (!json) { return { result: false, - value: 'data from source was corrupted', + value: "data from source was corrupted", }; } const outcome = await interaction.reply({ embeds: [ - createEmbed(null, null, '#FFE600', null, null, null, false, null, null, undefined, { - name: `${voca.titleCase(cryptoName)} to ${voca.titleCase(currencyName)} price is ${ - json[cryptoName][currencyName] - }`, - icon: 'https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/coin.gif', - }), + createEmbed( + null, + null, + "#FFE600", + null, + null, + null, + false, + null, + null, + undefined, + { + name: `${voca.titleCase(cryptoName)} to ${ + voca.titleCase(currencyName) + } price is ${json[cryptoName][currencyName]}`, + icon: + "https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/coin.gif", + }, + ), ], }); return { result: !!outcome, - value: outcome ? '' : 'failed to send message', + value: outcome ? "" : "failed to send message", }; }, } as Command; diff --git a/src/commands/noAuth/focus.ts b/src/commands/noAuth/focus.ts index 7a15ce50..350f9a01 100644 --- a/src/commands/noAuth/focus.ts +++ b/src/commands/noAuth/focus.ts @@ -1,11 +1,28 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction } from 'discord.js'; -import { messageHelp } from '../../libraries/help.library.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; -import { Command } from '../../types/Command.js'; - -const COMMAND_NAME = 'focus'; -const DESCRIPTION = 'creates a dedicated channel for two users to privately talk in'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { ChatInputCommandInteraction } from "npm:discord.js"; +import { ButtonStyle, GuildMember } from "npm:discord.js"; + +import { + createFocusChannel, + includedInVoiceList, + moveMembersBack, +} from "../../libraries/guild.library.ts"; +import { + askForApprovalByMember, + messageHelp, +} from "../../libraries/help.library.ts"; +import { VoiceLibrary } from "../../libraries/voice.library.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import type { Command } from "../../types/Command.ts"; +import logger from "../../utilities/log.utility.ts"; + +const COMMAND_NAME = "focus"; +const DESCRIPTION = + "creates a dedicated channel for two users to privately talk in"; export default { time: 1, @@ -16,143 +33,212 @@ export default { slashCommand: new SlashCommandBuilder() .setName(COMMAND_NAME) .setDescription(DESCRIPTION) - .addUserOption((option) => option.setName('member').setDescription('member to focus on').setRequired(true)) - .addNumberOption((option) => option.setName('duration').setDescription('duration in seconds').setRequired(true)), - async execute(interaction: ChatInputCommandInteraction): Promise { - const member = interaction.options.getMember('member'); - const duration = interaction.options.getNumber('duration'); + .addUserOption((option) => + option.setName("member").setDescription("member to focus on").setRequired( + true, + ) + ) + .addNumberOption((option) => + option.setName("duration").setDescription("duration in seconds") + .setRequired(true) + ), + // .addStringOption((option) => + // option.setName("name").setDescription("focus channel name") + // .setRequired(false) + // ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + const memberToFocus = interaction.options.getMember("member"); + if (!memberToFocus) { + return { + result: false, + value: messageHelp("commands", COMMAND_NAME, "user must be provided"), + }; + } + if (!(memberToFocus instanceof GuildMember)) { + return { + result: false, + value: messageHelp("commands", COMMAND_NAME, "could not find member"), + }; + } + + const member = interaction.member; if (!member) { return { result: false, - value: messageHelp('commands', COMMAND_NAME, 'user must be provided'), + value: messageHelp("commands", COMMAND_NAME, "could not find member"), + }; + } + + if (!(member instanceof GuildMember)) { + logger.info("member is not a guild member instance"); + return { + result: false, + value: messageHelp( + "commands", + COMMAND_NAME, + "you must be a guild member", + ), + }; + } + + if (member === memberToFocus) { + return { + result: false, + value: messageHelp( + "commands", + COMMAND_NAME, + "you can't focus on yourself", + ), + }; + } + + const duration = interaction.options.getNumber("duration") ?? (5 * 60); + + const voiceBasedChannel = VoiceLibrary.getVoiceChannelByMember(member); + if (!voiceBasedChannel) { + return { + result: false, + value: messageHelp( + "commands", + COMMAND_NAME, + "user not in voice channel", + ), + }; + } + + if (!includedInVoiceList(voiceBasedChannel.id, pGuild.pChannels)) { + return { + result: false, + value: messageHelp( + "commands", + COMMAND_NAME, + "lel the channel you are in is not handled by Portal", + ), + }; + } + + if (voiceBasedChannel.members.size <= 2) { + return { + result: false, + value: messageHelp( + "commands", + COMMAND_NAME, + "you can *only* use focus in channels with *more* than 2 members", + ), + }; + } + + if ( + voiceBasedChannel.members.some((m) => m.id === memberToFocus.id) + ) { + return { + result: false, + value: messageHelp( + "commands", + COMMAND_NAME, + "user to focus not in voice channel", + ), + }; + } + + const gotApproval = await askForApprovalByMember( + memberToFocus, + `*${memberToFocus.user}, member ${interaction.user}, would like to talk in ` + + `private${ + duration === 0 ? "" : ` for ${duration}'` + }*, do you **(yes / no)** ?`, + ButtonStyle.Success, + ); + + if (!gotApproval) { + return { + result: false, + value: messageHelp( + "commands", + COMMAND_NAME, + "user declined the request", + ), + }; + } + + if (!interaction.guild) { + return { + result: false, + value: messageHelp( + "commands", + COMMAND_NAME, + "could not fetch message's guild", + ), }; } - if (!duration) { + if (!memberToFocus) { return { result: false, - value: messageHelp('commands', COMMAND_NAME, 'duration must be provided'), + value: messageHelp( + "commands", + COMMAND_NAME, + "could not fetch message's member", + ), }; } + const pChannel = pGuild.pChannels.find((p) => + p.pVoiceChannels.some((v) => v.id === memberToFocus?.voice.channel?.id) + ); + + if (!pChannel) { + return { + result: false, + value: messageHelp( + "commands", + COMMAND_NAME, + "could not find member's portal channel", + ), + }; + } + + const oldChannel = voiceBasedChannel; + const focusChannelOutcome = await createFocusChannel( + interaction.guild, + memberToFocus, + memberToFocus, + duration, + pChannel, + ); + + setTimeout(async () => { + if (!memberToFocus) { + return { + result: false, + value: messageHelp( + "commands", + COMMAND_NAME, + "could not fetch message's member", + ), + }; + } + + const movedMembers = await moveMembersBack( + oldChannel, + memberToFocus, + memberToFocus, + ).catch((e) => { + logger.error(`commands.focus.error on moving members back: ${e}`); + }); + + if (!movedMembers) { + logger.error("could not move members back"); + } + }, duration * 60 * 1000); + return { - result: false, - value: 'focus is currently disabled', + result: true, + value: focusChannelOutcome, }; - - // if (!member.voice.channel) { - // return Promise.reject(messageHelp('commands', 'focus', 'you must be in a channel handled by Portal')); - // } - - // if (!includedInVoiceList(member.voice.channel.id, pGuild.pChannels)) { - // return Promise.reject(messageHelp('commands', 'focus', 'the channel you are in is not handled by Portal')); - // } - - // if (member.voice.channel.members.size <= 2) { - // return Promise.reject( - // messageHelp('commands', 'focus', 'you can *only* use focus in channels with *more* than 2 members') - // ); - // } - - // const argA = args - // .join(' ') - // .substring(0, args.join(' ').indexOf('|') - 1) - // .replace(/\s/g, ' '); - // const argB = args.join(' ').substring(args.join(' ').indexOf('|')).replace(/\s/g, ' '); - - // const focusName = (argA === '' ? argB : argA).trim(); - // const focusTime = argA === '' ? 0 : parseFloat(argB); - - // if (isNaN(focusTime)) { - // return Promise.reject(messageHelp('commands', 'focus', 'focus time must be a number')); - // } - - // if (!interaction.mentions) { - // return Promise.reject('no user mentioned to focus'); - // } - - // if (!interaction.mentions.members) { - // return Promise.reject('no user mentioned to focus'); - // } - - // if (!interaction.guild) { - // return Promise.reject('user guild could not be fetched'); - // } - - // if (interaction.mentions.members.size === 0) { - // return Promise.reject(messageHelp('commands', 'focus', 'you must tag a member')); - // } - - // const memberToFocus = interaction.mentions.members.first() || interaction.guild.members.cache.get(args[0]); - - // if (!memberToFocus) { - // return Promise.reject(`could not find "**${focusName}**" in current voice channel`); - // } - - // if (member === memberToFocus) { - // return Promise.reject(messageHelp('commands', 'focus', 'you can\'t focus on yourself')); - // } - - // if (member.voice.channel !== memberToFocus.voice.channel) { - // return Promise.reject(messageHelp('commands', 'focus', 'you can\'t focus on user from another channel')); - // } - - // const gotApproval = await askForApproval( - // interaction, - // memberToFocus, - // `*${memberToFocus.user}, member ${interaction.user}, would like to talk in ` + - // `private${focusTime === 0 ? '' : ` for ${focusTime}'`}*, do you **(yes / no)** ?` - // ).catch((e) => { - // return Promise.reject(`failed to get approval: ${e}`); - // }); - - // if (!gotApproval) { - // return Promise.reject('user declined the request'); - // } - - // if (!interaction.guild) { - // return Promise.reject('could not fetch message\'s guild'); - // } - - // if (!member) { - // return Promise.reject('could not fetch message\'s member'); - // } - - // const pChannel = pGuild.pChannels.find((p) => p.pVoiceChannels.some((v) => v.id === member?.voice.channel?.id)); - - // if (!pChannel) { - // return Promise.reject('could not find member\'s portal channel'); - // } - - // const oldChannel = member.voice.channel; - // const focusChannelOutcome = await createFocusChannel( - // interaction.guild, - // member, - // memberToFocus, - // focusTime, - // pChannel - // ).catch((e) => { - // return Promise.reject(`error while creating focus channel ${e}`); - // }); - - // setTimeout(async () => { - // if (!member) { - // return Promise.reject('could not fetch message\'s member'); - // } - - // const movedMembers = await moveMembersBack(oldChannel, member, memberToFocus).catch((e) => { - // return Promise.reject(e); - // }); - - // if (!movedMembers) { - // return Promise.reject('could not move members back'); - // } - // }, focusTime * 60 * 1000); - - // return { - // result: true, - // value: focusChannelOutcome, - // }; }, } as Command; diff --git a/src/commands/noAuth/help.ts b/src/commands/noAuth/help.ts index 00f65ad5..d780f50c 100644 --- a/src/commands/noAuth/help.ts +++ b/src/commands/noAuth/help.ts @@ -1,17 +1,21 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, EmbedBuilder } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { type ChatInputCommandInteraction, EmbedBuilder } from "npm:discord.js"; -import { createEmbed, messageHelp } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { Field, ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; -import { AttributeDocumentation } from './help/AttributeDocumentation.js'; -import { CommandDocumentation } from './help/CommandDocumentation.js'; -import { PipeDocumentation } from './help/PipeDocumentation.js'; -import { StructureDocumentation } from './help/StructureDocumentation.js'; -import { VariableDocumentation } from './help/VariableDocumentation.js'; +import { createEmbed, messageHelp } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type Field, + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import { AttributeDocumentation } from "./help/AttributeDocumentation.ts"; +import { CommandDocumentation } from "./help/CommandDocumentation.ts"; +import { PipeDocumentation } from "./help/PipeDocumentation.ts"; +import { StructureDocumentation } from "./help/StructureDocumentation.ts"; +import { VariableDocumentation } from "./help/VariableDocumentation.ts"; -const COMMAND_NAME = 'help'; -const DESCRIPTION = 'returns requested help page'; +const COMMAND_NAME = "help"; +const DESCRIPTION = "returns requested help page"; export default { time: 0, @@ -24,206 +28,213 @@ export default { .setDescription(DESCRIPTION) .addStringOption((option) => option - .setName('category') - .setDescription('Category to get help for') + .setName("category") + .setDescription("Category to get help for") .setRequired(true) .addChoices( - { name: 'All', value: 'all' }, - { name: 'Command description', value: 'description_commands' }, - { name: 'Variable description', value: 'description_variables' }, - { name: 'Pipe description', value: 'description_pipes' }, - { name: 'Attribute description', value: 'description_attributes' }, - { name: 'Structure description', value: 'description_structures' }, - { name: 'Command guide', value: 'guide_commands' }, - { name: 'Variable guide', value: 'guide_variables' }, - { name: 'Pipe guide', value: 'guide_pipes' }, - { name: 'Attribute guide', value: 'guide_attributes' }, - { name: 'Structure guide', value: 'guide_structures' }, - ), + { name: "All", value: "all" }, + { name: "Command description", value: "description_commands" }, + { name: "Variable description", value: "description_variables" }, + { name: "Pipe description", value: "description_pipes" }, + { name: "Attribute description", value: "description_attributes" }, + { name: "Structure description", value: "description_structures" }, + { name: "Command guide", value: "guide_commands" }, + { name: "Variable guide", value: "guide_variables" }, + { name: "Pipe guide", value: "guide_pipes" }, + { name: "Attribute guide", value: "guide_attributes" }, + { name: "Structure guide", value: "guide_structures" }, + ) ) .addStringOption((option) => option - .setName('command_unauthorised') - .setDescription('Command to get help for') + .setName("command_unauthorised") + .setDescription("Command to get help for") .setRequired(false) .addChoices( - { name: 'about', value: 'about' }, - { name: 'announce', value: 'announce' }, - { name: 'bet', value: 'bet' }, - { name: 'corona', value: 'corona' }, - { name: 'crypto', value: 'crypto' }, - { name: 'focus', value: 'focus' }, - { name: 'help', value: 'help' }, - { name: 'join', value: 'join' }, - { name: 'leaderboard', value: 'leaderboard' }, - { name: 'leave', value: 'leave' }, - { name: 'level', value: 'level' }, - { name: 'ping', value: 'ping' }, - { name: 'poll', value: 'poll' }, - { name: 'ranks', value: 'ranks' }, - { name: 'roll', value: 'roll' }, - { name: 'run', value: 'run' }, - { name: 'state', value: 'state' }, - { name: 'spam_rules', value: 'spam_rules' }, - { name: 'weather', value: 'weather' }, - { name: 'whoami', value: 'whoami' }, - ), + { name: "about", value: "about" }, + { name: "announce", value: "announce" }, + { name: "bet", value: "bet" }, + { name: "corona", value: "corona" }, + { name: "crypto", value: "crypto" }, + { name: "focus", value: "focus" }, + { name: "help", value: "help" }, + { name: "join", value: "join" }, + { name: "leaderboard", value: "leaderboard" }, + { name: "leave", value: "leave" }, + { name: "level", value: "level" }, + { name: "ping", value: "ping" }, + { name: "poll", value: "poll" }, + { name: "ranks", value: "ranks" }, + { name: "roll", value: "roll" }, + { name: "run", value: "run" }, + { name: "state", value: "state" }, + { name: "spam_rules", value: "spam_rules" }, + { name: "weather", value: "weather" }, + { name: "whoami", value: "whoami" }, + ) ) .addStringOption((option) => option - .setName('command_authorised') - .setDescription('Command to get help for') + .setName("command_authorised") + .setDescription("Command to get help for") .setRequired(false) .addChoices( - { name: 'announcement', value: 'announcement' }, - { name: 'ban', value: 'ban' }, - { name: 'delete_messages', value: 'delete_messages' }, - { name: 'force', value: 'force' }, - { name: 'ignore', value: 'ignore' }, - { name: 'invite', value: 'invite' }, - { name: 'kick', value: 'kick' }, - { name: 'music', value: 'music' }, - { name: 'portal', value: 'portal' }, - { name: 'vendor', value: 'vendor' }, - { name: 'set_ranks', value: 'set_ranks' }, - { name: 'set', value: 'set' }, - { name: 'url', value: 'url' }, - ), + { name: "announcement", value: "announcement" }, + { name: "ban", value: "ban" }, + { name: "delete_messages", value: "delete_messages" }, + { name: "force", value: "force" }, + { name: "ignore", value: "ignore" }, + { name: "invite", value: "invite" }, + { name: "kick", value: "kick" }, + { name: "music", value: "music" }, + { name: "portal", value: "portal" }, + { name: "vendor", value: "vendor" }, + { name: "set_ranks", value: "set_ranks" }, + { name: "set", value: "set" }, + { name: "url", value: "url" }, + ) ) .addStringOption((option) => option - .setName('variable') - .setDescription('Variable to get help for') + .setName("variable") + .setDescription("Variable to get help for") .setRequired(false) .addChoices( - { name: '##', value: '##' }, - { name: '#', value: '#' }, - { name: 'creatorPortal', value: 'creatorPortal' }, - { name: 'creatorVoice', value: 'creatorVoice' }, - { name: 'date', value: 'date' }, - { name: 'dayNumber', value: 'dayNumber' }, - { name: 'dayName', value: 'dayName' }, - { name: 'monthNumber', value: 'monthNumber' }, - { name: 'monthName', value: 'monthName' }, - { name: 'year', value: 'year' }, - { name: 'time', value: 'time' }, - { name: 'hour', value: 'hour' }, - { name: 'minute', value: 'minute' }, - { name: 'second', value: 'second' }, - { name: 'memberActiveCount', value: 'memberActiveCount' }, - { name: 'memberCount', value: 'memberCount' }, - { name: 'memberHistory', value: 'memberHistory' }, - { name: 'pMembers', value: 'pMembers' }, - { name: 'memberWithStatus', value: 'memberWithStatus' }, - { name: 'statusCount', value: 'statusCount' }, - { name: 'statusHistory', value: 'statusHistory' }, - { name: 'statusList', value: 'statusList' }, - ), + { name: "##", value: "##" }, + { name: "#", value: "#" }, + { name: "creatorPortal", value: "creatorPortal" }, + { name: "creatorVoice", value: "creatorVoice" }, + { name: "date", value: "date" }, + { name: "dayNumber", value: "dayNumber" }, + { name: "dayName", value: "dayName" }, + { name: "monthNumber", value: "monthNumber" }, + { name: "monthName", value: "monthName" }, + { name: "year", value: "year" }, + { name: "time", value: "time" }, + { name: "hour", value: "hour" }, + { name: "minute", value: "minute" }, + { name: "second", value: "second" }, + { name: "memberActiveCount", value: "memberActiveCount" }, + { name: "memberCount", value: "memberCount" }, + { name: "memberHistory", value: "memberHistory" }, + { name: "pMembers", value: "pMembers" }, + { name: "memberWithStatus", value: "memberWithStatus" }, + { name: "statusCount", value: "statusCount" }, + { name: "statusHistory", value: "statusHistory" }, + { name: "statusList", value: "statusList" }, + ) ) .addStringOption((option) => option - .setName('pipe') - .setDescription('Pipe to get help for') + .setName("pipe") + .setDescription("Pipe to get help for") .setRequired(false) .addChoices( - { name: 'acronym', value: 'acronym' }, - { name: 'vowels', value: 'vowels' }, - { name: 'consonants', value: 'consonants' }, - { name: 'camelCase', value: 'camelCase' }, - { name: 'capitalise', value: 'capitalise' }, - { name: 'decapitalise', value: 'decapitalise' }, - { name: 'lowerCase', value: 'lowerCase' }, - { name: 'upperCase', value: 'upperCase' }, - { name: 'populous_count', value: 'populous_count' }, - { name: 'populous', value: 'populous' }, - { name: 'snakeCase', value: 'snakeCase' }, - { name: 'souvlakiCase', value: 'souvlakiCase' }, - { name: 'words', value: 'words' }, - { name: 'titleCase', value: 'titleCase' }, - { name: 'length', value: 'length' }, - ), + { name: "acronym", value: "acronym" }, + { name: "vowels", value: "vowels" }, + { name: "consonants", value: "consonants" }, + { name: "camelCase", value: "camelCase" }, + { name: "capitalise", value: "capitalise" }, + { name: "decapitalise", value: "decapitalise" }, + { name: "lowerCase", value: "lowerCase" }, + { name: "upperCase", value: "upperCase" }, + { name: "populous_count", value: "populous_count" }, + { name: "populous", value: "populous" }, + { name: "snakeCase", value: "snakeCase" }, + { name: "souvlakiCase", value: "souvlakiCase" }, + { name: "words", value: "words" }, + { name: "titleCase", value: "titleCase" }, + { name: "length", value: "length" }, + ) ) .addStringOption((option) => option - .setName('attribute') - .setDescription('Attribute to get help for') + .setName("attribute") + .setDescription("Attribute to get help for") .setRequired(false) .addChoices( - { name: 'All', value: 'all' }, - { name: 'Command description', value: 'description_commands' }, - { name: 'Variable description', value: 'description_variables' }, - { name: 'Pipe description', value: 'description_pipes' }, - { name: 'Attribute description', value: 'description_attributes' }, - { name: 'Structure description', value: 'description_structures' }, - { name: 'Command guide', value: 'guide_commands' }, - { name: 'Variable guide', value: 'guide_variables' }, - { name: 'Pipe guide', value: 'guide_pipes' }, - { name: 'Attribute guide', value: 'guide_attributes' }, - { name: 'Structure guide', value: 'guide_structures' }, - ), + { name: "All", value: "all" }, + { name: "Command description", value: "description_commands" }, + { name: "Variable description", value: "description_variables" }, + { name: "Pipe description", value: "description_pipes" }, + { name: "Attribute description", value: "description_attributes" }, + { name: "Structure description", value: "description_structures" }, + { name: "Command guide", value: "guide_commands" }, + { name: "Variable guide", value: "guide_variables" }, + { name: "Pipe guide", value: "guide_pipes" }, + { name: "Attribute guide", value: "guide_attributes" }, + { name: "Structure guide", value: "guide_structures" }, + ) ) .addStringOption((option) => option - .setName('structure') - .setDescription('Structure to get help for') + .setName("structure") + .setDescription("Structure to get help for") .setRequired(false) .addChoices( - { name: 'annAnnounce', value: 'annAnnounce' }, - { name: 'noBots', value: 'noBots' }, - { name: 'allowedRoles', value: 'allowedRoles' }, - { name: 'render', value: 'render' }, - { name: 'annUser', value: 'annUser' }, - { name: 'bitrate', value: 'bitrate' }, - { name: 'kickAfter', value: 'kickAfter' }, - { name: 'banAfter', value: 'banAfter' }, - { name: 'prefix', value: 'prefix' }, - { name: 'muteRole', value: 'muteRole' }, - { name: 'rankSpeed', value: 'rankSpeed' }, - { name: 'profanityLevel', value: 'profanityLevel' }, - { name: 'initialRole', value: 'initialRole' }, - { name: 'locale', value: 'locale' }, - { name: 'position', value: 'position' }, - { name: 'regexOverwrite', value: 'regexOverwrite' }, - { name: 'regexPortal', value: 'regexPortal' }, - { name: 'regexVoice', value: 'regexVoice' }, - { name: 'regex', value: 'regex' }, - { name: 'userLimitPortal', value: 'userLimitPortal' }, - { name: 'userLimit', value: 'userLimit' }, - ), + { name: "annAnnounce", value: "annAnnounce" }, + { name: "noBots", value: "noBots" }, + { name: "allowedRoles", value: "allowedRoles" }, + { name: "render", value: "render" }, + { name: "annUser", value: "annUser" }, + { name: "bitrate", value: "bitrate" }, + { name: "kickAfter", value: "kickAfter" }, + { name: "banAfter", value: "banAfter" }, + { name: "prefix", value: "prefix" }, + { name: "muteRole", value: "muteRole" }, + { name: "rankSpeed", value: "rankSpeed" }, + { name: "profanityLevel", value: "profanityLevel" }, + { name: "initialRole", value: "initialRole" }, + { name: "locale", value: "locale" }, + { name: "position", value: "position" }, + { name: "regexOverwrite", value: "regexOverwrite" }, + { name: "regexPortal", value: "regexPortal" }, + { name: "regexVoice", value: "regexVoice" }, + { name: "regex", value: "regex" }, + { name: "userLimitPortal", value: "userLimitPortal" }, + { name: "userLimit", value: "userLimit" }, + ) ), - async execute(interaction: ChatInputCommandInteraction): Promise { - const category = interaction.options.getString('category'); - const command_unauthorised = interaction.options.getString('command_unauthorised'); - const command_authorised = interaction.options.getString('command_authorised'); - const variable = interaction.options.getString('variable'); - const pipe = interaction.options.getString('pipe'); - const attribute = interaction.options.getString('attribute'); - const structure = interaction.options.getString('structure'); - const specific = command_unauthorised ?? command_authorised ?? variable ?? pipe ?? attribute ?? structure; + async execute( + interaction: ChatInputCommandInteraction, + ): Promise { + const category = interaction.options.getString("category"); + const command_unauthorised = interaction.options.getString( + "command_unauthorised", + ); + const command_authorised = interaction.options.getString( + "command_authorised", + ); + const variable = interaction.options.getString("variable"); + const pipe = interaction.options.getString("pipe"); + const attribute = interaction.options.getString("attribute"); + const structure = interaction.options.getString("structure"); + const specific = command_unauthorised ?? command_authorised ?? variable ?? + pipe ?? attribute ?? structure; if (!category) { return { result: false, - value: messageHelp('commands', 'help', 'category must be provided'), + value: messageHelp("commands", "help", "category must be provided"), }; } - if (category === 'all') { + if (category === "all") { const response = await simpleReply(); return { result: !!response, value: response }; } - if (category.startsWith('description')) { - const response = await propertyReply(category.split('_')[1], specific); + if (category.startsWith("description")) { + const response = await propertyReply(category.split("_")[1], specific); return { result: !!response, value: response }; } - if (category.startsWith('guide')) { - const response = await guideReply(category.split('_')[1]); + if (category.startsWith("guide")) { + const response = await guideReply(category.split("_")[1]); return { result: !!response, value: response }; } - return { result: false, value: messageHelp('commands', 'help') }; + return { result: false, value: messageHelp("commands", "help") }; }, } as Command; @@ -236,78 +247,78 @@ const structureDocumentation = new StructureDocumentation(); const helpArray: Field[] = [ { emote: null, - role: '**[Commands](https://portal-bot.xyz/docs/commands/description)**', + role: "**[Commands](https://portal-bot.xyz/docs/commands/description)**", inline: false, }, { - emote: '`./help commands` or `./help commands guide`', - role: 'Commands are mini programs you can use to get a response or action\n', + emote: "`./help commands` or `./help commands guide`", + role: + "Commands are mini programs you can use to get a response or action\n", inline: false, }, { emote: null, - role: '**[Text Interpreter](https://portal-bot.xyz/docs/interpreter/description)**', + role: + "**[Text Interpreter](https://portal-bot.xyz/docs/interpreter/description)**", inline: false, }, { - emote: '`./help variables` or `./help variables guide`', - role: - 'Variables are live data about the current state of things\n' + - '_for more click [here](https://portal-bot.xyz/docs/interpreter/objects/variables/description)_', + emote: "`./help variables` or `./help variables guide`", + role: "Variables are live data about the current state of things\n" + + "_for more click [here](https://portal-bot.xyz/docs/interpreter/objects/variables/description)_", inline: false, }, { - emote: '`./help pipes` or `./help pipes guide`', + emote: "`./help pipes` or `./help pipes guide`", role: - 'Pipes are mini-programs that manipulate text or even variables and attributes\n' + - '_for more click [here](https://portal-bot.xyz/docs/interpreter/objects/pipes/description)_', + "Pipes are mini-programs that manipulate text or even variables and attributes\n" + + "_for more click [here](https://portal-bot.xyz/docs/interpreter/objects/pipes/description)_", inline: false, }, { - emote: '`./help attributes` or `./help attributes guide`', + emote: "`./help attributes` or `./help attributes guide`", role: - 'Attributes are options that can be altered with **[set](https://portal-bot.xyz/docs/commands/detailed/set)** command\n' + - '_for more click [here](https://portal-bot.xyz/docs/interpreter/objects/attributes/description)_', + "Attributes are options that can be altered with **[set](https://portal-bot.xyz/docs/commands/detailed/set)** command\n" + + "_for more click [here](https://portal-bot.xyz/docs/interpreter/objects/attributes/description)_", inline: false, }, { - emote: '`./help structures` or `./help structures guide`', - role: - 'Structures are rules to further manipulate the text outcome\n' + - '_for more click [here](https://portal-bot.xyz/docs/interpreter/objects/structures/description)_', + emote: "`./help structures` or `./help structures guide`", + role: "Structures are rules to further manipulate the text outcome\n" + + "_for more click [here](https://portal-bot.xyz/docs/interpreter/objects/structures/description)_", inline: false, }, { emote: null, - role: 'Specific help', + role: "Specific help", inline: false, }, { - emote: '`./help `', - role: - 'If you want to get a complete description of any property\n' + - '_(lets say you want to learn more about variables year, just type **./help year**)_', + emote: "`./help `", + role: "If you want to get a complete description of any property\n" + + "_(lets say you want to learn more about variables year, just type **./help year**)_", inline: false, }, { emote: null, - role: '**[FAQ](https://portal-bot.xyz/help#faq)** _frequently asked questioned_', + role: + "**[FAQ](https://portal-bot.xyz/help#faq)** _frequently asked questioned_", inline: false, }, ]; -async function simpleReply() { +function simpleReply() { const helpMessage = [ createEmbed( - 'Help Card', - 'Detailed documentation at [portal-bot.xyz/docs](https://portal-bot.xyz/docs)\n\n' + - '> make a member an **admin**, give role `p.admin`\n' + - '> make a member an **moderator**, give role `p.mod`\n' + - '> make a member a **dj**, give role `p.dj`\n' + - '> to **whitelist** a member, give role `p.mod`\n' + - '> to **ignore** a member, give role `p.ignore`\n' + - '> for more click [here](https://portal-bot.xyz/help#q-how-can-i-give-members-authority)', - '#05d1ff', + "Help Card", + "Detailed documentation at [portal-bot.xyz/docs](https://portal-bot.xyz/docs)\n\n" + + "> make a member an **admin**, give role `p.admin`\n" + + "> make a member an **moderator**, give role `p.mod`\n" + + "> make a member a **dj**, give role `p.dj`\n" + + "> to **whitelist** a member, give role `p.mod`\n" + + "> to **ignore** a member, give role `p.ignore`\n" + + "> for more click [here](https://portal-bot.xyz/help#q-how-can-i-give-members-authority)", + "#05d1ff", helpArray, null, null, @@ -320,10 +331,9 @@ async function simpleReply() { return helpMessage; } -async function propertyReply(type: string, specific: string | null) { +function propertyReply(type: string, specific: string | null) { if (specific) { - const detailed = - commandDocumentation.getHelpDetailed(specific) || + const detailed = commandDocumentation.getHelpDetailed(specific) || variableDocumentation.getHelpDetailed(specific) || pipeDocumentation.getHelpDetailed(specific) || attributeDocumentation.getHelpDetailed(specific) || @@ -332,49 +342,57 @@ async function propertyReply(type: string, specific: string | null) { if (detailed instanceof EmbedBuilder) { return [detailed]; } else { - return messageHelp('commands', 'help', `*${specific}* does not exist in portal`); + return messageHelp( + "commands", + "help", + `*${specific}* does not exist in portal`, + ); } } switch (type) { - case 'commands': - return commandDocumentation.getHelp(); - case 'variables': - return variableDocumentation.getHelp(); - case 'pipes': - return pipeDocumentation.getHelp(); - case 'attributes': - return attributeDocumentation.getHelp(); - case 'structures': - return structureDocumentation.getHelp(); + case "commands": + return commandDocumentation.getHelp(); + case "variables": + return variableDocumentation.getHelp(); + case "pipes": + return pipeDocumentation.getHelp(); + case "attributes": + return attributeDocumentation.getHelp(); + case "structures": + return structureDocumentation.getHelp(); } - return messageHelp('commands', 'help', `*${type}* does not exist in portal`); + return messageHelp("commands", "help", `*${type}* does not exist in portal`); } -async function guideReply(type: string) { +function guideReply(type: string) { let guide: EmbedBuilder | null = null; switch (type) { - case 'commands': - guide = commandDocumentation.getGuide(); - break; - case 'variables': - guide = variableDocumentation.getGuide(); - break; - case 'pipes': - guide = pipeDocumentation.getGuide(); - break; - case 'attributes': - guide = attributeDocumentation.getGuide(); - break; - case 'structures': - guide = structureDocumentation.getGuide(); - break; + case "commands": + guide = commandDocumentation.getGuide(); + break; + case "variables": + guide = variableDocumentation.getGuide(); + break; + case "pipes": + guide = pipeDocumentation.getGuide(); + break; + case "attributes": + guide = attributeDocumentation.getGuide(); + break; + case "structures": + guide = structureDocumentation.getGuide(); + break; } if (!guide) { - return messageHelp('commands', 'help', `*${type}* does not exist in portal`); + return messageHelp( + "commands", + "help", + `*${type}* does not exist in portal`, + ); } return [guide]; diff --git a/src/commands/noAuth/help/AttributeDocumentation.ts b/src/commands/noAuth/help/AttributeDocumentation.ts index 7d4d03f0..00e9deb8 100644 --- a/src/commands/noAuth/help/AttributeDocumentation.ts +++ b/src/commands/noAuth/help/AttributeDocumentation.ts @@ -1,62 +1,72 @@ -import { EmbedBuilder } from 'discord.js'; +import type { EmbedBuilder } from "npm:discord.js"; -import { AttributeBlueprints } from '../../../blueprints/attribute.blueprint.js'; -import { createEmbed } from '../../../libraries/help.library.js'; -import { Field, HelpDocumentation } from '../../../types/classes/PTypes.interface.js'; -import { Prefix } from '../../../types/enums/Prefix.enum.js'; +import { AttributeBlueprints } from "../../../blueprints/attribute.blueprint.ts"; +import { createEmbed } from "../../../libraries/help.library.ts"; +import type { + Field, + HelpDocumentation, +} from "../../../types/classes/PTypes.interface.ts"; +import { Prefix } from "../../../types/enums/Prefix.enum.ts"; -const PORTAL_URL = 'https://portal-bot.xyz/docs'; -const INTERPRETER_URL = '/interpreter/objects'; +const PORTAL_URL = "https://portal-bot.xyz/docs"; +const INTERPRETER_URL = "/interpreter/objects"; export class AttributeDocumentation implements HelpDocumentation { public getGuide(): EmbedBuilder { const attrArray: Field[] = [ { - emote: 'Used in Regex Interpreter', - role: '*used by channel name (regex, regexVoice, regexPortal) and run command*', + emote: "Used in Regex Interpreter", + role: + "*used by channel name (regex, regexVoice, regexPortal) and run command*", inline: true, }, { - emote: 'attributes are mutable data options', - role: '*options correspond to server, portal or voice channels*', + emote: "attributes are mutable data options", + role: "*options correspond to server, portal or voice channels*", inline: true, }, { - emote: '1.\tIn any text channel execute command `./run`', - role: './run just like channel name generation uses the text interpreter', + emote: "1.\tIn any text channel execute command `./run`", + role: + "./run just like channel name generation uses the text interpreter", inline: false, }, { - emote: '2.\t`./run My set locale is = &g.locale`', - role: './run executes the given text and replies with the processed output', + emote: "2.\t`./run My set locale is = &g.locale`", + role: + "./run executes the given text and replies with the processed output", inline: false, }, { - emote: '3.\tAwait a reply from portal which will be gr, de or en', - role: '*The replied string will look like this: `My set locale is = gr`*', + emote: "3.\tAwait a reply from portal which will be gr, de or en", + role: + "*The replied string will look like this: `My set locale is = gr`*", inline: false, }, { - emote: '4.\t`./set g.locale de` (no prefix & needed)', - role: '*set command, updates the data of an attribute in this case **locale** to **de***', + emote: "4.\t`./set g.locale de` (no prefix & needed)", + role: + "*set command, updates the data of an attribute in this case **locale** to **de***", inline: false, }, { - emote: '5.\tWait for portal response which will be inform you if it was executed without issues', - role: '*portal will either confirm update or inform you of the error it faced*', + emote: + "5.\tWait for portal response which will be inform you if it was executed without issues", + role: + "*portal will either confirm update or inform you of the error it faced*", inline: false, }, ]; return createEmbed( - 'Attribute Guide', - '[Attributes](' + + "Attribute Guide", + "[Attributes](" + PORTAL_URL + INTERPRETER_URL + - '/attributes/description) ' + - 'are options that can be manipulated by whomever has clearance.\n' + - 'How to use attributes with the Text Interpreter', - '#FF5714', + "/attributes/description) " + + "are options that can be manipulated by whomever has clearance.\n" + + "How to use attributes with the Text Interpreter", + "#FF5714", attrArray, null, null, @@ -71,10 +81,16 @@ export class AttributeDocumentation implements HelpDocumentation { for (let l = 0; l <= AttributeBlueprints.length / 25; l++) { attributeArray[l] = []; - for (let i = 24 * l; i < AttributeBlueprints.length && i < 24 * (l + 1); i++) { + for ( + let i = 24 * l; + i < AttributeBlueprints.length && i < 24 * (l + 1); + i++ + ) { attributeArray[l].push({ emote: `${i + 1}. ${AttributeBlueprints[i].name}`, - role: `[hover or click](${this.getLink(AttributeBlueprints[i].name)} "${AttributeBlueprints[i].hover}")`, + role: `[hover or click](${ + this.getLink(AttributeBlueprints[i].name) + } "${AttributeBlueprints[i].hover}")`, inline: true, }); } @@ -83,15 +99,15 @@ export class AttributeDocumentation implements HelpDocumentation { return attributeArray.map((_attribute, index) => { if (index === 0) { return createEmbed( - 'Attributes', - '[Attributes](' + + "Attributes", + "[Attributes](" + PORTAL_URL + INTERPRETER_URL + - '/attributes/description) ' + - 'are options that can be manipulated by whomever has clearance.\n' + - 'Prefix: ' + + "/attributes/description) " + + "are options that can be manipulated by whomever has clearance.\n" + + "Prefix: " + Prefix.ATTRIBUTE, - '#FF5714', + "#FF5714", attributeArray[0], null, null, @@ -100,7 +116,17 @@ export class AttributeDocumentation implements HelpDocumentation { null, ); } else { - return createEmbed(null, null, '#FF5714', attributeArray[index], null, null, null, null, null); + return createEmbed( + null, + null, + "#FF5714", + attributeArray[index], + null, + null, + null, + null, + null, + ); } }); } @@ -111,13 +137,15 @@ export class AttributeDocumentation implements HelpDocumentation { return createEmbed( AttributeBlueprints[i].name, null, - '#FF5714', + "#FF5714", [ - { emote: 'Type', role: 'Attribute', inline: true }, - { emote: 'Prefix', role: `${Prefix.ATTRIBUTE}`, inline: true }, + { emote: "Type", role: "Attribute", inline: true }, + { emote: "Prefix", role: `${Prefix.ATTRIBUTE}`, inline: true }, { - emote: 'Description', - role: `[hover or click](${this.getLink(candidate)} "${AttributeBlueprints[i].hover}")`, + emote: "Description", + role: `[hover or click](${this.getLink(candidate)} "${ + AttributeBlueprints[i].hover + }")`, inline: true, }, ], @@ -134,15 +162,15 @@ export class AttributeDocumentation implements HelpDocumentation { } private getLink(attribute: string): string { - const url = PORTAL_URL + INTERPRETER_URL + '/attributes'; + const url = PORTAL_URL + INTERPRETER_URL + "/attributes"; - if (attribute.indexOf('g.') > -1) { + if (attribute.indexOf("g.") > -1) { return `${url}/detailed/global/${attribute}`; - } else if (attribute.indexOf('m.') > -1) { + } else if (attribute.indexOf("m.") > -1) { return `${url}/detailed/member/${attribute}`; - } else if (attribute.indexOf('p.') > -1) { + } else if (attribute.indexOf("p.") > -1) { return `${url}/detailed/portal/${attribute}`; - } else if (attribute.indexOf('v.') > -1) { + } else if (attribute.indexOf("v.") > -1) { return `${url}/detailed/voice/${attribute}`; } else { return `${url}/description`; diff --git a/src/commands/noAuth/help/CommandDocumentation.ts b/src/commands/noAuth/help/CommandDocumentation.ts index fc767fb7..eadf500d 100644 --- a/src/commands/noAuth/help/CommandDocumentation.ts +++ b/src/commands/noAuth/help/CommandDocumentation.ts @@ -1,36 +1,41 @@ -import { EmbedBuilder } from 'discord.js'; +import type { EmbedBuilder } from "npm:discord.js"; -import * as auth from '../../../commands/auth/index.js'; -import * as noAuth from '../../../commands/noAuth/index.js'; -import { createEmbed } from '../../../libraries/help.library.js'; -import { Field, HelpDocumentation } from '../../../types/classes/PTypes.interface.js'; +import * as auth from "../../../commands/auth/index.ts"; +import * as noAuth from "../../../commands/noAuth/index.ts"; +import { createEmbed } from "../../../libraries/help.library.ts"; +import type { + Field, + HelpDocumentation, +} from "../../../types/classes/PTypes.interface.ts"; -const PORTAL_URL = 'https://portal-bot.xyz/docs'; +const PORTAL_URL = "https://portal-bot.xyz/docs"; export class CommandDocumentation implements HelpDocumentation { public getGuide(): EmbedBuilder { const commandArray: Field[] = [ { - emote: '1. Go to any channel', - role: '*you can write commands in any channel and Portal will see them*', + emote: "1. Go to any channel", + role: + "*you can write commands in any channel and Portal will see them*", inline: false, }, { - emote: '2. `./help`', - role: '*write your command, for example help*', + emote: "2. `./help`", + role: "*write your command, for example help*", inline: false, }, { - emote: '3. Wait for portal response', - role: '*portal will reply to almost all commands with an action or/and message*', + emote: "3. Wait for portal response", + role: + "*portal will reply to almost all commands with an action or/and message*", inline: false, }, ]; return createEmbed( - 'Command Guide', + "Command Guide", `[Commands](${PORTAL_URL}/commands/description) are the way you communicate with Portal.\nhow to use commands`, - '#9775A9', + "#9775A9", commandArray, null, null, @@ -49,7 +54,9 @@ export class CommandDocumentation implements HelpDocumentation { for (let i = 24 * l; i < commands.length && i < 24 * (l + 1); i++) { commandArray[l].push({ emote: `${i + 1}. ${commands[i].name}`, - role: `[hover or click](${PORTAL_URL}/commands/detailed/${commands[i].name} "${commands[i].hover}")`, + role: `[hover or click](${PORTAL_URL}/commands/detailed/${ + commands[i].name + } "${commands[i].hover}")`, inline: true, }); } @@ -58,9 +65,9 @@ export class CommandDocumentation implements HelpDocumentation { return commandArray.map((_command, index) => { if (index === 0) { return createEmbed( - 'Commands', + "Commands", `[Commands](${PORTAL_URL}/commands/description) are the way you communicate with Portal.`, - '#9775A9', + "#9775A9", commandArray[0], null, null, @@ -69,7 +76,17 @@ export class CommandDocumentation implements HelpDocumentation { null, ); } else { - return createEmbed(null, null, '#9775A9', commandArray[index], null, null, null, null, null); + return createEmbed( + null, + null, + "#9775A9", + commandArray[index], + null, + null, + null, + null, + null, + ); } }); } @@ -82,12 +99,15 @@ export class CommandDocumentation implements HelpDocumentation { return createEmbed( commands[i].name, null, - '#9775A9', + "#9775A9", [ - { emote: 'Type', role: 'Command', inline: true }, + { emote: "Type", role: "Command", inline: true }, { - emote: 'Description', - role: `[hover or click](${PORTAL_URL}/commands/detailed/${candidate} "${commands[i].hover}")`, + emote: "Description", + role: + `[hover or click](${PORTAL_URL}/commands/detailed/${candidate} "${ + commands[i].hover + }")`, inline: true, }, ], @@ -104,7 +124,9 @@ export class CommandDocumentation implements HelpDocumentation { } private getCommandList() { - return [...Object.values(auth), ...Object.values(noAuth)].map((command) => ({ + return [...Object.values(auth), ...Object.values(noAuth)].map(( + command, + ) => ({ name: command.slashCommand.name, hover: command.slashCommand.description, })); diff --git a/src/commands/noAuth/help/PipeDocumentation.ts b/src/commands/noAuth/help/PipeDocumentation.ts index 707bc531..2bda2095 100644 --- a/src/commands/noAuth/help/PipeDocumentation.ts +++ b/src/commands/noAuth/help/PipeDocumentation.ts @@ -1,52 +1,59 @@ -import { EmbedBuilder } from 'discord.js'; +import type { EmbedBuilder } from "npm:discord.js"; -import { PipeBlueprints } from '../../../blueprints/pipe.blueprint.js'; -import { createEmbed } from '../../../libraries/help.library.js'; -import { Field, HelpDocumentation } from '../../../types/classes/PTypes.interface.js'; -import { Prefix } from '../../../types/enums/Prefix.enum.js'; +import { PipeBlueprints } from "../../../blueprints/pipe.blueprint.ts"; +import { createEmbed } from "../../../libraries/help.library.ts"; +import type { + Field, + HelpDocumentation, +} from "../../../types/classes/PTypes.interface.ts"; +import { Prefix } from "../../../types/enums/Prefix.enum.ts"; -const PORTAL_URL = 'https://portal-bot.xyz/docs'; -const INTERPRETER_URL = '/interpreter/objects'; +const PORTAL_URL = "https://portal-bot.xyz/docs"; +const INTERPRETER_URL = "/interpreter/objects"; export class PipeDocumentation implements HelpDocumentation { public getGuide(): EmbedBuilder { const pipe_array: Field[] = [ { - emote: 'Used in Regex Interpreter', - role: '*used by channel name (regex, regex_voice, regex_portal) and run command*', + emote: "Used in Regex Interpreter", + role: + "*used by channel name (regex, regex_voice, regex_portal) and run command*", inline: true, }, { - emote: 'Pipes are inextricably linked with text', - role: '*pipes can used on plain text or even variables and attributes*', + emote: "Pipes are inextricably linked with text", + role: "*pipes can used on plain text or even variables and attributes*", inline: true, }, { - emote: '1.\tIn any text channel execute command `./run`', - role: './run just like channel name generation uses the text interpreter', + emote: "1.\tIn any text channel execute command `./run`", + role: + "./run just like channel name generation uses the text interpreter", inline: false, }, { - emote: '2.\t`./run My locale in caps is = &g.locale | upperCase`', - role: './run executes the given text and replies with the processed output', + emote: "2.\t`./run My locale in caps is = &g.locale | upperCase`", + role: + "./run executes the given text and replies with the processed output", inline: false, }, { - emote: '3.\tAwait a reply from portal which will be gr, de or en', - role: '*The replied string will look like this: `My locale in caps is = GR`*', + emote: "3.\tAwait a reply from portal which will be gr, de or en", + role: + "*The replied string will look like this: `My locale in caps is = GR`*", inline: false, }, ]; return createEmbed( - 'Pipe Guide', - '[Pipes](' + + "Pipe Guide", + "[Pipes](" + PORTAL_URL + INTERPRETER_URL + - '/pipes/description) ' + - 'are small programs you can pass text, variables or attributes, to manipulate their outcome\n' + - 'How to use pipes with the Text Interpreter', - '#6EEB83', + "/pipes/description) " + + "are small programs you can pass text, variables or attributes, to manipulate their outcome\n" + + "How to use pipes with the Text Interpreter", + "#6EEB83", pipe_array, null, null, @@ -64,9 +71,10 @@ export class PipeDocumentation implements HelpDocumentation { for (let i = 24 * l; i < PipeBlueprints.length && i < 24 * (l + 1); i++) { pipeArray[l].push({ emote: `${i + 1}. ${PipeBlueprints[i].name}`, - role: - `[hover or click](${PORTAL_URL}${INTERPRETER_URL}` + - `/pipes/detailed/${PipeBlueprints[i].name} "${PipeBlueprints[i].hover}")`, + role: `[hover or click](${PORTAL_URL}${INTERPRETER_URL}` + + `/pipes/detailed/${PipeBlueprints[i].name} "${ + PipeBlueprints[i].hover + }")`, inline: true, }); } @@ -75,15 +83,15 @@ export class PipeDocumentation implements HelpDocumentation { return pipeArray.map((_pipe, index): EmbedBuilder => { if (index === 0) { return createEmbed( - 'Pipes', - '[Pipes](' + + "Pipes", + "[Pipes](" + PORTAL_URL + INTERPRETER_URL + - '/pipes/description) ' + - 'are small programs you can pass text, variables or attributes, to manipulate their outcome\n' + - 'Prefix: ' + + "/pipes/description) " + + "are small programs you can pass text, variables or attributes, to manipulate their outcome\n" + + "Prefix: " + Prefix.PIPE, - '#6EEB83', + "#6EEB83", pipeArray[0], null, null, @@ -92,7 +100,17 @@ export class PipeDocumentation implements HelpDocumentation { null, ); } else { - return createEmbed(null, null, '#6EEB83', pipeArray[index], null, null, null, null, null); + return createEmbed( + null, + null, + "#6EEB83", + pipeArray[index], + null, + null, + null, + null, + null, + ); } }); } @@ -103,14 +121,13 @@ export class PipeDocumentation implements HelpDocumentation { return createEmbed( PipeBlueprints[i].name, null, - '#6EEB83', + "#6EEB83", [ - { emote: 'Type', role: 'Pipe', inline: true }, - { emote: 'Prefix', role: `${Prefix.PIPE}`, inline: true }, + { emote: "Type", role: "Pipe", inline: true }, + { emote: "Prefix", role: `${Prefix.PIPE}`, inline: true }, { - emote: 'Description', - role: - `[hover or click](${PORTAL_URL}${INTERPRETER_URL}` + + emote: "Description", + role: `[hover or click](${PORTAL_URL}${INTERPRETER_URL}` + `/pipes/detailed/${candidate} "${PipeBlueprints[i].hover}")`, inline: true, }, diff --git a/src/commands/noAuth/help/StructureDocumentation.ts b/src/commands/noAuth/help/StructureDocumentation.ts index cb05b3fc..0ef820d3 100644 --- a/src/commands/noAuth/help/StructureDocumentation.ts +++ b/src/commands/noAuth/help/StructureDocumentation.ts @@ -1,53 +1,61 @@ -import { EmbedBuilder } from 'discord.js'; +import type { EmbedBuilder } from "npm:discord.js"; -import { StructureBlueprint } from '../../../blueprints/structure.blueprint.js'; -import { createEmbed } from '../../../libraries/help.library.js'; -import { Field, HelpDocumentation } from '../../../types/classes/PTypes.interface.js'; -import { Prefix } from '../../../types/enums/Prefix.enum.js'; +import { StructureBlueprint } from "../../../blueprints/structure.blueprint.ts"; +import { createEmbed } from "../../../libraries/help.library.ts"; +import type { + Field, + HelpDocumentation, +} from "../../../types/classes/PTypes.interface.ts"; +import { Prefix } from "../../../types/enums/Prefix.enum.ts"; -const PORTAL_URL = 'https://portal-bot.xyz/docs'; -const INTERPRETER_URL = '/interpreter/objects'; +const PORTAL_URL = "https://portal-bot.xyz/docs"; +const INTERPRETER_URL = "/interpreter/objects"; export class StructureDocumentation implements HelpDocumentation { public getGuide(): EmbedBuilder { const structArray: Field[] = [ { - emote: 'Used in Regex Interpreter', - role: '*used by channel name (regex, regex_voice, regex_portal) and run command*', + emote: "Used in Regex Interpreter", + role: + "*used by channel name (regex, regex_voice, regex_portal) and run command*", inline: true, }, { - emote: 'structures are flow manipulators', - role: '*you can change the outcome of the regex corresponding with live data*', + emote: "structures are flow manipulators", + role: + "*you can change the outcome of the regex corresponding with live data*", inline: true, }, { - emote: '1.\tIn any text channel execute command `./run`', - role: './run just like channel name generation uses the text interpreter', + emote: "1.\tIn any text channel execute command `./run`", + role: + "./run just like channel name generation uses the text interpreter", inline: false, }, { emote: '2.\t`./run Is it 2020 ? {{ "if": "$year", "is": "===", "with": "2020", "yes": "yes it is", "no": "no it is not" }}!`', - role: './run executes the given text and replies with the processed output', + role: + "./run executes the given text and replies with the processed output", inline: false, }, { - emote: '3.\tAwait a reply from portal which will be `Is it 2020 ? no it is not!` (it is currently not 2020)', - role: '*note that year is variable as it is preceded by &*', + emote: + "3.\tAwait a reply from portal which will be `Is it 2020 ? no it is not!` (it is currently not 2020)", + role: "*note that year is variable as it is preceded by &*", inline: false, }, ]; return createEmbed( - 'Structure Guide', - '[Structures](' + + "Structure Guide", + "[Structures](" + PORTAL_URL + INTERPRETER_URL + - '/structures/description) ' + - 'conditional flow manipulators (if this do that, or if that do this).\n' + - 'How to use structures with the Text Interpreter', - '#EEB902', + "/structures/description) " + + "conditional flow manipulators (if this do that, or if that do this).\n" + + "How to use structures with the Text Interpreter", + "#EEB902", structArray, null, null, @@ -62,12 +70,17 @@ export class StructureDocumentation implements HelpDocumentation { for (let l = 0; l <= StructureBlueprint.length / 25; l++) { structArray[l] = []; - for (let i = 24 * l; i < StructureBlueprint.length && i < 24 * (l + 1); i++) { + for ( + let i = 24 * l; + i < StructureBlueprint.length && i < 24 * (l + 1); + i++ + ) { structArray[l].push({ emote: `${i + 1}. ${StructureBlueprint[i].name}`, - role: - `[hover or click](${PORTAL_URL}${INTERPRETER_URL}` + - `/structures/detailed/${StructureBlueprint[i].name} "${StructureBlueprint[i].hover}")`, + role: `[hover or click](${PORTAL_URL}${INTERPRETER_URL}` + + `/structures/detailed/${StructureBlueprint[i].name} "${ + StructureBlueprint[i].hover + }")`, inline: true, }); } @@ -76,15 +89,15 @@ export class StructureDocumentation implements HelpDocumentation { return structArray.map((_structure, index) => { if (index === 0) { return createEmbed( - 'Structures', - '[Structures](' + + "Structures", + "[Structures](" + PORTAL_URL + INTERPRETER_URL + - '/structures/description) ' + - 'conditional flow manipulators (if this do that, or if that do this).\n' + - 'Prefix: ' + + "/structures/description) " + + "conditional flow manipulators (if this do that, or if that do this).\n" + + "Prefix: " + Prefix.STRUCTURE, - '#EEB902', + "#EEB902", structArray[0], null, null, @@ -93,7 +106,17 @@ export class StructureDocumentation implements HelpDocumentation { null, ); } else { - return createEmbed(null, null, '#EEB902', structArray[index], null, null, null, null, null); + return createEmbed( + null, + null, + "#EEB902", + structArray[index], + null, + null, + null, + null, + null, + ); } }); } @@ -104,15 +127,16 @@ export class StructureDocumentation implements HelpDocumentation { return createEmbed( StructureBlueprint[i].name, null, - '#EEB902', + "#EEB902", [ - { emote: 'Type', role: 'structures', inline: true }, - { emote: 'Prefix', role: `${Prefix.STRUCTURE}`, inline: true }, + { emote: "Type", role: "structures", inline: true }, + { emote: "Prefix", role: `${Prefix.STRUCTURE}`, inline: true }, { - emote: 'Description', - role: - `[hover or click](${PORTAL_URL}${INTERPRETER_URL}` + - `/structures/detailed/${candidate} "${StructureBlueprint[i].name}")`, + emote: "Description", + role: `[hover or click](${PORTAL_URL}${INTERPRETER_URL}` + + `/structures/detailed/${candidate} "${ + StructureBlueprint[i].name + }")`, inline: true, }, ], @@ -129,27 +153,33 @@ export class StructureDocumentation implements HelpDocumentation { } private getLink(variable: string): string { - const url = PORTAL_URL + INTERPRETER_URL + '/variables'; - const general = ['creatorPortal', 'creatorVoice', '##', '#']; - const member = ['pMembers', 'memberCount', 'memberActiveCount', 'memberWithStatus', 'memberHistory']; - const status = ['statusList', 'statusCount', 'statusHistory']; + const url = PORTAL_URL + INTERPRETER_URL + "/variables"; + const general = ["creatorPortal", "creatorVoice", "##", "#"]; + const member = [ + "pMembers", + "memberCount", + "memberActiveCount", + "memberWithStatus", + "memberHistory", + ]; + const status = ["statusList", "statusCount", "statusHistory"]; const time = [ - 'date', - 'dayNumber', - 'dayName', - 'monthNumber', - 'monthName', - 'year', - 'time', - 'hour', - 'minute', - 'second', + "date", + "dayNumber", + "dayName", + "monthNumber", + "monthName", + "year", + "time", + "hour", + "minute", + "second", ]; if (general.includes(variable)) { - if (variable === '##') { + if (variable === "##") { return `${url}/detailed/general/slash`; - } else if (variable === '#') { + } else if (variable === "#") { return `${url}/detailed/general/doubleSlash`; } else { return `${url}/detailed/general/${variable}`; diff --git a/src/commands/noAuth/help/VariableDocumentation.ts b/src/commands/noAuth/help/VariableDocumentation.ts index 03402c4b..f45bcfc2 100644 --- a/src/commands/noAuth/help/VariableDocumentation.ts +++ b/src/commands/noAuth/help/VariableDocumentation.ts @@ -1,52 +1,58 @@ -import { EmbedBuilder } from 'discord.js'; +import type { EmbedBuilder } from "npm:discord.js"; -import { VariableBlueprints } from '../../../blueprints/variable.blueprint.js'; -import { createEmbed } from '../../../libraries/help.library.js'; -import { Field, HelpDocumentation } from '../../../types/classes/PTypes.interface.js'; -import { Prefix } from '../../../types/enums/Prefix.enum.js'; +import { VariableBlueprints } from "../../../blueprints/variable.blueprint.ts"; +import { createEmbed } from "../../../libraries/help.library.ts"; +import type { + Field, + HelpDocumentation, +} from "../../../types/classes/PTypes.interface.ts"; +import { Prefix } from "../../../types/enums/Prefix.enum.ts"; -const PORTAL_URL = 'https://portal-bot.xyz/docs'; -const INTERPRETER_URL = '/interpreter/objects'; +const PORTAL_URL = "https://portal-bot.xyz/docs"; +const INTERPRETER_URL = "/interpreter/objects"; export class VariableDocumentation implements HelpDocumentation { public getGuide(): EmbedBuilder { const structArray: Field[] = [ { - emote: 'Used in Regex Interpreter', - role: '*used by channel name (regex, regexVoice, regexPortal) and run command*', + emote: "Used in Regex Interpreter", + role: + "*used by channel name (regex, regexVoice, regexPortal) and run command*", inline: true, }, { - emote: 'variables are immutable and live data', - role: '*data corresponds to server, portal or voice channel live data*', + emote: "variables are immutable and live data", + role: "*data corresponds to server, portal or voice channel live data*", inline: true, }, { - emote: '1.\tIn any text channel execute command `./run`', - role: './run just like channel name generation uses the text interpreter', + emote: "1.\tIn any text channel execute command `./run`", + role: + "./run just like channel name generation uses the text interpreter", inline: false, }, { - emote: '2.\t`./run The year is $year`', - role: './run executes the given text and replies with the processed output', + emote: "2.\t`./run The year is $year`", + role: + "./run executes the given text and replies with the processed output", inline: false, }, { - emote: '3.\tAwait a reply from portal which will be `The year is 2021', - role: '*note that at the time of writhing it is 2021*', + emote: "3.\tAwait a reply from portal which will be `The year is 2021", + role: "*note that at the time of writhing it is 2021*", inline: false, }, ]; return createEmbed( - 'Variable Guide', - '[Variables](' + + "Variable Guide", + "[Variables](" + PORTAL_URL + INTERPRETER_URL + - '/variables/description) ' + - 'are immutable and live data that return information about your current voice channel.\n' + - 'how to use variables with text interpreter', - '#1BE7FF', + "/variables/description) " + + "are immutable and live data that return information about your current voice channel.\n" + + "how to use variables with text interpreter", + "#1BE7FF", structArray, null, null, @@ -61,10 +67,16 @@ export class VariableDocumentation implements HelpDocumentation { for (let l = 0; l <= VariableBlueprints.length / 25; l++) { variableArray[l] = []; - for (let i = 24 * l; i < VariableBlueprints.length && i < 24 * (l + 1); i++) { + for ( + let i = 24 * l; + i < VariableBlueprints.length && i < 24 * (l + 1); + i++ + ) { variableArray[l].push({ emote: `${i + 1}. ${VariableBlueprints[i].name}`, - role: `[hover or click](${this.getLink(VariableBlueprints[i].name)} "${VariableBlueprints[i].hover}")`, + role: `[hover or click](${ + this.getLink(VariableBlueprints[i].name) + } "${VariableBlueprints[i].hover}")`, inline: true, }); } @@ -73,15 +85,15 @@ export class VariableDocumentation implements HelpDocumentation { return variableArray.map((_variable, index) => { if (index === 0) { return createEmbed( - 'Variables', - '[Variables](' + + "Variables", + "[Variables](" + PORTAL_URL + INTERPRETER_URL + - '/variables/description) ' + - 'are immutable and live data that return information about your current voice channel.\n' + - 'Prefix: ' + + "/variables/description) " + + "are immutable and live data that return information about your current voice channel.\n" + + "Prefix: " + Prefix.VARIABLE, - '#1BE7FF', + "#1BE7FF", variableArray[0], null, null, @@ -90,7 +102,17 @@ export class VariableDocumentation implements HelpDocumentation { null, ); } else { - return createEmbed(null, null, '#1BE7FF', variableArray[index], null, null, null, null, null); + return createEmbed( + null, + null, + "#1BE7FF", + variableArray[index], + null, + null, + null, + null, + null, + ); } }); } @@ -101,13 +123,15 @@ export class VariableDocumentation implements HelpDocumentation { return createEmbed( VariableBlueprints[i].name, null, - '#1BE7FF', + "#1BE7FF", [ - { emote: 'Type', role: 'Variables', inline: true }, - { emote: 'Prefix', role: `${Prefix.VARIABLE}`, inline: true }, + { emote: "Type", role: "Variables", inline: true }, + { emote: "Prefix", role: `${Prefix.VARIABLE}`, inline: true }, { - emote: 'Description', - role: `[hover or click](${this.getLink(candidate)} "${VariableBlueprints[i].hover}")`, + emote: "Description", + role: `[hover or click](${this.getLink(candidate)} "${ + VariableBlueprints[i].hover + }")`, inline: true, }, ], @@ -124,27 +148,33 @@ export class VariableDocumentation implements HelpDocumentation { } private getLink(variable: string): string { - const url = PORTAL_URL + INTERPRETER_URL + '/variables'; - const general = ['creatorPortal', 'creatorVoice', '##', '#']; - const member = ['pMembers', 'memberCount', 'memberActiveCount', 'memberWithStatus', 'memberHistory']; - const status = ['statusList', 'statusCount', 'statusHistory']; + const url = PORTAL_URL + INTERPRETER_URL + "/variables"; + const general = ["creatorPortal", "creatorVoice", "##", "#"]; + const member = [ + "pMembers", + "memberCount", + "memberActiveCount", + "memberWithStatus", + "memberHistory", + ]; + const status = ["statusList", "statusCount", "statusHistory"]; const time = [ - 'date', - 'dayNumber', - 'dayName', - 'monthNumber', - 'monthName', - 'year', - 'time', - 'hour', - 'minute', - 'second', + "date", + "dayNumber", + "dayName", + "monthNumber", + "monthName", + "year", + "time", + "hour", + "minute", + "second", ]; if (general.includes(variable)) { - if (variable === '##') { + if (variable === "##") { return `${url}/detailed/general/slash`; - } else if (variable === '#') { + } else if (variable === "#") { return `${url}/detailed/general/doubleSlash`; } else { return `${url}/detailed/general/${variable}`; diff --git a/src/commands/noAuth/index.ts b/src/commands/noAuth/index.ts index 72e7fe5d..b84bcc31 100644 --- a/src/commands/noAuth/index.ts +++ b/src/commands/noAuth/index.ts @@ -1,20 +1,20 @@ -export { default as about } from './about.js'; -export { default as announce } from './announce.js'; -export { default as bet } from './bet.js'; -export { default as corona } from './corona.js'; -export { default as crypto } from './crypto.js'; -export { default as focus } from './focus.js'; -export { default as help } from './help.js'; -export { default as join } from './join.js'; -export { default as leaderboard } from './leaderboard.js'; -export { default as leave } from './leave.js'; -export { default as level } from './level.js'; -export { default as ping } from './ping.js'; -export { default as poll } from './poll.js'; -export { default as ranks } from './ranks.js'; -export { default as roll } from './roll.js'; -export { default as run } from './run.js'; -export { default as spam_rules } from './spam_rules.js'; -export { default as state } from './state.js'; -export { default as weather } from './weather.js'; -export { default as whoami } from './whoami.js'; +export { default as about } from "./about.ts"; +export { default as announce } from "./announce.ts"; +export { default as bet } from "./bet.ts"; +export { default as corona } from "./corona.ts"; +export { default as crypto } from "./crypto.ts"; +export { default as focus } from "./focus.ts"; +export { default as help } from "./help.ts"; +export { default as join } from "./join.ts"; +export { default as leaderboard } from "./leaderboard.ts"; +export { default as leave } from "./leave.ts"; +export { default as level } from "./level.ts"; +export { default as ping } from "./ping.ts"; +export { default as poll } from "./poll.ts"; +export { default as ranks } from "./ranks.ts"; +export { default as roll } from "./roll.ts"; +export { default as run } from "./run.ts"; +export { default as spam_rules } from "./spam_rules.ts"; +export { default as state } from "./state.ts"; +export { default as weather } from "./weather.ts"; +export { default as whoami } from "./whoami.ts"; diff --git a/src/commands/noAuth/join.ts b/src/commands/noAuth/join.ts index cc8032d6..c75e77ac 100644 --- a/src/commands/noAuth/join.ts +++ b/src/commands/noAuth/join.ts @@ -1,16 +1,24 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { type ChatInputCommandInteraction, GuildMember } from "npm:discord.js"; -import logger from '../../utilities/log.utility.js'; +import logger from "../../utilities/log.utility.ts"; -import { joinUserVoiceChannelByInteraction, messageHelp } from '../../libraries/help.library.js'; -import { clientTalk } from '../../libraries/localisation.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { AnnouncementAction, ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { + type joinUserVoiceChannelByInteraction, + messageHelp, +} from "../../libraries/help.library.ts"; +import { clientTalk } from "../../libraries/localisation.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + AnnouncementAction, + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import { VoiceLibrary } from "../../libraries/voice.library.ts"; -const COMMAND_NAME = 'join'; -const DESCRIPTION = 'makes portal join your voice channel'; +const COMMAND_NAME = "join"; +const DESCRIPTION = "makes portal join your voice channel"; export default { time: 1, @@ -18,15 +26,50 @@ export default { ephemeral: true, auth: false, scopeLimit: ScopeLimit.MEMBER, - slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription(DESCRIPTION), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { + slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription( + DESCRIPTION, + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { try { - const voiceChannel = await joinUserVoiceChannelByInteraction(interaction, pGuild); + const member = interaction?.member; + if (!member || !(member instanceof GuildMember)) { + return { + result: false, + value: messageHelp("commands", "join", "member not found"), + }; + } + const channelId = member.voice.channelId; + if (!channelId) { + return { + result: false, + value: messageHelp( + "commands", + "join", + "user must be in voice channel", + ), + }; + } + + const guild = interaction.guild; + if (!guild) { + return { + result: false, + value: messageHelp("commands", "join", "guild not found"), + }; + } + + const joinedChannel = VoiceLibrary.joinUserVoiceChannelById( + channelId, + guild, + ); - if (!voiceChannel) { + if (!joinedChannel) { return { result: false, - value: 'failed to join voice channel', + value: "failed to join voice channel", }; } @@ -34,14 +77,14 @@ export default { return { result: true, - value: 'successfully joined voice channel', + value: "successfully joined voice channel", }; } catch (error) { logger.error(`commands.join.error: ${error}`); return { result: false, - value: messageHelp('commands', 'join', 'failed to join voice channel'), + value: messageHelp("commands", "join", "failed to join voice channel"), }; } }, diff --git a/src/commands/noAuth/leaderboard.ts b/src/commands/noAuth/leaderboard.ts index cdf1468a..3d3cc153 100644 --- a/src/commands/noAuth/leaderboard.ts +++ b/src/commands/noAuth/leaderboard.ts @@ -1,13 +1,20 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, InteractionContextType } from 'discord.js'; -import { createEmbed, messageHelp } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { PMember } from '../../types/classes/PMember.class.js'; -import { Field, ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + type ChatInputCommandInteraction, + InteractionContextType, +} from "npm:discord.js"; +import { createEmbed, messageHelp } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import type { PMember } from "../../types/classes/PMember.class.ts"; +import { + type Field, + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'leaderboard'; -const DESCRIPTION = 'returns server\'s leaderboard'; +const COMMAND_NAME = "leaderboard"; +const DESCRIPTION = "returns server's leaderboard"; export default { time: 0, @@ -19,53 +26,63 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .addNumberOption((option) => - option.setName('requested_number').setDescription('Number of members to display').setRequired(false), + option.setName("requested_number").setDescription( + "Number of members to display", + ).setRequired(false) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { const pMembers = pGuild.pMembers; if (!pMembers) { return { result: false, - value: 'server has no members', + value: "server has no members", }; } - const requestedNumber = interaction.options.getNumber('requested_number'); + const requestedNumber = interaction.options.getNumber("requested_number"); - let entries = - requestedNumber && pMembers.length >= requestedNumber - ? requestedNumber > 25 - ? 24 - : requestedNumber - : pMembers.length > 25 - ? 24 - : pMembers.length; + let entries = requestedNumber && pMembers.length >= requestedNumber + ? requestedNumber > 25 ? 24 : requestedNumber + : pMembers.length > 25 + ? 24 + : pMembers.length; if (entries <= 0) { return { result: false, - value: messageHelp('commands', 'leaderboard', 'leaderboard entries must be at least one'), + value: messageHelp( + "commands", + "leaderboard", + "leaderboard entries must be at least one", + ), }; } if (!pGuild.pMembers) { return { result: false, - value: 'there are no members for this server', + value: "there are no members for this server", }; } const memberLevels: Field[] = []; pMembers.sort(compare).forEach((pMember, i) => { if (interaction.guild && entries > i) { - const thisPMember = interaction.guild.members.cache.find((member) => member.id === pMember.id); + const thisPMember = interaction.guild.members.cache.find((member) => + member.id === pMember.id + ); if (thisPMember) { memberLevels.push({ emote: `${i + 1}. ${thisPMember.displayName}`, - role: `level ${pMember.level}\t|\tpoints: ${Math.round(pMember.points)}`, + role: `level ${pMember.level}\t|\tpoints: ${ + Math.round(pMember.points) + }`, inline: false, }); @@ -73,7 +90,7 @@ export default { } else { return { result: false, - value: 'a member has been stored incorrectly', + value: "a member has been stored incorrectly", }; } } @@ -82,9 +99,9 @@ export default { const outcome = await interaction.reply({ embeds: [ createEmbed( - 'LEADERBOARD', - '[Ranking System](https://portal-bot.xyz/docs/ranking)', - '#00FFFF', + "LEADERBOARD", + "[Ranking System](https://portal-bot.xyz/docs/ranking)", + "#00FFFF", memberLevels, null, null, @@ -97,17 +114,15 @@ export default { return { result: !!outcome, - value: outcome ? '' : 'failed to send message', + value: outcome ? "" : "failed to send message", }; }, } as Command; function compare(memberA: PMember, memberB: PMember) { return memberB.level === memberA.level - ? memberB.points > memberA.points - ? 1 - : -1 + ? memberB.points > memberA.points ? 1 : -1 : memberB.level > memberA.level - ? 1 - : -1; + ? 1 + : -1; } diff --git a/src/commands/noAuth/leave.ts b/src/commands/noAuth/leave.ts index 0a707fff..4b083f5f 100644 --- a/src/commands/noAuth/leave.ts +++ b/src/commands/noAuth/leave.ts @@ -1,13 +1,23 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { getVoiceConnection, VoiceConnectionStatus } from '@discordjs/voice'; -import { ChatInputCommandInteraction } from 'discord.js'; -import { clientTalk, clientWrite } from '../../libraries/localisation.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { AnnouncementAction, ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + getVoiceConnection, + VoiceConnectionStatus, +} from "npm:@discordjs/voice"; +import type { ChatInputCommandInteraction } from "npm:discord.js"; +import { + clientTalk, + clientWrite, +} from "../../libraries/localisation.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + AnnouncementAction, + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'leave'; -const DESCRIPTION = 'makes portal leave your voice channel'; +const COMMAND_NAME = "leave"; +const DESCRIPTION = "makes portal leave your voice channel"; export default { time: 0, @@ -15,12 +25,17 @@ export default { ephemeral: true, auth: false, scopeLimit: ScopeLimit.NONE, - slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription(DESCRIPTION), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { + slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription( + DESCRIPTION, + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { if (!interaction.guild) { return { result: false, - value: 'guild could not be fetched', + value: "guild could not be fetched", }; } @@ -29,7 +44,7 @@ export default { if (!voiceConnection) { return { result: false, - value: 'portal must be connected to a voice channel with you', + value: "portal must be connected to a voice channel with you", }; } @@ -37,7 +52,7 @@ export default { // await voiceConnection.destroy(); return { result: false, - value: 'failed to destroy voice connection', + value: "failed to destroy voice connection", }; } diff --git a/src/commands/noAuth/level.ts b/src/commands/noAuth/level.ts index 30af53fe..605bbf53 100644 --- a/src/commands/noAuth/level.ts +++ b/src/commands/noAuth/level.ts @@ -1,12 +1,19 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, GuildMember, InteractionContextType } from 'discord.js'; -import { createEmbed } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import { + type ChatInputCommandInteraction, + type GuildMember, + InteractionContextType, +} from "npm:discord.js"; +import { createEmbed } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'level'; -const DESCRIPTION = 'returns your level'; +const COMMAND_NAME = "level"; +const DESCRIPTION = "returns your level"; export default { time: 0, @@ -18,14 +25,17 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { const member = interaction.member as GuildMember; const pMember = pGuild.pMembers.find((m) => m.id === member.id); if (!pMember) { return { result: false, - value: 'could not find member', + value: "could not find member", }; } @@ -34,13 +44,17 @@ export default { createEmbed( null, null, - '#00FFFF', + "#00FFFF", [ - { emote: 'Level', role: `${pMember.level}`, inline: true }, - { emote: 'Points', role: `${Math.round(pMember.points)}`, inline: true }, + { emote: "Level", role: `${pMember.level}`, inline: true }, + { + emote: "Points", + role: `${Math.round(pMember.points)}`, + inline: true, + }, // { emote: '', role: '', inline: false }, // { emote: 'Rank', role: `${pMember.rank}`, inline: true }, - { emote: 'Tier', role: `${pMember.tier}`, inline: true }, + { emote: "Tier", role: `${pMember.tier}`, inline: true }, ], null, member, @@ -55,7 +69,7 @@ export default { return { result: !!outcome, - value: outcome ? '' : 'failed to send message', + value: outcome ? "" : "failed to send message", }; }, } as Command; diff --git a/src/commands/noAuth/ping.ts b/src/commands/noAuth/ping.ts index 588492d6..dc8ba566 100644 --- a/src/commands/noAuth/ping.ts +++ b/src/commands/noAuth/ping.ts @@ -1,12 +1,15 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, Client } from 'discord.js'; -import { createEmbed } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { ChatInputCommandInteraction, Client } from "npm:discord.js"; +import { createEmbed } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'ping'; -const DESCRIPTION = 'pings portal'; +const COMMAND_NAME = "ping"; +const DESCRIPTION = "pings portal"; export default { time: 0, @@ -14,14 +17,33 @@ export default { ephemeral: true, auth: false, scopeLimit: ScopeLimit.NONE, - slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription(DESCRIPTION), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild, client: Client): Promise { + slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription( + DESCRIPTION, + ), + async execute( + interaction: ChatInputCommandInteraction, + _pGuild: PGuild, + client: Client, + ): Promise { const message = { embeds: [ - createEmbed(null, null, '#0093ff', null, null, null, false, null, null, undefined, { - name: 'Request sent', - icon: 'https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/ping.gif', - }), + createEmbed( + null, + null, + "#0093ff", + null, + null, + null, + false, + null, + null, + undefined, + { + name: "Request sent", + icon: + "https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/ping.gif", + }, + ), ], }; @@ -30,24 +52,39 @@ export default { if (!outcome) { return { result: false, - value: 'error while sending pong message', + value: "error while sending pong message", }; } const editMessage = await outcome.edit({ embeds: [ - createEmbed(null, null, '#0093ff', null, null, null, false, null, null, undefined, { - name: - `RTT latency\t${outcome.createdTimestamp - interaction.createdTimestamp} ms\n` + - `Portal latency\t${client.ws.ping} ms`, - icon: 'https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/ping.gif', - }), + createEmbed( + null, + null, + "#0093ff", + null, + null, + null, + false, + null, + null, + undefined, + { + name: + `RTT latency\t${ + outcome.createdTimestamp - interaction.createdTimestamp + } ms\n` + + `Portal latency\t${client.ws.ping} ms`, + icon: + "https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/ping.gif", + }, + ), ], }); return { result: !!editMessage, - value: editMessage ? '' : 'error while editing pong message', + value: editMessage ? "" : "error while editing pong message", }; }, } as Command; diff --git a/src/commands/noAuth/poll.ts b/src/commands/noAuth/poll.ts index f9bed38b..72a33f59 100644 --- a/src/commands/noAuth/poll.ts +++ b/src/commands/noAuth/poll.ts @@ -1,15 +1,23 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, ColorResolvable, TextChannel } from 'discord.js'; -import { createEmbed, messageHelp } from '../../libraries/help.library.js'; -import { insertPoll } from '../../libraries/mongo.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { PPoll } from '../../types/classes/PPoll.class.js'; -import { Field, ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; - -const COMMAND_NAME = 'poll'; -const DESCRIPTION = 'create a new poll'; -const emoji = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣']; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { + ChatInputCommandInteraction, + ColorResolvable, + TextChannel, +} from "npm:discord.js"; +import { createEmbed, messageHelp } from "../../libraries/help.library.ts"; +import { insertPoll } from "../../libraries/mongo.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import type { PPoll } from "../../types/classes/PPoll.class.ts"; +import { + type Field, + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; + +const COMMAND_NAME = "poll"; +const DESCRIPTION = "create a new poll"; +const emoji = ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣"]; export default { time: 0, @@ -20,34 +28,51 @@ export default { slashCommand: new SlashCommandBuilder() .setName(COMMAND_NAME) .setDescription(DESCRIPTION) - .addStringOption((option) => option.setName('title').setDescription('Poll title').setRequired(true)) - .addStringOption((option) => option.setName('option_1').setDescription('option 1').setRequired(true)) - .addStringOption((option) => option.setName('option_2').setDescription('option 2').setRequired(true)) - .addStringOption((option) => option.setName('option_3').setDescription('option 3').setRequired(false)) - .addStringOption((option) => option.setName('option_4').setDescription('option 4').setRequired(false)) - .addStringOption((option) => option.setName('option_5').setDescription('option 5').setRequired(false)) - .addStringOption((option) => option.setName('option_6').setDescription('option 6').setRequired(false)), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { + .addStringOption((option) => + option.setName("title").setDescription("Poll title").setRequired(true) + ) + .addStringOption((option) => + option.setName("option_1").setDescription("option 1").setRequired(true) + ) + .addStringOption((option) => + option.setName("option_2").setDescription("option 2").setRequired(true) + ) + .addStringOption((option) => + option.setName("option_3").setDescription("option 3").setRequired(false) + ) + .addStringOption((option) => + option.setName("option_4").setDescription("option 4").setRequired(false) + ) + .addStringOption((option) => + option.setName("option_5").setDescription("option 5").setRequired(false) + ) + .addStringOption((option) => + option.setName("option_6").setDescription("option 6").setRequired(false) + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { if (!interaction.guild) { return { result: true, - value: 'guild could not be fetched', + value: "guild could not be fetched", }; } - const title = interaction.options.getString('title'); + const title = interaction.options.getString("title"); - const option_1 = interaction.options.getString('option_1'); - const option_2 = interaction.options.getString('option_2'); - const option_3 = interaction.options.getString('option_3'); - const option_4 = interaction.options.getString('option_4'); - const option_5 = interaction.options.getString('option_5'); - const option_6 = interaction.options.getString('option_6'); + const option_1 = interaction.options.getString("option_1"); + const option_2 = interaction.options.getString("option_2"); + const option_3 = interaction.options.getString("option_3"); + const option_4 = interaction.options.getString("option_4"); + const option_5 = interaction.options.getString("option_5"); + const option_6 = interaction.options.getString("option_6"); if (!title || !option_1 || !option_2) { return { result: false, - value: messageHelp('commands', 'poll'), + value: messageHelp("commands", "poll"), }; } @@ -69,15 +94,15 @@ export default { pollMap.filter((poll) => !!poll).map((poll) => poll.trim()); const pollMapField = pollMap.map((p, i) => { - return { emote: emoji[i], role: p, inline: true }; + return { emote: emoji[i], role: p, inline: true }; }); const response = await createRoleMessage( - interaction.channel, + interaction.channel, pGuild, title, - '', - '#9900ff', + "", + "#9900ff", pollMapField, interaction.user.id, ); @@ -85,13 +110,13 @@ export default { if (!response) { return { result: false, - value: 'error creating role message', + value: "error creating role message", }; } return { result: response.result, - value: response.result ? '' : response.value, + value: response.result ? "" : response.value, }; }, } as Command; @@ -105,29 +130,39 @@ async function createRoleMessage( pollMap: Field[], memberId: string, ): Promise { - const roleMessageEmbed = createEmbed(title, desc, colour, pollMap, null, null, true, null, null); + const roleMessageEmbed = createEmbed( + title, + desc, + colour, + pollMap, + null, + null, + true, + null, + null, + ); const sentMessage = await channel.send({ embeds: [roleMessageEmbed] }); if (!sentMessage) { return { result: false, - value: 'failed to create role assigner message', + value: "failed to create role assigner message", }; } - const reactionCheckered = await sentMessage.react('🏁'); + const reactionCheckered = await sentMessage.react("🏁"); if (!reactionCheckered) { return { result: true, - value: 'failed to react to message', + value: "failed to react to message", }; } for (let i = 0; i < pollMap.length; i++) { - if (typeof pollMap[i].emote === 'string') { - sentMessage.react(pollMap[i].emote).catch((e) => { + if (typeof pollMap[i].emote === "string") { + sentMessage.react( pollMap[i].emote).catch((e) => { return { result: true, value: `failed to react to message: ${e}`, @@ -142,12 +177,12 @@ async function createRoleMessage( if (!newPoll) { return { result: false, - value: 'failed to set new ranks', + value: "failed to set new ranks", }; } return { result: newPoll, - value: newPoll ? 'successfully created poll' : 'failed to create poll', + value: newPoll ? "successfully created poll" : "failed to create poll", }; } diff --git a/src/commands/noAuth/ranks.ts b/src/commands/noAuth/ranks.ts index 6a4c107c..be7bac9f 100644 --- a/src/commands/noAuth/ranks.ts +++ b/src/commands/noAuth/ranks.ts @@ -1,12 +1,17 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction } from 'discord.js'; -import { createEmbed } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { Field, ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { ChatInputCommandInteraction } from "npm:discord.js"; -const COMMAND_NAME = 'ranks'; -const DESCRIPTION = 'display server ranks'; +import { createEmbed } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type Field, + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; + +const COMMAND_NAME = "ranks"; +const DESCRIPTION = "display server ranks"; export default { time: 0, @@ -14,19 +19,26 @@ export default { ephemeral: true, auth: false, scopeLimit: ScopeLimit.NONE, - slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription(DESCRIPTION), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { + slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription( + DESCRIPTION, + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { if (!pGuild.ranks || pGuild.ranks.length === 0) { return { result: true, - value: 'there is no ranking yet', + value: "there is no ranking yet", }; } const ranksMessage: Field[] = []; pGuild.ranks.forEach((rank) => { - const role = interaction.guild?.roles.cache.find((r) => r.id === rank.role); + const role = interaction.guild?.roles.cache.find((r) => + r.id === rank.role + ); ranksMessage.push({ emote: `At level ${rank.level}, you get role`, role: `${role ? role : rank.role}`, @@ -35,12 +47,24 @@ export default { }); const outcome = await interaction.reply({ - embeds: [createEmbed('Ranking System', null, '#FF4500', ranksMessage, null, null, true, null, null)], + embeds: [ + createEmbed( + "Ranking System", + null, + "#FF4500", + ranksMessage, + null, + null, + true, + null, + null, + ), + ], }); return { result: !!outcome, - value: outcome ? '' : 'failed to send message', + value: outcome ? "" : "failed to send message", }; }, } as Command; diff --git a/src/commands/noAuth/roll.ts b/src/commands/noAuth/roll.ts index 2ed67fcd..97096414 100644 --- a/src/commands/noAuth/roll.ts +++ b/src/commands/noAuth/roll.ts @@ -1,12 +1,21 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, GuildMember } from 'discord.js'; -import Roll from 'roll'; -import { createEmbed, maxString, messageHelp } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { ChatInputCommandInteraction, GuildMember } from "npm:discord.js"; +import Roll from "roll"; -const COMMAND_NAME = 'roll'; -const DESCRIPTION = 'roll a dice'; +import { + createEmbed, + maxString, + messageHelp, +} from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import logger from "../../utilities/log.utility.ts"; + +const COMMAND_NAME = "roll"; +const DESCRIPTION = "roll a dice"; export default { time: 0, @@ -17,47 +26,69 @@ export default { slashCommand: new SlashCommandBuilder() .setName(COMMAND_NAME) .setDescription(DESCRIPTION) - .addStringOption((option) => option.setName('roll_command').setDescription('Roll command').setRequired(true)) + .addStringOption((option) => + option.setName("roll_command").setDescription("Roll command").setRequired( + true, + ) + ) .addBooleanOption((option) => - option.setName('show').setDescription('show rolled dice in detail').setRequired(false), + option.setName("show").setDescription("show rolled dice in detail") + .setRequired(false) ), - async execute(interaction: ChatInputCommandInteraction): Promise { - let rollCommand = interaction.options.getString('roll_command'); - const show = interaction.options.getBoolean('show'); + async execute( + interaction: ChatInputCommandInteraction, + ): Promise { + let rollCommand = interaction.options.getString("roll_command"); + const show = interaction.options.getBoolean("show"); if (!rollCommand) { return { result: false, - value: messageHelp('commands', 'roll'), + value: messageHelp("commands", "roll"), }; } - rollCommand = rollCommand.replace(/\s/g, ''); + rollCommand = rollCommand.replace(/\s/g, ""); try { const member = interaction.member as GuildMember; const rollLibrary = new Roll(); const roll = rollLibrary.roll(rollCommand); - const rollDetail = show ? ` (${roll.rolled} from ${rollCommand})` : ''; - const rollMsg = `${member.displayName} rolled ${roll.result}${rollDetail}`; + const rollDetail = show ? ` (${roll.rolled} from ${rollCommand})` : ""; + const rollMsg = + `${member.displayName} rolled ${roll.result}${rollDetail}`; const outcome = await interaction.reply({ embeds: [ - createEmbed(null, null, '#FF0000', null, null, null, false, null, null, undefined, { - name: maxString(rollMsg, 256), - icon: 'https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/dice.gif', - }), + createEmbed( + null, + null, + "#FF0000", + null, + null, + null, + false, + null, + null, + undefined, + { + name: maxString(rollMsg, 256), + icon: + "https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/dice.gif", + }, + ), ], }); return { result: !!outcome, - value: outcome ? '' : 'failed to send message', + value: outcome ? "" : "failed to send message", }; } catch (e) { + logger.error(`Error while rolling: ${e}`); return { result: false, - value: 'error while rolling', + value: "error while rolling", }; } }, diff --git a/src/commands/noAuth/run.ts b/src/commands/noAuth/run.ts index a59d37fd..a835e3dc 100644 --- a/src/commands/noAuth/run.ts +++ b/src/commands/noAuth/run.ts @@ -1,14 +1,27 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, GuildMember, VoiceChannel } from 'discord.js'; -import { regexInterpreter } from '../../libraries/guild.library.js'; -import { createEmbed, maxString, messageHelp } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { Field, ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; -import { PVoiceChannel } from '../../types/classes/PVoiceChannel.class.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { + ChatInputCommandInteraction, + GuildMember, + VoiceChannel, +} from "npm:discord.js"; -const COMMAND_NAME = 'run'; -const DESCRIPTION = 'execute given code'; +import { regexInterpreter } from "../../libraries/guild.library.ts"; +import { + createEmbed, + maxString, + messageHelp, +} from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type Field, + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import type { PVoiceChannel } from "../../types/classes/PVoiceChannel.class.ts"; + +const COMMAND_NAME = "run"; +const DESCRIPTION = "execute given code"; export default { time: 0, @@ -19,28 +32,35 @@ export default { slashCommand: new SlashCommandBuilder() .setName(COMMAND_NAME) .setDescription(DESCRIPTION) - .addStringOption((option) => option.setName('command').setDescription('Command to run').setRequired(true)), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { - const command = interaction.options.getString('command'); + .addStringOption((option) => + option.setName("command").setDescription("Command to run").setRequired( + true, + ) + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + const command = interaction.options.getString("command"); if (!command) { return { result: false, - value: messageHelp('commands', 'run'), + value: messageHelp("commands", "run"), }; } if (!interaction.guild) { return { result: true, - value: 'guild could not be fetched', + value: "guild could not be fetched", }; } if (!interaction.member) { return { result: true, - value: 'member could not be fetched', + value: "member could not be fetched", }; } @@ -53,7 +73,9 @@ export default { if (currentVoiceChannel) { for (let i = 0; i < pGuild.pChannels.length; i++) { for (let j = 0; j < pGuild.pChannels[i].pVoiceChannels.length; j++) { - if (pGuild.pChannels[i].pVoiceChannels[j].id === currentVoiceChannel.id) { + if ( + pGuild.pChannels[i].pVoiceChannels[j].id === currentVoiceChannel.id + ) { pVoice = pGuild.pChannels[i].pVoiceChannels[j]; break; } @@ -64,9 +86,9 @@ export default { const message = { embeds: [ createEmbed( - 'executing: ' + command, + "executing: " + command, command, - '#00ffb3', + "#00ffb3", null, null, null, @@ -84,34 +106,36 @@ export default { if (!outcome) { return { result: true, - value: 'failed to send message', + value: "failed to send message", }; } const editedMessage = await outcome.edit({ embeds: [ createEmbed( - 'Text Interpreter', + "Text Interpreter", null, - '#00ffb3', - [ + "#00ffb3", + [ { - emote: 'input', + emote: "input", role: maxString(`\`\`\`\n${command}\n\`\`\``, 256), inline: false, }, { - emote: 'output', + emote: "output", role: maxString( - `\`\`\`\n${regexInterpreter( - command, - currentVoiceChannel as VoiceChannel, - pVoice, - pGuild.pChannels, - pGuild, - interaction.guild, - interaction.user.id, - )}\n\`\`\``, + `\`\`\`\n${ + regexInterpreter( + command, + currentVoiceChannel as VoiceChannel, + pVoice, + pGuild.pChannels, + pGuild, + interaction.guild, + interaction.user.id, + ) + }\n\`\`\``, 256, ), inline: false, @@ -130,7 +154,7 @@ export default { return { result: !!editedMessage, - value: editedMessage ? '' : 'failed to edit message', + value: editedMessage ? "" : "failed to edit message", }; }, } as Command; diff --git a/src/commands/noAuth/spam_rules.ts b/src/commands/noAuth/spam_rules.ts index b0271212..d2334982 100644 --- a/src/commands/noAuth/spam_rules.ts +++ b/src/commands/noAuth/spam_rules.ts @@ -1,14 +1,17 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, Client } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { ChatInputCommandInteraction, Client } from "npm:discord.js"; -import SPAM_CONFIG from '../../config.spam.json' assert { type: 'json' }; -import { createEmbed } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import SPAM_CONFIG from "../../config.spam.json" with { type: "json" }; +import { createEmbed } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; -const COMMAND_NAME = 'spam_rules'; -const DESCRIPTION = 'returns server\'s spam rules'; +const COMMAND_NAME = "spam_rules"; +const DESCRIPTION = "returns server's spam rules"; export default { time: 0, @@ -16,40 +19,68 @@ export default { ephemeral: true, auth: false, scopeLimit: ScopeLimit.NONE, - slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription(DESCRIPTION), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild, client: Client): Promise { - const guild = client.guilds.cache.find((guild) => guild.id === interaction?.guild?.id); + slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription( + DESCRIPTION, + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + client: Client, + ): Promise { + const guild = client.guilds.cache.find((guild) => + guild.id === interaction?.guild?.id + ); if (!guild) { return { result: false, - value: 'could not fetch guild', + value: "could not fetch guild", }; } const rules = `**Duplicate spam warning after ${SPAM_CONFIG.DUPLICATE_AFTER}.**\n` + `**Spam warning after ${SPAM_CONFIG.WARN_AFTER}.**\n` + - `**Mute after ${SPAM_CONFIG.MUTE_AFTER} ${SPAM_CONFIG.MUTE_AFTER === 1 ? 'warning' : 'warnings'} ` + - `for ${SPAM_CONFIG.MUTE_PERIOD} ${SPAM_CONFIG.MUTE_PERIOD === 1 ? 'minute' : 'minutes'}.**\n\n` + + `**Mute after ${SPAM_CONFIG.MUTE_AFTER} ${ + SPAM_CONFIG.MUTE_AFTER === 1 ? "warning" : "warnings" + } ` + + `for ${SPAM_CONFIG.MUTE_PERIOD} ${ + SPAM_CONFIG.MUTE_PERIOD === 1 ? "minute" : "minutes" + }.**\n\n` + `${ pGuild.kickAfter && pGuild.kickAfter > 0 - ? `***Member kicked after ${pGuild.kickAfter} ${SPAM_CONFIG.MUTE_AFTER === 1 ? 'penalty' : 'penalties'}.***\n` - : '***Automatic kick has not been set yet.***\n' + ? `***Member kicked after ${pGuild.kickAfter} ${ + SPAM_CONFIG.MUTE_AFTER === 1 ? "penalty" : "penalties" + }.***\n` + : "***Automatic kick has not been set yet.***\n" }` + `${ pGuild.banAfter && pGuild.banAfter > 0 - ? `***Member banned after ${pGuild.banAfter} ${SPAM_CONFIG.MUTE_AFTER === 1 ? 'penalty' : 'penalties'}.***` - : '***Automatic ban has not been set yet.***' + ? `***Member banned after ${pGuild.banAfter} ${ + SPAM_CONFIG.MUTE_AFTER === 1 ? "penalty" : "penalties" + }.***` + : "***Automatic ban has not been set yet.***" }`; const outcome = await interaction.reply({ - embeds: [createEmbed('Spam Rules', rules, '#006996', null, null, null, true, null, null)], + embeds: [ + createEmbed( + "Spam Rules", + rules, + "#006996", + null, + null, + null, + true, + null, + null, + ), + ], }); return { result: !!outcome, - value: outcome ? '' : 'failed to send message', + value: outcome ? "" : "failed to send message", }; }, } as Command; diff --git a/src/commands/noAuth/state.ts b/src/commands/noAuth/state.ts index 0aa596ce..629936c1 100644 --- a/src/commands/noAuth/state.ts +++ b/src/commands/noAuth/state.ts @@ -1,12 +1,17 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, Client } from 'discord.js'; -import { createEmbed } from '../../libraries/help.library.js'; -import { Command } from '../../types/Command.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { Field, ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { ChatInputCommandInteraction, Client } from "npm:discord.js"; -const COMMAND_NAME = 'state'; -const DESCRIPTION = 'returns server\'s state'; +import { createEmbed } from "../../libraries/help.library.ts"; +import type { Command } from "../../types/Command.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type Field, + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; + +const COMMAND_NAME = "state"; +const DESCRIPTION = "returns server's state"; export default { time: 0, @@ -14,21 +19,29 @@ export default { ephemeral: true, auth: false, scopeLimit: ScopeLimit.NONE, - slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription(DESCRIPTION), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild, client: Client): Promise { - const guild = client.guilds.cache.find((g) => g.id === interaction?.guild?.id); + slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription( + DESCRIPTION, + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + client: Client, + ): Promise { + const guild = client.guilds.cache.find((g) => + g.id === interaction?.guild?.id + ); if (!guild) { return { result: false, - value: 'could not fetch guild', + value: "could not fetch guild", }; } let portalState = [ - { - emote: 'Portal Channels', - role: '', + { + emote: "Portal Channels", + role: "", inline: false, }, ]; @@ -40,13 +53,15 @@ export default { .map((v, indexV) => { const voiceChannel = guild.channels.cache.find((c) => c.id === v.id); - return `${indexV + 1}. ${voiceChannel ? voiceChannel.name : 'unavailable'}`; + return `${indexV + 1}. ${ + voiceChannel ? voiceChannel.name : "unavailable" + }`; }) - .join('\n'); + .join("\n"); - return { - emote: `${portalChannel ? portalChannel.name : 'unavailable'}`, - role: '```\n' + voices ? voices : 'no voice' + '\n```', + return { + emote: `${portalChannel ? portalChannel.name : "unavailable"}`, + role: "```\n" + voices ? voices : "no voice" + "\n```", inline: true, }; }); @@ -55,99 +70,133 @@ export default { portalState = portalState.concat(portals); } - portalState.push({ - emote: '', - role: '', - inline: false, - }); + portalState.push( + { + emote: "", + role: "", + inline: false, + }, + ); - const music = guild.channels.cache.find((c) => c.id === pGuild.musicData.channelId); + const music = guild.channels.cache.find((c) => + c.id === pGuild.musicData.channelId + ); if (music) { - portalState.push({ - emote: 'Music channel', - role: '```\n' + music ? music.name : 'unavailable' + '\n```', - inline: true, - }); + portalState.push( + { + emote: "Music channel", + role: "```\n" + music ? music.name : "unavailable" + "\n```", + inline: true, + }, + ); } else { - portalState.push({ - emote: 'Music channel', - role: '```\nnone\n```', - inline: true, - }); + portalState.push( + { + emote: "Music channel", + role: "```\nnone\n```", + inline: true, + }, + ); } - const announcement = guild.channels.cache.find((c) => c.id === pGuild.announcement); + const announcement = guild.channels.cache.find((c) => + c.id === pGuild.announcement + ); if (announcement) { - portalState.push({ - emote: 'Announcement channel', - role: '```\n' + announcement ? announcement.name : 'unavailable' + '\n```', - inline: true, - }); + portalState.push( + { + emote: "Announcement channel", + role: "```\n" + announcement + ? announcement.name + : "unavailable" + "\n```", + inline: true, + }, + ); } else { - portalState.push({ - emote: 'Announcement channel', - role: '```\nnone\n```', - inline: true, - }); + portalState.push( + { + emote: "Announcement channel", + role: "```\nnone\n```", + inline: true, + }, + ); } - portalState.push({ - emote: '', - role: '', - inline: false, - }); + portalState.push( + { + emote: "", + role: "", + inline: false, + }, + ); const urls = pGuild.pURLs.map((uId, indexU) => { const channel = guild.channels.cache.find((c) => c.id === uId); - return `${indexU + 1}. ${channel ? channel.name : 'unavailable'}`; + return `${indexU + 1}. ${channel ? channel.name : "unavailable"}`; }); if (urls.length > 0) { - const urlSum = { - emote: 'URL channels', - role: '```\n' + urls ? urls.join('\n') : 'unavailable' + '\n```', + const urlSum = { + emote: "URL channels", + role: "```\n" + urls ? urls.join("\n") : "unavailable" + "\n```", inline: true, }; portalState = portalState.concat(urlSum); } else { - portalState.push({ - emote: 'URL channels', - role: '```\nnone\n```', - inline: true, - }); + portalState.push( + { + emote: "URL channels", + role: "```\nnone\n```", + inline: true, + }, + ); } const ignore = pGuild.pIgnores.map((uId, indexU) => { const channel = guild.channels.cache.find((c) => c.id === uId); - return `${indexU + 1}. ${channel ? channel.name : 'unavailable'}`; + return `${indexU + 1}. ${channel ? channel.name : "unavailable"}`; }); if (ignore.length > 0) { - const ignoreSum = { - emote: 'Ignored channels', - role: '```\n' + ignore ? ignore.join('\n') : 'unavailable' + '\n```', + const ignoreSum = { + emote: "Ignored channels", + role: "```\n" + ignore ? ignore.join("\n") : "unavailable" + "\n```", inline: true, }; portalState = portalState.concat(ignoreSum); } else { - portalState.push({ - emote: 'Ignored channels', - role: '```\nnone\n```', - inline: true, - }); + portalState.push( + { + emote: "Ignored channels", + role: "```\nnone\n```", + inline: true, + }, + ); } const outcome = await interaction.reply({ - embeds: [createEmbed('State of Portal', null, '#eba000', portalState, null, null, true, null, null)], + embeds: [ + createEmbed( + "State of Portal", + null, + "#eba000", + portalState, + null, + null, + true, + null, + null, + ), + ], }); return { result: !!outcome, - value: outcome ? '' : 'failed to send message', + value: outcome ? "" : "failed to send message", }; }, } as Command; diff --git a/src/commands/noAuth/stock.ts b/src/commands/noAuth/stock.ts index edb79d69..b0c28a35 100644 --- a/src/commands/noAuth/stock.ts +++ b/src/commands/noAuth/stock.ts @@ -1,12 +1,21 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import dayjs from 'dayjs'; -import { ChatInputCommandInteraction } from 'discord.js'; -import { RequestOptions } from 'https'; -import { createEmbed, getJSONFromString, messageHelp } from '../../libraries/help.library.js'; -import { httpsFetch } from '../../libraries/http.library.js'; -import { Command } from '../../types/Command.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; -// import { CountryCodes } from '../../data/lists/countryCodesISO.static.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import "@std/dotenv/load"; +import dayjs from "npm:dayjs"; +import type { ChatInputCommandInteraction } from "npm:discord.js"; + +import { + createEmbed, + getJSONFromString, + messageHelp, +} from "../../libraries/help.library.ts"; +import { httpsFetch } from "../../libraries/http.library.ts"; +import type { Command } from "../../types/Command.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; + +// import { CountryCodes } from '../../data/lists/countryCodesISO.static.ts'; // const country_codes: { name: string; code: string; }[] = CountryCodes; @@ -20,8 +29,8 @@ import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface. // return null; // }; -const COMMAND_NAME = 'stock'; -const DESCRIPTION = 'returns data on stocks'; +const COMMAND_NAME = "stock"; +const DESCRIPTION = "returns data on stocks"; export default { time: 0, @@ -33,51 +42,56 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .addStringOption((option) => - option.setName('stock').setDescription('Stock you want to get data for').setRequired(true), + option.setName("stock").setDescription("Stock you want to get data for") + .setRequired(true) ), - async execute(interaction: ChatInputCommandInteraction): Promise { - if (!process.env.YAHOO_FINANCE) { + async execute( + interaction: ChatInputCommandInteraction, + ): Promise { + if (!Deno.env.get("YAHOO_FINANCE")) { return { result: false, - value: 'YAHOO_FINANCE API key is not set up', + value: "YAHOO_FINANCE API key is not set up", }; } - const stock = interaction.options.getString('stock'); + const stock = interaction.options.getString("stock"); if (!stock) { return { result: false, - value: messageHelp('commands', 'stock'), + value: messageHelp("commands", "stock"), }; } - const options: RequestOptions = { - method: 'GET', - hostname: 'yahoo-finance-low-latency.p.rapidapi.com', - port: undefined, - path: `/v8/finance/chart/${stock}?events=div%2Csplit`, + const url = new URL( + `https://yahoo-finance-low-latency.p.rapidapi.com/v8/finance/chart/${stock}`, + ); + url.searchParams.append("events", "div,split"); + + const response = await httpsFetch(url, { + method: "GET", headers: { - 'x-rapidapi-host': 'yahoo-finance-low-latency.p.rapidapi.com', - 'x-rapidapi-key': process.env.YAHOO_FINANCE, - useQueryString: 1, + "x-rapidapi-host": "yahoo-finance-low-latency.p.rapidapi.com", + "x-rapidapi-key": Deno.env.get("YAHOO_FINANCE") || "", + "Accept": "application/json", }, - }; - - const response = await httpsFetch(options); + }); if (!response) { return { result: false, - value: 'could not access the server', + value: "could not access the server", }; } - const json = getJSONFromString(response.toString().substring(response.toString().indexOf('{'))); + const json = getJSONFromString( + response.toString().substring(response.toString().indexOf("{")), + ); if (json === null) { return { result: false, - value: 'data from source was corrupted', + value: "data from source was corrupted", }; } @@ -86,7 +100,7 @@ export default { if (chart === null) { return { result: false, - value: 'could not find any stock', + value: "could not find any stock", }; } @@ -95,7 +109,7 @@ export default { if (result === null) { return { result: false, - value: 'there were no results', + value: "there were no results", }; } @@ -104,16 +118,18 @@ export default { if (meta === null) { return { result: false, - value: 'there were no meta data', + value: "there were no meta data", }; } const outcome = await interaction.reply({ embeds: [ createEmbed( - `STOCK ${meta.symbol} (${meta.regularMarketPrice}) - ${dayjs().format('DD/MM/YY')}`, - 'powered by yahoo finance', - '#FF0000', + `STOCK ${meta.symbol} (${meta.regularMarketPrice}) - ${ + dayjs().format("DD/MM/YY") + }`, + "powered by yahoo finance", + "#FF0000", [], // [ // { @@ -133,7 +149,7 @@ export default { return { result: !!outcome, - value: outcome ? '' : 'failed to send message', + value: outcome ? "" : "failed to send message", }; }, } as Command; diff --git a/src/commands/noAuth/weather.ts b/src/commands/noAuth/weather.ts index 4df4ea8b..8267c0d6 100644 --- a/src/commands/noAuth/weather.ts +++ b/src/commands/noAuth/weather.ts @@ -1,14 +1,25 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import dayjs from 'dayjs'; -import { ChatInputCommandInteraction, InteractionContextType } from 'discord.js'; -import { RequestOptions } from 'https'; -import { createEmbed, getJSONFromString, messageHelp } from '../../libraries/help.library.js'; -import { httpsFetch } from '../../libraries/http.library.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; -import { Command } from '../../types/Command.js'; - -const COMMAND_NAME = 'weather'; -const DESCRIPTION = 'returns weather data'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import "@std/dotenv/load"; +import dayjs from "npm:dayjs"; +import { + type ChatInputCommandInteraction, + InteractionContextType, +} from "npm:discord.js"; + +import { + createEmbed, + getJSONFromString, + messageHelp, +} from "../../libraries/help.library.ts"; +import { httpsFetch } from "../../libraries/http.library.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import type { Command } from "../../types/Command.ts"; + +const COMMAND_NAME = "weather"; +const DESCRIPTION = "returns weather data"; export default { time: 0, @@ -20,55 +31,64 @@ export default { .setName(COMMAND_NAME) .setDescription(DESCRIPTION) .addStringOption((option) => - option.setName('country').setDescription('The country you want to get weather data for').setRequired(true), + option.setName("country").setDescription( + "The country you want to get weather data for", + ).setRequired(true) ) .setContexts(InteractionContextType.Guild), - async execute(interaction: ChatInputCommandInteraction): Promise { - if (!process.env.OPEN_WEATHER_MAP) { + async execute( + interaction: ChatInputCommandInteraction, + ): Promise { + if (!Deno.env.get("OPEN_WEATHER_MAP")) { return { result: false, - value: 'OPEN_WEATHER_MAP API key is not set up', + value: "OPEN_WEATHER_MAP API key is not set up", }; } - const country = interaction.options.getString('country'); + const country = interaction.options.getString("country"); if (!country) { return { result: false, - value: messageHelp('commands', 'weather'), + value: messageHelp("commands", "weather"), }; } - const location = country.split(' ').join('%2C%20'); - const options: RequestOptions = { - method: 'GET', - hostname: 'api.openweathermap.org', - port: undefined, - path: `/data/2.5/weather?q=${location}&appid=${process.env.OPEN_WEATHER_MAP}`, - }; + const url = new URL(`https://api.openweathermap.org/data/2.5/weather`); + + const location = country.split(" ").join("%2C%20"); + url.searchParams.append("q", location); + url.searchParams.append("appid", Deno.env.get("OPEN_WEATHER_MAP") || ""); - const response = await httpsFetch(options); + const response = await httpsFetch(url, { + method: "GET", + headers: { + "Accept": "application/json", + }, + }); if (!response) { return { result: false, - value: 'could not access the server', + value: "could not access the server", }; } - const json = getJSONFromString(response.toString().substring(response.toString().indexOf('{'))); + const json = getJSONFromString( + response.toString().substring(response.toString().indexOf("{")), + ); if (json === null) { return { result: false, - value: 'data from source was corrupted', + value: "data from source was corrupted", }; } - if (json.cod === '404') { + if (json.cod === "404") { return { result: false, - value: messageHelp('commands', 'weather', 'city not found'), + value: messageHelp("commands", "weather", "city not found"), }; } @@ -82,18 +102,22 @@ export default { const outcome = await interaction.reply({ embeds: [ createEmbed( - `${json.name}, ${json.sys.country} at ${dayjs().format('DD/MM/YY')}`, - 'powered by OpenWeatherMap', - '#BFEFFF', + `${json.name}, ${json.sys.country} at ${dayjs().format("DD/MM/YY")}`, + "powered by OpenWeatherMap", + "#BFEFFF", [ { - emote: 'Temperature', - role: `${kelvinToCelsius(json.main.temp)}°C / ${kelvinToFahrenheit(json.main.temp)}°F`, + emote: "Temperature", + role: `${kelvinToCelsius(json.main.temp)}°C / ${ + kelvinToFahrenheit(json.main.temp) + }°F`, inline: true, }, { - emote: 'Feels like', - role: `${kelvinToCelsius(json.main.feels_like)}°C / ${kelvinToFahrenheit(json.main.feels_like)}°F`, + emote: "Feels like", + role: `${kelvinToCelsius(json.main.feels_like)}°C / ${ + kelvinToFahrenheit(json.main.feels_like) + }°F`, inline: true, }, { @@ -102,28 +126,32 @@ export default { inline: false, }, { - emote: 'Humidity', + emote: "Humidity", role: `${json.main.humidity}`, inline: true, }, { - emote: 'Wind Speed', - role: `${msToKs(json.wind.speed)}kmh / ${msToMlh(json.wind.speed)}mlh`, + emote: "Wind Speed", + role: `${msToKs(json.wind.speed)}kmh / ${ + msToMlh(json.wind.speed) + }mlh`, inline: true, }, { - emote: 'Cloudiness', + emote: "Cloudiness", role: `${json.clouds.all}%`, inline: true, }, { - emote: 'Condition', + emote: "Condition", // eslint-disable-next-line @typescript-eslint/no-unsafe-call - role: `${json.weather - .map((weather: { main: string; description: string }) => { - return `${weather.main} (${weather.description})`; - }) - .join(', ')}`, + role: `${ + json.weather + .map((weather: { main: string; description: string }) => { + return `${weather.main} (${weather.description})`; + }) + .join(", ") + }`, inline: false, }, ], @@ -138,7 +166,7 @@ export default { return { result: !!outcome, - value: outcome ? `${json.name} weather` : 'failed to send message', + value: outcome ? `${json.name} weather` : "failed to send message", }; }, } as Command; diff --git a/src/commands/noAuth/whoami.ts b/src/commands/noAuth/whoami.ts index 9b01ad1b..7c9cf8c8 100644 --- a/src/commands/noAuth/whoami.ts +++ b/src/commands/noAuth/whoami.ts @@ -1,13 +1,16 @@ -import { SlashCommandBuilder } from '@discordjs/builders'; -import { ChatInputCommandInteraction, User } from 'discord.js'; +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { ChatInputCommandInteraction, User } from "npm:discord.js"; -import { createEmbed } from '../../libraries/help.library.js'; -import { PGuild } from '../../types/classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from '../../types/classes/PTypes.interface.js'; -import { Command } from '../../types/Command.js'; +import { createEmbed } from "../../libraries/help.library.ts"; +import type { PGuild } from "../../types/classes/PGuild.class.ts"; +import { + type ReturnPromise, + ScopeLimit, +} from "../../types/classes/PTypes.interface.ts"; +import type { Command } from "../../types/Command.ts"; -const COMMAND_NAME = 'whoami'; -const DESCRIPTION = 'returns your personal card'; +const COMMAND_NAME = "whoami"; +const DESCRIPTION = "returns your personal card"; export default { time: 0, @@ -15,13 +18,20 @@ export default { ephemeral: true, auth: false, scopeLimit: ScopeLimit.NONE, - slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription(DESCRIPTION), - async execute(interaction: ChatInputCommandInteraction, pGuild: PGuild): Promise { - const pMember = pGuild.pMembers.find((pMember) => pMember.id === interaction.user.id); + slashCommand: new SlashCommandBuilder().setName(COMMAND_NAME).setDescription( + DESCRIPTION, + ), + async execute( + interaction: ChatInputCommandInteraction, + pGuild: PGuild, + ): Promise { + const pMember = pGuild.pMembers.find((pMember) => + pMember.id === interaction.user.id + ); if (!pMember || !interaction.member) { return { result: false, - value: 'could not find guild', + value: "could not find guild", }; } @@ -30,25 +40,27 @@ export default { createEmbed( interaction.member?.user?.username, null, - '#ddff00', + "#ddff00", [ { - emote: 'Level', + emote: "Level", role: pMember.level, inline: true, }, { - emote: 'Regex', - role: !pMember.regex || pMember.regex === 'null' ? 'not set' : pMember.regex, + emote: "Regex", + role: !pMember.regex || pMember.regex === "null" + ? "not set" + : pMember.regex, inline: true, }, { - emote: 'Penalties', + emote: "Penalties", role: `${pMember.penalties ? pMember.penalties : 0}`, inline: true, }, { - emote: 'Id', + emote: "Id", role: pMember.id, inline: false, }, @@ -64,7 +76,7 @@ export default { return { result: !!outcome, - value: outcome ? '' : 'could not send message', + value: outcome ? "" : "could not send message", }; }, } as Command; diff --git a/src/events/channelDelete.event.ts b/src/events/channelDelete.event.ts index ff7f16f6..dfe49848 100644 --- a/src/events/channelDelete.event.ts +++ b/src/events/channelDelete.event.ts @@ -1,27 +1,40 @@ -import { ChannelType, DMChannel, GuildChannel, TextChannel, VoiceChannel } from 'discord.js'; -import { handleChannelDeletion } from '../libraries/mongo.library.js'; +import { + ChannelType, + type DMChannel, + type GuildChannel, + type TextChannel, + VoiceChannel, +} from "npm:discord.js"; +import { handleChannelDeletion } from "../libraries/mongo.library.ts"; -import { PortalChannelType } from '../types/enums/PortalChannel.enum.js'; -import logger from '../utilities/log.utility.js'; +import { PortalChannelType } from "../types/enums/PortalChannel.enum.ts"; +import logger from "../utilities/log.utility.ts"; -export async function channelDelete(channel: DMChannel | GuildChannel): Promise { - if (channel.type !== ChannelType.GuildText && channel.type !== ChannelType.GuildVoice) { - logger.error('only voice and text channels are handled'); +export async function channelDelete( + channel: DMChannel | GuildChannel, +): Promise { + if ( + channel.type !== ChannelType.GuildText && + channel.type !== ChannelType.GuildVoice + ) { + logger.error("only voice and text channels are handled"); return; } - const deletedChannel = channel instanceof VoiceChannel ? channel : (channel as TextChannel); + const deletedChannel = channel instanceof VoiceChannel + ? channel + : (channel as TextChannel); const deletedChannelPortalType = await handleChannelDeletion(deletedChannel); if (!Object.values(PortalChannelType).includes(deletedChannelPortalType)) { - throw new Error('Only guild voice and text channels are handled'); + throw new Error("Only guild voice and text channels are handled"); } if (deletedChannelPortalType > 0) { logger.info( - `${PortalChannelType[deletedChannelPortalType].toString()} channel removed from ${deletedChannel.guild.name}|${ - deletedChannel.guild.id - }`, + `${ + PortalChannelType[deletedChannelPortalType].toString() + } channel removed from ${deletedChannel.guild.name}|${deletedChannel.guild.id}`, ); } } diff --git a/src/events/guildCreate.event.ts b/src/events/guildCreate.event.ts index 5341f95a..42dd8eb8 100644 --- a/src/events/guildCreate.event.ts +++ b/src/events/guildCreate.event.ts @@ -1,7 +1,7 @@ -import { Client, Guild } from 'discord.js'; -import { guildExists, insertGuild } from '../libraries/mongo.library.js'; +import type { Client, Guild } from "npm:discord.js"; +import { guildExists, insertGuild } from "../libraries/mongo.library.ts"; -import logger from '../utilities/log.utility.js'; +import logger from "../utilities/log.utility.ts"; export async function guildCreate(client: Client, guild: Guild): Promise { const exists = await guildExists(guild.id); @@ -15,6 +15,8 @@ export async function guildCreate(client: Client, guild: Guild): Promise { if (guildInserted) { logger.info(`inserted guild ${guild.name} [${guild.id}] into database`); } else { - logger.error(`failed to insert guild ${guild.name} [${guild.id}] into database`); + logger.error( + `failed to insert guild ${guild.name} [${guild.id}] into database`, + ); } } diff --git a/src/events/guildDelete.event.ts b/src/events/guildDelete.event.ts index 8dbe6246..a62ebdbe 100644 --- a/src/events/guildDelete.event.ts +++ b/src/events/guildDelete.event.ts @@ -1,7 +1,7 @@ -import { Guild } from 'discord.js'; -import { removeGuild } from '../libraries/mongo.library.js'; +import type { Guild } from "npm:discord.js"; +import { removeGuild } from "../libraries/mongo.library.ts"; -import logger from '../utilities/log.utility.js'; +import logger from "../utilities/log.utility.ts"; export async function guildDelete(guild: Guild): Promise { const guildRemoved = await removeGuild(guild.id); diff --git a/src/events/guildMemberAdd.event.ts b/src/events/guildMemberAdd.event.ts index 9123f965..ca6e0679 100644 --- a/src/events/guildMemberAdd.event.ts +++ b/src/events/guildMemberAdd.event.ts @@ -1,12 +1,21 @@ -import { GuildMember, PartialGuildMember, TextChannel } from 'discord.js'; -import { createEmbed } from '../libraries/help.library.js'; -import { fetchAnnouncementChannelByGuildId, insertMember } from '../libraries/mongo.library.js'; +import type { + GuildMember, + PartialGuildMember, + TextChannel, +} from "npm:discord.js"; +import { createEmbed } from "../libraries/help.library.ts"; +import { + fetchAnnouncementChannelByGuildId, + insertMember, +} from "../libraries/mongo.library.ts"; -import logger from '../utilities/log.utility.js'; +import logger from "../utilities/log.utility.ts"; -export async function guildMemberAdd(member: GuildMember | PartialGuildMember): Promise { +export async function guildMemberAdd( + member: GuildMember | PartialGuildMember, +): Promise { if (member.user.bot) { - logger.info('new member is a bot, bots are not handled'); + logger.info("new member is a bot, bots are not handled"); return; } @@ -22,8 +31,10 @@ export async function guildMemberAdd(member: GuildMember | PartialGuildMember): return; } - if (pGuild?.initialRole !== 'null') { - const initialRole = member.guild.roles.cache.find((r) => r.id === pGuild.initialRole); + if (pGuild?.initialRole !== "null") { + const initialRole = member.guild.roles.cache.find((r) => + r.id === pGuild.initialRole + ); if (initialRole) { const roleAdded = await member.roles.add(initialRole); @@ -34,23 +45,37 @@ export async function guildMemberAdd(member: GuildMember | PartialGuildMember): } } - const joinMessage = - `member: ${member.presence?.user}\n` + `id: ${member.guild.id}\n` + `\thas joined ${member.guild}`; + const joinMessage = `member: ${member.presence?.user}\n` + + `id: ${member.guild.id}\n` + `\thas joined ${member.guild}`; - const announcementChannel = ( - member.guild.channels.cache.find((channel) => channel.id === pGuild.announcement) + const announcementChannel = ( + member.guild.channels.cache.find((channel) => + channel.id === pGuild.announcement + ) ); if (announcementChannel) { const message = { embeds: [ - createEmbed('member joined', joinMessage, '#00C70D', [], member.user.avatarURL(), null, true, null, null), + createEmbed( + "member joined", + joinMessage, + "#00C70D", + [], + member.user.avatarURL(), + null, + true, + null, + null, + ), ], }; const messageSent = await announcementChannel.send(message); if (!messageSent) { - logger.warn(`failed to send join message for ${member.id} to ${member.guild.id}`); + logger.warn( + `failed to send join message for ${member.id} to ${member.guild.id}`, + ); } } diff --git a/src/events/guildMemberRemove.event.ts b/src/events/guildMemberRemove.event.ts index c9098745..cba4a52f 100644 --- a/src/events/guildMemberRemove.event.ts +++ b/src/events/guildMemberRemove.event.ts @@ -1,18 +1,29 @@ -import { GuildMember, PartialGuildMember, TextChannel } from 'discord.js'; -import { createEmbed } from '../libraries/help.library.js'; -import { fetchAnnouncementChannelByGuildId, removeMember } from '../libraries/mongo.library.js'; +import type { + GuildMember, + PartialGuildMember, + TextChannel, +} from "npm:discord.js"; +import { createEmbed } from "../libraries/help.library.ts"; +import { + fetchAnnouncementChannelByGuildId, + removeMember, +} from "../libraries/mongo.library.ts"; -import logger from '../utilities/log.utility.js'; +import logger from "../utilities/log.utility.ts"; -export async function guildMemberRemove(member: GuildMember | PartialGuildMember): Promise { +export async function guildMemberRemove( + member: GuildMember | PartialGuildMember, +): Promise { if (member.user.bot) { - logger.info('new member is a bot, bots are not handled'); + logger.info("new member is a bot, bots are not handled"); return; } const removedMember = await removeMember(member.id, member.guild.id); if (!removedMember) { - logger.error(`failed to remove member ${member.id} from ${member.guild.id}`); + logger.error( + `failed to remove member ${member.id} from ${member.guild.id}`, + ); return; } @@ -23,23 +34,37 @@ export async function guildMemberRemove(member: GuildMember | PartialGuildMember return; } - const announcementChannel = ( - member.guild.channels.cache.find((channel) => channel.id === pGuild.announcement) + const announcementChannel = ( + member.guild.channels.cache.find((channel) => + channel.id === pGuild.announcement + ) ); if (announcementChannel) { - const leaveMessage = - `member: ${member.presence?.user}\n` + `id: ${member.guild.id}\n` + `\thas left ${member.guild}`; + const leaveMessage = `member: ${member.presence?.user}\n` + + `id: ${member.guild.id}\n` + `\thas left ${member.guild}`; const message = { embeds: [ - createEmbed('member left', leaveMessage, '#FC0303', [], member.user.avatarURL(), null, true, null, null), + createEmbed( + "member left", + leaveMessage, + "#FC0303", + [], + member.user.avatarURL(), + null, + true, + null, + null, + ), ], }; const messageSent = await announcementChannel.send(message); if (!messageSent) { - logger.warn(`failed to send leave message for ${member.id} to ${member.guild.id}`); + logger.warn( + `failed to send leave message for ${member.id} to ${member.guild.id}`, + ); } } diff --git a/src/events/index.ts b/src/events/index.ts index 4187e260..98306800 100644 --- a/src/events/index.ts +++ b/src/events/index.ts @@ -1,10 +1,11 @@ -export { channelDelete } from './channelDelete.event.js'; -export { guildCreate } from './guildCreate.event.js'; -export { guildDelete } from './guildDelete.event.js'; -export { guildMemberAdd } from './guildMemberAdd.event.js'; -export { guildMemberRemove } from './guildMemberRemove.event.js'; -export { interactionCreate } from './interactionCreate.event.js'; -export { messageDelete } from './messageDelete.event.js'; -export { messageReactionAdd } from './messageReactionAdd.event.js'; -export { ready } from './ready.event.js'; -export { voiceStateUpdate } from './voiceStateUpdate.event.js'; +export { channelDelete } from "./channelDelete.event.ts"; +export { guildCreate } from "./guildCreate.event.ts"; +export { guildDelete } from "./guildDelete.event.ts"; +export { guildMemberAdd } from "./guildMemberAdd.event.ts"; +export { guildMemberRemove } from "./guildMemberRemove.event.ts"; +export { interactionCreate } from "./interactionCreate.event.ts"; +export { messageCreate } from "./messageCreate.event.ts"; +export { messageDelete } from "./messageDelete.event.ts"; +export { messageReactionAdd } from "./messageReactionAdd.event.ts"; +export { ready } from "./ready.event.ts"; +export { voiceStateUpdate } from "./voiceStateUpdate.event.ts"; diff --git a/src/events/interactionCreate.event.ts b/src/events/interactionCreate.event.ts index a4bea715..84a52218 100644 --- a/src/events/interactionCreate.event.ts +++ b/src/events/interactionCreate.event.ts @@ -1,55 +1,94 @@ -import { BaseInteraction, ChannelType, ChatInputCommandInteraction, EmbedBuilder, GuildMember } from 'discord.js'; - -import { commandLoader } from '../handlers/command.handler.js'; -import { isUserAuthorised } from '../libraries/help.library.js'; -import { fetchGuildPreData, fetchGuildRest, insertMember } from '../libraries/mongo.library.js'; -import { commandFetcher } from '../libraries/preprocessor.library.js'; -import { ActiveCooldowns, AuthCommands, NoAuthCommands } from '../types/classes/PTypes.interface.js'; -import logger from '../utilities/log.utility.js'; - -function validateBaseInteractionIsCommand(interaction: BaseInteraction): interaction is ChatInputCommandInteraction { +import { + type BaseInteraction, + ChannelType, + type ChatInputCommandInteraction, + type EmbedBuilder, + type GuildMember, +} from "npm:discord.js"; + +import { commandLoader } from "../handlers/command.handler.ts"; +import { isUserAuthorised } from "../libraries/help.library.ts"; +import { + fetchGuildPreData, + fetchGuildRest, + insertMember, +} from "../libraries/mongo.library.ts"; +import { commandFetcher } from "../libraries/preprocessor.library.ts"; +import type { + ActiveCooldowns, + AuthCommands, + NoAuthCommands, +} from "../types/classes/PTypes.interface.ts"; +import logger from "../utilities/log.utility.ts"; + +function validateBaseInteractionIsCommand( + interaction: BaseInteraction, +): interaction is ChatInputCommandInteraction { return interaction.isCommand(); } -export async function interactionCreate(interaction: BaseInteraction, activeCooldowns: ActiveCooldowns): Promise { +export async function interactionCreate( + interaction: BaseInteraction, + activeCooldowns: ActiveCooldowns, +): Promise { if (!validateBaseInteractionIsCommand(interaction)) { return; } - if (!interaction || !interaction.user || !interaction.member || !interaction.guild || !interaction.channel) { + if ( + !interaction || !interaction.user || !interaction.member || + !interaction.guild || !interaction.channel + ) { return await InteractionReply(interaction, { - content: 'interaction is missing data', + content: "interaction is missing data", ephemeral: false, }); } if (interaction.channel.type === ChannelType.DM || interaction.user.bot) { return await InteractionReply(interaction, { - content: 'interaction was made in DM or by bot', + content: "interaction was made in DM or by bot", ephemeral: false, }); } - const pGuild = await fetchGuildPreData(interaction.guild.id, interaction.user.id); + const pGuild = await fetchGuildPreData( + interaction.guild.id, + interaction.user.id, + ); if (!pGuild) { - logger.error('fetching guild pre data failed'); - return await InteractionReply(interaction, { content: 'fetching guild pre data failed', ephemeral: false }); + logger.error("fetching guild pre data failed"); + return await InteractionReply(interaction, { + content: "fetching guild pre data failed", + ephemeral: false, + }); } if (!pGuild.pMembers.some((pMember) => pMember.id === interaction.user.id)) { - const insertResponse = await insertMember(interaction.guild.id, interaction.user.id); + const insertResponse = await insertMember( + interaction.guild.id, + interaction.user.id, + ); if (!insertResponse) { - logger.error('failed to late-insert member'); - return await InteractionReply(interaction, { content: 'failed to late-insert member', ephemeral: false }); + logger.error("failed to late-insert member"); + return await InteractionReply(interaction, { + content: "failed to late-insert member", + ephemeral: false, + }); } if (interaction.guild) { - logger.info(`late-insert ${interaction.user.id} to ${interaction.guild.name} [${interaction.guild.id}]`); + logger.info( + `late-insert ${interaction.user.id} to ${interaction.guild.name} [${interaction.guild.id}]`, + ); } - return await InteractionReply(interaction, { content: 'late-inserted member', ephemeral: false }); + return await InteractionReply(interaction, { + content: "late-inserted member", + ephemeral: false, + }); } const commandName = interaction.commandName as AuthCommands | NoAuthCommands; @@ -65,7 +104,9 @@ export async function interactionCreate(interaction: BaseInteraction, activeCool if ( commandData.auth && interaction.member && - !isUserAuthorised(interaction.member as GuildMember /* needs better implementation */) + !isUserAuthorised( + interaction.member as GuildMember, /* needs better implementation */ + ) ) { return await InteractionReply(interaction, { content: `you are not authorised to use ${interaction.commandName}`, @@ -76,8 +117,11 @@ export async function interactionCreate(interaction: BaseInteraction, activeCool const pGuildRest = await fetchGuildRest(interaction.guild.id); if (!pGuildRest) { - logger.error('fetching guild rest data failed'); - return await InteractionReply(interaction, { content: 'fetching guild rest data failed', ephemeral: false }); + logger.error("fetching guild rest data failed"); + return await InteractionReply(interaction, { + content: "fetching guild rest data failed", + ephemeral: false, + }); } pGuild.pMembers = pGuildRest.pMembers; @@ -99,11 +143,19 @@ export async function interactionCreate(interaction: BaseInteraction, activeCool ); if (!commandResponse) { - logger.error(`something went wrong with command ${interaction.commandName}`); - return await InteractionReply(interaction, { content: 'something went wrong', ephemeral: false }); + logger.error( + `something went wrong with command ${interaction.commandName}`, + ); + + return await InteractionReply(interaction, { + content: "something went wrong", + ephemeral: false, + }); } - const content = commandResponse.value !== '' ? commandResponse.value : 'command succeeded'; + const content = commandResponse.value !== "" + ? commandResponse.value + : "command succeeded"; const ephemeral = commandData.ephemeral; return await InteractionReply(interaction, { content, ephemeral }); @@ -117,10 +169,9 @@ async function InteractionReply( return; } - const reply = - typeof response.content === 'string' - ? { content: response.content, ephemeral: response.ephemeral } - : { embeds: response.content, ephemeral: response.ephemeral }; + const reply = typeof response.content === "string" + ? { content: response.content, ephemeral: response.ephemeral } + : { embeds: response.content, ephemeral: response.ephemeral }; if (interaction.isRepliable()) { await interaction.reply(reply); diff --git a/src/events/messageCreate.event.ts b/src/events/messageCreate.event.ts new file mode 100644 index 00000000..7e058014 --- /dev/null +++ b/src/events/messageCreate.event.ts @@ -0,0 +1,154 @@ +import type { GuildMember, Message, PartialMessage } from "npm:discord.js"; +import { fetchGuild } from "../libraries/mongo.library.ts"; + +import {} from "../libraries/help.library.ts"; +import { searchYoutube } from "../libraries/music.library2.ts"; +import { VoiceLibrary } from "../libraries/voice.library.ts"; +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import logger from "../utilities/log.utility.ts"; + +export async function messageCreate( + message: Message | PartialMessage, +): Promise { + if (!message.guild) { + logger.error("message does not have guild"); + return; + } + + const pGuild = await fetchGuild(message.guild.id); + if (!pGuild) { + logger.error(`failed to fetch guild ${message.guild.id}`); + return; + } + + if (message.author?.bot) { + return; + } + + if (pGuild.musicData.channelId === message.channelId) { + await handleMusicMessageCreation(message, pGuild); + } +} + +async function handleMusicMessageCreation( + message: Message | PartialMessage, + pGuild: PGuild, +): Promise { + try { + // Delete message right away + deleteMessage(message); + + const content = message.content; + if (!content) { + logger.error("Message does not have content"); + return; + } + + // Validate guild and channel + if ( + !message.guild?.channels.cache.some((channel) => + channel.id === pGuild.musicData.channelId + ) + ) { + logger.error( + `Failed to find music channel ${pGuild.musicData.channelId}`, + ); + return; + } + + const member = message.member; + if (!member) { + logger.error("Message does not have member"); + return; + } + + // Check if user is in a voice channel + const voiceChannel = member.voice.channel; + if (!voiceChannel) { + await sendUserDM( + member, + "You must be in a voice channel to use music commands", + ); + return; + } + + // Validate voice channel state + if (!voiceChannel.joinable) { + await sendUserDM( + member, + "I don't have permission to join your voice channel", + ); + return; + } + + // Check existing connection + const currentVoiceConnection = VoiceLibrary.getVoiceConnectionByGuildId( + member.guild.id, + ); + + // If already connected to the right channel, proceed with search + if (currentVoiceConnection) { + if (currentVoiceConnection.joinConfig.channelId === voiceChannel.id) { + const video = await searchYoutube(content); + if (!video) { + logger.error("Failed to search youtube"); + return; + } + logger.info(`Selected video ${video.title}`); + return; + } else { + // Connected to wrong channel - need to switch + currentVoiceConnection.destroy(); + } + } + + // Try to join voice channel + try { + const newVoiceConnection = await VoiceLibrary.joinUserVoiceChannelById( + voiceChannel.id, + member.guild, + ); + + if (!newVoiceConnection) { + throw new Error("Failed to establish voice connection"); + } + + const video = await searchYoutube(content); + if (!video) { + logger.error("Failed to search youtube"); + return; + } + logger.info(`Selected video ${video.title}`); + } catch (error) { + logger.error(`Failed to join voice channel: ${error}`); + await sendUserDM( + member, + "Failed to join voice channel. Please ensure you are connected and try again.", + ); + return; + } + } catch (error) { + logger.error(`Error in handleMusicMessageCreation: ${error}`); + } +} + +// Helper function for sending DMs +async function sendUserDM( + member: GuildMember, + content: string, +): Promise { + try { + const dmChannel = await member.createDM(); + await dmChannel.send(content); + } catch (error) { + logger.error(`Failed to send DM to user ${member.id}: ${error}`); + } +} + +function deleteMessage(message: Message | PartialMessage): void { + if (!message.deletable) { + return; + } + + message.delete(); +} diff --git a/src/events/messageDelete.event.ts b/src/events/messageDelete.event.ts index b26e6c2f..bf71678f 100644 --- a/src/events/messageDelete.event.ts +++ b/src/events/messageDelete.event.ts @@ -1,17 +1,24 @@ -import { Message, PartialMessage, TextChannel } from 'discord.js'; +import type { Message, PartialMessage, TextChannel } from "npm:discord.js"; import { createMusicLyricsMessage, createMusicMessage, isMessageDeleted, markMessageAsDeleted, -} from '../libraries/help.library.js'; -import { fetchGuild, removePoll, removeVendor } from '../libraries/mongo.library.js'; +} from "../libraries/help.library.ts"; +import { + fetchGuild, + removePoll, + removeVendor, +} from "../libraries/mongo.library.ts"; -import logger from '../utilities/log.utility.js'; +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import logger from "../utilities/log.utility.ts"; -export async function messageDelete(message: Message | PartialMessage): Promise { +export async function messageDelete( + message: Message | PartialMessage, +): Promise { if (!message.guild) { - logger.error('message does not have guild'); + logger.error("message does not have guild"); return; } @@ -21,75 +28,120 @@ export async function messageDelete(message: Message | PartialMessage): return; } - const pRoles = pGuild.pRoles; - const pMusicData = pGuild.musicData; + if (pGuild.musicData.messageId === message.id) { + await handleMusicMessageDeletion(message, pGuild); + } else if (pGuild.musicData.messageLyricsId === message.id) { + await handleLyricMessageDeletion(message, pGuild); + } else if (pGuild.pPolls.some((p) => p.messageId === message.id)) { + await handlePollMessageDeletion(message, pGuild); + } else if ( + pGuild.pRoles.some((roleGiver) => roleGiver.messageId === message.id) + ) { + await handleVendorMessageDeletion(message, pGuild); + } +} - if (pMusicData.messageId === message.id) { - const musicChannel = ( - message.guild?.channels.cache.find((channel) => channel.id === pGuild.musicData.channelId) - ); +async function handleMusicMessageDeletion( + message: Message | PartialMessage, + pGuild: PGuild, +): Promise { + const musicChannel = ( + message.guild?.channels.cache.find((channel) => + channel.id === pGuild.musicData.channelId + ) + ); - if (!musicChannel) { - logger.error(`failed to find music channel ${pGuild.musicData.channelId}`); - return; - } + if (!musicChannel) { + logger.error( + `failed to find music channel ${pGuild.musicData.channelId}`, + ); + return; + } - const musicMessage = await createMusicMessage(musicChannel, pGuild); - if (!musicMessage) { - logger.error('failed to create music message'); - return; - } + const musicMessage = await createMusicMessage(musicChannel, pGuild); + if (!musicMessage) { + logger.error("failed to create music message"); + return; + } - if (pGuild.musicData.messageLyricsId) { - if (musicChannel) { - const lyricMessage = await musicChannel.messages.fetch(pGuild.musicData.messageLyricsId); + if (pGuild.musicData.messageLyricsId) { + if (musicChannel) { + const lyricMessage = await musicChannel.messages.fetch( + pGuild.musicData.messageLyricsId, + ); - if (!lyricMessage) { - logger.error(`failed to fetch lyrics message ${pGuild.musicData.messageLyricsId}`); - return; - } + if (!lyricMessage) { + logger.error( + `failed to fetch lyrics message ${pGuild.musicData.messageLyricsId}`, + ); + return; + } - if (isMessageDeleted(lyricMessage)) { - const deletedMessage = await lyricMessage.delete(); + if (isMessageDeleted(lyricMessage)) { + const deletedMessage = await lyricMessage.delete(); - if (deletedMessage) { - markMessageAsDeleted(deletedMessage); - logger.info(`deleted lyrics message ${pGuild.musicData.messageLyricsId}`); - } + if (deletedMessage) { + markMessageAsDeleted(deletedMessage); + logger.info( + `deleted lyrics message ${pGuild.musicData.messageLyricsId}`, + ); } } } - } else if (pMusicData.messageLyricsId === message.id) { - const musicChannel = ( - message?.guild?.channels.cache.find((channel) => channel.id === pGuild.musicData.channelId) - ); + } +} - if (musicChannel && pGuild.musicData.messageId) { - const lyricMessage = await createMusicLyricsMessage(musicChannel, pGuild, pGuild.musicData.messageId); - if (!lyricMessage) { - logger.warn('failed to create lyrics message'); - } - } - } else if (pGuild.pPolls.some((p) => p.messageId === message.id)) { - // const poll = pGuild.pPolls.find((p) => p.messageId === message.id); - // if (!poll) { - // logger.warn(`failed to find poll ${message.id}`); - // } - - const removedPoll = await removePoll(pGuild.id, message.id); - if (!removedPoll) { - logger.warn(`failed to remove poll ${message.id}`); - } - } else { - const roleGiver = pRoles.find((roleGiver) => roleGiver.messageId === message.id); - if (!roleGiver) { - logger.warn(`failed to find role giver ${message.id}`); - return; - } +async function handleLyricMessageDeletion( + message: Message | PartialMessage, + pGuild: PGuild, +): Promise { + const musicChannel = ( + message?.guild?.channels.cache.find((channel) => + channel.id === pGuild.musicData.channelId + ) + ); - const response = await removeVendor(pGuild.id, roleGiver.messageId); - if (!response) { - logger.warn(`failed to remove vendor ${roleGiver.messageId}`); + if (musicChannel && pGuild.musicData.messageId) { + const lyricMessage = await createMusicLyricsMessage( + musicChannel, + pGuild, + pGuild.musicData.messageId, + ); + if (!lyricMessage) { + logger.warn("failed to create lyrics message"); } } } + +async function handlePollMessageDeletion( + message: Message | PartialMessage, + pGuild: PGuild, +): Promise { + // const poll = pGuild.pPolls.find((p) => p.messageId === message.id); + // if (!poll) { + // logger.warn(`failed to find poll ${message.id}`); + // } + + const removedPoll = await removePoll(pGuild.id, message.id); + if (!removedPoll) { + logger.warn(`failed to remove poll ${message.id}`); + } +} + +async function handleVendorMessageDeletion( + message: Message | PartialMessage, + pGuild: PGuild, +): Promise { + const roleGiver = pGuild.pRoles.find((roleGiver) => + roleGiver.messageId === message.id + ); + if (!roleGiver) { + logger.warn(`failed to find role giver ${message.id}`); + return; + } + + const response = await removeVendor(pGuild.id, roleGiver.messageId); + if (!response) { + logger.warn(`failed to remove vendor ${roleGiver.messageId}`); + } +} diff --git a/src/events/messageReactionAdd.event.ts b/src/events/messageReactionAdd.event.ts index 534785bc..dc3d1ecc 100644 --- a/src/events/messageReactionAdd.event.ts +++ b/src/events/messageReactionAdd.event.ts @@ -1,12 +1,12 @@ -// import { entersState, getVoiceConnection, VoiceConnectionStatus } from "@discordjs/voice"; -// import { Client, MessageReaction, Role, User } from "discord.js"; +// import { entersState, getVoiceConnection, VoiceConnectionStatus } from "npm:@discordjs/voice"; +// import { Client, MessageReaction, Role, User } from "npm:discord.js"; // import { getRole } from "../libraries/guild.library"; // import { createEmbed, isUserAuthorised, isUserDj, logger, updateMusicLyricsMessage, updateMusicMessage } from "../libraries/help.library"; // import { clearMusicVote, fetchGuildReactionData, insertMusicVote, removePoll, setMusicData, updateGuild } from "../libraries/mongo.library"; // // import { export_txt, get_lyrics, pause, play, skip } from "../libraries/music.library"; // import { PGuild } from "../types/classes/PGuild.class"; -import logger from '../utilities/log.utility.js'; +import logger from "../utilities/log.utility.ts"; // import { Client, MessageReaction, PartialMessageReaction, PartialUser, User } from 'discord.js'; @@ -460,7 +460,7 @@ import logger from '../utilities/log.utility.js'; // } // } -export async function messageReactionAdd( +export function messageReactionAdd( // @ts-expect-error: description client: Client, // @ts-expect-error: description @@ -470,7 +470,11 @@ export async function messageReactionAdd( ): Promise { return new Promise((resolve, reject) => { logger.info(`${client} ${messageReaction} ${user}`); - return reject('under construction'); + if (Date.now() > 0) { + return resolve(); + } + return reject("under construction"); + // if (user.bot) { // return resolve(''); // 'not handling bot reactions' // } else if (messageReaction.message?.guild) { diff --git a/src/events/ready.event.ts b/src/events/ready.event.ts index b6b9cba4..36066e1a 100644 --- a/src/events/ready.event.ts +++ b/src/events/ready.event.ts @@ -1,47 +1,67 @@ -import { ActivityOptions, ActivityType, Client, Guild, PresenceData, PresenceStatusData } from 'discord.js'; - -import { removeDeletedChannels, removeEmptyVoiceChannels } from '../libraries/help.library.js'; -import { getFunction } from '../libraries/localisation.library.js'; -import { fetchGuildMembers, guildExists, insertGuild, insertMember, removeMember } from '../libraries/mongo.library.js'; -import { PMember } from '../types/classes/PMember.class.js'; -import { LogActions } from '../types/classes/PTypes.interface.js'; -import logger from '../utilities/log.utility.js'; +import { + type ActivityOptions, + ActivityType, + type Client, + type Guild, + type PresenceData, + type PresenceStatusData, +} from "npm:discord.js"; + +import { + removeDeletedChannels, + removeEmptyVoiceChannels, +} from "../libraries/help.library.ts"; +import { getFunction } from "../libraries/localisation.library.ts"; +import { + fetchGuildMembers, + guildExists, + insertGuild, + insertMember, + removeMember, +} from "../libraries/mongo.library.ts"; +import type { PMember } from "../types/classes/PMember.class.ts"; +import { LogActions } from "../types/classes/PTypes.interface.ts"; +import logger from "../utilities/log.utility.ts"; export async function ready(client: Client): Promise { if (!client.user) { - logger.warn('could not fetch user from client'); + logger.warn("could not fetch user from client"); return; } const activitiesOptions: ActivityOptions = { - name: './help', // `in ${client.guilds.cache.size} servers`` + name: "./help", // `in ${client.guilds.cache.size} servers`` type: ActivityType.Listening, - url: 'https://github.com/keybraker', + url: "https://github.com/keybraker", }; const presenceData: PresenceData = { activities: [activitiesOptions], - status: 'online' satisfies PresenceStatusData, + status: "online" satisfies PresenceStatusData, afk: false, }; - client.user.setPresence(presenceData); + await client.user.setPresence(presenceData); let index = 0; client.guilds.cache.forEach((guild: Guild) => { logger.info(`${index++}. logged onto guild ${guild} (${guild.id})`); - addGuildAgain(guild, client).catch((e) => logger.warn(`failed to add guild ${guild.name} [${guild.id}] (${e})`)); + addGuildAgain(guild, client).catch((e) => + logger.warn(`failed to add guild ${guild.name} [${guild.id}] (${e})`) + ); removeDeletedChannels(guild); removeEmptyVoiceChannels(guild); }); - const func = getFunction('console', 1, LogActions.ready) as unknown as (args: { - memberLength: number; - channelLength: number; - guildLength: number; - }) => string; + const func = getFunction("console", 1, LogActions.ready) as unknown as ( + args: { + memberLength: number; + channelLength: number; + guildLength: number; + }, + ) => string; logger.info( func({ @@ -54,31 +74,44 @@ export async function ready(client: Client): Promise { async function addedWhenDown(guild: Guild, pMembers: PMember[]): Promise { const membersFetched = await guild.members.fetch(); - const members = membersFetched.map((member) => member).filter((member) => !member.user.bot); + const members = membersFetched.map((member) => member).filter((member) => + !member.user.bot + ); for (let j = 0; j < members.length; j++) { - const alreadyInDatabase = pMembers.find((pMember) => pMember.id === members[j].id); + const alreadyInDatabase = pMembers.find((pMember) => + pMember.id === members[j].id + ); if (alreadyInDatabase) { continue; } - logger.info(`inserting member: ${members[j].id} to ${guild.name} [${guild.id}]`); + logger.info( + `inserting member: ${members[j].id} to ${guild.name} [${guild.id}]`, + ); // if member is inside guild but not in portal db, add member const memberInserted = await insertMember(guild.id, members[j].id); if (!memberInserted) { - logger.error('failed to late-insert member'); + logger.error("failed to late-insert member"); } else { - logger.info(`late-insert ${members[j].id} to ${guild.name} [${guild.id}]`); + logger.info( + `late-insert ${members[j].id} to ${guild.name} [${guild.id}]`, + ); } } } -async function removedWhenDown(guild: Guild, pMembers: PMember[]): Promise { +async function removedWhenDown( + guild: Guild, + pMembers: PMember[], +): Promise { const membersFetched = await guild.members.fetch(); - const members = membersFetched.map((member) => member).filter((member) => !member.user.bot); + const members = membersFetched.map((member) => member).filter((member) => + !member.user.bot + ); for (let j = 0; j < pMembers.length; j++) { const member = members.find((member) => member.id === pMembers[j].id); @@ -87,14 +120,18 @@ async function removedWhenDown(guild: Guild, pMembers: PMember[]): Promise continue; } - logger.info(`removing member: ${pMembers[j].id} from ${guild.name} [${guild.id}]`); + logger.info( + `removing member: ${pMembers[j].id} from ${guild.name} [${guild.id}]`, + ); const memberRemoved = await removeMember(pMembers[j].id, guild.id); if (!memberRemoved) { - logger.error('failed to late-remove member'); + logger.error("failed to late-remove member"); } else { - logger.info(`late-remove ${pMembers[j].id} to ${guild.name} [${guild.id}]`); + logger.info( + `late-remove ${pMembers[j].id} to ${guild.name} [${guild.id}]`, + ); } } } diff --git a/src/events/voiceStateUpdate.event.ts b/src/events/voiceStateUpdate.event.ts index 0b39ce17..acf84a10 100644 --- a/src/events/voiceStateUpdate.event.ts +++ b/src/events/voiceStateUpdate.event.ts @@ -1,33 +1,52 @@ -import { VoiceConnectionStatus, getVoiceConnection } from '@discordjs/voice'; -import { Client, Guild, TextChannel, VoiceChannel, VoiceState } from 'discord.js'; +import { + getVoiceConnection, + VoiceConnectionStatus, +} from "npm:@discordjs/voice"; +import type { + Client, + Guild, + TextChannel, + VoiceChannel, + VoiceState, +} from "npm:discord.js"; import { createVoiceChannel, generateChannelName, includedInPChannels, includedInVoiceList, -} from '../libraries/guild.library.js'; +} from "../libraries/guild.library.ts"; import { isChannelDeleted, isGuildDeleted, updateMusicLyricsMessage, updateMusicMessage, -} from '../libraries/help.library.js'; -import { fetchGuild, removeVoice, setMusicData, updateGuild } from '../libraries/mongo.library.js'; -import { updateTimestamp } from '../libraries/user.library.js'; -import { PGuild } from '../types/classes/PGuild.class.js'; -import { PChannel } from '../types/classes/PPortalChannel.class.js'; -import logger from '../utilities/log.utility.js'; - -export async function voiceStateUpdate(client: Client, oldState: VoiceState, newState: VoiceState): Promise { - logger.info(`voiceStateUpdate event triggered with ${oldState.channelId} to ${newState.channelId}`); - if (oldState.channel?.id === newState.channel?.id) { - logger.warn('channel change detected'); +} from "../libraries/help.library.ts"; +import { + fetchGuild, + removeVoice, + setMusicData, + updateGuild, +} from "../libraries/mongo.library.ts"; +import { updateTimestamp } from "../libraries/user.library.ts"; +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import type { PChannel } from "../types/classes/PPortalChannel.class.ts"; +import logger from "../utilities/log.utility.ts"; + +export async function voiceStateUpdate( + client: Client, + oldState: VoiceState, + newState: VoiceState, +): Promise { + logger.info( + `voiceStateUpdate event triggered with ${oldState.channelId} to ${newState.channelId}`, + ); + if (newState.channel?.id === oldState.channel?.id) { return; } if (!newState?.guild) { - logger.warn('could not find guild in Portal'); + logger.warn("could not find guild in Portal"); return; } @@ -37,12 +56,12 @@ export async function voiceStateUpdate(client: Client, oldState: VoiceState, new const pGuild = await fetchGuild(newState?.guild.id); if (!pGuild) { - logger.warn('could not find guild in Portal'); + logger.warn("could not find guild in Portal"); return; } if (!pGuild) { - logger.warn('could not find guild in Portal'); + logger.warn("could not find guild in Portal"); return; } @@ -52,16 +71,20 @@ export async function voiceStateUpdate(client: Client, oldState: VoiceState, new if (p.id === newChannel.id) { if (p.noBots && newState.member?.user.bot) { - newState.disconnect('voice channel does not allow bots').catch((e) => { - logger.error(`failed to kick: ${e}`); - return; - }); + newState.disconnect("voice channel does not allow bots").catch( + (e) => { + logger.error(`failed to kick: ${e}`); + return; + }, + ); - channelEmptyCheck(newChannel as VoiceChannel, pGuild, client).catch((e) => { - logger.error(`failed to check channel state: ${e}`); - }); + channelEmptyCheck(newChannel as VoiceChannel, pGuild, client).catch( + (e) => { + logger.error(`failed to check channel state: ${e}`); + }, + ); - logger.warn('portal channel does not allow bots'); + logger.warn("portal channel does not allow bots"); return; } } @@ -71,16 +94,20 @@ export async function voiceStateUpdate(client: Client, oldState: VoiceState, new if (v.id === newChannel.id) { if (v.noBots) { - newState.disconnect('voice channel does not allow bots').catch((e) => { - logger.error(`failed to kick: ${e}`); - return; - }); - - channelEmptyCheck(newChannel as VoiceChannel, pGuild, client).catch((e) => { - logger.error(`failed to check channel state: ${e}`); - }); - - logger.warn('voice channel does not allow bots'); + newState.disconnect("voice channel does not allow bots").catch( + (e) => { + logger.error(`failed to kick: ${e}`); + return; + }, + ); + + channelEmptyCheck(newChannel as VoiceChannel, pGuild, client).catch( + (e) => { + logger.error(`failed to check channel state: ${e}`); + }, + ); + + logger.warn("voice channel does not allow bots"); return; } } @@ -107,10 +134,14 @@ export async function voiceStateUpdate(client: Client, oldState: VoiceState, new // } if (!oldChannel) { - const response = await fromNull(newChannel as VoiceChannel | null, pGuild, newState); + const response = await fromNull( + newChannel as VoiceChannel | null, + pGuild, + newState, + ); if (!response) { - logger.warn('failed to create voice channel'); + logger.warn("failed to create voice channel"); return; } @@ -126,7 +157,7 @@ export async function voiceStateUpdate(client: Client, oldState: VoiceState, new ); if (!response) { - logger.warn('failed to create voice channel'); + logger.warn("failed to create voice channel"); return; } @@ -136,7 +167,10 @@ export async function voiceStateUpdate(client: Client, oldState: VoiceState, new } // delete portal's voice channel -async function deleteVoiceChannel(channel: VoiceChannel | TextChannel, pGuild: PGuild): Promise { +async function deleteVoiceChannel( + channel: VoiceChannel | TextChannel, + pGuild: PGuild, +): Promise { if (!channel.deletable) { return `channel ${channel.name} (${channel.id}) is not deletable`; } @@ -146,12 +180,17 @@ async function deleteVoiceChannel(channel: VoiceChannel | TextChannel, pGuild: P if (pVoiceChannel.id === channel.id) { try { const deletedChannel = await channel.delete(); - const response = await removeVoice(pGuild.id, pChannel.id, pVoiceChannel.id); + const response = await removeVoice( + pGuild.id, + pChannel.id, + pVoiceChannel.id, + ); return response ? `channel (${deletedChannel.id}) deleted` : `channel (${deletedChannel.id}) failed to be deleted`; } catch (e) { + logger.error(`failed to delete channel: ${e}`); return `channel ${channel.name} (${channel.id}) failed to be delete`; } } @@ -168,12 +207,14 @@ async function fiveMinuteRefresher( minutes: number, ): Promise { if (isGuildDeleted(guild) || isChannelDeleted(voiceChannel)) { - logger.info(`voice channel with id ${voiceChannel.id} is deleted, stopping refreshers`); + logger.info( + `voice channel with id ${voiceChannel.id} is deleted, stopping refreshers`, + ); return; } const pGuild = await fetchGuild(guild.id).catch(() => { - logger.error('failed to fetch guild'); + logger.error("failed to fetch guild"); }); if (!pGuild) { @@ -181,15 +222,17 @@ async function fiveMinuteRefresher( } generateChannelName(voiceChannel, portalList, pGuild, guild).catch(() => { - logger.error('failed to generate channel name'); + logger.error("failed to generate channel name"); }); setTimeout( () => { if (!isGuildDeleted(guild) && !isChannelDeleted(voiceChannel)) { - generateChannelName(voiceChannel, portalList, pGuild, guild).catch(() => { - logger.error('failed to generate channel name'); - }); + generateChannelName(voiceChannel, portalList, pGuild, guild).catch( + () => { + logger.error("failed to generate channel name"); + }, + ); fiveMinuteRefresher(voiceChannel, portalList, guild, minutes); } @@ -203,26 +246,30 @@ async function channelEmptyCheck( pGuild: PGuild, client: Client, ): Promise { - if (oldChannel.members.size === 0 && includedInVoiceList(oldChannel.id, pGuild.pChannels)) { + if ( + oldChannel.members.size === 0 && + includedInVoiceList(oldChannel.id, pGuild.pChannels) + ) { return await deleteVoiceChannel(oldChannel, pGuild).catch((e) => { return `an error occurred while deleting voice | ${e}`; }); } else if (oldChannel.members.size === 1) { if (!client.voice) { - return 'Portal is not connected'; + return "Portal is not connected"; } const voiceConnection = getVoiceConnection(oldChannel.guild.id); if ( !voiceConnection || - [VoiceConnectionStatus.Destroyed, VoiceConnectionStatus.Disconnected].includes(voiceConnection.state.status) + [VoiceConnectionStatus.Destroyed, VoiceConnectionStatus.Disconnected] + .includes(voiceConnection.state.status) ) { - return 'Portal is not connected'; + return "Portal is not connected"; } pGuild.musicQueue = []; - updateGuild(pGuild.id, 'musicQueue', pGuild.musicQueue).catch((e) => { + updateGuild(pGuild.id, "musicQueue", pGuild.musicQueue).catch((e) => { return `failed to update guild: ${e}`; }); voiceConnection.disconnect(); @@ -238,13 +285,13 @@ async function channelEmptyCheck( oldChannel.guild, pGuild, pGuild.musicQueue.length > 0 ? pGuild.musicQueue[0] : undefined, - 'left last', + "left last", false, ).catch((e) => { return `failed to update music message: ${e}`; }); - updateMusicLyricsMessage(oldChannel.guild, pGuild, '').catch((e) => { + updateMusicLyricsMessage(oldChannel.guild, pGuild, "").catch((e) => { return `failed to update music lyrics: ${e}`; }); @@ -253,16 +300,20 @@ async function channelEmptyCheck( return `an error occurred while deleting voice | ${e}`; }); } else { - return 'Portal left voice channel'; + return "Portal left voice channel"; } } - return 'channel is not handled by Portal'; + return "channel is not handled by Portal"; } -async function fromNull(newChannel: VoiceChannel | null, pGuild: PGuild, newState: VoiceState): Promise { +async function fromNull( + newChannel: VoiceChannel | null, + pGuild: PGuild, + newState: VoiceState, +): Promise { if (!newChannel) { - return 'strange, from null to null'; + return "strange, from null to null"; } // joined from null @@ -271,7 +322,7 @@ async function fromNull(newChannel: VoiceChannel | null, pGuild: PGuild, newStat const pChannel = pGuild.pChannels.find((p) => p.id === newChannel.id); if (!pChannel) { - return 'null->existing (source: null | dest: portalList) / could not find pChannel'; + return "null->existing (source: null | dest: portalList) / could not find pChannel"; } await createVoiceChannel(newState, pChannel).catch((e) => { @@ -284,12 +335,13 @@ async function fromNull(newChannel: VoiceChannel | null, pGuild: PGuild, newStat }); if (level) { - newState.member?.send(`you reached level ${level} in ${newState.guild}!`).catch((e) => { - logger.error(`failed to send message: ${e}`); - }); + newState.member?.send(`you reached level ${level} in ${newState.guild}!`) + .catch((e) => { + logger.error(`failed to send message: ${e}`); + }); } - return 'null->existing (source: null | dest: portalList)'; + return "null->existing (source: null | dest: portalList)"; } else if (includedInVoiceList(newChannel.id, pGuild.pChannels)) { // joined voice channel fiveMinuteRefresher(newChannel, pGuild.pChannels, newState.guild, 5); @@ -299,12 +351,13 @@ async function fromNull(newChannel: VoiceChannel | null, pGuild: PGuild, newStat }); if (level) { - newState.member?.send(`you reached level ${level} in ${newState.guild}!`).catch((e) => { - logger.error(`failed to send message: ${e}`); - }); + newState.member?.send(`you reached level ${level} in ${newState.guild}!`) + .catch((e) => { + logger.error(`failed to send message: ${e}`); + }); } - return 'null->existing (source: null | dest: voiceList)'; + return "null->existing (source: null | dest: voiceList)"; } else { // joined other channel const level = await updateTimestamp(newState, pGuild) // points for voice @@ -313,12 +366,13 @@ async function fromNull(newChannel: VoiceChannel | null, pGuild: PGuild, newStat }); if (level) { - newState.member?.send(`you reached level ${level} in ${newState.guild}!`).catch((e) => { - logger.error(`failed to send message: ${e}`); - }); + newState.member?.send(`you reached level ${level} in ${newState.guild}!`) + .catch((e) => { + logger.error(`failed to send message: ${e}`); + }); } - return 'null->existing (source: null | dest: other channel)'; + return "null->existing (source: null | dest: other channel)"; } } @@ -336,16 +390,17 @@ async function fromExisting( }); if (level) { - newState.member?.send(`you reached level ${level} in ${newState.guild}!`).catch((e) => { - logger.error(`failed to send message: ${e}`); - }); + newState.member?.send(`you reached level ${level} in ${newState.guild}!`) + .catch((e) => { + logger.error(`failed to send message: ${e}`); + }); } channelEmptyCheck(oldChannel, pGuild, client).catch((e) => { logger.error(`failed to check channel state: ${e}`); }); - return 'existing->null'; + return "existing->null"; } // Moved from channel to channel @@ -355,20 +410,21 @@ async function fromExisting( }); if (level) { - newState.member?.send(`you reached level ${level} in ${newState.guild}!`).catch((e) => { - logger.error(`failed to send message: ${e}`); - }); + newState.member?.send(`you reached level ${level} in ${newState.guild}!`) + .catch((e) => { + logger.error(`failed to send message: ${e}`); + }); } if (includedInPChannels(oldChannel.id, pGuild.pChannels)) { if (!includedInVoiceList(newChannel.id, pGuild.pChannels)) { - return 'not handled by portal'; + return "not handled by portal"; } // has been handled before await fiveMinuteRefresher(newChannel, pGuild.pChannels, newState.guild, 5); - return 'existing->existing (source: portalList | dest: voiceList) / has been handled before'; + return "existing->existing (source: portalList | dest: voiceList) / has been handled before"; } else if (includedInVoiceList(oldChannel.id, pGuild.pChannels)) { await channelEmptyCheck(oldChannel, pGuild, client).catch((e) => { logger.error(`failed to check channel state: ${e}`); @@ -379,22 +435,27 @@ async function fromExisting( const pChannel = pGuild.pChannels.find((p) => p.id === newChannel.id); if (!pChannel) { - return 'could not find Portal in database'; + return "could not find Portal in database"; } await createVoiceChannel(newState, pChannel).catch((e) => { return `an error occurred while creating voice channel: ${e}`; }); - return 'existing->existing (source: voiceList | dest: portalList) has been handled before'; + return "existing->existing (source: voiceList | dest: portalList) has been handled before"; } else if (includedInVoiceList(newChannel.id, pGuild.pChannels)) { // moved from voice to voice - await fiveMinuteRefresher(newChannel, pGuild.pChannels, newState.guild, 5); - - return 'existing->existing (source: voiceList | dest: voiceList)'; + await fiveMinuteRefresher( + newChannel, + pGuild.pChannels, + newState.guild, + 5, + ); + + return "existing->existing (source: voiceList | dest: voiceList)"; } else { // moved from voice to other refresher(newChannel, pGuild.portalList, newState.guild, 5); - return 'existing->existing (source: voiceList | dest: other)'; + return "existing->existing (source: voiceList | dest: other)"; } } else { // Joined portal channel @@ -402,20 +463,25 @@ async function fromExisting( const pChannel = pGuild.pChannels.find((p) => p.id === newChannel.id); if (!pChannel) { - return 'existing->existing (source: other voice | dest: portalList) / could not find portal in DB, contact Portal support'; + return "existing->existing (source: other voice | dest: portalList) / could not find portal in DB, contact Portal support"; } await createVoiceChannel(newState, pChannel).catch((e) => { return `existing->existing (source: other voice | dest: portalList ): ${e}`; }); - return 'existing->existing (source: other voice | dest: portalList)'; + return "existing->existing (source: other voice | dest: portalList)"; } else if (includedInVoiceList(newChannel.id, pGuild.pChannels)) { // left created channel and joins another created - await fiveMinuteRefresher(newChannel, pGuild.pChannels, newState.guild, 5); - return 'existing->existing (source: other voice | dest: voiceList)'; + await fiveMinuteRefresher( + newChannel, + pGuild.pChannels, + newState.guild, + 5, + ); + return "existing->existing (source: other voice | dest: voiceList)"; } } - return 'existing->existing (source: other voice | dest: voiceList)'; + return "existing->existing (source: other voice | dest: voiceList)"; } diff --git a/src/handlers/command.handler.ts b/src/handlers/command.handler.ts index 8519051c..b1abed5c 100644 --- a/src/handlers/command.handler.ts +++ b/src/handlers/command.handler.ts @@ -1,11 +1,16 @@ -import { ChatInputCommandInteraction } from 'discord.js'; - -import * as auth from '../commands/auth/index.js'; -import * as noAuth from '../commands/noAuth/index.js'; -import { getElapsedTime, pad } from '../libraries/help.library.js'; -import { PGuild } from '../types/classes/PGuild.class.js'; -import { ActiveCooldowns, AuthCommands, NoAuthCommands, ScopeLimit } from '../types/classes/PTypes.interface.js'; -import logger from '../utilities/log.utility.js'; +import type { ChatInputCommandInteraction } from "npm:discord.js"; + +import * as auth from "../commands/auth/index.ts"; +import * as noAuth from "../commands/noAuth/index.ts"; +import { getElapsedTime, pad } from "../libraries/help.library.ts"; +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import { + type ActiveCooldowns, + type AuthCommands, + type NoAuthCommands, + ScopeLimit, +} from "../types/classes/PTypes.interface.ts"; +import logger from "../utilities/log.utility.ts"; export async function commandLoader( interaction: ChatInputCommandInteraction, @@ -19,19 +24,29 @@ export async function commandLoader( return await commandExecution(interaction, command, pGuild); } - const cooldown = hasActiveCooldown(interaction, command, scopeLimit, activeCooldowns); + const cooldown = hasActiveCooldown( + interaction, + command, + scopeLimit, + activeCooldowns, + ); if (cooldown) { - logger.info(`User ${interaction.user.id} tried to use ${command} but is on cooldown`); + logger.info( + `User ${interaction.user.id} tried to use ${command} but is on cooldown`, + ); const elapsedTime = getElapsedTime(cooldown.timestamp, time); - const ending = - scopeLimit !== ScopeLimit.MEMBER ? `, as it was used again in* **${interaction.guild?.name}**` : '.*'; + const ending = scopeLimit !== ScopeLimit.MEMBER + ? `, as it was used again in* **${interaction.guild?.name}**` + : ".*"; const awaitMessage = `you need to wait **${pad(elapsedTime.remainingMin)}:` + `${pad(elapsedTime.remainingSec)}/${pad(elapsedTime.timeoutMin)}:` + - `${pad(elapsedTime.timeoutSec)}** *to use* **${command}** *again${ending}`; + `${ + pad(elapsedTime.timeoutSec) + }** *to use* **${command}** *again${ending}`; return { result: false, @@ -42,12 +57,13 @@ export async function commandLoader( const commandReturn = await commandExecution(interaction, command, pGuild); if (commandReturn.result) { - const activeCooldown = - scopeLimit === ScopeLimit.GUILD ? activeCooldowns[ScopeLimit.GUILD] : activeCooldowns[ScopeLimit.MEMBER]; + const activeCooldown = scopeLimit === ScopeLimit.GUILD + ? activeCooldowns[ScopeLimit.GUILD] + : activeCooldowns[ScopeLimit.MEMBER]; activeCooldown.push({ member: interaction.user.id, - guild: interaction?.guild?.id ?? 'null', + guild: interaction?.guild?.id ?? "null", command: command, timestamp: Date.now(), }); @@ -55,7 +71,9 @@ export async function commandLoader( if (time) { setTimeout( () => { - const updatedCooldown = activeCooldown.filter((active) => active.command !== command); + const updatedCooldown = activeCooldown.filter((active) => + active.command !== command + ); if (scopeLimit === ScopeLimit.GUILD) { activeCooldowns[ScopeLimit.GUILD] = updatedCooldown; } else { @@ -88,12 +106,16 @@ function hasActiveCooldown( scopeLimit: Omit, activeCooldowns: ActiveCooldowns, ) { - const activeCooldown = - scopeLimit === ScopeLimit.GUILD ? activeCooldowns[ScopeLimit.GUILD] : activeCooldowns[ScopeLimit.MEMBER]; + const activeCooldown = scopeLimit === ScopeLimit.GUILD + ? activeCooldowns[ScopeLimit.GUILD] + : activeCooldowns[ScopeLimit.MEMBER]; return activeCooldown.find((activeCurrent) => { if (activeCurrent.command === command) { - if (scopeLimit === ScopeLimit.MEMBER && activeCurrent.member === interaction?.user.id) { + if ( + scopeLimit === ScopeLimit.MEMBER && + activeCurrent.member === interaction?.user.id + ) { if (interaction.guild && activeCurrent.guild === interaction.guild.id) { return true; } diff --git a/src/handlers/discord.handler.ts b/src/handlers/discord.handler.ts index 5a6b0a49..4fbd266d 100644 --- a/src/handlers/discord.handler.ts +++ b/src/handlers/discord.handler.ts @@ -1,14 +1,23 @@ -import { CacheFactory, Client, ClientOptions, GatewayIntentBits, Partials, Options } from 'discord.js'; +import { + type CacheFactory, + Client, + type ClientOptions, + GatewayIntentBits, + Options, + Partials, +} from "npm:discord.js"; export function clientHandler() { - const makeCache: CacheFactory = Options.cacheWithLimits({ MessageManager: 200 }); + const makeCache: CacheFactory = Options.cacheWithLimits({ + MessageManager: 200, + }); const partials = [ Partials.User, Partials.Channel, Partials.GuildMember, Partials.Message, - Partials.Reaction + Partials.Reaction, ]; const intents = [ @@ -29,5 +38,5 @@ export function clientHandler() { } export async function connectToDiscord(client: Client, token: string) { - return client.login(token); + return await client.login(token); } diff --git a/src/handlers/event.handler.ts b/src/handlers/event.handler.ts index fd9ac3ac..86a4893a 100644 --- a/src/handlers/event.handler.ts +++ b/src/handlers/event.handler.ts @@ -1,4 +1,4 @@ -import { +import type { BaseInteraction, Client, DMChannel, @@ -13,49 +13,78 @@ import { PartialUser, User, VoiceState, -} from 'discord.js'; +} from "npm:discord.js"; -import * as events from '../events/index.js'; -import { ActiveCooldowns } from '../types/classes/PTypes.interface.js'; -import logger from '../utilities/log.utility.js'; +import * as events from "../events/index.ts"; +import type { ActiveCooldowns } from "../types/classes/PTypes.interface.ts"; +import logger from "../utilities/log.utility.ts"; -export async function eventHandler( +export function eventHandler( client: Client, activeCooldowns: ActiveCooldowns = { guild: [], member: [] }, -): Promise { +): void { // This event will run if the bot starts, and logs in, successfully. - client.once('ready', async () => await events.ready(client)); + client.once("ready", async () => await events.ready(client)); // This event triggers when a channel is deleted - client.on('channelDelete', async (channel: DMChannel | GuildChannel) => await events.channelDelete(channel)); + client.on( + "channelDelete", + async (channel: DMChannel | GuildChannel) => + await events.channelDelete(channel), + ); // This event triggers when the bot joins a guild - client.on('guildCreate', async (guild: Guild) => await events.guildCreate(client, guild)); + client.on( + "guildCreate", + async (guild: Guild) => await events.guildCreate(client, guild), + ); // this event triggers when the bot is removed from a guild - client.on('guildDelete', async (guild: Guild) => await events.guildDelete(guild)); + client.on( + "guildDelete", + async (guild: Guild) => await events.guildDelete(guild), + ); // This event triggers when a new member joins a guild. - client.on('guildMemberAdd', async (member: GuildMember | PartialGuildMember) => await events.guildMemberAdd(member)); + client.on( + "guildMemberAdd", + async (member: GuildMember | PartialGuildMember) => + await events.guildMemberAdd(member), + ); // This event triggers when a new member leaves a guild. client.on( - 'guildMemberRemove', - async (member: GuildMember | PartialGuildMember) => await events.guildMemberRemove(member), + "guildMemberRemove", + async (member: GuildMember | PartialGuildMember) => + await events.guildMemberRemove(member), + ); + // This event triggers when a message is created + client.on( + "messageCreate", + async (message: Message | PartialMessage) => + await events.messageCreate(message), ); // This event triggers when a message is deleted - client.on('messageDelete', async (message: Message | PartialMessage) => await events.messageDelete(message)); + client.on( + "messageDelete", + async (message: Message | PartialMessage) => + await events.messageDelete(message), + ); // This event triggers when a member reacts to a message client.on( - 'messageReactionAdd', - async (messageReaction: MessageReaction | PartialMessageReaction, user: User | PartialUser) => - await events.messageReactionAdd(client, messageReaction, user), + "messageReactionAdd", + async ( + messageReaction: MessageReaction | PartialMessageReaction, + user: User | PartialUser, + ) => await events.messageReactionAdd(client, messageReaction, user), ); // This event triggers when a member joins or leaves a voice channel client.on( - 'voiceStateUpdate', - async (oldState: VoiceState, newState: VoiceState) => await events.voiceStateUpdate(client, oldState, newState), + "voiceStateUpdate", + async (oldState: VoiceState, newState: VoiceState) => + await events.voiceStateUpdate(client, oldState, newState), ); // This event will run when a slash command is called. client.on( - 'interactionCreate', - async (interaction: BaseInteraction) => await events.interactionCreate(interaction, activeCooldowns), + "interactionCreate", + async (interaction: BaseInteraction) => + await events.interactionCreate(interaction, activeCooldowns), ); - logger.info('Event handlers registered'); + logger.info("event handlers registered"); } diff --git a/src/handlers/mongo.handler.ts b/src/handlers/mongo.handler.ts index 12dfe157..606265fc 100644 --- a/src/handlers/mongo.handler.ts +++ b/src/handlers/mongo.handler.ts @@ -1,19 +1,19 @@ -import mongoose, { ConnectOptions } from 'mongoose'; +import mongoose, { type ConnectOptions } from "npm:mongoose"; -import logger from '../utilities/log.utility.js'; +import logger from "../utilities/log.utility.ts"; export async function mongoHandler(mongoUrl: string) { - mongoose.connection.on('connecting', () => { - logger.info('connecting to mongo', { service: 'mongse' }); + mongoose.connection.on("connecting", () => { + logger.info("connecting to mongo", { service: "mongse" }); }); - mongoose.connection.on('connected', () => { - logger.info('connected to mongo', { service: 'mongse' }); + mongoose.connection.on("connected", () => { + logger.info("connected to mongo", { service: "mongse" }); }); const connectOptions: ConnectOptions = { - dbName: 'portal', - compressors: 'zlib', + dbName: "portal", + compressors: "zlib", maxPoolSize: 50, wtimeoutMS: 2500, }; @@ -24,5 +24,5 @@ export async function mongoHandler(mongoUrl: string) { // compressors: 'zlib' // } - return mongoose.connect(mongoUrl, connectOptions); + return await mongoose.connect(mongoUrl, connectOptions); } diff --git a/src/libraries/adapter.library.ts b/src/libraries/adapter.library.ts index e32d0d25..54f52b3d 100644 --- a/src/libraries/adapter.library.ts +++ b/src/libraries/adapter.library.ts @@ -1,6 +1,16 @@ -import { DiscordGatewayAdapterCreator, DiscordGatewayAdapterLibraryMethods } from '@discordjs/voice'; -// import { GatewayVoiceServerUpdateDispatchData } from 'discord-api-types/v9'; -import { Client, Events, GatewayDispatchEvents, Guild, Snowflake, Status, VoiceBasedChannel } from 'discord.js'; +import type { + DiscordGatewayAdapterCreator, + DiscordGatewayAdapterLibraryMethods, +} from "npm:@discordjs/voice"; +import { + type Client, + Events, + GatewayDispatchEvents, + type Guild, + type Snowflake, + Status, + type VoiceBasedChannel, +} from "npm:discord.js"; const adapters = new Map(); const trackedClients = new Set(); @@ -17,7 +27,10 @@ function trackClient(client: Client) { adapters.get(payload.guild_id)?.onVoiceServerUpdate(payload); }); client.ws.on(GatewayDispatchEvents.VoiceStateUpdate, (payload) => { - if (payload.guild_id && payload.session_id && payload.user_id === client.user?.id) { + if ( + payload.guild_id && payload.session_id && + payload.user_id === client.user?.id + ) { adapters.get(payload.guild_id)?.onVoiceStateUpdate(payload); } }); @@ -48,7 +61,9 @@ function trackGuild(guild: Guild) { * * @param channel - The channel to create the adapter for */ -export function createDiscordJSAdapter(channel: VoiceBasedChannel): DiscordGatewayAdapterCreator { +export function createDiscordJSAdapter( + channel: VoiceBasedChannel, +): DiscordGatewayAdapterCreator { return (methods) => { adapters.set(channel.guild.id, methods); trackClient(channel.client); diff --git a/src/libraries/guild.library.ts b/src/libraries/guild.library.ts index 99dbc5f7..fa2ee191 100644 --- a/src/libraries/guild.library.ts +++ b/src/libraries/guild.library.ts @@ -1,57 +1,67 @@ -import dayjs from 'dayjs'; +import "@std/dotenv/load"; +import dayjs from "npm:dayjs"; import { - CategoryChannel, - CategoryChannelResolvable, + type CategoryChannel, + type CategoryChannelResolvable, ChannelType, - ChatInputCommandInteraction, - Guild, - GuildChannelCreateOptions, - GuildMember, - Message, - OverwriteResolvable, + type ChatInputCommandInteraction, + type Guild, + type GuildChannelCreateOptions, + type GuildMember, + type Message, + type OverwriteResolvable, PermissionFlagsBits, PermissionsBitField, - Role, - TextBasedChannel, - TextChannel, - VoiceBasedChannel, - VoiceChannel, - VoiceState -} from 'discord.js'; -import voca from 'voca'; - -import { getAttribute, isAttribute } from '../Interpreter/attribute.functions.js'; -import { getPipe, isPipe } from '../Interpreter/pipe.functions.js'; -import { getVariable, isVariable } from '../Interpreter/variable.functions.js'; -import { PGuild } from '../types/classes/PGuild.class.js'; -import { PChannel } from '../types/classes/PPortalChannel.class.js'; -import { PVoiceChannel } from '../types/classes/PVoiceChannel.class.js'; -import { PortalChannelType } from '../types/enums/PortalChannel.enum.js'; -import { Prefix } from '../types/enums/Prefix.enum.js'; -import logger from '../utilities/log.utility.js'; -import { createMusicLyricsMessage, createMusicMessage, getJSONFromString, maxString } from './help.library.js'; -import { insertVoice, updateGuild } from './mongo.library.js'; + type Role, + type TextBasedChannel, + type TextChannel, + type VoiceBasedChannel, + type VoiceChannel, + type VoiceState, +} from "npm:discord.js"; +import voca from "npm:voca"; + +import { + getAttribute, + isAttribute, +} from "../Interpreter/attribute.functions.ts"; +import { getPipe, isPipe } from "../Interpreter/pipe.functions.ts"; +import { getVariable, isVariable } from "../Interpreter/variable.functions.ts"; +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import type { PChannel } from "../types/classes/PPortalChannel.class.ts"; +import { PVoiceChannel } from "../types/classes/PVoiceChannel.class.ts"; +import type { PortalChannelType } from "../types/enums/PortalChannel.enum.ts"; +import { Prefix } from "../types/enums/Prefix.enum.ts"; +import logger from "../utilities/log.utility.ts"; +import { + createMusicLyricsMessage, + createMusicMessage, + getJSONFromString, + maxString, +} from "./help.library.ts"; +import { insertVoice, updateGuild } from "./mongo.library.ts"; +import { TextChannelType } from "../types/enums/TextChannelType.enum.ts"; function inlineOperator(str: string) { switch (str) { - case '==': - return (a: string, b: string) => a == b; - case '===': - return (a: string, b: string) => a === b; - case '!=': - return (a: string, b: string) => a != b; - case '!==': - return (a: string, b: string) => a !== b; - case '>': - return (a: string, b: string) => a > b; - case '<': - return (a: string, b: string) => a < b; - case '>=': - return (a: string, b: string) => a >= b; - case '<=': - return (a: string, b: string) => a <= b; - default: - return (a: string, b: string) => a == b; + case "==": + return (a: string, b: string) => a == b; + case "===": + return (a: string, b: string) => a === b; + case "!=": + return (a: string, b: string) => a != b; + case "!==": + return (a: string, b: string) => a !== b; + case ">": + return (a: string, b: string) => a > b; + case "<": + return (a: string, b: string) => a < b; + case ">=": + return (a: string, b: string) => a >= b; + case "<=": + return (a: string, b: string) => a <= b; + default: + return (a: string, b: string) => a == b; } } @@ -60,7 +70,7 @@ export function getOptions( topic: string, canWrite = true, parent?: CategoryChannelResolvable, - type: ChannelType = ChannelType.GuildText + type: ChannelType = ChannelType.GuildText, ) { return { name: topic, @@ -79,16 +89,27 @@ export function getOptions( } as GuildChannelCreateOptions; } -export function includedInPortalGuilds(guildId: string, pGuilds: PGuild[]): boolean { +export function includedInPortalGuilds( + guildId: string, + pGuilds: PGuild[], +): boolean { return pGuilds ? pGuilds.some((pGuild) => pGuild.id === guildId) : false; } -export function includedInPChannels(channelId: string, pChannels: PChannel[]): boolean { +export function includedInPChannels( + channelId: string, + pChannels: PChannel[], +): boolean { return pChannels ? pChannels.some((p) => p.id === channelId) : false; } -export function includedInVoiceList(channelId: string, pChannels: PChannel[]): boolean { - return pChannels ? pChannels.some((p) => p.pVoiceChannels.some((v) => v.id === channelId)) : false; +export function includedInVoiceList( + channelId: string, + pChannels: PChannel[], +): boolean { + return pChannels + ? pChannels.some((p) => p.pVoiceChannels.some((v) => v.id === channelId)) + : false; } export function includedInPIgnores(channelId: string, pGuild: PGuild): boolean { @@ -103,27 +124,38 @@ export function isMusicChannel(channelId: string, pGuild: PGuild): boolean { return pGuild ? pGuild.musicData.channelId === channelId : false; } -export function isAnnouncementChannel(channelId: string, pGuild: PGuild): boolean { +export function isAnnouncementChannel( + channelId: string, + pGuild: PGuild, +): boolean { return pGuild ? pGuild.announcement === channelId : false; } -export function getRole(guild: Guild | null, roleIdOrName: string): Role | undefined { - return guild?.roles.cache.find((role) => role.id === roleIdOrName || role.name === roleIdOrName); +export function getRole( + guild: Guild | null, + roleIdOrName: string, +): Role | undefined { + return guild?.roles.cache.find((role) => + role.id === roleIdOrName || role.name === roleIdOrName + ); } export async function createChannel( guild: Guild, channelName: string, channelOptions: GuildChannelCreateOptions, - channelCategory: string | null + channelCategory: string | null, ): Promise { - const newGuildChannel = await guild.channels.create({ ...channelOptions, name: channelName }); + const newGuildChannel = await guild.channels.create({ + ...channelOptions, + name: channelName, + }); if (!newGuildChannel) { - return Promise.reject(new Error('failed to create new channel')); + return Promise.reject(new Error("failed to create new channel")); } - if (typeof channelCategory === 'string') { + if (typeof channelCategory === "string") { // create category const newGuildCategoryChannel = await guild.channels.create({ name: channelName, @@ -131,7 +163,7 @@ export async function createChannel( }); // channelName if (!newGuildCategoryChannel) { - return Promise.reject(new Error('failed to create new category channel')); + return Promise.reject(new Error("failed to create new category channel")); } newGuildChannel.setParent(newGuildCategoryChannel).catch((e) => { @@ -142,18 +174,23 @@ export async function createChannel( return newGuildChannel.id; } -function createVoiceOptions(state: VoiceState, pChannel: PChannel): GuildChannelCreateOptions { +function createVoiceOptions( + state: VoiceState, + pChannel: PChannel, +): GuildChannelCreateOptions { let permissionOverwrites = null; if (pChannel.allowedRoles) { permissionOverwrites = pChannel.allowedRoles.map( (id) => - { + { id, allow: PermissionsBitField.Flags.Connect, // ['CONNECT'] - } + }, ); - if (!pChannel.allowedRoles.some((id) => id === state.guild.roles.everyone.id)) { + if ( + !pChannel.allowedRoles.some((id) => id === state.guild.roles.everyone.id) + ) { permissionOverwrites.push({ id: state.guild.roles.everyone.id, deny: PermissionsBitField.Flags.Connect, // ['CONNECT'] @@ -169,7 +206,7 @@ function createVoiceOptions(state: VoiceState, pChannel: PChannel): GuildChannel } return { - name: 'loading..', + name: "loading..", type: ChannelType.GuildVoice, bitrate: 96000, userLimit: pChannel.userLimitPortal, @@ -178,18 +215,27 @@ function createVoiceOptions(state: VoiceState, pChannel: PChannel): GuildChannel } as GuildChannelCreateOptions; } -export async function createVoiceChannel(state: VoiceState, pChannel: PChannel): Promise { +export async function createVoiceChannel( + state: VoiceState, + pChannel: PChannel, +): Promise { if (!state) { - return Promise.reject('there is no state'); + return Promise.reject("there is no state"); } else if (!state.channel) { - return Promise.reject('state has no channel'); + return Promise.reject("state has no channel"); } else if (!state.member) { - return Promise.reject('state has no member'); + return Promise.reject("state has no member"); } - const voiceOptions: GuildChannelCreateOptions = createVoiceOptions(state, pChannel); + const voiceOptions: GuildChannelCreateOptions = createVoiceOptions( + state, + pChannel, + ); - const newGuildVoiceChannel = await state.guild.channels.create({ ...voiceOptions, name: 'loading..' }); + const newGuildVoiceChannel = await state.guild.channels.create({ + ...voiceOptions, + name: "loading..", + }); if (!newGuildVoiceChannel) { return false; } @@ -202,16 +248,18 @@ export async function createVoiceChannel(state: VoiceState, pChannel: PChannel): pChannel.noBots, pChannel.locale, pChannel.annAnnounce, - pChannel.annUser + pChannel.annUser, ); insertVoice(state.member.guild.id, pChannel.id, newVoice).catch((e) => { return Promise.reject(`failed to store voice channel: ${e}`); }); - await state.member.voice.setChannel(newGuildVoiceChannel as unknown as VoiceBasedChannel); // as VoiceBasedChannel) + await state.member.voice.setChannel( + newGuildVoiceChannel as unknown as VoiceBasedChannel, + ); // as VoiceBasedChannel) - return 'created channel and moved member to new voice'; + return "created channel and moved member to new voice"; } // @deprecated replaced by music.ts @@ -219,10 +267,10 @@ export async function createMusicChannel( guild: Guild, musicChannel: string, musicCategory: string | CategoryChannel | null, - pGuild: PGuild + pGuild: PGuild, ): Promise { let newMusicCategoryGuildChannel: CategoryChannel | undefined; - if (musicCategory && typeof musicCategory === 'string') { + if (musicCategory && typeof musicCategory === "string") { // with category newMusicCategoryGuildChannel = await guild.channels .create({ name: musicCategory, type: ChannelType.GuildCategory }) @@ -239,7 +287,8 @@ export async function createMusicChannel( name: `${musicChannel}`, parent: newMusicCategoryGuildChannel, type: ChannelType.GuildText, - topic: 'play:▶️, pause:⏸, skip:⏭, pin last:📌, lyrics:📄, queue text:⬇️, clear queue:🧹, leave:🚪', // , vol dwn ➖, vol up ➕ + topic: + "play:▶️, pause:⏸, skip:⏭, pin last:📌, lyrics:📄, queue text:⬇️, clear queue:🧹, leave:🚪", // , vol dwn ➖, vol up ➕ }) .catch((e) => { return Promise.reject(`failed to create focus channel: ${e}`); @@ -251,18 +300,25 @@ export async function createMusicChannel( pGuild.musicData.channelId = newMusicGuildChannel.id; - const musicMessageId = await createMusicMessage(newMusicGuildChannel, pGuild).catch((e) => { - return Promise.reject(`failed to send music message: ${e}`); - }); + const musicMessageId = await createMusicMessage(newMusicGuildChannel, pGuild) + .catch((e) => { + return Promise.reject(`failed to send music message: ${e}`); + }); if (!musicMessageId) { return false; } - logger.log({ level: 'info', type: 'none', message: `send music message ${musicMessageId}` }); - createMusicLyricsMessage(newMusicGuildChannel, pGuild, musicMessageId).catch((e) => { - return Promise.reject(`failed to send music lyrics message: ${e}`); + logger.log({ + level: "info", + type: "none", + message: `send music message ${musicMessageId}`, }); + createMusicLyricsMessage(newMusicGuildChannel, pGuild, musicMessageId).catch( + (e) => { + return Promise.reject(`failed to send music lyrics message: ${e}`); + }, + ); return true; } @@ -270,29 +326,34 @@ export async function createMusicChannel( export async function moveMembersBack( oldChannel: VoiceBasedChannel, member: GuildMember, - memberFound: GuildMember + memberFound: GuildMember, ): Promise { if (!oldChannel.deletable) { - return Promise.reject('could not move to original voice channel because it was deleted'); + return Promise.reject( + "could not move to original voice channel because it was deleted", + ); } - const setUserBackToOriginalChannel = await member.voice.setChannel(oldChannel).catch((e) => { - return Promise.reject(`focus did not end properly: ${e}`); - }); + const setUserBackToOriginalChannel = await member.voice.setChannel(oldChannel) + .catch((e) => { + return Promise.reject(`focus did not end properly: ${e}`); + }); if (!setUserBackToOriginalChannel) { - return Promise.reject('did not move requester back to original channel'); + return Promise.reject("did not move requester back to original channel"); } - const setUserFocusBackToOriginalChannel = await memberFound.voice.setChannel(oldChannel).catch((e) => { - return Promise.reject(`focus did not end properly: ${e}`); - }); + const setUserFocusBackToOriginalChannel = await memberFound.voice + .setChannel(oldChannel) + .catch((e) => { + return Promise.reject(`focus did not end properly: ${e}`); + }); if (!setUserFocusBackToOriginalChannel) { - return Promise.reject('did not move requested back to original channel'); + return Promise.reject("did not move requested back to original channel"); } - return 'focus ended properly'; + return "focus ended properly"; } export async function createFocusChannel( @@ -300,17 +361,18 @@ export async function createFocusChannel( member: GuildMember, memberFound: GuildMember, focusTime: number, - pChannel: PChannel + pChannel: PChannel, ): Promise { if (!member.voice.channel) { - return Promise.reject('member is not in a voice channel'); + return Promise.reject("member is not in a voice channel"); } - const chatRoomName = `${focusTime === 0 - ? 'Private Room' - : `PR-${focusTime}' $hour:$minute/${dayjs() - .add(focusTime, focusTime === 1 ? 'minute' : 'minutes') - .format('hh:mm')}` + const chatRoomName = `${ + focusTime === 0 ? "Private Room" : `PR-${focusTime}' $hour:$minute/${ + dayjs() + .add(focusTime, focusTime === 1 ? "minute" : "minutes") + .format("hh:mm") + }` }`; const voiceOptions: GuildChannelCreateOptions = { @@ -320,12 +382,14 @@ export async function createFocusChannel( userLimit: 2, }; - const newVoiceChannel = await guild.channels.create(voiceOptions).catch((e) => { - return Promise.reject(`failed to create focus channel: ${e}`); - }); + const newVoiceChannel = await guild.channels.create(voiceOptions).catch( + (error) => { + return Promise.reject(`failed to create focus channel: ${error}`); + }, + ); if (!newVoiceChannel) { - return Promise.reject('failed to create new voice channel'); + return Promise.reject("failed to create new voice channel"); } member.voice @@ -351,26 +415,32 @@ export async function createFocusChannel( pChannel.noBots, pChannel.locale, pChannel.annAnnounce, - pChannel.annUser - ) + pChannel.annUser, + ), ).catch((e) => { return Promise.reject(`failed to store voice channel: ${e}`); }); if (focusTime === 0) { - return 'private room successfully created'; + return "private room successfully created"; } - return focusTime === 0 ? 'private room successfully created' : 'focus channel successfully created'; + return focusTime === 0 + ? "private room successfully created" + : "focus channel successfully created"; } -export async function deleteChannel( +export function deleteChannel( type: PortalChannelType, channelToDelete: VoiceChannel | TextChannel, interaction: ChatInputCommandInteraction | null, - isPortal = false -): Promise { - logger.log({ level: 'info', type: 'none', message: `${type}, ${channelToDelete}, ${interaction}, ${isPortal}` }); + isPortal = false, +): boolean { + logger.log({ + level: "info", + type: "none", + message: `${type}, ${channelToDelete}, ${interaction}, ${isPortal}`, + }); return true; // if (isPortal && channelToDelete.deletable) { // const channelDeleted = await channelToDelete.delete().catch((e) => { @@ -490,12 +560,14 @@ export async function deleteChannel( // return true; } -export async function deleteMessage(message: Message): Promise { +export function deleteMessage(message: Message): Promise { if (!message || !message.deletable) { - return false; + return new Promise( + (resolve) => resolve(false), + ); } - const delay = (process.env.DELETE_DELAY as unknown as number) * 1000; + const delay = (Deno.env.get("DELETE_DELAY") as unknown as number) * 1000; return new Promise((resolve) => { setTimeout(async () => { @@ -513,7 +585,7 @@ export async function generateChannelName( voiceChannel: VoiceChannel, pChannels: PChannel[], pGuild: PGuild, - guild: Guild + guild: Guild, ): Promise { for (let i = 0; i < pChannels.length; i++) { for (let j = 0; j < pChannels[i].pVoiceChannels.length; j++) { @@ -523,12 +595,14 @@ export async function generateChannelName( // me creating an database spam let regex = pChannels[i].pVoiceChannels[j].regex; if (pChannels[i].regexOverwrite) { - const member = voiceChannel.members.find((m) => m.id === pChannels[i].pVoiceChannels[j].creatorId); + const member = voiceChannel.members.find( + (m) => m.id === pChannels[i].pVoiceChannels[j].creatorId, + ); if (member) { const pMember = pGuild.pMembers.find((m) => m.id === member.id); - if (pMember?.regex && pMember.regex !== 'null') { + if (pMember?.regex && pMember.regex !== "null") { regex = pMember.regex; } } @@ -542,7 +616,7 @@ export async function generateChannelName( pChannels, pGuild, guild, - pChannels[i].pVoiceChannels[j].creatorId + pChannels[i].pVoiceChannels[j].creatorId, ) : regex; @@ -574,28 +648,30 @@ export function regexInterpreter( pChannels: PChannel[], pGuild: PGuild, guild: Guild, - memberId: string + memberId: string, ): string { let lastSpaceIndex = 0; let lastVariableEndIndex = 0; let lastAttributeEndIndex = 0; - let lastVariable = ''; - let lastAttribute = ''; - let newChannelName = ''; + let lastVariable = ""; + let lastAttribute = ""; + let newChannelName = ""; for (let i = 0; i < regex.length; i++) { if (regex[i] === Prefix.VARIABLE) { const variable = isVariable(regex.substring(i)); if (variable.length !== 0) { - const returnValue: string | number = getVariable( - voiceChannel, - pVoiceChannel, - pChannels, - pGuild, - guild, - variable + const returnValue: string | number = ( + getVariable( + voiceChannel, + pVoiceChannel, + pChannels, + pGuild, + guild, + variable, + ) ); if (returnValue !== null) { @@ -621,7 +697,7 @@ export function regexInterpreter( pChannels, pGuild, guild, - attr //, pMember + attr, //, pMember // voiceChannel, pVoiceChannel, p, pGuild, attr, pMember ); @@ -646,7 +722,8 @@ export function regexInterpreter( if (returnValue !== null) { newChannelName = newChannelName.substring( 0, - voca.chars(newChannelName).length - voca.chars(lastVariable).length + voca.chars(newChannelName).length - + voca.chars(lastVariable).length, ); newChannelName += returnValue; i += voca.chars(pipe).length; @@ -659,7 +736,8 @@ export function regexInterpreter( if (returnValue !== null) { newChannelName = newChannelName.substring( 0, - voca.chars(newChannelName).length - voca.chars(lastAttribute).length + voca.chars(newChannelName).length - + voca.chars(lastAttribute).length, ); newChannelName += returnValue; i += voca.chars(pipe).length; @@ -667,7 +745,10 @@ export function regexInterpreter( newChannelName += regex[i]; } } else { - const returnValue = getPipe(newChannelName.substring(lastSpaceIndex, newChannelName.length), pipe); + const returnValue = getPipe( + newChannelName.substring(lastSpaceIndex, newChannelName.length), + pipe, + ); if (returnValue !== null) { const str_for_pipe = returnValue; @@ -681,22 +762,27 @@ export function regexInterpreter( } else { newChannelName += regex[i]; } - } else if (regex[i] === '{' && regex[i + 1] !== undefined && regex[i + 1] === '{') { + } else if ( + regex[i] === "{" && regex[i + 1] !== undefined && regex[i + 1] === "{" + ) { try { // did not put into structure_list due to many unnecessary function calls let isValid = false; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const statement = getJSONFromString( - regex.substring(i + 1, i + 1 + regex.substring(i + 1).indexOf('}}') + 1) + regex.substring( + i + 1, + i + 1 + regex.substring(i + 1).indexOf("}}") + 1, + ), ); - if (!statement) return 'error'; + if (!statement) return "error"; - if (Object.prototype.hasOwnProperty.call(statement, 'if')) { - if (Object.prototype.hasOwnProperty.call(statement, 'is')) { - if (Object.prototype.hasOwnProperty.call(statement, 'with')) { - if (Object.prototype.hasOwnProperty.call(statement, 'yes')) { - if (Object.prototype.hasOwnProperty.call(statement, 'no')) { + if (Object.prototype.hasOwnProperty.call(statement, "if")) { + if (Object.prototype.hasOwnProperty.call(statement, "is")) { + if (Object.prototype.hasOwnProperty.call(statement, "with")) { + if (Object.prototype.hasOwnProperty.call(statement, "yes")) { + if (Object.prototype.hasOwnProperty.call(statement, "no")) { isValid = true; } } @@ -706,19 +792,19 @@ export function regexInterpreter( if (!isValid) { newChannelName += regex[i]; - if (regex[i] === ' ') { + if (regex[i] === " ") { lastSpaceIndex = i + 1; } } else { if ( - statement.is === '==' || - statement.is === '===' || - statement.is === '!=' || - statement.is === '!==' || - statement.is === '>' || - statement.is === '<' || - statement.is === '>=' || - statement.is === '<=' + statement.is === "==" || + statement.is === "===" || + statement.is === "!=" || + statement.is === "!==" || + statement.is === ">" || + statement.is === "<" || + statement.is === ">=" || + statement.is === "<=" ) { if ( inlineOperator(statement.is)( @@ -729,7 +815,7 @@ export function regexInterpreter( pChannels, pGuild, guild, - memberId + memberId, ), regexInterpreter( statement.with, @@ -738,8 +824,8 @@ export function regexInterpreter( pChannels, pGuild, guild, - memberId - ) + memberId, + ), ) ) { const value = regexInterpreter( @@ -749,9 +835,9 @@ export function regexInterpreter( pChannels, pGuild, guild, - memberId + memberId, ); - if (value !== '--') { + if (value !== "--") { newChannelName += value; } } else { @@ -762,74 +848,59 @@ export function regexInterpreter( pChannels, pGuild, guild, - memberId + memberId, ); - if (value !== '--') { + if (value !== "--") { newChannelName += value; } } - i += regex.substring(i + 1).indexOf('}}') + 2; + i += regex.substring(i + 1).indexOf("}}") + 2; } else { - return 'error'; + return "error"; } } } catch (e) { - logger.log({ level: 'info', type: 'none', message: `failed to parse json: ${e}` }); + logger.log({ + level: "info", + type: "none", + message: `failed to parse json: ${e}`, + }); newChannelName += regex[i]; } } else { newChannelName += regex[i]; - if (regex[i] === ' ') { + if (regex[i] === " ") { lastSpaceIndex = i + 1; } } } - if (newChannelName === '') { - return ''; + if (newChannelName === "") { + return ""; } return newChannelName; } -export async function doesChannelHaveUsage(textBasedChannelId: TextBasedChannel['id'], pGuild: PGuild) { +export function getChannelTypeById( + textBasedChannelId: string, + pGuild: PGuild, +): TextChannelType { if (!textBasedChannelId) { - return { - result: false, - value: 'could not get channel id', - }; + return TextChannelType.NONE; } if (isAnnouncementChannel(textBasedChannelId, pGuild)) { - const response = await updateGuild(pGuild.id, 'announcement', 'null').catch(() => { - return { - result: true, - value: 'failed to remove announcement channel', - }; - }); - - return { - result: true, - value: response ? 'successfully removed announcement channel' : 'failed to remove announcement channel', - }; + return TextChannelType.ANNOUNCEMENT; } if (isMusicChannel(textBasedChannelId, pGuild)) { - return { - result: true, - value: 'this can\'t be set as an announcement channel for it is the music channel', - }; + return TextChannelType.MUSIC; } if (isUrlOnlyChannel(textBasedChannelId, pGuild)) { - return { - result: true, - value: 'this can\'t be set as the announcement channel for it is an url channel', - }; + return TextChannelType.URL; } - return { - result: false, - value: '', - }; + return TextChannelType.NONE; } diff --git a/src/libraries/help.library.ts b/src/libraries/help.library.ts index 87fee4ad..a3b5c340 100644 --- a/src/libraries/help.library.ts +++ b/src/libraries/help.library.ts @@ -1,43 +1,47 @@ -import { getVoiceConnection, joinVoiceChannel, VoiceConnection } from '@discordjs/voice'; -import dayjs from 'dayjs'; -import duration from 'dayjs/plugin/duration.js'; -import relativeTime from 'dayjs/plugin/relativeTime.js'; +import "@std/dotenv/load"; +import duration from "dayjs/plugin/duration.js"; +import relativeTime from "dayjs/plugin/relativeTime.js"; +import dayjs from "npm:dayjs"; import { ActionRowBuilder, ButtonBuilder, ButtonStyle, - ChatInputCommandInteraction, - Collection, - ColorResolvable, - EmbedAuthorOptions, + type ChatInputCommandInteraction, + type Collection, + type ColorResolvable, + type EmbedAuthorOptions, EmbedBuilder, - Guild, - GuildBasedChannel, - GuildMember, - Message, - MessageComponentInteraction, - PermissionResolvable, - TextBasedChannel, + type Guild, + type GuildBasedChannel, + type GuildMember, + type Message, + type MessageComponentInteraction, + type PermissionResolvable, + type TextBasedChannel, TextChannel, -} from 'discord.js'; -import { VideoSearchResult } from 'yt-search'; - -import { MusicData, PGuild } from '../types/classes/PGuild.class.js'; -import { Field, TimeElapsed } from '../types/classes/PTypes.interface.js'; -import { Locale } from '../types/enums/Locales.enum.js'; -import { OpapGameId } from '../types/enums/OpapGames.enum.js'; -import { ProfanityLevel } from '../types/enums/ProfanityLevel.enum.js'; -import { RankSpeed } from '../types/enums/RankSpeed.enum.js'; -import logger from '../utilities/log.utility.js'; -import { createDiscordJSAdapter } from './adapter.library.js'; -import { fetchGuild, fetchGuildList, setMusicData } from './mongo.library.js'; +} from "npm:discord.js"; +import type { VideoSearchResult } from "yt-search"; + +import { MusicData, type PGuild } from "../types/classes/PGuild.class.ts"; +import type { Field, TimeElapsed } from "../types/classes/PTypes.interface.ts"; +import { Locale } from "../types/enums/Locales.enum.ts"; +import { OpapGameId } from "../types/enums/OpapGames.enum.ts"; +import { ProfanityLevel } from "../types/enums/ProfanityLevel.enum.ts"; +import { RankSpeed } from "../types/enums/RankSpeed.enum.ts"; +import logger from "../utilities/log.utility.ts"; +import { fetchGuild, fetchGuildList, setMusicData } from "./mongo.library.ts"; dayjs.extend(duration); dayjs.extend(relativeTime); -type enumTypes = typeof OpapGameId | typeof RankSpeed | typeof ProfanityLevel | typeof Locale; +type enumTypes = + | typeof OpapGameId + | typeof RankSpeed + | typeof ProfanityLevel + | typeof Locale; -const idleThumbnail = 'https://raw.githubusercontent.com/keybraker/' + 'Portal/master/src/assets/img/emptyQueue.png'; +const idleThumbnail = + "https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/empty_queue.png"; const deletedMessages = new WeakSet(); const deletedChannel = new WeakSet(); @@ -51,7 +55,9 @@ export function markMessageAsDeleted(message: Message) { deletedMessages.add(message); } -export function isChannelDeleted(channel: GuildBasedChannel | TextBasedChannel) { +export function isChannelDeleted( + channel: GuildBasedChannel | TextBasedChannel, +) { return deletedChannel.has(channel); } @@ -67,16 +73,25 @@ export function markGuildAsDeleted(guild: Guild) { deletedGuild.add(guild); } -export async function askForApproval( +export async function askForApprovalByInteraction( interaction: ChatInputCommandInteraction, question: string, buttonStyle: ButtonStyle, ): Promise { - const confirm = new ButtonBuilder().setCustomId('confirm').setLabel('Confirm').setStyle(buttonStyle); - - const cancel = new ButtonBuilder().setCustomId('cancel').setLabel('Cancel').setStyle(ButtonStyle.Secondary); - - const row = new ActionRowBuilder().addComponents(cancel, confirm); + const confirm = new ButtonBuilder() + .setCustomId("confirm") + .setLabel("Confirm") + .setStyle(buttonStyle); + + const cancel = new ButtonBuilder() + .setCustomId("cancel") + .setLabel("Cancel") + .setStyle(ButtonStyle.Secondary); + + const row = new ActionRowBuilder().addComponents( + cancel, + confirm, + ); const reply = await interaction.reply({ fetchReply: true, @@ -84,16 +99,66 @@ export async function askForApproval( components: [row], }); - const filter = (i: MessageComponentInteraction) => i.customId === 'confirm' || i.customId === 'cancel'; + const filter = (i: MessageComponentInteraction) => + i.customId === "confirm" || i.customId === "cancel"; const collected = await reply.awaitMessageComponent({ filter, time: 10_000 }); - if (collected.customId === 'confirm') { + if (collected.customId === "confirm") { await collected.update({ content: `${question} **Confirmed**` }); } else { await collected.update({ content: `${question} **Cancelled**` }); } - return collected.customId === 'confirm'; + return collected.customId === "confirm"; +} + +export async function askForApprovalByMember( + member: GuildMember, + question: string, + buttonStyle: ButtonStyle, +): Promise { + const confirm = new ButtonBuilder() + .setCustomId("confirm") + .setLabel("Confirm") + .setStyle(buttonStyle); + + const cancel = new ButtonBuilder() + .setCustomId("cancel") + .setLabel("Cancel") + .setStyle(ButtonStyle.Secondary); + + const row = new ActionRowBuilder() + .addComponents(cancel, confirm); + + const dmChannel = await member.createDM(); + const message = await dmChannel.send({ + content: question, + components: [row], + }); + + try { + const filter = (i: MessageComponentInteraction) => + i.customId === "confirm" || i.customId === "cancel"; + const collected = await message.awaitMessageComponent({ + filter, + time: 10_000, + }); + + if (collected.customId === "confirm") { + await collected.update({ content: `${question} **Confirmed**` }); + return true; + } else { + await collected.update({ content: `${question} **Cancelled**` }); + return false; + } + } catch (error) { + logger.error(`failed to collect message: ${error}`); + await message.edit({ + content: `${question} **Timed out**`, + components: [], + }); + return false; + } } export function getJSONFromString(str: string) { @@ -102,6 +167,7 @@ export function getJSONFromString(str: string) { try { data = JSON.parse(str); } catch (error) { + logger.error(`failed to parse JSON: ${error}`); return null; } @@ -109,26 +175,31 @@ export function getJSONFromString(str: string) { } export function maxString(abstract: string, max: number): string { - return abstract.length < max ? abstract : abstract.substring(0, max - 3) + '...'; + return abstract.length < max + ? abstract + : abstract.substring(0, max - 3) + "..."; } -export function getKeyFromEnum(value: string, enumeration: enumTypes): string | number | undefined { +export function getKeyFromEnum( + value: string, + enumeration: enumTypes, +): string | number | undefined { let enumerationArray; switch (enumeration) { - case OpapGameId: - enumerationArray = Object.values(OpapGameId); - break; - case RankSpeed: - enumerationArray = Object.values(RankSpeed); - break; - case ProfanityLevel: - enumerationArray = Object.values(ProfanityLevel); - break; - case Locale: - enumerationArray = Object.values(Locale); - break; - default: - return undefined; + case OpapGameId: + enumerationArray = Object.values(OpapGameId); + break; + case RankSpeed: + enumerationArray = Object.values(RankSpeed); + break; + case ProfanityLevel: + enumerationArray = Object.values(ProfanityLevel); + break; + case Locale: + enumerationArray = Object.values(Locale); + break; + default: + return undefined; } for (const enumerationValue of enumerationArray) { @@ -140,42 +211,57 @@ export function getKeyFromEnum(value: string, enumeration: enumTypes): string | return undefined; } -export async function createMusicMessage(channel: TextChannel, pGuild: PGuild): Promise { +export async function createMusicMessage( + channel: TextChannel, + pGuild: PGuild, +): Promise { const musicMessageEmb = createEmbed( - 'Music Player', - 'Type and Portal will play it !', - '#e60026', + "Music Player", + "Type and Portal will play it !", + "#e60026", [ - { emote: 'Duration', role: '-', inline: true }, - { emote: 'Views', role: '-', inline: true }, - { emote: 'Pinned', role: pGuild.musicData.pinned ? 'yes' : 'no', inline: true }, - { emote: 'Queue', role: 'empty', inline: false }, - { emote: 'Latest Action', role: '```music message created```', inline: false }, + { emote: "Duration", role: "-", inline: true }, + { emote: "Views", role: "-", inline: true }, + { + emote: "Pinned", + role: pGuild.musicData.pinned ? "yes" : "no", + inline: true, + }, + { emote: "Queue", role: "empty", inline: false }, + { + emote: "Latest Action", + role: "```music message created```", + inline: false, + }, ], null, null, true, null, idleThumbnail, - 'https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/music.png', + "https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/music.png", ); const sentMessage = await channel.send({ embeds: [musicMessageEmb] }); if (!sentMessage) { - return 'failed to send message to channel'; + return "failed to send message to channel"; } - const emojis = ['▶️', '⏸', '⏭', '📌', '📄', '⬇️', '🧹', '🚪']; + const emojis = ["▶️", "⏸", "⏭", "📌", "📄", "⬇️", "🧹", "🚪"]; for (const emoji of emojis) { - sentMessage.react(emoji).catch((e) => logger.error(`failed to react to message: ${e}`)); + sentMessage.react(emoji).catch((e) => + logger.error(`failed to react to message: ${e}`) + ); } const musicData = new MusicData( channel.id, sentMessage.id, - pGuild.musicData.messageLyricsId ? pGuild.musicData.messageLyricsId : 'null', + pGuild.musicData.messageLyricsId + ? pGuild.musicData.messageLyricsId + : "null", [], false, ); @@ -190,15 +276,33 @@ export async function createMusicLyricsMessage( pGuild: PGuild, messageId: string, ): Promise { - const musicLyricsMessageEmb = createEmbed('Lyrics 📄', '', '#e60026', null, null, null, false, null, null); + const musicLyricsMessageEmb = createEmbed( + "Lyrics 📄", + "", + "#e60026", + null, + null, + null, + false, + null, + null, + ); - const sentMessageLyrics = await channel.send({ embeds: [musicLyricsMessageEmb] }); + const sentMessageLyrics = await channel.send({ + embeds: [musicLyricsMessageEmb], + }); if (!sentMessageLyrics) { return undefined; } - const musicData = new MusicData(channel.id, messageId, sentMessageLyrics.id, [], false); + const musicData = new MusicData( + channel.id, + messageId, + sentMessageLyrics.id, + [], + false, + ); await setMusicData(pGuild.id, musicData); return sentMessageLyrics.id; @@ -219,7 +323,7 @@ export async function updateMusicMessage( return false; } - const channel: TextChannel = guildChannel; + const channel: TextChannel = guildChannel; if (!channel || !pGuild.musicData.messageId) { return false; @@ -236,22 +340,30 @@ export async function updateMusicMessage( } }) .filter((v) => !!v) - .join('\n') - : 'empty' - : 'empty'; + .join("\n") + : "empty" + : "empty"; const musicMessageEmb = createEmbed( - yts ? yts.title : 'Music Player', - yts ? yts.url : 'Type and Portal will play it !', - '#e60026', + yts ? yts.title : "Music Player", + yts ? yts.url : "Type and Portal will play it !", + "#e60026", [ - { emote: 'Duration', role: yts ? yts.timestamp : '-', inline: true }, - { emote: 'Views', role: (yts ? yts.timestamp : 0) === 0 ? '-' : yts ? yts.views : '-', inline: true }, - { emote: 'Pinned', role: pGuild.musicData.pinned ? 'yes' : 'no', inline: true }, + { emote: "Duration", role: yts ? yts.timestamp : "-", inline: true }, + { + emote: "Views", + role: (yts ? yts.timestamp : 0) === 0 ? "-" : yts ? yts.views : "-", + inline: true, + }, + { + emote: "Pinned", + role: pGuild.musicData.pinned ? "yes" : "no", + inline: true, + }, // { emote: null, role: null, inline: true }, - { emote: 'Queue', role: musicQueue, inline: false }, + { emote: "Queue", role: musicQueue, inline: false }, // { emote: null, role: null, inline: true }, - { emote: 'Latest Action', role: '```' + status + '```', inline: false }, + { emote: "Latest Action", role: "```" + status + "```", inline: false }, ], null, null, @@ -259,8 +371,8 @@ export async function updateMusicMessage( null, yts ? yts.thumbnail : idleThumbnail, animated - ? 'https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/music.gif' - : 'https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/music.png', + ? "https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/music.gif" + : "https://raw.githubusercontent.com/keybraker/Portal/master/src/assets/img/music.png", ); if (!pGuild.musicData.messageId || !channel) { @@ -284,22 +396,24 @@ export async function updateMusicLyricsMessage( lyrics: string, url?: string, ): Promise { - const guildChannel = guild.channels.cache.find((c) => c.id === pGuild.musicData.channelId); + const guildChannel = guild.channels.cache.find((c) => + c.id === pGuild.musicData.channelId + ); if (!guildChannel) { return false; } - const channel: TextChannel = guildChannel; + const channel: TextChannel = guildChannel; if (!channel || !pGuild.musicData.messageId) { return false; } const musicMessageEmb = createEmbed( - `Lyrics 📄 ${url ? `at ${url}` : ''}`, + `Lyrics 📄 ${url ? `at ${url}` : ""}`, maxString(lyrics, 2000), - '#e60026', + "#e60026", null, null, null, @@ -312,77 +426,21 @@ export async function updateMusicLyricsMessage( return false; } - const fetchedMessage = await channel.messages.fetch(pGuild.musicData.messageLyricsId); + const fetchedMessage = await channel.messages.fetch( + pGuild.musicData.messageLyricsId, + ); if (!fetchedMessage) { return false; } - const editedMessage = await fetchedMessage.edit({ embeds: [musicMessageEmb] }); + const editedMessage = await fetchedMessage.edit({ + embeds: [musicMessageEmb], + }); return !!editedMessage; } -export async function joinUserVoiceChannelByInteraction( - interaction: ChatInputCommandInteraction, - pGuild: PGuild, -): Promise { - const member = interaction.member; - - if (!member) { - return undefined; // throw('user could not be fetched for message'); - } - - if (!(member instanceof GuildMember)) { - return undefined; // throw('member is not a guild member instance'); - } - - if (!member.voice) { - return undefined; // throw('voice could not be fetched for member'); - } - - const voiceChannel = member.voice.channel; - if (!voiceChannel) { - return undefined; // throw('you aren\'t in a voice channel'); - } - - const guild = interaction.guild; - if (!guild) { - return undefined; // throw('guild could not be fetched for message'); - } - - if (!guild.voiceAdapterCreator) { - return undefined; // throw('voiceAdapterCreator could not be fetched for guild'); - } - - if (!pGuild) { - return undefined; // throw('could not find guild of message'); - } - - let voiceConnection = getVoiceConnection(voiceChannel.id); - const clientVoiceState = guild.voiceStates.cache.get(guild.client.user.id); - - if (voiceConnection && clientVoiceState?.channelId === voiceChannel?.id) { - clientVoiceState.setDeaf(true); - } else { - voiceConnection = joinVoiceChannel({ - channelId: voiceChannel.id, - guildId: guild.id, - adapterCreator: createDiscordJSAdapter(voiceChannel), - }); - - if (!voiceConnection) { - return undefined; // throw('could not join voice channel'); - } - - if (clientVoiceState) { - clientVoiceState.setDeaf(true); - } - } - - return voiceConnection; -} - export function createEmbed( title: string | null | undefined, description: string | null | undefined, @@ -397,8 +455,8 @@ export function createEmbed( author?: { name: string; icon: string }, footer?: string, ): EmbedBuilder { - const portalIconUrl: string = - 'https://raw.githubusercontent.com/keybraker' + '/Portal/master/src/assets/img/portal_logo_spinr.gif'; + const portalIconUrl: string = "https://raw.githubusercontent.com/keybraker" + + "/Portal/master/src/assets/img/portal_logo_spinr.gif"; const richMessage = new EmbedBuilder(); @@ -407,26 +465,28 @@ export function createEmbed( if (colour) richMessage.setColor(colour); if (description) richMessage.setDescription(description); if (footer) richMessage.setFooter({ text: footer }); - if (fromBot) + if (fromBot) { richMessage .setFooter({ - text: footer ?? 'Portal', + text: footer ?? "Portal", iconURL: customGif ?? portalIconUrl, }) .setTimestamp(); + } if (thumbnail) richMessage.setThumbnail(thumbnail); if (image) richMessage.setImage(image); - if (author) + if (author) { richMessage.setAuthor({ name: author.name, iconURL: author.icon, // url: 'https://discord.js.org' }); + } if (fieldArray) { fieldArray.forEach((row) => { richMessage.addFields({ - name: row.emote === '' || !row.emote ? '\u200b' : `${row.emote}`, - value: row.role === '' || !row.role ? '\u200b' : `${row.role}`, + name: row.emote === "" || !row.emote ? "\u200b" : `${row.emote}`, + value: row.role === "" || !row.role ? "\u200b" : `${row.role}`, inline: row.inline, }); }); @@ -445,14 +505,14 @@ export function createEmbed( } export function isUserAuthorised(member: GuildMember): boolean { - const administrator: PermissionResolvable = 'Administrator'; + const administrator: PermissionResolvable = "Administrator"; if (member.permissions.has(administrator, true)) { return true; } if (member.roles.cache) { - return member.roles.cache.some((r) => r.name.toLowerCase() === 'p.admin'); + return member.roles.cache.some((r) => r.name.toLowerCase() === "p.admin"); } return false; @@ -460,14 +520,14 @@ export function isUserAuthorised(member: GuildMember): boolean { export function isUserDj(member: GuildMember): boolean { if (member.roles.cache) { - return member.roles.cache.some((r) => r.name.toLowerCase() === 'p.dj'); + return member.roles.cache.some((r) => r.name.toLowerCase() === "p.dj"); } return false; } export function isUserIgnored(member: GuildMember): boolean { - return member.roles.cache.some((r) => r.name.toLowerCase() === 'p.ignore'); + return member.roles.cache.some((r) => r.name.toLowerCase() === "p.ignore"); } export function isMod(member: GuildMember | null): boolean { @@ -475,27 +535,31 @@ export function isMod(member: GuildMember | null): boolean { return false; } - return member.guild.ownerId === member.id || member.roles.cache.some((r) => r.name.toLowerCase() === 'p.mod'); + return member.guild.ownerId === member.id || + member.roles.cache.some((r) => r.name.toLowerCase() === "p.mod"); } export function isWhitelist(member: GuildMember | null): boolean { if (member && member.roles.cache) { - return member.roles.cache.some((r) => r.name.toLowerCase() === 'p.whitelist'); + return member.roles.cache.some((r) => + r.name.toLowerCase() === "p.whitelist" + ); } return false; } -export function messageHelp(type: string, argument: string, info = ''): string { - let message = ''; +export function messageHelp(type: string, argument: string, info = ""): string { + let message = ""; if (info) { message += `**Info:** ${info}\n`; } - message += '**Help:** '; + message += "**Help:** "; message += `You can get detailed guidance by typing \`/help ${argument}\` `; - message += `or by visiting [our documentation]().`; + message += + `or by visiting [our documentation]().`; return message; } @@ -506,24 +570,27 @@ export async function messageReply( replyString: string, deleteSource = false, deleteReply = false, - emotePass = '✔️', - emoteFail = '❌', + emotePass = "✔️", + emoteFail = "❌", ): Promise { if (!message) { - return Promise.reject('failed to find message'); + return Promise.reject("failed to find message"); } - if (!isChannelDeleted(message.channel) && replyString !== null && replyString !== '') { + if ( + !isChannelDeleted(message.channel) && replyString !== null && + replyString !== "" + ) { const sentMessage = await message.reply(replyString).catch((e) => { return Promise.reject(`failed to send message: ${e}`); }); if (!sentMessage) { - return Promise.reject('failed to send message'); + return Promise.reject("failed to send message"); } if (deleteReply) { - const delay = (process.env.DELETE_DELAY as unknown as number) * 1000; + const delay = (Deno.env.get("DELETE_DELAY") as unknown as number) * 1000; setTimeout(async () => { if (isMessageDeleted(sentMessage)) { const deletedMessage = await sentMessage.delete().catch((e) => { @@ -539,15 +606,17 @@ export async function messageReply( } if (deleteSource) { - const reaction = await message.react(status ? emotePass : emoteFail).catch((e) => { - return Promise.reject(`failed to react to message: ${e}`); - }); + const reaction = await message.react(status ? emotePass : emoteFail).catch( + (e) => { + return Promise.reject(`failed to react to message: ${e}`); + }, + ); if (!reaction) { - return Promise.reject('failed to react to message'); + return Promise.reject("failed to react to message"); } - const delay = (process.env.DELETE_DELAY as unknown as number) * 1000; + const delay = (Deno.env.get("DELETE_DELAY") as unknown as number) * 1000; setTimeout(async () => { if (isMessageDeleted(message)) { const deletedMessage = await message.delete().catch((e) => { @@ -568,13 +637,13 @@ export async function messageReply( export function isUrl(potentialURL: string): boolean { const pattern = new RegExp( - '^(https?:\\/\\/)?' + // protocol - '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name - '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address - '(\\:\\d+)?(\\/[-a-z\\d%.~+]*)*' + // port and path - '(\\?[;&a-z\\d%.~+=-]*)?' + // query string - '(\\#[-a-z\\d]*)?$', - 'i', + "^(https?:\\/\\/)?" + // protocol + "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name + "((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address + "(\\:\\d+)?(\\/[-a-z\\d%.~+]*)*" + // port and path + "(\\?[;&a-z\\d%.~+=-]*)?" + // query string + "(\\#[-a-z\\d]*)?$", + "i", ); // fragment locator return pattern.test(potentialURL); @@ -584,9 +653,16 @@ export function pad(num: number): string { return num.toString().length >= 2 ? `${num}` : `0${num}`; } -export function getElapsedTime(timestamp: Date | number, timeout: number): TimeElapsed { +export function getElapsedTime( + timestamp: Date | number, + timeout: number, +): TimeElapsed { const timeoutTime = timeout * 60 * 1000; - const el = dayjs.duration(dayjs().diff(dayjs(typeof timestamp === 'number' ? timestamp : timestamp.getTime()))); + const el = dayjs.duration( + dayjs().diff( + dayjs(typeof timestamp === "number" ? timestamp : timestamp.getTime()), + ), + ); const timeoutMin = dayjs.duration(timeoutTime).minutes(); const timeoutSec = dayjs.duration(timeoutTime).seconds(); @@ -606,11 +682,15 @@ export async function removeDeletedChannels(guild: Guild): Promise { } pGuild.pChannels.forEach((portalChannel, indexP) => { - if (!guild.channels.cache.some((channel) => channel.id === portalChannel.id)) { + if ( + !guild.channels.cache.some((channel) => channel.id === portalChannel.id) + ) { pGuild.pChannels.splice(indexP, 1); } portalChannel.pVoiceChannels.forEach((portalVoice, indexV) => { - if (!guild.channels.cache.some((channel) => channel.id === portalVoice.id)) { + if ( + !guild.channels.cache.some((channel) => channel.id === portalVoice.id) + ) { portalChannel.pVoiceChannels.splice(indexV, 1); } }); @@ -652,13 +732,19 @@ export async function removeDeletedChannels(guild: Guild): Promise { } }); - if (!guild.channels.cache.some((channel) => channel.id === pGuild.musicData.channelId)) { + if ( + !guild.channels.cache.some((channel) => + channel.id === pGuild.musicData.channelId + ) + ) { pGuild.musicData.channelId = undefined; pGuild.musicData.messageId = undefined; pGuild.musicData.votes = undefined; } - if (!guild.channels.cache.some((channel) => channel.id === pGuild.announcement)) { + if ( + !guild.channels.cache.some((channel) => channel.id === pGuild.announcement) + ) { pGuild.announcement = null; } @@ -681,25 +767,33 @@ export async function removeEmptyVoiceChannels(guild: Guild): Promise { guildList.some((portalGuild) => portalGuild.pChannels.some((portalChannel) => portalChannel.pVoiceChannels.some((portalVoice, index) => { - if (portalVoice.id === channel.id && (>channel.members).size === 0) { + if ( + portalVoice.id === channel.id && + (> channel.members).size === 0 + ) { channel .delete() .then(() => { portalChannel.pVoiceChannels.splice(index, 1); logger.log({ - level: 'info', - type: 'none', - message: `deleted empty channel: ${channel.name} ` + `(${channel.id}) from ${channel.guild.name}`, + level: "info", + type: "none", + message: `deleted empty channel: ${channel.name} ` + + `(${channel.id}) from ${channel.guild.name}`, }); }) .catch((e) => { - logger.log({ level: 'error', type: 'none', message: `failed to send message: ${e}` }); + logger.log({ + level: "error", + type: "none", + message: `failed to send message: ${e}`, + }); }); return true; } return false; - }), - ), + }) + ) ); }); diff --git a/src/libraries/http.library.ts b/src/libraries/http.library.ts index a8f8ae1a..5f482fbe 100644 --- a/src/libraries/http.library.ts +++ b/src/libraries/http.library.ts @@ -1,45 +1,93 @@ -import * as cheerio from 'cheerio'; -import https, { RequestOptions } from 'https'; -import fetch from 'node-fetch'; -import { URL } from 'url'; - -export async function httpsFetch(options: string | RequestOptions | URL): Promise { - return new Promise((resolve, reject) => { - const req = https.request(options, function (res) { - const chunks: Uint8Array[] = []; - - res.on('data', function (chunk: Uint8Array) { - chunks.push(chunk); - }); +// http.library.ts +import * as cheerio from "npm:cheerio"; +import logger from "../utilities/log.utility.ts"; - res.on('end', function () { - // (chunk) { - return resolve(Buffer.concat(chunks)); - }); +interface RetryConfig { + maxRetries: number; + initialDelay: number; + maxDelay: number; + timeout: number; +} + +const defaultRetryConfig: RetryConfig = { + maxRetries: 3, + initialDelay: 1000, + maxDelay: 5000, + timeout: 5000, +}; + +function delay(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +export async function httpsFetch( + input: string | URL | Request, + init?: RequestInit, + retryConfig: RetryConfig = defaultRetryConfig, +): Promise { + let lastError: Error | undefined; - res.on('error', function () { - // (error) { - return reject(false); + for (let attempt = 0; attempt < retryConfig.maxRetries; attempt++) { + try { + const controller = new AbortController(); + const timeoutId = setTimeout( + () => controller.abort(), + retryConfig.timeout, + ); + + const response = await fetch(input, { + ...init, + signal: controller.signal, }); - }); - req.end(); - }); + clearTimeout(timeoutId); + + if (!response?.ok) { + throw new Error(`HTTP error! status: ${response?.status}`); + } + + if (!(response instanceof Response)) { + throw new Error("Invalid response type received"); + } + + logger.info(`Response received on attempt ${attempt + 1}`); + return response; + } catch (error) { + lastError = error as Error; + logger.error( + `Attempt ${attempt + 1} failed: ${ + error instanceof Error ? error.message : "Unknown error" + }`, + ); + + if (attempt < retryConfig.maxRetries - 1) { + const delayTime = Math.min( + retryConfig.initialDelay * Math.pow(2, attempt), + retryConfig.maxDelay, + ); + await delay(delayTime); + } + } + } + + throw new Error( + `Failed after ${retryConfig.maxRetries} attempts. Last error: ${lastError?.message}`, + ); } export async function scrapeLyrics(url: string): Promise { const response = await fetch(url); if (!response) { - return 'no lyrics found'; + return "no lyrics found"; } const text = await response.text(); if (!text) { - return 'text not found'; + return "text not found"; } const $ = cheerio.load(text); - return $('.lyrics').text().trim(); + return $(".lyrics").text().trim(); } diff --git a/src/libraries/localisation.library.ts b/src/libraries/localisation.library.ts index 15402594..c115ef3e 100644 --- a/src/libraries/localisation.library.ts +++ b/src/libraries/localisation.library.ts @@ -1,32 +1,40 @@ -import { createAudioPlayer, createAudioResource, getVoiceConnection } from '@discordjs/voice'; -import { ChatInputCommandInteraction, GuildMember, User } from 'discord.js'; -import { PGuild } from '../types/classes/PGuild.class.js'; +import { + createAudioPlayer, + createAudioResource, + getVoiceConnection, +} from "npm:@discordjs/voice"; +import type { + ChatInputCommandInteraction, + GuildMember, + User, +} from "npm:discord.js"; +import type { PGuild } from "../types/classes/PGuild.class.ts"; import { AnnouncementAction, - ClientArguments, - DataArguments, + type ClientArguments, + type DataArguments, EventAction, - LocalisationConsoleOption, - LocalisationPortalOption, + type LocalisationConsoleOption, + type LocalisationPortalOption, LogActions, - PresenceArguments, - StatusArguments, -} from '../types/classes/PTypes.interface.js'; -import { Locale } from '../types/enums/Locales.enum.js'; -import logger from '../utilities/log.utility.js'; + type PresenceArguments, + type StatusArguments, +} from "../types/classes/PTypes.interface.ts"; +import { Locale } from "../types/enums/Locales.enum.ts"; +import logger from "../utilities/log.utility.ts"; export const portal: LocalisationPortalOption[] = [ { name: AnnouncementAction.join, lang: { gr: () => { - return '> Γειά σας, το Πόρταλ είναι εδώ'; + return "> Γειά σας, το Πόρταλ είναι εδώ"; }, en: () => { - return '> Cheers love, Portal\'s here'; + return "> Cheers love, Portal's here"; }, de: () => { - return '> Hallo, Portal ist da'; + return "> Hallo, Portal ist da"; }, }, }, @@ -34,13 +42,13 @@ export const portal: LocalisationPortalOption[] = [ name: AnnouncementAction.leave, lang: { gr: () => { - return '> Αποχαιρετώ, καλή συνέχεια σε όλους'; + return "> Αποχαιρετώ, καλή συνέχεια σε όλους"; }, en: () => { - return '> Goodbye everyone'; + return "> Goodbye everyone"; }, de: () => { - return '> Auf Wiedersehen alle'; + return "> Auf Wiedersehen alle"; }, }, }, @@ -164,15 +172,15 @@ export const consoleText: LocalisationConsoleOption[] = [ lang: { gr: () => { // args: unknown - return '> Το αρχείο JSON των συντεχνιών ενημερώθηκε'; + return "> Το αρχείο JSON των συντεχνιών ενημερώθηκε"; }, en: () => { // args: unknown - return '> Guild JSON file has been updated'; + return "> Guild JSON file has been updated"; }, de: () => { // args: unknown - return '> Die JSON Datei der Gilde wurde aktualisiert'; + return "> Die JSON Datei der Gilde wurde aktualisiert"; }, }, }, @@ -182,7 +190,7 @@ export const consoleText: LocalisationConsoleOption[] = [ gr: (args: PresenceArguments) => { return ( `ο χρήστης ${args?.newPresence?.member?.displayName} είναι μέλος ` + - 'μια ελεγχόμενης συντεχνίας, έχει αλλάξει κατάσταση, αλλά βρίσκεται στη συντεχνία ' + + "μια ελεγχόμενης συντεχνίας, έχει αλλάξει κατάσταση, αλλά βρίσκεται στη συντεχνία " + `(${args?.newPresence?.guild?.name})` ); }, @@ -249,24 +257,24 @@ export function clientTalk( const player = createAudioPlayer(); const localeToString: Record = { - [Locale.gr]: 'gr', - [Locale.en]: 'en', - [Locale.de]: 'de', + [Locale.gr]: "gr", + [Locale.en]: "en", + [Locale.de]: "de", }; const AnnouncementActionToString: Record = { - [AnnouncementAction.fail]: 'fail', - [AnnouncementAction.announce]: 'announce', - [AnnouncementAction.spotify]: 'spotify', - [AnnouncementAction.url]: 'url', - [AnnouncementAction.readOnly]: 'readOnly', - [AnnouncementAction.join]: 'join', - [AnnouncementAction.leave]: 'leave', + [AnnouncementAction.fail]: "fail", + [AnnouncementAction.announce]: "announce", + [AnnouncementAction.spotify]: "spotify", + [AnnouncementAction.url]: "url", + [AnnouncementAction.readOnly]: "readOnly", + [AnnouncementAction.join]: "join", + [AnnouncementAction.leave]: "leave", }; const EventActionToString: Record = { - [EventAction.userConnected]: 'user_connected', - [EventAction.userDisconnected]: 'user_disconnected', + [EventAction.userConnected]: "user_connected", + [EventAction.userDisconnected]: "user_disconnected", }; for (let i = 0; i < pGuild.pChannels.length; i++) { @@ -281,7 +289,9 @@ export function clientTalk( const resource = createAudioResource( `src/assets/mp3s/${locale}/${contextAsAction}/${contextAsAction}_${random}.mp3`, ); - logger.info(`src/assets/mp3s/${locale}/${contextAsAction}/${contextAsAction}_${random}.mp3, ${!!resource}`); + logger.info( + `src/assets/mp3s/${locale}/${contextAsAction}/${contextAsAction}_${random}.mp3, ${!!resource}`, + ); player.play(resource); voiceConnection.subscribe(player); @@ -296,7 +306,9 @@ export function clientTalk( const resource = createAudioResource( `src/assets/mp3s/${locale}/${contextAsAction}/${contextAsAction}_${random}.mp3`, ); - logger.info(`src/assets/mp3s/${locale}/${contextAsAction}/${contextAsAction}_${random}.mp3, ${!!resource}`); + logger.info( + `src/assets/mp3s/${locale}/${contextAsAction}/${contextAsAction}_${random}.mp3, ${!!resource}`, + ); player.play(resource); voiceConnection.subscribe(player); @@ -309,13 +321,32 @@ export function clientTalk( return false; } -export function getFunction(output: string, locale: number, context: EventAction | AnnouncementAction | LogActions) { +export function getFunction( + output: string, + locale: number, + context: EventAction | AnnouncementAction | LogActions, +) { let func; - if (output === 'portal') { + if (output === "portal") { portal.some((ct) => { if (ct.name === context) { switch (locale) { + case Locale.gr: + func = ct.lang.gr; + return true; + case Locale.en: + func = ct.lang.en; + return true; + case Locale.de: + func = ct.lang.de; + return true; + } + } + }); + } else if (output === "console") { + consoleText.some((ct) => { + switch (locale) { case Locale.gr: func = ct.lang.gr; return true; @@ -325,21 +356,6 @@ export function getFunction(output: string, locale: number, context: EventAction case Locale.de: func = ct.lang.de; return true; - } - } - }); - } else if (output === 'console') { - consoleText.some((ct) => { - switch (locale) { - case Locale.gr: - func = ct.lang.gr; - return true; - case Locale.en: - func = ct.lang.en; - return true; - case Locale.de: - func = ct.lang.de; - return true; } }); } @@ -353,26 +369,32 @@ export function clientWrite( context: EventAction | AnnouncementAction | LogActions, ): string { const member = interaction.member as GuildMember; - if (!interaction) return 'could not fetch message'; - if (!member) return 'could not fetch member'; - if (!member.voice) return 'could not fetch voice'; + if (!interaction) return "could not fetch message"; + if (!member) return "could not fetch member"; + if (!member.voice) return "could not fetch voice"; - let returnValue = 'could not find data'; + let returnValue = "could not find data"; const found = pGuild.pChannels.some((p) => p.pVoiceChannels.some((v) => { if (member && member.voice.channel) { if (v.id === member.voice.channel.id) { switch (v.locale) { - case Locale.gr: - returnValue = portal.find((p) => p.name === context)?.lang.gr({} as User) as unknown as string; - break; - case Locale.en: - returnValue = portal.find((p) => p.name === context)?.lang.en({} as User) as unknown as string; - break; - case Locale.de: - returnValue = portal.find((p) => p.name === context)?.lang.de({} as User) as unknown as string; - break; + case Locale.gr: + returnValue = portal.find((p) => p.name === context)?.lang.gr( + {} as User, + ) as unknown as string; + break; + case Locale.en: + returnValue = portal.find((p) => p.name === context)?.lang.en( + {} as User, + ) as unknown as string; + break; + case Locale.de: + returnValue = portal.find((p) => p.name === context)?.lang.de( + {} as User, + ) as unknown as string; + break; } return true; @@ -380,13 +402,15 @@ export function clientWrite( } return false; - }), + }) ); if (found) { return returnValue; } else { - return portal.find((p) => p.name === context)?.lang.en({} as User) as unknown as string; + return portal.find((p) => p.name === context)?.lang.en( + {} as User, + ) as unknown as string; } } diff --git a/src/libraries/mod.library.ts b/src/libraries/mod.library.ts index 1cb33a21..1e9cfadb 100644 --- a/src/libraries/mod.library.ts +++ b/src/libraries/mod.library.ts @@ -1,16 +1,16 @@ -import dayjs from 'dayjs'; -import { BanOptions, Message, TextChannel } from 'discord.js'; - -import { ProfaneWords } from '../assets/lists/profaneWords.static.js'; -import configSpam from '../config.spam.json' assert { type: 'json' }; -import { PGuild } from '../types/classes/PGuild.class.js'; -import { SpamCache } from '../types/classes/PTypes.interface.js'; -import { ProfanityLevel } from '../types/enums/ProfanityLevel.enum.js'; -import logger from '../utilities/log.utility.js'; -import { deleteMessage, getRole } from './guild.library.js'; -import { isWhitelist, messageReply } from './help.library.js'; -import { updateMember } from './mongo.library.js'; -import { ban, kick } from './user.library.js'; +import dayjs from "npm:dayjs"; +import { type BanOptions, type Message, TextChannel } from "npm:discord.js"; + +import { ProfaneWords } from "../assets/lists/profaneWords.static.ts"; +import configSpam from "../config.spam.json" with { type: "json" }; +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import type { SpamCache } from "../types/classes/PTypes.interface.ts"; +import { ProfanityLevel } from "../types/enums/ProfanityLevel.enum.ts"; +import logger from "../utilities/log.utility.ts"; +import { deleteMessage, getRole } from "./guild.library.ts"; +import { isWhitelist, messageReply } from "./help.library.ts"; +import { updateMember } from "./mongo.library.ts"; +import { ban, kick } from "./user.library.ts"; const profaneWords = ProfaneWords as { gr: string[]; @@ -28,8 +28,10 @@ export function isProfane(candidate: string, profanityLevel: number): string[] { const en = profaneWords.en.filter((word: string) => { const wordExp = new RegExp( - ProfanityLevel.default === profanityLevel ? `\\b(${word})\\b` : `\\b(\\w*${word}\\w*)\\b`, - 'gi', + ProfanityLevel.default === profanityLevel + ? `\\b(${word})\\b` + : `\\b(\\w*${word}\\w*)\\b`, + "gi", ); return wordExp.test(candidate); @@ -37,25 +39,35 @@ export function isProfane(candidate: string, profanityLevel: number): string[] { const de = profaneWords.de.filter((word: string) => { const wordExp = new RegExp( - ProfanityLevel.default === profanityLevel ? `\\b(${word})\\b` : `\\b(\\w*${word}\\w*)\\b`, - 'gi', + ProfanityLevel.default === profanityLevel + ? `\\b(${word})\\b` + : `\\b(\\w*${word}\\w*)\\b`, + "gi", ); return wordExp.test(candidate); }); - return gr.length > 0 && en.length > 0 && de.length > 0 ? gr.concat(en).concat(de) : []; + return gr.length > 0 && en.length > 0 && de.length > 0 + ? gr.concat(en).concat(de) + : []; } /** * Determines if a user is spamming */ -export function messageSpamCheck(message: Message, pGuild: PGuild, spamCache: SpamCache[]): void { +export function messageSpamCheck( + message: Message, + pGuild: PGuild, + spamCache: SpamCache[], +): void { if (isWhitelist(message.member)) { return; } - const memberSpamCache = spamCache.find((c) => c.memberId === message.author.id); + const memberSpamCache = spamCache.find((c) => + c.memberId === message.author.id + ); if (!memberSpamCache) { spamCache.push({ @@ -79,7 +91,9 @@ export function messageSpamCheck(message: Message, pGuild: PGuild, spamCache: Sp return; } - const elapsedTime = dayjs.duration(dayjs().diff(dayjs(memberSpamCache.timestamp.getTime()))); + const elapsedTime = dayjs.duration( + dayjs().diff(dayjs(memberSpamCache.timestamp.getTime())), + ); if (elapsedTime.asSeconds() > configSpam.MESSAGE_INTERVAL / 1000) { memberSpamCache.timestamp = null; @@ -97,21 +111,42 @@ export function messageSpamCheck(message: Message, pGuild: PGuild, spamCache: Sp memberSpamCache.duplicateFouls = 0; } - if (configSpam.DUPLICATE_AFTER !== 0 && memberSpamCache.duplicateFouls === configSpam.DUPLICATE_AFTER) { - messageReply(false, message, 'warning: please stop spamming the same message', false, true).catch((e) => { + if ( + configSpam.DUPLICATE_AFTER !== 0 && + memberSpamCache.duplicateFouls === configSpam.DUPLICATE_AFTER + ) { + messageReply( + false, + message, + "warning: please stop spamming the same message", + false, + true, + ).catch((e) => { logger.error(`failed to reply to message: ${e}`); }); memberSpamCache.timestamp = new Date(); - } else if (configSpam.WARN_AFTER !== 0 && memberSpamCache.spamFouls === configSpam.WARN_AFTER) { - messageReply(false, message, 'warning: please stop spamming messages', false, true).catch((e) => { + } else if ( + configSpam.WARN_AFTER !== 0 && + memberSpamCache.spamFouls === configSpam.WARN_AFTER + ) { + messageReply( + false, + message, + "warning: please stop spamming messages", + false, + true, + ).catch((e) => { logger.error(`failed to reply to message: ${e}`); }); memberSpamCache.timestamp = new Date(); } - if (configSpam.MUTE_AFTER !== 0 && memberSpamCache.spamFouls === configSpam.MUTE_AFTER) { + if ( + configSpam.MUTE_AFTER !== 0 && + memberSpamCache.spamFouls === configSpam.MUTE_AFTER + ) { memberSpamCache.timestamp = null; memberSpamCache.spamFouls = 0; @@ -121,31 +156,45 @@ export function messageSpamCheck(message: Message, pGuild: PGuild, spamCache: Sp pGuild.pMembers[0].penalties = 1; } - if (pGuild.kickAfter && pGuild.kickAfter !== 0 && pGuild.pMembers[0].penalties === pGuild.kickAfter) { + if ( + pGuild.kickAfter && pGuild.kickAfter !== 0 && + pGuild.pMembers[0].penalties === pGuild.kickAfter + ) { if (message.member) { - kick(message.member, 'kicked due to spamming') + kick(message.member, "kicked due to spamming") .then((r) => { const replyMessage = r ? `kicked ${message.author} due to spamming` : `member ${message.author} cannot be kicked`; - messageReply(false, message, replyMessage, false, true).catch((e) => { - logger.error(`failed to reply to message: ${e}`); - }); + messageReply(false, message, replyMessage, false, true).catch( + (e) => { + logger.error(`failed to reply to message: ${e}`); + }, + ); }) .catch((e) => { logger.error(`failed to kick member: ${e}`); }); } else { - messageReply(false, message, `could not kick ${message.author}`, false, true).catch((e) => { + messageReply( + false, + message, + `could not kick ${message.author}`, + false, + true, + ).catch((e) => { logger.error(`failed to reply to message: ${e}`); }); } - } else if (pGuild.banAfter && pGuild.banAfter !== 0 && pGuild.pMembers[0].penalties === pGuild.banAfter) { + } else if ( + pGuild.banAfter && pGuild.banAfter !== 0 && + pGuild.pMembers[0].penalties === pGuild.banAfter + ) { if (message.member) { const banOptions: BanOptions = { deleteMessageDays: 0, - reason: 'banned due to spamming', + reason: "banned due to spamming", }; ban(message.member, banOptions) @@ -154,20 +203,33 @@ export function messageSpamCheck(message: Message, pGuild: PGuild, spamCache: Sp ? `banned ${message.author} due to spamming` : `member ${message.author} cannot be banned`; - messageReply(false, message, replyMessage, false, true).catch((e) => { - logger.error(`failed to reply to message: ${e}`); - }); + messageReply(false, message, replyMessage, false, true).catch( + (e) => { + logger.error(`failed to reply to message: ${e}`); + }, + ); }) .catch((e) => { logger.error(`failed to ban member: ${e}`); }); } else { - messageReply(false, message, `could not kick ${message.author}`, false, true).catch((e) => { + messageReply( + false, + message, + `could not kick ${message.author}`, + false, + true, + ).catch((e) => { logger.error(`failed to reply to message: ${e}`); }); } } else { - updateMember(pGuild.id, message.author.id, 'penalties', pGuild.pMembers[0].penalties).catch((e) => { + updateMember( + pGuild.id, + message.author.id, + "penalties", + pGuild.pMembers[0].penalties, + ).catch((e) => { logger.error(`failed to update member: ${e}`); }); @@ -195,7 +257,7 @@ async function muteUser(message: Message, muteRoleId: string): Promise { const addedRole = await message.member?.roles.add(muteRole); if (!addedRole) { - logger.error('failed to give role to member'); + logger.error("failed to give role to member"); return; } @@ -225,7 +287,7 @@ async function muteUser(message: Message, muteRoleId: string): Promise { }) .catch((e) => { logger.error(`failed to reply to message: ${e}`); - }), + }) ) .catch(logger.error); }, diff --git a/src/libraries/mongo.library.ts b/src/libraries/mongo.library.ts index bb9deb8b..cb9cd632 100644 --- a/src/libraries/mongo.library.ts +++ b/src/libraries/mongo.library.ts @@ -1,28 +1,44 @@ -import { ChannelType, Client, Guild, TextChannel, VoiceChannel } from 'discord.js'; -import { FilterQuery } from 'mongoose'; -import { VideoSearchResult } from 'yt-search'; - -import { PGiveRole } from '../types/classes/PGiveRole.class.js'; -import { MusicData, PGuild } from '../types/classes/PGuild.class.js'; -import { PMember } from '../types/classes/PMember.class.js'; -import { PPoll } from '../types/classes/PPoll.class.js'; -import { IPChannel, PChannel } from '../types/classes/PPortalChannel.class.js'; -import { Rank } from '../types/classes/PTypes.interface.js'; -import { PVoiceChannel } from '../types/classes/PVoiceChannel.class.js'; -import { PortalChannelType } from '../types/enums/PortalChannel.enum.js'; -import { ProfanityLevel } from '../types/enums/ProfanityLevel.enum.js'; -import { RankSpeed } from '../types/enums/RankSpeed.enum.js'; -import PGuildModel from '../types/models/PGuild.model.js'; - -export async function fetchGuildList(filter: FilterQuery): Promise { +import { + ChannelType, + type Client, + type Guild, + type TextChannel, + type VoiceChannel, +} from "npm:discord.js"; +import type { FilterQuery } from "npm:mongoose"; +import type { VideoSearchResult } from "yt-search"; + +import type { PGiveRole } from "../types/classes/PGiveRole.class.ts"; +import { MusicData, type PGuild } from "../types/classes/PGuild.class.ts"; +import { PMember } from "../types/classes/PMember.class.ts"; +import type { PPoll } from "../types/classes/PPoll.class.ts"; +import type { + IPChannel, + PChannel, +} from "../types/classes/PPortalChannel.class.ts"; +import type { Rank } from "../types/classes/PTypes.interface.ts"; +import type { PVoiceChannel } from "../types/classes/PVoiceChannel.class.ts"; +import { PortalChannelType } from "../types/enums/PortalChannel.enum.ts"; +import { ProfanityLevel } from "../types/enums/ProfanityLevel.enum.ts"; +import { RankSpeed } from "../types/enums/RankSpeed.enum.ts"; +import PGuildModel from "../types/models/PGuild.model.ts"; + +export async function fetchGuildList( + filter: FilterQuery, +): Promise { return (await PGuildModel.find(filter).exec()) as unknown as PGuild[]; } -export async function fetchGuild(guildId: PGuild['id']): Promise { - return (await PGuildModel.findOne({ id: guildId }).exec()) as unknown as PGuild; +export async function fetchGuild( + guildId: PGuild["id"], +): Promise { + return (await PGuildModel.findOne({ id: guildId }) + .exec()) as unknown as PGuild; } -export async function fetchGuildChannelDelete(guildId: PGuild['id']): Promise { +export async function fetchGuildChannelDelete( + guildId: PGuild["id"], +): Promise { return (await PGuildModel.findOne( { id: guildId, @@ -39,8 +55,8 @@ export async function fetchGuildChannelDelete(guildId: PGuild['id']): Promise | undefined> { + guildId: PGuild["id"], +): Promise | undefined> { const pGuild = (await PGuildModel.findOne( { id: guildId, @@ -57,7 +73,10 @@ export async function fetchAnnouncementChannelByGuildId( }; } -export async function fetchGuildReactionData(guildId: PGuild['id'], memberId: string): Promise { +export async function fetchGuildReactionData( + guildId: PGuild["id"], + memberId: string, +): Promise { return (await PGuildModel.findOne( { id: guildId, @@ -77,7 +96,9 @@ export async function fetchGuildReactionData(guildId: PGuild['id'], memberId: st ).exec()) as unknown as PGuild; } -export async function fetchGuildMembers(guildId: PGuild['id']): Promise { +export async function fetchGuildMembers( + guildId: PGuild["id"], +): Promise { const pGuild = (await PGuildModel.findOne( { id: guildId, @@ -91,7 +112,7 @@ export async function fetchGuildMembers(guildId: PGuild['id']): Promise { const pGuild = (await PGuildModel.findOne( { @@ -109,7 +130,10 @@ export async function fetchGuildMusicQueue( }; } -export async function fetchGuildPreData(guildId: PGuild['id'], memberId: string): Promise { +export async function fetchGuildPreData( + guildId: PGuild["id"], + memberId: string, +): Promise { return (await PGuildModel.findOne( { id: guildId, @@ -137,7 +161,9 @@ export async function fetchGuildPreData(guildId: PGuild['id'], memberId: string) ).exec()) as unknown as PGuild; } -export async function fetchGuildRest(guildId: PGuild['id']): Promise { +export async function fetchGuildRest( + guildId: PGuild["id"], +): Promise { return (await PGuildModel.findOne( { id: guildId, @@ -155,11 +181,14 @@ export async function fetchGuildRest(guildId: PGuild['id']): Promise { +export async function guildExists(guildId: PGuild["id"]): Promise { return (await PGuildModel.countDocuments({ id: guildId }).exec()) > 0; } -export async function memberExists(guildId: PGuild['id'], memberId: string): Promise { +export async function memberExists( + guildId: PGuild["id"], + memberId: string, +): Promise { return ( (await PGuildModel.countDocuments({ id: guildId, @@ -172,7 +201,11 @@ export async function memberExists(guildId: PGuild['id'], memberId: string): Pro ); } -export async function updateGuild(guildId: PGuild['id'], key: keyof PGuild, value: unknown): Promise { +export async function updateGuild( + guildId: PGuild["id"], + key: keyof PGuild, + value: unknown, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -191,8 +224,13 @@ export async function updateGuild(guildId: PGuild['id'], key: keyof PGuild, valu } // CRUD guilds -async function createMembers(guildId: PGuild['id'], client: Client): Promise { - const guild = client.guilds.cache.find((guild) => guild.id === guildId) as Guild; +async function createMembers( + guildId: PGuild["id"], + client: Client, +): Promise { + const guild = client.guilds.cache.find((guild) => + guild.id === guildId + ) as Guild; if (!guild) { return []; @@ -208,10 +246,24 @@ async function createMembers(guildId: PGuild['id'], client: Client): Promise member) .filter((member) => !member.user.bot) .filter((member) => member.id !== client?.user?.id) - .map((member) => new PMember(member.id, 1, 0, 1, 0, 0, new Date('1 January, 1970, 00:00:00 UTC'), 'null')); -} - -export async function insertGuild(guildId: PGuild['id'], client: Client): Promise { + .map((member) => + new PMember( + member.id, + 1, + 0, + 1, + 0, + 0, + new Date("1 January, 1970, 00:00:00 UTC"), + "null", + ) + ); +} + +export async function insertGuild( + guildId: PGuild["id"], + client: Client, +): Promise { const id: string = guildId; const pChannels: PChannel[] = []; const pMembers: PMember[] = await createMembers(guildId, client); @@ -219,17 +271,17 @@ export async function insertGuild(guildId: PGuild['id'], client: Client): Promis const pRoles: PGiveRole[] = []; const pPolls: string[] = []; const ranks: Rank[] = []; - const initialRole: string | null = 'null'; + const initialRole: string | null = "null"; const musicData: MusicData = { - channelId: 'null', - messageId: 'null', - messageLyricsId: 'null', + channelId: "null", + messageId: "null", + messageLyricsId: "null", votes: [], pinned: false, }; const musicQueue: VideoSearchResult[] = []; - const announcement: string | null = 'null'; - const muteRole: string | null = 'null'; + const announcement: string | null = "null"; + const muteRole: string | null = "null"; const locale = 1; const announce = true; const rankSpeed: number = RankSpeed.default; @@ -261,12 +313,12 @@ export async function insertGuild(guildId: PGuild['id'], client: Client): Promis })); } -export async function removeGuild(guildId: PGuild['id']): Promise { +export async function removeGuild(guildId: PGuild["id"]): Promise { return !!(await PGuildModel.deleteOne({ id: guildId })); } export async function updateMember( - guildId: PGuild['id'], + guildId: PGuild["id"], memberId: string, key: string, value: unknown, @@ -277,14 +329,14 @@ export async function updateMember( }, { $set: { - ['pMembers.$[m].' + key]: value, + ["pMembers.$[m]." + key]: value, }, }, { new: true, arrayFilters: [ { - 'm.id': memberId, + "m.id": memberId, }, ], }, @@ -293,21 +345,25 @@ export async function updateMember( return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function updateEntireMember(guildId: PGuild['id'], memberId: string, member: PMember): Promise { +export async function updateEntireMember( + guildId: PGuild["id"], + memberId: string, + member: PMember, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, }, { $set: { - ['pMembers.$[m]']: member, + ["pMembers.$[m]"]: member, }, }, { new: true, arrayFilters: [ { - 'm.id': memberId, + "m.id": memberId, }, ], }, @@ -316,8 +372,11 @@ export async function updateEntireMember(guildId: PGuild['id'], memberId: string return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function insertMember(guildId: PGuild['id'], memberId: string): Promise { - const newPMember = new PMember(memberId, 1, 0, 1, 0, 0, null, 'null'); +export async function insertMember( + guildId: PGuild["id"], + memberId: string, +): Promise { + const newPMember = new PMember(memberId, 1, 0, 1, 0, 0, null, "null"); const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId }, @@ -331,7 +390,10 @@ export async function insertMember(guildId: PGuild['id'], memberId: string): Pro return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function removeMember(memberId: string, guildId: PGuild['id']): Promise { +export async function removeMember( + memberId: string, + guildId: PGuild["id"], +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -349,7 +411,7 @@ export async function removeMember(memberId: string, guildId: PGuild['id']): Pro } export async function updatePortal( - guildId: PGuild['id'], + guildId: PGuild["id"], portalId: string, key: string, value: unknown, @@ -360,19 +422,22 @@ export async function updatePortal( }, { $set: { - ['pChannels.$[p].' + key]: value, + ["pChannels.$[p]." + key]: value, }, }, { new: true, - arrayFilters: [{ 'p.id': portalId }], + arrayFilters: [{ "p.id": portalId }], }, ); return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function insertPortal(guildId: PGuild['id'], newPortal: IPChannel): Promise { +export async function insertPortal( + guildId: PGuild["id"], + newPortal: IPChannel, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -387,7 +452,10 @@ export async function insertPortal(guildId: PGuild['id'], newPortal: IPChannel): return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function removePortal(guildId: PGuild['id'], portalId: string): Promise { +export async function removePortal( + guildId: PGuild["id"], + portalId: string, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -405,7 +473,7 @@ export async function removePortal(guildId: PGuild['id'], portalId: string): Pro } export async function updateVoice( - guildId: PGuild['id'], + guildId: PGuild["id"], portalId: string, voiceId: string, key: string, @@ -417,45 +485,53 @@ export async function updateVoice( }, { $set: { - ['pChannels.$[p].pVoiceChannels.$[v].' + key]: value, + ["pChannels.$[p].pVoiceChannels.$[v]." + key]: value, }, }, { new: true, - arrayFilters: [{ 'p.id': portalId }, { 'v.id': voiceId }], + arrayFilters: [{ "p.id": portalId }, { "v.id": voiceId }], }, ); return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function insertVoice(guildId: PGuild['id'], portalId: string, newVoice: PVoiceChannel): Promise { +export async function insertVoice( + guildId: PGuild["id"], + portalId: string, + newVoice: PVoiceChannel, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, }, { $push: { - 'pChannels.$[p].pVoiceChannels': newVoice, + "pChannels.$[p].pVoiceChannels": newVoice, }, }, { new: true, - arrayFilters: [{ 'p.id': portalId }], + arrayFilters: [{ "p.id": portalId }], }, ); return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function removeVoice(guildId: PGuild['id'], portalId: string, voiceId: string): Promise { +export async function removeVoice( + guildId: PGuild["id"], + portalId: string, + voiceId: string, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, }, { $pull: { - 'pChannels.$[p].pVoiceChannels': { + "pChannels.$[p].pVoiceChannels": { id: voiceId, }, }, @@ -464,7 +540,7 @@ export async function removeVoice(guildId: PGuild['id'], portalId: string, voice new: true, arrayFilters: [ { - 'p.id': portalId, + "p.id": portalId, }, ], }, @@ -473,7 +549,10 @@ export async function removeVoice(guildId: PGuild['id'], portalId: string, voice return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function insertURL(guildId: PGuild['id'], newUrl: string): Promise { +export async function insertURL( + guildId: PGuild["id"], + newUrl: string, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -488,7 +567,10 @@ export async function insertURL(guildId: PGuild['id'], newUrl: string): Promise< return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function removeURL(guildId: PGuild['id'], removeUrl: string): Promise { +export async function removeURL( + guildId: PGuild["id"], + removeUrl: string, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -503,7 +585,10 @@ export async function removeURL(guildId: PGuild['id'], removeUrl: string): Promi return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function insertIgnore(guildId: PGuild['id'], newIgnore: string): Promise { +export async function insertIgnore( + guildId: PGuild["id"], + newIgnore: string, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -518,7 +603,10 @@ export async function insertIgnore(guildId: PGuild['id'], newIgnore: string): Pr return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function removeIgnore(guildId: PGuild['id'], removeIgnore: string): Promise { +export async function removeIgnore( + guildId: PGuild["id"], + removeIgnore: string, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -533,7 +621,10 @@ export async function removeIgnore(guildId: PGuild['id'], removeIgnore: string): return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function setRanks(guildId: PGuild['id'], newRanks: Rank[]): Promise { +export async function setRanks( + guildId: PGuild["id"], + newRanks: Rank[], +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -546,7 +637,10 @@ export async function setRanks(guildId: PGuild['id'], newRanks: Rank[]): Promise return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function insertPoll(guildId: PGuild['id'], poll: PPoll): Promise { +export async function insertPoll( + guildId: PGuild["id"], + poll: PPoll, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -561,7 +655,10 @@ export async function insertPoll(guildId: PGuild['id'], poll: PPoll): Promise { +export async function removePoll( + guildId: PGuild["id"], + messageId: string, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -578,7 +675,10 @@ export async function removePoll(guildId: PGuild['id'], messageId: string): Prom return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function insertVendor(guildId: PGuild['id'], newVendor: PGiveRole): Promise { +export async function insertVendor( + guildId: PGuild["id"], + newVendor: PGiveRole, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -593,7 +693,10 @@ export async function insertVendor(guildId: PGuild['id'], newVendor: PGiveRole): return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function removeVendor(guildId: PGuild['id'], messageId: string): Promise { +export async function removeVendor( + guildId: PGuild["id"], + messageId: string, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -610,7 +713,10 @@ export async function removeVendor(guildId: PGuild['id'], messageId: string): Pr return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function insertMusicVideo(guildId: PGuild['id'], video: VideoSearchResult): Promise { +export async function insertMusicVideo( + guildId: PGuild["id"], + video: VideoSearchResult, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -625,35 +731,41 @@ export async function insertMusicVideo(guildId: PGuild['id'], video: VideoSearch return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function clearMusicVote(guildId: PGuild['id']): Promise { +export async function clearMusicVote(guildId: PGuild["id"]): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, }, { $set: { - 'musicData.votes': [], + "musicData.votes": [], }, }, ); return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function insertMusicVote(guildId: PGuild['id'], userId: string): Promise { +export async function insertMusicVote( + guildId: PGuild["id"], + userId: string, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, }, { $push: { - 'musicData.votes': userId, + "musicData.votes": userId, }, }, ); return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function setMusicData(guildId: PGuild['id'], newMusicData: MusicData): Promise { +export async function setMusicData( + guildId: PGuild["id"], + newMusicData: MusicData, +): Promise { const updateWriteOpResult = await PGuildModel.updateOne( { id: guildId, @@ -667,7 +779,9 @@ export async function setMusicData(guildId: PGuild['id'], newMusicData: MusicDat return updateWriteOpResult && updateWriteOpResult.modifiedCount === 1; } -export async function handleChannelDeletion(channelToRemove: VoiceChannel | TextChannel): Promise { +export async function handleChannelDeletion( + channelToRemove: VoiceChannel | TextChannel, +): Promise { const pGuild = await fetchGuildChannelDelete(channelToRemove.guild.id); if (!pGuild) { @@ -687,28 +801,45 @@ export async function handleChannelDeletion(channelToRemove: VoiceChannel | Text for (const pVoiceChannel of pChannel.pVoiceChannels) { if (pVoiceChannel.id === voiceChannelToRemove.id) { - return (await removeVoice(voiceChannelToRemove.guild.id, pChannel.id, pVoiceChannel.id)) + return (await removeVoice( + voiceChannelToRemove.guild.id, + pChannel.id, + pVoiceChannel.id, + )) ? PortalChannelType.voice : PortalChannelType.unknown; } } } } else if ( - [ChannelType.GuildText, ChannelType.GuildText, ChannelType.GuildAnnouncement].includes(channelToRemove.type) + [ + ChannelType.GuildText, + ChannelType.GuildText, + ChannelType.GuildAnnouncement, + ].includes(channelToRemove.type) ) { const textChannelToRemove = channelToRemove; if (pGuild.announcement === textChannelToRemove.id) { - return (await updateGuild(textChannelToRemove.guild.id, 'announcement', 'null')) + return (await updateGuild( + textChannelToRemove.guild.id, + "announcement", + "null", + )) ? PortalChannelType.announcement : PortalChannelType.unknown; } else if (pGuild.musicData.channelId === textChannelToRemove.id) { - const musicData = new MusicData('null', 'null', 'null', [], false); - return (await setMusicData(pGuild.id, musicData)) ? PortalChannelType.music : PortalChannelType.unknown; + const musicData = new MusicData("null", "null", "null", [], false); + return (await setMusicData(pGuild.id, musicData)) + ? PortalChannelType.music + : PortalChannelType.unknown; } else { for (let i = 0; i < pGuild.pURLs.length; i++) { if (pGuild.pURLs[i] === textChannelToRemove.id) { - return (await removeURL(textChannelToRemove.guild.id, textChannelToRemove.id)) + return (await removeURL( + textChannelToRemove.guild.id, + textChannelToRemove.id, + )) ? PortalChannelType.url : PortalChannelType.unknown; } @@ -716,7 +847,10 @@ export async function handleChannelDeletion(channelToRemove: VoiceChannel | Text for (let i = 0; i < pGuild.pIgnores.length; i++) { if (pGuild.pIgnores[i] === textChannelToRemove.id) { - return (await removeIgnore(textChannelToRemove.guild.id, textChannelToRemove.id)) + return (await removeIgnore( + textChannelToRemove.guild.id, + textChannelToRemove.id, + )) ? PortalChannelType.url : PortalChannelType.unknown; } diff --git a/src/libraries/music.library.ts b/src/libraries/music.library.ts index 62f8931a..38fcdbb6 100644 --- a/src/libraries/music.library.ts +++ b/src/libraries/music.library.ts @@ -1,13 +1,12 @@ -// // // const ytdl = require('ytdl-core'); // import ytdl from 'discord-ytdl-core'; -// import { Client, Guild, Message, MessageAttachment, User } from "discord.js"; -// import { RequestOptions } from 'https'; +// import { Client, Guild, Message, MessageAttachment, User } from "npm:discord.js"; +// import { RequestOptions } from 'node:https'; // import yts, { Duration, PlaylistMetadataResult, SearchResult, VideoMetadataResult, VideoSearchResult } from 'yt-search'; // import { GuildPrtl } from "../types/classes/GuildPrtl.class"; -// import { get_json, is_url, join_by_reaction, joinUserVoiceChannelByReaction, update_music_lyrics_message, update_music_message } from './help.library.js'; -// import { https_fetch, scrape_lyrics } from './http.library.js'; -// import { clear_music_vote, fetch_guild_music_queue, insert_music_video, update_guild } from './mongo.library.js'; +// import { get_json, is_url, join_by_reaction, joinUserVoiceChannelByReaction, update_music_lyrics_message, update_music_message } from './help.library.ts'; +// import { https_fetch, scrape_lyrics } from './http.library.ts'; +// import { clear_music_vote, fetch_guild_music_queue, insert_music_video, update_guild } from './mongo.library.ts'; // async function pop_music_queue( // pGuild: GuildPrtl @@ -766,7 +765,7 @@ // "path": `/search?q=${search_term}`, // 'headers': { // "x-rapidapi-host": "genius.p.rapidapi.com", -// 'x-rapidapi-key': process.env.LYRICS, +// 'x-rapidapi-key': Deno.env.get("LYRICS, // 'useQueryString': 1 // }, // } diff --git a/src/libraries/music.library2.ts b/src/libraries/music.library2.ts new file mode 100644 index 00000000..528e417c --- /dev/null +++ b/src/libraries/music.library2.ts @@ -0,0 +1,573 @@ +import { + type AudioPlayer, + createAudioPlayer, + createAudioResource, + StreamType, + type VoiceConnection, +} from "npm:@discordjs/voice"; +// import { Buffer } from "node:buffer"; +// import type { RequestOptions } from "node:https"; +import ytdl from "npm:@distube/ytdl-core@^4.15.1"; +import type { VideoSearchResult } from "npm:yt-search"; +import yts from "npm:yt-search"; +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import logger from "../utilities/log.utility.ts"; +import { insertMusicVideo } from "./mongo.library.ts"; +// import type { PGuild } from "../types/classes/PGuild.class.ts"; +// import { +// getJSONFromString, +// isUrl, +// joinUserVoiceChannelByReaction, +// updateMusicLyricsMessage, +// updateMusicMessage, +// } from "./help.library.ts"; +// import { httpsFetch, scrapeLyrics } from "./http.library.ts"; +// import { +// clearMusicVote, +// fetchGuildMusicQueue, +// insertMusicVideo, +// updateGuild, +// } from "./mongo.library.ts"; + +// export class MusicUtil { +// private readonly client: Client; +// private readonly guild: Guild; +// private readonly pGuild: PGuild; + +function createVideoSearchResult( + video: VideoSearchResult, + playlistId: string, + index: number, +): VideoSearchResult { + return { + type: "video", + videoId: video.videoId, + url: `https://www.youtube.com/watch?v=${video.videoId}${ + playlistId ? `&list=${playlistId}&index=${index + 1}` : "" + }`, + title: video.title, + description: video.description || "", + image: video.image || "", + thumbnail: video.thumbnail, + seconds: video.seconds || 0, + timestamp: video.timestamp || "", + duration: video.duration || { seconds: 0, timestamp: "-" }, + ago: video.ago || "", + views: video.views || 0, + author: video.author, + }; +} + +export async function searchYoutube( + searchTerm: string, +): Promise { + try { + const response: { videos: VideoSearchResult[] } = await yts(searchTerm); + + if (response.videos.length === 0) { + throw new Error( + `Could not find anything matching "${searchTerm}" on YouTube`, + ); + } + + return createVideoSearchResult(response.videos[0], "", 0); + } catch (error) { + logger.error(error); + return null; + } +} + +async function pushVideoToQueue( + video: VideoSearchResult, + pGuild: PGuild, +): Promise { + return false; + if (!pGuild.musicQueue) { + pGuild.musicQueue = []; + } + + pGuild.musicQueue.push(video); + + return await insertMusicVideo(pGuild.id, video); +} + +export async function startPlayback( + voiceConnection: VoiceConnection, + video: VideoSearchResult, + pGuild: PGuild, +): Promise { + try { + await pushVideoToQueue(video, pGuild); + + playStream( + pGuild.musicQueue.length > 0 ? pGuild.musicQueue[0].url : video.url, + voiceConnection, + ); + + return true; + } catch (error) { + logger.error(`Error starting playback: ${error}`); + return false; + } +} + +// constructor(client: Client, guild: Guild, pGuild: PGuild) { +// this.client = client; +// this.guild = guild; +// this.pGuild = pGuild; +// } + +// private async popMusicQueue(): Promise { +// try { +// const music = await fetchGuildMusicQueue(this.pGuild.id); +// if (!music) return undefined; + +// if (!music.data.pinned && music.queue.length > 0) { +// music.queue.shift(); +// await updateGuild(this.pGuild.id, "musicQueue", music.queue); +// } + +// this.pGuild.musicQueue = music.queue; +// this.pGuild.musicData = music.data; + +// return music.queue.length > 0 ? music.queue[0] : undefined; +// } catch (error) { +// throw new Error(`Could not fetch music queue: ${error}`); +// } +// } + +function playStream( + videoUrl: string, + voiceConnection: VoiceConnection, +): AudioPlayer | null { + try { + const stream = ytdl(videoUrl, { filter: "audioonly" }); + + const resource = createAudioResource(stream, { + inputType: StreamType.Opus, + }); + + const player: AudioPlayer = createAudioPlayer(); + + player.play(resource); + voiceConnection.subscribe(player); + + return player; + } catch (error) { + logger.error(`Error playing stream: ${error}`); + return null; + } +} + +// public async start( +// connection: VoiceConnection | undefined, +// user: User, +// message: Message, +// searchTerm: string, +// ): Promise { +// try { +// if (message.attachments.size > 0) { +// return await this.handleAttachment(message, connection, user); +// } + +// if (isUrl(searchTerm)) { +// return await this.handleUrl(searchTerm, connection, user, message); +// } + +// return await this.handleSearch(searchTerm, connection, user, message); +// } catch (error) { +// throw new Error(`Failed to start playback: ${error}`); +// } +// } + +// public async play( +// connection: VoiceConnection | undefined, +// user: User, +// ): Promise { +// if (connection?.dispatcher?.paused) { +// connection.dispatcher.resume(); +// return "Playback resumed"; +// } + +// try { +// return await this.startQueuedPlayback(connection, user); +// } catch (error) { +// throw new Error(`Failed to start playback: ${error}`); +// } +// } + +// public pause(connection: VoiceConnection | undefined): string { +// if (!connection) return "Portal is not connected"; +// if (!connection.dispatcher) return "Player is idle"; +// if (connection.dispatcher.paused) return "Already paused"; + +// connection.dispatcher.pause(); +// return "Playback paused"; +// } + +// public async skip( +// connection: VoiceConnection | undefined, +// user: User, +// ): Promise { +// if (connection?.dispatcher) { +// if (connection.dispatcher.paused) { +// setTimeout(() => { +// connection.dispatcher.resume(); +// setTimeout(() => connection.dispatcher.end(), 200); +// }, 200); +// } else { +// connection.dispatcher.end(); +// } +// return "Skipped to queued song"; +// } + +// return await this.startQueuedPlayback(connection, user); +// } + +// public async getLyrics(): Promise { +// if (this.pGuild.musicQueue.length === 0) { +// await updateMusicLyricsMessage(this.guild, this.pGuild, ""); +// return "No song in queue"; +// } + +// try { +// const searchTerm = this.formatLyricsSearchTerm(); +// const response = await this.fetchLyrics(searchTerm); +// return await this.handleLyricsResponse(response); +// } catch (error) { +// throw new Error(`Failed to get lyrics: ${error}`); +// } +// } + +// public exportQueue(): MessageAttachment | null { +// if (!this.pGuild.musicQueue?.length) { +// return null; +// } + +// const stringData = JSON.stringify(this.pGuild.musicQueue); +// const buffer = Buffer.from(stringData, "utf-8"); +// return new MessageAttachment(buffer, "portal_video_queue.json"); +// } + +// // Volume control methods +// public adjustVolume( +// connection: VoiceConnection | undefined, +// delta: number, +// ): string { +// if (!connection?.dispatcher) return "Player is idle"; + +// const newVolume = connection.dispatcher.volume + delta; +// if (newVolume < 0) return "Volume cannot be negative"; +// if (newVolume > 2) return "Volume cannot exceed 200%"; + +// connection.dispatcher.setVolume(newVolume); +// return `Volume ${delta > 0 ? "increased" : "decreased"} to ${ +// newVolume * 100 +// }%`; +// } + +// private async handleAttachment( +// message: Message, +// connection: VoiceConnection | undefined, +// user: User, +// ): Promise { +// const attachment = message.attachments.find((a) => !!a); +// if (!attachment) return "File is not a portal queue"; + +// const urlPath = attachment.url.substring(26); +// const options: RequestOptions = { +// method: "GET", +// hostname: "cdn.discordapp.com", +// port: null, +// path: urlPath, +// }; + +// try { +// const response = await httpsFetch(options); +// const json = getJSONFromString( +// response.toString(), +// ) as VideoSearchResult[]; + +// if (!json) return "Data from source was corrupted"; +// if (json.length === 0) return "Must give at least one"; + +// const result = await this.startPlayback( +// connection, +// user, +// message, +// json[0], +// ); + +// // Add remaining videos to queue +// for (let i = 1; i < json.length; i++) { +// await this.pushVideoToQueue(json[i]); +// } + +// return result; +// } catch (error) { +// throw new Error(`Could not process attachment: ${error}`); +// } +// } + +// private async handleUrl( +// url: string, +// connection: VoiceConnection | undefined, +// user: User, +// message: Message, +// ): Promise { +// const plistIndex = url.indexOf("list="); +// const pindxIndex = url.indexOf("index="); +// const videoIndex = url.indexOf("?v="); + +// if (plistIndex > 0) { +// return await this.handlePlaylist( +// url, +// plistIndex, +// pindxIndex, +// connection, +// user, +// message, +// ); +// } else if (videoIndex > 0) { +// return await this.handleSingleVideo( +// url, +// videoIndex, +// connection, +// user, +// message, +// ); +// } + +// return "The URL is not a valid YouTube video or playlist"; +// } + +// private async handlePlaylist( +// url: string, +// plistIndex: number, +// pindxIndex: number, +// connection: VoiceConnection | undefined, +// user: User, +// message: Message, +// ): Promise { +// const listId = url.substring(plistIndex + 5, 34); +// const indexStr = pindxIndex > 0 ? url.substring(pindxIndex + 6) : "0"; +// const index = isNaN(+indexStr) ? 0 : +indexStr; + +// try { +// const playlist = await yts({ listId }); +// if (playlist.videos.length <= 0) { +// return "Could not find the playlist on YouTube"; +// } + +// await updateMusicLyricsMessage(this.guild, this.pGuild, ""); + +// const initialVideo = this.createVideoSearchResult( +// playlist.videos[index], +// playlist.listId, +// index, +// ); +// const result = await this.startPlayback( +// connection, +// user, +// message, +// initialVideo, +// ); + +// // Queue remaining videos +// for (let i = index + 1; i < playlist.videos.length; i++) { +// const video = this.createVideoSearchResult( +// playlist.videos[i], +// playlist.listId, +// i, +// ); +// await this.pushVideoToQueue(video); +// } + +// return result; +// } catch (error) { +// throw new Error(`Error handling playlist: ${error}`); +// } +// } + +// private async handleSingleVideo( +// url: string, +// videoIndex: number, +// connection: VoiceConnection | undefined, +// user: User, +// message: Message, +// ): Promise { +// const videoId = url.substring(videoIndex + 3, videoIndex + 14); + +// try { +// const video = await yts({ videoId }); +// const searchResult = this.createVideoSearchResult(video, "", 0); +// return await this.startPlayback(connection, user, message, searchResult); +// } catch (error) { +// throw new Error(`Error handling video: ${error}`); +// } +// } + +// private async handleSearch( +// searchTerm: string, +// connection: VoiceConnection | undefined, +// user: User, +// message: Message, +// ): Promise { +// try { +// const searchResult = await yts(searchTerm); +// if (searchResult.videos.length <= 0) { +// return `Could not find anything matching "${searchTerm}" on YouTube`; +// } + +// return await this.startPlayback( +// connection, +// user, +// message, +// searchResult.videos[0], +// ); +// } catch (error) { +// throw new Error(`Error searching YouTube: ${error}`); +// } +// } + +// private async startPlayback( +// connection: VoiceConnection | undefined, +// user: User, +// message: Message, +// video: VideoSearchResult, +// ): Promise { +// try { +// await this.pushVideoToQueue(video); + +// if (connection) { +// if (!connection.dispatcher) { +// const dispatcher = this.spawnDispatcher( +// this.pGuild.musicQueue?.[0] || video, +// connection, +// ); +// this.setupDispatcherListeners(dispatcher, connection, user); +// return "Playback started"; +// } +// return "Already playing, song added to queue"; +// } + +// const newConnection = await joinUserVoiceChannelByReaction( +// this.client, +// message, +// this.pGuild, +// false, +// ); + +// if (!newConnection) { +// return "Could not join your voice channel"; +// } + +// const dispatcher = this.spawnDispatcher( +// this.pGuild.musicQueue?.[0] || video, +// newConnection, +// ); +// this.setupDispatcherListeners(dispatcher, newConnection, user); +// return "Playback started"; +// } catch (error) { +// throw new Error(`Error starting playback: ${error}`); +// } +// } + +function setupDispatcherListeners( + dispatcher: StreamDispatcher, + connection: VoiceConnection, + user: User, +): void { + dispatcher.once("finish", async () => { + await handlePlaybackFinish(dispatcher, connection, user); + }); +} + +async function handlePlaybackFinish( + dispatcher: StreamDispatcher, + connection: VoiceConnection, + user: User, +): Promise { + try { + if (!dispatcher.destroyed) { + dispatcher.destroy(); + } + + // Skip to next song + await this.skip(connection, user); + + // Clear vote state + await clear_music_vote(this.pGuild.id); + + // Determine animation state + const animate = connection?.dispatcher + ? !connection.dispatcher.paused + : false; + + // Update message display + await update_music_message( + this.guild, + this.pGuild, + this.pGuild.music_queue?.[0], + "Next song", + animate, + ); + } catch (error) { + throw new Error(`Failed to handle playback finish: ${error}`); + } +} + +// private formatLyricsSearchTerm(): string { +// const uselessWords = ["official", "music", "video", "ft."]; +// const expStr = uselessWords.join("|"); + +// return this.pGuild.musicQueue[0].title +// .replace(new RegExp("\\b(" + expStr + ")\\b", "gi"), " ") +// .replace(/\s{2,}/g, " ") +// .replace(/[&/\\#,+()$~%.'"-:*?<>{}]/g, "") +// .split(" ") +// .filter((s, i) => i < 6) +// .filter((s) => s) +// .join("%20"); +// } + +// private async fetchLyrics(searchTerm: string): Promise { +// const options: RequestOptions = { +// method: "GET", +// hostname: "genius.p.rapidapi.com", +// port: null, +// path: `/search?q=${searchTerm}`, +// headers: { +// "x-rapidapi-host": "genius.p.rapidapi.com", +// "x-rapidapi-key": Deno.env.get("LYRICS"), +// "useQueryString": 1, +// }, +// }; + +// return await httpsFetch(options); +// } + +// private async handleLyricsResponse(response: Buffer): Promise { +// const json = getJSONFromString( +// response.toString().substring(response.toString().indexOf("{")), +// ); + +// if (!json) throw new Error("Data from source was corrupted"); +// if (json.meta.status !== 200) return "Could not fetch lyrics"; +// if (!json.response.hits.length || json.response.hits[0].type !== "song") { +// return "Could not find song"; +// } + +// const path = json.response.hits[0].result.path; +// const lyrics = await scrapeLyrics(`https://genius.com${path}`); + +// await updateMusicLyricsMessage( +// this.guild, +// this.pGuild, +// lyrics, +// `https://genius.com${path}`, +// ); + +// return "Displayed lyrics"; +// } +// } diff --git a/src/libraries/preprocessor.library.ts b/src/libraries/preprocessor.library.ts index b19aa5e8..4e0cf219 100644 --- a/src/libraries/preprocessor.library.ts +++ b/src/libraries/preprocessor.library.ts @@ -1,28 +1,40 @@ -import { Message } from 'discord.js'; +import type { Message } from "npm:discord.js"; -import * as auth from '../commands/auth/index.js'; -import * as noAuth from '../commands/noAuth/index.js'; -import { MusicData, PGuild } from '../types/classes/PGuild.class.js'; -import { AuthCommands, CommandOptions, NoAuthCommands } from '../types/classes/PTypes.interface.js'; -import logger from '../utilities/log.utility.js'; -import { includedInPIgnores, isUrlOnlyChannel } from './guild.library.js'; -import { isMessageDeleted, isUserIgnored, markMessageAsDeleted, messageReply } from './help.library.js'; -import { removeIgnore, removeURL, setMusicData } from './mongo.library.js'; -import { addPointsMessage } from './user.library.js'; +import * as auth from "../commands/auth/index.ts"; +import * as noAuth from "../commands/noAuth/index.ts"; +import { MusicData, type PGuild } from "../types/classes/PGuild.class.ts"; +import type { + AuthCommands, + CommandOptions, + NoAuthCommands, +} from "../types/classes/PTypes.interface.ts"; +import logger from "../utilities/log.utility.ts"; +import { includedInPIgnores, isUrlOnlyChannel } from "./guild.library.ts"; +import { + isMessageDeleted, + isUserIgnored, + markMessageAsDeleted, + messageReply, +} from "./help.library.ts"; +import { removeIgnore, removeURL, setMusicData } from "./mongo.library.ts"; +import { addPointsMessage } from "./user.library.ts"; /* * Returns: true/false if processing must continue */ -export async function portalPreprocessor(message: Message, pGuild: PGuild): Promise { +export async function portalPreprocessor( + message: Message, + pGuild: PGuild, +): Promise { if (!message.member) { - logger.error('could not get member'); + logger.error("could not get member"); return true; } if (isUserIgnored(message.member)) { if (!handleUrlChannels(message, pGuild)) { if (pGuild.musicData.channelId === message.channel.id) { - message.member.send('you can\'t play music when ignored').catch((e) => { + message.member.send("you can't play music when ignored").catch((e) => { logger.error(`failed to send message: ${e}`); }); @@ -74,7 +86,7 @@ export async function portalPreprocessor(message: Message, pGuild: PGuild): Prom } } -export function commandDecipher(messageContent: Message['content']): { +export function commandDecipher(messageContent: Message["content"]): { commandName: AuthCommands | NoAuthCommands | undefined; args: string[]; } { @@ -96,7 +108,9 @@ export function commandDecipher(messageContent: Message['content']): { } export function commandFetcher(commandName: AuthCommands | NoAuthCommands) { - const authCommand = [...Object.values(auth)].find((command) => command.slashCommand.name === commandName); + const authCommand = [...Object.values(auth)].find((command) => + command.slashCommand.name === commandName + ); if (authCommand) { return { @@ -110,7 +124,9 @@ export function commandFetcher(commandName: AuthCommands | NoAuthCommands) { } as CommandOptions; } - const noAuthCommand = [...Object.values(noAuth)].find((command) => command.slashCommand.name === commandName); + const noAuthCommand = [...Object.values(noAuth)].find((command) => + command.slashCommand.name === commandName + ); if (noAuthCommand) { return { @@ -131,9 +147,11 @@ export function handleRankingSystem(message: Message, pGuild: PGuild): void { addPointsMessage(message, pGuild.pMembers[0], pGuild.rankSpeed) .then((level) => { if (level) { - messageReply(true, message, `you reached level ${level}!`).catch((e) => { - logger.error(`failed to send message: ${e}`); - }); + messageReply(true, message, `you reached level ${level}!`).catch( + (e) => { + logger.error(`failed to send message: ${e}`); + }, + ); } }) .catch((e) => { @@ -141,12 +159,19 @@ export function handleRankingSystem(message: Message, pGuild: PGuild): void { }); } -export async function handleUrlChannels(message: Message, pGuild: PGuild): Promise { +export async function handleUrlChannels( + message: Message, + pGuild: PGuild, +): Promise { if (isUrlOnlyChannel(message.channel.id, pGuild)) { - if (message.content === './url') { + if (message.content === "./url") { removeURL(pGuild.id, message.channel.id) .then((r) => { - messageReply(true, message, `removed url channel ${r ? 'successfully' : 'unsuccessfully'}`).catch((e) => { + messageReply( + true, + message, + `removed url channel ${r ? "successfully" : "unsuccessfully"}`, + ).catch((e) => { logger.error(`failed to send message: ${e}`); }); }) @@ -154,9 +179,11 @@ export async function handleUrlChannels(message: Message, pGuild: PGuild): Promi logger.error(`failed to remove url channel: ${e}`); }); } else { - message.author.send(`${message.channel} is a url-only channel`).catch((e) => { - logger.error(`failed to remove url channel: ${e}`); - }); + message.author.send(`${message.channel} is a url-only channel`).catch( + (e) => { + logger.error(`failed to remove url channel: ${e}`); + }, + ); if (isMessageDeleted(message)) { const deletedMessage = await message.delete().catch((e) => { @@ -175,12 +202,21 @@ export async function handleUrlChannels(message: Message, pGuild: PGuild): Promi return false; } -export function handleIgnoredChannels(message: Message, pGuild: PGuild): boolean { +export function handleIgnoredChannels( + message: Message, + pGuild: PGuild, +): boolean { if (includedInPIgnores(message.channel.id, pGuild)) { - if (message.content === './ignore') { + if (message.content === "./ignore") { removeIgnore(pGuild.id, message.channel.id) .then((r) => { - messageReply(true, message, `removed from ignored channels ${r ? 'successfully' : 'unsuccessfully'}`).catch( + messageReply( + true, + message, + `removed from ignored channels ${ + r ? "successfully" : "unsuccessfully" + }`, + ).catch( (e) => { logger.error(`failed to send message: ${e}`); }, @@ -199,16 +235,22 @@ export function handleIgnoredChannels(message: Message, pGuild: PGuild): boolean export function handleMusicChannels(message: Message, pGuild: PGuild): boolean { if (pGuild.musicData.channelId === message.channel.id) { - if (message.content === './music') { + if (message.content === "./music") { if (!message.guild) { - logger.error('failed to get guild from message'); + logger.error("failed to get guild from message"); return true; } - const musicData = new MusicData('null', 'null', 'null', [], false); + const musicData = new MusicData("null", "null", "null", [], false); setMusicData(pGuild.id, musicData) .then((r) => { - messageReply(true, message, `removed from ignored channels ${r ? 'successfully' : 'unsuccessfully'}`).catch( + messageReply( + true, + message, + `removed from ignored channels ${ + r ? "successfully" : "unsuccessfully" + }`, + ).catch( (e) => logger.error(`failed to send message: ${e}`), ); }) diff --git a/src/libraries/status.library.ts b/src/libraries/status.library.ts index 09b98dab..438f9fd3 100644 --- a/src/libraries/status.library.ts +++ b/src/libraries/status.library.ts @@ -1,9 +1,9 @@ -import { Activity, GuildMember, VoiceChannel } from 'discord.js'; +import type { Activity, GuildMember, VoiceChannel } from "npm:discord.js"; -import { GameNames } from '../assets/lists/gameNames.static.js'; -import { ProgramNames } from '../assets/lists/programNames.static.js'; -import { PVoiceChannel } from '../types/classes/PVoiceChannel.class.js'; -import { Locale } from '../types/enums/Locales.enum.js'; +import { GameNames } from "../assets/lists/gameNames.static.ts"; +import { ProgramNames } from "../assets/lists/programNames.static.ts"; +import type { PVoiceChannel } from "../types/classes/PVoiceChannel.class.ts"; +import { Locale } from "../types/enums/Locales.enum.ts"; function statusAliases(activities: Activity[], locale: number): string[] { const newStatus: string[] = []; @@ -11,7 +11,7 @@ function statusAliases(activities: Activity[], locale: number): string[] { activities.forEach((activity) => { let found = false; - if (activity.name.toLowerCase() === 'custom status') { + if (activity.name.toLowerCase() === "custom status") { found = true; } @@ -55,7 +55,10 @@ function statusAliases(activities: Activity[], locale: number): string[] { return newStatus; } -export function getStatusList(voiceChannel: VoiceChannel, pVoiceChannel: PVoiceChannel): string[] { +export function getStatusList( + voiceChannel: VoiceChannel, + pVoiceChannel: PVoiceChannel, +): string[] { const arrayOfStatuses: string[] = []; voiceChannel.members.forEach((member: GuildMember) => { @@ -63,11 +66,12 @@ export function getStatusList(voiceChannel: VoiceChannel, pVoiceChannel: PVoiceC if (!member.user.bot) { if (member.presence.activities !== undefined) { if (member.presence.activities.length > 0) { - statusAliases(member.presence.activities, pVoiceChannel.locale).forEach((stat) => { - if (!arrayOfStatuses.includes(stat)) { - arrayOfStatuses.push(stat); - } - }); + statusAliases(member.presence.activities, pVoiceChannel.locale) + .forEach((stat) => { + if (!arrayOfStatuses.includes(stat)) { + arrayOfStatuses.push(stat); + } + }); } } } @@ -76,11 +80,11 @@ export function getStatusList(voiceChannel: VoiceChannel, pVoiceChannel: PVoiceC if (arrayOfStatuses.length === 0) { if (pVoiceChannel.locale === Locale.gr) { - arrayOfStatuses.push('Άραγμα'); + arrayOfStatuses.push("Άραγμα"); } else if (pVoiceChannel.locale === Locale.de) { - arrayOfStatuses.push('Chillen'); + arrayOfStatuses.push("Chillen"); } else { - arrayOfStatuses.push('Chilling'); + arrayOfStatuses.push("Chilling"); } } diff --git a/src/libraries/user.library.ts b/src/libraries/user.library.ts index 3bee0197..5a3f96a3 100644 --- a/src/libraries/user.library.ts +++ b/src/libraries/user.library.ts @@ -1,14 +1,23 @@ -import { BanOptions, Guild, GuildMember, Message, VoiceState } from 'discord.js'; - -import { PGuild } from '../types/classes/PGuild.class.js'; -import { PMember } from '../types/classes/PMember.class.js'; -import { Rank } from '../types/classes/PTypes.interface.js'; -import { RankSpeed, RankSpeedValueList } from '../types/enums/RankSpeed.enum.js'; -import logger from '../utilities/log.utility.js'; -import { getElapsedTime } from './help.library.js'; -import { updateEntireMember, updateMember } from './mongo.library.js'; - -export async function calculateRank(member: PMember): Promise { +import type { + BanOptions, + Guild, + GuildMember, + Message, + VoiceState, +} from "npm:discord.js"; + +import type { PGuild } from "../types/classes/PGuild.class.ts"; +import type { PMember } from "../types/classes/PMember.class.ts"; +import type { Rank } from "../types/classes/PTypes.interface.ts"; +import { + RankSpeed, + RankSpeedValueList, +} from "../types/enums/RankSpeed.enum.ts"; +import logger from "../utilities/log.utility.ts"; +import { getElapsedTime } from "./help.library.ts"; +import { updateEntireMember, updateMember } from "./mongo.library.ts"; + +export function calculateRank(member: PMember): number { if (member.tier === 0) { member.tier = 1; // must be removed } @@ -25,28 +34,39 @@ export async function calculateRank(member: PMember): Promise { return member.level; } -export async function addPointsTime(pMember: PMember, rankSpeed: number): Promise { +export function addPointsTime(pMember: PMember, rankSpeed: number): number { if (!pMember.timestamp) { return pMember.points; } const voiceTime = getElapsedTime(pMember.timestamp, 0); - pMember.points += Math.round(voiceTime.remainingSec * RankSpeedValueList[rankSpeed] * 0.5); - pMember.points += Math.round(voiceTime.remainingMin * RankSpeedValueList[rankSpeed] * 30 * 1.15); - pMember.points += Math.round(voiceTime.remainingHrs * RankSpeedValueList[rankSpeed] * 30 * 30 * 1.25); + pMember.points += Math.round( + voiceTime.remainingSec * RankSpeedValueList[rankSpeed] * 0.5, + ); + pMember.points += Math.round( + voiceTime.remainingMin * RankSpeedValueList[rankSpeed] * 30 * 1.15, + ); + pMember.points += Math.round( + voiceTime.remainingHrs * RankSpeedValueList[rankSpeed] * 30 * 30 * 1.25, + ); pMember.timestamp = null; return pMember.points; } -export async function updateTimestamp(voiceState: VoiceState, pGuild: PGuild): Promise { +export async function updateTimestamp( + voiceState: VoiceState, + pGuild: PGuild, +): Promise { if (!voiceState.member || voiceState.member.user.bot) { return false; } - const pMember = pGuild.pMembers.find((m) => voiceState && voiceState.member && m.id === voiceState.member.id); + const pMember = pGuild.pMembers.find((m) => + voiceState && voiceState.member && m.id === voiceState.member.id + ); if (!pMember) { return false; @@ -64,20 +84,36 @@ export async function updateTimestamp(voiceState: VoiceState, pGuild: PGuild): P if (!pMember.timestamp) { pMember.timestamp = new Date(); - (await updateMember(voiceState.guild.id, member.id, 'timestamp', pMember.timestamp)) ? false : pMember.level; + (await updateMember( + voiceState.guild.id, + member.id, + "timestamp", + pMember.timestamp, + )) + ? false + : pMember.level; } pMember.points = await addPointsTime(pMember, speed); pMember.level = await calculateRank(pMember); pMember.timestamp = null; - const updatedEntireMember = await updateEntireMember(voiceState.guild.id, member.id, pMember); + const updatedEntireMember = await updateEntireMember( + voiceState.guild.id, + member.id, + pMember, + ); if (!updatedEntireMember) { return false; } - const roleRankUp = await giveRoleFromRankUp(pMember, member, ranks, voiceState.guild); + const roleRankUp = await giveRoleFromRankUp( + pMember, + member, + ranks, + voiceState.guild, + ); if (!roleRankUp) { return false; @@ -102,22 +138,27 @@ export async function addPointsMessage( const points = message.content.length * RankSpeedValueList[rankSpeed]; member.points += points > 5 ? 5 : points; - updateMember(message.guild.id, member.id, 'points', member.points).catch(() => { - return 'failed to update member'; - }); + updateMember(message.guild.id, member.id, "points", member.points).catch( + () => { + return "failed to update member"; + }, + ); const level = await calculateRank(member); if (level) { - updateMember(message.guild.id, member.id, 'level', level).catch(() => { - return 'failed to update member'; + updateMember(message.guild.id, member.id, "level", level).catch(() => { + return "failed to update member"; }); } return level ?? false; } -export async function kick(memberToKick: GuildMember, kickReason: string): Promise { +export async function kick( + memberToKick: GuildMember, + kickReason: string, +): Promise { if (!memberToKick.kickable) { return false; } @@ -125,7 +166,10 @@ export async function kick(memberToKick: GuildMember, kickReason: string): Promi return !!(await memberToKick.kick(kickReason)); } -export async function ban(memberToBan: GuildMember, banOptions: BanOptions): Promise { +export async function ban( + memberToBan: GuildMember, + banOptions: BanOptions, +): Promise { if (!memberToBan.bannable) { return false; } @@ -140,28 +184,31 @@ async function giveRoleFromRankUp( guild: Guild, ): Promise { if (!ranks) { - logger.error('At least one rank must be given'); + logger.error("At least one rank must be given"); return false; } const newRank = await ranks.find((rank) => rank.level === pMember.level); if (!newRank) { - logger.error('Could not find rank'); + logger.error("Could not find rank"); return false; } - const newRole = await guild.roles.cache.find((role) => role.id === newRank.role); + const newRole = await guild.roles.cache.find((role) => + role.id === newRank.role + ); if (!newRole) { - logger.error('Could not find role'); + logger.error("Could not find role"); return false; } try { await member.roles.add(newRole); } catch (e) { - throw new Error('failed to give role to member'); + logger.error(`Could not give role to member: ${e}`); + throw new Error("failed to give role to member"); } return true; diff --git a/src/libraries/voice.library.ts b/src/libraries/voice.library.ts new file mode 100644 index 00000000..79ced333 --- /dev/null +++ b/src/libraries/voice.library.ts @@ -0,0 +1,58 @@ +import { + getVoiceConnection, + joinVoiceChannel, + type VoiceConnection, +} from "npm:@discordjs/voice"; +import type { Guild, GuildMember, VoiceBasedChannel } from "npm:discord.js"; + +import { createDiscordJSAdapter } from "./adapter.library.ts"; +import logger from "../utilities/log.utility.ts"; + +export class VoiceLibrary { + static getVoiceConnectionByGuildId( + guildId: string, + ): VoiceConnection | null { + return getVoiceConnection(guildId) ?? null; + } + + static getVoiceChannelByMember( + member: GuildMember, + ): VoiceBasedChannel | null { + return member.voice.channel; + } + + static getVoiceStateByGuildId( + member: GuildMember, + ): VoiceBasedChannel | null { + return member.voice.channel; + } + + static joinUserVoiceChannelById( + channelId: string, + guild: Guild, + ): VoiceConnection | null { + const clientVoiceState = guild.voiceStates.cache.get(guild.client.user.id); + + if (clientVoiceState && clientVoiceState.channelId === channelId) { + logger.info("already in the same channel"); + clientVoiceState.setDeaf(true); + return this.getVoiceConnectionByGuildId(guild.id); + } else if (clientVoiceState) { + logger.info("moving to the same channel"); + clientVoiceState.setDeaf(true); + return null; + } + + const voiceBasedChannel = guild.channels.cache.get(channelId); + if (!voiceBasedChannel || !voiceBasedChannel.isVoiceBased()) { + return null; + } + + logger.info("joining voice channel"); + return joinVoiceChannel({ + channelId: voiceBasedChannel.id, + guildId: guild.id, + adapterCreator: createDiscordJSAdapter(voiceBasedChannel), + }); + } +} diff --git a/src/types/Command.ts b/src/types/Command.ts index 14b59df8..aa9b713f 100644 --- a/src/types/Command.ts +++ b/src/types/Command.ts @@ -1,6 +1,9 @@ -import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js'; -import { PGuild } from './classes/PGuild.class.js'; -import { ReturnPromise, ScopeLimit } from './classes/PTypes.interface.js'; +import type { + ChatInputCommandInteraction, + SlashCommandBuilder, +} from "npm:discord.js"; +import type { PGuild } from "./classes/PGuild.class.ts"; +import type { ReturnPromise, ScopeLimit } from "./classes/PTypes.interface.ts"; export type Command = { time: number; @@ -9,5 +12,8 @@ export type Command = { auth: boolean; scopeLimit: ScopeLimit; slashCommand: SlashCommandBuilder; - execute: (interaction: ChatInputCommandInteraction, pGuild?: PGuild) => Promise; + execute: ( + interaction: ChatInputCommandInteraction, + pGuild?: PGuild, + ) => Promise; }; diff --git a/src/types/classes/PGiveRole.class.ts b/src/types/classes/PGiveRole.class.ts index 6966ca37..0f838b47 100644 --- a/src/types/classes/PGiveRole.class.ts +++ b/src/types/classes/PGiveRole.class.ts @@ -1,4 +1,4 @@ -import { Document } from 'mongoose'; +import type { Document } from "npm:mongoose"; export class GiveRole { public emote: string; diff --git a/src/types/classes/PGuild.class.ts b/src/types/classes/PGuild.class.ts index 1d81f388..79d4170b 100644 --- a/src/types/classes/PGuild.class.ts +++ b/src/types/classes/PGuild.class.ts @@ -1,10 +1,11 @@ -import { Document } from 'mongoose'; -import { VideoSearchResult } from 'yt-search'; -import { PGiveRole } from './PGiveRole.class.js'; -import { PMember } from './PMember.class.js'; -import { PPoll } from './PPoll.class.js'; -import { IPChannel, PChannel } from './PPortalChannel.class.js'; -import { Rank } from './PTypes.interface'; +import type { Document } from "mongoose"; +import type { VideoSearchResult } from "npm:yt-search"; + +import type { PGiveRole } from "./PGiveRole.class.ts"; +import type { PMember } from "./PMember.class.ts"; +import type { PPoll } from "./PPoll.class.ts"; +import type { IPChannel, PChannel } from "./PPortalChannel.class.ts"; +import type { Rank } from "./PTypes.interface.ts"; export class MusicData { public channelId: string | undefined; @@ -13,7 +14,13 @@ export class MusicData { public votes: string[] | undefined; public pinned: boolean; - constructor(channelId: string, messageId: string, messageLyricsId: string, votes: string[], pinned: boolean) { + constructor( + channelId: string, + messageId: string, + messageLyricsId: string, + votes: string[], + pinned: boolean, + ) { this.channelId = channelId; this.messageId = messageId; this.messageLyricsId = messageLyricsId; diff --git a/src/types/classes/PMember.class.ts b/src/types/classes/PMember.class.ts index 8809063e..5cb9d987 100644 --- a/src/types/classes/PMember.class.ts +++ b/src/types/classes/PMember.class.ts @@ -1,4 +1,4 @@ -import { Document } from 'mongoose'; +import type { Document } from "npm:mongoose"; export class PMember { public id: string; @@ -18,7 +18,7 @@ export class PMember { points: number, penalties: number, timestamp: Date | null, - regex: string | null + regex: string | null, ) { this.id = id; this.level = level; diff --git a/src/types/classes/PPoll.class.ts b/src/types/classes/PPoll.class.ts index 9cd3f81c..93a89160 100644 --- a/src/types/classes/PPoll.class.ts +++ b/src/types/classes/PPoll.class.ts @@ -1,4 +1,4 @@ -import { Document } from 'mongoose'; +import type { Document } from "npm:mongoose"; export class PPoll { public messageId: string; diff --git a/src/types/classes/PPortalChannel.class.ts b/src/types/classes/PPortalChannel.class.ts index 80b4d37a..a90da7ce 100644 --- a/src/types/classes/PPortalChannel.class.ts +++ b/src/types/classes/PPortalChannel.class.ts @@ -1,5 +1,5 @@ -import { Document } from 'mongoose'; -import { PVoiceChannel } from './PVoiceChannel.class.js'; +import type { Document } from "npm:mongoose"; +import type { PVoiceChannel } from "./PVoiceChannel.class.ts"; export class PChannel { public id: string; diff --git a/src/types/classes/PTypes.interface.ts b/src/types/classes/PTypes.interface.ts index ed028856..c0d25b33 100644 --- a/src/types/classes/PTypes.interface.ts +++ b/src/types/classes/PTypes.interface.ts @@ -1,51 +1,59 @@ -import { ChatInputCommandInteraction, EmbedBuilder, Guild, Presence, Role, User, VoiceChannel } from 'discord.js'; +import type { + ChatInputCommandInteraction, + EmbedBuilder, + Guild, + Presence, + Role, + User, + VoiceChannel, +} from "npm:discord.js"; -import { PGuild } from './PGuild.class.js'; -import { PMember } from './PMember.class.js'; -import { PChannel } from './PPortalChannel.class.js'; -import { PVoiceChannel } from './PVoiceChannel.class.js'; +import type { PGuild } from "./PGuild.class.ts"; +import type { PMember } from "./PMember.class.ts"; +import type { PChannel } from "./PPortalChannel.class.ts"; +import type { PVoiceChannel } from "./PVoiceChannel.class.ts"; export type NoAuthCommands = - | 'about' - | 'announce' - | 'bet' - | 'corona' - | 'crypto' - | 'focus' - | 'help' - | 'join' - | 'leaderboard' - | 'leave' - | 'level' - | 'ping' - | 'poll' - | 'ranks' - | 'roll' - | 'run' - | 'state' - | 'spam_rules' - | 'weather' - | 'whoami'; + | "about" + | "announce" + | "bet" + | "corona" + | "crypto" + | "focus" + | "help" + | "join" + | "leaderboard" + | "leave" + | "level" + | "ping" + | "poll" + | "ranks" + | "roll" + | "run" + | "state" + | "spam_rules" + | "weather" + | "whoami"; export type AuthCommands = - | 'announcement' - | 'ban' - | 'delete_messages' - | 'force' - | 'ignore' - | 'invite' - | 'kick' - | 'music' - | 'portal' - | 'vendor' - | 'set_ranks' - | 'set' - | 'url'; + | "announcement" + | "ban" + | "delete_messages" + | "force" + | "ignore" + | "invite" + | "kick" + | "music" + | "portal" + | "vendor" + | "set_ranks" + | "set" + | "url"; export enum ScopeLimit { - NONE = 'none', - MEMBER = 'member', - GUILD = 'guild', + NONE = "none", + MEMBER = "member", + GUILD = "guild", } export enum AnnouncementAction { @@ -131,7 +139,11 @@ export type PresenceArguments = { newPresence: Presence; }; -export type LanguageConsoleArguments = ClientArguments & StatusArguments & DataArguments & PresenceArguments; +export type LanguageConsoleArguments = + & ClientArguments + & StatusArguments + & DataArguments + & PresenceArguments; export type LanguageConsole = { gr: (args: LanguageConsoleArguments) => string; @@ -232,7 +244,13 @@ export type Blueprint = { interaction?: ChatInputCommandInteraction; }, value: string | Role, - ) => Promise | boolean | string | string[] | number | undefined; + ) => + | Promise + | boolean + | string + | string[] + | number + | undefined; }; export interface HelpDocumentation { diff --git a/src/types/classes/PVoiceChannel.class.ts b/src/types/classes/PVoiceChannel.class.ts index 065bc9de..cd72a058 100644 --- a/src/types/classes/PVoiceChannel.class.ts +++ b/src/types/classes/PVoiceChannel.class.ts @@ -1,5 +1,5 @@ -import { Document } from 'mongoose'; -import { Locale } from '../enums/Locales.enum.js'; +import type { Document } from "npm:mongoose"; +import type { Locale } from "../enums/Locales.enum.ts"; export class PVoiceChannel { public id: string; diff --git a/src/types/enums/Admin.enum.ts b/src/types/enums/Admin.enum.ts index a80c3a9f..890f8954 100644 --- a/src/types/enums/Admin.enum.ts +++ b/src/types/enums/Admin.enum.ts @@ -1,8 +1,8 @@ export enum AuthType { - none, - portal, - voice, - admin, + NONE, + PORTAL, + VOICE, + ADMIN, } -export const AuthTypeList = ['none', 'portal', 'voice', 'admin']; +export const AuthTypeList = ["none", "portal", "voice", "admin"]; diff --git a/src/types/enums/Locales.enum.ts b/src/types/enums/Locales.enum.ts index 2375ce86..789a9369 100644 --- a/src/types/enums/Locales.enum.ts +++ b/src/types/enums/Locales.enum.ts @@ -4,4 +4,4 @@ export enum Locale { de, } -export const LocaleList = ['gr', 'en', 'de']; +export const LocaleList = ["gr", "en", "de"]; diff --git a/src/types/enums/OpapGames.enum.ts b/src/types/enums/OpapGames.enum.ts index 898fbe3d..a05b756a 100644 --- a/src/types/enums/OpapGames.enum.ts +++ b/src/types/enums/OpapGames.enum.ts @@ -8,4 +8,12 @@ export enum OpapGameId { extra5 = 5106, } -export const OpapGameIdList = ['kino', 'powerspin', 'super3', 'proto', 'lotto', 'tzoker', 'extra5']; +export const OpapGameIdList = [ + "kino", + "powerspin", + "super3", + "proto", + "lotto", + "tzoker", + "extra5", +]; diff --git a/src/types/enums/Prefix.enum.ts b/src/types/enums/Prefix.enum.ts index 409f181f..b17e47ce 100644 --- a/src/types/enums/Prefix.enum.ts +++ b/src/types/enums/Prefix.enum.ts @@ -1,6 +1,6 @@ export enum Prefix { - ATTRIBUTE = '&', - PIPE = '|', - STRUCTURE = '{{', - VARIABLE = '$', + ATTRIBUTE = "&", + PIPE = "|", + STRUCTURE = "{{", + VARIABLE = "$", } diff --git a/src/types/enums/ProfanityLevel.enum.ts b/src/types/enums/ProfanityLevel.enum.ts index cf1f4bb2..65b777fa 100644 --- a/src/types/enums/ProfanityLevel.enum.ts +++ b/src/types/enums/ProfanityLevel.enum.ts @@ -4,4 +4,4 @@ export enum ProfanityLevel { strict, } -export const ProfanityLevelList = ['none', 'default', 'strict']; +export const ProfanityLevelList = ["none", "default", "strict"]; diff --git a/src/types/enums/RankSpeed.enum.ts b/src/types/enums/RankSpeed.enum.ts index eeedcb37..bf56bbe0 100644 --- a/src/types/enums/RankSpeed.enum.ts +++ b/src/types/enums/RankSpeed.enum.ts @@ -5,6 +5,6 @@ export enum RankSpeed { fast, } -export const RankSpeedList = ['none', 'slow', 'default', 'fast']; +export const RankSpeedList = ["none", "slow", "default", "fast"]; export const RankSpeedValueList = [0.0, 0.05, 0.1, 0.15]; diff --git a/src/types/enums/TextChannelType.enum.ts b/src/types/enums/TextChannelType.enum.ts new file mode 100644 index 00000000..bf4de7c7 --- /dev/null +++ b/src/types/enums/TextChannelType.enum.ts @@ -0,0 +1,8 @@ +export enum TextChannelType { + NONE, + URL, + ANNOUNCEMENT, + MUSIC, +} + +export const TextChannelTypeList = ["none", "url", "announcement", "music"]; diff --git a/src/types/models/PGuild.model.ts b/src/types/models/PGuild.model.ts index f64c94d2..dd4c65f2 100644 --- a/src/types/models/PGuild.model.ts +++ b/src/types/models/PGuild.model.ts @@ -1,10 +1,10 @@ -import { model, Schema } from 'mongoose'; +import { model, Schema } from "npm:mongoose"; -import { IPGuild } from '../classes/PGuild.class.js'; -import PGiveRoleSchema from './schemas/PGiveRole.schema.js'; -import PMemberSchema from './schemas/PMember.schema.js'; -import PPollSchema from './schemas/PPoll.schema.js'; -import PPortalChannelSchema from './schemas/PPortalChannel.schema.js'; +import type { IPGuild } from "../classes/PGuild.class.ts"; +import PGiveRoleSchema from "./schemas/PGiveRole.schema.ts"; +import PMemberSchema from "./schemas/PMember.schema.ts"; +import PPollSchema from "./schemas/PPoll.schema.ts"; +import PPortalChannelSchema from "./schemas/PPortalChannel.schema.ts"; const VideoSearchResult = new Schema( { @@ -37,7 +37,7 @@ const VideoSearchResult = new Schema( role: { type: String, required: true }, }, { - collection: 'guild_list', + collection: "guild_list", }, ); @@ -47,7 +47,7 @@ const Rank = new Schema( role: { type: String, required: true }, }, { - collection: 'guild_list', + collection: "guild_list", }, ); @@ -60,7 +60,7 @@ const MusicData = new Schema( pinned: { type: Boolean, required: true }, }, { - collection: 'guild_list', + collection: "guild_list", }, ); @@ -88,8 +88,8 @@ const PGuildSchema = new Schema( premium: { type: Boolean, required: true }, }, { - collection: 'guild_list', + collection: "guild_list", }, ); -export default model('PGuildSchema', PGuildSchema); +export default model("PGuildSchema", PGuildSchema); diff --git a/src/types/models/schemas/PGiveRole.schema.ts b/src/types/models/schemas/PGiveRole.schema.ts index a729aa2c..60c91156 100644 --- a/src/types/models/schemas/PGiveRole.schema.ts +++ b/src/types/models/schemas/PGiveRole.schema.ts @@ -1,4 +1,4 @@ -import { Schema } from 'mongoose'; +import { Schema } from "npm:mongoose"; const GiveRoleSchema = new Schema( { @@ -6,8 +6,8 @@ const GiveRoleSchema = new Schema( role: { type: [String], required: true }, }, { - collection: 'guild_list', - } + collection: "guild_list", + }, ); const PGiveRoleSchema = new Schema( @@ -16,8 +16,8 @@ const PGiveRoleSchema = new Schema( roleEmoteMap: { type: [GiveRoleSchema], required: true }, }, { - collection: 'guild_list', - } + collection: "guild_list", + }, ); export default PGiveRoleSchema; diff --git a/src/types/models/schemas/PMember.schema.ts b/src/types/models/schemas/PMember.schema.ts index 32c4b260..a0b86619 100644 --- a/src/types/models/schemas/PMember.schema.ts +++ b/src/types/models/schemas/PMember.schema.ts @@ -1,4 +1,4 @@ -import { Schema } from 'mongoose'; +import { Schema } from "npm:mongoose"; const PMemberSchema = new Schema( { @@ -12,8 +12,8 @@ const PMemberSchema = new Schema( regex: { type: String, required: true }, }, { - collection: 'guild_list', - } + collection: "guild_list", + }, ); export default PMemberSchema; diff --git a/src/types/models/schemas/PPoll.schema.ts b/src/types/models/schemas/PPoll.schema.ts index 0c1fbbef..67e206ea 100644 --- a/src/types/models/schemas/PPoll.schema.ts +++ b/src/types/models/schemas/PPoll.schema.ts @@ -1,4 +1,4 @@ -import { Schema } from 'mongoose'; +import { Schema } from "npm:mongoose"; const PPollSchema = new Schema( { @@ -6,8 +6,8 @@ const PPollSchema = new Schema( memberId: { type: String, required: true }, }, { - collection: 'guild_list', - } + collection: "guild_list", + }, ); export default PPollSchema; diff --git a/src/types/models/schemas/PPortalChannel.schema.ts b/src/types/models/schemas/PPortalChannel.schema.ts index 9f1d7f75..ce9522a0 100644 --- a/src/types/models/schemas/PPortalChannel.schema.ts +++ b/src/types/models/schemas/PPortalChannel.schema.ts @@ -1,6 +1,6 @@ -import { Schema } from 'mongoose'; +import { Schema } from "npm:mongoose"; -import PVoiceChannelSchema from './PVoiceChannel.schema.js'; +import PVoiceChannelSchema from "./PVoiceChannel.schema.ts"; const PPortalChannelSchema = new Schema( { @@ -19,7 +19,7 @@ const PPortalChannelSchema = new Schema( regexOverwrite: { type: Boolean, required: true }, }, { - collection: 'guild_list', + collection: "guild_list", }, ); diff --git a/src/types/models/schemas/PVoiceChannel.schema.ts b/src/types/models/schemas/PVoiceChannel.schema.ts index 971a41a0..672ac38f 100644 --- a/src/types/models/schemas/PVoiceChannel.schema.ts +++ b/src/types/models/schemas/PVoiceChannel.schema.ts @@ -1,4 +1,4 @@ -import { Schema } from 'mongoose'; +import { Schema } from "npm:mongoose"; const PVoiceChannelSchema = new Schema( { @@ -12,8 +12,8 @@ const PVoiceChannelSchema = new Schema( annUser: { type: Boolean, required: true }, }, { - collection: 'guild_list', - } + collection: "guild_list", + }, ); export default PVoiceChannelSchema; diff --git a/src/utilities/log.utility.test.ts b/src/utilities/log.utility.test.ts new file mode 100644 index 00000000..27edb4d1 --- /dev/null +++ b/src/utilities/log.utility.test.ts @@ -0,0 +1,81 @@ +import { assertEquals, assertExists } from "jsr:@std/assert"; +import { spy } from "jsr:@std/testing/mock"; +import logger from "./log.utility.ts"; + +Deno.test("log.utility", () => { + Deno.test("logger initialization", () => { + assertExists(logger); + }); + + Deno.test("logger has correct default metadata", () => { + assertEquals(logger.defaultMeta, { service: "portal" }); + }); + + Deno.test("logger logging methods exist", () => { + assertExists(logger.error); + assertExists(logger.warn); + assertExists(logger.info); + assertExists(logger.debug); + }); + + Deno.test("logger logging methods call console.log", () => { + const consoleSpy = spy(console, "log"); + + logger.error("error"); + logger.warn("warn"); + logger.info("info"); + logger.debug("debug"); + + assertEquals(consoleSpy.calls.length, 4); + }); + + Deno.test("logger logging methods call console.error", () => { + const consoleErrorSpy = spy(console, "error"); + + logger.error("error"); + + assertEquals(consoleErrorSpy.calls.length, 1); + }); + + Deno.test("logger logging methods call console.warn", () => { + const consoleWarnSpy = spy(console, "warn"); + + logger.warn("warn"); + + assertEquals(consoleWarnSpy.calls.length, 1); + }); + + Deno.test("logger logging methods call console.info", () => { + const consoleInfoSpy = spy(console, "info"); + + logger.info("info"); + + assertEquals(consoleInfoSpy.calls.length, 1); + }); + + Deno.test("logger logging methods do not call console.log when DEBUG is not set", () => { + const consoleSpy = spy(console, "log"); + + Deno.env.set("DEBUG", ""); + + logger.error("error"); + logger.warn("warn"); + logger.info("info"); + logger.debug("debug"); + + assertEquals(consoleSpy.calls.length, 0); + }); + + Deno.test("logger logging methods call console.log when DEBUG is set", () => { + const consoleSpy = spy(console, "log"); + + Deno.env.set("DEBUG", "true"); + + logger.error("error"); + logger.warn("warn"); + logger.info("info"); + logger.debug("debug"); + + assertEquals(consoleSpy.calls.length, 4); + }); +}); diff --git a/src/utilities/log.utility.ts b/src/utilities/log.utility.ts index 9acb67fe..5e9e5873 100644 --- a/src/utilities/log.utility.ts +++ b/src/utilities/log.utility.ts @@ -1,34 +1,52 @@ -import dotenv from 'dotenv'; -import { createLogger, format, transports } from 'winston'; +import "@std/dotenv/load"; +import { createLogger, format, transports } from "npm:winston"; -dotenv.config(); +class LoggerUtility { + private static readonly consoleFormat = format.combine( + format.colorize(), + format.timestamp({ format: "DD-MM-YY HH:mm:ss" }), + format.errors({ stack: true }), + format.splat(), + format.printf(({ timestamp, level, message, service }) => + `${timestamp} service: ${service} ${level}: ${message}` + ), + ); -const consoleFormat = format.combine( - format.colorize(), - format.timestamp({ format: 'DD-MM-YY HH:mm:ss' }), - format.errors({ stack: true }), - format.splat(), - format.printf(({ timestamp, level, message, service }) => `${timestamp} service: ${service} ${level}: ${message}`), -); + private static readonly fileFormat = format.combine( + format.timestamp({ format: "DD-MM-YY HH:mm:ss" }), + format.errors({ stack: true }), + format.splat(), + format.printf(({ timestamp, level, message, service }) => + `${timestamp} service: ${service} ${level}: ${message}` + ), + format.json(), + ); -const fileFormat = format.combine( - format.timestamp({ format: 'DD-MM-YY HH:mm:ss' }), - format.errors({ stack: true }), - format.splat(), - format.printf(({ timestamp, level, message, service }) => `${timestamp} service: ${service} ${level}: ${message}`), - format.json(), -); + private static readonly fileTransports = [ + new transports.File({ + filename: "error.log", + level: "error", + format: LoggerUtility.fileFormat, + silent: true, + }), + new transports.File({ + filename: "combined.log", + format: LoggerUtility.fileFormat, + silent: true, + }), + ]; -const fileTransports = [ - new transports.File({ filename: 'error.log', level: 'error', format: fileFormat, silent: true }), - new transports.File({ filename: 'combined.log', format: fileFormat, silent: true }), -]; + private static readonly consoleTransport = Deno.env.get("DEBUG") + ? [new transports.Console({ format: LoggerUtility.consoleFormat })] + : []; -const consoleTransport = process.env['DEBUG'] ? [new transports.Console({ format: consoleFormat })] : []; + public static readonly logger = createLogger({ + defaultMeta: { service: "portal" }, + transports: [ + ...LoggerUtility.fileTransports, + ...LoggerUtility.consoleTransport, + ], + }); +} -const logger = createLogger({ - defaultMeta: { service: 'portal' }, - transports: [...fileTransports, ...consoleTransport], -}); - -export default logger; +export default LoggerUtility.logger; diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json deleted file mode 100644 index fc8520e7..00000000 --- a/tsconfig.eslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "./tsconfig.json" -} diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index cdaaffb2..00000000 --- a/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "target": "es2023", - "lib": ["es2023", "dom"], - "module": "esnext", - "moduleResolution": "bundler", - "outDir": "build", - "rootDir": "src", - "removeComments": true, - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "resolveJsonModule": true, - "incremental": true, - "declaration": true, - "forceConsistentCasingInFileNames": true, - "typeRoots": ["node_modules/@types"] - }, - "include": ["src"], - "exclude": ["node_modules", "**/*.spec.ts", "**/*.spec.js", "**/*.test.ts", "**/*.test.js"] -}