From bf9b748f4f1102fc2e0675e4a1cb3c08acf6e858 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 29 Jul 2024 18:18:11 +0100 Subject: [PATCH 01/59] Update dependency @types/node to v20.14.13 (#325) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.14.11` -> `20.14.13`](https://renovatebot.com/diffs/npm/@types%2fnode/20.14.11/20.14.13) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/325 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b953c94..cddbe89 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1259,9 +1259,9 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.14.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.11.tgz#09b300423343460455043ddd4d0ded6ac579b74b" - integrity sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA== + version "20.14.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.13.tgz#bf4fe8959ae1c43bc284de78bd6c01730933736b" + integrity sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w== dependencies: undici-types "~5.26.4" From 73776408b5a33eb4f067054356074242fdc4dc1b Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 29 Jul 2024 18:19:47 +0100 Subject: [PATCH 02/59] Update dependency @typescript-eslint/eslint-plugin to v7.17.0 (#326) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@typescript-eslint/eslint-plugin](https://typescript-eslint.io/packages/eslint-plugin) ([source](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin)) | devDependencies | minor | [`7.15.0` -> `7.17.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2feslint-plugin/7.15.0/7.17.0) | --- ### Release Notes
typescript-eslint/typescript-eslint (@​typescript-eslint/eslint-plugin) ### [`v7.17.0`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#7170-2024-07-22) [Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v7.16.1...v7.17.0) ##### 🚀 Features - **eslint-plugin:** backport no-unsafe-function type, no-wrapper-object-types from v8 to v7 - **eslint-plugin:** \[return-await] add option to report in error-handling scenarios only, and deprecate "never" ##### 🩹 Fixes - **eslint-plugin:** \[no-floating-promises] check top-level type assertions (and more) - **eslint-plugin:** \[strict-boolean-expressions] consider assertion function argument a boolean context - **eslint-plugin:** \[no-unnecessary-condition] false positive on optional private field ##### ❤️ Thank You - Armano - Josh Goldberg ✨ - Kirk Waiblinger - StyleShit You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. ### [`v7.16.1`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#7161-2024-07-15) [Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v7.16.0...v7.16.1) ##### 🩹 Fixes - **eslint-plugin:** \[no-unnecessary-type-parameters] descend into all parts of mapped types in no-unnecessary-type-parameters ##### ❤️ Thank You - Dan Vanderkam You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website. ### [`v7.16.0`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#7160-2024-07-08) [Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v7.15.0...v7.16.0) ##### 🚀 Features - **rule-tester:** stricter rule test validations - **eslint-plugin:** \[no-unnecessary-parameter-property-assignment] add new rule - **eslint-plugin:** add support for nested namespaces to unsafe-member-access - **eslint-plugin:** \[no-floating-promises] add checkThenables option ##### 🩹 Fixes - **deps:** update dependency [@​eslint-community/regexpp](https://github.com/eslint-community/regexpp) to v4.11.0 - **eslint-plugin:** \[no-floating-promises] add `suggestions` to tests from [#​9263](https://github.com/typescript-eslint/typescript-eslint/issues/9263) `checkThenables` - **website:** react key error on internal pages of website - **eslint-plugin:** \[restrict-template-expressions] don't report tuples if `allowArray` option is enabled ##### ❤️ Thank You - Abraham Guo - auvred - Josh Goldberg ✨ - Juan Sanchez - Vinccool96 - YeonJuan - Yukihiro Hasegawa You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/326 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 98 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/yarn.lock b/yarn.lock index cddbe89..184c1d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1339,15 +1339,15 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^7.0.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz#8eaf396ac2992d2b8f874b68eb3fcd6b179cb7f3" - integrity sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz#c8ed1af1ad2928ede5cdd207f7e3090499e1f77b" + integrity sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "7.15.0" - "@typescript-eslint/type-utils" "7.15.0" - "@typescript-eslint/utils" "7.15.0" - "@typescript-eslint/visitor-keys" "7.15.0" + "@typescript-eslint/scope-manager" "7.17.0" + "@typescript-eslint/type-utils" "7.17.0" + "@typescript-eslint/utils" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" @@ -1372,21 +1372,21 @@ "@typescript-eslint/types" "6.21.0" "@typescript-eslint/visitor-keys" "6.21.0" -"@typescript-eslint/scope-manager@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz#201b34b0720be8b1447df17b963941bf044999b2" - integrity sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw== +"@typescript-eslint/scope-manager@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz#e072d0f914662a7bfd6c058165e3c2b35ea26b9d" + integrity sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA== dependencies: - "@typescript-eslint/types" "7.15.0" - "@typescript-eslint/visitor-keys" "7.15.0" + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" -"@typescript-eslint/type-utils@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz#5b83c904c6de91802fb399305a50a56d10472c39" - integrity sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg== +"@typescript-eslint/type-utils@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz#c5da78feb134c9c9978cbe89e2b1a589ed22091a" + integrity sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA== dependencies: - "@typescript-eslint/typescript-estree" "7.15.0" - "@typescript-eslint/utils" "7.15.0" + "@typescript-eslint/typescript-estree" "7.17.0" + "@typescript-eslint/utils" "7.17.0" debug "^4.3.4" ts-api-utils "^1.3.0" @@ -1395,10 +1395,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== -"@typescript-eslint/types@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.15.0.tgz#fb894373a6e3882cbb37671ffddce44f934f62fc" - integrity sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw== +"@typescript-eslint/types@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.17.0.tgz#7ce8185bdf06bc3494e73d143dbf3293111b9cff" + integrity sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A== "@typescript-eslint/typescript-estree@6.21.0": version "6.21.0" @@ -1414,13 +1414,13 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz#e323bfa3966e1485b638ce751f219fc1f31eba37" - integrity sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ== +"@typescript-eslint/typescript-estree@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz#dcab3fea4c07482329dd6107d3c6480e228e4130" + integrity sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw== dependencies: - "@typescript-eslint/types" "7.15.0" - "@typescript-eslint/visitor-keys" "7.15.0" + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -1428,15 +1428,15 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/utils@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.15.0.tgz#9e6253c4599b6e7da2fb64ba3f549c73eb8c1960" - integrity sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA== +"@typescript-eslint/utils@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.17.0.tgz#815cd85b9001845d41b699b0ce4f92d6dfb84902" + integrity sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "7.15.0" - "@typescript-eslint/types" "7.15.0" - "@typescript-eslint/typescript-estree" "7.15.0" + "@typescript-eslint/scope-manager" "7.17.0" + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/typescript-estree" "7.17.0" "@typescript-eslint/visitor-keys@6.21.0": version "6.21.0" @@ -1446,12 +1446,12 @@ "@typescript-eslint/types" "6.21.0" eslint-visitor-keys "^3.4.1" -"@typescript-eslint/visitor-keys@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz#1da0726201a859343fe6a05742a7c1792fff5b66" - integrity sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw== +"@typescript-eslint/visitor-keys@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz#680465c734be30969e564b4647f38d6cdf49bfb0" + integrity sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A== dependencies: - "@typescript-eslint/types" "7.15.0" + "@typescript-eslint/types" "7.17.0" eslint-visitor-keys "^3.4.3" "@ungap/structured-clone@^1.2.0": @@ -2389,13 +2389,20 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: version "4.3.5" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== dependencies: ms "2.1.2" +debug@^4.3.4: + version "4.3.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + dependencies: + ms "2.1.2" + decompress-response@^4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" @@ -5860,11 +5867,16 @@ semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5, semver@^7.3.7, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0: +semver@^7.3.5, semver@^7.3.7, semver@^7.5.3, semver@^7.5.4: version "7.6.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== +semver@^7.6.0: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" From 89c6dc527ab9f2ad9a0fcf836559a1f07c246b8b Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 2 Aug 2024 18:20:23 +0100 Subject: [PATCH 03/59] Document the google drive sync process (#328) #82 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/328 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- docs/google-drive-sync.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 docs/google-drive-sync.md diff --git a/docs/google-drive-sync.md b/docs/google-drive-sync.md new file mode 100644 index 0000000..1847f70 --- /dev/null +++ b/docs/google-drive-sync.md @@ -0,0 +1,35 @@ +# Google Drive Sync + +The bot relies on an external sync between the local file system and Google +Drive in order to get newer cards to the bot. This is done using +[Rclone](https://rclone.org/). + +The process for this is done by once the `/gdrivesync` command is executed by +an admin user of the bot, which calls the system shell to run rclone to the +card folder. + +- The admins who can run the command is specifed in `$BOT_ADMINS`, which are +discord user ids separated by commas. +- The card folder is located at `$DATA_DIR/cards`. +- The source requires rclone's remote to be setup as `card-drop-gdrive`. + +The exact command it runs is: `rclone sync card-drop-gdrive: $DATA_DIR/cards`. + +Once it syncs the database will reread all the cards for updates and then load +them into the bot to be given. + +## Safe Mode +Safe mode is a function of the bot which disables the `/drop` command function +and any other functions which rely on the card metadata. Safe mode is activated +upon failure to sync properly. It is disabled once errors are resolved. + +The reason for safe mode is to ensure that the bot stays online for admins to +be able to resync the bot in case there's an error without it crashing. + +## Google Drive +Please see the Rclone documentation on how to setup a remote using Google +Drive. You will need to make an app password for this. + +- scope: `drive.readonly` +- root\_folder\_id: The folder id where the cards are located, this can be found + by looking at the url when viewing the folder in the browser in google drive. From ec0292d6587968d6efa57aa9f0f6ec92275f597a Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 2 Aug 2024 18:23:01 +0100 Subject: [PATCH 04/59] Upgrade @types/uuid to v10 (#329) #310 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/329 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 9126a28..2d47693 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@types/clone-deep": "^4.0.4", "@types/express": "^4.17.20", "@types/jest": "^29.0.0", - "@types/uuid": "^9.0.0", + "@types/uuid": "^10.0.0", "body-parser": "^1.20.2", "canvas": "^2.11.2", "clone-deep": "^4.0.1", diff --git a/yarn.lock b/yarn.lock index 184c1d5..e13db6d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1314,10 +1314,10 @@ resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c" integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw== -"@types/uuid@^9.0.0": - version "9.0.8" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" - integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== +"@types/uuid@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-10.0.0.tgz#e9c07fe50da0f53dc24970cca94d619ff03f6f6d" + integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ== "@types/ws@^8.5.10": version "8.5.10" From 7a99d273f6bb66a08dd5e0dd0ab707528cc42d01 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 5 Aug 2024 18:51:10 +0100 Subject: [PATCH 05/59] Update dependency @types/node to v20.14.14 (#332) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.14.13` -> `20.14.14`](https://renovatebot.com/diffs/npm/@types%2fnode/20.14.13/20.14.14) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/332 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e13db6d..cac1eb2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1259,9 +1259,9 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.14.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.13.tgz#bf4fe8959ae1c43bc284de78bd6c01730933736b" - integrity sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w== + version "20.14.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.14.tgz#6b655d4a88623b0edb98300bb9dd2107225f885e" + integrity sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ== dependencies: undici-types "~5.26.4" From 981cdbfdd7133ded4e8d86b3a4274cca1dbc0070 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 5 Aug 2024 18:52:08 +0100 Subject: [PATCH 06/59] Update dependency @typescript-eslint/eslint-plugin to v7.18.0 (#333) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@typescript-eslint/eslint-plugin](https://typescript-eslint.io/packages/eslint-plugin) ([source](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin)) | devDependencies | minor | [`7.17.0` -> `7.18.0`](https://renovatebot.com/diffs/npm/@typescript-eslint%2feslint-plugin/7.17.0/7.18.0) | --- ### Release Notes
typescript-eslint/typescript-eslint (@​typescript-eslint/eslint-plugin) ### [`v7.18.0`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#7180-2024-07-29) [Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v7.17.0...v7.18.0) ##### 🩹 Fixes - **eslint-plugin:** \[no-unnecessary-type-assertion] prevent runtime error when asserting a variable declared in default TS lib - **eslint-plugin:** \[unbound-method] report on destructuring in function parameters - **eslint-plugin:** \[no-duplicate-type-constituents] shouldn't report on error types - **eslint-plugin:** \[strict-boolean-expressions] support branded booleans ##### ❤️ Thank You - auvred - Oliver Salzburg - Vinccool96 - Yukihiro Hasegawa You can read about our [versioning strategy](https://main--typescript-eslint.netlify.app/users/versioning) and [releases](https://main--typescript-eslint.netlify.app/users/releases) on our website.
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/333 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 82 +++++++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/yarn.lock b/yarn.lock index cac1eb2..10b5429 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1339,15 +1339,15 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^7.0.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz#c8ed1af1ad2928ede5cdd207f7e3090499e1f77b" - integrity sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A== + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz#b16d3cf3ee76bf572fdf511e79c248bdec619ea3" + integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "7.17.0" - "@typescript-eslint/type-utils" "7.17.0" - "@typescript-eslint/utils" "7.17.0" - "@typescript-eslint/visitor-keys" "7.17.0" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/type-utils" "7.18.0" + "@typescript-eslint/utils" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" @@ -1372,21 +1372,21 @@ "@typescript-eslint/types" "6.21.0" "@typescript-eslint/visitor-keys" "6.21.0" -"@typescript-eslint/scope-manager@7.17.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz#e072d0f914662a7bfd6c058165e3c2b35ea26b9d" - integrity sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA== +"@typescript-eslint/scope-manager@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" + integrity sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA== dependencies: - "@typescript-eslint/types" "7.17.0" - "@typescript-eslint/visitor-keys" "7.17.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" -"@typescript-eslint/type-utils@7.17.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz#c5da78feb134c9c9978cbe89e2b1a589ed22091a" - integrity sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA== +"@typescript-eslint/type-utils@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b" + integrity sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA== dependencies: - "@typescript-eslint/typescript-estree" "7.17.0" - "@typescript-eslint/utils" "7.17.0" + "@typescript-eslint/typescript-estree" "7.18.0" + "@typescript-eslint/utils" "7.18.0" debug "^4.3.4" ts-api-utils "^1.3.0" @@ -1395,10 +1395,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== -"@typescript-eslint/types@7.17.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.17.0.tgz#7ce8185bdf06bc3494e73d143dbf3293111b9cff" - integrity sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A== +"@typescript-eslint/types@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" + integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== "@typescript-eslint/typescript-estree@6.21.0": version "6.21.0" @@ -1414,13 +1414,13 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@7.17.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz#dcab3fea4c07482329dd6107d3c6480e228e4130" - integrity sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw== +"@typescript-eslint/typescript-estree@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" + integrity sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA== dependencies: - "@typescript-eslint/types" "7.17.0" - "@typescript-eslint/visitor-keys" "7.17.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -1428,15 +1428,15 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/utils@7.17.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.17.0.tgz#815cd85b9001845d41b699b0ce4f92d6dfb84902" - integrity sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw== +"@typescript-eslint/utils@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f" + integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "7.17.0" - "@typescript-eslint/types" "7.17.0" - "@typescript-eslint/typescript-estree" "7.17.0" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/typescript-estree" "7.18.0" "@typescript-eslint/visitor-keys@6.21.0": version "6.21.0" @@ -1446,12 +1446,12 @@ "@typescript-eslint/types" "6.21.0" eslint-visitor-keys "^3.4.1" -"@typescript-eslint/visitor-keys@7.17.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz#680465c734be30969e564b4647f38d6cdf49bfb0" - integrity sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A== +"@typescript-eslint/visitor-keys@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7" + integrity sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg== dependencies: - "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/types" "7.18.0" eslint-visitor-keys "^3.4.3" "@ungap/structured-clone@^1.2.0": From 480786a1e9c1f8dfa8d24c5772558b972face0d2 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 10 Aug 2024 16:08:45 +0100 Subject: [PATCH 07/59] Remove dependency minimatch (#334) - Removed the dependency minimatch from the project - Its not actually used anywhere, I believe it wasn't removed when I was trying out glob packages prior to merging #312 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/334 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- package.json | 1 - yarn.lock | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 2d47693..e213df9 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ "jest": "^29.0.0", "jest-mock-extended": "^3.0.0", "jimp": "^0.22.12", - "minimatch": "9.0.5", "mysql": "^2.18.1", "ts-jest": "^29.0.0", "typeorm": "0.3.20", diff --git a/yarn.lock b/yarn.lock index 10b5429..4846f78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4778,13 +4778,6 @@ minimatch@9.0.3: dependencies: brace-expansion "^2.0.1" -minimatch@9.0.5, minimatch@^9.0.4: - version "9.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" - integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== - dependencies: - brace-expansion "^2.0.1" - minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -4799,6 +4792,13 @@ minimatch@^9.0.0: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" From 9302902b17f48aee2c762bbd485084f15a11b1e9 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 12 Aug 2024 20:59:56 +0100 Subject: [PATCH 08/59] Update dependency @types/node to v20.14.15 (#335) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.14.14` -> `20.14.15`](https://renovatebot.com/diffs/npm/@types%2fnode/20.14.14/20.14.15) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/335 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4846f78..a19aeee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1259,9 +1259,9 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.14.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.14.tgz#6b655d4a88623b0edb98300bb9dd2107225f885e" - integrity sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ== + version "20.14.15" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.15.tgz#e59477ab7bc7db1f80c85540bfd192a0becc588b" + integrity sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw== dependencies: undici-types "~5.26.4" From 8bd5f445241d277f34b783e0967689eec8e075ea Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 12 Aug 2024 21:01:21 +0100 Subject: [PATCH 09/59] Update dependency ts-jest to v29.2.4 (#336) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [ts-jest](https://kulshekhar.github.io/ts-jest) ([source](https://github.com/kulshekhar/ts-jest)) | dependencies | minor | [`29.1.5` -> `29.2.4`](https://renovatebot.com/diffs/npm/ts-jest/29.1.5/29.2.4) | --- ### Release Notes
kulshekhar/ts-jest (ts-jest) ### [`v29.2.4`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#2924-2024-08-01) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.2.3...v29.2.4) ### [`v29.2.3`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#2923-2024-07-18) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.2.2...v29.2.3) ### [`v29.2.2`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#2922-2024-07-10) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.2.1...v29.2.2) ### [`v29.2.1`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#2921-2024-07-10) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.2.0...v29.2.1) ### [`v29.2.0`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#2920-2024-07-08) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.1.5...v29.2.0) ##### Bug Fixes - fix: don't show warning message with Node16/NodeNext ([99c4f49](https://github.com/kulshekhar/ts-jest/commit/99c4f49)), closes [#​4266](https://github.com/kulshekhar/ts-jest/issues/4266) ##### Features - feat(cli): allow migrating cjs `presets` to `transform` config ([22fb027](https://github.com/kulshekhar/ts-jest/commit/22fb027)) - feat(presets): add util functions to create ESM presets ([06f78ed](https://github.com/kulshekhar/ts-jest/commit/06f78ed)), close [#​4200](https://github.com/kulshekhar/ts-jest/issues/4200) - feat(presets): add util functions to create CJS presets ([f9cc3c0](https://github.com/kulshekhar/ts-jest/commit/f9cc3c0)), close [#​4200](https://github.com/kulshekhar/ts-jest/issues/4200) ##### Code refactoring - refactor: replace lodash deps with native js implementation ([40f1708](https://github.com/kulshekhar/ts-jest/commit/40f1708)) - refactor: use `TsJestTransformerOptions` type everywhere possibly ([7d001be](https://github.com/kulshekhar/ts-jest/commit/7d001be)) - refactor(cli): use new preset util functions to initialize test config ([c2b56ca](https://github.com/kulshekhar/ts-jest/commit/c2b56ca)) - refactor(presets): use create preset util functions for cjs presets ([922d6d0](https://github.com/kulshekhar/ts-jest/commit/922d6d0)) - test: switch `react-app` to use Vite ([827c8ad](https://github.com/kulshekhar/ts-jest/commit/827c8ad))
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/336 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 63 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index a19aeee..5bba916 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1247,11 +1247,11 @@ integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/node@*": - version "20.14.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.9.tgz#12e8e765ab27f8c421a1820c99f5f313a933b420" - integrity sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg== + version "22.2.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.2.0.tgz#7cf046a99f0ba4d628ad3088cb21f790df9b0c5b" + integrity sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ== dependencies: - undici-types "~5.26.4" + undici-types "~6.13.0" "@types/node@16.9.1": version "16.9.1" @@ -1332,9 +1332,9 @@ integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^17.0.8": - version "17.0.32" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" - integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== + version "17.0.33" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d" + integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA== dependencies: "@types/yargs-parser" "*" @@ -2018,7 +2018,7 @@ chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2601,6 +2601,13 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== +ejs@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== + dependencies: + jake "^10.8.5" + electron-to-chromium@^1.4.668: version "1.4.788" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.788.tgz#a3545959d5cfa0a266d3e551386c040be34e7e06" @@ -3014,6 +3021,13 @@ file-type@^16.5.4: strtok3 "^6.2.4" token-types "^4.1.1" +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + fill-range@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" @@ -3957,6 +3971,16 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +jake@^10.8.5: + version "10.9.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" + integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + jest-changed-files@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" @@ -4785,6 +4809,13 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + minimatch@^9.0.0: version "9.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" @@ -5867,12 +5898,12 @@ semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5, semver@^7.3.7, semver@^7.5.3, semver@^7.5.4: +semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: version "7.6.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== -semver@^7.6.0: +semver@^7.5.3, semver@^7.6.0: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== @@ -6420,11 +6451,12 @@ ts-essentials@^10.0.0: integrity sha512-77FHNJEyysF9+1s4G6eejuA1lxw7uMchT3ZPy3CIbh7GIunffpshtM8pTe5G6N5dpOzNevqRHew859ceLWVBfw== ts-jest@^29.0.0: - version "29.1.5" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.5.tgz#d6c0471cc78bffa2cb4664a0a6741ef36cfe8f69" - integrity sha512-UuClSYxM7byvvYfyWdFI+/2UxMmwNyJb0NPkZPQE2hew3RurV7l7zURgOHAd/1I1ZdPpe3GUsXNXAcN8TFKSIg== + version "29.2.4" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.2.4.tgz#38ccf487407d7a63054a72689f6f99b075e296e5" + integrity sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw== dependencies: bs-logger "0.x" + ejs "^3.1.10" fast-json-stable-stringify "2.x" jest-util "^29.0.0" json5 "^2.2.3" @@ -6556,6 +6588,11 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.13.0.tgz#e3e79220ab8c81ed1496b5812471afd7cf075ea5" + integrity sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg== + undici@6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/undici/-/undici-6.13.0.tgz#7edbf4b7f3aac5f8a681d515151bf55cb3589d72" From 5defb682c195f37b4431c3438265bb7dcff599cf Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 17 Aug 2024 17:26:31 +0100 Subject: [PATCH 10/59] Update view command to use fuzzy search instead of direct card number (#340) - Install `fuse.js` package to allow for fuzzy finding - Update the `/view` command to use fuzzy search by name instead of the card number - Add pagination for the command via the `View` button event #154 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/340 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- .env.example | 1 + package.json | 1 + src/buttonEvents/View.ts | 25 +++++++++++ src/commands/view.ts | 74 +++++++-------------------------- src/helpers/CardSearchHelper.ts | 62 +++++++++++++++++++++++++++ src/registry.ts | 2 + yarn.lock | 5 +++ 7 files changed, 112 insertions(+), 58 deletions(-) create mode 100644 src/buttonEvents/View.ts create mode 100644 src/helpers/CardSearchHelper.ts diff --git a/.env.example b/.env.example index 00a861f..c260a7d 100644 --- a/.env.example +++ b/.env.example @@ -32,6 +32,7 @@ DB_AUTH_PASS= DB_SYNC= DB_LOGGING= DB_DATA_LOCATION=./.temp/database +DB_ROOT_HOST=0.0.0.0 DB_CARD_FILE=:memory: diff --git a/package.json b/package.json index e213df9..c18a18f 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "discord.js": "^14.15.3", "dotenv": "^16.0.0", "express": "^4.18.2", + "fuse.js": "^7.0.0", "glob": "^10.3.10", "jest": "^29.0.0", "jest-mock-extended": "^3.0.0", diff --git a/src/buttonEvents/View.ts b/src/buttonEvents/View.ts new file mode 100644 index 0000000..8c133ba --- /dev/null +++ b/src/buttonEvents/View.ts @@ -0,0 +1,25 @@ +import {ButtonInteraction} from "discord.js"; +import {ButtonEvent} from "../type/buttonEvent.js"; +import CardSearchHelper from "../helpers/CardSearchHelper.js"; + +export default class View extends ButtonEvent { + public override async execute(interaction: ButtonInteraction) { + const page = interaction.customId.split(" ")[1]; + const query = interaction.customId.split(" ").splice(1).join(" "); + + await interaction.deferUpdate(); + + const searchResult = await CardSearchHelper.GenerateSearchPage(query, interaction.user.id, Number(page)); + + if (!searchResult) { + await interaction.followUp("No results found"); + return; + } + + await interaction.editReply({ + embeds: [ searchResult.embed ], + components: [ searchResult.row ], + files: [ searchResult.attachment ], + }); + } +} diff --git a/src/commands/view.ts b/src/commands/view.ts index ce6f9cb..aff1ef5 100644 --- a/src/commands/view.ts +++ b/src/commands/view.ts @@ -1,11 +1,7 @@ -import { AttachmentBuilder, CommandInteraction, DiscordAPIError, SlashCommandBuilder } from "discord.js"; +import { CommandInteraction, SlashCommandBuilder } from "discord.js"; import { Command } from "../type/command"; -import { CoreClient } from "../client/client"; -import { readFileSync } from "fs"; -import path from "path"; -import Inventory from "../database/entities/app/Inventory"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import AppLogger from "../client/appLogger"; +import CardSearchHelper from "../helpers/CardSearchHelper"; export default class View extends Command { constructor() { @@ -16,67 +12,29 @@ export default class View extends Command { .setDescription("View a specific command") .addStringOption(x => x - .setName("cardnumber") - .setDescription("The card number to view") + .setName("name") + .setDescription("The card name to search for") .setRequired(true)); } public override async execute(interaction: CommandInteraction) { - const cardNumber = interaction.options.get("cardnumber"); + const name = interaction.options.get("name", true); - AppLogger.LogSilly("Commands/View", `Parameters: cardNumber=${cardNumber?.value}`); - - if (!cardNumber || !cardNumber.value) { - await interaction.reply("Card number is required."); - return; - } - - const card = CoreClient.Cards - .flatMap(x => x.cards) - .find(x => x.id == cardNumber.value); - - if (!card) { - await interaction.reply("Card not found."); - return; - } - - const series = CoreClient.Cards - .find(x => x.cards.includes(card))!; - - let image: Buffer; - const imageFileName = card.path.split("/").pop()!; - - try { - image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.path)); - } catch { - AppLogger.LogError("Commands/View", `Unable to fetch image for card ${card.id}.`); - - await interaction.reply(`Unable to fetch image for card ${card.id}.`); - return; - } + AppLogger.LogSilly("Commands/View", `Parameters: name=${name.value}`); await interaction.deferReply(); - const attachment = new AttachmentBuilder(image, { name: imageFileName }); + const searchResult = await CardSearchHelper.GenerateSearchPage(name.value!.toString(), interaction.user.id, 0); - const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, card.id); - const quantityClaimed = inventory ? inventory.Quantity : 0; - - const embed = CardDropHelperMetadata.GenerateDropEmbed({ card, series }, quantityClaimed, imageFileName); - - try { - await interaction.editReply({ - embeds: [ embed ], - files: [ attachment ], - }); - } catch (e) { - AppLogger.LogError("Commands/View", `Error sending view for card ${card.id}: ${e}`); - - if (e instanceof DiscordAPIError) { - await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. Code: ${e.code}.`); - } else { - await interaction.editReply("Unable to send next drop. Please try again, and report this if it keeps happening. Code: UNKNOWN."); - } + if (!searchResult) { + await interaction.editReply("No results found"); + return; } + + await interaction.editReply({ + embeds: [ searchResult.embed ], + components: [ searchResult.row ], + files: [ searchResult.attachment ], + }); } } \ No newline at end of file diff --git a/src/helpers/CardSearchHelper.ts b/src/helpers/CardSearchHelper.ts new file mode 100644 index 0000000..c0f6bd5 --- /dev/null +++ b/src/helpers/CardSearchHelper.ts @@ -0,0 +1,62 @@ +import {ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder} from "discord.js"; +import Fuse from "fuse.js"; +import {CoreClient} from "../client/client.js"; +import CardDropHelperMetadata from "./CardDropHelperMetadata.js"; +import Inventory from "../database/entities/app/Inventory.js"; +import {readFileSync} from "fs"; +import path from "path"; +import AppLogger from "../client/appLogger.js"; + +interface ReturnedPage { + embed: EmbedBuilder, + row: ActionRowBuilder, + attachment: AttachmentBuilder, +} + +export default class CardSearchHelper { + public static async GenerateSearchPage(query: string, userid: string, page: number): Promise { + const fzf = new Fuse(CoreClient.Cards.flatMap(x => x.cards), { keys: ["name"] }); + const entries = fzf.search(query); + + const entry = entries[page]; + + if (!entry) return undefined; + + const card = CardDropHelperMetadata.GetCardByCardNumber(entry.item.id); + + if (!card) return undefined; + + let image: Buffer; + const imageFileName = card.card.path.split("/").pop()!; + + try { + image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.card.path)); + } catch { + AppLogger.LogError("Commands/View", `Unable to fetch image for card ${card.card.id}.`); + + return undefined; + } + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + const inventory = await Inventory.FetchOneByCardNumberAndUserId(userid, card.card.id); + const quantityClaimed = inventory?.Quantity ?? 0; + + const embed = CardDropHelperMetadata.GenerateDropEmbed(card, quantityClaimed, imageFileName); + + const row = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId(`view ${page - 1} ${query}`) + .setLabel("Previous") + .setStyle(ButtonStyle.Primary) + .setDisabled(page == 0), + new ButtonBuilder() + .setCustomId(`view ${page + 1} ${query}`) + .setLabel("Next") + .setStyle(ButtonStyle.Primary) + .setDisabled(page + 1 == entries.length)); + + return { embed, row, attachment }; + } +} diff --git a/src/registry.ts b/src/registry.ts index 86b2b68..20787af 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -27,6 +27,7 @@ import Reroll from "./buttonEvents/Reroll"; import SacrificeButtonEvent from "./buttonEvents/Sacrifice"; import SeriesEvent from "./buttonEvents/Series"; import TradeButtonEvent from "./buttonEvents/Trade"; +import ViewButtonEvent from "./buttonEvents/View"; export default class Registry { public static RegisterCommands() { @@ -57,5 +58,6 @@ export default class Registry { CoreClient.RegisterButtonEvent("sacrifice", new SacrificeButtonEvent()); CoreClient.RegisterButtonEvent("series", new SeriesEvent()); CoreClient.RegisterButtonEvent("trade", new TradeButtonEvent()); + CoreClient.RegisterButtonEvent("view", new ViewButtonEvent()); } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 5bba916..c743923 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3152,6 +3152,11 @@ function-bind@^1.1.2: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== +fuse.js@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-7.0.0.tgz#6573c9fcd4c8268e403b4fc7d7131ffcf99a9eb2" + integrity sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q== + gauge@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" From 805dd00357235b54000ca8c95f847d9079d0c7ec Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 17 Aug 2024 17:29:17 +0100 Subject: [PATCH 11/59] Upgrade node in workflow to use v20 (#341) - Update the deployment workflows to use node v20 #330 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/341 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- .forgejo/workflows/production.yml | 2 +- .forgejo/workflows/stage.yml | 2 +- .forgejo/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.forgejo/workflows/production.yml b/.forgejo/workflows/production.yml index 1dd774e..f71273d 100644 --- a/.forgejo/workflows/production.yml +++ b/.forgejo/workflows/production.yml @@ -16,7 +16,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 20.x - run: yarn install --frozen-lockfile - run: yarn build - run: yarn test diff --git a/.forgejo/workflows/stage.yml b/.forgejo/workflows/stage.yml index 8903a70..1e73e7a 100644 --- a/.forgejo/workflows/stage.yml +++ b/.forgejo/workflows/stage.yml @@ -16,7 +16,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 20.x - run: yarn install --frozen-lockfile - run: yarn build - run: yarn test diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml index b2de547..6becf3e 100644 --- a/.forgejo/workflows/test.yml +++ b/.forgejo/workflows/test.yml @@ -18,7 +18,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 20.x - run: yarn install --frozen-lockfile - run: yarn build - run: yarn test From 8e4597512f60c21827fdfc4418b8a6f2d13b7c9f Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 20 Aug 2024 17:37:05 +0100 Subject: [PATCH 12/59] Update dependency @types/node to v20.16.0 (#342) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | minor | [`20.14.15` -> `20.16.0`](https://renovatebot.com/diffs/npm/@types%2fnode/20.14.15/20.16.0) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/342 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index c743923..af00e5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1259,11 +1259,11 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.14.15" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.15.tgz#e59477ab7bc7db1f80c85540bfd192a0becc588b" - integrity sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw== + version "20.16.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.0.tgz#02e5cd414f76bf345874ee65a1e5590d755d894f" + integrity sha512-vDxceJcoZhIVh67S568bm1UGZO0DX0hpplJZxzeXMKwIPLn190ec5RRxQ69BKhX44SUGIxxgMdDY557lGLKprQ== dependencies: - undici-types "~5.26.4" + undici-types "~6.19.2" "@types/normalize-package-data@^2.4.3": version "2.4.4" @@ -6588,16 +6588,16 @@ typescript@^5.0.0: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== - undici-types@~6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.13.0.tgz#e3e79220ab8c81ed1496b5812471afd7cf075ea5" integrity sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg== +undici-types@~6.19.2: + version "6.19.6" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.6.tgz#e218c3df0987f4c0e0008ca00d6b6472d9b89b36" + integrity sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org== + undici@6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/undici/-/undici-6.13.0.tgz#7edbf4b7f3aac5f8a681d515151bf55cb3589d72" From 79a4d18df36a96771eedafe71883ec083fb82ac2 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 20 Aug 2024 17:38:06 +0100 Subject: [PATCH 13/59] Update dependency typescript to v5.5.4 (#343) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [typescript](https://www.typescriptlang.org/) ([source](https://github.com/Microsoft/TypeScript)) | devDependencies | minor | [`5.4.5` -> `5.5.4`](https://renovatebot.com/diffs/npm/typescript/5.4.5/5.5.4) | --- ### Release Notes
Microsoft/TypeScript (typescript) ### [`v5.5.4`](https://github.com/microsoft/TypeScript/releases/tag/v5.5.4): TypeScript 5.5.4 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v5.5.3...v5.5.4) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/). For the complete list of fixed issues, check out the - [fixed issues query for TypeScript v5.5.4 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.4%22+is%3Aclosed+). - [fixed issues query for TypeScript v5.5.3 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.3%22+is%3Aclosed+). - [fixed issues query for TypeScript v5.5.2 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.2%22+is%3Aclosed+). - [fixed issues query for TypeScript v5.5.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.1%22+is%3Aclosed+). - [fixed issues query for TypeScript v5.5.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.0%22+is%3Aclosed+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) (soon!) ### [`v5.5.3`](https://github.com/microsoft/TypeScript/releases/tag/v5.5.3): TypeScript 5.5.3 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v5.5.2...v5.5.3) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/). For the complete list of fixed issues, check out the - [fixed issues query for TypeScript v5.5.3 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.3%22+is%3Aclosed+). - [fixed issues query for TypeScript v5.5.2 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.2%22+is%3Aclosed+). - [fixed issues query for TypeScript v5.5.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.1%22+is%3Aclosed+). - [fixed issues query for TypeScript v5.5.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.0%22+is%3Aclosed+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild) ### [`v5.5.2`](https://github.com/microsoft/TypeScript/releases/tag/v5.5.2): TypeScript 5.5 [Compare Source](https://github.com/Microsoft/TypeScript/compare/v5.4.5...v5.5.2) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/). For the complete list of fixed issues, check out the - [fixed issues query for TypeScript v5.5.2 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.2%22+is%3Aclosed+). - [fixed issues query for TypeScript v5.5.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.1%22+is%3Aclosed+). - [fixed issues query for TypeScript v5.5.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=is%3Aissue+milestone%3A%22TypeScript+5.5.0%22+is%3Aclosed+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/343 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index af00e5b..ecff5d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6584,9 +6584,9 @@ types-pkg-json@^1.1.0: types-json "^1.2.2" typescript@^5.0.0: - version "5.4.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" - integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== + version "5.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" + integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== undici-types@~6.13.0: version "6.13.0" From 66243e67427587434d6ffaa4d5bfb84fcdb2c1c6 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 24 Aug 2024 17:26:26 +0100 Subject: [PATCH 14/59] Fix fuzzy /view to be consistent with its pages (#345) - Fix the `/view` command to have a set amount of cards in its page rotation - This is done now by updating it so instead of requerying each page turn it instead queries once at the start and passes the top 5 results to the button event #154 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/345 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/buttonEvents/View.ts | 4 +- src/commands/id.ts | 82 +++++++++++++++++++++++++++++++++ src/commands/view.ts | 4 +- src/helpers/CardSearchHelper.ts | 75 ++++++++++++++++++++++++++---- src/registry.ts | 2 + 5 files changed, 153 insertions(+), 14 deletions(-) create mode 100644 src/commands/id.ts diff --git a/src/buttonEvents/View.ts b/src/buttonEvents/View.ts index 8c133ba..f79a1af 100644 --- a/src/buttonEvents/View.ts +++ b/src/buttonEvents/View.ts @@ -5,11 +5,11 @@ import CardSearchHelper from "../helpers/CardSearchHelper.js"; export default class View extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { const page = interaction.customId.split(" ")[1]; - const query = interaction.customId.split(" ").splice(1).join(" "); + const results = interaction.customId.split(" ").splice(2); await interaction.deferUpdate(); - const searchResult = await CardSearchHelper.GenerateSearchPage(query, interaction.user.id, Number(page)); + const searchResult = await CardSearchHelper.GenerateSearchPageFromQuery(results, interaction.user.id, Number(page)); if (!searchResult) { await interaction.followUp("No results found"); diff --git a/src/commands/id.ts b/src/commands/id.ts new file mode 100644 index 0000000..ae924a6 --- /dev/null +++ b/src/commands/id.ts @@ -0,0 +1,82 @@ +import { AttachmentBuilder, CommandInteraction, DiscordAPIError, SlashCommandBuilder } from "discord.js"; +import { Command } from "../type/command"; +import { CoreClient } from "../client/client"; +import { readFileSync } from "fs"; +import path from "path"; +import Inventory from "../database/entities/app/Inventory"; +import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; +import AppLogger from "../client/appLogger"; + +export default class Id extends Command { + constructor() { + super(); + + this.CommandBuilder = new SlashCommandBuilder() + .setName("id") + .setDescription("View a specific command by its id") + .addStringOption(x => + x + .setName("cardnumber") + .setDescription("The card number to view") + .setRequired(true)); + } + + public override async execute(interaction: CommandInteraction) { + const cardNumber = interaction.options.get("cardnumber"); + + AppLogger.LogSilly("Commands/View", `Parameters: cardNumber=${cardNumber?.value}`); + + if (!cardNumber || !cardNumber.value) { + await interaction.reply("Card number is required."); + return; + } + + const card = CoreClient.Cards + .flatMap(x => x.cards) + .find(x => x.id == cardNumber.value); + + if (!card) { + await interaction.reply("Card not found."); + return; + } + + const series = CoreClient.Cards + .find(x => x.cards.includes(card))!; + + let image: Buffer; + const imageFileName = card.path.split("/").pop()!; + + try { + image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.path)); + } catch { + AppLogger.LogError("Commands/View", `Unable to fetch image for card ${card.id}.`); + + await interaction.reply(`Unable to fetch image for card ${card.id}.`); + return; + } + + await interaction.deferReply(); + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, card.id); + const quantityClaimed = inventory ? inventory.Quantity : 0; + + const embed = CardDropHelperMetadata.GenerateDropEmbed({ card, series }, quantityClaimed, imageFileName); + + try { + await interaction.editReply({ + embeds: [ embed ], + files: [ attachment ], + }); + } catch (e) { + AppLogger.LogError("Commands/View", `Error sending view for card ${card.id}: ${e}`); + + if (e instanceof DiscordAPIError) { + await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. Code: ${e.code}.`); + } else { + await interaction.editReply("Unable to send next drop. Please try again, and report this if it keeps happening. Code: UNKNOWN."); + } + } + } +} diff --git a/src/commands/view.ts b/src/commands/view.ts index aff1ef5..3ba5621 100644 --- a/src/commands/view.ts +++ b/src/commands/view.ts @@ -9,7 +9,7 @@ export default class View extends Command { this.CommandBuilder = new SlashCommandBuilder() .setName("view") - .setDescription("View a specific command") + .setDescription("Search for a card by its name") .addStringOption(x => x .setName("name") @@ -24,7 +24,7 @@ export default class View extends Command { await interaction.deferReply(); - const searchResult = await CardSearchHelper.GenerateSearchPage(name.value!.toString(), interaction.user.id, 0); + const searchResult = await CardSearchHelper.GenerateSearchQuery(name.value!.toString(), interaction.user.id, 7); if (!searchResult) { await interaction.editReply("No results found"); diff --git a/src/helpers/CardSearchHelper.ts b/src/helpers/CardSearchHelper.ts index c0f6bd5..29014f7 100644 --- a/src/helpers/CardSearchHelper.ts +++ b/src/helpers/CardSearchHelper.ts @@ -11,16 +11,26 @@ interface ReturnedPage { embed: EmbedBuilder, row: ActionRowBuilder, attachment: AttachmentBuilder, + results: string[], } export default class CardSearchHelper { - public static async GenerateSearchPage(query: string, userid: string, page: number): Promise { + public static async GenerateSearchQuery(query: string, userid: string, pages: number): Promise { + AppLogger.LogSilly("CardSearchHelper/GenerateSearchQuery", `Parameters: query=${query}, userid=${userid}, pages=${pages}`); + const fzf = new Fuse(CoreClient.Cards.flatMap(x => x.cards), { keys: ["name"] }); - const entries = fzf.search(query); + const entries = fzf.search(query) + .splice(0, pages); - const entry = entries[page]; + const entry = entries[0]; + const results = entries + .flatMap(x => x.item.id); - if (!entry) return undefined; + if (!entry) { + AppLogger.LogVerbose("CardSearchHelper/GenerateSearchQuery", `Unable to find entry: ${query}`); + + return undefined; + } const card = CardDropHelperMetadata.GetCardByCardNumber(entry.item.id); @@ -32,7 +42,7 @@ export default class CardSearchHelper { try { image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.card.path)); } catch { - AppLogger.LogError("Commands/View", `Unable to fetch image for card ${card.card.id}.`); + AppLogger.LogError("CardSearchHelper/GenerateSearchQuery", `Unable to fetch image for card ${card.card.id}.`); return undefined; } @@ -47,16 +57,61 @@ export default class CardSearchHelper { const row = new ActionRowBuilder() .addComponents( new ButtonBuilder() - .setCustomId(`view ${page - 1} ${query}`) + .setCustomId(`view 0 ${results.join(" ")}`) .setLabel("Previous") .setStyle(ButtonStyle.Primary) - .setDisabled(page == 0), + .setDisabled(true), new ButtonBuilder() - .setCustomId(`view ${page + 1} ${query}`) + .setCustomId(`view 2 ${results.join(" ")}`) .setLabel("Next") .setStyle(ButtonStyle.Primary) - .setDisabled(page + 1 == entries.length)); + .setDisabled(pages == 1)); - return { embed, row, attachment }; + return { embed, row, attachment, results }; + } + + public static async GenerateSearchPageFromQuery(results: string[], userid: string, page: number): Promise { + const currentPageId = results[page - 1]; + + const card = CardDropHelperMetadata.GetCardByCardNumber(currentPageId); + + if (!card) { + AppLogger.LogError("CardSearchHelper/GenerateSearchPageFromQuery", `Unable to find card by id: ${currentPageId}.`); + + return undefined; + } + + let image: Buffer; + const imageFileName = card.card.path.split("/").pop()!; + + try { + image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.card.path)); + } catch { + AppLogger.LogError("CardSearchHelper/GenerateSearchPageFromQuery", `Unable to fetch image for card ${card.card.id}.`); + + return undefined; + } + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + const inventory = await Inventory.FetchOneByCardNumberAndUserId(userid, card.card.id); + const quantityClaimed = inventory?.Quantity ?? 0; + + const embed = CardDropHelperMetadata.GenerateDropEmbed(card, quantityClaimed, imageFileName); + + const row = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId(`view ${page - 1} ${results.join(" ")}`) + .setLabel("Previous") + .setStyle(ButtonStyle.Primary) + .setDisabled(page - 1 == 0), + new ButtonBuilder() + .setCustomId(`view ${page + 1} ${results.join(" ")}`) + .setLabel("Next") + .setStyle(ButtonStyle.Primary) + .setDisabled(page == results.length)); + + return { embed, row, attachment, results }; } } diff --git a/src/registry.ts b/src/registry.ts index 20787af..561d370 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -9,6 +9,7 @@ import Daily from "./commands/daily"; import Drop from "./commands/drop"; import Gdrivesync from "./commands/gdrivesync"; import Give from "./commands/give"; +import Id from "./commands/id"; import Inventory from "./commands/inventory"; import Resync from "./commands/resync"; import Sacrifice from "./commands/sacrifice"; @@ -39,6 +40,7 @@ export default class Registry { CoreClient.RegisterCommand("drop", new Drop()); CoreClient.RegisterCommand("gdrivesync", new Gdrivesync()); CoreClient.RegisterCommand("give", new Give()); + CoreClient.RegisterCommand("id", new Id()); CoreClient.RegisterCommand("inventory", new Inventory()); CoreClient.RegisterCommand("resync", new Resync()); CoreClient.RegisterCommand("sacrifice", new Sacrifice()); From d605eb5d59f73d2e1e33675eae7e4f26634aaad6 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 26 Aug 2024 10:07:02 +0100 Subject: [PATCH 15/59] Update dependency @types/node to v20.16.1 (#346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.16.0` -> `20.16.1`](https://renovatebot.com/diffs/npm/@types%2fnode/20.16.0/20.16.1) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/346 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index ecff5d5..84dbfa5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1259,9 +1259,9 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.16.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.0.tgz#02e5cd414f76bf345874ee65a1e5590d755d894f" - integrity sha512-vDxceJcoZhIVh67S568bm1UGZO0DX0hpplJZxzeXMKwIPLn190ec5RRxQ69BKhX44SUGIxxgMdDY557lGLKprQ== + version "20.16.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.1.tgz#0b44b15271d0e2191ca68faf1fbe506e06aed732" + integrity sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ== dependencies: undici-types "~6.19.2" @@ -6594,9 +6594,9 @@ undici-types@~6.13.0: integrity sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg== undici-types@~6.19.2: - version "6.19.6" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.6.tgz#e218c3df0987f4c0e0008ca00d6b6472d9b89b36" - integrity sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org== + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== undici@6.13.0: version "6.13.0" From 57e06be9af5f5e55c6eebbd2f78f800857fb9839 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 26 Aug 2024 10:08:20 +0100 Subject: [PATCH 16/59] Update dependency ts-jest to v29.2.5 (#347) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [ts-jest](https://kulshekhar.github.io/ts-jest) ([source](https://github.com/kulshekhar/ts-jest)) | dependencies | patch | [`29.2.4` -> `29.2.5`](https://renovatebot.com/diffs/npm/ts-jest/29.2.4/29.2.5) | --- ### Release Notes
kulshekhar/ts-jest (ts-jest) ### [`v29.2.5`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#2925-2024-08-23) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.2.4...v29.2.5)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/347 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/yarn.lock b/yarn.lock index 84dbfa5..cc19227 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1247,11 +1247,11 @@ integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/node@*": - version "22.2.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.2.0.tgz#7cf046a99f0ba4d628ad3088cb21f790df9b0c5b" - integrity sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ== + version "22.5.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.0.tgz#10f01fe9465166b4cab72e75f60d8b99d019f958" + integrity sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg== dependencies: - undici-types "~6.13.0" + undici-types "~6.19.2" "@types/node@16.9.1": version "16.9.1" @@ -1667,9 +1667,9 @@ array-union@^2.1.0: integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== async@^3.2.3: - version "3.2.5" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" - integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== asynckit@^0.4.0: version "0.4.0" @@ -1841,7 +1841,7 @@ browserslist@^4.22.2: node-releases "^2.0.14" update-browserslist-db "^1.0.13" -bs-logger@0.x: +bs-logger@^0.2.6: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== @@ -4550,7 +4550,7 @@ lodash.isequal@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== -lodash.memoize@4.x: +lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== @@ -4681,7 +4681,7 @@ make-dir@^4.0.0: dependencies: semver "^7.5.3" -make-error@1.x: +make-error@^1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -5908,7 +5908,7 @@ semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== -semver@^7.5.3, semver@^7.6.0: +semver@^7.5.3, semver@^7.6.0, semver@^7.6.3: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== @@ -6456,19 +6456,19 @@ ts-essentials@^10.0.0: integrity sha512-77FHNJEyysF9+1s4G6eejuA1lxw7uMchT3ZPy3CIbh7GIunffpshtM8pTe5G6N5dpOzNevqRHew859ceLWVBfw== ts-jest@^29.0.0: - version "29.2.4" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.2.4.tgz#38ccf487407d7a63054a72689f6f99b075e296e5" - integrity sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw== + version "29.2.5" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.2.5.tgz#591a3c108e1f5ebd013d3152142cb5472b399d63" + integrity sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA== dependencies: - bs-logger "0.x" + bs-logger "^0.2.6" ejs "^3.1.10" - fast-json-stable-stringify "2.x" + fast-json-stable-stringify "^2.1.0" jest-util "^29.0.0" json5 "^2.2.3" - lodash.memoize "4.x" - make-error "1.x" - semver "^7.5.3" - yargs-parser "^21.0.1" + lodash.memoize "^4.1.2" + make-error "^1.3.6" + semver "^7.6.3" + yargs-parser "^21.1.1" ts-mixer@^6.0.4: version "6.0.4" @@ -6588,11 +6588,6 @@ typescript@^5.0.0: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== -undici-types@~6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.13.0.tgz#e3e79220ab8c81ed1496b5812471afd7cf075ea5" - integrity sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg== - undici-types@~6.19.2: version "6.19.8" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" @@ -6955,7 +6950,7 @@ yargs-parser@^20.2.2: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-parser@^21.0.1, yargs-parser@^21.1.1: +yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== From 761c58fb106b4cd907851d42abaf8682d70dcbfd Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 31 Aug 2024 17:59:56 +0100 Subject: [PATCH 17/59] Upgrade package glob to v11 (#331) #311 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/331 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- package.json | 2 +- yarn.lock | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 690b0c7..f4289aa 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "dotenv": "^16.0.0", "express": "^4.18.2", "fuse.js": "^7.0.0", - "glob": "^10.3.10", + "glob": "^11.0.0", "jest": "^29.0.0", "jest-mock-extended": "^3.0.0", "jimp": "^0.22.12", diff --git a/yarn.lock b/yarn.lock index cc19227..d63470e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3254,6 +3254,18 @@ glob@^10.3.10: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" +glob@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.0.tgz#6031df0d7b65eaa1ccb9b29b5ced16cea658e77e" + integrity sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^4.0.1" + minimatch "^10.0.0" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^2.0.0" + glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -3976,6 +3988,15 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +jackspeak@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.0.1.tgz#9fca4ce961af6083e259c376e9e3541431f5287b" + integrity sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jake@^10.8.5: version "10.9.2" resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" @@ -4650,6 +4671,11 @@ lru-cache@^10.2.0: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +lru-cache@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.0.tgz#15d93a196f189034d7166caf9fe55e7384c98a21" + integrity sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -4807,6 +4833,13 @@ minimatch@9.0.3: dependencies: brace-expansion "^2.0.1" +minimatch@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b" + integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ== + dependencies: + brace-expansion "^2.0.1" + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -5437,6 +5470,14 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-scurry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" + integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== + dependencies: + lru-cache "^11.0.0" + minipass "^7.1.2" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" From a7b03d03552141ee547988327372a419ecf18599 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 2 Sep 2024 19:10:47 +0100 Subject: [PATCH 18/59] Update dependency @types/node to v20.16.3 (#351) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.16.1` -> `20.16.3`](https://renovatebot.com/diffs/npm/@types%2fnode/20.16.1/20.16.3) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/351 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index d63470e..0ade6e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1259,9 +1259,9 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.16.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.1.tgz#0b44b15271d0e2191ca68faf1fbe506e06aed732" - integrity sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ== + version "20.16.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.3.tgz#7b4f9a37091cf03a0c2561bf76a9a55f03f4f523" + integrity sha512-/wdGiWRkMOm53gAsSyFMXFZHbVg7C6CbkrzHNpaHoYfsUWPg7m6ZRKtvQjgvQ9i8WT540a3ydRlRQbxjY30XxQ== dependencies: undici-types "~6.19.2" From 21d11afd31da9a95c72f1d4f25180aade319a5d5 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 2 Sep 2024 19:12:02 +0100 Subject: [PATCH 19/59] Update dependency winston to v3.14.2 (#352) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [winston](https://github.com/winstonjs/winston) | dependencies | minor | [`3.13.1` -> `3.14.2`](https://renovatebot.com/diffs/npm/winston/3.13.1/3.14.2) | --- ### Release Notes
winstonjs/winston (winston) ### [`v3.14.2`](https://github.com/winstonjs/winston/releases/tag/v3.14.2) [Compare Source](https://github.com/winstonjs/winston/compare/v3.14.1...v3.14.2) - Move initialization to constructor ([#​2503](https://github.com/winstonjs/winston/issues/2503)) [`2458ba6`](https://github.com/winstonjs/winston/commit/2458ba6) ### [`v3.14.1`](https://github.com/winstonjs/winston/releases/tag/v3.14.1) [Compare Source](https://github.com/winstonjs/winston/compare/v3.14.0...v3.14.1) - Save a reference to console methods in console transport ([#​2498](https://github.com/winstonjs/winston/issues/2498)) [`e82752f`](https://github.com/winstonjs/winston/commit/e82752f) - Add `forceConsole` to `ConsoleTransportOptions` ([#​2496](https://github.com/winstonjs/winston/issues/2496)) [`4ff0538`](https://github.com/winstonjs/winston/commit/4ff0538) - Bump mocha from 10.6.0 to 10.7.0 ([#​2489](https://github.com/winstonjs/winston/issues/2489)) [`62acaad`](https://github.com/winstonjs/winston/commit/62acaad) - Update readme with forceConsole info ([#​2493](https://github.com/winstonjs/winston/issues/2493)) [`b2b79af`](https://github.com/winstonjs/winston/commit/b2b79af) ### [`v3.14.0`](https://github.com/winstonjs/winston/releases/tag/v3.14.0) [Compare Source](https://github.com/winstonjs/winston/compare/v3.13.1...v3.14.0) - Add option forceConsole ([#​2276](https://github.com/winstonjs/winston/issues/2276)) [`b2098fd`](https://github.com/winstonjs/winston/commit/b2098fd) - Set \_rotate false on emit 'rotate' false ([#​2457](https://github.com/winstonjs/winston/issues/2457)) [`1719275`](https://github.com/winstonjs/winston/commit/1719275) - Bump [@​babel/core](https://github.com/babel/core) from 7.24.7 to 7.24.9 ([#​2485](https://github.com/winstonjs/winston/issues/2485)) [`d2859f3`](https://github.com/winstonjs/winston/commit/d2859f3) - Bump [@​babel/preset-env](https://github.com/babel/preset-env) from 7.24.7 to 7.24.8 ([#​2487](https://github.com/winstonjs/winston/issues/2487)) [`71e4bb1`](https://github.com/winstonjs/winston/commit/71e4bb1) - fix: readme ([#​2488](https://github.com/winstonjs/winston/issues/2488)) [`0cb8c7c`](https://github.com/winstonjs/winston/commit/0cb8c7c)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/352 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0ade6e9..d1ca4fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5913,9 +5913,9 @@ safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-stable-stringify@^2.3.1: - version "2.4.3" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" - integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + version "2.5.0" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" + integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== "safer-buffer@>= 2.1.2 < 3": version "2.1.2" @@ -6840,9 +6840,9 @@ winston-transport@^4.7.0: triple-beam "^1.3.0" winston@^3.11.0: - version "3.13.1" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.13.1.tgz#53ddadb9c2332eb12cff8306413b3480dc82b6c3" - integrity sha512-SvZit7VFNvXRzbqGHsv5KSmgbEYR5EiQfDAL9gxYkRqa934Hnk++zze0wANKtMHcy/gI4W/3xmSDwlhf865WGw== + version "3.14.2" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.14.2.tgz#94ce5fd26d374f563c969d12f0cd9c641065adab" + integrity sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg== dependencies: "@colors/colors" "^1.6.0" "@dabh/diagnostics" "^2.0.2" From ea0ca170446fd51cba35935a38c43a0344b5a67e Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 11 Sep 2024 17:54:46 +0100 Subject: [PATCH 20/59] Update dependency @types/node to v20.16.5 (#356) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.16.3` -> `20.16.5`](https://renovatebot.com/diffs/npm/@types%2fnode/20.16.3/20.16.5) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/356 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index d1ca4fc..dacc21c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1259,9 +1259,9 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.16.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.3.tgz#7b4f9a37091cf03a0c2561bf76a9a55f03f4f523" - integrity sha512-/wdGiWRkMOm53gAsSyFMXFZHbVg7C6CbkrzHNpaHoYfsUWPg7m6ZRKtvQjgvQ9i8WT540a3ydRlRQbxjY30XxQ== + version "20.16.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.5.tgz#d43c7f973b32ffdf9aa7bd4f80e1072310fd7a53" + integrity sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA== dependencies: undici-types "~6.19.2" From 8683c1e58ab8044aea915437d3a00bda6891d078 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 11 Sep 2024 17:56:29 +0100 Subject: [PATCH 21/59] Update dependency @discordjs/rest to v2.4.0 (#357) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@discordjs/rest](https://discord.js.org) ([source](https://github.com/discordjs/discord.js/tree/HEAD/packages/rest)) | dependencies | minor | [`2.3.0` -> `2.4.0`](https://renovatebot.com/diffs/npm/@discordjs%2frest/2.3.0/2.4.0) | --- ### Release Notes
discordjs/discord.js (@​discordjs/rest) ### [`v2.4.0`](https://github.com/discordjs/discord.js/blob/HEAD/packages/rest/CHANGELOG.md#discordjsrest240---2024-09-01) [Compare Source](https://github.com/discordjs/discord.js/compare/@discordjs/rest@2.3.0...@discordjs/rest@2.4.0) #### Bug Fixes - Correct base path for GIF stickers ([#​10330](https://github.com/discordjs/discord.js/issues/10330)) ([599ad3e](https://github.com/discordjs/discord.js/commit/599ad3eab556463bcde60f8941d0354475cde16b)) #### Features - **User:** Add `avatarDecorationData` ([#​9888](https://github.com/discordjs/discord.js/issues/9888)) ([3b5c600](https://github.com/discordjs/discord.js/commit/3b5c600b9e3f8d40ed48f02e3c9acec7433f1cc3))
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/357 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 55 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/yarn.lock b/yarn.lock index dacc21c..94d05b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -343,6 +343,11 @@ resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-2.1.0.tgz#f327d944ab2dcf9a1f674470a481f78a120a5e3b" integrity sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw== +"@discordjs/collection@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-2.1.1.tgz#901917bc538c12b9c3613036d317847baee08cae" + integrity sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg== + "@discordjs/formatters@^0.4.0": version "0.4.0" resolved "https://registry.yarnpkg.com/@discordjs/formatters/-/formatters-0.4.0.tgz#066a2c2163b26ac066e6f621f17445be9690c6a9" @@ -351,25 +356,30 @@ discord-api-types "0.37.83" "@discordjs/rest@^2.0.0", "@discordjs/rest@^2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@discordjs/rest/-/rest-2.3.0.tgz#06d37c7fb54a9be61134b5bbb201abd760343472" - integrity sha512-C1kAJK8aSYRv3ZwMG8cvrrW4GN0g5eMdP8AuN8ODH5DyOCbHgJspze1my3xHOAgwLJdKUbWNVyAeJ9cEdduqIg== + version "2.4.0" + resolved "https://registry.yarnpkg.com/@discordjs/rest/-/rest-2.4.0.tgz#63bfc816af58af844914e3589d7eae609cd199b5" + integrity sha512-Xb2irDqNcq+O8F0/k/NaDp7+t091p+acb51iA4bCKfIn+WFWd6HrNvcsSbMMxIR9NjcMZS6NReTKygqiQN+ntw== dependencies: - "@discordjs/collection" "^2.1.0" - "@discordjs/util" "^1.1.0" - "@sapphire/async-queue" "^1.5.2" + "@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.2.4" - discord-api-types "0.37.83" + "@vladfrangu/async_event_emitter" "^2.4.6" + discord-api-types "0.37.97" magic-bytes.js "^1.10.0" - tslib "^2.6.2" - undici "6.13.0" + tslib "^2.6.3" + undici "6.19.8" "@discordjs/util@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@discordjs/util/-/util-1.1.0.tgz#dcffd2b61aab8eadd66bea67811bc34fc769bb2a" integrity sha512-IndcI5hzlNZ7GS96RV3Xw1R2kaDuXEp7tRIy/KlhidpN/BQ1qh1NZt3377dMLTa44xDUNKT7hnXkA/oUAzD/lg== +"@discordjs/util@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@discordjs/util/-/util-1.1.1.tgz#bafcde0faa116c834da1258d78ec237080bbab29" + integrity sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g== + "@discordjs/ws@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@discordjs/ws/-/ws-1.1.1.tgz#bffbfd46838258ab09054ed98ddef1a36f6507a3" @@ -1036,6 +1046,11 @@ resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.5.2.tgz#2982dce16e5b8b1ea792604d20c23c0585877b97" integrity sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg== +"@sapphire/async-queue@^1.5.3": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.5.3.tgz#03cd2a2f3665068f314736bdc56eee2025352422" + integrity sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w== + "@sapphire/shapeshift@^3.9.7": version "3.9.7" resolved "https://registry.yarnpkg.com/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz#43e23243cac8a0c046bf1e73baf3dbf407d33a0c" @@ -1464,6 +1479,11 @@ resolved "https://registry.yarnpkg.com/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz#d3537432c6db6444680a596271dff8ea407343b3" integrity sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug== +"@vladfrangu/async_event_emitter@^2.4.6": + version "2.4.6" + resolved "https://registry.yarnpkg.com/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.6.tgz#508b6c45b03f917112a9008180b308ba0e4d1805" + integrity sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA== + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -2542,6 +2562,11 @@ discord-api-types@0.37.83: resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.83.tgz#a22a799729ceded8176ea747157837ddf4708b1f" integrity sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA== +discord-api-types@0.37.97: + version "0.37.97" + resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.97.tgz#d658573f726ad179261d538dbad4e7e8eca48d11" + integrity sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA== + discord.js@^14.15.3: version "14.15.3" resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.15.3.tgz#b2a67a1a4ef192be498fb8b6784224a42906f1be" @@ -6526,6 +6551,11 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.6.3: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -6639,6 +6669,11 @@ undici@6.13.0: resolved "https://registry.yarnpkg.com/undici/-/undici-6.13.0.tgz#7edbf4b7f3aac5f8a681d515151bf55cb3589d72" integrity sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw== +undici@6.19.8: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.19.8.tgz#002d7c8a28f8cc3a44ff33c3d4be4d85e15d40e1" + integrity sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g== + unicorn-magic@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.1.0.tgz#1bb9a51c823aaf9d73a8bfcd3d1a23dde94b0ce4" From 52c93c7803fa8eb3ed226789d7b200f18049d6dc Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 15 Sep 2024 16:55:18 +0100 Subject: [PATCH 22/59] Ability to trade multiple cards at once (#360) - Add the ability to trade multiple cards at once using an optional quantity field #338 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/360 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/buttonEvents/Trade.ts | 28 ++++++++++++--------- src/commands/trade.ts | 35 ++++++++++++++++++-------- src/database/entities/app/Inventory.ts | 4 +++ 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/buttonEvents/Trade.ts b/src/buttonEvents/Trade.ts index d0d7b38..fb8449d 100644 --- a/src/buttonEvents/Trade.ts +++ b/src/buttonEvents/Trade.ts @@ -28,8 +28,10 @@ export default class Trade extends ButtonEvent { const user2CardNumber = interaction.customId.split(" ")[5]; const expiry = interaction.customId.split(" ")[6]; const timeoutId = interaction.customId.split(" ")[7]; + const user1Quantity = Number(interaction.customId.split(" ")[8]) || 1; + const user2Quantity = Number(interaction.customId.split(" ")[9]) || 1; - AppLogger.LogSilly("Button/Trade/AcceptTrade", `Parameters: user1UserId=${user1UserId}, user2UserId=${user2UserId}, user1CardNumber=${user1CardNumber}, user2CardNumber=${user2CardNumber}, expiry=${expiry}, timeoutId=${timeoutId}`); + AppLogger.LogSilly("Button/Trade/AcceptTrade", `Parameters: user1UserId=${user1UserId}, user2UserId=${user2UserId}, user1CardNumber=${user1CardNumber}, user2CardNumber=${user2CardNumber}, expiry=${expiry}, timeoutId=${timeoutId} user1Quantity=${user1Quantity} user2Quantity=${user2Quantity}`); const expiryDate = new Date(expiry); @@ -67,13 +69,13 @@ export default class Trade extends ButtonEvent { return; } - if (user1UserInventory1.Quantity < 1 || user2UserInventory1.Quantity < 1) { + if (user1UserInventory1.Quantity < user1Quantity || user2UserInventory1.Quantity < user2Quantity) { await interaction.reply("One or more of the items you are trying to trade does not exist."); return; } - user1UserInventory1.SetQuantity(user1UserInventory1.Quantity - 1); - user2UserInventory1.SetQuantity(user2UserInventory1.Quantity - 1); + user1UserInventory1.RemoveQuantity(user1Quantity); + user2UserInventory1.RemoveQuantity(user2Quantity); await user1UserInventory1.Save(Inventory, user1UserInventory1); await user2UserInventory1.Save(Inventory, user2UserInventory1); @@ -82,15 +84,15 @@ export default class Trade extends ButtonEvent { let user2UserInventory2 = await Inventory.FetchOneByCardNumberAndUserId(user2UserId, user1CardNumber); if (!user1UserInventory2) { - user1UserInventory2 = new Inventory(user1UserId, user1CardNumber, 1); + user1UserInventory2 = new Inventory(user1UserId, user2CardNumber, user2Quantity); } else { - user1UserInventory2.SetQuantity(user1UserInventory2.Quantity + 1); + user1UserInventory2.AddQuantity(user2Quantity); } if (!user2UserInventory2) { - user2UserInventory2 = new Inventory(user2UserId, user2CardNumber, 1); + user2UserInventory2 = new Inventory(user2UserId, user1CardNumber, user1Quantity); } else { - user2UserInventory2.SetQuantity(user2UserInventory2.Quantity + 1); + user2UserInventory2.AddQuantity(user1Quantity); } await user1UserInventory2.Save(Inventory, user1UserInventory2); @@ -106,12 +108,12 @@ export default class Trade extends ButtonEvent { .addFields([ { name: `${user1User.username} Receives`, - value: `${user2Item.id}: ${user2Item.name}`, + value: `${user2Item.id}: ${user2Item.name} x${user2Quantity}`, inline: true, }, { name: `${user2User.username} Receives`, - value: `${user1Item.id}: ${user1Item.name}`, + value: `${user1Item.id}: ${user1Item.name} x${user1Quantity}`, inline: true, }, { @@ -144,6 +146,8 @@ export default class Trade extends ButtonEvent { const user2CardNumber = interaction.customId.split(" ")[5]; // No need to get expiry date const timeoutId = interaction.customId.split(" ")[7]; + const user1Quantity = Number(interaction.customId.split(" ")[8]) || 1; + const user2Quantity = Number(interaction.customId.split(" ")[9]) || 1; AppLogger.LogSilly("Button/Trade/DeclineTrade", `Parameters: user1UserId=${user1UserId}, user2UserId=${user2UserId}, user1CardNumber=${user1CardNumber}, user2CardNumber=${user2CardNumber}, timeoutId=${timeoutId}`); @@ -178,12 +182,12 @@ export default class Trade extends ButtonEvent { .addFields([ { name: `${user1User.username} Receives`, - value: `${user2Item.id}: ${user2Item.name}`, + value: `${user2Item.id}: ${user2Item.name} x${user2Quantity}`, inline: true, }, { name: `${user2User.username} Receives`, - value: `${user1Item.id}: ${user1Item.name}`, + value: `${user1Item.id}: ${user1Item.name} x${user1Quantity}`, inline: true, }, { diff --git a/src/commands/trade.ts b/src/commands/trade.ts index 569e88f..fcd312a 100644 --- a/src/commands/trade.ts +++ b/src/commands/trade.ts @@ -26,13 +26,26 @@ export default class Trade extends Command { x .setName("receive") .setDescription("Item to receive") - .setRequired(true)); + .setRequired(true)) + .addNumberOption(x => + x + .setName("givequantity") + .setDescription("Amount to give")) + .addNumberOption(x => + x + .setName("receivequantity") + .setDescription("Amount to receive")); } public override async execute(interaction: CommandInteraction) { const user = interaction.options.get("user", true).user!; const give = interaction.options.get("give", true); const receive = interaction.options.get("receive", true); + const givequantityInput = interaction.options.get("givequantity")?.value ?? 1; + const receivequantityInput = interaction.options.get("receivequantity")?.value ?? 1; + + const givequantity = Number(givequantityInput) || 1; + const receivequantity = Number(receivequantityInput) || 1; AppLogger.LogSilly("Commands/Trade", `Parameters: user=${user.id}, give=${give.value}, receive=${receive.value}`); @@ -44,12 +57,12 @@ export default class Trade extends Command { const user1ItemEntity = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, give.value!.toString()); const user2ItemEntity = await Inventory.FetchOneByCardNumberAndUserId(user.id, receive.value!.toString()); - if (!user1ItemEntity) { + if (!user1ItemEntity || user1ItemEntity.Quantity < givequantity) { await interaction.reply("You do not have the item you are trying to trade."); return; } - if (!user2ItemEntity) { + if (!user2ItemEntity || user2ItemEntity.Quantity < receivequantity) { await interaction.reply("The user you are trying to trade with does not have the item you are trying to trade for."); return; } @@ -78,12 +91,12 @@ export default class Trade extends Command { .addFields([ { name: `${interaction.user.username} Receives`, - value: `${user2Item.id}: ${user2Item.name}`, + value: `${user2Item.id}: ${user2Item.name} x${receivequantity}`, inline: true, }, { name: `${user.username} Receives`, - value: `${user1Item.id}: ${user1Item.name}`, + value: `${user1Item.id}: ${user1Item.name} x${givequantity}`, inline: true, }, { @@ -92,16 +105,16 @@ export default class Trade extends Command { } ]); - const timeoutId = setTimeout(async () => this.autoDecline(interaction, interaction.user.username, user.username, user1Item.id, user2Item.id, user1Item.name, user2Item.name), 1000 * 60 * 15); // 15 minutes + const timeoutId = setTimeout(async () => this.autoDecline(interaction, interaction.user.username, user.username, user1Item.id, user2Item.id, user1Item.name, user2Item.name, givequantity, receivequantity), 1000 * 60 * 15); // 15 minutes const row = new ActionRowBuilder() .addComponents([ new ButtonBuilder() - .setCustomId(`trade accept ${interaction.user.id} ${user.id} ${user1Item.id} ${user2Item.id} ${expiry} ${timeoutId}`) + .setCustomId(`trade accept ${interaction.user.id} ${user.id} ${user1Item.id} ${user2Item.id} ${expiry} ${timeoutId} ${givequantity} ${receivequantity}`) .setLabel("Accept") .setStyle(ButtonStyle.Success), new ButtonBuilder() - .setCustomId(`trade decline ${interaction.user.id} ${user.id} ${user1Item.id} ${user2Item.id} ${expiry} ${timeoutId}`) + .setCustomId(`trade decline ${interaction.user.id} ${user.id} ${user1Item.id} ${user2Item.id} ${expiry} ${timeoutId} ${givequantity} ${receivequantity}`) .setLabel("Decline") .setStyle(ButtonStyle.Danger), ]); @@ -109,7 +122,7 @@ export default class Trade extends Command { await interaction.reply({ content: `${user}`, embeds: [ tradeEmbed ], components: [ row ] }); } - private async autoDecline(interaction: CommandInteraction, user1Username: string, user2Username: string, user1CardNumber: string, user2CardNumber: string, user1CardName: string, user2CardName: string) { + private async autoDecline(interaction: CommandInteraction, user1Username: string, user2Username: string, user1CardNumber: string, user2CardNumber: string, user1CardName: string, user2CardName: string, user1Quantity: number, user2Quantity: number) { AppLogger.LogSilly("Commands/Trade/AutoDecline", `Auto declining trade between ${user1Username} and ${user2Username}`); const tradeEmbed = new EmbedBuilder() @@ -120,12 +133,12 @@ export default class Trade extends Command { .addFields([ { name: `${user1Username} Receives`, - value: `${user2CardNumber}: ${user2CardName}`, + value: `${user2CardNumber}: ${user2CardName} x${user2Quantity}`, inline: true, }, { name: `${user2Username} Receives`, - value: `${user1CardNumber}: ${user1CardName}`, + value: `${user1CardNumber}: ${user1CardName} x${user1Quantity}`, inline: true, }, { diff --git a/src/database/entities/app/Inventory.ts b/src/database/entities/app/Inventory.ts index 7d659fe..c780dad 100644 --- a/src/database/entities/app/Inventory.ts +++ b/src/database/entities/app/Inventory.ts @@ -35,6 +35,10 @@ export default class Inventory extends AppBaseEntity { this.Quantity -= amount; } + public AddQuantity(amount: number) { + this.Quantity += amount; + } + public AddClaim(claim: Claim) { this.Claims.push(claim); } From c0e9378813caf289b9137096db253785746f229c Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 15 Sep 2024 16:57:25 +0100 Subject: [PATCH 23/59] Add ability to sacrifice multiple cards at once (#354) - The `/sacrifice` command now accepts an optional parameter to be able to specify the quantity - The `Sacrifice` button event now accepts a parameter to specify the quantity, this one is required but the command will default it to 1 if not supplied #337 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/354 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/buttonEvents/Sacrifice.ts | 24 +++++++++++++++++++----- src/commands/sacrifice.ts | 21 +++++++++++++++++---- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/buttonEvents/Sacrifice.ts b/src/buttonEvents/Sacrifice.ts index a82ba81..463ca1f 100644 --- a/src/buttonEvents/Sacrifice.ts +++ b/src/buttonEvents/Sacrifice.ts @@ -23,6 +23,7 @@ export default class Sacrifice extends ButtonEvent { private async confirm(interaction: ButtonInteraction) { const userId = interaction.customId.split(" ")[2]; const cardNumber = interaction.customId.split(" ")[3]; + const quantity = Number(interaction.customId.split(" ")[4]) || 1; if (userId != interaction.user.id) { await interaction.reply("Only the user who created this sacrifice can confirm it."); @@ -31,11 +32,16 @@ export default class Sacrifice extends ButtonEvent { const cardInInventory = await Inventory.FetchOneByCardNumberAndUserId(userId, cardNumber); - if (!cardInInventory) { + if (!cardInInventory || cardInInventory.Quantity == 0) { await interaction.reply("Unable to find card in inventory."); return; } + if (cardInInventory.Quantity < quantity) { + await interaction.reply("You can only sacrifice what you own."); + return; + } + const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); if (!cardData) { @@ -50,11 +56,11 @@ export default class Sacrifice extends ButtonEvent { return; } - cardInInventory.RemoveQuantity(1); + cardInInventory.RemoveQuantity(quantity); await cardInInventory.Save(Inventory, cardInInventory); - const cardValue = GetSacrificeAmount(cardData.card.type); + const cardValue = GetSacrificeAmount(cardData.card.type) * quantity; const cardRarityString = CardRarityToString(cardData.card.type); user.AddCurrency(cardValue); @@ -66,6 +72,7 @@ export default class Sacrifice extends ButtonEvent { `Series: ${cardData.series.name}`, `Rarity: ${cardRarityString}`, `Quantity Owned: ${cardInInventory.Quantity}`, + `Quantity To Sacrifice: ${quantity}`, `Sacrifice Amount: ${cardValue}`, ]; @@ -98,6 +105,7 @@ export default class Sacrifice extends ButtonEvent { private async cancel(interaction: ButtonInteraction) { const userId = interaction.customId.split(" ")[2]; const cardNumber = interaction.customId.split(" ")[3]; + const quantity = Number(interaction.customId.split(" ")[4]) || 1; if (userId != interaction.user.id) { await interaction.reply("Only the user who created this sacrifice can cancel it."); @@ -106,11 +114,16 @@ export default class Sacrifice extends ButtonEvent { const cardInInventory = await Inventory.FetchOneByCardNumberAndUserId(userId, cardNumber); - if (!cardInInventory) { + if (!cardInInventory || cardInInventory.Quantity == 0) { await interaction.reply("Unable to find card in inventory."); return; } + if (cardInInventory.Quantity < quantity) { + await interaction.reply("You can only sacrifice what you own."); + return; + } + const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); if (!cardData) { @@ -118,7 +131,7 @@ export default class Sacrifice extends ButtonEvent { return; } - const cardValue = GetSacrificeAmount(cardData.card.type); + const cardValue = GetSacrificeAmount(cardData.card.type) * quantity; const cardRarityString = CardRarityToString(cardData.card.type); const description = [ @@ -126,6 +139,7 @@ export default class Sacrifice extends ButtonEvent { `Series: ${cardData.series.name}`, `Rarity: ${cardRarityString}`, `Quantity Owned: ${cardInInventory.Quantity}`, + `Quantity To Sacrifice: ${quantity}`, `Sacrifice Amount: ${cardValue}`, ]; diff --git a/src/commands/sacrifice.ts b/src/commands/sacrifice.ts index 4d1c51a..9683714 100644 --- a/src/commands/sacrifice.ts +++ b/src/commands/sacrifice.ts @@ -16,11 +16,18 @@ export default class Sacrifice extends Command { x .setName("cardnumber") .setDescription("The card to sacrifice from your inventory") - .setRequired(true)); + .setRequired(true)) + .addNumberOption(x => + x + .setName("quantity") + .setDescription("The amount to sacrifice (default 1)")); } public override async execute(interaction: CommandInteraction): Promise { const cardnumber = interaction.options.get("cardnumber", true); + const quantityInput = interaction.options.get("quantity")?.value ?? 1; + + const quantity = Number(quantityInput) || 1; const cardInInventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, cardnumber.value! as string); @@ -29,6 +36,11 @@ export default class Sacrifice extends Command { return; } + if (cardInInventory.Quantity < quantity) { + await interaction.reply(`You can only sacrifice what you own! You have ${cardInInventory.Quantity} of this card`); + return; + } + const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardnumber.value! as string); if (!cardData) { @@ -36,7 +48,7 @@ export default class Sacrifice extends Command { return; } - const cardValue = GetSacrificeAmount(cardData.card.type); + const cardValue = GetSacrificeAmount(cardData.card.type) * quantity; const cardRarityString = CardRarityToString(cardData.card.type); const description = [ @@ -44,6 +56,7 @@ export default class Sacrifice extends Command { `Series: ${cardData.series.name}`, `Rarity: ${cardRarityString}`, `Quantity Owned: ${cardInInventory.Quantity}`, + `Quantity To Sacrifice: ${quantity}`, `Sacrifice Amount: ${cardValue}`, ]; @@ -56,11 +69,11 @@ export default class Sacrifice extends Command { const row = new ActionRowBuilder() .addComponents([ new ButtonBuilder() - .setCustomId(`sacrifice confirm ${interaction.user.id} ${cardnumber.value!}`) + .setCustomId(`sacrifice confirm ${interaction.user.id} ${cardnumber.value!} ${quantity}`) .setLabel("Confirm") .setStyle(ButtonStyle.Success), new ButtonBuilder() - .setCustomId(`sacrifice cancel ${interaction.user.id} ${cardnumber.value!}`) + .setCustomId(`sacrifice cancel ${interaction.user.id} ${cardnumber.value!} ${quantity}`) .setLabel("Cancel") .setStyle(ButtonStyle.Secondary), ]); From 2263871b3b61e583fcc79bf0be911576cd5c2e53 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 16 Sep 2024 18:49:24 +0100 Subject: [PATCH 24/59] Update dependency @types/jest to v29.5.13 (#361) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/jest) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest)) | dependencies | patch | [`29.5.12` -> `29.5.13`](https://renovatebot.com/diffs/npm/@types%2fjest/29.5.12/29.5.13) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/361 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/yarn.lock b/yarn.lock index 94d05b4..b35d70d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,7 +10,7 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.24.6": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.24.6": version "7.24.6" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.6.tgz#ab88da19344445c3d8889af2216606d3329f3ef2" integrity sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA== @@ -18,6 +18,14 @@ "@babel/highlight" "^7.24.6" picocolors "^1.0.0" +"@babel/code-frame@^7.12.13": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== + dependencies: + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" + "@babel/compat-data@^7.24.6": version "7.24.6" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.6.tgz#b3600217688cabb26e25f8e467019e66d71b7ae2" @@ -127,10 +135,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz#28583c28b15f2a3339cfafafeaad42f9a0e828df" integrity sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q== -"@babel/helper-validator-identifier@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz#08bb6612b11bdec78f3feed3db196da682454a5e" - integrity sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw== +"@babel/helper-validator-identifier@^7.24.6", "@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== "@babel/helper-validator-option@^7.24.6": version "7.24.6" @@ -145,12 +153,12 @@ "@babel/template" "^7.24.6" "@babel/types" "^7.24.6" -"@babel/highlight@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.6.tgz#6d610c1ebd2c6e061cade0153bf69b0590b7b3df" - integrity sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ== +"@babel/highlight@^7.24.6", "@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== dependencies: - "@babel/helper-validator-identifier" "^7.24.6" + "@babel/helper-validator-identifier" "^7.24.7" chalk "^2.4.2" js-tokens "^4.0.0" picocolors "^1.0.0" @@ -1237,9 +1245,9 @@ "@types/istanbul-lib-report" "*" "@types/jest@^29.0.0": - version "29.5.12" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" - integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== + version "29.5.13" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.13.tgz#8bc571659f401e6a719a7bf0dbcb8b78c71a8adc" + integrity sha512-wd+MVEZCHt23V0/L642O5APvspWply/rGY5BcW4SUETo2UzPU3Z26qr8jC2qxpimI2jjx9h7+2cj2FwIr01bXg== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -1262,9 +1270,9 @@ integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/node@*": - version "22.5.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.0.tgz#10f01fe9465166b4cab72e75f60d8b99d019f958" - integrity sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg== + version "22.5.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.5.tgz#52f939dd0f65fc552a4ad0b392f3c466cc5d7a44" + integrity sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA== dependencies: undici-types "~6.19.2" @@ -4775,9 +4783,9 @@ methods@^1.1.2, methods@~1.1.2: integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== micromatch@^4.0.4: - version "4.0.7" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5" - integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: braces "^3.0.3" picomatch "^2.3.1" @@ -5525,7 +5533,12 @@ phin@^3.7.1: dependencies: centra "^2.7.0" -picocolors@^1.0.0, picocolors@^1.0.1: +picocolors@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== + +picocolors@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== From 5ebc5ff27c02727b7f432519c72a999259f5aa47 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 16 Sep 2024 18:50:58 +0100 Subject: [PATCH 25/59] Update dependency body-parser to v1.20.3 (#362) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [body-parser](https://github.com/expressjs/body-parser) | dependencies | patch | [`1.20.2` -> `1.20.3`](https://renovatebot.com/diffs/npm/body-parser/1.20.2/1.20.3) | --- ### Release Notes
expressjs/body-parser (body-parser) ### [`v1.20.3`](https://github.com/expressjs/body-parser/blob/HEAD/HISTORY.md#1203--2024-09-10) [Compare Source](https://github.com/expressjs/body-parser/compare/1.20.2...1.20.3) \=================== - deps: qs@6.13.0 - add `depth` option to customize the depth level in the parser - IMPORTANT: The default `depth` level for parsing URL-encoded data is now `32` (previously was `Infinity`)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/362 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index b35d70d..270a68f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1798,7 +1798,7 @@ bmp-js@^0.1.0: resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" integrity sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw== -body-parser@1.20.2, body-parser@^1.20.2: +body-parser@1.20.2: version "1.20.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== @@ -1816,6 +1816,24 @@ body-parser@1.20.2, body-parser@^1.20.2: type-is "~1.6.18" unpipe "1.0.0" +body-parser@^1.20.2: + version "1.20.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" + integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.13.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + boxen@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.1.1.tgz#f9ba525413c2fec9cdb88987d835c4f7cad9c8f4" @@ -5166,9 +5184,9 @@ object-hash@^3.0.0: integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== object-inspect@^1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== omggif@^1.0.10, omggif@^1.0.9: version "1.0.10" @@ -5666,6 +5684,13 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" +qs@6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== + dependencies: + side-channel "^1.0.6" + qs@^6.9.1: version "6.12.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.1.tgz#39422111ca7cbdb70425541cba20c7d7b216599a" From 1762b525b29b0ca7eeab1b5d5b3fdf9fbe9fd1f4 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 21 Sep 2024 18:09:24 +0100 Subject: [PATCH 26/59] Add dropdown to /inventory command for quick navigation (#365) - Add ability to handle dropdown menus with the bot - Add a dropdown to the inventoryhelper - Add handler for the dropdown to navigate to that page #344 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/365 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/bot.ts | 1 + src/buttonEvents/Inventory.ts | 4 +- src/client/client.ts | 23 ++++++++++ src/client/events.ts | 6 +++ .../interactionCreate/StringDropdown.ts | 29 +++++++++++++ src/commands/inventory.ts | 2 +- src/contracts/StringDropdownEventItem.ts | 10 +++++ src/helpers/InventoryHelper.ts | 23 ++++++++-- src/registry.ts | 7 +++ src/stringDropdowns/Inventory.ts | 43 +++++++++++++++++++ src/type/stringDropdownEvent.ts | 5 +++ 11 files changed, 146 insertions(+), 7 deletions(-) create mode 100644 src/client/interactionCreate/StringDropdown.ts create mode 100644 src/contracts/StringDropdownEventItem.ts create mode 100644 src/stringDropdowns/Inventory.ts create mode 100644 src/type/stringDropdownEvent.ts diff --git a/src/bot.ts b/src/bot.ts index e5e25a3..871b927 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -38,6 +38,7 @@ const client = new CoreClient([ Registry.RegisterCommands(); Registry.RegisterButtonEvents(); +Registry.RegisterStringDropdownEvents(); if (!existsSync(`${process.env.DATA_DIR}/cards`) && process.env.GDRIVESYNC_AUTO && process.env.GDRIVESYNC_AUTO == "true") { console.log("Card directory not found, syncing..."); diff --git a/src/buttonEvents/Inventory.ts b/src/buttonEvents/Inventory.ts index 8356305..73c7019 100644 --- a/src/buttonEvents/Inventory.ts +++ b/src/buttonEvents/Inventory.ts @@ -11,7 +11,7 @@ export default class Inventory extends ButtonEvent { const page = interaction.customId.split(" ")[2]; AppLogger.LogSilly("Button/Inventory", `Parameters: userid=${userid}, page=${page}`); - + await interaction.deferUpdate(); const member = interaction.guild.members.cache.find(x => x.id == userid) || await interaction.guild.members.fetch(userid); @@ -34,7 +34,7 @@ export default class Inventory extends ButtonEvent { await interaction.editReply({ files: [ embed.image ], embeds: [ embed.embed ], - components: [ embed.row ], + components: [ embed.row1, embed.row2 ], }); } catch (e) { AppLogger.LogError("Button/Inventory", `Error generating inventory page for ${member.user.username} with id ${member.user.id}: ${e}`); diff --git a/src/client/client.ts b/src/client/client.ts index 117bdb9..87b496e 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -17,11 +17,14 @@ import AppLogger from "./appLogger"; import TimerHelper from "../helpers/TimerHelper"; import GiveCurrency from "../timers/GiveCurrency"; import PurgeClaims from "../timers/PurgeClaims"; +import StringDropdownEventItem from "../contracts/StringDropdownEventItem"; +import {StringDropdownEvent} from "../type/stringDropdownEvent"; export class CoreClient extends Client { private static _commandItems: ICommandItem[]; private static _eventExecutors: EventExecutors; private static _buttonEvents: IButtonEventItem[]; + private static _stringDropdowns: StringDropdownEventItem[]; private _events: Events; private _util: Util; @@ -45,6 +48,10 @@ export class CoreClient extends Client { return this._buttonEvents; } + public static get stringDropdowns(): StringDropdownEventItem[] { + return this._stringDropdowns; + } + constructor(intents: number[]) { super({ intents: intents }); dotenv.config(); @@ -59,6 +66,7 @@ export class CoreClient extends Client { CoreClient._commandItems = []; CoreClient._buttonEvents = []; + CoreClient._stringDropdowns = []; this._events = new Events(); this._util = new Util(); @@ -408,4 +416,19 @@ export class CoreClient extends Client { AppLogger.LogVerbose("Client", `Registered Button Event: ${buttonId}`); } } + + public static RegisterStringDropdownEvent(dropdownId: string, event: StringDropdownEvent, environment: Environment = Environment.All) { + const item: StringDropdownEventItem = { + DropdownId: dropdownId, + Event: event, + Environment: environment, + }; + + if ((environment & CoreClient.Environment) == CoreClient.Environment) { + CoreClient._stringDropdowns.push(item); + + AppLogger.LogVerbose("Client", `Registered String Dropdown Event: ${dropdownId}`); + } + } } + diff --git a/src/client/events.ts b/src/client/events.ts index f02fb9c..5f61da5 100644 --- a/src/client/events.ts +++ b/src/client/events.ts @@ -3,6 +3,7 @@ import ChatInputCommand from "./interactionCreate/ChatInputCommand"; import Button from "./interactionCreate/Button"; import AppLogger from "./appLogger"; import NewUserDiscovery from "./interactionCreate/middleware/NewUserDiscovery"; +import StringDropdown from "./interactionCreate/StringDropdown"; export class Events { public async onInteractionCreate(interaction: Interaction) { @@ -19,6 +20,11 @@ export class Events { AppLogger.LogVerbose("Client", `Button: ${interaction.customId}`); Button.onButtonClicked(interaction); } + + if (interaction.isStringSelectMenu()) { + AppLogger.LogVerbose("Client", `StringDropdown: ${interaction.customId}`); + StringDropdown.onStringDropdownSelected(interaction); + } } // Emit when bot is logged in and ready to use diff --git a/src/client/interactionCreate/StringDropdown.ts b/src/client/interactionCreate/StringDropdown.ts new file mode 100644 index 0000000..608b81b --- /dev/null +++ b/src/client/interactionCreate/StringDropdown.ts @@ -0,0 +1,29 @@ +import {StringSelectMenuInteraction} from "discord.js"; +import {CoreClient} from "../client"; +import AppLogger from "../appLogger"; + +export default class StringDropdown { + public static async onStringDropdownSelected(interaction: StringSelectMenuInteraction) { + if (!interaction.isStringSelectMenu()) return; + + const item = CoreClient.stringDropdowns.find(x => x.DropdownId == interaction.customId.split(" ")[0]); + + if (!item) { + AppLogger.LogVerbose("StringDropdown", `Event not found: ${interaction.customId}`); + + await interaction.reply("Event not found"); + return; + } + + try { + AppLogger.LogDebug("StringDropdown", `Executing ${interaction.customId}`); + + item.Event.execute(interaction); + } catch (e) { + AppLogger.LogError("StringDropdown", `Error occurred while executing event: ${interaction.customId}`); + AppLogger.LogError("StringDropdown", e as string); + + await interaction.reply("An error occurred while executing the event"); + } + } +} diff --git a/src/commands/inventory.ts b/src/commands/inventory.ts index 8d2ef2c..deb4735 100644 --- a/src/commands/inventory.ts +++ b/src/commands/inventory.ts @@ -47,7 +47,7 @@ export default class Inventory extends Command { await interaction.followUp({ files: [ embed.image ], embeds: [ embed.embed ], - components: [ embed.row ], + components: [ embed.row1, embed.row2 ], }); } catch (e) { AppLogger.LogError("Commands/Inventory", e as string); diff --git a/src/contracts/StringDropdownEventItem.ts b/src/contracts/StringDropdownEventItem.ts new file mode 100644 index 0000000..1a7b0aa --- /dev/null +++ b/src/contracts/StringDropdownEventItem.ts @@ -0,0 +1,10 @@ +import {Environment} from "../constants/Environment"; +import {StringDropdownEvent} from "../type/stringDropdownEvent"; + +interface StringDropdownEventItem { + DropdownId: string, + Event: StringDropdownEvent, + Environment: Environment, +} + +export default StringDropdownEventItem; diff --git a/src/helpers/InventoryHelper.ts b/src/helpers/InventoryHelper.ts index 8b8ffa1..3a7fbff 100644 --- a/src/helpers/InventoryHelper.ts +++ b/src/helpers/InventoryHelper.ts @@ -1,4 +1,4 @@ -import { ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; +import { ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder } from "discord.js"; import Inventory from "../database/entities/app/Inventory"; import { CoreClient } from "../client/client"; import EmbedColours from "../constants/EmbedColours"; @@ -24,7 +24,8 @@ interface InventoryPageCards { interface ReturnedInventoryPage { embed: EmbedBuilder, - row: ActionRowBuilder, + row1: ActionRowBuilder, + row2: ActionRowBuilder, image: AttachmentBuilder, } @@ -99,7 +100,7 @@ export default class InventoryHelper { .setColor(EmbedColours.Ok) .setImage("attachment://page.png"); - const row = new ActionRowBuilder() + const row1 = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId(`inventory ${userid} ${page - 1}`) @@ -112,9 +113,23 @@ export default class InventoryHelper { .setStyle(ButtonStyle.Primary) .setDisabled(page + 1 == pages.length)); + let pageNum = 0; + + const row2 = new ActionRowBuilder() + .addComponents( + new StringSelectMenuBuilder() + .setCustomId("inventory") + .setPlaceholder(`${currentPage.name} (${currentPage.seriesSubpage + 1})`) + .addOptions(...pages.map(x => + new StringSelectMenuOptionBuilder() + .setLabel(`${x.name} (${x.seriesSubpage + 1})`.substring(0, 100)) + .setDescription(`Page ${pageNum + 1}`) + .setDefault(currentPage.id == x.id) + .setValue(`${userid} ${pageNum++}`)))); + const buffer = await ImageHelper.GenerateCardImageGrid(currentPage.cards.map(x => ({ id: x.id, path: x.path }))); const image = new AttachmentBuilder(buffer, { name: "page.png" }); - return { embed, row, image }; + return { embed, row1, row2, image }; } } diff --git a/src/registry.ts b/src/registry.ts index 1f7f509..67936c8 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -31,6 +31,9 @@ import SeriesEvent from "./buttonEvents/Series"; import TradeButtonEvent from "./buttonEvents/Trade"; import ViewButtonEvent from "./buttonEvents/View"; +// String Dropdown Event Imports +import InventoryStringDropdown from "./stringDropdowns/Inventory"; + export default class Registry { public static RegisterCommands() { // Global Commands @@ -64,4 +67,8 @@ export default class Registry { CoreClient.RegisterButtonEvent("trade", new TradeButtonEvent()); CoreClient.RegisterButtonEvent("view", new ViewButtonEvent()); } + + public static RegisterStringDropdownEvents() { + CoreClient.RegisterStringDropdownEvent("inventory", new InventoryStringDropdown()); + } } \ No newline at end of file diff --git a/src/stringDropdowns/Inventory.ts b/src/stringDropdowns/Inventory.ts new file mode 100644 index 0000000..2a218ea --- /dev/null +++ b/src/stringDropdowns/Inventory.ts @@ -0,0 +1,43 @@ +import {StringSelectMenuInteraction} from "discord.js"; +import {StringDropdownEvent} from "../type/stringDropdownEvent"; +import AppLogger from "../client/appLogger"; +import InventoryHelper from "../helpers/InventoryHelper"; + +export default class Inventory extends StringDropdownEvent { + public override async execute(interaction: StringSelectMenuInteraction) { + if (!interaction.guild) return; + + const userid = interaction.values[0].split(" ")[0]; + const page = interaction.values[0].split(" ")[1]; + + AppLogger.LogDebug("StringDropdown/Inventory", `Parameters: userid=${userid}, page=${page}`); + + await interaction.deferUpdate(); + + const member = interaction.guild.members.cache.find(x => x.id == userid) || await interaction.guild.members.fetch(userid); + + if (!member) { + await interaction.reply("Unable to find user."); + return; + } + + try { + const embed = await InventoryHelper.GenerateInventoryPage(member.user.username, member.user.id, Number(page)); + + if (!embed) { + await interaction.followUp("No page for user found."); + return; + } + + await interaction.editReply({ + files: [ embed.image ], + embeds: [ embed.embed ], + components: [ embed.row1, embed.row2 ], + }); + } catch (e) { + AppLogger.LogError("StringDropdown/Inventory", `Error generating inventory page for ${member.user.username} with id ${member.user.id}: ${e}`); + + await interaction.followUp("An error has occurred running this command."); + } + } +} diff --git a/src/type/stringDropdownEvent.ts b/src/type/stringDropdownEvent.ts new file mode 100644 index 0000000..c097cda --- /dev/null +++ b/src/type/stringDropdownEvent.ts @@ -0,0 +1,5 @@ +import {StringSelectMenuInteraction} from "discord.js"; + +export abstract class StringDropdownEvent { + abstract execute(interaction: StringSelectMenuInteraction): Promise; +} From 768f64b5ee370f5f3d23ea9058a321acbb8f9a26 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 23 Sep 2024 18:33:07 +0100 Subject: [PATCH 27/59] Update dependency eslint to v8.57.1 (#366) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [eslint](https://eslint.org) ([source](https://github.com/eslint/eslint)) | devDependencies | patch | [`8.57.0` -> `8.57.1`](https://renovatebot.com/diffs/npm/eslint/8.57.0/8.57.1) | --- ### Release Notes
eslint/eslint (eslint) ### [`v8.57.1`](https://github.com/eslint/eslint/releases/tag/v8.57.1) [Compare Source](https://github.com/eslint/eslint/compare/v8.57.0...v8.57.1) #### Bug Fixes - [`a19072f`](https://github.com/eslint/eslint/commit/a19072f9f17ea8266bc66193e5f8a4bf1368835d) fix: add logic to handle fixTypes in the lintText() method ([#​18900](https://github.com/eslint/eslint/issues/18900)) (Francesco Trotta) - [`04c7188`](https://github.com/eslint/eslint/commit/04c718865b75a95ebfc4d429b8c9fad773228624) fix: Don't lint same file multiple times ([#​18899](https://github.com/eslint/eslint/issues/18899)) (Francesco Trotta) - [`87ec3c4`](https://github.com/eslint/eslint/commit/87ec3c49dd23ab8892bc19aae711292d03a73483) fix: do not throw when defining a global named `__defineSetter__` ([#​18898](https://github.com/eslint/eslint/issues/18898)) (Francesco Trotta) - [`60a1267`](https://github.com/eslint/eslint/commit/60a12676878c3fe0623c3b93e7565f003daac5f0) fix: Provide helpful error message for nullish configs ([#​18889](https://github.com/eslint/eslint/issues/18889)) (Milos Djermanovic) - [`a0dea8e`](https://github.com/eslint/eslint/commit/a0dea8ee01cc4c1b65927562afd3a46418573a02) fix: allow `name` in global ignores, fix `--no-ignore` for non-global ([#​18875](https://github.com/eslint/eslint/issues/18875)) (Milos Djermanovic) - [`3836bb4`](https://github.com/eslint/eslint/commit/3836bb48d3f12058ec36c2edf2ca1b50eb1c923b) fix: do not crash on error in `fs.walk` filter ([#​18886](https://github.com/eslint/eslint/issues/18886)) (Milos Djermanovic) - [`2dec349`](https://github.com/eslint/eslint/commit/2dec349199df4cba1554172ad38163cc09ad0a52) fix: skip processor code blocks that match only universal patterns ([#​18880](https://github.com/eslint/eslint/issues/18880)) (Milos Djermanovic) #### Documentation - [`6a5add4`](https://github.com/eslint/eslint/commit/6a5add41e80941c7253b56b02815ac316e583006) docs: v8.x Add EOL banner ([#​18744](https://github.com/eslint/eslint/issues/18744)) (Amaresh S M) - [`b034575`](https://github.com/eslint/eslint/commit/b034575978e3bb57e2edca0d2dc547c7a3abc928) docs: v8.x add version support page to the dropdown ([#​18731](https://github.com/eslint/eslint/issues/18731)) (Amaresh S M) - [`760ef7d`](https://github.com/eslint/eslint/commit/760ef7d9dbd7b615ccbdc20f02cbc05dbabbada8) docs: v8.x add version support page in the side navbar ([#​18740](https://github.com/eslint/eslint/issues/18740)) (Amaresh S M) - [`428b7ea`](https://github.com/eslint/eslint/commit/428b7ea0a9c086b7d8afa0adb629b09d7347d41d) docs: Add Powered by Algolia label to the search ([#​18658](https://github.com/eslint/eslint/issues/18658)) (Amaresh S M) - [`c68c07f`](https://github.com/eslint/eslint/commit/c68c07ff44c180952e93c6f2c860079db6291b29) docs: version selectors synchronization ([#​18265](https://github.com/eslint/eslint/issues/18265)) (Milos Djermanovic) #### Build Related - [`35d366a`](https://github.com/eslint/eslint/commit/35d366aed6e8ab0cfa8f9c9bac4656e3784c11f6) build: Support updates to previous major versions ([#​18870](https://github.com/eslint/eslint/issues/18870)) (Milos Djermanovic) #### Chores - [`140ec45`](https://github.com/eslint/eslint/commit/140ec4569fda5a974b6964242b0b2991828a5567) chore: upgrade [@​eslint/js](https://github.com/eslint/js)[@​8](https://github.com/8).57.1 ([#​18913](https://github.com/eslint/eslint/issues/18913)) (Milos Djermanovic) - [`bcdfc04`](https://github.com/eslint/eslint/commit/bcdfc04a69c53dbf1fc3d38603fe0a796bf2274d) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (Jenkins) - [`3f6ce8d`](https://github.com/eslint/eslint/commit/3f6ce8d6b74aba0d645448e898f271825eeb9630) chore: pin vite-plugin-commonjs@0.10.1 ([#​18910](https://github.com/eslint/eslint/issues/18910)) (Milos Djermanovic) - [`9f07549`](https://github.com/eslint/eslint/commit/9f0754979527d05cd0abb2ea7ab1c3563fb4a361) chore: ignore `/docs/v8.x` in link checker ([#​18660](https://github.com/eslint/eslint/issues/18660)) (Milos Djermanovic)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/366 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 66 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/yarn.lock b/yarn.lock index 270a68f..157119d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -416,9 +416,9 @@ integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== "@eslint-community/regexpp@^4.6.1": - version "4.10.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.1.tgz#361461e5cb3845d874e61731c11cfedd664d83a0" - integrity sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA== + version "4.11.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" + integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== "@eslint/eslintrc@^2.1.4": version "2.1.4" @@ -435,17 +435,17 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.57.0": - version "8.57.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" - integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== +"@eslint/js@8.57.1": + version "8.57.1" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" + integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== -"@humanwhocodes/config-array@^0.11.14": - version "0.11.14" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" - integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== +"@humanwhocodes/config-array@^0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" + integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== dependencies: - "@humanwhocodes/object-schema" "^2.0.2" + "@humanwhocodes/object-schema" "^2.0.3" debug "^4.3.1" minimatch "^3.0.5" @@ -454,7 +454,7 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^2.0.2": +"@humanwhocodes/object-schema@^2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== @@ -1511,9 +1511,9 @@ acorn-jsx@^5.3.2: integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn@^8.9.0: - version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" - integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== agent-base@6: version "6.0.2" @@ -2435,13 +2435,20 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: +debug@4, debug@^4.1.0, debug@^4.1.1: version "4.3.5" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== dependencies: ms "2.1.2" +debug@^4.3.1, debug@^4.3.2: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + debug@^4.3.4: version "4.3.6" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" @@ -2769,15 +2776,15 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.56.0: - version "8.57.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" - integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== + version "8.57.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" + integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.57.0" - "@humanwhocodes/config-array" "^0.11.14" + "@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" @@ -2827,9 +2834,9 @@ esprima@^4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" @@ -3584,7 +3591,12 @@ ignore-walk@^6.0.3: dependencies: minimatch "^9.0.0" -ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1: +ignore@^5.2.0: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== + +ignore@^5.2.4, ignore@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== @@ -4974,7 +4986,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.1.1: +ms@2.1.3, ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== From cd7e0945a9559f5dcab394e8924dd341465446b4 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 8 Oct 2024 19:32:47 +0100 Subject: [PATCH 28/59] Update dependency @types/node to v20.16.10 (#372) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.16.5` -> `20.16.10`](https://renovatebot.com/diffs/npm/@types%2fnode/20.16.5/20.16.10) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/372 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 157119d..a7b8ad3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1282,9 +1282,9 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.16.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.5.tgz#d43c7f973b32ffdf9aa7bd4f80e1072310fd7a53" - integrity sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA== + version "20.16.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.10.tgz#0cc3fdd3daf114a4776f54ba19726a01c907ef71" + integrity sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA== dependencies: undici-types "~6.19.2" From 816e550c84e9b6f17ad4c5baf9056d3f2cf1f353 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 8 Oct 2024 19:34:18 +0100 Subject: [PATCH 29/59] Update dependency express to v4.21.0 (#373) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [express](http://expressjs.com/) ([source](https://github.com/expressjs/express)) | dependencies | minor | [`4.19.2` -> `4.21.0`](https://renovatebot.com/diffs/npm/express/4.19.2/4.21.0) | --- ### Release Notes
expressjs/express (express) ### [`v4.21.0`](https://github.com/expressjs/express/releases/tag/4.21.0) [Compare Source](https://github.com/expressjs/express/compare/4.20.0...4.21.0) #### What's Changed - Deprecate `"back"` magic string in redirects by [@​blakeembrey](https://github.com/blakeembrey) in https://github.com/expressjs/express/pull/5935 - finalhandler@1.3.1 by [@​wesleytodd](https://github.com/wesleytodd) in https://github.com/expressjs/express/pull/5954 - fix(deps): serve-static@1.16.2 by [@​wesleytodd](https://github.com/wesleytodd) in https://github.com/expressjs/express/pull/5951 - Upgraded dependency qs to 6.13.0 to match qs in body-parser by [@​agadzinski93](https://github.com/agadzinski93) in https://github.com/expressjs/express/pull/5946 #### New Contributors - [@​agadzinski93](https://github.com/agadzinski93) made their first contribution in https://github.com/expressjs/express/pull/5946 **Full Changelog**: https://github.com/expressjs/express/compare/4.20.0...4.21.0 ### [`v4.20.0`](https://github.com/expressjs/express/blob/HEAD/History.md#4200--2024-09-10) [Compare Source](https://github.com/expressjs/express/compare/4.19.2...4.20.0) \========== - deps: serve-static@0.16.0 - Remove link renderization in html while redirecting - deps: send@0.19.0 - Remove link renderization in html while redirecting - deps: body-parser@0.6.0 - add `depth` option to customize the depth level in the parser - IMPORTANT: The default `depth` level for parsing URL-encoded data is now `32` (previously was `Infinity`) - Remove link renderization in html while using `res.redirect` - deps: path-to-regexp@0.1.10 - Adds support for named matching groups in the routes using a regex - Adds backtracking protection to parameters without regexes defined - deps: encodeurl@~2.0.0 - Removes encoding of `\`, `|`, and `^` to align better with URL spec - Deprecate passing `options.maxAge` and `options.expires` to `res.clearCookie` - Will be ignored in v5, clearCookie will set a cookie with an expires in the past to instruct clients to delete the cookie
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/373 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 102 ++++++++++++++++++++++-------------------------------- 1 file changed, 41 insertions(+), 61 deletions(-) diff --git a/yarn.lock b/yarn.lock index a7b8ad3..9a89b7e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1798,25 +1798,7 @@ bmp-js@^0.1.0: resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" integrity sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw== -body-parser@1.20.2: - version "1.20.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" - integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== - dependencies: - bytes "3.1.2" - content-type "~1.0.5" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.2" - type-is "~1.6.18" - unpipe "1.0.0" - -body-parser@^1.20.2: +body-parser@1.20.3, body-parser@^1.20.2: version "1.20.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== @@ -2701,6 +2683,11 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -2934,36 +2921,36 @@ expect@^29.0.0, expect@^29.7.0: jest-util "^29.7.0" express@^4.18.2: - version "4.19.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" - integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + version "4.21.0" + resolved "https://registry.yarnpkg.com/express/-/express-4.21.0.tgz#d57cb706d49623d4ac27833f1cbc466b668eb915" + integrity sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.2" + body-parser "1.20.3" content-disposition "0.5.4" content-type "~1.0.4" cookie "0.6.0" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.2.0" + finalhandler "1.3.1" fresh "0.5.2" http-errors "2.0.0" - merge-descriptors "1.0.1" + merge-descriptors "1.0.3" methods "~1.1.2" on-finished "2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.7" + path-to-regexp "0.1.10" proxy-addr "~2.0.7" - qs "6.11.0" + qs "6.13.0" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" + send "0.19.0" + serve-static "1.16.2" setprototypeof "1.2.0" statuses "2.0.1" type-is "~1.6.18" @@ -3093,13 +3080,13 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== +finalhandler@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" + integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== dependencies: debug "2.6.9" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" on-finished "2.4.1" parseurl "~1.3.3" @@ -4792,10 +4779,10 @@ meow@^12.1.1: resolved "https://registry.yarnpkg.com/meow/-/meow-12.1.1.tgz#e558dddbab12477b69b2e9a2728c327f191bace6" integrity sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw== -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== merge-stream@^2.0.0: version "2.0.0" @@ -5541,10 +5528,10 @@ path-scurry@^2.0.0: lru-cache "^11.0.0" minipass "^7.1.2" -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== +path-to-regexp@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" + integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== path-type@^4.0.0: version "4.0.0" @@ -5689,13 +5676,6 @@ pure-rand@^6.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== -qs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - qs@6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" @@ -6029,10 +6009,10 @@ semver@^7.5.3, semver@^7.6.0, semver@^7.6.3: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== dependencies: debug "2.6.9" depd "2.0.0" @@ -6048,15 +6028,15 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== +serve-static@1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== dependencies: - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.18.0" + send "0.19.0" set-blocking@^2.0.0: version "2.0.0" @@ -6107,7 +6087,7 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -side-channel@^1.0.4, side-channel@^1.0.6: +side-channel@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== From a8a5e39e011fa627f547422b76cca1baa6171560 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 8 Oct 2024 19:35:21 +0100 Subject: [PATCH 30/59] Update appleboy/ssh-action action to v1.1.0 (#374) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [appleboy/ssh-action](https://github.com/appleboy/ssh-action) | action | minor | `v1.0.3` -> `v1.1.0` | --- ### Release Notes
appleboy/ssh-action (appleboy/ssh-action) ### [`v1.1.0`](https://github.com/appleboy/ssh-action/releases/tag/v1.1.0) [Compare Source](https://github.com/appleboy/ssh-action/compare/v1.0.3...v1.1.0) ##### Changelog ##### Bug fixes - [`0c7561b`](https://github.com/appleboy/ssh-action/commit/0c7561b1a30e223b97730bb8b92671995d9fb1d0): fix: switch to SSH key authentication for security ([@​appleboy](https://github.com/appleboy)) ##### Enhancements - [`9b978f0`](https://github.com/appleboy/ssh-action/commit/9b978f09f2587beff9c80449f57cb0f0612d3039): chore: update SSH action version in README files ([@​appleboy](https://github.com/appleboy)) - [`1991c55`](https://github.com/appleboy/ssh-action/commit/1991c553ec29aeb9fe1cbffabfabe0c2f0ea891e): chore(file): update target file ([@​appleboy](https://github.com/appleboy)) - [`aa293c2`](https://github.com/appleboy/ssh-action/commit/aa293c24bb8b49499c238d2260b26a5ab2ee10e0): chore: optimize system configuration and API integration ([@​appleboy](https://github.com/appleboy)) - [`036cad7`](https://github.com/appleboy/ssh-action/commit/036cad7df774e9168d1de6c77d668c6a292d4540): chore: update drone-ssh to version 1.7.7 ([@​appleboy](https://github.com/appleboy)) - [`8b60782`](https://github.com/appleboy/ssh-action/commit/8b6078208d71a6d9364c7f23d78ca9b38bed48c0): chore(cli): enhance version handling and testing mechanisms ([@​appleboy](https://github.com/appleboy)) - [`5ade826`](https://github.com/appleboy/ssh-action/commit/5ade82648576fb5118b586573e9c607af4941b24): chore: improve CLI reliability and version visibility ([@​appleboy](https://github.com/appleboy)) - [`eaeb069`](https://github.com/appleboy/ssh-action/commit/eaeb06998d86f5e66259ee8dc3d0909612f0ce65): chore(cli): enhance curl command with silent mode and redirects ([@​appleboy](https://github.com/appleboy)) - [`58164d0`](https://github.com/appleboy/ssh-action/commit/58164d0dc2b76ba5c47e110152e94bfbd13ea235): chore: remove Dockerfile and related configurations ([@​appleboy](https://github.com/appleboy)) ##### Refactor - [`da612c8`](https://github.com/appleboy/ssh-action/commit/da612c801589d64bea89ca943c84fe1aae7a1d06): refactor: optimize CI pipeline for faster execution ([@​appleboy](https://github.com/appleboy)) ##### Build process updates - [`c781418`](https://github.com/appleboy/ssh-action/commit/c78141851a6d716353b2ce13c978924e0300775e): ci: enhance GitHub Actions for IPv6 and flexibility ([#​303](https://github.com/appleboy/ssh-action/issues/303)) ([@​appleboy](https://github.com/appleboy)) - [`d2d6858`](https://github.com/appleboy/ssh-action/commit/d2d68588591b705c406168accae85968a2f75c0d): ci: enhance GitHub workflow for SSH actions and deployments ([@​appleboy](https://github.com/appleboy)) - [`551964e`](https://github.com/appleboy/ssh-action/commit/551964ebda1034f0b5449d74db25c42e371ca1f7): ci: optimize GitHub Actions workflow configuration ([@​appleboy](https://github.com/appleboy)) - [`f916346`](https://github.com/appleboy/ssh-action/commit/f9163462563f649b27272d32e585525a5fe68d76): ci: refactor CI workflow and improve robustness ([#​320](https://github.com/appleboy/ssh-action/issues/320)) ([@​appleboy](https://github.com/appleboy)) - [`aabaf12`](https://github.com/appleboy/ssh-action/commit/aabaf1254d78efafd55cd5880a874e9715b4c6e8): ci: add bug report template ([@​appleboy](https://github.com/appleboy)) - [`c8594ae`](https://github.com/appleboy/ssh-action/commit/c8594ae37d5bd9a779dc12abd0236b1bcff70119): ci: implement GitHub Actions for remote SSH execution ([@​appleboy](https://github.com/appleboy)) - [`40aad53`](https://github.com/appleboy/ssh-action/commit/40aad53c5a18b2676371816d258458b2ccd56c50): ci: add SSH authentication setup for GitHub Actions ([@​appleboy](https://github.com/appleboy)) - [`0b0e770`](https://github.com/appleboy/ssh-action/commit/0b0e77098a4fa59703014092ddd6d2ad7267088f): ci: optimize and enhance SSH server workflow ([@​appleboy](https://github.com/appleboy)) - [`977b74a`](https://github.com/appleboy/ssh-action/commit/977b74a12d4201105f3b851126516847ed6b80b0): ci: enhance CI workflow with SSH job and optimizations ([@​appleboy](https://github.com/appleboy)) - [`2eeab5b`](https://github.com/appleboy/ssh-action/commit/2eeab5bdbadfcfd821c3f107a694803080f4b126): ci: refactor GitHub Actions key management ([@​appleboy](https://github.com/appleboy)) - [`acd41e5`](https://github.com/appleboy/ssh-action/commit/acd41e5091e04c5db86c78f86723e9baec27f452): ci: enhance SSH job testing with varied key/password scenarios ([@​appleboy](https://github.com/appleboy)) - [`f05aefe`](https://github.com/appleboy/ssh-action/commit/f05aefe3514f74f9cda4825a2a5d9905aa45ae2a): ci: enhance SSH action configuration and error handling ([@​appleboy](https://github.com/appleboy)) - [`e40b597`](https://github.com/appleboy/ssh-action/commit/e40b597081b0c96e4f93bee63cec35d4ea3b4d3a): ci: add GitHub Actions job for SSH key passphrase support ([@​appleboy](https://github.com/appleboy)) - [`15b64dc`](https://github.com/appleboy/ssh-action/commit/15b64dc8919f9e984dd7c4e96fdd5d74ccc03088): ci: enhance CI pipeline with SSH key handling improvements ([@​appleboy](https://github.com/appleboy)) - [`a39b3cc`](https://github.com/appleboy/ssh-action/commit/a39b3cce7dbd84fb06164ac1a60a27615417de71): ci: enhance CI/CD pipeline with SSH command execution ([@​appleboy](https://github.com/appleboy)) - [`815c574`](https://github.com/appleboy/ssh-action/commit/815c5743ac3927b147e22309d57a1f5a140a2d30): ci: enhance deployment with multi-host SSH action ([@​appleboy](https://github.com/appleboy)) - [`378323e`](https://github.com/appleboy/ssh-action/commit/378323e4c85be1bb394f07e5a3a3c7c687499829): ci: add multi-server support to CI workflow ([@​appleboy](https://github.com/appleboy)) - [`fc1c1fc`](https://github.com/appleboy/ssh-action/commit/fc1c1fce5140b0530a36d88286de8a29df8518bb): ci: add GitHub Actions job for [`ed25519`](https://github.com/appleboy/ssh-action/commit/ed25519) key support ([@​appleboy](https://github.com/appleboy)) - [`f0e5a23`](https://github.com/appleboy/ssh-action/commit/f0e5a23d530cb42b84b01340c5fb1a6ad570d4e8): ci: add environment variable handling in GitHub Actions ([@​appleboy](https://github.com/appleboy)) - [`9c32aa6`](https://github.com/appleboy/ssh-action/commit/9c32aa61f8c24f38e93a3282178429b314c14e8a): ci: refactor workflows and API integrations ([@​appleboy](https://github.com/appleboy)) - [`97f8d75`](https://github.com/appleboy/ssh-action/commit/97f8d752b568999364c7296fa08e33d68367e3fd): ci: enable root access in CI pipeline ([@​appleboy](https://github.com/appleboy)) - [`5a8776f`](https://github.com/appleboy/ssh-action/commit/5a8776fd157405e3e88da24413b04c2aaf01e99c): ci: switch to password authentication in GitHub workflow ([@​appleboy](https://github.com/appleboy)) - [`b6941ae`](https://github.com/appleboy/ssh-action/commit/b6941ae5d5746e351d7fede90e718688304d2b4a): ci: refactor codebase and optimize performance ([@​appleboy](https://github.com/appleboy)) - [`43895f2`](https://github.com/appleboy/ssh-action/commit/43895f2cd585d373b747690a3e7f9bdcdd09e1cd): ci: refactor SSH testing workflows and job configurations ([@​appleboy](https://github.com/appleboy)) - [`06fa62e`](https://github.com/appleboy/ssh-action/commit/06fa62e61cac6c39015db4efcde64776f56965c4): ci: rename the workflow files. ([@​appleboy](https://github.com/appleboy)) - [`b4a07ca`](https://github.com/appleboy/ssh-action/commit/b4a07ca5940a7dc94925e99f8e6eab3671b0fa64): ci: enhance GitHub Actions with secret variable support ([#​330](https://github.com/appleboy/ssh-action/issues/330)) ([@​appleboy](https://github.com/appleboy)) - [`25ce8cb`](https://github.com/appleboy/ssh-action/commit/25ce8cbbcb08177468c7ff7ec5cbfa236f9341e1): ci: implement automated release workflow with GoReleaser ([@​appleboy](https://github.com/appleboy)) ##### Documentation updates - [`8a779a5`](https://github.com/appleboy/ssh-action/commit/8a779a5b1a8a79465e63ce4724624b4755fed49b): docs: describe true usage of allenvs parameter ([#​301](https://github.com/appleboy/ssh-action/issues/301)) ([@​hussu010](https://github.com/hussu010)) - [`fe44be0`](https://github.com/appleboy/ssh-action/commit/fe44be0b96e09ca219322f172bc338fd0718a55b): docs: improve documentation and CI robustness ([@​appleboy](https://github.com/appleboy)) - [`dd0f09c`](https://github.com/appleboy/ssh-action/commit/dd0f09ca072e60babe3cc58ed83c66a86176300c): docs: improve README clarity and completeness ([@​appleboy](https://github.com/appleboy)) - [`71d43ea`](https://github.com/appleboy/ssh-action/commit/71d43ea0f75a1f73c9b0e4608c059783968ad29c): docs: improve documentation and testing configurations ([@​appleboy](https://github.com/appleboy)) - [`28428a1`](https://github.com/appleboy/ssh-action/commit/28428a13f5b0283d667b1c6501d144f15b059726): docs: improve cross-platform clipboard support for key copying ([@​appleboy](https://github.com/appleboy)) - [`d732991`](https://github.com/appleboy/ssh-action/commit/d732991ab09097d8c8f390d91385b0386e619598): docs(lang): README.zh-cn Document ([#​332](https://github.com/appleboy/ssh-action/issues/332)) ([@​astralwaveio](https://github.com/astralwaveio))
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/374 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- .forgejo/workflows/production.yml | 2 +- .forgejo/workflows/stage.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/production.yml b/.forgejo/workflows/production.yml index f71273d..d7b014b 100644 --- a/.forgejo/workflows/production.yml +++ b/.forgejo/workflows/production.yml @@ -30,7 +30,7 @@ jobs: needs: build runs-on: node steps: - - uses: https://github.com/appleboy/ssh-action@v1.0.3 + - uses: https://github.com/appleboy/ssh-action@v1.1.0 env: DB_NAME: ${{ secrets.PROD_DB_NAME }} DB_AUTH_USER: ${{ secrets.PROD_DB_AUTH_USER }} diff --git a/.forgejo/workflows/stage.yml b/.forgejo/workflows/stage.yml index 1e73e7a..60712ca 100644 --- a/.forgejo/workflows/stage.yml +++ b/.forgejo/workflows/stage.yml @@ -30,7 +30,7 @@ jobs: needs: build runs-on: node steps: - - uses: https://github.com/appleboy/ssh-action@v1.0.3 + - uses: https://github.com/appleboy/ssh-action@v1.1.0 env: DB_NAME: ${{ secrets.STAGE_DB_NAME }} DB_AUTH_USER: ${{ secrets.STAGE_DB_AUTH_USER }} From 480e496984c866a085e9a7096ff7abbe91b1d1b7 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 8 Oct 2024 19:36:36 +0100 Subject: [PATCH 31/59] Update dependency typescript to v5.6.2 (#375) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [typescript](https://www.typescriptlang.org/) ([source](https://github.com/microsoft/TypeScript)) | devDependencies | minor | [`5.5.4` -> `5.6.2`](https://renovatebot.com/diffs/npm/typescript/5.5.4/5.6.2) | --- ### Release Notes
microsoft/TypeScript (typescript) ### [`v5.6.2`](https://github.com/microsoft/TypeScript/releases/tag/v5.6.2): TypeScript 5.6 [Compare Source](https://github.com/microsoft/TypeScript/compare/v5.5.4...v5.6.2) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-6/). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 5.6.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+5.6.0%22+is%3Aclosed+). - [fixed issues query for Typescript 5.6.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+5.6.1%22+is%3Aclosed+). - [fixed issues query for Typescript 5.6.2 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+5.6.2%22+is%3Aclosed+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/375 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9a89b7e..e379630 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6685,9 +6685,9 @@ types-pkg-json@^1.1.0: types-json "^1.2.2" typescript@^5.0.0: - version "5.5.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" - integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== + version "5.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" + integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== undici-types@~6.19.2: version "6.19.8" From f4c02d3613255ef68e07579bfaced9d65dd00b1b Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 12 Oct 2024 17:26:13 +0100 Subject: [PATCH 32/59] Update the User entity to be nullable (#371) - Update the user entity to be nullable in the typescript side - The migration script already did this, but if you have the `DB_SYNC` environment variable sync it then it doesn't get set to nullable #353 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/371 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/database/entities/app/User.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database/entities/app/User.ts b/src/database/entities/app/User.ts index c3d8437..3a9018d 100644 --- a/src/database/entities/app/User.ts +++ b/src/database/entities/app/User.ts @@ -13,7 +13,7 @@ export default class User extends AppBaseEntity { @Column() Currency: number; - @Column() + @Column({ nullable: true }) LastUsedDaily?: Date; public AddCurrency(amount: number) { From 8352b377bb718753d1c704250fd02f2f3a79f39e Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 12 Oct 2024 17:30:20 +0100 Subject: [PATCH 33/59] Create ability to drop multiple cards in a row (#376) - Create a `/multidrop` command - This will take the price of 10 drops from you and give you 11 cards to sort through - You then have a choice to keep the card or sacrifice it - Create the `multidrop keep` and `multidrop sacrifice` button events #262 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/376 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/buttonEvents/Claim.ts | 2 +- src/buttonEvents/Multidrop.ts | 213 ++++++++++++++++++++++++++ src/commands/drop.ts | 15 +- src/commands/multidrop.ts | 87 +++++++++++ src/constants/CardConstants.ts | 4 + src/constants/ErrorMessages.ts | 8 + src/helpers/CardDropHelperMetadata.ts | 26 +++- src/registry.ts | 4 + 8 files changed, 348 insertions(+), 11 deletions(-) create mode 100644 src/buttonEvents/Multidrop.ts create mode 100644 src/commands/multidrop.ts create mode 100644 src/constants/ErrorMessages.ts diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts index 4d5d97a..190a09e 100644 --- a/src/buttonEvents/Claim.ts +++ b/src/buttonEvents/Claim.ts @@ -58,7 +58,7 @@ export default class Claim extends ButtonEvent { if (!inventory) { inventory = new Inventory(userId, cardNumber, 1); } else { - inventory.SetQuantity(inventory.Quantity + 1); + inventory.AddQuantity(1); } await inventory.Save(Inventory, inventory); diff --git a/src/buttonEvents/Multidrop.ts b/src/buttonEvents/Multidrop.ts new file mode 100644 index 0000000..604f02c --- /dev/null +++ b/src/buttonEvents/Multidrop.ts @@ -0,0 +1,213 @@ +import { AttachmentBuilder, ButtonInteraction, EmbedBuilder } from "discord.js"; +import { ButtonEvent } from "../type/buttonEvent"; +import AppLogger from "../client/appLogger"; +import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; +import Inventory from "../database/entities/app/Inventory"; +import EmbedColours from "../constants/EmbedColours"; +import { readFileSync } from "fs"; +import path from "path"; +import ErrorMessages from "../constants/ErrorMessages"; +import User from "../database/entities/app/User"; +import { GetSacrificeAmount } from "../constants/CardRarity"; + +export default class Multidrop extends ButtonEvent { + public override async execute(interaction: ButtonInteraction) { + const action = interaction.customId.split(" ")[1]; + + switch (action) { + case "keep": + await this.Keep(interaction); + break; + case "sacrifice": + await this.Sacrifice(interaction); + break; + default: + await interaction.reply("Invalid action"); + AppLogger.LogError("Button/Multidrop", `Invalid action, ${action}`); + } + } + + private async Keep(interaction: ButtonInteraction) { + const cardNumber = interaction.customId.split(" ")[2]; + let cardsRemaining = Number(interaction.customId.split(" ")[3]) || 0; + const userId = interaction.customId.split(" ")[4]; + + if (interaction.user.id != userId) { + await interaction.reply("You're not the user this drop was made for!"); + return; + } + + const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + + if (!card) { + await interaction.reply("Unable to find card."); + AppLogger.LogWarn("Button/Multidrop/Keep", `Card not found, ${cardNumber}`); + return; + } + + if (cardsRemaining < 0) { + await interaction.reply("Your multidrop has ran out! Please buy a new one!"); + return; + } + + const user = await User.FetchOneById(User, interaction.user.id); + + if (!user) { + AppLogger.LogWarn("Button/Multidrop/Keep", ErrorMessages.UnableToFetchUser); + await interaction.reply(ErrorMessages.UnableToFetchUser); + return; + } + + // Claim + let inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, cardNumber); + + if (!inventory) { + inventory = new Inventory(interaction.user.id, cardNumber, 1); + } else { + inventory.AddQuantity(1); + } + + await inventory.Save(Inventory, inventory); + + // Pack has ran out + if (cardsRemaining == 0) { + const embed = new EmbedBuilder() + .setDescription("Your multidrop has ran out! Please buy a new one!") + .setColor(EmbedColours.Ok); + + await interaction.update({ + embeds: [ embed ], + attachments: [], + components: [], + }); + + return; + } + + // Drop next card + const randomCard = CardDropHelperMetadata.GetRandomCard(); + cardsRemaining -= 1; + + if (!randomCard) { + AppLogger.LogWarn("Button/Multidrop/Keep", ErrorMessages.UnableToFetchCard); + await interaction.reply(ErrorMessages.UnableToFetchCard); + return; + } + + await interaction.deferUpdate(); + + try { + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path)); + const imageFileName = randomCard.card.path.split("/").pop()!; + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); + const quantityClaimed = inventory ? inventory.Quantity : 0; + + const embed = CardDropHelperMetadata.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); + + const row = CardDropHelperMetadata.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id, cardsRemaining < 0); + + await interaction.editReply({ + embeds: [ embed ], + files: [ attachment ], + components: [ row ], + }); + } catch (e) { + AppLogger.LogError("Button/Multidrop/Keep", `Error sending next drop for card ${randomCard.card.id}: ${e}`); + + await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. (${randomCard.card.id})`); + } + } + + private async Sacrifice(interaction: ButtonInteraction) { + const cardNumber = interaction.customId.split(" ")[2]; + let cardsRemaining = Number(interaction.customId.split(" ")[3]) || 0; + const userId = interaction.customId.split(" ")[4]; + + if (interaction.user.id != userId) { + await interaction.reply("You're not the user this drop was made for!"); + return; + } + + const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + + if (!card) { + await interaction.reply("Unable to find card."); + AppLogger.LogWarn("Button/Multidrop/Sacrifice", `Card not found, ${cardNumber}`); + return; + } + + if (cardsRemaining < 0) { + await interaction.reply("Your multidrop has ran out! Please buy a new one!"); + return; + } + + const user = await User.FetchOneById(User, interaction.user.id); + + if (!user) { + AppLogger.LogWarn("Button/Multidrop/Sacrifice", ErrorMessages.UnableToFetchUser); + await interaction.reply(ErrorMessages.UnableToFetchUser); + return; + } + + // Sacrifice + const sacrificeAmount = GetSacrificeAmount(card.card.type); + + user.AddCurrency(sacrificeAmount); + + await user.Save(User, user); + + // Pack has ran out + if (cardsRemaining == 0) { + const embed = new EmbedBuilder() + .setDescription("Your multidrop has ran out! Please buy a new one!") + .setColor(EmbedColours.Ok); + + await interaction.update({ + embeds: [ embed ], + attachments: [], + components: [], + }); + + return; + } + + // Drop next card + const randomCard = CardDropHelperMetadata.GetRandomCard(); + cardsRemaining -= 1; + + if (!randomCard) { + AppLogger.LogWarn("Button/Multidrop/Sacrifice", ErrorMessages.UnableToFetchCard); + await interaction.reply(ErrorMessages.UnableToFetchCard); + return; + } + + await interaction.deferUpdate(); + + try { + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path)); + const imageFileName = randomCard.card.path.split("/").pop()!; + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); + const quantityClaimed = inventory ? inventory.Quantity : 0; + + const embed = CardDropHelperMetadata.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); + + const row = CardDropHelperMetadata.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id, cardsRemaining < 0); + + await interaction.editReply({ + embeds: [ embed ], + files: [ attachment ], + components: [ row ], + }); + } catch (e) { + AppLogger.LogError("Button/Multidrop/Sacrifice", `Error sending next drop for card ${randomCard.card.id}: ${e}`); + + await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. (${randomCard.card.id})`); + } + } +} \ No newline at end of file diff --git a/src/commands/drop.ts b/src/commands/drop.ts index 6f74d3a..6799a2c 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -10,6 +10,7 @@ import path from "path"; import AppLogger from "../client/appLogger"; import User from "../database/entities/app/User"; import CardConstants from "../constants/CardConstants"; +import ErrorMessages from "../constants/ErrorMessages"; export default class Drop extends Command { constructor() { @@ -22,14 +23,13 @@ export default class Drop extends Command { public override async execute(interaction: CommandInteraction) { if (!CoreClient.AllowDrops) { - await interaction.reply("Bot is currently syncing, please wait until its done."); + await interaction.reply(ErrorMessages.BotSyncing); return; } if (await Config.GetValue("safemode") == "true") { - AppLogger.LogWarn("Commands/Drop", "Safe Mode is active, refusing to send next drop."); - - await interaction.reply("Safe Mode has been activated, please resync to continue."); + AppLogger.LogWarn("Commands/Drop", ErrorMessages.SafeMode); + await interaction.reply(ErrorMessages.SafeMode); return; } @@ -43,16 +43,15 @@ export default class Drop extends Command { } if (user.Currency < CardConstants.ClaimCost) { - await interaction.reply(`Not enough currency! You need ${CardConstants.ClaimCost} currency, you have ${user.Currency}!`); + await interaction.reply(ErrorMessages.NotEnoughCurrency(CardConstants.ClaimCost, user.Currency)); return; } const randomCard = CardDropHelperMetadata.GetRandomCard(); if (!randomCard) { - AppLogger.LogWarn("Commands/Drop", "Unable to fetch card, please try again. (randomCard is null)"); - - await interaction.reply("Unable to fetch card, please try again."); + AppLogger.LogWarn("Commands/Drop", ErrorMessages.UnableToFetchCard); + await interaction.reply(ErrorMessages.UnableToFetchCard); return; } diff --git a/src/commands/multidrop.ts b/src/commands/multidrop.ts new file mode 100644 index 0000000..f35b921 --- /dev/null +++ b/src/commands/multidrop.ts @@ -0,0 +1,87 @@ +import { AttachmentBuilder, CommandInteraction, SlashCommandBuilder } from "discord.js"; +import { Command } from "../type/command"; +import { CoreClient } from "../client/client"; +import ErrorMessages from "../constants/ErrorMessages"; +import Config from "../database/entities/app/Config"; +import AppLogger from "../client/appLogger"; +import User from "../database/entities/app/User"; +import CardConstants from "../constants/CardConstants"; +import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; +import { readFileSync } from "fs"; +import path from "path"; +import Inventory from "../database/entities/app/Inventory"; + +export default class Multidrop extends Command { + constructor() { + super(); + + this.CommandBuilder = new SlashCommandBuilder() + .setName("multidrop") + .setDescription("Drop 11 cards for the price of 10!"); + } + + public override async execute(interaction: CommandInteraction) { + if (!CoreClient.AllowDrops) { + await interaction.reply(ErrorMessages.BotSyncing); + return; + } + + if (await Config.GetValue("safemode") == "true") { + AppLogger.LogWarn("Commands/Multidrop", ErrorMessages.SafeMode); + await interaction.reply(ErrorMessages.SafeMode); + return; + } + + let user = await User.FetchOneById(User, interaction.user.id); + + if (!user) { + user = new User(interaction.user.id, CardConstants.StartingCurrency); + await user.Save(User, user); + + AppLogger.LogInfo("Commands/Multidrop", `New user (${interaction.user.id}) saved to the database`); + } + + if (user.Currency < CardConstants.MultidropCost) { + await interaction.reply(ErrorMessages.NotEnoughCurrency(CardConstants.MultidropCost, user.Currency)); + return; + } + + user.RemoveCurrency(CardConstants.MultidropCost); + await user.Save(User, user); + + const randomCard = CardDropHelperMetadata.GetRandomCard(); + const cardsRemaining = CardConstants.MultidropQuantity - 1; + + if (!randomCard) { + AppLogger.LogWarn("Commands/Multidrop", ErrorMessages.UnableToFetchCard); + await interaction.reply(ErrorMessages.UnableToFetchCard); + return; + } + + await interaction.deferReply(); + + try { + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path)); + const imageFileName = randomCard.card.path.split("/").pop()!; + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); + const quantityClaimed = inventory ? inventory.Quantity : 0; + + const embed = CardDropHelperMetadata.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); + + const row = CardDropHelperMetadata.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id); + + await interaction.editReply({ + embeds: [ embed ], + files: [ attachment ], + components: [ row ], + }); + } catch (e) { + AppLogger.LogError("Commands/Multidrop", `Error sending next drop for card ${randomCard.card.id}: ${e}`); + + await interaction.editReply(`Unable to send next drop. Please try again, and report this if it keeps happening. (${randomCard.card.id})`); + } + } +} \ No newline at end of file diff --git a/src/constants/CardConstants.ts b/src/constants/CardConstants.ts index 0a87e22..3f9723b 100644 --- a/src/constants/CardConstants.ts +++ b/src/constants/CardConstants.ts @@ -3,4 +3,8 @@ export default class CardConstants { public static readonly TimerGiveAmount = 10; public static readonly DailyCurrency = 100; public static readonly StartingCurrency = 300; + + // Multidrop + public static readonly MultidropCost = this.ClaimCost * 10; + public static readonly MultidropQuantity = 11; } \ No newline at end of file diff --git a/src/constants/ErrorMessages.ts b/src/constants/ErrorMessages.ts new file mode 100644 index 0000000..c8749ec --- /dev/null +++ b/src/constants/ErrorMessages.ts @@ -0,0 +1,8 @@ +export default class ErrorMessages { + public static readonly BotSyncing = "Bot is currently syncing, please wait until its done."; + public static readonly SafeMode = "Safe Mode has been activated, please resync to continue."; + public static readonly UnableToFetchCard = "Unable to fetch card, please try again."; + public static readonly UnableToFetchUser = "Unable to fetch user, please try again."; + + public static readonly NotEnoughCurrency = (need: number, have: number) => `Not enough currency! You need ${need} currency, you have ${have}!`; +} \ No newline at end of file diff --git a/src/helpers/CardDropHelperMetadata.ts b/src/helpers/CardDropHelperMetadata.ts index bc59e93..8b9b273 100644 --- a/src/helpers/CardDropHelperMetadata.ts +++ b/src/helpers/CardDropHelperMetadata.ts @@ -1,5 +1,5 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; -import { CardRarity, CardRarityToColour, CardRarityToString } from "../constants/CardRarity"; +import { CardRarity, CardRarityToColour, CardRarityToString, GetSacrificeAmount } from "../constants/CardRarity"; import CardRarityChances from "../constants/CardRarityChances"; import { DropResult } from "../contracts/SeriesMetadata"; import { CoreClient } from "../client/client"; @@ -89,7 +89,7 @@ export default class CardDropHelperMetadata { const hexCode = Number("0x" + drop.card.colour); if (hexCode) { - colour = hexCode; + colour = hexCode; } else { AppLogger.LogWarn("CardDropHelperMetadata/GenerateDropEmbed", `Card's colour override is invalid: ${drop.card.id}, ${drop.card.colour}`); } @@ -149,4 +149,26 @@ export default class CardDropHelperMetadata { .setLabel("Reroll") .setStyle(ButtonStyle.Secondary)); } + + public static GenerateMultidropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, cardsRemaining: number, claimedBy?: string, currency?: number): EmbedBuilder { + const dropEmbed = this.GenerateDropEmbed(drop, quantityClaimed, imageFileName, claimedBy, currency); + + dropEmbed.setFooter({ text: `${dropEmbed.data.footer?.text} · ${cardsRemaining} Remaining`}); + + return dropEmbed; + } + + public static GenerateMultidropButtons(drop: DropResult, cardsRemaining: number, userId: string, disabled = false): ActionRowBuilder { + return new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId(`multidrop keep ${drop.card.id} ${cardsRemaining} ${userId}`) + .setLabel("Keep") + .setStyle(ButtonStyle.Primary) + .setDisabled(disabled), + new ButtonBuilder() + .setCustomId(`multidrop sacrifice ${drop.card.id} ${cardsRemaining} ${userId}`) + .setLabel(`Sacrifice (+${GetSacrificeAmount(drop.card.type)} 🪙)`) + .setStyle(ButtonStyle.Secondary)); + } } diff --git a/src/registry.ts b/src/registry.ts index 67936c8..e4e5d64 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -11,6 +11,7 @@ import Gdrivesync from "./commands/gdrivesync"; import Give from "./commands/give"; import Id from "./commands/id"; import Inventory from "./commands/inventory"; +import Multidrop from "./commands/multidrop"; import Resync from "./commands/resync"; import Sacrifice from "./commands/sacrifice"; import Series from "./commands/series"; @@ -25,6 +26,7 @@ import Droprarity from "./commands/stage/droprarity"; // Button Event Imports import Claim from "./buttonEvents/Claim"; import InventoryButtonEvent from "./buttonEvents/Inventory"; +import MultidropButtonEvent from "./buttonEvents/Multidrop"; import Reroll from "./buttonEvents/Reroll"; import SacrificeButtonEvent from "./buttonEvents/Sacrifice"; import SeriesEvent from "./buttonEvents/Series"; @@ -46,6 +48,7 @@ export default class Registry { CoreClient.RegisterCommand("give", new Give()); CoreClient.RegisterCommand("id", new Id()); CoreClient.RegisterCommand("inventory", new Inventory()); + CoreClient.RegisterCommand("multidrop", new Multidrop()); CoreClient.RegisterCommand("resync", new Resync()); CoreClient.RegisterCommand("sacrifice", new Sacrifice()); CoreClient.RegisterCommand("series", new Series()); @@ -61,6 +64,7 @@ export default class Registry { public static RegisterButtonEvents() { CoreClient.RegisterButtonEvent("claim", new Claim()); CoreClient.RegisterButtonEvent("inventory", new InventoryButtonEvent()); + CoreClient.RegisterButtonEvent("multidrop", new MultidropButtonEvent()); CoreClient.RegisterButtonEvent("reroll", new Reroll()); CoreClient.RegisterButtonEvent("sacrifice", new SacrificeButtonEvent()); CoreClient.RegisterButtonEvent("series", new SeriesEvent()); From 73caf9315d90277e3db2e4cf040c1179b4cd539b Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 12 Oct 2024 20:56:13 +0100 Subject: [PATCH 34/59] Fix build --- src/database/entities/app/Inventory.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/database/entities/app/Inventory.ts b/src/database/entities/app/Inventory.ts index 258527d..c780dad 100644 --- a/src/database/entities/app/Inventory.ts +++ b/src/database/entities/app/Inventory.ts @@ -29,10 +29,6 @@ export default class Inventory extends AppBaseEntity { this.Quantity = quantity; } - public AddQuantity(amount: number) { - this.Quantity += amount; - } - public RemoveQuantity(amount: number) { if (this.Quantity < amount) return; From 3304779297eeed73a458c22143d155ef6deea254 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 15 Oct 2024 18:54:29 +0100 Subject: [PATCH 35/59] Update dependency @types/node to v20.16.11 (#391) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.16.10` -> `20.16.11`](https://renovatebot.com/diffs/npm/@types%2fnode/20.16.10/20.16.11) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/391 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e379630..039a773 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1282,9 +1282,9 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.16.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.10.tgz#0cc3fdd3daf114a4776f54ba19726a01c907ef71" - integrity sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA== + version "20.16.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.11.tgz#9b544c3e716b1577ac12e70f9145193f32750b33" + integrity sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw== dependencies: undici-types "~6.19.2" From 4c322f01dee0ff73a9b3bdb755cfe6f7fdd9fb0b Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 15 Oct 2024 18:55:49 +0100 Subject: [PATCH 36/59] Update dependency express to v4.21.1 (#392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [express](http://expressjs.com/) ([source](https://github.com/expressjs/express)) | dependencies | patch | [`4.21.0` -> `4.21.1`](https://renovatebot.com/diffs/npm/express/4.21.0/4.21.1) | --- ### Release Notes
expressjs/express (express) ### [`v4.21.1`](https://github.com/expressjs/express/releases/tag/4.21.1) [Compare Source](https://github.com/expressjs/express/compare/4.21.0...4.21.1) #### What's Changed - Backport a fix for CVE-2024-47764 to the 4.x branch by [@​joshbuker](https://github.com/joshbuker) in https://github.com/expressjs/express/pull/6029 - Release: 4.21.1 by [@​UlisesGascon](https://github.com/UlisesGascon) in https://github.com/expressjs/express/pull/6031 **Full Changelog**: https://github.com/expressjs/express/compare/4.21.0...4.21.1
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/392 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 039a773..6d229d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2338,10 +2338,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" - integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== +cookie@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" + integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== cookiejar@^2.1.2: version "2.1.4" @@ -2921,16 +2921,16 @@ expect@^29.0.0, expect@^29.7.0: jest-util "^29.7.0" express@^4.18.2: - version "4.21.0" - resolved "https://registry.yarnpkg.com/express/-/express-4.21.0.tgz#d57cb706d49623d4ac27833f1cbc466b668eb915" - integrity sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng== + version "4.21.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.21.1.tgz#9dae5dda832f16b4eec941a4e44aa89ec481b281" + integrity sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ== dependencies: accepts "~1.3.8" array-flatten "1.1.1" body-parser "1.20.3" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.6.0" + cookie "0.7.1" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" From 27c0e68f7ae1e7295dbfcc261d4e5498c23d33a2 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 24 Oct 2024 17:48:09 +0100 Subject: [PATCH 37/59] Update dependency @types/node to v20.16.13 (#398) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.16.11` -> `20.16.13`](https://renovatebot.com/diffs/npm/@types%2fnode/20.16.11/20.16.13) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/398 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6d229d7..8dc3bcf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1282,9 +1282,9 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.16.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.11.tgz#9b544c3e716b1577ac12e70f9145193f32750b33" - integrity sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw== + version "20.16.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.13.tgz#148c152d757dc73f8d65f0f6f078f39050b85b0c" + integrity sha512-GjQ7im10B0labo8ZGXDGROUl9k0BNyDgzfGpb4g/cl+4yYDWVKcozANF4FGr4/p0O/rAkQClM6Wiwkije++1Tg== dependencies: undici-types "~6.19.2" From 9e963d90cb4ab252346aa6fb590ff32a36003b69 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 24 Oct 2024 17:49:55 +0100 Subject: [PATCH 38/59] Update dependency typescript to v5.6.3 (#399) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [typescript](https://www.typescriptlang.org/) ([source](https://github.com/microsoft/TypeScript)) | devDependencies | patch | [`5.6.2` -> `5.6.3`](https://renovatebot.com/diffs/npm/typescript/5.6.2/5.6.3) | --- ### Release Notes
microsoft/TypeScript (typescript) ### [`v5.6.3`](https://github.com/microsoft/TypeScript/releases/tag/v5.6.3): TypeScript 5.6.3 [Compare Source](https://github.com/microsoft/TypeScript/compare/v5.6.2...v5.6.3) For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-6/). For the complete list of fixed issues, check out the - [fixed issues query for Typescript 5.6.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+5.6.0%22+is%3Aclosed+). - [fixed issues query for Typescript 5.6.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+5.6.1%22+is%3Aclosed+). - [fixed issues query for Typescript 5.6.2 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+5.6.2%22+is%3Aclosed+). - [fixed issues query for Typescript 5.6.3 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+5.6.3%22+is%3Aclosed+). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) - [NuGet package](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/399 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8dc3bcf..8352304 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6685,9 +6685,9 @@ types-pkg-json@^1.1.0: types-json "^1.2.2" typescript@^5.0.0: - version "5.6.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" - integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== + version "5.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" + integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== undici-types@~6.19.2: version "6.19.8" From e67efd4197664d20d481be6e213f8905cce47f90 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Mon, 28 Oct 2024 12:03:12 +0000 Subject: [PATCH 39/59] Upgrade packages --- package.json | 24 +- src/buttonEvents/Claim.ts | 1 + src/helpers/ImageHelper.ts | 4 +- yarn.lock | 2751 ++++++++++++++---------------------- 4 files changed, 1047 insertions(+), 1733 deletions(-) diff --git a/package.json b/package.json index 8b068bc..7e10c7f 100644 --- a/package.json +++ b/package.json @@ -27,37 +27,35 @@ "dependencies": { "@discordjs/rest": "^2.0.0", "@types/clone-deep": "^4.0.4", - "@types/express": "^4.17.20", - "@types/jest": "^29.0.0", + "@types/express": "^5.0.0", + "@types/jest": "^29.5.14", "@types/uuid": "^10.0.0", "body-parser": "^1.20.2", "canvas": "^2.11.2", "clone-deep": "^4.0.1", "cron": "^3.1.7", - "discord.js": "^14.15.3", + "discord.js": "^14.16.3", "dotenv": "^16.0.0", "express": "^4.18.2", "fuse.js": "^7.0.0", "glob": "^11.0.0", "jest": "^29.0.0", "jest-mock-extended": "^3.0.0", - "jimp": "^0.22.12", + "jimp": "^1.6.0", "mysql": "^2.18.1", "ts-jest": "^29.0.0", "typeorm": "0.3.20", - "winston": "^3.11.0", + "winston": "^3.15.0", "winston-daily-rotate-file": "^5.0.0", "winston-discord-transport": "^1.3.0" }, - "resolutions": { - "**/ws": "^8.17.1" - }, + "resolutions": {}, "devDependencies": { - "@types/node": "^20.0.0", - "@typescript-eslint/eslint-plugin": "^7.0.0", - "@typescript-eslint/parser": "^6.16.0", - "eslint": "^8.56.0", - "np": "^9.0.0", + "@types/node": "^22.8.1", + "@typescript-eslint/eslint-plugin": "^8.11.0", + "@typescript-eslint/parser": "^8.11.0", + "eslint": "^9.13.0", + "np": "^10.0.7", "typescript": "^5.0.0" } } diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts index 190a09e..522ab40 100644 --- a/src/buttonEvents/Claim.ts +++ b/src/buttonEvents/Claim.ts @@ -12,6 +12,7 @@ export default class Claim extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { if (!interaction.guild || !interaction.guildId) return; if (!interaction.channel) return; + if (!interaction.channel.isSendable()) return; await interaction.deferUpdate(); diff --git a/src/helpers/ImageHelper.ts b/src/helpers/ImageHelper.ts index be3d083..4e43977 100644 --- a/src/helpers/ImageHelper.ts +++ b/src/helpers/ImageHelper.ts @@ -3,7 +3,7 @@ import path from "path"; import AppLogger from "../client/appLogger"; import {existsSync} from "fs"; import Inventory from "../database/entities/app/Inventory"; -import Jimp from "jimp"; +import {Jimp} from "jimp"; interface CardInput { id: string; @@ -46,7 +46,7 @@ export default class ImageHelper { } } - const image = await loadImage(await imageData.getBufferAsync("image/png")); + const image = await loadImage(await imageData.getBuffer("image/png")); const x = i % gridWidth; const y = Math.floor(i / gridWidth); diff --git a/yarn.lock b/yarn.lock index 8352304..93f7d56 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,163 +10,114 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.6.tgz#ab88da19344445c3d8889af2216606d3329f3ef2" - integrity sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.0.tgz#9374b5cd068d128dac0b94ff482594273b1c2815" + integrity sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g== dependencies: - "@babel/highlight" "^7.24.6" + "@babel/helper-validator-identifier" "^7.25.9" + js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/code-frame@^7.12.13": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" - integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== - dependencies: - "@babel/highlight" "^7.24.7" - picocolors "^1.0.0" - -"@babel/compat-data@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.6.tgz#b3600217688cabb26e25f8e467019e66d71b7ae2" - integrity sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ== +"@babel/compat-data@^7.25.9": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.0.tgz#f02ba6d34e88fadd5e8861e8b38902f43cc1c819" + integrity sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA== "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.6.tgz#8650e0e4b03589ebe886c4e4a60398db0a7ec787" - integrity sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ== + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40" + integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.24.6" - "@babel/generator" "^7.24.6" - "@babel/helper-compilation-targets" "^7.24.6" - "@babel/helper-module-transforms" "^7.24.6" - "@babel/helpers" "^7.24.6" - "@babel/parser" "^7.24.6" - "@babel/template" "^7.24.6" - "@babel/traverse" "^7.24.6" - "@babel/types" "^7.24.6" + "@babel/code-frame" "^7.26.0" + "@babel/generator" "^7.26.0" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-module-transforms" "^7.26.0" + "@babel/helpers" "^7.26.0" + "@babel/parser" "^7.26.0" + "@babel/template" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.26.0" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.24.6", "@babel/generator@^7.7.2": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.6.tgz#dfac82a228582a9d30c959fe50ad28951d4737a7" - integrity sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg== +"@babel/generator@^7.25.9", "@babel/generator@^7.26.0", "@babel/generator@^7.7.2": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.0.tgz#505cc7c90d92513f458a477e5ef0703e7c91b8d7" + integrity sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w== dependencies: - "@babel/types" "^7.24.6" + "@babel/parser" "^7.26.0" + "@babel/types" "^7.26.0" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^2.5.1" + jsesc "^3.0.2" -"@babel/helper-compilation-targets@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.6.tgz#4a51d681f7680043d38e212715e2a7b1ad29cb51" - integrity sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg== +"@babel/helper-compilation-targets@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875" + integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ== dependencies: - "@babel/compat-data" "^7.24.6" - "@babel/helper-validator-option" "^7.24.6" - browserslist "^4.22.2" + "@babel/compat-data" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + browserslist "^4.24.0" lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-environment-visitor@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.6.tgz#ac7ad5517821641550f6698dd5468f8cef78620d" - integrity sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g== - -"@babel/helper-function-name@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.24.6.tgz#cebdd063386fdb95d511d84b117e51fc68fec0c8" - integrity sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w== +"@babel/helper-module-imports@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715" + integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw== dependencies: - "@babel/template" "^7.24.6" - "@babel/types" "^7.24.6" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/helper-hoist-variables@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.6.tgz#8a7ece8c26756826b6ffcdd0e3cf65de275af7f9" - integrity sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA== +"@babel/helper-module-transforms@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae" + integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw== dependencies: - "@babel/types" "^7.24.6" + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/helper-module-imports@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz#65e54ffceed6a268dc4ce11f0433b82cfff57852" - integrity sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.25.9", "@babel/helper-plugin-utils@^7.8.0": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46" + integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw== + +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== + +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + +"@babel/helper-validator-option@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72" + integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw== + +"@babel/helpers@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4" + integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw== dependencies: - "@babel/types" "^7.24.6" + "@babel/template" "^7.25.9" + "@babel/types" "^7.26.0" -"@babel/helper-module-transforms@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.6.tgz#22346ed9df44ce84dee850d7433c5b73fab1fe4e" - integrity sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.25.9", "@babel/parser@^7.26.0": + version "7.26.1" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.1.tgz#44e02499960df2cdce2c456372a3e8e0c3c5c975" + integrity sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw== dependencies: - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-module-imports" "^7.24.6" - "@babel/helper-simple-access" "^7.24.6" - "@babel/helper-split-export-declaration" "^7.24.6" - "@babel/helper-validator-identifier" "^7.24.6" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.24.6", "@babel/helper-plugin-utils@^7.8.0": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz#fa02a32410a15a6e8f8185bcbf608f10528d2a24" - integrity sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg== - -"@babel/helper-simple-access@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.6.tgz#1d6e04d468bba4fc963b4906f6dac6286cfedff1" - integrity sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g== - dependencies: - "@babel/types" "^7.24.6" - -"@babel/helper-split-export-declaration@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz#e830068f7ba8861c53b7421c284da30ae656d7a3" - integrity sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw== - dependencies: - "@babel/types" "^7.24.6" - -"@babel/helper-string-parser@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz#28583c28b15f2a3339cfafafeaad42f9a0e828df" - integrity sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q== - -"@babel/helper-validator-identifier@^7.24.6", "@babel/helper-validator-identifier@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" - integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== - -"@babel/helper-validator-option@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.6.tgz#59d8e81c40b7d9109ab7e74457393442177f460a" - integrity sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ== - -"@babel/helpers@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.6.tgz#cd124245299e494bd4e00edda0e4ea3545c2c176" - integrity sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA== - dependencies: - "@babel/template" "^7.24.6" - "@babel/types" "^7.24.6" - -"@babel/highlight@^7.24.6", "@babel/highlight@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" - integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== - dependencies: - "@babel/helper-validator-identifier" "^7.24.7" - chalk "^2.4.2" - js-tokens "^4.0.0" - picocolors "^1.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.6.tgz#5e030f440c3c6c78d195528c3b688b101a365328" - integrity sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q== + "@babel/types" "^7.26.0" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -182,14 +133,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-import-meta@^7.8.3": +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-import-attributes@^7.24.7": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz#3b1412847699eea739b4f2602c74ce36f6b0b0f7" + integrity sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-syntax-import-meta@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== @@ -204,13 +169,13 @@ "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-jsx@^7.7.2": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.6.tgz#bcca2964150437f88f65e3679e3d68762287b9c8" - integrity sha512-lWfvAIFNWMlCsU0DRUun2GpFwZdGTukLaHJqRh1JRb80NdAP5Sb1HDHB5X9P9OtgZHQl089UzQkpYlBq2VTPRw== + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz#a34313a178ea56f1951599b929c1ceacee719290" + integrity sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== @@ -224,7 +189,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.8.3": +"@babel/plugin-syntax-numeric-separator@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== @@ -252,7 +217,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.8.3": +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== @@ -260,60 +232,47 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.7.2": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.6.tgz#769daf2982d60308bc83d8936eaecb7582463c87" - integrity sha512-TzCtxGgVTEJWWwcYwQhCIQ6WaKlo80/B+Onsk4RRCcYqpYGFcG9etPW94VToGte5AAcxRrhjPUFvUS3Y2qKi4A== + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz#67dda2b74da43727cf21d46cf9afef23f4365399" + integrity sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/template@^7.24.6", "@babel/template@^7.3.3": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.6.tgz#048c347b2787a6072b24c723664c8d02b67a44f9" - integrity sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw== +"@babel/template@^7.25.9", "@babel/template@^7.3.3": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016" + integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg== dependencies: - "@babel/code-frame" "^7.24.6" - "@babel/parser" "^7.24.6" - "@babel/types" "^7.24.6" + "@babel/code-frame" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/traverse@^7.24.6": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.6.tgz#0941ec50cdeaeacad0911eb67ae227a4f8424edc" - integrity sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw== +"@babel/traverse@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84" + integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw== dependencies: - "@babel/code-frame" "^7.24.6" - "@babel/generator" "^7.24.6" - "@babel/helper-environment-visitor" "^7.24.6" - "@babel/helper-function-name" "^7.24.6" - "@babel/helper-hoist-variables" "^7.24.6" - "@babel/helper-split-export-declaration" "^7.24.6" - "@babel/parser" "^7.24.6" - "@babel/types" "^7.24.6" + "@babel/code-frame" "^7.25.9" + "@babel/generator" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/template" "^7.25.9" + "@babel/types" "^7.25.9" debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.6", "@babel/types@^7.3.3": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.6.tgz#ba4e1f59870c10dc2fa95a274ac4feec23b21912" - integrity sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.3.3": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff" + integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA== dependencies: - "@babel/helper-string-parser" "^7.24.6" - "@babel/helper-validator-identifier" "^7.24.6" - to-fast-properties "^2.0.0" + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@bconnorwhite/module@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@bconnorwhite/module/-/module-2.0.2.tgz#557846110bb89412e9689ac778358bc2b1af0c4a" - integrity sha512-ck1me5WMgZKp06gnJrVKEkytpehTTQbvsAMbF1nGPeHri/AZNhj87++PSE2LOxmZqM0EtGMaqeLdx7Lw7SUnTA== - dependencies: - find-up "^5.0.0" - read-json-safe "^1.0.5" - types-pkg-json "^1.1.0" - "@colors/colors@1.6.0", "@colors/colors@^1.6.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" @@ -328,42 +287,37 @@ enabled "2.0.x" kuler "^2.0.0" -"@discordjs/builders@^1.8.2": - version "1.8.2" - resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-1.8.2.tgz#535d970331ee40f20dec9ef8079e43092f323ce9" - integrity sha512-6wvG3QaCjtMu0xnle4SoOIeFB4y6fKMN6WZfy3BMKJdQQtPLik8KGzDwBVL/+wTtcE/ZlFjgEk74GublyEVZ7g== +"@discordjs/builders@^1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-1.9.0.tgz#71fa6de91132bd1deaff2a9daea7aa5d5c9f124a" + integrity sha512-0zx8DePNVvQibh5ly5kCEei5wtPBIUbSoE9n+91Rlladz4tgtFbJ36PZMxxZrTEOQ7AHMZ/b0crT/0fCy6FTKg== dependencies: - "@discordjs/formatters" "^0.4.0" - "@discordjs/util" "^1.1.0" - "@sapphire/shapeshift" "^3.9.7" - discord-api-types "0.37.83" + "@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.2" + tslib "^2.6.3" "@discordjs/collection@1.5.3": version "1.5.3" resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-1.5.3.tgz#5a1250159ebfff9efa4f963cfa7e97f1b291be18" integrity sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ== -"@discordjs/collection@^2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-2.1.0.tgz#f327d944ab2dcf9a1f674470a481f78a120a5e3b" - integrity sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw== - -"@discordjs/collection@^2.1.1": +"@discordjs/collection@^2.1.0", "@discordjs/collection@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-2.1.1.tgz#901917bc538c12b9c3613036d317847baee08cae" integrity sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg== -"@discordjs/formatters@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@discordjs/formatters/-/formatters-0.4.0.tgz#066a2c2163b26ac066e6f621f17445be9690c6a9" - integrity sha512-fJ06TLC1NiruF35470q3Nr1bi95BdvKFAF+T5bNfZJ4bNdqZ3VZ+Ttg6SThqTxm6qumSG3choxLBHMC69WXNXQ== +"@discordjs/formatters@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@discordjs/formatters/-/formatters-0.5.0.tgz#2d284c4271bc41984339936df1d0164e470f3b7a" + integrity sha512-98b3i+Y19RFq1Xke4NkVY46x8KjJQjldHUuEbCqMvp1F5Iq9HgnGpu91jOi/Ufazhty32eRsKnnzS8n4c+L93g== dependencies: - discord-api-types "0.37.83" + discord-api-types "0.37.97" -"@discordjs/rest@^2.0.0", "@discordjs/rest@^2.3.0": +"@discordjs/rest@^2.0.0", "@discordjs/rest@^2.3.0", "@discordjs/rest@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@discordjs/rest/-/rest-2.4.0.tgz#63bfc816af58af844914e3589d7eae609cd199b5" integrity sha512-Xb2irDqNcq+O8F0/k/NaDp7+t091p+acb51iA4bCKfIn+WFWd6HrNvcsSbMMxIR9NjcMZS6NReTKygqiQN+ntw== @@ -378,17 +332,12 @@ tslib "^2.6.3" undici "6.19.8" -"@discordjs/util@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@discordjs/util/-/util-1.1.0.tgz#dcffd2b61aab8eadd66bea67811bc34fc769bb2a" - integrity sha512-IndcI5hzlNZ7GS96RV3Xw1R2kaDuXEp7tRIy/KlhidpN/BQ1qh1NZt3377dMLTa44xDUNKT7hnXkA/oUAzD/lg== - -"@discordjs/util@^1.1.1": +"@discordjs/util@^1.1.0", "@discordjs/util@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@discordjs/util/-/util-1.1.1.tgz#bafcde0faa116c834da1258d78ec237080bbab29" integrity sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g== -"@discordjs/ws@^1.1.1": +"@discordjs/ws@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@discordjs/ws/-/ws-1.1.1.tgz#bffbfd46838258ab09054ed98ddef1a36f6507a3" integrity sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA== @@ -404,65 +353,90 @@ ws "^8.16.0" "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + version "4.4.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56" + integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA== dependencies: - eslint-visitor-keys "^3.3.0" + eslint-visitor-keys "^3.4.3" -"@eslint-community/regexpp@^4.10.0": - version "4.11.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" - integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.11.0": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== -"@eslint-community/regexpp@^4.6.1": - version "4.11.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" - integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== +"@eslint/config-array@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.18.0.tgz#37d8fe656e0d5e3dbaea7758ea56540867fd074d" + integrity sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw== + dependencies: + "@eslint/object-schema" "^2.1.4" + debug "^4.3.1" + minimatch "^3.1.2" -"@eslint/eslintrc@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" - integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== +"@eslint/core@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.7.0.tgz#a1bb4b6a4e742a5ff1894b7ee76fbf884ec72bd3" + integrity sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw== + +"@eslint/eslintrc@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.1.0.tgz#dbd3482bfd91efa663cbe7aa1f506839868207b6" + integrity sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" + espree "^10.0.1" + globals "^14.0.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" -"@eslint/js@8.57.1": - version "8.57.1" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" - integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== +"@eslint/js@9.13.0": + version "9.13.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.13.0.tgz#c5f89bcd57eb54d5d4fa8b77693e9c28dc97e547" + integrity sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA== -"@humanwhocodes/config-array@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" - integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== +"@eslint/object-schema@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843" + integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ== + +"@eslint/plugin-kit@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz#cd14fe2db79fa639839dfef4105e83bad1814482" + integrity sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw== dependencies: - "@humanwhocodes/object-schema" "^2.0.3" - debug "^4.3.1" - minimatch "^3.0.5" + levn "^0.4.1" + +"@humanfs/core@^0.19.0": + version "0.19.0" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.0.tgz#08db7a8c73bb07673d9ebd925f2dad746411fcec" + integrity sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw== + +"@humanfs/node@^0.16.5": + version "0.16.5" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.5.tgz#a9febb7e7ad2aff65890fdc630938f8d20aa84ba" + integrity sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg== + dependencies: + "@humanfs/core" "^0.19.0" + "@humanwhocodes/retry" "^0.3.0" "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" - integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@humanwhocodes/retry@^0.3.0", "@humanwhocodes/retry@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" + integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== "@inquirer/figures@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.3.tgz#1227cc980f88e6d6ab85abadbf164f5038041edd" - integrity sha512-ErXXzENMH5pJt5/ssXV0DfWUZqly8nGzf0UcBV9xTnP+KyffE2mqyxIMBrZ8ijQck2nU0TQm40EQB53YreyWHw== + version "1.0.7" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.7.tgz#d050ccc0eabfacc0248c4ff647a9dfba1b01594b" + integrity sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw== "@isaacs/cliui@^8.0.2": version "8.0.2" @@ -684,262 +658,278 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jimp/bmp@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.22.12.tgz#0316044dc7b1a90274aef266d50349347fb864d4" - integrity sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g== +"@jimp/core@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/core/-/core-1.6.0.tgz#3ef241bf02f40431bb382aea665e5187a2c05eef" + integrity sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w== dependencies: - "@jimp/utils" "^0.22.12" - bmp-js "^0.1.0" - -"@jimp/core@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.22.12.tgz#70785ea7d10b138fb65bcfe9f712826f00a10e1d" - integrity sha512-l0RR0dOPyzMKfjUW1uebzueFEDtCOj9fN6pyTYWWOM/VS4BciXQ1VVrJs8pO3kycGYZxncRKhCoygbNr8eEZQA== - dependencies: - "@jimp/utils" "^0.22.12" - any-base "^1.1.0" - buffer "^5.2.0" + "@jimp/file-ops" "1.6.0" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + await-to-js "^3.0.0" exif-parser "^0.1.12" - file-type "^16.5.4" - isomorphic-fetch "^3.0.0" - pixelmatch "^4.0.2" - tinycolor2 "^1.6.0" + file-type "^16.0.0" + mime "3" -"@jimp/custom@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.22.12.tgz#236f2a3f016b533c50869ff22ad1ac00dd0c36be" - integrity sha512-xcmww1O/JFP2MrlGUMd3Q78S3Qu6W3mYTXYuIqFq33EorgYHV/HqymHfXy9GjiCJ7OI+7lWx6nYFOzU7M4rd1Q== +"@jimp/diff@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/diff/-/diff-1.6.0.tgz#f8d058bfad64751c5e5c135499d1a784f797c5c8" + integrity sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw== dependencies: - "@jimp/core" "^0.22.12" + "@jimp/plugin-resize" "1.6.0" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + pixelmatch "^5.3.0" -"@jimp/gif@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.22.12.tgz#6caccb45df497fb971b7a88690345596e22163c0" - integrity sha512-y6BFTJgch9mbor2H234VSjd9iwAhaNf/t3US5qpYIs0TSbAvM02Fbc28IaDETj9+4YB4676sz4RcN/zwhfu1pg== +"@jimp/file-ops@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/file-ops/-/file-ops-1.6.0.tgz#ae9c6aa65b2c9a5a16515a8fdf83b55f51100087" + integrity sha512-Dx/bVDmgnRe1AlniRpCKrGRm5YvGmUwbDzt+MAkgmLGf+jvBT75hmMEZ003n9HQI/aPnm/YKnXjg/hOpzNCpHQ== + +"@jimp/js-bmp@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/js-bmp/-/js-bmp-1.6.0.tgz#ff7c4306e764745063e249ee926d0dd807924abf" + integrity sha512-FU6Q5PC/e3yzLyBDXupR3SnL3htU7S3KEs4e6rjDP6gNEOXRFsWs6YD3hXuXd50jd8ummy+q2WSwuGkr8wi+Gw== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + bmp-ts "^1.0.9" + +"@jimp/js-gif@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/js-gif/-/js-gif-1.6.0.tgz#0efa5d83317a89d6eda936e2ae1df2b7d122a38d" + integrity sha512-N9CZPHOrJTsAUoWkWZstLPpwT5AwJ0wge+47+ix3++SdSL/H2QzyMqxbcDYNFe4MoI5MIhATfb0/dl/wmX221g== + dependencies: + "@jimp/core" "1.6.0" + "@jimp/types" "1.6.0" gifwrap "^0.10.1" - omggif "^1.0.9" + omggif "^1.0.10" -"@jimp/jpeg@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.22.12.tgz#b5c74a5aac9826245311370dda8c71a1fcca05ed" - integrity sha512-Rq26XC/uQWaQKyb/5lksCTCxXhtY01NJeBN+dQv5yNYedN0i7iYu+fXEoRsfaJ8xZzjoANH8sns7rVP4GE7d/Q== +"@jimp/js-jpeg@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/js-jpeg/-/js-jpeg-1.6.0.tgz#e47da6758346548079f0ac8ff215d0d9d1ec435e" + integrity sha512-6vgFDqeusblf5Pok6B2DUiMXplH8RhIKAryj1yn+007SIAQ0khM1Uptxmpku/0MfbClx2r7pnJv9gWpAEJdMVA== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/types" "1.6.0" jpeg-js "^0.4.4" -"@jimp/plugin-blit@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.22.12.tgz#0fa8320767fda77434b4408798655ff7c7e415d4" - integrity sha512-xslz2ZoFZOPLY8EZ4dC29m168BtDx95D6K80TzgUi8gqT7LY6CsajWO0FAxDwHz6h0eomHMfyGX0stspBrTKnQ== +"@jimp/js-png@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/js-png/-/js-png-1.6.0.tgz#c857adfdbfcb7107a6511c3b2939ffbad0fefedc" + integrity sha512-AbQHScy3hDDgMRNfG0tPjL88AV6qKAILGReIa3ATpW5QFjBKpisvUaOqhzJ7Reic1oawx3Riyv152gaPfqsBVg== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/types" "1.6.0" + pngjs "^7.0.0" -"@jimp/plugin-blur@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.22.12.tgz#0c37b2ff4e588b45f4307b4f13d3d0eef813920d" - integrity sha512-S0vJADTuh1Q9F+cXAwFPlrKWzDj2F9t/9JAbUvaaDuivpyWuImEKXVz5PUZw2NbpuSHjwssbTpOZ8F13iJX4uw== +"@jimp/js-tiff@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/js-tiff/-/js-tiff-1.6.0.tgz#f18fa3d59f52fda339acfdcadbe7363bed912e81" + integrity sha512-zhReR8/7KO+adijj3h0ZQUOiun3mXUv79zYEAKvE0O+rP7EhgtKvWJOZfRzdZSNv0Pu1rKtgM72qgtwe2tFvyw== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/types" "1.6.0" + utif2 "^4.1.0" -"@jimp/plugin-circle@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-circle/-/plugin-circle-0.22.12.tgz#9fffda83d3fc5bad8c1e1492b15b1433cb42e16e" - integrity sha512-SWVXx1yiuj5jZtMijqUfvVOJBwOifFn0918ou4ftoHgegc5aHWW5dZbYPjvC9fLpvz7oSlptNl2Sxr1zwofjTg== +"@jimp/plugin-blit@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-1.6.0.tgz#fed35aefbb5757599a4299a9ff6c06cc3466f46f" + integrity sha512-M+uRWl1csi7qilnSK8uxK4RJMSuVeBiO1AY0+7APnfUbQNZm6hCe0CCFv1Iyw1D/Dhb8ph8fQgm5mwM0eSxgVA== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-color@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.22.12.tgz#1e49f2e7387186507e917b0686599767c15be336" - integrity sha512-xImhTE5BpS8xa+mAN6j4sMRWaUgUDLoaGHhJhpC+r7SKKErYDR0WQV4yCE4gP+N0gozD0F3Ka1LUSaMXrn7ZIA== +"@jimp/plugin-blur@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-1.6.0.tgz#781b3be9de2744e5eb6ab86ec05ee7d2ce5092e8" + integrity sha512-zrM7iic1OTwUCb0g/rN5y+UnmdEsT3IfuCXCJJNs8SZzP0MkZ1eTvuwK9ZidCuMo4+J3xkzCidRwYXB5CyGZTw== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/utils" "1.6.0" + +"@jimp/plugin-circle@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-circle/-/plugin-circle-1.6.0.tgz#2314dc7955068cb4a000de4eceb02890eb131c88" + integrity sha512-xt1Gp+LtdMKAXfDp3HNaG30SPZW6AQ7dtAtTnoRKorRi+5yCJjKqXRgkewS5bvj8DEh87Ko1ydJfzqS3P2tdWw== + dependencies: + "@jimp/types" "1.6.0" + zod "^3.23.8" + +"@jimp/plugin-color@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-1.6.0.tgz#927c83ee932070ad285266840728c21ac39bf27b" + integrity sha512-J5q8IVCpkBsxIXM+45XOXTrsyfblyMZg3a9eAo0P7VPH4+CrvyNQwaYatbAIamSIN1YzxmO3DkIZXzRjFSz1SA== + dependencies: + "@jimp/core" "1.6.0" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" tinycolor2 "^1.6.0" + zod "^3.23.8" -"@jimp/plugin-contain@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-0.22.12.tgz#ed5ed9af3d4afd02a7568ff8d60603cff340e3f3" - integrity sha512-Eo3DmfixJw3N79lWk8q/0SDYbqmKt1xSTJ69yy8XLYQj9svoBbyRpSnHR+n9hOw5pKXytHwUW6nU4u1wegHNoQ== +"@jimp/plugin-contain@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-1.6.0.tgz#d08900ecf85ac564a6f9f3fc0d61cc8d5e43626e" + integrity sha512-oN/n+Vdq/Qg9bB4yOBOxtY9IPAtEfES8J1n9Ddx+XhGBYT1/QTU/JYkGaAkIGoPnyYvmLEDqMz2SGihqlpqfzQ== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/plugin-blit" "1.6.0" + "@jimp/plugin-resize" "1.6.0" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-cover@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-0.22.12.tgz#4abbfabe4c78c71d8d46e707c35a65dc55f08afd" - integrity sha512-z0w/1xH/v/knZkpTNx+E8a7fnasQ2wHG5ze6y5oL2dhH1UufNua8gLQXlv8/W56+4nJ1brhSd233HBJCo01BXA== +"@jimp/plugin-cover@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-1.6.0.tgz#07ffb2f3d6ac53616c66f1131cd66ced17e3ca3e" + integrity sha512-Iow0h6yqSC269YUJ8HC3Q/MpCi2V55sMlbkkTTx4zPvd8mWZlC0ykrNDeAy9IJegrQ7v5E99rJwmQu25lygKLA== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/plugin-crop" "1.6.0" + "@jimp/plugin-resize" "1.6.0" + "@jimp/types" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-crop@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-0.22.12.tgz#e28329a9f285071442998560b040048d2ef5c32e" - integrity sha512-FNuUN0OVzRCozx8XSgP9MyLGMxNHHJMFt+LJuFjn1mu3k0VQxrzqbN06yIl46TVejhyAhcq5gLzqmSCHvlcBVw== +"@jimp/plugin-crop@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-1.6.0.tgz#59f2b20869330fd768d1743d845b8ba9ed9bc52a" + integrity sha512-KqZkEhvs+21USdySCUDI+GFa393eDIzbi1smBqkUPTE+pRwSWMAf01D5OC3ZWB+xZsNla93BDS9iCkLHA8wang== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-displace@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-0.22.12.tgz#2e4b2b989a23da6687c49f2f628e1e6d686ec9b6" - integrity sha512-qpRM8JRicxfK6aPPqKZA6+GzBwUIitiHaZw0QrJ64Ygd3+AsTc7BXr+37k2x7QcyCvmKXY4haUrSIsBug4S3CA== +"@jimp/plugin-displace@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-1.6.0.tgz#41b3257a6c0f64c749c29c1a2e64ba7df31a7a25" + integrity sha512-4Y10X9qwr5F+Bo5ME356XSACEF55485j5nGdiyJ9hYzjQP9nGgxNJaZ4SAOqpd+k5sFaIeD7SQ0Occ26uIng5Q== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-dither@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-0.22.12.tgz#3cc5f3a58dbf85653c4e532d31a756a4fc8cabf7" - integrity sha512-jYgGdSdSKl1UUEanX8A85v4+QUm+PE8vHFwlamaKk89s+PXQe7eVE3eNeSZX4inCq63EHL7cX580dMqkoC3ZLw== +"@jimp/plugin-dither@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-1.6.0.tgz#10c17070dcbec565904f11b7986e90ae20850b6f" + integrity sha512-600d1RxY0pKwgyU0tgMahLNKsqEcxGdbgXadCiVCoGd6V6glyCvkNrnnwC0n5aJ56Htkj88PToSdF88tNVZEEQ== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/types" "1.6.0" -"@jimp/plugin-fisheye@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.12.tgz#77aef2f3ec59c0bafbd2dbc94b89eab60ce05a3e" - integrity sha512-LGuUTsFg+fOp6KBKrmLkX4LfyCy8IIsROwoUvsUPKzutSqMJnsm3JGDW2eOmWIS/jJpPaeaishjlxvczjgII+Q== +"@jimp/plugin-fisheye@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-fisheye/-/plugin-fisheye-1.6.0.tgz#2831c0060598b27bf004bf8a70adfeec003d4fcc" + integrity sha512-E5QHKWSCBFtpgZarlmN3Q6+rTQxjirFqo44ohoTjzYVrDI6B6beXNnPIThJgPr0Y9GwfzgyarKvQuQuqCnnfbA== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-flip@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-0.22.12.tgz#7e2154592da01afcf165a3f9d1d25032aa8d8c57" - integrity sha512-m251Rop7GN8W0Yo/rF9LWk6kNclngyjIJs/VXHToGQ6EGveOSTSQaX2Isi9f9lCDLxt+inBIb7nlaLLxnvHX8Q== +"@jimp/plugin-flip@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-1.6.0.tgz#75c87bdb0f0ca9db44b320cc9671aa201e52b5c3" + integrity sha512-/+rJVDuBIVOgwoyVkBjUFHtP+wmW0r+r5OQ2GpatQofToPVbJw1DdYWXlwviSx7hvixTWLKVgRWQ5Dw862emDg== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/types" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-gaussian@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.12.tgz#49a40950cedbbea6c84b3a6bccc45365fe78d6b7" - integrity sha512-sBfbzoOmJ6FczfG2PquiK84NtVGeScw97JsCC3rpQv1PHVWyW+uqWFF53+n3c8Y0P2HWlUjflEla2h/vWShvhg== +"@jimp/plugin-hash@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-hash/-/plugin-hash-1.6.0.tgz#8de89dfbbb6be671f9cdb2b59816acf3f07c4298" + integrity sha512-wWzl0kTpDJgYVbZdajTf+4NBSKvmI3bRI8q6EH9CVeIHps9VWVsUvEyb7rpbcwVLWYuzDtP2R0lTT6WeBNQH9Q== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/js-bmp" "1.6.0" + "@jimp/js-jpeg" "1.6.0" + "@jimp/js-png" "1.6.0" + "@jimp/js-tiff" "1.6.0" + "@jimp/plugin-color" "1.6.0" + "@jimp/plugin-resize" "1.6.0" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + any-base "^1.1.0" -"@jimp/plugin-invert@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-invert/-/plugin-invert-0.22.12.tgz#c569e85c1f59911a9a33ef36a51c9cf26065078e" - integrity sha512-N+6rwxdB+7OCR6PYijaA/iizXXodpxOGvT/smd/lxeXsZ/empHmFFFJ/FaXcYh19Tm04dGDaXcNF/dN5nm6+xQ== +"@jimp/plugin-mask@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-1.6.0.tgz#2b5a437e5d9a9906dcabb7a7baf4d5cd7d2361b1" + integrity sha512-Cwy7ExSJMZszvkad8NV8o/Z92X2kFUFM8mcDAhNVxU0Q6tA0op2UKRJY51eoK8r6eds/qak3FQkXakvNabdLnA== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/types" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-mask@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-0.22.12.tgz#0ac0d9c282f403255b126556521f90fb8e2997f0" - integrity sha512-4AWZg+DomtpUA099jRV8IEZUfn1wLv6+nem4NRJC7L/82vxzLCgXKTxvNvBcNmJjT9yS1LAAmiJGdWKXG63/NA== +"@jimp/plugin-print@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-1.6.0.tgz#ccef327f53afb47617aa66ca65435447380faf34" + integrity sha512-zarTIJi8fjoGMSI/M3Xh5yY9T65p03XJmPsuNet19K/Q7mwRU6EV2pfj+28++2PV2NJ+htDF5uecAlnGyxFN2A== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/js-jpeg" "1.6.0" + "@jimp/js-png" "1.6.0" + "@jimp/plugin-blit" "1.6.0" + "@jimp/types" "1.6.0" + parse-bmfont-ascii "^1.0.6" + parse-bmfont-binary "^1.0.6" + parse-bmfont-xml "^1.1.6" + simple-xml-to-json "^1.2.2" + zod "^3.23.8" -"@jimp/plugin-normalize@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-normalize/-/plugin-normalize-0.22.12.tgz#6c44d216f2489cf9b0e0f1e03aa5dfb97f198c53" - integrity sha512-0So0rexQivnWgnhacX4cfkM2223YdExnJTTy6d06WbkfZk5alHUx8MM3yEzwoCN0ErO7oyqEWRnEkGC+As1FtA== +"@jimp/plugin-quantize@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-quantize/-/plugin-quantize-1.6.0.tgz#880095fc0ead41321d94bf54895e366dd7d079d6" + integrity sha512-EmzZ/s9StYQwbpG6rUGBCisc3f64JIhSH+ncTJd+iFGtGo0YvSeMdAd+zqgiHpfZoOL54dNavZNjF4otK+mvlg== dependencies: - "@jimp/utils" "^0.22.12" + image-q "^4.0.0" + zod "^3.23.8" -"@jimp/plugin-print@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-0.22.12.tgz#6a49020947a9bf21a5a28324425670a25587ca65" - integrity sha512-c7TnhHlxm87DJeSnwr/XOLjJU/whoiKYY7r21SbuJ5nuH+7a78EW1teOaj5gEr2wYEd7QtkFqGlmyGXY/YclyQ== +"@jimp/plugin-resize@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-1.6.0.tgz#331e8912ed68746846145019bc6e2ea057e6f175" + integrity sha512-uSUD1mqXN9i1SGSz5ov3keRZ7S9L32/mAQG08wUwZiEi5FpbV0K8A8l1zkazAIZi9IJzLlTauRNU41Mi8IF9fA== dependencies: - "@jimp/utils" "^0.22.12" - load-bmfont "^1.4.1" + "@jimp/core" "1.6.0" + "@jimp/types" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-resize@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.22.12.tgz#f92acbf73beb97dd1fe93b166ef367a323b81e81" - integrity sha512-3NyTPlPbTnGKDIbaBgQ3HbE6wXbAlFfxHVERmrbqAi8R3r6fQPxpCauA8UVDnieg5eo04D0T8nnnNIX//i/sXg== +"@jimp/plugin-rotate@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-1.6.0.tgz#de271f39a3ac9e853b02e01d3d44ab086d12e099" + integrity sha512-JagdjBLnUZGSG4xjCLkIpQOZZ3Mjbg8aGCCi4G69qR+OjNpOeGI7N2EQlfK/WE8BEHOW5vdjSyglNqcYbQBWRw== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/plugin-crop" "1.6.0" + "@jimp/plugin-resize" "1.6.0" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-rotate@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.22.12.tgz#2235d45aeb4914ff70d99e95750a6d9de45a0d9f" - integrity sha512-9YNEt7BPAFfTls2FGfKBVgwwLUuKqy+E8bDGGEsOqHtbuhbshVGxN2WMZaD4gh5IDWvR+emmmPPWGgaYNYt1gA== +"@jimp/plugin-threshold@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-threshold/-/plugin-threshold-1.6.0.tgz#11479cf59131ea95dcaff6a1403af1964593a3fa" + integrity sha512-M59m5dzLoHOVWdM41O8z9SyySzcDn43xHseOH0HavjsfQsT56GGCC4QzU1banJidbUrePhzoEdS42uFE8Fei8w== dependencies: - "@jimp/utils" "^0.22.12" + "@jimp/core" "1.6.0" + "@jimp/plugin-color" "1.6.0" + "@jimp/plugin-hash" "1.6.0" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" + zod "^3.23.8" -"@jimp/plugin-scale@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-scale/-/plugin-scale-0.22.12.tgz#91f1ec3d114ff44092b946a16e66b14d918e32ed" - integrity sha512-dghs92qM6MhHj0HrV2qAwKPMklQtjNpoYgAB94ysYpsXslhRTiPisueSIELRwZGEr0J0VUxpUY7HgJwlSIgGZw== +"@jimp/types@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/types/-/types-1.6.0.tgz#27022730fd673653e1430e6bd8ac6f6de1596f89" + integrity sha512-7UfRsiKo5GZTAATxm2qQ7jqmUXP0DxTArztllTcYdyw6Xi5oT4RaoXynVtCD4UyLK5gJgkZJcwonoijrhYFKfg== dependencies: - "@jimp/utils" "^0.22.12" + zod "^3.23.8" -"@jimp/plugin-shadow@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-shadow/-/plugin-shadow-0.22.12.tgz#52e3a1d55f61ddfcfb3265544f8d23b887a667b8" - integrity sha512-FX8mTJuCt7/3zXVoeD/qHlm4YH2bVqBuWQHXSuBK054e7wFRnRnbSLPUqAwSeYP3lWqpuQzJtgiiBxV3+WWwTg== +"@jimp/utils@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-1.6.0.tgz#e196f3953ea1ebc88f50cf0d490adb24aeffe596" + integrity sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA== dependencies: - "@jimp/utils" "^0.22.12" - -"@jimp/plugin-threshold@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugin-threshold/-/plugin-threshold-0.22.12.tgz#1efe20e154bf3a1fc4a5cc016092dbacaa60c958" - integrity sha512-4x5GrQr1a/9L0paBC/MZZJjjgjxLYrqSmWd+e+QfAEPvmRxdRoQ5uKEuNgXnm9/weHQBTnQBQsOY2iFja+XGAw== - dependencies: - "@jimp/utils" "^0.22.12" - -"@jimp/plugins@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/plugins/-/plugins-0.22.12.tgz#45a3b96d2d24cec21d4f8b79d1cfcec6fcb2f1d4" - integrity sha512-yBJ8vQrDkBbTgQZLty9k4+KtUQdRjsIDJSPjuI21YdVeqZxYywifHl4/XWILoTZsjTUASQcGoH0TuC0N7xm3ww== - dependencies: - "@jimp/plugin-blit" "^0.22.12" - "@jimp/plugin-blur" "^0.22.12" - "@jimp/plugin-circle" "^0.22.12" - "@jimp/plugin-color" "^0.22.12" - "@jimp/plugin-contain" "^0.22.12" - "@jimp/plugin-cover" "^0.22.12" - "@jimp/plugin-crop" "^0.22.12" - "@jimp/plugin-displace" "^0.22.12" - "@jimp/plugin-dither" "^0.22.12" - "@jimp/plugin-fisheye" "^0.22.12" - "@jimp/plugin-flip" "^0.22.12" - "@jimp/plugin-gaussian" "^0.22.12" - "@jimp/plugin-invert" "^0.22.12" - "@jimp/plugin-mask" "^0.22.12" - "@jimp/plugin-normalize" "^0.22.12" - "@jimp/plugin-print" "^0.22.12" - "@jimp/plugin-resize" "^0.22.12" - "@jimp/plugin-rotate" "^0.22.12" - "@jimp/plugin-scale" "^0.22.12" - "@jimp/plugin-shadow" "^0.22.12" - "@jimp/plugin-threshold" "^0.22.12" - timm "^1.6.1" - -"@jimp/png@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.22.12.tgz#e033586caf38d9c9d33808e92eb87c4d7f0aa1eb" - integrity sha512-Mrp6dr3UTn+aLK8ty/dSKELz+Otdz1v4aAXzV5q53UDD2rbB5joKVJ/ChY310B+eRzNxIovbUF1KVrUsYdE8Hg== - dependencies: - "@jimp/utils" "^0.22.12" - pngjs "^6.0.0" - -"@jimp/tiff@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.22.12.tgz#67cac3f2ded6fde3ef631fbf74bea0fa53800123" - integrity sha512-E1LtMh4RyJsoCAfAkBRVSYyZDTtLq9p9LUiiYP0vPtXyxX4BiYBUYihTLSBlCQg5nF2e4OpQg7SPrLdJ66u7jg== - dependencies: - utif2 "^4.0.1" - -"@jimp/types@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.22.12.tgz#6f83761ba171cb8cd5998fa66a5cbfb0b22d3d8c" - integrity sha512-wwKYzRdElE1MBXFREvCto5s699izFHNVvALUv79GXNbsOVqlwlOxlWJ8DuyOGIXoLP4JW/m30YyuTtfUJgMRMA== - dependencies: - "@jimp/bmp" "^0.22.12" - "@jimp/gif" "^0.22.12" - "@jimp/jpeg" "^0.22.12" - "@jimp/png" "^0.22.12" - "@jimp/tiff" "^0.22.12" - timm "^1.6.1" - -"@jimp/utils@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.22.12.tgz#8ffaed8f2dc2962539ccaf14727ac60793c7a537" - integrity sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q== - dependencies: - regenerator-runtime "^0.13.3" + "@jimp/types" "1.6.0" + tinycolor2 "^1.6.0" "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" @@ -961,9 +951,9 @@ integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" @@ -973,13 +963,6 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@ljharb/through@^2.3.13": - version "2.3.13" - resolved "https://registry.yarnpkg.com/@ljharb/through/-/through-2.3.13.tgz#b7e4766e0b65aa82e529be945ab078de79874edc" - integrity sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ== - dependencies: - call-bind "^1.0.7" - "@mapbox/node-pre-gyp@^1.0.0": version "1.0.11" resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" @@ -1008,7 +991,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": +"@nodelib/fs.walk@^1.2.3": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -1034,9 +1017,9 @@ graceful-fs "4.2.10" "@pnpm/npm-conf@^2.1.0": - version "2.2.2" - resolved "https://registry.yarnpkg.com/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz#0058baf1c26cbb63a828f0193795401684ac86f0" - integrity sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz#bb375a571a0bd63ab0a23bece33033c683e9b6b0" + integrity sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw== dependencies: "@pnpm/config.env-replace" "^1.1.0" "@pnpm/network.ca-file" "^1.0.1" @@ -1049,20 +1032,15 @@ dependencies: any-observable "^0.3.0" -"@sapphire/async-queue@^1.5.2": - version "1.5.2" - resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.5.2.tgz#2982dce16e5b8b1ea792604d20c23c0585877b97" - integrity sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg== - -"@sapphire/async-queue@^1.5.3": +"@sapphire/async-queue@^1.5.2", "@sapphire/async-queue@^1.5.3": version "1.5.3" resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.5.3.tgz#03cd2a2f3665068f314736bdc56eee2025352422" integrity sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w== -"@sapphire/shapeshift@^3.9.7": - version "3.9.7" - resolved "https://registry.yarnpkg.com/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz#43e23243cac8a0c046bf1e73baf3dbf407d33a0c" - integrity sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g== +"@sapphire/shapeshift@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@sapphire/shapeshift/-/shapeshift-4.0.0.tgz#86c1b41002ff5d0b2ad21cbc3418b06834b89040" + integrity sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg== dependencies: fast-deep-equal "^3.1.3" lodash "^4.17.21" @@ -1077,16 +1055,6 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== -"@sindresorhus/is@^4.0.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" - integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== - -"@sindresorhus/is@^5.2.0", "@sindresorhus/is@^5.3.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668" - integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g== - "@sinonjs/commons@^3.0.0": version "3.0.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" @@ -1106,20 +1074,6 @@ resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.5.tgz#3abc203c79b8c3e90fd6c156a0c62d5403520e12" integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw== -"@szmarczak/http-timer@^4.0.5": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" - integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== - dependencies: - defer-to-connect "^2.0.0" - -"@szmarczak/http-timer@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" - integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== - dependencies: - defer-to-connect "^2.0.1" - "@tokenizer/token@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" @@ -1166,16 +1120,6 @@ "@types/connect" "*" "@types/node" "*" -"@types/cacheable-request@^6.0.1": - version "6.0.3" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" - integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== - dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "^3.1.4" - "@types/node" "*" - "@types/responselike" "^1.0.0" - "@types/clone-deep@^4.0.4": version "4.0.4" resolved "https://registry.yarnpkg.com/@types/clone-deep/-/clone-deep-4.0.4.tgz#6932f2d0a4b4ef337d97cb72e6ecdf091c05145d" @@ -1188,23 +1132,28 @@ dependencies: "@types/node" "*" -"@types/express-serve-static-core@^4.17.33": - version "4.19.3" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz#e469a13e4186c9e1c0418fb17be8bc8ff1b19a7a" - integrity sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg== +"@types/estree@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + +"@types/express-serve-static-core@^5.0.0": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz#3c9997ae9d00bc236e45c6374e84f2596458d9db" + integrity sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA== dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" "@types/send" "*" -"@types/express@^4.17.20": - version "4.17.21" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" - integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== +"@types/express@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.0.tgz#13a7d1f75295e90d19ed6e74cab3678488eaa96c" + integrity sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ== dependencies: "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" + "@types/express-serve-static-core" "^5.0.0" "@types/qs" "*" "@types/serve-static" "*" @@ -1215,11 +1164,6 @@ dependencies: "@types/node" "*" -"@types/http-cache-semantics@*", "@types/http-cache-semantics@^4.0.2": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" - integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== - "@types/http-errors@*": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" @@ -1244,20 +1188,18 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^29.0.0": - version "29.5.13" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.13.tgz#8bc571659f401e6a719a7bf0dbcb8b78c71a8adc" - integrity sha512-wd+MVEZCHt23V0/L642O5APvspWply/rGY5BcW4SUETo2UzPU3Z26qr8jC2qxpimI2jjx9h7+2cj2FwIr01bXg== +"@types/jest@^29.5.14": + version "29.5.14" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.14.tgz#2b910912fa1d6856cadcd0c1f95af7df1d6049e5" + integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ== dependencies: expect "^29.0.0" pretty-format "^29.0.0" -"@types/keyv@^3.1.4": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" - integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== - dependencies: - "@types/node" "*" +"@types/json-schema@^7.0.15": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/luxon@~3.4.0": version "3.4.2" @@ -1269,47 +1211,33 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== -"@types/node@*": - version "22.5.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.5.tgz#52f939dd0f65fc552a4ad0b392f3c466cc5d7a44" - integrity sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA== +"@types/node@*", "@types/node@^22.8.1": + version "22.8.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.8.1.tgz#b39d4b98165e2ae792ce213f610c7c6108ccfa16" + integrity sha512-k6Gi8Yyo8EtrNtkHXutUu2corfDf9su95VYVP10aGYMMROM6SAItZi0w1XszA6RtWTHSVp5OeFof37w0IEqCQg== dependencies: - undici-types "~6.19.2" + undici-types "~6.19.8" "@types/node@16.9.1": version "16.9.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.1.tgz#0611b37db4246c937feef529ddcc018cf8e35708" integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== -"@types/node@^20.0.0": - version "20.16.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.13.tgz#148c152d757dc73f8d65f0f6f078f39050b85b0c" - integrity sha512-GjQ7im10B0labo8ZGXDGROUl9k0BNyDgzfGpb4g/cl+4yYDWVKcozANF4FGr4/p0O/rAkQClM6Wiwkije++1Tg== - dependencies: - undici-types "~6.19.2" - "@types/normalize-package-data@^2.4.3": version "2.4.4" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== "@types/qs@*": - version "6.9.15" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.15.tgz#adde8a060ec9c305a82de1babc1056e73bd64dce" - integrity sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg== + version "6.9.16" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.16.tgz#52bba125a07c0482d26747d5d4947a64daf8f794" + integrity sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A== "@types/range-parser@*": version "1.2.7" resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== -"@types/responselike@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" - integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw== - dependencies: - "@types/node" "*" - "@types/send@*": version "0.17.4" resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" @@ -1343,9 +1271,9 @@ integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ== "@types/ws@^8.5.10": - version "8.5.10" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" - integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== + version "8.5.12" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.12.tgz#619475fe98f35ccca2a2f6c137702d85ec247b7e" + integrity sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ== dependencies: "@types/node" "*" @@ -1361,133 +1289,88 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^7.0.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz#b16d3cf3ee76bf572fdf511e79c248bdec619ea3" - integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw== +"@typescript-eslint/eslint-plugin@^8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz#c3f087d20715fa94310b30666c08b3349e0ab084" + integrity sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/type-utils" "7.18.0" - "@typescript-eslint/utils" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" + "@typescript-eslint/scope-manager" "8.11.0" + "@typescript-eslint/type-utils" "8.11.0" + "@typescript-eslint/utils" "8.11.0" + "@typescript-eslint/visitor-keys" "8.11.0" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/parser@^6.16.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" - integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== +"@typescript-eslint/parser@^8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.11.0.tgz#2ad1481388dc1c937f50b2d138c9ca57cc6c5cce" + integrity sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg== 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" + "@typescript-eslint/scope-manager" "8.11.0" + "@typescript-eslint/types" "8.11.0" + "@typescript-eslint/typescript-estree" "8.11.0" + "@typescript-eslint/visitor-keys" "8.11.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" - integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== +"@typescript-eslint/scope-manager@8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz#9d399ce624118966732824878bc9a83593a30405" + integrity sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ== dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/types" "8.11.0" + "@typescript-eslint/visitor-keys" "8.11.0" -"@typescript-eslint/scope-manager@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" - integrity sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA== +"@typescript-eslint/type-utils@8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.11.0.tgz#b7f9e6120c1ddee8a1a07615646642ad85fc91b5" + integrity sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg== dependencies: - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" - -"@typescript-eslint/type-utils@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b" - integrity sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA== - dependencies: - "@typescript-eslint/typescript-estree" "7.18.0" - "@typescript-eslint/utils" "7.18.0" + "@typescript-eslint/typescript-estree" "8.11.0" + "@typescript-eslint/utils" "8.11.0" debug "^4.3.4" ts-api-utils "^1.3.0" -"@typescript-eslint/types@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" - integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== +"@typescript-eslint/types@8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.11.0.tgz#7c766250502097f49bbc2e651132e6bf489e20b8" + integrity sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw== -"@typescript-eslint/types@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" - integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== - -"@typescript-eslint/typescript-estree@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" - integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== +"@typescript-eslint/typescript-estree@8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz#35fe5d3636fc5727c52429393415412e552e222b" + integrity sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg== dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/types" "8.11.0" + "@typescript-eslint/visitor-keys" "8.11.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" - -"@typescript-eslint/typescript-estree@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" - integrity sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA== - dependencies: - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" - debug "^4.3.4" - globby "^11.1.0" + fast-glob "^3.3.2" is-glob "^4.0.3" minimatch "^9.0.4" semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/utils@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f" - integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== +"@typescript-eslint/utils@8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.11.0.tgz#4480d1e9f2bb18ea3510c79f870a1aefc118103d" + integrity sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/typescript-estree" "7.18.0" + "@typescript-eslint/scope-manager" "8.11.0" + "@typescript-eslint/types" "8.11.0" + "@typescript-eslint/typescript-estree" "8.11.0" -"@typescript-eslint/visitor-keys@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" - integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== +"@typescript-eslint/visitor-keys@8.11.0": + version "8.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz#273de1cbffe63d9f9cd7dfc20b5a5af66310cb92" + integrity sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw== dependencies: - "@typescript-eslint/types" "6.21.0" - eslint-visitor-keys "^3.4.1" - -"@typescript-eslint/visitor-keys@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7" - integrity sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg== - dependencies: - "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/types" "8.11.0" eslint-visitor-keys "^3.4.3" -"@ungap/structured-clone@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== - -"@vladfrangu/async_event_emitter@^2.2.4": - version "2.2.4" - resolved "https://registry.yarnpkg.com/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz#d3537432c6db6444680a596271dff8ea407343b3" - integrity sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug== - -"@vladfrangu/async_event_emitter@^2.4.6": +"@vladfrangu/async_event_emitter@^2.2.4", "@vladfrangu/async_event_emitter@^2.4.6": version "2.4.6" resolved "https://registry.yarnpkg.com/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.6.tgz#508b6c45b03f917112a9008180b308ba0e4d1805" integrity sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA== @@ -1497,6 +1380,13 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -1510,10 +1400,10 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.9.0: - version "8.12.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" - integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== +acorn@^8.12.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== agent-base@6: version "6.0.2" @@ -1540,17 +1430,6 @@ ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -all-package-names@^2.0.2: - version "2.0.897" - resolved "https://registry.yarnpkg.com/all-package-names/-/all-package-names-2.0.897.tgz#d672ca5d9566eef046b996523dec84b21512e20c" - integrity sha512-ZWd7bk4fK2Doei5nLP28ytHa5hTD+qr8bWuJQh1Bbi36Ij4RVXSL6tM0zEni85usEhX0iQ32IuYlyoYM0sKFyQ== - dependencies: - commander-version "^1.1.0" - p-lock "^2.0.0" - parse-json-object "^2.0.1" - progress "^2.0.3" - types-json "^1.2.2" - ansi-align@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" @@ -1598,9 +1477,9 @@ ansi-regex@^5.0.1: integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== ansi-styles@^2.2.1: version "2.2.1" @@ -1626,7 +1505,7 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansi-styles@^6.1.0: +ansi-styles@^6.1.0, ansi-styles@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== @@ -1689,11 +1568,6 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - async@^3.2.3: version "3.2.6" resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" @@ -1704,6 +1578,19 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +atomically@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/atomically/-/atomically-2.0.3.tgz#27e47bbe39994d324918491ba7c0edb7783e56cb" + integrity sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw== + dependencies: + stubborn-fs "^1.2.5" + when-exit "^2.1.1" + +await-to-js@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/await-to-js/-/await-to-js-3.0.0.tgz#70929994185616f4675a91af6167eb61cc92868f" + integrity sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g== + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -1739,22 +1626,25 @@ babel-plugin-jest-hoist@^29.6.3: "@types/babel__traverse" "^7.0.6" babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz#9a929eafece419612ef4ae4f60b1862ebad8ef30" + integrity sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw== dependencies: "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-import-attributes" "^7.24.7" + "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" babel-preset-jest@^29.6.3: version "29.6.3" @@ -1774,11 +1664,6 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -big-integer@^1.6.44: - version "1.6.52" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" - integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== - bignumber.js@9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" @@ -1793,10 +1678,10 @@ bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" -bmp-js@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" - integrity sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw== +bmp-ts@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/bmp-ts/-/bmp-ts-1.0.9.tgz#0fd124ba812be9b786b29e5b186ee76d74ff5538" + integrity sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw== body-parser@1.20.3, body-parser@^1.20.2: version "1.20.3" @@ -1816,26 +1701,19 @@ body-parser@1.20.3, body-parser@^1.20.2: type-is "~1.6.18" unpipe "1.0.0" -boxen@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.1.1.tgz#f9ba525413c2fec9cdb88987d835c4f7cad9c8f4" - integrity sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog== +boxen@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-8.0.1.tgz#7e9fcbb45e11a2d7e6daa8fdcebfc3242fc19fe3" + integrity sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw== dependencies: ansi-align "^3.0.1" - camelcase "^7.0.1" - chalk "^5.2.0" + camelcase "^8.0.0" + chalk "^5.3.0" cli-boxes "^3.0.0" - string-width "^5.1.2" - type-fest "^2.13.0" - widest-line "^4.0.1" - wrap-ansi "^8.1.0" - -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - big-integer "^1.6.44" + string-width "^7.2.0" + type-fest "^4.21.0" + widest-line "^5.0.0" + wrap-ansi "^9.0.0" brace-expansion@^1.1.7: version "1.1.11" @@ -1859,15 +1737,15 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" -browserslist@^4.22.2: - version "4.23.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" - integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== +browserslist@^4.24.0: + version "4.24.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" + integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== dependencies: - caniuse-lite "^1.0.30001587" - electron-to-chromium "^1.4.668" - node-releases "^2.0.14" - update-browserslist-db "^1.0.13" + caniuse-lite "^1.0.30001669" + electron-to-chromium "^1.5.41" + node-releases "^2.0.18" + update-browserslist-db "^1.1.1" bs-logger@^0.2.6: version "0.2.6" @@ -1883,17 +1761,12 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-equal@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" - integrity sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA== - buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^5.2.0, buffer@^5.5.0: +buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -1909,59 +1782,18 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== - -bundle-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" - integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== +bundle-name@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-4.1.0.tgz#f3b96b34160d6431a19d7688135af7cfb8797889" + integrity sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q== dependencies: - run-applescript "^5.0.0" + run-applescript "^7.0.0" bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== - -cacheable-lookup@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" - integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w== - -cacheable-request@^10.2.8: - version "10.2.14" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.2.14.tgz#eb915b665fda41b79652782df3f553449c406b9d" - integrity sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ== - dependencies: - "@types/http-cache-semantics" "^4.0.2" - get-stream "^6.0.1" - http-cache-semantics "^4.1.1" - keyv "^4.5.3" - mimic-response "^4.0.0" - normalize-url "^8.0.0" - responselike "^3.0.0" - -cacheable-request@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" - integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - call-bind@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" @@ -1978,11 +1810,6 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -callsites@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-4.1.0.tgz#de72b98612eed4e1e2564c952498677faa9d86c2" - integrity sha512-aBMbD1Xxay75ViYezwT40aQONfr+pSXTHwNKvIXhXD6+LY3F1dLIcceoC5OZKBVHbXcysz1hL9D2w0JJIMXpUw== - camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -1993,15 +1820,15 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -camelcase@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-7.0.1.tgz#f02e50af9fd7782bc8b88a3558c32fd3a388f048" - integrity sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw== +camelcase@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-8.0.0.tgz#c0d36d418753fb6ad9c5e0437579745c1c14a534" + integrity sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA== -caniuse-lite@^1.0.30001587: - version "1.0.30001627" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001627.tgz#8071c42d468e06ed2fb2c545efe79a663fd326ab" - integrity sha512-4zgNiB8nTyV/tHhwZrFs88ryjls/lHiqFhrxCW4qSTeuRByBVnPYpDInchOIySWknznucaf31Z4KYqjfbrecVw== +caniuse-lite@^1.0.30001669: + version "1.0.30001673" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz#5aa291557af1c71340e809987367410aab7a5a9e" + integrity sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw== canvas@^2.11.2: version "2.11.2" @@ -2012,13 +1839,6 @@ canvas@^2.11.2: nan "^2.17.0" simple-get "^3.0.3" -centra@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/centra/-/centra-2.7.0.tgz#4c8312a58436e8a718302011561db7e6a2b0ec18" - integrity sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg== - dependencies: - follow-redirects "^1.15.6" - chalk-template@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/chalk-template/-/chalk-template-1.1.0.tgz#ffc55db6dd745e9394b85327c8ac8466edb7a7b1" @@ -2080,9 +1900,9 @@ ci-info@^3.2.0: integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== cjs-module-lexer@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz#c485341ae8fd999ca4ee5af2d7a1c9ae01e0099c" - integrity sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q== + version "1.4.1" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" + integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA== clean-stack@^4.0.0: version "4.2.0" @@ -2177,13 +1997,6 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clone-response@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" - integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== - dependencies: - mimic-response "^1.0.0" - clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" @@ -2269,19 +2082,6 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander-version@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/commander-version/-/commander-version-1.1.0.tgz#fbfaea4632921a42f8f855f96bcaa3d9920a6296" - integrity sha512-9aNW4N6q6EPDUszLRH6k9IwO6OoGYh3HRgUF/fA7Zs+Mz1v1x5akSqT7QGB8JsGY7AG7qMA7oRRB/4yyn33FYA== - dependencies: - "@bconnorwhite/module" "^2.0.2" - commander "^6.1.0" - -commander@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - component-emitter@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" @@ -2300,16 +2100,15 @@ config-chain@^1.1.11: ini "^1.3.4" proto-list "~1.2.1" -configstore@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-6.0.0.tgz#49eca2ebc80983f77e09394a1a56e0aca8235566" - integrity sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA== +configstore@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-7.0.0.tgz#4461561fc51cb40e5ee1161230bc0337e069cc6b" + integrity sha512-yk7/5PN5im4qwz0WFZW3PXnzHgPu9mX29Y8uZ3aefe2lBPC1FYttWZRcaW9fKkT0pBCJyuQ2HfbmPVaODi9jcQ== dependencies: - dot-prop "^6.0.1" - graceful-fs "^4.2.6" - unique-string "^3.0.0" - write-file-atomic "^3.0.3" - xdg-basedir "^5.0.1" + atomically "^2.0.3" + dot-prop "^9.0.0" + graceful-fs "^4.2.11" + xdg-basedir "^5.1.0" console-control-strings@^1.0.0, console-control-strings@^1.1.0: version "1.1.0" @@ -2393,22 +2192,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -crypto-random-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-4.0.0.tgz#5a3cc53d7dd86183df5da0312816ceeeb5bb1fc2" - integrity sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA== - dependencies: - type-fest "^1.0.1" - date-fns@^1.27.2: version "1.30.1" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== dayjs@^1.11.9: - version "1.11.11" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.11.tgz#dfe0e9d54c5f8b68ccf8ca5f72ac603e7e5ed59e" - integrity sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg== + version "1.11.13" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c" + integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== debug@2.6.9: version "2.6.9" @@ -2417,27 +2209,13 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1: - version "4.3.5" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" - integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== - dependencies: - ms "2.1.2" - -debug@^4.3.1, debug@^4.3.2: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== dependencies: ms "^2.1.3" -debug@^4.3.4: - version "4.3.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" - integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== - dependencies: - ms "2.1.2" - decompress-response@^4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" @@ -2445,13 +2223,6 @@ decompress-response@^4.2.0: dependencies: mimic-response "^2.0.0" -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - dedent@^1.0.0: version "1.5.3" resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" @@ -2472,23 +2243,18 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -default-browser-id@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" - integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== - dependencies: - bplist-parser "^0.2.0" - untildify "^4.0.0" +default-browser-id@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-5.0.0.tgz#a1d98bf960c15082d8a3fa69e83150ccccc3af26" + integrity sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA== -default-browser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" - integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== +default-browser@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-5.2.1.tgz#7b7ba61204ff3e425b556869ae6d3e9d9f1712cf" + integrity sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg== dependencies: - bundle-name "^3.0.0" - default-browser-id "^3.0.0" - execa "^7.1.1" - titleize "^3.0.0" + bundle-name "^4.1.0" + default-browser-id "^5.0.0" defaults@^1.0.3: version "1.0.4" @@ -2497,11 +2263,6 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -defer-to-connect@^2.0.0, defer-to-connect@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" - integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== - define-data-property@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" @@ -2572,6 +2333,11 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +discord-api-types@0.37.100: + version "0.37.100" + resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.100.tgz#5979892d39511bc7f1dbb9660d2d2cad698b3de7" + integrity sha512-a8zvUI0GYYwDtScfRd/TtaNBDTXwP5DiDVX7K5OmE+DRT57gBqKnwtOC5Ol8z0mRW8KQfETIgiB8U0YZ9NXiCA== + discord-api-types@0.37.83: version "0.37.83" resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.83.tgz#a22a799729ceded8176ea747157837ddf4708b1f" @@ -2582,49 +2348,30 @@ discord-api-types@0.37.97: resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.97.tgz#d658573f726ad179261d538dbad4e7e8eca48d11" integrity sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA== -discord.js@^14.15.3: - version "14.15.3" - resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.15.3.tgz#b2a67a1a4ef192be498fb8b6784224a42906f1be" - integrity sha512-/UJDQO10VuU6wQPglA4kz2bw2ngeeSbogiIPx/TsnctfzV/tNf+q+i1HlgtX1OGpeOBpJH9erZQNO5oRM2uAtQ== +discord.js@^14.16.3: + version "14.16.3" + resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.16.3.tgz#9553366953c992469f47a55af2a11c2054a9babe" + integrity sha512-EPCWE9OkA9DnFFNrO7Kl1WHHDYFXu3CNVFJg63bfU7hVtjZGyhShwZtSBImINQRWxWP2tgo2XI+QhdXx28r0aA== dependencies: - "@discordjs/builders" "^1.8.2" + "@discordjs/builders" "^1.9.0" "@discordjs/collection" "1.5.3" - "@discordjs/formatters" "^0.4.0" - "@discordjs/rest" "^2.3.0" - "@discordjs/util" "^1.1.0" - "@discordjs/ws" "^1.1.1" + "@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.83" + discord-api-types "0.37.100" fast-deep-equal "3.1.3" lodash.snakecase "4.1.1" - tslib "2.6.2" - undici "6.13.0" + tslib "^2.6.3" + undici "6.19.8" -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== +dot-prop@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-9.0.0.tgz#bae5982fe6dc6b8fddb92efef4f2ddff26779e92" + integrity sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ== dependencies: - esutils "^2.0.2" - -dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" - integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== - -dot-prop@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" - integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== - dependencies: - is-obj "^2.0.0" - -dot-prop@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-7.2.0.tgz#468172a3529779814d21a779c1ba2f6d76609809" - integrity sha512-Ol/IPXUARn9CSbkrdV4VJo7uCy1I3VuSiWCaFSg+8BdUOzF9n3jefIpcgAydvUZbTdEBZs2vEiTiS9m61ssiDA== - dependencies: - type-fest "^2.11.2" + type-fest "^4.18.2" dotenv@^16.0.0, dotenv@^16.0.3: version "16.4.5" @@ -2648,10 +2395,10 @@ ejs@^3.1.10: dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.668: - version "1.4.788" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.788.tgz#a3545959d5cfa0a266d3e551386c040be34e7e06" - integrity sha512-ubp5+Ev/VV8KuRoWnfP2QF2Bg+O2ZFdb49DiiNbz2VmgkIqrnyYaqIOqj8A6K/3p1xV0QcU5hBQ1+BmB6ot1OA== +electron-to-chromium@^1.5.41: + version "1.5.47" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz#ef0751bc19b28be8ee44cd8405309de3bf3b20c7" + integrity sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ== elegant-spinner@^1.0.1: version "1.0.1" @@ -2663,6 +2410,11 @@ emittery@^0.13.1: resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== +emoji-regex@^10.3.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.4.0.tgz#03553afea80b3975749cfcb36f776ca268e413d4" + integrity sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -2688,13 +2440,6 @@ encodeurl@~2.0.0: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -2714,10 +2459,10 @@ es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -escalade@^3.1.1, escalade@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" - integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== +escalade@^3.1.1, escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-goat@^4.0.0: version "4.0.0" @@ -2749,78 +2494,80 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== +eslint-scope@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.1.0.tgz#70214a174d4cbffbc3e8a26911d8bf51b9ae9d30" + integrity sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@^8.56.0: - version "8.57.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" - integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== +eslint-visitor-keys@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz#1f785cc5e81eb7534523d85922248232077d2f8c" + integrity sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg== + +eslint@^9.13.0: + version "9.13.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.13.0.tgz#7659014b7dda1ff876ecbd990f726e11c61596e6" + integrity sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA== 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" + "@eslint-community/regexpp" "^4.11.0" + "@eslint/config-array" "^0.18.0" + "@eslint/core" "^0.7.0" + "@eslint/eslintrc" "^3.1.0" + "@eslint/js" "9.13.0" + "@eslint/plugin-kit" "^0.2.0" + "@humanfs/node" "^0.16.5" "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" + "@humanwhocodes/retry" "^0.3.1" + "@types/estree" "^1.0.6" + "@types/json-schema" "^7.0.15" 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" + eslint-scope "^8.1.0" + eslint-visitor-keys "^4.1.0" + espree "^10.2.0" + esquery "^1.5.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" + file-entry-cache "^8.0.0" 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" -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== +espree@^10.0.1, espree@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.2.0.tgz#f4bcead9e05b0615c968e85f83816bc386a45df6" + integrity sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g== dependencies: - acorn "^8.9.0" + acorn "^8.12.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" + eslint-visitor-keys "^4.1.0" esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.2: +esquery@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== @@ -2849,6 +2596,16 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -2864,21 +2621,6 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -execa@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" - integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== - 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" - execa@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" @@ -2971,7 +2713,7 @@ fast-deep-equal@3.1.3, fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.9, fast-glob@^3.3.0: +fast-glob@^3.3.0, fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -3043,12 +2785,12 @@ figures@^3.0.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== dependencies: - flat-cache "^3.0.4" + flat-cache "^4.0.0" file-stream-rotator@^0.6.1: version "0.6.1" @@ -3057,7 +2799,7 @@ file-stream-rotator@^0.6.1: dependencies: moment "^2.29.1" -file-type@^16.5.4: +file-type@^16.0.0: version "16.5.4" resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.4.tgz#474fb4f704bee427681f98dd390058a172a6c2fd" integrity sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw== @@ -3114,14 +2856,13 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -flat-cache@^3.0.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" - integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== dependencies: flatted "^3.2.9" - keyv "^4.5.3" - rimraf "^3.0.2" + keyv "^4.5.4" flatted@^3.2.9: version "3.3.1" @@ -3133,28 +2874,18 @@ fn.name@1.x.x: resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== -follow-redirects@^1.15.6: - version "1.15.6" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" - integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== - foreground-child@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.2.1.tgz#767004ccf3a5b30df39bed90718bab43fe0a59f7" - integrity sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA== + version "3.3.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" + integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== dependencies: cross-spawn "^7.0.0" signal-exit "^4.0.1" -form-data-encoder@^2.1.2: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5" - integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== - form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + version "3.0.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.2.tgz#83ad9ced7c03feaad97e293d6f6091011e1659c8" + integrity sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" @@ -3227,6 +2958,11 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-east-asian-width@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz#21b4071ee58ed04ee0db653371b55b4299875389" + integrity sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ== + get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" @@ -3243,14 +2979,7 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -get-stream@^6.0.0, get-stream@^6.0.1: +get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== @@ -3330,44 +3059,15 @@ global-directory@^4.0.1: dependencies: ini "4.1.1" -global-dirs@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" - integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== - dependencies: - ini "2.0.0" - -global@~4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.19.0: - version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" - integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== - dependencies: - type-fest "^0.20.2" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - 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" +globals@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" + integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== globby@^13.1.2: version "13.2.2" @@ -3387,46 +3087,12 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -got@^11.8.5: - version "11.8.6" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" - integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== - dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" - "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" - responselike "^2.0.0" - -got@^12.1.0: - version "12.6.1" - resolved "https://registry.yarnpkg.com/got/-/got-12.6.1.tgz#8869560d1383353204b5a9435f782df9c091f549" - integrity sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ== - dependencies: - "@sindresorhus/is" "^5.2.0" - "@szmarczak/http-timer" "^5.0.1" - cacheable-lookup "^7.0.0" - cacheable-request "^10.2.8" - decompress-response "^6.0.0" - form-data-encoder "^2.1.2" - get-stream "^6.0.1" - http2-wrapper "^2.1.10" - lowercase-keys "^3.0.0" - p-cancelable "^3.0.0" - responselike "^3.0.0" - graceful-fs@4.2.10: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -graceful-fs@^4.2.10, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.2.10, graceful-fs@^4.2.11, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -3475,12 +3141,7 @@ has-unicode@^2.0.1: resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== -has-yarn@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-3.0.0.tgz#c3c21e559730d1d3b57e28af1f30d06fac38147d" - integrity sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA== - -hasown@^2.0.0: +hasown@^2.0.0, hasown@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== @@ -3504,11 +3165,6 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -3520,22 +3176,6 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" - integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.0.0" - -http2-wrapper@^2.1.10: - version "2.2.1" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.1.tgz#310968153dcdedb160d8b72114363ef5fce1f64a" - integrity sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.2.0" - https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -3549,11 +3189,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -human-signals@^4.3.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" - integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== - human-signals@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" @@ -3571,23 +3206,18 @@ ieee754@^1.1.13, ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore-walk@^6.0.3: +ignore-walk@^6.0.4: version "6.0.5" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.5.tgz#ef8d61eab7da169078723d1f82833b36e200b0dd" integrity sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A== dependencies: minimatch "^9.0.0" -ignore@^5.2.0: +ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== -ignore@^5.2.4, ignore@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" - integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== - image-q@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/image-q/-/image-q-4.0.0.tgz#31e075be7bae3c1f42a85c469b4732c358981776" @@ -3603,15 +3233,10 @@ import-fresh@^3.2.1, import-fresh@^3.3.0: parent-module "^1.0.0" resolve-from "^4.0.0" -import-lazy@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" - integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== - import-local@^3.0.2, import-local@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + version "3.2.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" + integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== dependencies: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" @@ -3649,11 +3274,6 @@ inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, i resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" - integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== - ini@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.1.tgz#d95b3d843b1e906e56d6747d5447904ff50ce7a1" @@ -3711,19 +3331,15 @@ inquirer@^7.0.0: strip-ansi "^6.0.0" through "^2.3.6" -inquirer@^9.2.12: - version "9.2.23" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-9.2.23.tgz#cd2fe34edca12315b624fbc3c8cb99b1c4f61f90" - integrity sha512-kod5s+FBPIDM2xiy9fu+6wdU/SkK5le5GS9lh4FEBjBHqiMgD9lLFbCbuqFNAjNL2ZOy9Wd9F694IOzN9pZHBA== +inquirer@^9.2.15: + version "9.3.7" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-9.3.7.tgz#0b562bf843812208844741c9aec9244c939b83d4" + integrity sha512-LJKFHCSeIRq9hanN14IlOtPSTe3lNES7TYDTE2xxdAy1LS5rYphajK1qtwvj3YmQXvvk0U2Vbmcni8P9EIQW9w== dependencies: "@inquirer/figures" "^1.0.3" - "@ljharb/through" "^2.3.13" ansi-escapes "^4.3.2" - chalk "^5.3.0" - cli-cursor "^3.1.0" cli-width "^4.1.0" external-editor "^3.1.0" - lodash "^4.17.21" mute-stream "1.0.0" ora "^5.4.1" run-async "^3.0.0" @@ -3731,6 +3347,7 @@ inquirer@^9.2.12: string-width "^4.2.3" strip-ansi "^6.0.1" wrap-ansi "^6.2.0" + yoctocolors-cjs "^2.1.2" ipaddr.js@1.9.1: version "1.9.1" @@ -3747,17 +3364,12 @@ is-arrayish@^0.3.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== -is-core-module@^2.13.0, is-core-module@^2.8.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== +is-core-module@^2.13.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" + integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== dependencies: - hasown "^2.0.0" - -is-docker@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + hasown "^2.0.2" is-docker@^3.0.0: version "3.0.0" @@ -3786,11 +3398,6 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-function@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" - integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== - is-generator-fn@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" @@ -3803,10 +3410,10 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: dependencies: is-extglob "^2.1.1" -is-in-ci@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-in-ci/-/is-in-ci-0.1.0.tgz#5e07d6a02ec3a8292d3f590973357efa3fceb0d3" - integrity sha512-d9PXLEY0v1iJ64xLiQMJ51J128EYHAaOR4yZqQi8aHGfw6KgifM3/Viw1oZZ1GCVmb3gBuyhLyHj0HgR2DhSXQ== +is-in-ci@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-in-ci/-/is-in-ci-1.0.0.tgz#9a86bbda7e42c6129902e0574c54b018fbb6ab88" + integrity sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg== is-inside-container@^1.0.0: version "1.0.0" @@ -3815,14 +3422,6 @@ is-inside-container@^1.0.0: dependencies: is-docker "^3.0.0" -is-installed-globally@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" - integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== - dependencies: - global-dirs "^3.0.0" - is-path-inside "^3.0.2" - is-installed-globally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-1.0.0.tgz#08952c43758c33d815692392f7f8437b9e436d5a" @@ -3841,15 +3440,6 @@ is-interactive@^2.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-2.0.0.tgz#40c57614593826da1100ade6059778d597f16e90" integrity sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ== -is-name-taken@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-name-taken/-/is-name-taken-2.0.0.tgz#c36e6515e07621dc48cd026b6b015a504942fae1" - integrity sha512-W+FUWF5g7ONVJTx3rldZeVizmPzrMMUdscpSQ96vyYerx+4b2NcqaujLJJDWruGzE0FjzGZO9RFIipOGxx/WIw== - dependencies: - all-package-names "^2.0.2" - package-name-conflict "^1.0.3" - validate-npm-package-name "^3.0.0" - is-npm@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-6.0.0.tgz#b59e75e8915543ca5d881ecff864077cba095261" @@ -3860,11 +3450,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - is-observable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" @@ -3877,11 +3462,6 @@ is-path-cwd@^3.0.0: resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-3.0.0.tgz#889b41e55c8588b1eb2a96a61d05740a674521c7" integrity sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA== -is-path-inside@^3.0.2, is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - is-path-inside@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-4.0.0.tgz#805aeb62c47c1b12fc3fd13bfb3ed1e7430071db" @@ -3921,11 +3501,6 @@ is-stream@^3.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== -is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== - is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" @@ -3941,12 +3516,12 @@ is-url-superb@^6.1.0: resolved "https://registry.yarnpkg.com/is-url-superb/-/is-url-superb-6.1.0.tgz#182f0d92b482412afeadfba8e6ea2c76680e3631" integrity sha512-LXdhGlYqUPdvEyIhWPEEwYYK3yrUiPcBjmFGlZNv1u5GtIL5qQRf7ddDyPNAvsMFqdzS923FROpTQU97tLe3JQ== -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== +is-wsl@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.0.tgz#e1c657e39c10090afcbedec61720f6b924c3cbd2" + integrity sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw== dependencies: - is-docker "^2.0.0" + is-inside-container "^1.0.0" isarray@~1.0.0: version "1.0.0" @@ -3963,18 +3538,10 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isomorphic-fetch@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" - integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== - dependencies: - node-fetch "^2.6.1" - whatwg-fetch "^3.4.1" - issue-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/issue-regex/-/issue-regex-4.1.0.tgz#e2039123748a48e6711eed7a9eb392f2c17c9341" - integrity sha512-X3HBmm7+Th+l4/kMtqwcHHgELD0Lfl0Ina6S3+grr+mKmTxsrM84NAO1UuRPIxIbGLIl3TCEu45S1kdu21HYbQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/issue-regex/-/issue-regex-4.3.0.tgz#e73db1b475fa12b93ddc66c36ebd5a5f57d0d838" + integrity sha512-7731a/t2llyrk8Hdwl1x3LkhIFGzxHQGpJA7Ur9cIRViakQF2y25Lwhx8Ziy1B068+kBYUmYPBzw5uo3DdWrdQ== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" @@ -3993,9 +3560,9 @@ istanbul-lib-instrument@^5.0.4: semver "^6.3.0" istanbul-lib-instrument@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz#91655936cf7380e4e473383081e38478b69993b1" - integrity sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw== + version "6.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" + integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== dependencies: "@babel/core" "^7.23.9" "@babel/parser" "^7.23.9" @@ -4039,13 +3606,11 @@ jackspeak@^3.1.2: "@pkgjs/parseargs" "^0.11.0" jackspeak@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.0.1.tgz#9fca4ce961af6083e259c376e9e3541431f5287b" - integrity sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog== + version "4.0.2" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.0.2.tgz#11f9468a3730c6ff6f56823a820d7e3be9bef015" + integrity sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw== dependencies: "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" jake@^10.8.5: version "10.9.2" @@ -4422,15 +3987,38 @@ jest@^29.0.0: import-local "^3.0.2" jest-cli "^29.7.0" -jimp@^0.22.12: - version "0.22.12" - resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.22.12.tgz#f99d1f3ec0d9d930cb7bd8f5b479859ee3a15694" - integrity sha512-R5jZaYDnfkxKJy1dwLpj/7cvyjxiclxU3F4TrI/J4j2rS0niq6YDUMoPn5hs8GDpO+OZGo7Ky057CRtWesyhfg== +jimp@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/jimp/-/jimp-1.6.0.tgz#7c7e5133c8dc06706e1ed35e771c685af393bfd2" + integrity sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg== dependencies: - "@jimp/custom" "^0.22.12" - "@jimp/plugins" "^0.22.12" - "@jimp/types" "^0.22.12" - regenerator-runtime "^0.13.3" + "@jimp/core" "1.6.0" + "@jimp/diff" "1.6.0" + "@jimp/js-bmp" "1.6.0" + "@jimp/js-gif" "1.6.0" + "@jimp/js-jpeg" "1.6.0" + "@jimp/js-png" "1.6.0" + "@jimp/js-tiff" "1.6.0" + "@jimp/plugin-blit" "1.6.0" + "@jimp/plugin-blur" "1.6.0" + "@jimp/plugin-circle" "1.6.0" + "@jimp/plugin-color" "1.6.0" + "@jimp/plugin-contain" "1.6.0" + "@jimp/plugin-cover" "1.6.0" + "@jimp/plugin-crop" "1.6.0" + "@jimp/plugin-displace" "1.6.0" + "@jimp/plugin-dither" "1.6.0" + "@jimp/plugin-fisheye" "1.6.0" + "@jimp/plugin-flip" "1.6.0" + "@jimp/plugin-hash" "1.6.0" + "@jimp/plugin-mask" "1.6.0" + "@jimp/plugin-print" "1.6.0" + "@jimp/plugin-quantize" "1.6.0" + "@jimp/plugin-resize" "1.6.0" + "@jimp/plugin-rotate" "1.6.0" + "@jimp/plugin-threshold" "1.6.0" + "@jimp/types" "1.6.0" + "@jimp/utils" "1.6.0" jpeg-js@^0.4.4: version "0.4.4" @@ -4457,10 +4045,10 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== json-buffer@3.0.1: version "3.0.1" @@ -4487,7 +4075,7 @@ json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -keyv@^4.0.0, keyv@^4.5.3: +keyv@^4.5.4: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== @@ -4509,12 +4097,17 @@ kuler@^2.0.0: resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== -latest-version@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-7.0.0.tgz#843201591ea81a4d404932eeb61240fe04e9e5da" - integrity sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg== +ky@^1.2.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/ky/-/ky-1.7.2.tgz#b97d9b997ba51ff1e152f0815d3d27b86513eb1c" + integrity sha512-OzIvbHKKDpi60TnF9t7UUVAF1B4mcqc02z5PIvrm08Wyb+yOcz63GRvEuVxNT18a9E1SrNouhB4W2NNLeD7Ykg== + +latest-version@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-9.0.0.tgz#e91ed216e7a4badc6f73b66c65adb46c58ec6ba1" + integrity sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA== dependencies: - package-json "^8.1.0" + package-json "^10.0.0" leven@^3.1.0: version "3.1.0" @@ -4588,20 +4181,6 @@ listr@^0.14.3: p-map "^2.0.0" rxjs "^6.3.3" -load-bmfont@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.2.tgz#e0f4516064fa5be8439f9c3696c01423a64e8717" - integrity sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog== - dependencies: - buffer-equal "0.0.1" - mime "^1.3.4" - parse-bmfont-ascii "^1.0.3" - parse-bmfont-binary "^1.0.5" - parse-bmfont-xml "^1.1.4" - phin "^3.7.1" - xhr "^2.0.1" - xtend "^4.0.0" - locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -4616,11 +4195,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.isequal@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== - lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -4701,30 +4275,15 @@ logform@^2.6.0, logform@^2.6.1: safe-stable-stringify "^2.3.1" triple-beam "^1.3.0" -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lowercase-keys@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" - integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== - -lru-cache@^10.0.1: - version "10.2.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.2.tgz#48206bc114c1252940c41b25b41af5b545aca878" - integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ== - -lru-cache@^10.2.0: +lru-cache@^10.0.1, lru-cache@^10.2.0: version "10.4.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== lru-cache@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.0.tgz#15d93a196f189034d7166caf9fe55e7384c98a21" - integrity sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA== + version "11.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.1.tgz#3a732fbfedb82c5ba7bca6564ad3f42afcb6e147" + integrity sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ== lru-cache@^5.1.1: version "5.1.1" @@ -4774,10 +4333,10 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -meow@^12.1.1: - version "12.1.1" - resolved "https://registry.yarnpkg.com/meow/-/meow-12.1.1.tgz#e558dddbab12477b69b2e9a2728c327f191bace6" - integrity sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw== +meow@^13.2.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-13.2.0.tgz#6b7d63f913f984063b3cc261b6e8800c4cd3474f" + integrity sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA== merge-descriptors@1.0.3: version "1.0.3" @@ -4819,11 +4378,16 @@ mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: dependencies: mime-db "1.52.0" -mime@1.6.0, mime@^1.3.4: +mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + mime@^2.4.4: version "2.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" @@ -4849,40 +4413,11 @@ mimic-function@^5.0.0: resolved "https://registry.yarnpkg.com/mimic-function/-/mimic-function-5.0.1.tgz#acbe2b3349f99b9deaca7fb70e48b83e94e67076" integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA== -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - mimic-response@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - -mimic-response@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" - integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== - -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== - dependencies: - dom-walk "^0.1.0" - -minimatch@9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimatch@^10.0.0: version "10.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b" @@ -4890,7 +4425,7 @@ minimatch@^10.0.0: dependencies: brace-expansion "^2.0.1" -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -4904,14 +4439,7 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.0: - version "9.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" - integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^9.0.4: +minimatch@^9.0.0, minimatch@^9.0.4: version "9.0.5" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== @@ -4968,11 +4496,6 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - ms@2.1.3, ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" @@ -5013,9 +4536,9 @@ mz@^2.4.0: thenify-all "^1.0.0" nan@^2.17.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.20.0.tgz#08c5ea813dd54ed16e5bd6505bf42af4f7838ca3" - integrity sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw== + version "2.22.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.22.0.tgz#31bc433fc33213c97bad36404bb68063de604de3" + integrity sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw== natural-compare@^1.4.0: version "1.4.0" @@ -5034,7 +4557,7 @@ new-github-release-url@^2.0.0: dependencies: type-fest "^2.5.1" -node-fetch@^2.6.1, node-fetch@^2.6.7: +node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -5046,10 +4569,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" - integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== nopt@^5.0.0: version "5.0.0" @@ -5059,12 +4582,11 @@ nopt@^5.0.0: abbrev "1" normalize-package-data@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-6.0.1.tgz#fa69e9452210f0fabf4d79ee08d0c2870c51ed88" - integrity sha512-6rvCfeRW+OEZagAB4lMLSNuTNYZWLVtKccK79VSTf//yTY5VOCgcpH80O+bZK8Neps7pUnd5G+QlMg1yV/2iZQ== + version "6.0.2" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-6.0.2.tgz#a7bc22167fe24025412bcff0a9651eb768b03506" + integrity sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g== dependencies: hosted-git-info "^7.0.0" - is-core-module "^2.8.1" semver "^7.3.5" validate-npm-package-license "^3.0.4" @@ -5073,20 +4595,10 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - -normalize-url@^8.0.0: - version "8.0.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.1.tgz#9b7d96af9836577c58f5883e939365fa15623a4a" - integrity sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w== - -np@^9.0.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/np/-/np-9.2.0.tgz#93323e1535b47317f02885e726f2aa0f41c14ac8" - integrity sha512-VYA8IKyx5XJqROr2vu8NAstfgBznrnOu3PUByFl3TBwzQVkeGC+gzOPzGbvYKM1QwlX6Gt7kVSPMzDP4qkSs1g== +np@^10.0.7: + version "10.0.7" + resolved "https://registry.yarnpkg.com/np/-/np-10.0.7.tgz#6f0dc3c7440c8ac95d55a2fa5d488c3d0848b7a5" + integrity sha512-vIPKQwOYKpQU40PU5x/vLfN2haj8ObxMvR1QGt7EZnBPWdm4WEbHdumYAnMV7AeR9kACsMqcqAP37sAo5cW5jA== dependencies: chalk "^5.3.0" chalk-template "^1.1.0" @@ -5097,11 +4609,10 @@ np@^9.0.0: execa "^8.0.1" exit-hook "^4.0.0" github-url-from-git "^1.5.0" - has-yarn "^3.0.0" hosted-git-info "^7.0.1" - ignore-walk "^6.0.3" + ignore-walk "^6.0.4" import-local "^3.1.0" - inquirer "^9.2.12" + inquirer "^9.2.15" is-installed-globally "^1.0.0" is-interactive "^2.0.0" is-scoped "^3.0.0" @@ -5109,12 +4620,11 @@ np@^9.0.0: listr "^0.14.3" listr-input "^0.2.1" log-symbols "^6.0.0" - meow "^12.1.1" + meow "^13.2.0" new-github-release-url "^2.0.0" - npm-name "^7.1.1" + npm-name "^8.0.0" onetime "^7.0.0" - open "^9.1.0" - ow "^1.1.1" + open "^10.0.4" p-memoize "^7.1.1" p-timeout "^6.1.2" path-exists "^5.0.0" @@ -5122,26 +4632,25 @@ np@^9.0.0: read-package-up "^11.0.0" read-pkg "^9.0.1" rxjs "^7.8.1" - semver "^7.5.4" + semver "^7.6.0" symbol-observable "^4.0.0" terminal-link "^3.0.0" update-notifier "^7.0.0" -npm-name@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/npm-name/-/npm-name-7.1.1.tgz#373774cc044b4dab7835e1d02c84f60680f7f748" - integrity sha512-lyOwsFndLoozriMEsaqJ5lXvhCATYOEhDvxlom8TNvB9a/htDXuLgpVhMUOBd9zCewUXCyBXAPxrGr2TK2adgQ== +npm-name@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/npm-name/-/npm-name-8.0.0.tgz#05aeda9748706ffad66d9ecec8188b99d6e3908b" + integrity sha512-DIuCGcKYYhASAZW6Xh/tiaGMko8IHOHe0n3zOA7SzTi0Yvy00x8L7sa5yNiZ75Ny58O/KeRtNouy8Ut6gPbKiw== dependencies: - got "^11.8.5" - is-name-taken "^2.0.0" is-scoped "^3.0.0" is-url-superb "^6.1.0" + ky "^1.2.0" lodash.zip "^4.2.0" org-regex "^1.0.0" - p-map "^5.5.0" - registry-auth-token "^4.2.2" + p-map "^7.0.1" + registry-auth-token "^5.0.2" registry-url "^6.0.1" - validate-npm-package-name "^3.0.0" + validate-npm-package-name "^5.0.0" npm-run-path@^4.0.1: version "4.0.1" @@ -5187,7 +4696,7 @@ object-inspect@^1.13.1: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== -omggif@^1.0.10, omggif@^1.0.9: +omggif@^1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw== @@ -5199,7 +4708,7 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0, once@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -5241,15 +4750,15 @@ onetime@^7.0.0: dependencies: mimic-function "^5.0.0" -open@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" - integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== +open@^10.0.4: + version "10.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-10.1.0.tgz#a7795e6e5d519abe4286d9937bb24b51122598e1" + integrity sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw== dependencies: - default-browser "^4.0.0" + default-browser "^5.2.1" define-lazy-prop "^3.0.0" is-inside-container "^1.0.0" - is-wsl "^2.2.0" + is-wsl "^3.1.0" optionator@^0.9.3: version "0.9.4" @@ -5288,27 +4797,6 @@ os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== -ow@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ow/-/ow-1.1.1.tgz#354a0f7df9d8d0cf961b29116daf972ef6be1632" - integrity sha512-sJBRCbS5vh1Jp9EOgwp1Ws3c16lJrUkJYlvWTYC03oyiYVwS/ns7lKRWow4w4XjDyTrA2pplQv4B2naWSR6yDA== - dependencies: - "@sindresorhus/is" "^5.3.0" - callsites "^4.0.0" - dot-prop "^7.2.0" - lodash.isequal "^4.5.0" - vali-date "^1.0.0" - -p-cancelable@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" - integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== - -p-cancelable@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" - integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== - p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -5337,11 +4825,6 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-lock@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-lock/-/p-lock-2.1.0.tgz#6f9dbc55d3aac5b0f75c8ec47f3a6f1b954135f8" - integrity sha512-pi2yT8gNhVrV4LgsUvJWQy58TXH1HG2+NXDby9+UrsS/9fXb0FJH9aCxbdHJ0EAQ6XC7ggSP6GAzuR5puDArUQ== - p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -5354,6 +4837,11 @@ p-map@^5.5.0: dependencies: aggregate-error "^4.0.0" +p-map@^7.0.1: + version "7.0.2" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-7.0.2.tgz#7c5119fada4755660f70199a66aa3fe2f85a1fe8" + integrity sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q== + p-memoize@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/p-memoize/-/p-memoize-7.1.1.tgz#53b1d0e6007288f7261cfa11a7603b84c9261bfa" @@ -5363,9 +4851,9 @@ p-memoize@^7.1.1: type-fest "^3.0.0" p-timeout@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-6.1.2.tgz#22b8d8a78abf5e103030211c5fc6dee1166a6aa5" - integrity sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ== + version "6.1.3" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-6.1.3.tgz#9635160c4e10c7b4c3db45b7d5d26f911d9fd853" + integrity sha512-UJUyfKbwvr/uZSV6btANfb+0t/mOhKV/KXcCUTp8FcQI+v/0d+wXqH4htrW0E4rR6WiEO/EPvUFiV9D5OI4vlw== p-try@^2.0.0: version "2.2.0" @@ -5373,24 +4861,19 @@ p-try@^2.0.0: integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== package-json-from-dist@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" - integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== -package-json@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-8.1.1.tgz#3e9948e43df40d1e8e78a85485f1070bf8f03dc8" - integrity sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA== +package-json@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-10.0.1.tgz#e49ee07b8de63b638e7f1b5bb353733e428fe7d7" + integrity sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg== dependencies: - got "^12.1.0" - registry-auth-token "^5.0.1" - registry-url "^6.0.0" - semver "^7.3.7" - -package-name-conflict@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/package-name-conflict/-/package-name-conflict-1.0.3.tgz#5147d35e8ae7f93401f1b3f9f3763c070463f25c" - integrity sha512-DPBNWSUWC0wPofXeNThao0uP4a93J7r90UyhagmJS0QcacTTkorZwXYsOop70phn1hKdcf/2e9lJIhazS8bx5A== + ky "^1.2.0" + registry-auth-token "^5.0.2" + registry-url "^6.0.1" + semver "^7.6.0" pako@^1.0.11: version "1.0.11" @@ -5404,17 +4887,17 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-bmfont-ascii@^1.0.3: +parse-bmfont-ascii@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285" integrity sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA== -parse-bmfont-binary@^1.0.5: +parse-bmfont-binary@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006" integrity sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA== -parse-bmfont-xml@^1.1.4: +parse-bmfont-xml@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz#016b655da7aebe6da38c906aca16bf0415773767" integrity sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA== @@ -5422,25 +4905,6 @@ parse-bmfont-xml@^1.1.4: xml-parse-from-string "^1.0.0" xml2js "^0.5.0" -parse-headers@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" - integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== - -parse-json-object@^1.0.5: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parse-json-object/-/parse-json-object-1.1.0.tgz#eef60211cec368259723d8586ecec7252f8fcdb2" - integrity sha512-4w5s6uJY1tW9REY8UwUOyaZKSKsrbQrMEzlV/Le/g5t4iMWuuyK83pZZ0OZimSOL9iyv2ORvRSgz71Ekd7iD3g== - dependencies: - types-json "^1.0.6" - -parse-json-object@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/parse-json-object/-/parse-json-object-2.0.1.tgz#a441bd8c36d2c33a69516286e7e4138a23607ee0" - integrity sha512-/oF7PUUBjCqHmMEE6xIQeX5ZokQ9+miudACzPt4KBU2qi6CxZYPdisPXx4ad7wpZJYi2ZpcW2PacLTU3De3ebw== - dependencies: - types-json "^1.2.0" - parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -5543,22 +5007,10 @@ peek-readable@^4.1.0: resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== -phin@^3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/phin/-/phin-3.7.1.tgz#bf841da75ee91286691b10e41522a662aa628fd6" - integrity sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ== - dependencies: - centra "^2.7.0" - -picocolors@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" - integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== - -picocolors@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" - integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picocolors@^1.0.0, picocolors@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" @@ -5570,12 +5022,12 @@ pirates@^4.0.4: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== -pixelmatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854" - integrity sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA== +pixelmatch@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-5.3.0.tgz#5e5321a7abedfb7962d60dbf345deda87cb9560a" + integrity sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q== dependencies: - pngjs "^3.0.0" + pngjs "^6.0.0" pkg-dir@^4.2.0: version "4.2.0" @@ -5591,16 +5043,16 @@ pkg-dir@^8.0.0: dependencies: find-up-simple "^1.0.0" -pngjs@^3.0.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" - integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== - pngjs@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-6.0.0.tgz#ca9e5d2aa48db0228a52c419c3308e87720da821" integrity sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg== +pngjs@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-7.0.0.tgz#a8b7446020ebbc6ac739db6c5415a65d17090e26" + integrity sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -5625,11 +5077,6 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== -progress@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -5651,14 +5098,6 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - punycode@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -5676,30 +5115,18 @@ pure-rand@^6.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== -qs@6.13.0: +qs@6.13.0, qs@^6.9.1: version "6.13.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== dependencies: side-channel "^1.0.6" -qs@^6.9.1: - version "6.12.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.1.tgz#39422111ca7cbdb70425541cba20c7d7b216599a" - integrity sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ== - dependencies: - side-channel "^1.0.6" - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -5730,19 +5157,6 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== -read-file-safe@^1.0.5: - version "1.0.10" - resolved "https://registry.yarnpkg.com/read-file-safe/-/read-file-safe-1.0.10.tgz#9ac9118f12cb122614612211f90dad9daf732e39" - integrity sha512-qW25fd2uMX3dV6Ui/R0jYK1MhTpjx8FO/VHaHTXzwWsGnkNwLRcqYfCXd9qDM+NZ273DPUvP2RaimYuLSu1K/g== - -read-json-safe@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/read-json-safe/-/read-json-safe-1.0.5.tgz#c459443b8e6eb3a2672cf68ddc81d2f4ef95c8d7" - integrity sha512-SJyNY/U9+vW35FPus22Qvv1oilnR7PCfN2E70uKQEGaJS313A5/cz9Yhv7ZtWzZ+XIwrtEPxXf10BOyYemHehA== - dependencies: - parse-json-object "^1.0.5" - read-file-safe "^1.0.5" - read-package-up@^11.0.0: version "11.0.0" resolved "https://registry.yarnpkg.com/read-package-up/-/read-package-up-11.0.0.tgz#71fb879fdaac0e16891e6e666df22de24a48d5ba" @@ -5789,7 +5203,7 @@ readable-stream@^2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.4.0, readable-stream@^3.6.0, readable-stream@^3.6.2: +readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -5798,6 +5212,17 @@ readable-stream@^3.4.0, readable-stream@^3.6.0, readable-stream@^3.6.2: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@^4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" + integrity sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g== + dependencies: + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + string_decoder "^1.3.0" + readable-web-to-node-stream@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" @@ -5810,26 +5235,14 @@ reflect-metadata@^0.2.1: resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== -regenerator-runtime@^0.13.3: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -registry-auth-token@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.2.tgz#f02d49c3668884612ca031419491a13539e21fac" - integrity sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg== - dependencies: - rc "1.2.8" - -registry-auth-token@^5.0.1: +registry-auth-token@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.0.2.tgz#8b026cc507c8552ebbe06724136267e63302f756" integrity sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ== dependencies: "@pnpm/npm-conf" "^2.1.0" -registry-url@^6.0.0, registry-url@^6.0.1: +registry-url@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-6.0.1.tgz#056d9343680f2f64400032b1e199faa692286c58" integrity sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q== @@ -5841,11 +5254,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== -resolve-alpn@^1.0.0, resolve-alpn@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" - integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== - resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -5877,20 +5285,6 @@ resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -responselike@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" - integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== - dependencies: - lowercase-keys "^2.0.0" - -responselike@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-3.0.0.tgz#20decb6c298aff0dbee1c355ca95461d42823626" - integrity sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg== - dependencies: - lowercase-keys "^3.0.0" - restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -5919,12 +5313,10 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -run-applescript@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" - integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== - dependencies: - execa "^5.0.0" +run-applescript@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-7.0.0.tgz#e5a553c2bffd620e169d276c1cd8f1b64778fbeb" + integrity sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A== run-async@^2.2.0, run-async@^2.4.0: version "2.4.1" @@ -5987,24 +5379,12 @@ scoped-regex@^3.0.0: resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-3.0.0.tgz#cd7ede7d942f2ae90da53272102ff2d73129c46f" integrity sha512-yEsN6TuxZhZ1Tl9iB81frTNS292m0I/IG7+w8lTvfcJQP2x3vnpOoevjBoE3Np5A6KnZM2+RtVenihj9t6NiYg== -semver-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-4.0.0.tgz#3afcf5ed6d62259f5c72d0d5d50dffbdc9680df5" - integrity sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA== - dependencies: - semver "^7.3.5" - semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: - version "7.6.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" - integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== - -semver@^7.5.3, semver@^7.6.0, semver@^7.6.3: +semver@^7.3.5, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== @@ -6128,6 +5508,11 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +simple-xml-to-json@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/simple-xml-to-json/-/simple-xml-to-json-1.2.3.tgz#79c7188ff99ae209a267b70ee0db06b0e4597787" + integrity sha512-kWJDCr9EWtZ+/EYYM5MareWj2cRnZGF93YDNpH4jQiHB+hBIZnfPFSQiVMzZOdk+zXWqTZ/9fTeQNu2DqeiudA== + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -6183,9 +5568,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.18" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz#22aa922dcf2f2885a6494a261f2d8b75345d0326" - integrity sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ== + version "3.0.20" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz#e44ed19ed318dd1e5888f93325cee800f0f51b89" + integrity sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw== sprintf-js@~1.0.2: version "1.0.3" @@ -6266,7 +5651,16 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string_decoder@^1.1.1: +string-width@^7.0.0, string-width@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc" + integrity sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ== + dependencies: + emoji-regex "^10.3.0" + get-east-asian-width "^1.0.0" + strip-ansi "^7.1.0" + +string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -6315,7 +5709,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: +strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== @@ -6355,6 +5749,11 @@ strtok3@^6.2.4: "@tokenizer/token" "^0.3.0" peek-readable "^4.1.0" +stubborn-fs@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/stubborn-fs/-/stubborn-fs-1.2.5.tgz#e5e244223166921ddf66ed5e062b6b3bf285bfd2" + integrity sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g== + superagent@5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.2.2.tgz#6ff726c5642795b2c27009e92687c8e69a6bb07d" @@ -6479,21 +5878,11 @@ through@^2.3.6, through@^2.3.8: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -timm@^1.6.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/timm/-/timm-1.7.1.tgz#96bab60c7d45b5a10a8a4d0f0117c6b7e5aff76f" - integrity sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw== - tinycolor2@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e" integrity sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw== -titleize@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" - integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== - tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -6506,11 +5895,6 @@ tmpl@1.0.5: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -6541,15 +5925,15 @@ triple-beam@^1.2.0, triple-beam@^1.3.0, triple-beam@^1.4.1: resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== -ts-api-utils@^1.0.1, ts-api-utils@^1.3.0: +ts-api-utils@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== ts-essentials@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-10.0.0.tgz#4abb58d4ed9219e313a10cf86758d257470e4d38" - integrity sha512-77FHNJEyysF9+1s4G6eejuA1lxw7uMchT3ZPy3CIbh7GIunffpshtM8pTe5G6N5dpOzNevqRHew859ceLWVBfw== + version "10.0.2" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-10.0.2.tgz#8c7aa74ed79580ffe49df5ca28d06cc6bea0ff3c" + integrity sha512-Xwag0TULqriaugXqVdDiGZ5wuZpqABZlpwQ2Ho4GDyiu/R2Xjkp/9+zcFxL7uzeLl/QCPrflnvpVYyS3ouT7Zw== ts-jest@^29.0.0: version "29.2.5" @@ -6571,20 +5955,15 @@ ts-mixer@^6.0.4: resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.4.tgz#1da39ceabc09d947a82140d9f09db0f84919ca28" integrity sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA== -tslib@2.6.2, tslib@^2.1.0, tslib@^2.5.0, tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.6.3: - version "2.7.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" - integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== +tslib@^2.1.0, tslib@^2.5.0, tslib@^2.6.2, tslib@^2.6.3: + version "2.8.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b" + integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -6598,22 +5977,17 @@ type-detect@4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-fest@^1.0.1, type-fest@^1.0.2: +type-fest@^1.0.2: version "1.4.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== -type-fest@^2.11.2, type-fest@^2.13.0, type-fest@^2.5.1: +type-fest@^2.5.1: version "2.19.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== @@ -6623,10 +5997,10 @@ type-fest@^3.0.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== -type-fest@^4.6.0, type-fest@^4.7.1: - version "4.18.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.18.3.tgz#5249f96e7c2c3f0f1561625f54050e343f1c8f68" - integrity sha512-Q08/0IrpvM+NMY9PA2rti9Jb+JejTddwmwmVQGskAlhtcrw1wsRzoR6ode6mR+OAabNa75w/dxedSUY2mlphaQ== +type-fest@^4.18.2, type-fest@^4.21.0, type-fest@^4.6.0, type-fest@^4.7.1: + version "4.26.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.26.1.tgz#a4a17fa314f976dd3e6d6675ef6c775c16d7955e" + integrity sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg== type-is@~1.6.18: version "1.6.18" @@ -6636,13 +6010,6 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - typeorm@0.3.20: version "0.3.20" resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.20.tgz#4b61d737c6fed4e9f63006f88d58a5e54816b7ab" @@ -6664,41 +6031,16 @@ typeorm@0.3.20: uuid "^9.0.0" yargs "^17.6.2" -types-eslintrc@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/types-eslintrc/-/types-eslintrc-1.0.3.tgz#b277d301caca6c330477cbaa67bf6f79ac3d6fee" - integrity sha512-zKTR6aKHEudQpl+JoZjS3qh0B5IzSpQK/BCpYBECujcnKtqL87DJJ1sJKe5B8k/y8/UJ5sukq42QDvlaJyCO2w== - dependencies: - types-json "^1.2.2" - -types-json@^1.0.6, types-json@^1.2.0, types-json@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/types-json/-/types-json-1.2.2.tgz#91ebe6de59e741ab38a98b071708a29494cedfe6" - integrity sha512-VfVLISHypS7ayIHvhacOESOTib4Sm4mAhnsgR8fzQdGp89YoBwMqvGmqENjtYehUQzgclT+7NafpEXkK/MHKwA== - -types-pkg-json@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/types-pkg-json/-/types-pkg-json-1.2.1.tgz#890fe4f231000a721299831ef3e17a489b1e635e" - integrity sha512-Wj75lCkPwfj1BhmaJxMPpTQj9YGpihjs3WICigt1IjTAswr7zPXP0iJYPZjU0Rw/IriODhMJjAImkCIxt9KeuQ== - dependencies: - types-eslintrc "^1.0.3" - types-json "^1.2.2" - typescript@^5.0.0: version "5.6.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== -undici-types@~6.19.2: +undici-types@~6.19.8: version "6.19.8" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== -undici@6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-6.13.0.tgz#7edbf4b7f3aac5f8a681d515151bf55cb3589d72" - integrity sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw== - undici@6.19.8: version "6.19.8" resolved "https://registry.yarnpkg.com/undici/-/undici-6.19.8.tgz#002d7c8a28f8cc3a44ff33c3d4be4d85e15d40e1" @@ -6709,47 +6051,33 @@ unicorn-magic@^0.1.0: resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.1.0.tgz#1bb9a51c823aaf9d73a8bfcd3d1a23dde94b0ce4" integrity sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ== -unique-string@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-3.0.0.tgz#84a1c377aff5fd7a8bc6b55d8244b2bd90d75b9a" - integrity sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ== - dependencies: - crypto-random-string "^4.0.0" - unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - -update-browserslist-db@^1.0.13: - version "1.0.16" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz#f6d489ed90fb2f07d67784eb3f53d7891f736356" - integrity sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ== +update-browserslist-db@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== dependencies: - escalade "^3.1.2" - picocolors "^1.0.1" + escalade "^3.2.0" + picocolors "^1.1.0" update-notifier@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-7.0.0.tgz#295aa782dadab784ed4073f7ffaea1fb2123031c" - integrity sha512-Hv25Bh+eAbOLlsjJreVPOs4vd51rrtCrmhyOJtbpAojro34jS4KQaEp4/EvlHJX7jSO42VvEFpkastVyXyIsdQ== + version "7.3.1" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-7.3.1.tgz#49af1ad6acfa0ea01c0d0f3c04047c154ead7096" + integrity sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA== dependencies: - boxen "^7.1.1" + boxen "^8.0.1" chalk "^5.3.0" - configstore "^6.0.0" - import-lazy "^4.0.0" - is-in-ci "^0.1.0" - is-installed-globally "^0.4.0" + configstore "^7.0.0" + is-in-ci "^1.0.0" + is-installed-globally "^1.0.0" is-npm "^6.0.0" - latest-version "^7.0.0" + latest-version "^9.0.0" pupa "^3.1.0" - semver "^7.5.4" - semver-diff "^4.0.0" + semver "^7.6.3" xdg-basedir "^5.1.0" uri-js@^4.2.2: @@ -6759,7 +6087,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -utif2@^4.0.1: +utif2@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/utif2/-/utif2-4.1.0.tgz#e768d37bd619b995d56d9780b5d2b4611a3d932b" integrity sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w== @@ -6782,19 +6110,14 @@ uuid@^9.0.0: integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== v8-to-istanbul@^9.0.1: - version "9.2.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" - integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== + version "9.3.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" + integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^2.0.0" -vali-date@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" - integrity sha512-sgECfZthyaCKW10N0fm27cg8HYTFK5qMWgypqkXMQ4Wbl/zZKx7xZICgcoxIIE+WFAP/MBL2EFwC/YvLxw3Zeg== - validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -6803,12 +6126,10 @@ validate-npm-package-license@^3.0.4: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw== - dependencies: - builtins "^1.0.3" +validate-npm-package-name@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz#a316573e9b49f3ccd90dbb6eb52b3f06c6d604e8" + integrity sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ== vary@~1.1.2: version "1.1.2" @@ -6834,11 +6155,6 @@ webidl-conversions@^3.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== -whatwg-fetch@^3.4.1: - version "3.6.20" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" - integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== - whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -6847,6 +6163,11 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +when-exit@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/when-exit/-/when-exit-2.1.3.tgz#5831cdbed8ad4984645da98c4a00d4ee3a3757e7" + integrity sha512-uVieSTccFIr/SFQdFWN/fFaQYmV37OKtuaGphMAzi4DmmUlrvRBJW5WSLkHyjNQY/ePJMz3LoiX9R3yy1Su6Hw== + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -6861,12 +6182,12 @@ wide-align@^1.1.2: dependencies: string-width "^1.0.2 || 2 || 3 || 4" -widest-line@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2" - integrity sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig== +widest-line@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-5.0.0.tgz#b74826a1e480783345f0cd9061b49753c9da70d0" + integrity sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA== dependencies: - string-width "^5.0.1" + string-width "^7.0.0" winston-daily-rotate-file@^5.0.0: version "5.0.0" @@ -6896,18 +6217,18 @@ winston-transport@4.3.0: triple-beam "^1.2.0" winston-transport@^4.7.0: - version "4.7.1" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.7.1.tgz#52ff1bcfe452ad89991a0aaff9c3b18e7f392569" - integrity sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA== + version "4.8.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.8.0.tgz#a15080deaeb80338455ac52c863418c74fcf38ea" + integrity sha512-qxSTKswC6llEMZKgCQdaWgDuMJQnhuvF5f2Nk3SNXc4byfQ+voo2mX1Px9dkNOuR8p0KAjfPG29PuYUSIb+vSA== dependencies: logform "^2.6.1" - readable-stream "^3.6.2" + readable-stream "^4.5.2" triple-beam "^1.3.0" -winston@^3.11.0: - version "3.14.2" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.14.2.tgz#94ce5fd26d374f563c969d12f0cd9c641065adab" - integrity sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg== +winston@^3.15.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.15.0.tgz#4df7b70be091bc1a38a4f45b969fa79589b73ff5" + integrity sha512-RhruH2Cj0bV0WgNL+lOfoUBI4DVfdUNjVnJGVovWZmrcKtrFTTRzgXYK2O9cymSGjrERCtaAeHwMNnUWXlwZow== dependencies: "@colors/colors" "^1.6.0" "@dabh/diagnostics" "^2.0.2" @@ -6970,21 +6291,20 @@ wrap-ansi@^8.1.0: string-width "^5.0.1" strip-ansi "^7.0.1" +wrap-ansi@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-9.0.0.tgz#1a3dc8b70d85eeb8398ddfb1e4a02cd186e58b3e" + integrity sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q== + dependencies: + ansi-styles "^6.2.1" + string-width "^7.0.0" + strip-ansi "^7.1.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -write-file-atomic@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - write-file-atomic@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" @@ -6993,26 +6313,16 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@^8.16.0, ws@^8.17.1: +ws@^8.16.0: version "8.18.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== -xdg-basedir@^5.0.1, xdg-basedir@^5.1.0: +xdg-basedir@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-5.1.0.tgz#1efba19425e73be1bc6f2a6ceb52a3d2c884c0c9" integrity sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ== -xhr@^2.0.1: - version "2.6.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" - integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== - dependencies: - global "~4.4.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - xml-parse-from-string@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" @@ -7031,11 +6341,6 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -7091,3 +6396,13 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yoctocolors-cjs@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz#f4b905a840a37506813a7acaa28febe97767a242" + integrity sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA== + +zod@^3.23.8: + version "3.23.8" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" + integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== From 6c17a67d7aa54cb5fe0256f55548a64ff9f4e7bd Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Mon, 28 Oct 2024 12:06:27 +0000 Subject: [PATCH 40/59] Fix linter --- .eslintrc.json | 45 -------------------------------------- eslint.config.mjs | 55 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 ++- yarn.lock | 13 +++++++++-- 4 files changed, 68 insertions(+), 48 deletions(-) delete mode 100644 .eslintrc.json create mode 100644 eslint.config.mjs diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 29f04b8..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - "indent": [ - "error", - 4 - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "double" - ], - "semi": [ - "error", - "always" - ] - }, - "globals": { - "jest": true, - "require": true, - "exports": true, - "process": true - }, - "ignorePatterns": [ - "dist/**/*" - ] -} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..64bf3e2 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,55 @@ +import js from "@eslint/js"; +import ts from "typescript-eslint"; + +export default [ + { + ignores: [ + "**/dist/", + "eslint.config.mjs", + "jest.config.cjs", + "jest.setup.js", + "**/.temp/**/*" + ], + }, + js.configs.recommended, + ...ts.configs.recommended, + { + languageOptions: { + globals: { + exports: "writable", + module: "writable", + require: "writable", + process: "writable", + console: "writable", + jest: "writable", + }, + + ecmaVersion: 6, + sourceType: "script", + }, + + files: [ + "./src", + "./tests" + ], + + rules: { + camelcase: "error", + "brace-style": ["error", "1tbs"], + "comma-dangle": ["error", "never"], + + "comma-spacing": ["error", { + before: false, + after: true, + }], + + "comma-style": ["error", "last"], + "arrow-body-style": ["error", "as-needed"], + "arrow-parens": ["error", "as-needed"], + "arrow-spacing": "error", + "no-var": "error", + "prefer-template": "error", + "prefer-const": "error", + }, + } +]; diff --git a/package.json b/package.json index 7e10c7f..8a5bf43 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@typescript-eslint/parser": "^8.11.0", "eslint": "^9.13.0", "np": "^10.0.7", - "typescript": "^5.0.0" + "typescript": "^5.0.0", + "typescript-eslint": "^8.11.0" } } diff --git a/yarn.lock b/yarn.lock index 93f7d56..0313723 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1289,7 +1289,7 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^8.11.0": +"@typescript-eslint/eslint-plugin@8.11.0", "@typescript-eslint/eslint-plugin@^8.11.0": version "8.11.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz#c3f087d20715fa94310b30666c08b3349e0ab084" integrity sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA== @@ -1304,7 +1304,7 @@ natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/parser@^8.11.0": +"@typescript-eslint/parser@8.11.0", "@typescript-eslint/parser@^8.11.0": version "8.11.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.11.0.tgz#2ad1481388dc1c937f50b2d138c9ca57cc6c5cce" integrity sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg== @@ -6031,6 +6031,15 @@ typeorm@0.3.20: uuid "^9.0.0" yargs "^17.6.2" +typescript-eslint@^8.11.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.11.0.tgz#74a0551972d675b4141672cec3acc5139b7399c0" + integrity sha512-cBRGnW3FSlxaYwU8KfAewxFK5uzeOAp0l2KebIlPDOT5olVi65KDG/yjBooPBG0kGW/HLkoz1c/iuBFehcS3IA== + dependencies: + "@typescript-eslint/eslint-plugin" "8.11.0" + "@typescript-eslint/parser" "8.11.0" + "@typescript-eslint/utils" "8.11.0" + typescript@^5.0.0: version "5.6.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" From d7a5472759469529201cfa803f9ba87c8dbcb5dd Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 9 Nov 2024 21:31:11 +0000 Subject: [PATCH 41/59] Create effects concept (#402) # Description Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. #378 ## Type of change Please delete options that are not relevant. - [x] New feature (non-breaking change which adds functionality) # How Has This Been Tested? Please describe the tests that you ran to verify the changes. Provide instructions so we can reproduce. Please also list any relevant details to your test configuration. # Checklist - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that provde my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/402 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- .../Down/01-table-userEffect.sql | 1 + .../Up/01-table-userEffect.sql | 10 + jest.setup.js | 3 +- package.json | 2 +- src/database/entities/app/UserEffect.ts | 60 ++++ .../app/0.9/1729962056556-createUserEffect.ts | 18 ++ src/helpers/EffectHelper.ts | 49 +++ .../database/entities/app/UserEffect.test.ts | 103 +++++++ tests/helpers/EffectHelper.test.ts | 281 ++++++++++++++++++ tests/registry.test.ts | 66 ---- 10 files changed, 525 insertions(+), 68 deletions(-) create mode 100644 database/0.9/1729962056556-createUserEffect/Down/01-table-userEffect.sql create mode 100644 database/0.9/1729962056556-createUserEffect/Up/01-table-userEffect.sql create mode 100644 src/database/entities/app/UserEffect.ts create mode 100644 src/database/migrations/app/0.9/1729962056556-createUserEffect.ts create mode 100644 src/helpers/EffectHelper.ts create mode 100644 tests/database/entities/app/UserEffect.test.ts create mode 100644 tests/helpers/EffectHelper.test.ts delete mode 100644 tests/registry.test.ts diff --git a/database/0.9/1729962056556-createUserEffect/Down/01-table-userEffect.sql b/database/0.9/1729962056556-createUserEffect/Down/01-table-userEffect.sql new file mode 100644 index 0000000..ca2a800 --- /dev/null +++ b/database/0.9/1729962056556-createUserEffect/Down/01-table-userEffect.sql @@ -0,0 +1 @@ +DROP TABLE `user_effect`; diff --git a/database/0.9/1729962056556-createUserEffect/Up/01-table-userEffect.sql b/database/0.9/1729962056556-createUserEffect/Up/01-table-userEffect.sql new file mode 100644 index 0000000..17c1811 --- /dev/null +++ b/database/0.9/1729962056556-createUserEffect/Up/01-table-userEffect.sql @@ -0,0 +1,10 @@ +CREATE TABLE `user_effect` ( + `Id` varchar(255) NOT NULL, + `WhenCreated` datetime NOT NULL, + `WhenUpdated` datetime NOT NULL, + `Name` varchar(255) NOT NULL, + `UserId` varchar(255) NOT NULL, + `Unused` int NOT NULL DEFAULT 0, + `WhenExpires` datetime NULL, + PRIMARY KEY (`Id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/jest.setup.js b/jest.setup.js index d583d1a..8e9ae9a 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -1,3 +1,4 @@ jest.setTimeout(1 * 1000); // 1 second jest.resetModules(); -jest.resetAllMocks(); \ No newline at end of file +jest.resetAllMocks(); +jest.useFakeTimers(); \ No newline at end of file diff --git a/package.json b/package.json index 8a5bf43..0dc2630 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "clean": "rm -rf node_modules/ dist/", "build": "tsc", "start": "node ./dist/bot.js", - "test": "echo true", + "test": "jest", "lint": "eslint .", "lint:fix": "eslint . --fix", "db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js", diff --git a/src/database/entities/app/UserEffect.ts b/src/database/entities/app/UserEffect.ts new file mode 100644 index 0000000..fa1b584 --- /dev/null +++ b/src/database/entities/app/UserEffect.ts @@ -0,0 +1,60 @@ +import {Column, Entity} from "typeorm"; +import AppBaseEntity from "../../../contracts/AppBaseEntity"; +import AppDataSource from "../../dataSources/appDataSource"; + +@Entity() +export default class UserEffect extends AppBaseEntity { + constructor(name: string, userId: string, unused: number, WhenExpires?: Date) { + super(); + + this.Name = name; + this.UserId = userId; + this.Unused = unused; + this.WhenExpires = WhenExpires; + } + + @Column() + Name: string; + + @Column() + UserId: string; + + @Column() + Unused: number; + + @Column({ nullable: true }) + WhenExpires?: Date; + + public AddUnused(amount: number) { + this.Unused += amount; + } + + public UseEffect(whenExpires: Date): boolean { + if (this.Unused == 0) { + return false; + } + + this.Unused -= 1; + this.WhenExpires = whenExpires; + + return true; + } + + public IsEffectActive(): boolean { + const now = new Date(); + + if (this.WhenExpires && now < this.WhenExpires) { + return true; + } + + return false; + } + + public static async FetchOneByUserIdAndName(userId: string, name: string): Promise { + const repository = AppDataSource.getRepository(UserEffect); + + const single = await repository.findOne({ where: { UserId: userId, Name: name } }); + + return single; + } +} diff --git a/src/database/migrations/app/0.9/1729962056556-createUserEffect.ts b/src/database/migrations/app/0.9/1729962056556-createUserEffect.ts new file mode 100644 index 0000000..f59b7d4 --- /dev/null +++ b/src/database/migrations/app/0.9/1729962056556-createUserEffect.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; +import MigrationHelper from "../../../../helpers/MigrationHelper"; + +export class CreateUserEffect1729962056556 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + MigrationHelper.Up("1729962056556-createUserEffect", "0.9", [ + "01-table-userEffect", + ], queryRunner); + } + + public async down(queryRunner: QueryRunner): Promise { + MigrationHelper.Down("1729962056556-createUserEffect", "0.9", [ + "01-table-userEffect", + ], queryRunner); + } + +} diff --git a/src/helpers/EffectHelper.ts b/src/helpers/EffectHelper.ts new file mode 100644 index 0000000..14c2f43 --- /dev/null +++ b/src/helpers/EffectHelper.ts @@ -0,0 +1,49 @@ +import UserEffect from "../database/entities/app/UserEffect"; + +export default class EffectHelper { + public static async AddEffectToUserInventory(userId: string, name: string, quantity: number = 1) { + let effect = await UserEffect.FetchOneByUserIdAndName(userId, name); + + if (!effect) { + effect = new UserEffect(name, userId, quantity); + } else { + effect.AddUnused(quantity); + } + + await effect.Save(UserEffect, effect); + } + + public static async UseEffect(userId: string, name: string, whenExpires: Date): Promise { + const effect = await UserEffect.FetchOneByUserIdAndName(userId, name); + const now = new Date(); + + if (!effect || effect.Unused == 0) { + return false; + } + + if (effect.WhenExpires && now < effect.WhenExpires) { + return false; + } + + effect.UseEffect(whenExpires); + + await effect.Save(UserEffect, effect); + + return true; + } + + public static async HasEffect(userId: string, name: string): Promise { + const effect = await UserEffect.FetchOneByUserIdAndName(userId, name); + const now = new Date(); + + if (!effect || !effect.WhenExpires) { + return false; + } + + if (now > effect.WhenExpires) { + return false; + } + + return true; + } +} diff --git a/tests/database/entities/app/UserEffect.test.ts b/tests/database/entities/app/UserEffect.test.ts new file mode 100644 index 0000000..66992ec --- /dev/null +++ b/tests/database/entities/app/UserEffect.test.ts @@ -0,0 +1,103 @@ +import UserEffect from "../../../../src/database/entities/app/UserEffect"; + +let userEffect: UserEffect; +const now = new Date(); + +beforeEach(() => { + userEffect = new UserEffect("name", "userId", 1); +}); + +describe("AddUnused", () => { + beforeEach(() => { + userEffect.AddUnused(1); + }); + + test("EXPECT unused to be the amount more", () => { + expect(userEffect.Unused).toBe(2); + }); +}); + +describe("UseEffect", () => { + describe("GIVEN Unused is 0", () => { + let result: boolean; + + beforeEach(() => { + userEffect.Unused = 0; + + result = userEffect.UseEffect(now); + }); + + test("EXPECT false returned", () => { + expect(result).toBe(false); + }); + + test("EXPECT details not to be changed", () => { + expect(userEffect.Unused).toBe(0); + expect(userEffect.WhenExpires).toBeUndefined(); + }); + }); + + describe("GIVEN Unused is greater than 0", () => { + let result: boolean; + + beforeEach(() => { + result = userEffect.UseEffect(now); + }); + + test("EXPECT true returned", () => { + expect(result).toBe(true); + }); + + test("EXPECT Unused to be subtracted by 1", () => { + expect(userEffect.Unused).toBe(0); + }); + + test("EXPECT WhenExpires to be set", () => { + expect(userEffect.WhenExpires).toBe(now); + }); + }); +}); + +describe("IsEffectActive", () => { + describe("GIVEN WhenExpires is null", () => { + let result: boolean; + + beforeEach(() => { + result = userEffect.IsEffectActive(); + }); + + test("EXPECT false returned", () => { + expect(result).toBe(false); + }); + }); + + describe("GIVEN WhenExpires is defined", () => { + describe("AND WhenExpires is in the past", () => { + let result: boolean; + + beforeEach(() => { + userEffect.WhenExpires = new Date(now.getTime() - 100); + + result = userEffect.IsEffectActive(); + }); + + test("EXPECT false returned", () => { + expect(result).toBe(false); + }); + }); + + describe("AND WhenExpires is in the future", () => { + let result: boolean; + + beforeEach(() => { + userEffect.WhenExpires = new Date(now.getTime() + 100); + + result = userEffect.IsEffectActive(); + }); + + test("EXPECT true returned", () => { + expect(result).toBe(true); + }); + }); + }); +}); diff --git a/tests/helpers/EffectHelper.test.ts b/tests/helpers/EffectHelper.test.ts new file mode 100644 index 0000000..343f06c --- /dev/null +++ b/tests/helpers/EffectHelper.test.ts @@ -0,0 +1,281 @@ +import UserEffect from "../../src/database/entities/app/UserEffect"; +import EffectHelper from "../../src/helpers/EffectHelper"; + +describe("AddEffectToUserInventory", () => { + describe("GIVEN effect is in database", () => { + const effectMock = { + AddUnused: jest.fn(), + Save: jest.fn(), + }; + + beforeAll(async () => { + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(effectMock); + + await EffectHelper.AddEffectToUserInventory("userId", "name", 1); + }); + + test("EXPECT database to be fetched", () => { + expect(UserEffect.FetchOneByUserIdAndName).toHaveBeenCalledTimes(1); + expect(UserEffect.FetchOneByUserIdAndName).toHaveBeenCalledWith("userId", "name"); + }); + + test("EXPECT effect to be updated", () => { + expect(effectMock.AddUnused).toHaveBeenCalledTimes(1); + expect(effectMock.AddUnused).toHaveBeenCalledWith(1); + }); + + test("EXPECT effect to be saved", () => { + expect(effectMock.Save).toHaveBeenCalledTimes(1); + expect(effectMock.Save).toHaveBeenCalledWith(UserEffect, effectMock); + }); + }); + + describe("GIVEN effect is not in database", () => { + beforeAll(async () => { + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(null); + UserEffect.prototype.Save = jest.fn(); + + await EffectHelper.AddEffectToUserInventory("userId", "name", 1); + }); + + test("EXPECT effect to be saved", () => { + expect(UserEffect.prototype.Save).toHaveBeenCalledTimes(1); + expect(UserEffect.prototype.Save).toHaveBeenCalledWith(UserEffect, expect.any(UserEffect)); + }); + }); +}); + +describe("UseEffect", () => { + describe("GIVEN effect is in database", () => { + describe("GIVEN now is before effect.WhenExpires", () => { + let result: boolean | undefined; + + // nowMock < whenExpires + const nowMock = new Date(2024, 11, 3, 13, 30); + const whenExpires = new Date(2024, 11, 3, 14, 0); + + const userEffect = { + Unused: 1, + WhenExpires: whenExpires, + }; + + beforeAll(async () => { + jest.setSystemTime(nowMock); + + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); + + result = await EffectHelper.UseEffect("userId", "name", new Date()); + }); + + test("EXPECT false returned", () => { + expect(result).toBe(false); + }); + }); + + describe("GIVEN currently used effect is inactive", () => { + let result: boolean | undefined; + + // nowMock > whenExpires + const nowMock = new Date(2024, 11, 3, 13, 30); + const whenExpires = new Date(2024, 11, 3, 13, 0); + const whenExpiresNew = new Date(2024, 11, 3, 15, 0); + + const userEffect = { + Unused: 1, + WhenExpires: whenExpires, + UseEffect: jest.fn(), + Save: jest.fn(), + }; + + beforeAll(async () => { + jest.setSystemTime(nowMock); + + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); + + result = await EffectHelper.UseEffect("userId", "name", whenExpiresNew); + }); + + test("EXPECT UseEffect to be called", () => { + expect(userEffect.UseEffect).toHaveReturnedTimes(1); + expect(userEffect.UseEffect).toHaveBeenCalledWith(whenExpiresNew); + }); + + test("EXPECT effect to be saved", () => { + expect(userEffect.Save).toHaveBeenCalledTimes(1); + expect(userEffect.Save).toHaveBeenCalledWith(UserEffect, userEffect); + }); + + test("EXPECT true returned", () => { + expect(result).toBe(true); + }); + }); + + describe("GIVEN effect.WhenExpires is null", () => { + let result: boolean | undefined; + + // nowMock > whenExpires + const nowMock = new Date(2024, 11, 3, 13, 30); + const whenExpiresNew = new Date(2024, 11, 3, 15, 0); + + const userEffect = { + Unused: 1, + WhenExpires: null, + UseEffect: jest.fn(), + Save: jest.fn(), + }; + + beforeAll(async () => { + jest.setSystemTime(nowMock); + + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); + + result = await EffectHelper.UseEffect("userId", "name", whenExpiresNew); + }); + + test("EXPECT UseEffect to be called", () => { + expect(userEffect.UseEffect).toHaveBeenCalledTimes(1); + expect(userEffect.UseEffect).toHaveBeenCalledWith(whenExpiresNew); + }); + + test("EXPECT effect to be saved", () => { + expect(userEffect.Save).toHaveBeenCalledTimes(1); + expect(userEffect.Save).toHaveBeenCalledWith(UserEffect, userEffect); + }); + + test("EXPECT true returned", () => { + expect(result).toBe(true); + }); + }); + }); + + describe("GIVEN effect is not in database", () => { + let result: boolean | undefined; + + // nowMock > whenExpires + const nowMock = new Date(2024, 11, 3, 13, 30); + const whenExpiresNew = new Date(2024, 11, 3, 15, 0); + + beforeAll(async () => { + jest.setSystemTime(nowMock); + + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(null); + + result = await EffectHelper.UseEffect("userId", "name", whenExpiresNew); + }); + + test("EXPECT false returned", () => { + expect(result).toBe(false); + }); + }); + + describe("GIVEN effect.Unused is 0", () => { + let result: boolean | undefined; + + // nowMock > whenExpires + const nowMock = new Date(2024, 11, 3, 13, 30); + const whenExpiresNew = new Date(2024, 11, 3, 15, 0); + + const userEffect = { + Unused: 0, + WhenExpires: null, + UseEffect: jest.fn(), + Save: jest.fn(), + }; + + beforeAll(async () => { + jest.setSystemTime(nowMock); + + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); + + result = await EffectHelper.UseEffect("userId", "name", whenExpiresNew); + }); + + test("EXPECT false returned", () => { + expect(result).toBe(false); + }); + }); +}); + +describe("HasEffect", () => { + describe("GIVEN effect is in database", () => { + describe("GIVEN effect.WhenExpires is defined", () => { + describe("GIVEN now is before effect.WhenExpires", () => { + let result: boolean | undefined; + + const nowMock = new Date(2024, 11, 3, 13, 30); + const whenExpires = new Date(2024, 11, 3, 15, 0); + + const userEffect = { + WhenExpires: whenExpires, + }; + + beforeAll(async () => { + jest.setSystemTime(nowMock); + + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); + + result = await EffectHelper.HasEffect("userId", "name"); + }); + + test("EXPECT true returned", () => { + expect(result).toBe(true); + }); + }); + + describe("GIVEN now is after effect.WhenExpires", () => { + let result: boolean | undefined; + + const nowMock = new Date(2024, 11, 3, 16, 30); + const whenExpires = new Date(2024, 11, 3, 15, 0); + + const userEffect = { + WhenExpires: whenExpires, + }; + + beforeAll(async () => { + jest.setSystemTime(nowMock); + + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); + + result = await EffectHelper.HasEffect("userId", "name"); + }); + + test("EXPECT false returned", () => { + expect(result).toBe(false); + }); + }); + }); + + describe("GIVEN effect.WhenExpires is undefined", () => { + let result: boolean | undefined; + + const userEffect = { + WhenExpires: undefined, + }; + + beforeAll(async () => { + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); + + result = await EffectHelper.HasEffect("userId", "name"); + }); + + test("EXPECT false returned", () => { + expect(result).toBe(false); + }); + }); + }); + + describe("GIVEN effect is not in database", () => { + let result: boolean | undefined; + + beforeAll(async () => { + UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(null); + + result = await EffectHelper.HasEffect("userId", "name"); + }); + + test("EXPECT false returned", () => { + expect(result).toBe(false); + }); + }); +}); diff --git a/tests/registry.test.ts b/tests/registry.test.ts deleted file mode 100644 index 71d80db..0000000 --- a/tests/registry.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import {CoreClient} from "../src/client/client"; -import Registry from "../src/registry"; -import fs from "fs"; -import path from "path"; - -describe("RegisterCommands", () => { - test("EXPECT every command in the commands folder to be registered", () => { - const registeredCommands: string[] = []; - - CoreClient.RegisterCommand = jest.fn().mockImplementation((name: string) => { - registeredCommands.push(name); - }); - - Registry.RegisterCommands(); - - const commandFiles = getFilesInDirectory(path.join(process.cwd(), "src", "commands")) - .filter(x => x.endsWith(".ts")); - - for (const file of commandFiles) { - expect(registeredCommands).toContain(file.split("/").pop()!.split(".")[0]); - } - - expect(commandFiles.length).toBe(registeredCommands.length); - }); -}); - -describe("RegisterButtonEvents", () => { - test("EXEPCT every button event in the button events folder to be registered", () => { - const registeredButtonEvents: string[] = []; - - CoreClient.RegisterButtonEvent = jest.fn().mockImplementation((name: string) => { - registeredButtonEvents.push(name); - }); - - Registry.RegisterButtonEvents(); - - const eventFiles = getFilesInDirectory(path.join(process.cwd(), "src", "buttonEvents")) - .filter(x => x.endsWith(".ts")); - - for (const file of eventFiles) { - expect(registeredButtonEvents).toContain(file.split("/").pop()!.split(".")[0].toLowerCase()); - } - - expect(eventFiles.length).toBe(registeredButtonEvents.length); - }); -}); - -function getFilesInDirectory(dir: string): string[] { - let results: string[] = []; - const list = fs.readdirSync(dir); - - list.forEach(file => { - file = path.join(dir, file); - const stat = fs.statSync(file); - - if (stat && stat.isDirectory()) { - /* recurse into a subdirectory */ - results = results.concat(getFilesInDirectory(file)); - } else { - /* is a file */ - results.push(file); - } - }); - - return results; -} From 3d143e7c7331b392eb7c8b7b4add56a7afb24a18 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 7 Dec 2024 22:32:19 +0000 Subject: [PATCH 42/59] Create list effects command (#412) # Description Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. #379 ## Type of change Please delete options that are not relevant. - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update # How Has This Been Tested? Please describe the tests that you ran to verify the changes. Provide instructions so we can reproduce. Please also list any relevant details to your test configuration. # Checklist - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that provde my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/412 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/buttonEvents/Effects.ts | 33 ++++ src/commands/effects.ts | 45 +++++ src/database/entities/app/UserEffect.ts | 14 ++ src/helpers/EffectHelper.ts | 47 +++++ src/registry.ts | 4 + tests/buttonEvents/Effects.test.ts | 127 ++++++++++++++ .../__snapshots__/effects.test.ts.snap | 40 +++++ tests/commands/effects.test.ts | 164 ++++++++++++++++++ tests/helpers/EffectHelper.test.ts | 99 +++++++++++ .../__snapshots__/EffectHelper.test.ts.snap | 71 ++++++++ 10 files changed, 644 insertions(+) create mode 100644 src/buttonEvents/Effects.ts create mode 100644 src/commands/effects.ts create mode 100644 tests/buttonEvents/Effects.test.ts create mode 100644 tests/commands/__snapshots__/effects.test.ts.snap create mode 100644 tests/commands/effects.test.ts create mode 100644 tests/helpers/__snapshots__/EffectHelper.test.ts.snap diff --git a/src/buttonEvents/Effects.ts b/src/buttonEvents/Effects.ts new file mode 100644 index 0000000..0810c94 --- /dev/null +++ b/src/buttonEvents/Effects.ts @@ -0,0 +1,33 @@ +import {ButtonInteraction} from "discord.js"; +import {ButtonEvent} from "../type/buttonEvent"; +import EffectHelper from "../helpers/EffectHelper"; + +export default class Effects extends ButtonEvent { + public override async execute(interaction: ButtonInteraction) { + const action = interaction.customId.split(" ")[1]; + + switch (action) { + case "list": + await this.List(interaction); + break; + } + } + + private async List(interaction: ButtonInteraction) { + const pageOption = interaction.customId.split(" ")[2]; + + const page = Number(pageOption); + + if (!page) { + await interaction.reply("Page option is not a valid number"); + return; + } + + const result = await EffectHelper.GenerateEffectEmbed(interaction.user.id, page); + + await interaction.update({ + embeds: [ result.embed ], + components: [ result.row ], + }); + } +} diff --git a/src/commands/effects.ts b/src/commands/effects.ts new file mode 100644 index 0000000..bcaa929 --- /dev/null +++ b/src/commands/effects.ts @@ -0,0 +1,45 @@ +import {CommandInteraction, SlashCommandBuilder} from "discord.js"; +import {Command} from "../type/command"; +import EffectHelper from "../helpers/EffectHelper"; + +export default class Effects extends Command { + constructor() { + super(); + + this.CommandBuilder = new SlashCommandBuilder() + .setName("effects") + .setDescription("Effects") + .addSubcommand(x => x + .setName("list") + .setDescription("List all effects I have") + .addNumberOption(x => x + .setName("page") + .setDescription("The page number") + .setMinValue(1))); + } + + public override async execute(interaction: CommandInteraction) { + if (!interaction.isChatInputCommand()) return; + + const subcommand = interaction.options.getSubcommand(); + + switch (subcommand) { + case "list": + await this.List(interaction); + break; + } + } + + private async List(interaction: CommandInteraction) { + const pageOption = interaction.options.get("page"); + + const page = !isNaN(Number(pageOption?.value)) ? Number(pageOption?.value) : 1; + + const result = await EffectHelper.GenerateEffectEmbed(interaction.user.id, page); + + await interaction.reply({ + embeds: [ result.embed ], + components: [ result.row ], + }); + } +} diff --git a/src/database/entities/app/UserEffect.ts b/src/database/entities/app/UserEffect.ts index fa1b584..72fae5f 100644 --- a/src/database/entities/app/UserEffect.ts +++ b/src/database/entities/app/UserEffect.ts @@ -57,4 +57,18 @@ export default class UserEffect extends AppBaseEntity { return single; } + + public static async FetchAllByUserIdPaginated(userId: string, page: number = 0, itemsPerPage: number = 10): Promise<[UserEffect[], number]> { + const repository = AppDataSource.getRepository(UserEffect); + + const query = await repository.createQueryBuilder("effect") + .where("effect.UserId = :userId", { userId }) + .where("effect.Unused > 0") + .orderBy("effect.Name", "ASC") + .skip(page * itemsPerPage) + .take(itemsPerPage) + .getManyAndCount(); + + return query; + } } diff --git a/src/helpers/EffectHelper.ts b/src/helpers/EffectHelper.ts index 14c2f43..d0d29a0 100644 --- a/src/helpers/EffectHelper.ts +++ b/src/helpers/EffectHelper.ts @@ -1,4 +1,6 @@ +import {ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder} from "discord.js"; import UserEffect from "../database/entities/app/UserEffect"; +import EmbedColours from "../constants/EmbedColours"; export default class EffectHelper { public static async AddEffectToUserInventory(userId: string, name: string, quantity: number = 1) { @@ -46,4 +48,49 @@ export default class EffectHelper { return true; } + + public static async GenerateEffectEmbed(userId: string, page: number): Promise<{ + embed: EmbedBuilder, + row: ActionRowBuilder, + }> { + const itemsPerPage = 10; + + const query = await UserEffect.FetchAllByUserIdPaginated(userId, page - 1, itemsPerPage); + + const effects = query[0]; + const count = query[1]; + + const totalPages = count > 0 ? Math.ceil(count / itemsPerPage) : 1; + + let description = "*none*"; + + if (effects.length > 0) { + description = effects.map(x => `${x.Name} x${x.Unused}`).join("\n"); + } + + const embed = new EmbedBuilder() + .setTitle("Effects") + .setDescription(description) + .setColor(EmbedColours.Ok) + .setFooter({ text: `Page ${page} of ${totalPages}` }); + + const row = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId(`effects list ${page - 1}`) + .setLabel("Previous") + .setStyle(ButtonStyle.Primary) + .setDisabled(page == 1), + new ButtonBuilder() + .setCustomId(`effects list ${page + 1}`) + .setLabel("Next") + .setStyle(ButtonStyle.Primary) + .setDisabled(page == totalPages), + ); + + return { + embed, + row, + }; + } } diff --git a/src/registry.ts b/src/registry.ts index e4e5d64..3ae885d 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -7,6 +7,7 @@ import AllBalance from "./commands/allbalance"; import Balance from "./commands/balance"; import Daily from "./commands/daily"; import Drop from "./commands/drop"; +import Effects from "./commands/effects"; import Gdrivesync from "./commands/gdrivesync"; import Give from "./commands/give"; import Id from "./commands/id"; @@ -25,6 +26,7 @@ import Droprarity from "./commands/stage/droprarity"; // Button Event Imports import Claim from "./buttonEvents/Claim"; +import EffectsButtonEvent from "./buttonEvents/Effects"; import InventoryButtonEvent from "./buttonEvents/Inventory"; import MultidropButtonEvent from "./buttonEvents/Multidrop"; import Reroll from "./buttonEvents/Reroll"; @@ -44,6 +46,7 @@ export default class Registry { CoreClient.RegisterCommand("balance", new Balance()); CoreClient.RegisterCommand("daily", new Daily()); CoreClient.RegisterCommand("drop", new Drop()); + CoreClient.RegisterCommand("effects", new Effects()); CoreClient.RegisterCommand("gdrivesync", new Gdrivesync()); CoreClient.RegisterCommand("give", new Give()); CoreClient.RegisterCommand("id", new Id()); @@ -63,6 +66,7 @@ export default class Registry { public static RegisterButtonEvents() { CoreClient.RegisterButtonEvent("claim", new Claim()); + CoreClient.RegisterButtonEvent("effects", new EffectsButtonEvent()); CoreClient.RegisterButtonEvent("inventory", new InventoryButtonEvent()); CoreClient.RegisterButtonEvent("multidrop", new MultidropButtonEvent()); CoreClient.RegisterButtonEvent("reroll", new Reroll()); diff --git a/tests/buttonEvents/Effects.test.ts b/tests/buttonEvents/Effects.test.ts new file mode 100644 index 0000000..557e64a --- /dev/null +++ b/tests/buttonEvents/Effects.test.ts @@ -0,0 +1,127 @@ +import {ButtonInteraction} from "discord.js"; +import Effects from "../../src/buttonEvents/Effects"; +import EffectHelper from "../../src/helpers/EffectHelper"; + +describe("execute", () => { + describe("GIVEN action in custom id is list", () => { + const interaction = { + customId: "effects list", + } as unknown as ButtonInteraction; + + let listSpy: jest.SpyInstance; + + beforeAll(async () => { + const effects = new Effects(); + + listSpy = jest.spyOn(effects as unknown as {"List": () => object}, "List") + .mockImplementation(); + + await effects.execute(interaction); + }); + + test("EXPECT list function to be called", () => { + expect(listSpy).toHaveBeenCalledTimes(1); + expect(listSpy).toHaveBeenCalledWith(interaction); + }); + }); +}); + +describe("List", () => { + let interaction: ButtonInteraction; + + const embed = { + name: "Embed", + }; + + const row = { + name: "Row", + }; + + beforeEach(() => { + interaction = { + customId: "effects list", + user: { + id: "userId", + }, + update: jest.fn(), + reply: jest.fn(), + } as unknown as ButtonInteraction; + }); + + describe("GIVEN page is a valid number", () => { + beforeEach(async () => { + interaction.customId += " 1"; + + EffectHelper.GenerateEffectEmbed = jest.fn() + .mockResolvedValue({ + embed, + row, + }); + + const effects = new Effects(); + + await effects.execute(interaction); + }); + + test("EXPECT EffectHelper.GenerateEffectEmbed to be called", () => { + expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledTimes(1); + expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledWith("userId", 1); + }); + + test("EXPECT interaction to be updated", () => { + expect(interaction.update).toHaveBeenCalledTimes(1); + expect(interaction.update).toHaveBeenCalledWith({ + embeds: [ embed ], + components: [ row ], + }); + }); + }); + + describe("GIVEN page in custom id is not supplied", () => { + beforeEach(async () => { + EffectHelper.GenerateEffectEmbed = jest.fn() + .mockResolvedValue({ + embed, + row, + }); + + const effects = new Effects(); + + await effects.execute(interaction); + }); + + test("EXPECT interaction to be replied with error", () => { + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith("Page option is not a valid number"); + }); + + test("EXPECT interaction to not be updated", () => { + expect(interaction.update).not.toHaveBeenCalled(); + }); + }); + + describe("GIVEN page in custom id is not a number", () => { + beforeEach(async () => { + interaction.customId += " test"; + + EffectHelper.GenerateEffectEmbed = jest.fn() + .mockResolvedValue({ + embed, + row, + }); + + const effects = new Effects(); + + await effects.execute(interaction); + }); + + test("EXPECT interaction to be replied with error", () => { + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith("Page option is not a valid number"); + }); + + test("EXPECT interaction to not be updated", () => { + expect(interaction.update).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/tests/commands/__snapshots__/effects.test.ts.snap b/tests/commands/__snapshots__/effects.test.ts.snap new file mode 100644 index 0000000..ede2091 --- /dev/null +++ b/tests/commands/__snapshots__/effects.test.ts.snap @@ -0,0 +1,40 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`constructor EXPECT CommandBuilder to be defined 1`] = ` +{ + "contexts": undefined, + "default_member_permissions": undefined, + "default_permission": undefined, + "description": "Effects", + "description_localizations": undefined, + "dm_permission": undefined, + "integration_types": undefined, + "name": "effects", + "name_localizations": undefined, + "nsfw": undefined, + "options": [ + { + "description": "List all effects I have", + "description_localizations": undefined, + "name": "list", + "name_localizations": undefined, + "options": [ + { + "autocomplete": undefined, + "choices": undefined, + "description": "The page number", + "description_localizations": undefined, + "max_value": undefined, + "min_value": 1, + "name": "page", + "name_localizations": undefined, + "required": false, + "type": 10, + }, + ], + "type": 1, + }, + ], + "type": 1, +} +`; diff --git a/tests/commands/effects.test.ts b/tests/commands/effects.test.ts new file mode 100644 index 0000000..8985477 --- /dev/null +++ b/tests/commands/effects.test.ts @@ -0,0 +1,164 @@ +import {ChatInputCommandInteraction} from "discord.js"; +import Effects from "../../src/commands/effects"; +import EffectHelper from "../../src/helpers/EffectHelper"; + +describe("constructor", () => { + let effects: Effects; + + beforeEach(() => { + effects = new Effects(); + }); + + test("EXPECT CommandBuilder to be defined", () => { + expect(effects.CommandBuilder).toMatchSnapshot(); + }); +}); + +describe("execute", () => { + describe("GIVEN interaction is not a chat input command", () => { + let interaction: ChatInputCommandInteraction; + + let listSpy: jest.SpyInstance; + + beforeEach(async () => { + interaction = { + isChatInputCommand: jest.fn().mockReturnValue(false), + } as unknown as ChatInputCommandInteraction; + + const effects = new Effects(); + + listSpy = jest.spyOn(effects as unknown as {"List": () => object}, "List") + .mockImplementation(); + + await effects.execute(interaction); + }); + + test("EXPECT isChatInputCommand to have been called", () => { + expect(interaction.isChatInputCommand).toHaveBeenCalledTimes(1); + }); + + test("EXPECT nothing to happen", () => { + expect(listSpy).not.toHaveBeenCalled(); + }); + }); + + describe("GIVEN subcommand is list", () => { + let interaction: ChatInputCommandInteraction; + + let listSpy: jest.SpyInstance; + + beforeEach(async () => { + interaction = { + isChatInputCommand: jest.fn().mockReturnValue(true), + options: { + getSubcommand: jest.fn().mockReturnValue("list"), + }, + } as unknown as ChatInputCommandInteraction; + + const effects = new Effects(); + + listSpy = jest.spyOn(effects as unknown as {"List": () => object}, "List") + .mockImplementation(); + + await effects.execute(interaction); + }); + + test("EXPECT subcommand function to be called", () => { + expect(interaction.options.getSubcommand).toHaveBeenCalledTimes(1); + }); + + test("EXPECT list function to be called", () => { + expect(listSpy).toHaveBeenCalledTimes(1); + expect(listSpy).toHaveBeenCalledWith(interaction); + }); + }); +}); + +describe("List", () => { + const effects: Effects = new Effects(); + let interaction: ChatInputCommandInteraction; + + const embed = { + name: "embed", + }; + + const row = { + name: "row", + }; + + beforeEach(async () => { + interaction = { + isChatInputCommand: jest.fn().mockReturnValue(true), + options: { + getSubcommand: jest.fn().mockReturnValue("list"), + }, + reply: jest.fn(), + user: { + id: "userId", + }, + } as unknown as ChatInputCommandInteraction; + + const effects = new Effects(); + + EffectHelper.GenerateEffectEmbed = jest.fn().mockReturnValue({ + embed, + row, + }); + + jest.spyOn(effects as unknown as {"List": () => object}, "List") + .mockImplementation(); + }); + + describe("GIVEN page option is supplied", () => { + describe("AND page is a valid number", () => { + beforeEach(async () => { + interaction.options.get = jest.fn().mockReturnValueOnce({ + value: "2", + }); + + await effects.execute(interaction); + }); + + test("EXPECT EffectHelper.GenerateEffectEmbed to have been called with page", () => { + expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledTimes(1); + expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledWith("userId", 2); + }); + + test("EXPECT interaction to have been replied", () => { + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith({ + embeds: [ embed ], + components: [ row ], + }); + }); + }); + + describe("AND page is not a valid number", () => { + beforeEach(async () => { + interaction.options.get = jest.fn().mockReturnValueOnce({ + value: "test", + }); + + await effects.execute(interaction); + }); + + test("EXPECT EffectHelper.GenerateEffectEmbed to have been called with page of 1", () => { + expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledTimes(1); + expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledWith("userId", 1); + }); + }); + }); + + describe("GIVEN page option is not supplied", () => { + beforeEach(async () => { + interaction.options.get = jest.fn().mockReturnValueOnce(undefined); + + await effects.execute(interaction); + }); + + test("EXPECT EffectHelper.GenerateEffectEmbed to have been called with page of 1", () => { + expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledTimes(1); + expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledWith("userId", 1); + }); + }); +}); diff --git a/tests/helpers/EffectHelper.test.ts b/tests/helpers/EffectHelper.test.ts index 343f06c..13dca37 100644 --- a/tests/helpers/EffectHelper.test.ts +++ b/tests/helpers/EffectHelper.test.ts @@ -1,3 +1,4 @@ +import {ActionRowBuilder, ButtonBuilder, EmbedBuilder} from "discord.js"; import UserEffect from "../../src/database/entities/app/UserEffect"; import EffectHelper from "../../src/helpers/EffectHelper"; @@ -279,3 +280,101 @@ describe("HasEffect", () => { }); }); }); + +describe("GenerateEffectEmbed", () => { + beforeEach(async () => { + UserEffect.FetchAllByUserIdPaginated = jest.fn() + .mockResolvedValue([ + [], + 0, + ]); + + await EffectHelper.GenerateEffectEmbed("userId", 1); + }); + + test("EXPECT UserEffect.FetchAllByUserIdPaginated to be called", () => { + expect(UserEffect.FetchAllByUserIdPaginated).toHaveBeenCalledTimes(1); + expect(UserEffect.FetchAllByUserIdPaginated).toHaveBeenCalledWith("userId", 0, 10); + }); + + describe("GIVEN there are no effects returned", () => { + let result: { + embed: EmbedBuilder, + row: ActionRowBuilder, + }; + + beforeEach(async () => { + UserEffect.FetchAllByUserIdPaginated = jest.fn() + .mockResolvedValue([ + [], + 0, + ]); + + result = await EffectHelper.GenerateEffectEmbed("userId", 1); + }); + + test("EXPECT result returned", () => { + expect(result).toMatchSnapshot(); + }); + }); + + describe("GIVEN there are effects returned", () => { + let result: { + embed: EmbedBuilder, + row: ActionRowBuilder, + }; + + beforeEach(async () => { + UserEffect.FetchAllByUserIdPaginated = jest.fn() + .mockResolvedValue([ + [ + { + Name: "name", + Unused: 1, + }, + ], + 1, + ]); + + result = await EffectHelper.GenerateEffectEmbed("userId", 1); + }); + + test("EXPECT result returned", () => { + expect(result).toMatchSnapshot(); + }); + + describe("AND it is the first page", () => { + beforeEach(async () => { + result = await EffectHelper.GenerateEffectEmbed("userId", 1) + }); + + test("EXPECT Previous button to be disabled", () => { + const button = result.row.components[0].data as unknown as { + label: string, + disabled: boolean + }; + + expect(button).toBeDefined(); + expect(button.label).toBe("Previous"); + expect(button.disabled).toBe(true); + }); + }); + + describe("AND it is the last page", () => { + beforeEach(async () => { + result = await EffectHelper.GenerateEffectEmbed("userId", 1) + }); + + test("EXPECT Next button to be disabled", () => { + const button = result.row.components[1].data as unknown as { + label: string, + disabled: boolean + }; + + expect(button).toBeDefined(); + expect(button.label).toBe("Next"); + expect(button.disabled).toBe(true); + }); + }); + }); +}); diff --git a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap new file mode 100644 index 0000000..6484acd --- /dev/null +++ b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap @@ -0,0 +1,71 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`GenerateEffectEmbed GIVEN there are effects returned EXPECT result returned 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "name x1", + "footer": { + "icon_url": undefined, + "text": "Page 1 of 1", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 0", + "disabled": true, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 2", + "disabled": true, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; + +exports[`GenerateEffectEmbed GIVEN there are no effects returned EXPECT result returned 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "*none*", + "footer": { + "icon_url": undefined, + "text": "Page 1 of 1", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 0", + "disabled": true, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 2", + "disabled": true, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; From 5db7cd9f11527ca5b71bc4176caf33750c4e7902 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 10 Dec 2024 10:57:50 +0000 Subject: [PATCH 43/59] Use node v22 --- .forgejo/workflows/production.yml | 2 +- .forgejo/workflows/stage.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/production.yml b/.forgejo/workflows/production.yml index cb4ed46..2625609 100644 --- a/.forgejo/workflows/production.yml +++ b/.forgejo/workflows/production.yml @@ -16,7 +16,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x - run: yarn install --frozen-lockfile - run: yarn build - run: yarn test diff --git a/.forgejo/workflows/stage.yml b/.forgejo/workflows/stage.yml index b6c27da..ff10ba6 100644 --- a/.forgejo/workflows/stage.yml +++ b/.forgejo/workflows/stage.yml @@ -16,7 +16,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x - run: yarn install --frozen-lockfile - run: yarn build - run: yarn test From 1cace42983dde7ccfd6d924d012b23270cc483b0 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 10 Dec 2024 11:00:11 +0000 Subject: [PATCH 44/59] Use node 20 --- .forgejo/workflows/production.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/production.yml b/.forgejo/workflows/production.yml index 2625609..cb4ed46 100644 --- a/.forgejo/workflows/production.yml +++ b/.forgejo/workflows/production.yml @@ -16,7 +16,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 22.x + node-version: 20.x - run: yarn install --frozen-lockfile - run: yarn build - run: yarn test From ed52f3e3dc508fdc5e6a5dca3f7c317e686d1721 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 10 Dec 2024 11:06:01 +0000 Subject: [PATCH 45/59] Use node 20 --- .forgejo/workflows/stage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/stage.yml b/.forgejo/workflows/stage.yml index ff10ba6..b6c27da 100644 --- a/.forgejo/workflows/stage.yml +++ b/.forgejo/workflows/stage.yml @@ -16,7 +16,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 22.x + node-version: 20.x - run: yarn install --frozen-lockfile - run: yarn build - run: yarn test From 3e81f8ce1d4b01fb5fc4e4ee710b5ed95fa34202 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 19 Jan 2025 15:19:28 +0000 Subject: [PATCH 46/59] Update id command from merge --- src/commands/id.ts | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/commands/id.ts b/src/commands/id.ts index ae924a6..ea37965 100644 --- a/src/commands/id.ts +++ b/src/commands/id.ts @@ -43,22 +43,20 @@ export default class Id extends Command { const series = CoreClient.Cards .find(x => x.cards.includes(card))!; - let image: Buffer; - const imageFileName = card.path.split("/").pop()!; + const files = []; + let imageFileName = ""; - try { - image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.path)); - } catch { - AppLogger.LogError("Commands/View", `Unable to fetch image for card ${card.id}.`); + if (!(card.path.startsWith("http://") || card.path.startsWith("https://"))) { + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.path)); + imageFileName = card.path.split("/").pop()!; - await interaction.reply(`Unable to fetch image for card ${card.id}.`); - return; + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + files.push(attachment); } await interaction.deferReply(); - const attachment = new AttachmentBuilder(image, { name: imageFileName }); - const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; @@ -67,7 +65,7 @@ export default class Id extends Command { try { await interaction.editReply({ embeds: [ embed ], - files: [ attachment ], + files: files, }); } catch (e) { AppLogger.LogError("Commands/View", `Error sending view for card ${card.id}: ${e}`); From a3248e978a676a7ed1794fa7efabd73ef074f8b2 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 25 Jan 2025 17:29:01 +0000 Subject: [PATCH 47/59] Create use effect command (#419) # Description Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. #380 ## Type of change Please delete options that are not relevant. - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update # How Has This Been Tested? Please describe the tests that you ran to verify the changes. Provide instructions so we can reproduce. Please also list any relevant details to your test configuration. # Checklist - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that provde my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/419 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- .env.example | 4 +- src/buttonEvents/Claim.ts | 11 +- src/buttonEvents/Effects.ts | 33 +- src/buttonEvents/Effects/List.ts | 20 + src/buttonEvents/Effects/Use.ts | 132 ++++++ src/buttonEvents/Multidrop.ts | 19 +- src/buttonEvents/Reroll.ts | 9 +- src/buttonEvents/Sacrifice.ts | 6 +- src/commands/drop.ts | 9 +- src/commands/effects.ts | 79 +++- src/commands/give.ts | 4 +- src/commands/id.ts | 4 +- src/commands/multidrop.ts | 9 +- src/commands/sacrifice.ts | 4 +- src/commands/stage/dropnumber.ts | 6 +- src/commands/stage/droprarity.ts | 9 +- src/constants/CardConstants.ts | 3 + src/constants/EffectDetails.ts | 19 + src/helpers/CardDropHelperMetadata.ts | 180 --------- src/helpers/CardSearchHelper.ts | 11 +- src/helpers/DropHelpers/DropEmbedHelper.ts | 85 ++++ src/helpers/DropHelpers/GetCardsHelper.ts | 91 +++++ .../DropHelpers/GetUnclaimedCardsHelper.ts | 63 +++ .../DropHelpers/MultidropEmbedHelper.ts | 28 ++ src/helpers/EffectHelper.ts | 27 +- src/helpers/TimeLengthInput.ts | 15 + tests/.gitkeep | 0 .../GenerateButtonInteractionMock.ts | 21 + tests/__types__/discord.js.ts | 17 + tests/buttonEvents/Claim.test.ts | 109 +++++ tests/buttonEvents/Effects.test.ts | 171 +++----- tests/buttonEvents/Effects/List.test.ts | 50 +++ tests/buttonEvents/Effects/Use.test.ts | 148 +++++++ .../Effects/__snapshots__/Use.test.ts.snap | 95 +++++ .../__snapshots__/effects.test.ts.snap | 40 -- tests/commands/effects.test.ts | 164 -------- .../database/entities/app/UserEffect.test.ts | 103 ----- .../DropHelpers/GetCardsHelper.test.ts | 68 ++++ .../GetUnclaimedCardsHelper.test.ts | 19 + tests/helpers/EffectHelper.test.ts | 380 ------------------ tests/helpers/TimeLengthInput.test.ts | 38 ++ .../__snapshots__/EffectHelper.test.ts.snap | 71 ---- 42 files changed, 1241 insertions(+), 1133 deletions(-) create mode 100644 src/buttonEvents/Effects/List.ts create mode 100644 src/buttonEvents/Effects/Use.ts create mode 100644 src/constants/EffectDetails.ts delete mode 100644 src/helpers/CardDropHelperMetadata.ts create mode 100644 src/helpers/DropHelpers/DropEmbedHelper.ts create mode 100644 src/helpers/DropHelpers/GetCardsHelper.ts create mode 100644 src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts create mode 100644 src/helpers/DropHelpers/MultidropEmbedHelper.ts delete mode 100644 tests/.gitkeep create mode 100644 tests/__functions__/discord.js/GenerateButtonInteractionMock.ts create mode 100644 tests/__types__/discord.js.ts create mode 100644 tests/buttonEvents/Claim.test.ts create mode 100644 tests/buttonEvents/Effects/List.test.ts create mode 100644 tests/buttonEvents/Effects/Use.test.ts create mode 100644 tests/buttonEvents/Effects/__snapshots__/Use.test.ts.snap delete mode 100644 tests/commands/__snapshots__/effects.test.ts.snap delete mode 100644 tests/commands/effects.test.ts delete mode 100644 tests/database/entities/app/UserEffect.test.ts create mode 100644 tests/helpers/DropHelpers/GetCardsHelper.test.ts create mode 100644 tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts delete mode 100644 tests/helpers/EffectHelper.test.ts create mode 100644 tests/helpers/TimeLengthInput.test.ts delete mode 100644 tests/helpers/__snapshots__/EffectHelper.test.ts.snap diff --git a/.env.example b/.env.example index 489569a..7f873ca 100644 --- a/.env.example +++ b/.env.example @@ -34,8 +34,6 @@ DB_LOGGING= DB_DATA_LOCATION=./.temp/database DB_ROOT_HOST=0.0.0.0 -DB_CARD_FILE=:memory: - EXPRESS_PORT=3302 -GDRIVESYNC_AUTO=true +GDRIVESYNC_AUTO=false diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts index 522ab40..97ee54d 100644 --- a/src/buttonEvents/Claim.ts +++ b/src/buttonEvents/Claim.ts @@ -4,9 +4,10 @@ import Inventory from "../database/entities/app/Inventory"; import { CoreClient } from "../client/client"; import { default as eClaim } from "../database/entities/app/Claim"; import AppLogger from "../client/appLogger"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import User from "../database/entities/app/User"; import CardConstants from "../constants/CardConstants"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import DropEmbedHelper from "../helpers/DropHelpers/DropEmbedHelper"; export default class Claim extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -69,16 +70,18 @@ export default class Claim extends ButtonEvent { await claim.Save(eClaim, claim); - const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + const card = GetCardsHelper.GetCardByCardNumber(cardNumber); if (!card) { + AppLogger.LogError("Button/Claim", `Unable to find card, ${cardNumber}`); + return; } const imageFileName = card.card.path.split("/").pop()!; - const embed = CardDropHelperMetadata.GenerateDropEmbed(card, inventory.Quantity, imageFileName, interaction.user.username, user.Currency); - const row = CardDropHelperMetadata.GenerateDropButtons(card, claimId, interaction.user.id, true); + const embed = DropEmbedHelper.GenerateDropEmbed(card, inventory.Quantity, imageFileName, interaction.user.username, user.Currency); + const row = DropEmbedHelper.GenerateDropButtons(card, claimId, interaction.user.id, true); await interaction.editReply({ embeds: [ embed ], diff --git a/src/buttonEvents/Effects.ts b/src/buttonEvents/Effects.ts index 0810c94..0f9686b 100644 --- a/src/buttonEvents/Effects.ts +++ b/src/buttonEvents/Effects.ts @@ -1,6 +1,8 @@ -import {ButtonInteraction} from "discord.js"; -import {ButtonEvent} from "../type/buttonEvent"; -import EffectHelper from "../helpers/EffectHelper"; +import { ButtonInteraction } from "discord.js"; +import { ButtonEvent } from "../type/buttonEvent"; +import List from "./Effects/List"; +import Use from "./Effects/Use"; +import AppLogger from "../client/appLogger"; export default class Effects extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -8,26 +10,13 @@ export default class Effects extends ButtonEvent { switch (action) { case "list": - await this.List(interaction); + await List(interaction); break; + case "use": + await Use.Execute(interaction); + break; + default: + AppLogger.LogError("Buttons/Effects", `Unknown action, ${action}`); } } - - private async List(interaction: ButtonInteraction) { - const pageOption = interaction.customId.split(" ")[2]; - - const page = Number(pageOption); - - if (!page) { - await interaction.reply("Page option is not a valid number"); - return; - } - - const result = await EffectHelper.GenerateEffectEmbed(interaction.user.id, page); - - await interaction.update({ - embeds: [ result.embed ], - components: [ result.row ], - }); - } } diff --git a/src/buttonEvents/Effects/List.ts b/src/buttonEvents/Effects/List.ts new file mode 100644 index 0000000..059623b --- /dev/null +++ b/src/buttonEvents/Effects/List.ts @@ -0,0 +1,20 @@ +import { ButtonInteraction } from "discord.js"; +import EffectHelper from "../../helpers/EffectHelper"; + +export default async function List(interaction: ButtonInteraction) { + const pageOption = interaction.customId.split(" ")[2]; + + const page = Number(pageOption); + + if (!page) { + await interaction.reply("Page option is not a valid number"); + return; + } + + const result = await EffectHelper.GenerateEffectEmbed(interaction.user.id, page); + + await interaction.update({ + embeds: [ result.embed ], + components: [ result.row ], + }); +} \ No newline at end of file diff --git a/src/buttonEvents/Effects/Use.ts b/src/buttonEvents/Effects/Use.ts new file mode 100644 index 0000000..5bfe2fd --- /dev/null +++ b/src/buttonEvents/Effects/Use.ts @@ -0,0 +1,132 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, EmbedBuilder } from "discord.js"; +import { EffectDetails } from "../../constants/EffectDetails"; +import EffectHelper from "../../helpers/EffectHelper"; +import EmbedColours from "../../constants/EmbedColours"; +import TimeLengthInput from "../../helpers/TimeLengthInput"; +import AppLogger from "../../client/appLogger"; + +export default class Use { + public static async Execute(interaction: ButtonInteraction) { + const subaction = interaction.customId.split(" ")[2]; + + switch (subaction) { + case "confirm": + await this.UseConfirm(interaction); + break; + case "cancel": + await this.UseCancel(interaction); + break; + } + } + + private static async UseConfirm(interaction: ButtonInteraction) { + const id = interaction.customId.split(" ")[3]; + + const effectDetail = EffectDetails.get(id); + + if (!effectDetail) { + AppLogger.LogError("Button/Effects/Use", `Effect not found, ${id}`); + + await interaction.reply("Effect not found in system!"); + return; + } + + const now = new Date(); + + const whenExpires = new Date(now.getTime() + effectDetail.duration); + + const result = await EffectHelper.UseEffect(interaction.user.id, id, whenExpires); + + if (!result) { + await interaction.reply("Unable to use effect! Please make sure you have it in your inventory and is not on cooldown"); + return; + } + + const embed = new EmbedBuilder() + .setTitle("Effect Used") + .setDescription("You now have an active effect!") + .setColor(EmbedColours.Green) + .addFields([ + { + name: "Effect", + value: effectDetail.friendlyName, + inline: true, + }, + { + name: "Expires", + value: ``, + inline: true, + }, + ]); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setLabel("Confirm") + .setCustomId(`effects use confirm ${effectDetail.id}`) + .setStyle(ButtonStyle.Primary) + .setDisabled(true), + new ButtonBuilder() + .setLabel("Cancel") + .setCustomId(`effects use cancel ${effectDetail.id}`) + .setStyle(ButtonStyle.Danger) + .setDisabled(true), + ]); + + await interaction.update({ + embeds: [ embed ], + components: [ row ], + }); + } + + private static async UseCancel(interaction: ButtonInteraction) { + const id = interaction.customId.split(" ")[3]; + + const effectDetail = EffectDetails.get(id); + + if (!effectDetail) { + AppLogger.LogError("Button/Effects/Cancel", `Effect not found, ${id}`); + + await interaction.reply("Effect not found in system!"); + return; + } + + const timeLengthInput = TimeLengthInput.ConvertFromMilliseconds(effectDetail.duration); + + const embed = new EmbedBuilder() + .setTitle("Effect Use Cancelled") + .setDescription("The effect from your inventory has not been used") + .setColor(EmbedColours.Grey) + .addFields([ + { + name: "Effect", + value: effectDetail.friendlyName, + inline: true, + }, + { + name: "Expires", + value: timeLengthInput.GetLengthShort(), + inline: true, + }, + ]); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setLabel("Confirm") + .setCustomId(`effects use confirm ${effectDetail.id}`) + .setStyle(ButtonStyle.Primary) + .setDisabled(true), + new ButtonBuilder() + .setLabel("Cancel") + .setCustomId(`effects use cancel ${effectDetail.id}`) + .setStyle(ButtonStyle.Danger) + .setDisabled(true), + ]); + + await interaction.update({ + embeds: [ embed ], + components: [ row ], + }); + } +} diff --git a/src/buttonEvents/Multidrop.ts b/src/buttonEvents/Multidrop.ts index 604f02c..e6ea7c2 100644 --- a/src/buttonEvents/Multidrop.ts +++ b/src/buttonEvents/Multidrop.ts @@ -1,7 +1,6 @@ import { AttachmentBuilder, ButtonInteraction, EmbedBuilder } from "discord.js"; import { ButtonEvent } from "../type/buttonEvent"; import AppLogger from "../client/appLogger"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import Inventory from "../database/entities/app/Inventory"; import EmbedColours from "../constants/EmbedColours"; import { readFileSync } from "fs"; @@ -9,6 +8,8 @@ import path from "path"; import ErrorMessages from "../constants/ErrorMessages"; import User from "../database/entities/app/User"; import { GetSacrificeAmount } from "../constants/CardRarity"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import MultidropEmbedHelper from "../helpers/DropHelpers/MultidropEmbedHelper"; export default class Multidrop extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -37,7 +38,7 @@ export default class Multidrop extends ButtonEvent { return; } - const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + const card = GetCardsHelper.GetCardByCardNumber(cardNumber); if (!card) { await interaction.reply("Unable to find card."); @@ -85,7 +86,7 @@ export default class Multidrop extends ButtonEvent { } // Drop next card - const randomCard = CardDropHelperMetadata.GetRandomCard(); + const randomCard = GetCardsHelper.GetRandomCard(); cardsRemaining -= 1; if (!randomCard) { @@ -105,9 +106,9 @@ export default class Multidrop extends ButtonEvent { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); + const embed = MultidropEmbedHelper.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); - const row = CardDropHelperMetadata.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id, cardsRemaining < 0); + const row = MultidropEmbedHelper.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id, cardsRemaining < 0); await interaction.editReply({ embeds: [ embed ], @@ -131,7 +132,7 @@ export default class Multidrop extends ButtonEvent { return; } - const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + const card = GetCardsHelper.GetCardByCardNumber(cardNumber); if (!card) { await interaction.reply("Unable to find card."); @@ -175,7 +176,7 @@ export default class Multidrop extends ButtonEvent { } // Drop next card - const randomCard = CardDropHelperMetadata.GetRandomCard(); + const randomCard = GetCardsHelper.GetRandomCard(); cardsRemaining -= 1; if (!randomCard) { @@ -195,9 +196,9 @@ export default class Multidrop extends ButtonEvent { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); + const embed = MultidropEmbedHelper.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); - const row = CardDropHelperMetadata.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id, cardsRemaining < 0); + const row = MultidropEmbedHelper.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id, cardsRemaining < 0); await interaction.editReply({ embeds: [ embed ], diff --git a/src/buttonEvents/Reroll.ts b/src/buttonEvents/Reroll.ts index dc9622a..e25e474 100644 --- a/src/buttonEvents/Reroll.ts +++ b/src/buttonEvents/Reroll.ts @@ -5,11 +5,12 @@ import { v4 } from "uuid"; import { CoreClient } from "../client/client"; import Inventory from "../database/entities/app/Inventory"; import Config from "../database/entities/app/Config"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import path from "path"; import AppLogger from "../client/appLogger"; import User from "../database/entities/app/User"; import CardConstants from "../constants/CardConstants"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import DropEmbedHelper from "../helpers/DropHelpers/DropEmbedHelper"; export default class Reroll extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -39,7 +40,7 @@ export default class Reroll extends ButtonEvent { return; } - const randomCard = CardDropHelperMetadata.GetRandomCard(); + const randomCard = await GetCardsHelper.FetchCard(interaction.user.id); if (!randomCard) { await interaction.reply("Unable to fetch card, please try again."); @@ -66,11 +67,11 @@ export default class Reroll extends ButtonEvent { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed(randomCard, quantityClaimed, imageFileName, undefined, user.Currency); + const embed = DropEmbedHelper.GenerateDropEmbed(randomCard, quantityClaimed, imageFileName, undefined, user.Currency); const claimId = v4(); - const row = CardDropHelperMetadata.GenerateDropButtons(randomCard, claimId, interaction.user.id); + const row = DropEmbedHelper.GenerateDropButtons(randomCard, claimId, interaction.user.id); await interaction.editReply({ embeds: [ embed ], diff --git a/src/buttonEvents/Sacrifice.ts b/src/buttonEvents/Sacrifice.ts index 463ca1f..de0bb77 100644 --- a/src/buttonEvents/Sacrifice.ts +++ b/src/buttonEvents/Sacrifice.ts @@ -1,10 +1,10 @@ import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, EmbedBuilder } from "discord.js"; import { ButtonEvent } from "../type/buttonEvent"; import Inventory from "../database/entities/app/Inventory"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import { CardRarityToString, GetSacrificeAmount } from "../constants/CardRarity"; import EmbedColours from "../constants/EmbedColours"; import User from "../database/entities/app/User"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; export default class Sacrifice extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -42,7 +42,7 @@ export default class Sacrifice extends ButtonEvent { return; } - const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + const cardData = GetCardsHelper.GetCardByCardNumber(cardNumber); if (!cardData) { await interaction.reply("Unable to find card in the database."); @@ -124,7 +124,7 @@ export default class Sacrifice extends ButtonEvent { return; } - const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardNumber); + const cardData = GetCardsHelper.GetCardByCardNumber(cardNumber); if (!cardData) { await interaction.reply("Unable to find card in the database."); diff --git a/src/commands/drop.ts b/src/commands/drop.ts index 63ecdd9..6c93af6 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -5,12 +5,13 @@ import { CoreClient } from "../client/client"; import { v4 } from "uuid"; import Inventory from "../database/entities/app/Inventory"; import Config from "../database/entities/app/Config"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import path from "path"; import AppLogger from "../client/appLogger"; import User from "../database/entities/app/User"; import CardConstants from "../constants/CardConstants"; import ErrorMessages from "../constants/ErrorMessages"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import DropEmbedHelper from "../helpers/DropHelpers/DropEmbedHelper"; export default class Drop extends Command { constructor() { @@ -47,7 +48,7 @@ export default class Drop extends Command { return; } - const randomCard = CardDropHelperMetadata.GetRandomCard(); + const randomCard = await GetCardsHelper.FetchCard(interaction.user.id); if (!randomCard) { AppLogger.LogWarn("Commands/Drop", ErrorMessages.UnableToFetchCard); @@ -73,11 +74,11 @@ export default class Drop extends Command { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed(randomCard, quantityClaimed, imageFileName, undefined, user.Currency); + const embed = DropEmbedHelper.GenerateDropEmbed(randomCard, quantityClaimed, imageFileName, undefined, user.Currency); const claimId = v4(); - const row = CardDropHelperMetadata.GenerateDropButtons(randomCard, claimId, interaction.user.id); + const row = DropEmbedHelper.GenerateDropButtons(randomCard, claimId, interaction.user.id); await interaction.editReply({ embeds: [ embed ], diff --git a/src/commands/effects.ts b/src/commands/effects.ts index bcaa929..98727b9 100644 --- a/src/commands/effects.ts +++ b/src/commands/effects.ts @@ -1,6 +1,10 @@ -import {CommandInteraction, SlashCommandBuilder} from "discord.js"; -import {Command} from "../type/command"; +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; +import { Command } from "../type/command"; import EffectHelper from "../helpers/EffectHelper"; +import { EffectDetails } from "../constants/EffectDetails"; +import TimeLengthInput from "../helpers/TimeLengthInput"; +import EmbedColours from "../constants/EmbedColours"; +import AppLogger from "../client/appLogger"; export default class Effects extends Command { constructor() { @@ -15,7 +19,17 @@ export default class Effects extends Command { .addNumberOption(x => x .setName("page") .setDescription("The page number") - .setMinValue(1))); + .setMinValue(1))) + .addSubcommand(x => x + .setName("use") + .setDescription("Use an effect in your inventory") + .addStringOption(y => y + .setName("id") + .setDescription("The effect id to use") + .setRequired(true) + .setChoices([ + { name: "Unclaimed Chance Up", value: "unclaimed" }, + ]))); } public override async execute(interaction: CommandInteraction) { @@ -27,6 +41,9 @@ export default class Effects extends Command { case "list": await this.List(interaction); break; + case "use": + await this.Use(interaction); + break; } } @@ -42,4 +59,60 @@ export default class Effects extends Command { components: [ result.row ], }); } + + private async Use(interaction: CommandInteraction) { + const id = interaction.options.get("id", true).value!.toString(); + + const effectDetail = EffectDetails.get(id); + + if (!effectDetail) { + AppLogger.LogWarn("Commands/Effects", `Unable to find effect details for ${id}`); + + await interaction.reply("Unable to find effect!"); + return; + } + + const canUseEffect = await EffectHelper.CanUseEffect(interaction.user.id, id); + + if (!canUseEffect) { + await interaction.reply("Unable to use effect! Please make sure you have it in your inventory and is not on cooldown"); + return; + } + + const timeLengthInput = TimeLengthInput.ConvertFromMilliseconds(effectDetail.duration); + + const embed = new EmbedBuilder() + .setTitle("Effect Confirmation") + .setDescription("Would you like to use this effect?") + .setColor(EmbedColours.Ok) + .addFields([ + { + name: "Effect", + value: effectDetail.friendlyName, + inline: true, + }, + { + name: "Length", + value: timeLengthInput.GetLengthShort(), + inline: true, + }, + ]); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setLabel("Confirm") + .setCustomId(`effects use confirm ${effectDetail.id}`) + .setStyle(ButtonStyle.Primary), + new ButtonBuilder() + .setLabel("Cancel") + .setCustomId(`effects use cancel ${effectDetail.id}`) + .setStyle(ButtonStyle.Danger), + ]); + + await interaction.reply({ + embeds: [ embed ], + components: [ row ], + }); + } } diff --git a/src/commands/give.ts b/src/commands/give.ts index 3ffbe8f..35dfa04 100644 --- a/src/commands/give.ts +++ b/src/commands/give.ts @@ -2,10 +2,10 @@ import { CacheType, CommandInteraction, PermissionsBitField, SlashCommandBuilder import { Command } from "../type/command"; import { CoreClient } from "../client/client"; import Config from "../database/entities/app/Config"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import Inventory from "../database/entities/app/Inventory"; import AppLogger from "../client/appLogger"; import User from "../database/entities/app/User"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; export default class Give extends Command { constructor() { @@ -81,7 +81,7 @@ export default class Give extends Command { AppLogger.LogSilly("Commands/Give/GiveCard", `Parameters: cardNumber=${cardNumber.value}, user=${user.id}`); - const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber.value!.toString()); + const card = GetCardsHelper.GetCardByCardNumber(cardNumber.value!.toString()); if (!card) { await interaction.reply("Unable to fetch card, please try again."); diff --git a/src/commands/id.ts b/src/commands/id.ts index ea37965..0f11aaa 100644 --- a/src/commands/id.ts +++ b/src/commands/id.ts @@ -4,8 +4,8 @@ import { CoreClient } from "../client/client"; import { readFileSync } from "fs"; import path from "path"; import Inventory from "../database/entities/app/Inventory"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import AppLogger from "../client/appLogger"; +import DropEmbedHelper from "../helpers/DropHelpers/DropEmbedHelper"; export default class Id extends Command { constructor() { @@ -60,7 +60,7 @@ export default class Id extends Command { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed({ card, series }, quantityClaimed, imageFileName); + const embed = DropEmbedHelper.GenerateDropEmbed({ card, series }, quantityClaimed, imageFileName); try { await interaction.editReply({ diff --git a/src/commands/multidrop.ts b/src/commands/multidrop.ts index f35b921..aa42686 100644 --- a/src/commands/multidrop.ts +++ b/src/commands/multidrop.ts @@ -6,10 +6,11 @@ import Config from "../database/entities/app/Config"; import AppLogger from "../client/appLogger"; import User from "../database/entities/app/User"; import CardConstants from "../constants/CardConstants"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import { readFileSync } from "fs"; import path from "path"; import Inventory from "../database/entities/app/Inventory"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import MultidropEmbedHelper from "../helpers/DropHelpers/MultidropEmbedHelper"; export default class Multidrop extends Command { constructor() { @@ -49,7 +50,7 @@ export default class Multidrop extends Command { user.RemoveCurrency(CardConstants.MultidropCost); await user.Save(User, user); - const randomCard = CardDropHelperMetadata.GetRandomCard(); + const randomCard = GetCardsHelper.GetRandomCard(); const cardsRemaining = CardConstants.MultidropQuantity - 1; if (!randomCard) { @@ -69,9 +70,9 @@ export default class Multidrop extends Command { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); + const embed = MultidropEmbedHelper.GenerateMultidropEmbed(randomCard, quantityClaimed, imageFileName, cardsRemaining, undefined, user.Currency); - const row = CardDropHelperMetadata.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id); + const row = MultidropEmbedHelper.GenerateMultidropButtons(randomCard, cardsRemaining, interaction.user.id); await interaction.editReply({ embeds: [ embed ], diff --git a/src/commands/sacrifice.ts b/src/commands/sacrifice.ts index 9683714..a44a69e 100644 --- a/src/commands/sacrifice.ts +++ b/src/commands/sacrifice.ts @@ -2,8 +2,8 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CacheType, CommandInterac import { Command } from "../type/command"; import Inventory from "../database/entities/app/Inventory"; import { CardRarityToString, GetSacrificeAmount } from "../constants/CardRarity"; -import CardDropHelperMetadata from "../helpers/CardDropHelperMetadata"; import EmbedColours from "../constants/EmbedColours"; +import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; export default class Sacrifice extends Command { constructor() { @@ -41,7 +41,7 @@ export default class Sacrifice extends Command { return; } - const cardData = CardDropHelperMetadata.GetCardByCardNumber(cardnumber.value! as string); + const cardData = GetCardsHelper.GetCardByCardNumber(cardnumber.value! as string); if (!cardData) { await interaction.reply("Unable to find card in the database."); diff --git a/src/commands/stage/dropnumber.ts b/src/commands/stage/dropnumber.ts index 750210d..f9391d2 100644 --- a/src/commands/stage/dropnumber.ts +++ b/src/commands/stage/dropnumber.ts @@ -5,7 +5,7 @@ import Inventory from "../../database/entities/app/Inventory"; import { v4 } from "uuid"; import { CoreClient } from "../../client/client"; import path from "path"; -import CardDropHelperMetadata from "../../helpers/CardDropHelperMetadata"; +import DropEmbedHelper from "../../helpers/DropHelpers/DropEmbedHelper"; export default class Dropnumber extends Command { constructor() { @@ -60,11 +60,11 @@ export default class Dropnumber extends Command { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed({ card, series }, quantityClaimed, imageFileName); + const embed = DropEmbedHelper.GenerateDropEmbed({ card, series }, quantityClaimed, imageFileName); const claimId = v4(); - const row = CardDropHelperMetadata.GenerateDropButtons({ card, series }, claimId, interaction.user.id); + const row = DropEmbedHelper.GenerateDropButtons({ card, series }, claimId, interaction.user.id); try { await interaction.editReply({ diff --git a/src/commands/stage/droprarity.ts b/src/commands/stage/droprarity.ts index 0e95db0..75f8a7f 100644 --- a/src/commands/stage/droprarity.ts +++ b/src/commands/stage/droprarity.ts @@ -5,8 +5,9 @@ import { readFileSync } from "fs"; import Inventory from "../../database/entities/app/Inventory"; import { v4 } from "uuid"; import { CoreClient } from "../../client/client"; -import CardDropHelperMetadata from "../../helpers/CardDropHelperMetadata"; import path from "path"; +import GetCardsHelper from "../../helpers/DropHelpers/GetCardsHelper"; +import DropEmbedHelper from "../../helpers/DropHelpers/DropEmbedHelper"; export default class Droprarity extends Command { constructor() { @@ -39,7 +40,7 @@ export default class Droprarity extends Command { return; } - const card = await CardDropHelperMetadata.GetRandomCardByRarity(rarityType); + const card = await GetCardsHelper.GetRandomCardByRarity(rarityType); if (!card) { await interaction.reply("Card not found"); @@ -61,11 +62,11 @@ export default class Droprarity extends Command { const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, card.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed(card, quantityClaimed, imageFileName); + const embed = DropEmbedHelper.GenerateDropEmbed(card, quantityClaimed, imageFileName); const claimId = v4(); - const row = CardDropHelperMetadata.GenerateDropButtons(card, claimId, interaction.user.id); + const row = DropEmbedHelper.GenerateDropButtons(card, claimId, interaction.user.id); try { await interaction.editReply({ diff --git a/src/constants/CardConstants.ts b/src/constants/CardConstants.ts index 3f9723b..60a7f59 100644 --- a/src/constants/CardConstants.ts +++ b/src/constants/CardConstants.ts @@ -7,4 +7,7 @@ export default class CardConstants { // Multidrop public static readonly MultidropCost = this.ClaimCost * 10; public static readonly MultidropQuantity = 11; + + // Effects + public static readonly UnusedChanceUpChance = 0.5; } \ No newline at end of file diff --git a/src/constants/EffectDetails.ts b/src/constants/EffectDetails.ts new file mode 100644 index 0000000..4b84dad --- /dev/null +++ b/src/constants/EffectDetails.ts @@ -0,0 +1,19 @@ +class EffectDetail { + public readonly id: string; + public readonly friendlyName: string; + public readonly duration: number; + public readonly cost: number; + public readonly cooldown: number; + + constructor(id: string, friendlyName: string, duration: number, cost: number, cooldown: number) { + this.id = id; + this.friendlyName = friendlyName; + this.duration = duration; + this.cost = cost; + this.cooldown = cooldown; + } +}; + +export const EffectDetails = new Map([ + [ "unclaimed", new EffectDetail("unclaimed", "Unclaimed Chance Up", 10 * 60 * 1000, 100, 3 * 60 * 60 * 1000) ], +]); diff --git a/src/helpers/CardDropHelperMetadata.ts b/src/helpers/CardDropHelperMetadata.ts deleted file mode 100644 index f9f1ea8..0000000 --- a/src/helpers/CardDropHelperMetadata.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; -import { CardRarity, CardRarityToColour, CardRarityToString, GetSacrificeAmount } from "../constants/CardRarity"; -import CardRarityChances from "../constants/CardRarityChances"; -import { DropResult } from "../contracts/SeriesMetadata"; -import { CoreClient } from "../client/client"; -import AppLogger from "../client/appLogger"; -import CardConstants from "../constants/CardConstants"; -import StringTools from "./StringTools"; - -export default class CardDropHelperMetadata { - public static GetRandomCard(): DropResult | undefined { - const randomRarity = Math.random() * 100; - - let cardRarity: CardRarity; - - const bronzeChance = CardRarityChances.Bronze; - const silverChance = bronzeChance + CardRarityChances.Silver; - const goldChance = silverChance + CardRarityChances.Gold; - const mangaChance = goldChance + CardRarityChances.Manga; - - if (randomRarity < bronzeChance) cardRarity = CardRarity.Bronze; - else if (randomRarity < silverChance) cardRarity = CardRarity.Silver; - else if (randomRarity < goldChance) cardRarity = CardRarity.Gold; - else if (randomRarity < mangaChance) cardRarity = CardRarity.Manga; - else cardRarity = CardRarity.Legendary; - - const randomCard = this.GetRandomCardByRarity(cardRarity); - - AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCard", `Random card: ${randomCard?.card.id} ${randomCard?.card.name}`); - - return randomCard; - } - - public static GetRandomCardByRarity(rarity: CardRarity): DropResult | undefined { - AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarity", `Parameters: rarity=${rarity}`); - - const allCards = CoreClient.Cards - .flatMap(x => x.cards) - .filter(x => x.type == rarity); - - const randomCardIndex = Math.floor(Math.random() * allCards.length); - - const card = allCards[randomCardIndex]; - const series = CoreClient.Cards - .find(x => x.cards.includes(card)); - - if (!series) { - AppLogger.LogWarn("CardDropHelperMetadata/GetRandomCardByRarity", `Series not found for card ${card.id}`); - - return undefined; - } - - AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarity", `Random card: ${card.id} ${card.name}`); - - return { - series: series, - card: card, - }; - } - - public static GetCardByCardNumber(cardNumber: string): DropResult | undefined { - AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Parameters: cardNumber=${cardNumber}`); - - const card = CoreClient.Cards - .flatMap(x => x.cards) - .find(x => x.id == cardNumber); - - const series = CoreClient.Cards - .find(x => x.cards.find(y => y.id == card?.id)); - - AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Card: ${card?.id} ${card?.name}`); - AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Series: ${series?.id} ${series?.name}`); - - if (!card || !series) { - AppLogger.LogVerbose("CardDropHelperMetadata/GetCardByCardNumber", `Unable to find card metadata: ${cardNumber}`); - return undefined; - } - - return { card, series }; - } - - public static GenerateDropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, claimedBy?: string, currency?: number): EmbedBuilder { - AppLogger.LogSilly("CardDropHelperMetadata/GenerateDropEmbed", `Parameters: drop=${drop.card.id}, quantityClaimed=${quantityClaimed}, imageFileName=${imageFileName}`); - - const description = drop.card.subseries ?? drop.series.name; - let colour = CardRarityToColour(drop.card.type); - - if (drop.card.colour && StringTools.IsHexCode(drop.card.colour)) { - const hexCode = Number("0x" + drop.card.colour); - - if (hexCode) { - colour = hexCode; - } else { - AppLogger.LogWarn("CardDropHelperMetadata/GenerateDropEmbed", `Card's colour override is invalid: ${drop.card.id}, ${drop.card.colour}`); - } - } else if (drop.card.colour) { - AppLogger.LogWarn("CardDropHelperMetadata/GenerateDropEmbed", `Card's colour override is invalid: ${drop.card.id}, ${drop.card.colour}`); - } - - let imageUrl = `attachment://${imageFileName}`; - - if (drop.card.path.startsWith("http://") || drop.card.path.startsWith("https://")) { - imageUrl = drop.card.path; - } - - const embed = new EmbedBuilder() - .setTitle(drop.card.name) - .setDescription(description) - .setFooter({ text: `${CardRarityToString(drop.card.type)} · ${drop.card.id}` }) - .setColor(colour) - .setImage(imageUrl) - .addFields([ - { - name: "Claimed", - value: `${quantityClaimed}`, - inline: true, - } - ]); - - if (claimedBy != null) { - embed.addFields([ - { - name: "Claimed by", - value: claimedBy, - inline: true, - } - ]); - } - - if (currency != null) { - embed.addFields([ - { - name: "Currency", - value: `${currency}`, - inline: true, - } - ]); - } - - return embed; - } - - public static GenerateDropButtons(drop: DropResult, claimId: string, userId: string, disabled: boolean = false): ActionRowBuilder { - AppLogger.LogSilly("CardDropHelperMetadata/GenerateDropButtons", `Parameters: drop=${drop.card.id}, claimId=${claimId}, userId=${userId}`); - - return new ActionRowBuilder() - .addComponents( - new ButtonBuilder() - .setCustomId(`claim ${drop.card.id} ${claimId} ${userId}`) - .setLabel(`Claim (${CardConstants.ClaimCost} 🪙)`) - .setStyle(ButtonStyle.Primary) - .setDisabled(disabled), - new ButtonBuilder() - .setCustomId("reroll") - .setLabel("Reroll") - .setStyle(ButtonStyle.Secondary)); - } - - public static GenerateMultidropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, cardsRemaining: number, claimedBy?: string, currency?: number): EmbedBuilder { - const dropEmbed = this.GenerateDropEmbed(drop, quantityClaimed, imageFileName, claimedBy, currency); - - dropEmbed.setFooter({ text: `${dropEmbed.data.footer?.text} · ${cardsRemaining} Remaining`}); - - return dropEmbed; - } - - public static GenerateMultidropButtons(drop: DropResult, cardsRemaining: number, userId: string, disabled = false): ActionRowBuilder { - return new ActionRowBuilder() - .addComponents( - new ButtonBuilder() - .setCustomId(`multidrop keep ${drop.card.id} ${cardsRemaining} ${userId}`) - .setLabel("Keep") - .setStyle(ButtonStyle.Primary) - .setDisabled(disabled), - new ButtonBuilder() - .setCustomId(`multidrop sacrifice ${drop.card.id} ${cardsRemaining} ${userId}`) - .setLabel(`Sacrifice (+${GetSacrificeAmount(drop.card.type)} 🪙)`) - .setStyle(ButtonStyle.Secondary)); - } -} diff --git a/src/helpers/CardSearchHelper.ts b/src/helpers/CardSearchHelper.ts index d548245..df0265c 100644 --- a/src/helpers/CardSearchHelper.ts +++ b/src/helpers/CardSearchHelper.ts @@ -1,11 +1,12 @@ import {ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder} from "discord.js"; import Fuse from "fuse.js"; import {CoreClient} from "../client/client.js"; -import CardDropHelperMetadata from "./CardDropHelperMetadata.js"; import Inventory from "../database/entities/app/Inventory.js"; import {readFileSync} from "fs"; import path from "path"; import AppLogger from "../client/appLogger.js"; +import GetCardsHelper from "./DropHelpers/GetCardsHelper.js"; +import DropEmbedHelper from "./DropHelpers/DropEmbedHelper.js"; interface ReturnedPage { embed: EmbedBuilder, @@ -32,7 +33,7 @@ export default class CardSearchHelper { return undefined; } - const card = CardDropHelperMetadata.GetCardByCardNumber(entry.item.id); + const card = GetCardsHelper.GetCardByCardNumber(entry.item.id); if (!card) return undefined; @@ -51,7 +52,7 @@ export default class CardSearchHelper { const inventory = await Inventory.FetchOneByCardNumberAndUserId(userid, card.card.id); const quantityClaimed = inventory?.Quantity ?? 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed(card, quantityClaimed, imageFileName); + const embed = DropEmbedHelper.GenerateDropEmbed(card, quantityClaimed, imageFileName); const row = new ActionRowBuilder() .addComponents( @@ -72,7 +73,7 @@ export default class CardSearchHelper { public static async GenerateSearchPageFromQuery(results: string[], userid: string, page: number): Promise { const currentPageId = results[page - 1]; - const card = CardDropHelperMetadata.GetCardByCardNumber(currentPageId); + const card = GetCardsHelper.GetCardByCardNumber(currentPageId); if (!card) { AppLogger.LogError("CardSearchHelper/GenerateSearchPageFromQuery", `Unable to find card by id: ${currentPageId}.`); @@ -95,7 +96,7 @@ export default class CardSearchHelper { const inventory = await Inventory.FetchOneByCardNumberAndUserId(userid, card.card.id); const quantityClaimed = inventory?.Quantity ?? 0; - const embed = CardDropHelperMetadata.GenerateDropEmbed(card, quantityClaimed, imageFileName); + const embed = DropEmbedHelper.GenerateDropEmbed(card, quantityClaimed, imageFileName); const row = new ActionRowBuilder() .addComponents( diff --git a/src/helpers/DropHelpers/DropEmbedHelper.ts b/src/helpers/DropHelpers/DropEmbedHelper.ts new file mode 100644 index 0000000..c739de7 --- /dev/null +++ b/src/helpers/DropHelpers/DropEmbedHelper.ts @@ -0,0 +1,85 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; +import { DropResult } from "../../contracts/SeriesMetadata"; +import AppLogger from "../../client/appLogger"; +import { CardRarityToColour, CardRarityToString } from "../../constants/CardRarity"; +import StringTools from "../StringTools"; +import CardConstants from "../../constants/CardConstants"; + +export default class DropEmbedHelper { + public static GenerateDropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, claimedBy?: string, currency?: number): EmbedBuilder { + AppLogger.LogSilly("CardDropHelperMetadata/GenerateDropEmbed", `Parameters: drop=${drop.card.id}, quantityClaimed=${quantityClaimed}, imageFileName=${imageFileName}`); + + const description = drop.card.subseries ?? drop.series.name; + let colour = CardRarityToColour(drop.card.type); + + if (drop.card.colour && StringTools.IsHexCode(drop.card.colour)) { + const hexCode = Number("0x" + drop.card.colour); + + if (hexCode) { + colour = hexCode; + } else { + AppLogger.LogWarn("CardDropHelperMetadata/GenerateDropEmbed", `Card's colour override is invalid: ${drop.card.id}, ${drop.card.colour}`); + } + } else if (drop.card.colour) { + AppLogger.LogWarn("CardDropHelperMetadata/GenerateDropEmbed", `Card's colour override is invalid: ${drop.card.id}, ${drop.card.colour}`); + } + + let imageUrl = `attachment://${imageFileName}`; + + if (drop.card.path.startsWith("http://") || drop.card.path.startsWith("https://")) { + imageUrl = drop.card.path; + } + + const embed = new EmbedBuilder() + .setTitle(drop.card.name) + .setDescription(description) + .setFooter({ text: `${CardRarityToString(drop.card.type)} · ${drop.card.id}` }) + .setColor(colour) + .setImage(imageUrl) + .addFields([ + { + name: "Claimed", + value: `${quantityClaimed}`, + inline: true, + } + ]); + + if (claimedBy != null) { + embed.addFields([ + { + name: "Claimed by", + value: claimedBy, + inline: true, + } + ]); + } + + if (currency != null) { + embed.addFields([ + { + name: "Currency", + value: `${currency}`, + inline: true, + } + ]); + } + + return embed; + } + + public static GenerateDropButtons(drop: DropResult, claimId: string, userId: string, disabled: boolean = false): ActionRowBuilder { + AppLogger.LogSilly("CardDropHelperMetadata/GenerateDropButtons", `Parameters: drop=${drop.card.id}, claimId=${claimId}, userId=${userId}`); + + return new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId(`claim ${drop.card.id} ${claimId} ${userId}`) + .setLabel(`Claim (${CardConstants.ClaimCost} 🪙)`) + .setStyle(ButtonStyle.Primary) + .setDisabled(disabled), + new ButtonBuilder() + .setCustomId("reroll") + .setLabel("Reroll") + .setStyle(ButtonStyle.Secondary)); + } +} \ No newline at end of file diff --git a/src/helpers/DropHelpers/GetCardsHelper.ts b/src/helpers/DropHelpers/GetCardsHelper.ts new file mode 100644 index 0000000..8bc4fe7 --- /dev/null +++ b/src/helpers/DropHelpers/GetCardsHelper.ts @@ -0,0 +1,91 @@ +import AppLogger from "../../client/appLogger"; +import { CoreClient } from "../../client/client"; +import CardConstants from "../../constants/CardConstants"; +import { CardRarity } from "../../constants/CardRarity"; +import CardRarityChances from "../../constants/CardRarityChances"; +import { DropResult } from "../../contracts/SeriesMetadata"; +import EffectHelper from "../EffectHelper"; +import GetUnclaimedCardsHelper from "./GetUnclaimedCardsHelper"; + +export default class GetCardsHelper { + public static async FetchCard(userId: string): Promise { + const hasChanceUpEffect = await EffectHelper.HasEffect(userId, "unclaimed"); + + if (hasChanceUpEffect && Math.random() <= CardConstants.UnusedChanceUpChance) { + return await GetUnclaimedCardsHelper.GetRandomCardUnclaimed(userId); + } + + return this.GetRandomCard(); + } + + public static GetRandomCard(): DropResult | undefined { + const randomRarity = Math.random() * 100; + + let cardRarity: CardRarity; + + const bronzeChance = CardRarityChances.Bronze; + const silverChance = bronzeChance + CardRarityChances.Silver; + const goldChance = silverChance + CardRarityChances.Gold; + const mangaChance = goldChance + CardRarityChances.Manga; + + if (randomRarity < bronzeChance) cardRarity = CardRarity.Bronze; + else if (randomRarity < silverChance) cardRarity = CardRarity.Silver; + else if (randomRarity < goldChance) cardRarity = CardRarity.Gold; + else if (randomRarity < mangaChance) cardRarity = CardRarity.Manga; + else cardRarity = CardRarity.Legendary; + + const randomCard = this.GetRandomCardByRarity(cardRarity); + + AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCard", `Random card: ${randomCard?.card.id} ${randomCard?.card.name}`); + + return randomCard; + } + + public static GetRandomCardByRarity(rarity: CardRarity): DropResult | undefined { + AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarity", `Parameters: rarity=${rarity}`); + + const allCards = CoreClient.Cards + .flatMap(x => x.cards) + .filter(x => x.type == rarity); + + const randomCardIndex = Math.floor(Math.random() * allCards.length); + + const card = allCards[randomCardIndex]; + const series = CoreClient.Cards + .find(x => x.cards.includes(card)); + + if (!series) { + AppLogger.LogWarn("CardDropHelperMetadata/GetRandomCardByRarity", `Series not found for card ${card.id}`); + + return undefined; + } + + AppLogger.LogSilly("CardDropHelperMetadata/GetRandomCardByRarity", `Random card: ${card.id} ${card.name}`); + + return { + series: series, + card: card, + }; + } + + public static GetCardByCardNumber(cardNumber: string): DropResult | undefined { + AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Parameters: cardNumber=${cardNumber}`); + + const card = CoreClient.Cards + .flatMap(x => x.cards) + .find(x => x.id == cardNumber); + + const series = CoreClient.Cards + .find(x => x.cards.find(y => y.id == card?.id)); + + AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Card: ${card?.id} ${card?.name}`); + AppLogger.LogSilly("CardDropHelperMetadata/GetCardByCardNumber", `Series: ${series?.id} ${series?.name}`); + + if (!card || !series) { + AppLogger.LogVerbose("CardDropHelperMetadata/GetCardByCardNumber", `Unable to find card metadata: ${cardNumber}`); + return undefined; + } + + return { card, series }; + } +} diff --git a/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts b/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts new file mode 100644 index 0000000..87fafea --- /dev/null +++ b/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts @@ -0,0 +1,63 @@ +import AppLogger from "../../client/appLogger"; +import { CoreClient } from "../../client/client"; +import { CardRarity } from "../../constants/CardRarity"; +import CardRarityChances from "../../constants/CardRarityChances"; +import { DropResult } from "../../contracts/SeriesMetadata"; +import Inventory from "../../database/entities/app/Inventory"; +import GetCardsHelper from "./GetCardsHelper"; + +export default class GetUnclaimedCardsHelper { + public static async GetRandomCardUnclaimed(userId: string): Promise { + const randomRarity = Math.random() * 100; + + let cardRarity: CardRarity; + + const bronzeChance = CardRarityChances.Bronze; + const silverChance = bronzeChance + CardRarityChances.Silver; + const goldChance = silverChance + CardRarityChances.Gold; + const mangaChance = goldChance + CardRarityChances.Manga; + + if (randomRarity < bronzeChance) cardRarity = CardRarity.Bronze; + else if (randomRarity < silverChance) cardRarity = CardRarity.Silver; + else if (randomRarity < goldChance) cardRarity = CardRarity.Gold; + else if (randomRarity < mangaChance) cardRarity = CardRarity.Manga; + else cardRarity = CardRarity.Legendary; + + const randomCard = await this.GetRandomCardByRarityUnclaimed(cardRarity, userId); + + return randomCard; + } + + public static async GetRandomCardByRarityUnclaimed(rarity: CardRarity, userId: string): Promise { + const claimedCards = await Inventory.FetchAllByUserId(userId); + + if (!claimedCards) { + // They don't have any cards, so safe to get any random card + return GetCardsHelper.GetRandomCardByRarity(rarity); + } + + const allCards = CoreClient.Cards + .flatMap(x => x.cards) + .filter(x => x.type == rarity) + .filter(x => !claimedCards.find(y => y.CardNumber == x.id)); + + if (!allCards) return undefined; + + const randomCardIndex = Math.floor(Math.random() * allCards.length); + + const card = allCards[randomCardIndex]; + const series = CoreClient.Cards + .find(x => x.cards.includes(card)); + + if (!series) { + AppLogger.LogWarn("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `Series not found for card ${card.id}`); + + return undefined; + } + + return { + series: series, + card: card, + }; + } +} diff --git a/src/helpers/DropHelpers/MultidropEmbedHelper.ts b/src/helpers/DropHelpers/MultidropEmbedHelper.ts new file mode 100644 index 0000000..526993e --- /dev/null +++ b/src/helpers/DropHelpers/MultidropEmbedHelper.ts @@ -0,0 +1,28 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; +import { DropResult } from "../../contracts/SeriesMetadata"; +import { GetSacrificeAmount } from "../../constants/CardRarity"; +import DropEmbedHelper from "./DropEmbedHelper"; + +export default class MultidropEmbedHelper { + public static GenerateMultidropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, cardsRemaining: number, claimedBy?: string, currency?: number): EmbedBuilder { + const dropEmbed = DropEmbedHelper.GenerateDropEmbed(drop, quantityClaimed, imageFileName, claimedBy, currency); + + dropEmbed.setFooter({ text: `${dropEmbed.data.footer?.text} · ${cardsRemaining} Remaining`}); + + return dropEmbed; + } + + public static GenerateMultidropButtons(drop: DropResult, cardsRemaining: number, userId: string, disabled = false): ActionRowBuilder { + return new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId(`multidrop keep ${drop.card.id} ${cardsRemaining} ${userId}`) + .setLabel("Keep") + .setStyle(ButtonStyle.Primary) + .setDisabled(disabled), + new ButtonBuilder() + .setCustomId(`multidrop sacrifice ${drop.card.id} ${cardsRemaining} ${userId}`) + .setLabel(`Sacrifice (+${GetSacrificeAmount(drop.card.type)} 🪙)`) + .setStyle(ButtonStyle.Secondary)); + } +} diff --git a/src/helpers/EffectHelper.ts b/src/helpers/EffectHelper.ts index d0d29a0..d4673f4 100644 --- a/src/helpers/EffectHelper.ts +++ b/src/helpers/EffectHelper.ts @@ -1,6 +1,7 @@ -import {ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder} from "discord.js"; +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; import UserEffect from "../database/entities/app/UserEffect"; import EmbedColours from "../constants/EmbedColours"; +import { EffectDetails } from "../constants/EffectDetails"; export default class EffectHelper { public static async AddEffectToUserInventory(userId: string, name: string, quantity: number = 1) { @@ -16,6 +17,20 @@ export default class EffectHelper { } public static async UseEffect(userId: string, name: string, whenExpires: Date): Promise { + const canUseEffect = await this.CanUseEffect(userId, name); + + if (!canUseEffect) return false; + + const effect = await UserEffect.FetchOneByUserIdAndName(userId, name); + + effect!.UseEffect(whenExpires); + + await effect!.Save(UserEffect, effect!); + + return true; + } + + public static async CanUseEffect(userId: string, name: string): Promise { const effect = await UserEffect.FetchOneByUserIdAndName(userId, name); const now = new Date(); @@ -23,13 +38,15 @@ export default class EffectHelper { return false; } - if (effect.WhenExpires && now < effect.WhenExpires) { + const effectDetail = EffectDetails.get(effect.Name); + + if (!effectDetail) { return false; } - effect.UseEffect(whenExpires); - - await effect.Save(UserEffect, effect); + if (effect.WhenExpires && now < new Date(effect.WhenExpires.getTime() + effectDetail.cooldown)) { + return false; + } return true; } diff --git a/src/helpers/TimeLengthInput.ts b/src/helpers/TimeLengthInput.ts index d1d8734..aef58ba 100644 --- a/src/helpers/TimeLengthInput.ts +++ b/src/helpers/TimeLengthInput.ts @@ -118,4 +118,19 @@ export default class TimeLengthInput { return desNumber; } + + public static ConvertFromMilliseconds(ms: number): TimeLengthInput { + const seconds = Math.floor(ms / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + + const remainingSeconds = seconds % 60; + const remainingMinutes = minutes % 60; + const remainingHours = hours % 24; + + const timeString = `${days}d ${remainingHours}h ${remainingMinutes}m ${remainingSeconds}s`; + + return new TimeLengthInput(timeString); + } } \ No newline at end of file diff --git a/tests/.gitkeep b/tests/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts b/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts new file mode 100644 index 0000000..a1024ee --- /dev/null +++ b/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts @@ -0,0 +1,21 @@ +import { ButtonInteraction } from "../../__types__/discord.js"; + +export default function GenerateButtonInteractionMock(): ButtonInteraction { + return { + guild: {}, + guildId: "guildId", + channel: { + isSendable: jest.fn().mockReturnValue(true), + send: jest.fn(), + }, + deferUpdate: jest.fn(), + editReply: jest.fn(), + message: { + createdAt: new Date(1000 * 60 * 27), + }, + user: { + id: "userId", + }, + customId: "customId", + }; +} \ No newline at end of file diff --git a/tests/__types__/discord.js.ts b/tests/__types__/discord.js.ts new file mode 100644 index 0000000..6506b1d --- /dev/null +++ b/tests/__types__/discord.js.ts @@ -0,0 +1,17 @@ +export type ButtonInteraction = { + guild: object | null, + guildId: string | null, + channel: { + isSendable: jest.Func, + send: jest.Func, + } | null, + deferUpdate: jest.Func, + editReply: jest.Func, + message: { + createdAt: Date, + } | null, + user: { + id: string, + } | null, + customId: string, +} \ No newline at end of file diff --git a/tests/buttonEvents/Claim.test.ts b/tests/buttonEvents/Claim.test.ts new file mode 100644 index 0000000..d9e7e6f --- /dev/null +++ b/tests/buttonEvents/Claim.test.ts @@ -0,0 +1,109 @@ +import { ButtonInteraction, TextChannel } from "discord.js"; +import Claim from "../../src/buttonEvents/Claim"; +import { ButtonInteraction as ButtonInteractionType } from "../__types__/discord.js"; +import User from "../../src/database/entities/app/User"; +import GenerateButtonInteractionMock from "../__functions__/discord.js/GenerateButtonInteractionMock"; + +jest.mock("../../src/client/appLogger"); + +let interaction: ButtonInteractionType; + +beforeEach(() => { + jest.useFakeTimers(); + jest.setSystemTime(1000 * 60 * 30); + + interaction = GenerateButtonInteractionMock(); + interaction.customId = "claim cardNumber claimId droppedBy userId"; +}); + +afterAll(() => { + jest.useRealTimers(); +}); + +test("GIVEN interaction.guild is null, EXPECT nothing to happen", async () => { + // Arrange + interaction.guild = null; + + // Act + const claim = new Claim(); + await claim.execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.deferUpdate).not.toHaveBeenCalled(); + expect(interaction.editReply).not.toHaveBeenCalled(); + expect((interaction.channel as TextChannel).send).not.toHaveBeenCalled(); +}); + +test("GIVEN interaction.guildId is null, EXPECT nothing to happen", async () => { + // Arrange + interaction.guildId = null; + + // Act + const claim = new Claim(); + await claim.execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.deferUpdate).not.toHaveBeenCalled(); + expect(interaction.editReply).not.toHaveBeenCalled(); + expect((interaction.channel as TextChannel).send).not.toHaveBeenCalled(); +}); + +test("GIVEN interaction.channel is null, EXPECT nothing to happen", async () => { + // Arrange + interaction.channel = null; + + // Act + const claim = new Claim(); + await claim.execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.deferUpdate).not.toHaveBeenCalled(); + expect(interaction.editReply).not.toHaveBeenCalled(); +}); + +test("GIVEN channel is not sendable, EXPECT nothing to happen", async () => { + // Arrange + interaction.channel!.isSendable = jest.fn().mockReturnValue(false); + + // Act + const claim = new Claim(); + await claim.execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.deferUpdate).not.toHaveBeenCalled(); + expect(interaction.editReply).not.toHaveBeenCalled(); + expect((interaction.channel as TextChannel).send).not.toHaveBeenCalled(); +}); + +test("GIVEN interaction.message was created more than 5 minutes ago, EXPECT error", async () => { + // Arrange + interaction.message!.createdAt = new Date(0); + + // Act + const claim = new Claim(); + await claim.execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.channel!.send).toHaveBeenCalledTimes(1); + expect(interaction.channel!.send).toHaveBeenCalledWith("[object Object], Cards can only be claimed within 5 minutes of it being dropped!"); + + expect(interaction.editReply).not.toHaveBeenCalled(); +}); + +test("GIVEN user.RemoveCurrency fails, EXPECT error", async () => { + // Arrange + User.FetchOneById = jest.fn().mockResolvedValue({ + RemoveCurrency: jest.fn().mockReturnValue(false), + Currency: 5, + }); + + // Act + const claim = new Claim(); + await claim.execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.channel!.send).toHaveBeenCalledTimes(1); + expect(interaction.channel!.send).toHaveBeenCalledWith("[object Object], Not enough currency! You need 10 currency, you have 5!"); + + expect(interaction.editReply).not.toHaveBeenCalled(); +}); \ No newline at end of file diff --git a/tests/buttonEvents/Effects.test.ts b/tests/buttonEvents/Effects.test.ts index 557e64a..f1f86be 100644 --- a/tests/buttonEvents/Effects.test.ts +++ b/tests/buttonEvents/Effects.test.ts @@ -1,127 +1,66 @@ -import {ButtonInteraction} from "discord.js"; +import { ButtonInteraction } from "discord.js"; import Effects from "../../src/buttonEvents/Effects"; -import EffectHelper from "../../src/helpers/EffectHelper"; +import GenerateButtonInteractionMock from "../__functions__/discord.js/GenerateButtonInteractionMock"; +import { ButtonInteraction as ButtonInteractionType } from "../__types__/discord.js"; +import List from "../../src/buttonEvents/Effects/List"; +import Use from "../../src/buttonEvents/Effects/Use"; +import AppLogger from "../../src/client/appLogger"; -describe("execute", () => { - describe("GIVEN action in custom id is list", () => { - const interaction = { - customId: "effects list", - } as unknown as ButtonInteraction; +jest.mock("../../src/client/appLogger"); +jest.mock("../../src/buttonEvents/Effects/List"); +jest.mock("../../src/buttonEvents/Effects/Use"); - let listSpy: jest.SpyInstance; +let interaction: ButtonInteractionType; - beforeAll(async () => { - const effects = new Effects(); +beforeEach(() => { + jest.resetAllMocks(); - listSpy = jest.spyOn(effects as unknown as {"List": () => object}, "List") - .mockImplementation(); - - await effects.execute(interaction); - }); - - test("EXPECT list function to be called", () => { - expect(listSpy).toHaveBeenCalledTimes(1); - expect(listSpy).toHaveBeenCalledWith(interaction); - }); - }); + interaction = GenerateButtonInteractionMock(); + interaction.customId = "effects"; }); -describe("List", () => { - let interaction: ButtonInteraction; +test("GIVEN action is list, EXPECT list function to be called", async () => { + // Arrange + interaction.customId = "effects list"; - const embed = { - name: "Embed", - }; + // Act + const effects = new Effects(); + await effects.execute(interaction as unknown as ButtonInteraction); - const row = { - name: "Row", - }; + // Assert + expect(List).toHaveBeenCalledTimes(1); + expect(List).toHaveBeenCalledWith(interaction); - beforeEach(() => { - interaction = { - customId: "effects list", - user: { - id: "userId", - }, - update: jest.fn(), - reply: jest.fn(), - } as unknown as ButtonInteraction; - }); - - describe("GIVEN page is a valid number", () => { - beforeEach(async () => { - interaction.customId += " 1"; - - EffectHelper.GenerateEffectEmbed = jest.fn() - .mockResolvedValue({ - embed, - row, - }); - - const effects = new Effects(); - - await effects.execute(interaction); - }); - - test("EXPECT EffectHelper.GenerateEffectEmbed to be called", () => { - expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledTimes(1); - expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledWith("userId", 1); - }); - - test("EXPECT interaction to be updated", () => { - expect(interaction.update).toHaveBeenCalledTimes(1); - expect(interaction.update).toHaveBeenCalledWith({ - embeds: [ embed ], - components: [ row ], - }); - }); - }); - - describe("GIVEN page in custom id is not supplied", () => { - beforeEach(async () => { - EffectHelper.GenerateEffectEmbed = jest.fn() - .mockResolvedValue({ - embed, - row, - }); - - const effects = new Effects(); - - await effects.execute(interaction); - }); - - test("EXPECT interaction to be replied with error", () => { - expect(interaction.reply).toHaveBeenCalledTimes(1); - expect(interaction.reply).toHaveBeenCalledWith("Page option is not a valid number"); - }); - - test("EXPECT interaction to not be updated", () => { - expect(interaction.update).not.toHaveBeenCalled(); - }); - }); - - describe("GIVEN page in custom id is not a number", () => { - beforeEach(async () => { - interaction.customId += " test"; - - EffectHelper.GenerateEffectEmbed = jest.fn() - .mockResolvedValue({ - embed, - row, - }); - - const effects = new Effects(); - - await effects.execute(interaction); - }); - - test("EXPECT interaction to be replied with error", () => { - expect(interaction.reply).toHaveBeenCalledTimes(1); - expect(interaction.reply).toHaveBeenCalledWith("Page option is not a valid number"); - }); - - test("EXPECT interaction to not be updated", () => { - expect(interaction.update).not.toHaveBeenCalled(); - }); - }); + expect(Use.Execute).not.toHaveBeenCalled(); }); + +test("GIVEN action is use, EXPECT use function to be called", async () => { + // Arrange + interaction.customId = "effects use"; + + // Act + const effects = new Effects(); + await effects.execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(Use.Execute).toHaveBeenCalledTimes(1); + expect(Use.Execute).toHaveBeenCalledWith(interaction); + + expect(List).not.toHaveBeenCalled(); +}); + +test("GIVEN action is invalid, EXPECT nothing to be called", async () => { + // Arrange + interaction.customId = "effects invalid"; + + // Act + const effects = new Effects(); + await effects.execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(List).not.toHaveBeenCalled(); + expect(Use.Execute).not.toHaveBeenCalled(); + + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buttons/Effects", "Unknown action, invalid"); +}); \ No newline at end of file diff --git a/tests/buttonEvents/Effects/List.test.ts b/tests/buttonEvents/Effects/List.test.ts new file mode 100644 index 0000000..52fa550 --- /dev/null +++ b/tests/buttonEvents/Effects/List.test.ts @@ -0,0 +1,50 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, EmbedBuilder } from "discord.js"; +import List from "../../../src/buttonEvents/Effects/List"; +import EffectHelper from "../../../src/helpers/EffectHelper"; +import { mock } from "jest-mock-extended"; + +jest.mock("../../../src/helpers/EffectHelper"); + +let interaction: ReturnType>; + +beforeEach(() => { + jest.resetAllMocks(); + + (EffectHelper.GenerateEffectEmbed as jest.Mock).mockResolvedValue({ + embed: mock(), + row: mock>(), + }); + + interaction = mock(); + interaction.user.id = "userId"; + interaction.customId = "effects list 1"; +}); + +test("GIVEN pageOption is NOT a number, EXPECT error", async () => { + // Arrange + interaction.customId = "effects list invalid"; + + // Act + await List(interaction); + + // Assert + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith("Page option is not a valid number") + + expect(EffectHelper.GenerateEffectEmbed).not.toHaveBeenCalled(); + expect(interaction.update).not.toHaveBeenCalled(); +}); + +test("GIVEN pageOption is a number, EXPECT interaction updated", async () => { + // Arrange + interaction.customId = "effects list 1"; + + // Act + await List(interaction); + + // Assert + expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledTimes(1); + expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledWith("userId", 1); + + expect(interaction.update).toHaveBeenCalledTimes(1); +}); \ No newline at end of file diff --git a/tests/buttonEvents/Effects/Use.test.ts b/tests/buttonEvents/Effects/Use.test.ts new file mode 100644 index 0000000..86391cc --- /dev/null +++ b/tests/buttonEvents/Effects/Use.test.ts @@ -0,0 +1,148 @@ +import { ButtonInteraction, InteractionResponse, InteractionUpdateOptions, MessagePayload } from "discord.js"; +import Use from "../../../src/buttonEvents/Effects/Use"; +import { mock } from "jest-mock-extended"; +import AppLogger from "../../../src/client/appLogger"; +import EffectHelper from "../../../src/helpers/EffectHelper"; + +jest.mock("../../../src/client/appLogger"); +jest.mock("../../../src/helpers/EffectHelper"); + +beforeEach(() => { + jest.resetAllMocks(); + + jest.useFakeTimers(); + jest.setSystemTime(0); +}); + +afterAll(() => { + jest.useRealTimers(); +}); + +describe("Execute", () => { + test("GIVEN subaction is unknown, EXPECT nothing to be called", async () => { + // Arrange + const interaction = mock(); + interaction.customId = "effects use invalud"; + + // Act + await Use.Execute(interaction); + + // Assert + expect(interaction.reply).not.toHaveBeenCalled(); + expect(interaction.update).not.toHaveBeenCalled(); + }); +}); + +describe("UseConfirm", () => { + let interaction = mock(); + + beforeEach(() => { + interaction = mock(); + interaction.customId = "effects use confirm"; + }); + + test("GIVEN effectDetail is not found, EXPECT error", async () => { + // Arrange + interaction.customId += " invalid"; + + // Act + await Use.Execute(interaction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Button/Effects/Use", "Effect not found, invalid"); + + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith("Effect not found in system!"); + }); + + test("GIVEN EffectHelper.UseEffect failed, EXPECT error", async () => { + // Arrange + interaction.customId += " unclaimed"; + interaction.user.id = "userId"; + + (EffectHelper.UseEffect as jest.Mock).mockResolvedValue(false); + + const whenExpires = new Date(Date.now() + 10 * 60 * 1000); + + // Act + await Use.Execute(interaction); + + // Assert + expect(EffectHelper.UseEffect).toHaveBeenCalledTimes(1); + expect(EffectHelper.UseEffect).toHaveBeenCalledWith("userId", "unclaimed", whenExpires); + + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith("Unable to use effect! Please make sure you have it in your inventory and is not on cooldown"); + }); + + test("GIVEN EffectHelper.UseEffect succeeded, EXPECT interaction updated", async () => { + let updatedWith; + + // Arrange + interaction.customId += " unclaimed"; + interaction.user.id = "userId"; + interaction.update.mockImplementation(async (opts: string | MessagePayload | InteractionUpdateOptions) => { + updatedWith = opts; + + return mock>(); + }); + + (EffectHelper.UseEffect as jest.Mock).mockResolvedValue(true); + + const whenExpires = new Date(Date.now() + 10 * 60 * 1000); + + // Act + await Use.Execute(interaction); + + // Assert + expect(EffectHelper.UseEffect).toHaveBeenCalledTimes(1); + expect(EffectHelper.UseEffect).toHaveBeenCalledWith("userId", "unclaimed", whenExpires); + + expect(interaction.update).toHaveBeenCalledTimes(1); + expect(updatedWith).toMatchSnapshot(); + }); +}); + +describe("UseCancel", () => { + let interaction = mock(); + + beforeEach(() => { + interaction = mock(); + interaction.customId = "effects use cancel"; + }); + + test("GIVEN effectDetail is not found, EXPECT error", async () => { + // Arrange + interaction.customId += " invalid"; + + // Act + await Use.Execute(interaction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Button/Effects/Cancel", "Effect not found, invalid"); + + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith("Effect not found in system!"); + }); + + test("GIVEN effectDetail is found, EXPECT interaction updated", async () => { + let updatedWith; + + // Arrange + interaction.customId += " unclaimed"; + interaction.user.id = "userId"; + interaction.update.mockImplementation(async (opts: string | MessagePayload | InteractionUpdateOptions) => { + updatedWith = opts; + + return mock>(); + }); + // Act + await Use.Execute(interaction); + + // Assert + expect(interaction.update).toHaveBeenCalledTimes(1); + expect(updatedWith).toMatchSnapshot(); + }); +}); \ No newline at end of file diff --git a/tests/buttonEvents/Effects/__snapshots__/Use.test.ts.snap b/tests/buttonEvents/Effects/__snapshots__/Use.test.ts.snap new file mode 100644 index 0000000..6cec0f4 --- /dev/null +++ b/tests/buttonEvents/Effects/__snapshots__/Use.test.ts.snap @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`UseCancel GIVEN effectDetail is found, EXPECT interaction updated 1`] = ` +{ + "components": [ + { + "components": [ + { + "custom_id": "effects use confirm unclaimed", + "disabled": true, + "emoji": undefined, + "label": "Confirm", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects use cancel unclaimed", + "disabled": true, + "emoji": undefined, + "label": "Cancel", + "style": 4, + "type": 2, + }, + ], + "type": 1, + }, + ], + "embeds": [ + { + "color": 13882323, + "description": "The effect from your inventory has not been used", + "fields": [ + { + "inline": true, + "name": "Effect", + "value": "Unclaimed Chance Up", + }, + { + "inline": true, + "name": "Expires", + "value": "10m", + }, + ], + "title": "Effect Use Cancelled", + }, + ], +} +`; + +exports[`UseConfirm GIVEN EffectHelper.UseEffect succeeded, EXPECT interaction updated 1`] = ` +{ + "components": [ + { + "components": [ + { + "custom_id": "effects use confirm unclaimed", + "disabled": true, + "emoji": undefined, + "label": "Confirm", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects use cancel unclaimed", + "disabled": true, + "emoji": undefined, + "label": "Cancel", + "style": 4, + "type": 2, + }, + ], + "type": 1, + }, + ], + "embeds": [ + { + "color": 2263842, + "description": "You now have an active effect!", + "fields": [ + { + "inline": true, + "name": "Effect", + "value": "Unclaimed Chance Up", + }, + { + "inline": true, + "name": "Expires", + "value": "", + }, + ], + "title": "Effect Used", + }, + ], +} +`; diff --git a/tests/commands/__snapshots__/effects.test.ts.snap b/tests/commands/__snapshots__/effects.test.ts.snap deleted file mode 100644 index ede2091..0000000 --- a/tests/commands/__snapshots__/effects.test.ts.snap +++ /dev/null @@ -1,40 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`constructor EXPECT CommandBuilder to be defined 1`] = ` -{ - "contexts": undefined, - "default_member_permissions": undefined, - "default_permission": undefined, - "description": "Effects", - "description_localizations": undefined, - "dm_permission": undefined, - "integration_types": undefined, - "name": "effects", - "name_localizations": undefined, - "nsfw": undefined, - "options": [ - { - "description": "List all effects I have", - "description_localizations": undefined, - "name": "list", - "name_localizations": undefined, - "options": [ - { - "autocomplete": undefined, - "choices": undefined, - "description": "The page number", - "description_localizations": undefined, - "max_value": undefined, - "min_value": 1, - "name": "page", - "name_localizations": undefined, - "required": false, - "type": 10, - }, - ], - "type": 1, - }, - ], - "type": 1, -} -`; diff --git a/tests/commands/effects.test.ts b/tests/commands/effects.test.ts deleted file mode 100644 index 8985477..0000000 --- a/tests/commands/effects.test.ts +++ /dev/null @@ -1,164 +0,0 @@ -import {ChatInputCommandInteraction} from "discord.js"; -import Effects from "../../src/commands/effects"; -import EffectHelper from "../../src/helpers/EffectHelper"; - -describe("constructor", () => { - let effects: Effects; - - beforeEach(() => { - effects = new Effects(); - }); - - test("EXPECT CommandBuilder to be defined", () => { - expect(effects.CommandBuilder).toMatchSnapshot(); - }); -}); - -describe("execute", () => { - describe("GIVEN interaction is not a chat input command", () => { - let interaction: ChatInputCommandInteraction; - - let listSpy: jest.SpyInstance; - - beforeEach(async () => { - interaction = { - isChatInputCommand: jest.fn().mockReturnValue(false), - } as unknown as ChatInputCommandInteraction; - - const effects = new Effects(); - - listSpy = jest.spyOn(effects as unknown as {"List": () => object}, "List") - .mockImplementation(); - - await effects.execute(interaction); - }); - - test("EXPECT isChatInputCommand to have been called", () => { - expect(interaction.isChatInputCommand).toHaveBeenCalledTimes(1); - }); - - test("EXPECT nothing to happen", () => { - expect(listSpy).not.toHaveBeenCalled(); - }); - }); - - describe("GIVEN subcommand is list", () => { - let interaction: ChatInputCommandInteraction; - - let listSpy: jest.SpyInstance; - - beforeEach(async () => { - interaction = { - isChatInputCommand: jest.fn().mockReturnValue(true), - options: { - getSubcommand: jest.fn().mockReturnValue("list"), - }, - } as unknown as ChatInputCommandInteraction; - - const effects = new Effects(); - - listSpy = jest.spyOn(effects as unknown as {"List": () => object}, "List") - .mockImplementation(); - - await effects.execute(interaction); - }); - - test("EXPECT subcommand function to be called", () => { - expect(interaction.options.getSubcommand).toHaveBeenCalledTimes(1); - }); - - test("EXPECT list function to be called", () => { - expect(listSpy).toHaveBeenCalledTimes(1); - expect(listSpy).toHaveBeenCalledWith(interaction); - }); - }); -}); - -describe("List", () => { - const effects: Effects = new Effects(); - let interaction: ChatInputCommandInteraction; - - const embed = { - name: "embed", - }; - - const row = { - name: "row", - }; - - beforeEach(async () => { - interaction = { - isChatInputCommand: jest.fn().mockReturnValue(true), - options: { - getSubcommand: jest.fn().mockReturnValue("list"), - }, - reply: jest.fn(), - user: { - id: "userId", - }, - } as unknown as ChatInputCommandInteraction; - - const effects = new Effects(); - - EffectHelper.GenerateEffectEmbed = jest.fn().mockReturnValue({ - embed, - row, - }); - - jest.spyOn(effects as unknown as {"List": () => object}, "List") - .mockImplementation(); - }); - - describe("GIVEN page option is supplied", () => { - describe("AND page is a valid number", () => { - beforeEach(async () => { - interaction.options.get = jest.fn().mockReturnValueOnce({ - value: "2", - }); - - await effects.execute(interaction); - }); - - test("EXPECT EffectHelper.GenerateEffectEmbed to have been called with page", () => { - expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledTimes(1); - expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledWith("userId", 2); - }); - - test("EXPECT interaction to have been replied", () => { - expect(interaction.reply).toHaveBeenCalledTimes(1); - expect(interaction.reply).toHaveBeenCalledWith({ - embeds: [ embed ], - components: [ row ], - }); - }); - }); - - describe("AND page is not a valid number", () => { - beforeEach(async () => { - interaction.options.get = jest.fn().mockReturnValueOnce({ - value: "test", - }); - - await effects.execute(interaction); - }); - - test("EXPECT EffectHelper.GenerateEffectEmbed to have been called with page of 1", () => { - expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledTimes(1); - expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledWith("userId", 1); - }); - }); - }); - - describe("GIVEN page option is not supplied", () => { - beforeEach(async () => { - interaction.options.get = jest.fn().mockReturnValueOnce(undefined); - - await effects.execute(interaction); - }); - - test("EXPECT EffectHelper.GenerateEffectEmbed to have been called with page of 1", () => { - expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledTimes(1); - expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledWith("userId", 1); - }); - }); -}); diff --git a/tests/database/entities/app/UserEffect.test.ts b/tests/database/entities/app/UserEffect.test.ts deleted file mode 100644 index 66992ec..0000000 --- a/tests/database/entities/app/UserEffect.test.ts +++ /dev/null @@ -1,103 +0,0 @@ -import UserEffect from "../../../../src/database/entities/app/UserEffect"; - -let userEffect: UserEffect; -const now = new Date(); - -beforeEach(() => { - userEffect = new UserEffect("name", "userId", 1); -}); - -describe("AddUnused", () => { - beforeEach(() => { - userEffect.AddUnused(1); - }); - - test("EXPECT unused to be the amount more", () => { - expect(userEffect.Unused).toBe(2); - }); -}); - -describe("UseEffect", () => { - describe("GIVEN Unused is 0", () => { - let result: boolean; - - beforeEach(() => { - userEffect.Unused = 0; - - result = userEffect.UseEffect(now); - }); - - test("EXPECT false returned", () => { - expect(result).toBe(false); - }); - - test("EXPECT details not to be changed", () => { - expect(userEffect.Unused).toBe(0); - expect(userEffect.WhenExpires).toBeUndefined(); - }); - }); - - describe("GIVEN Unused is greater than 0", () => { - let result: boolean; - - beforeEach(() => { - result = userEffect.UseEffect(now); - }); - - test("EXPECT true returned", () => { - expect(result).toBe(true); - }); - - test("EXPECT Unused to be subtracted by 1", () => { - expect(userEffect.Unused).toBe(0); - }); - - test("EXPECT WhenExpires to be set", () => { - expect(userEffect.WhenExpires).toBe(now); - }); - }); -}); - -describe("IsEffectActive", () => { - describe("GIVEN WhenExpires is null", () => { - let result: boolean; - - beforeEach(() => { - result = userEffect.IsEffectActive(); - }); - - test("EXPECT false returned", () => { - expect(result).toBe(false); - }); - }); - - describe("GIVEN WhenExpires is defined", () => { - describe("AND WhenExpires is in the past", () => { - let result: boolean; - - beforeEach(() => { - userEffect.WhenExpires = new Date(now.getTime() - 100); - - result = userEffect.IsEffectActive(); - }); - - test("EXPECT false returned", () => { - expect(result).toBe(false); - }); - }); - - describe("AND WhenExpires is in the future", () => { - let result: boolean; - - beforeEach(() => { - userEffect.WhenExpires = new Date(now.getTime() + 100); - - result = userEffect.IsEffectActive(); - }); - - test("EXPECT true returned", () => { - expect(result).toBe(true); - }); - }); - }); -}); diff --git a/tests/helpers/DropHelpers/GetCardsHelper.test.ts b/tests/helpers/DropHelpers/GetCardsHelper.test.ts new file mode 100644 index 0000000..421d4ef --- /dev/null +++ b/tests/helpers/DropHelpers/GetCardsHelper.test.ts @@ -0,0 +1,68 @@ +import GetCardsHelper from "../../../src/helpers/DropHelpers/GetCardsHelper"; +import EffectHelper from "../../../src/helpers/EffectHelper"; +import GetUnclaimedCardsHelper from "../../../src/helpers/DropHelpers/GetUnclaimedCardsHelper"; +import CardConstants from "../../../src/constants/CardConstants"; + +jest.mock("../../../src/helpers/EffectHelper"); +jest.mock("../../../src/helpers/DropHelpers/GetUnclaimedCardsHelper"); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe("FetchCard", () => { + test("GIVEN user has the unclaimed effect AND unused chance is within constraint, EXPECT unclaimed card returned", async () => { + // Arrange + (EffectHelper.HasEffect as jest.Mock).mockResolvedValue(true); + GetCardsHelper.GetRandomCard = jest.fn(); + Math.random = jest.fn().mockReturnValue(CardConstants.UnusedChanceUpChance - 0.1); + + // Act + await GetCardsHelper.FetchCard("userId"); + + // Assert + expect(EffectHelper.HasEffect).toHaveBeenCalledTimes(1); + expect(EffectHelper.HasEffect).toHaveBeenCalledWith("userId", "unclaimed"); + + expect(GetUnclaimedCardsHelper.GetRandomCardUnclaimed).toHaveBeenCalledTimes(1); + expect(GetUnclaimedCardsHelper.GetRandomCardUnclaimed).toHaveBeenCalledWith("userId"); + + expect(GetCardsHelper.GetRandomCard).not.toHaveBeenCalled(); + }); + + test("GIVEN user has unclaimed effect AND unused chance is NOT within constraint, EXPECT random card returned", async () => { + // Arrange + (EffectHelper.HasEffect as jest.Mock).mockResolvedValue(true); + GetCardsHelper.GetRandomCard = jest.fn(); + Math.random = jest.fn().mockReturnValue(CardConstants.UnusedChanceUpChance + 0.1); + + // Act + await GetCardsHelper.FetchCard("userId"); + + // Assert + expect(EffectHelper.HasEffect).toHaveBeenCalledTimes(1); + expect(EffectHelper.HasEffect).toHaveBeenCalledWith("userId", "unclaimed"); + + expect(GetCardsHelper.GetRandomCard).toHaveBeenCalledTimes(1); + + expect(GetUnclaimedCardsHelper.GetRandomCardUnclaimed).not.toHaveBeenCalled(); + }); + + test("GIVEN user does NOT have unclaimed effect, EXPECT random card returned", async () => { + // Arrange + (EffectHelper.HasEffect as jest.Mock).mockResolvedValue(false); + GetCardsHelper.GetRandomCard = jest.fn(); + Math.random = jest.fn().mockReturnValue(CardConstants.UnusedChanceUpChance + 0.1); + + // Act + await GetCardsHelper.FetchCard("userId"); + + // Assert + expect(EffectHelper.HasEffect).toHaveBeenCalledTimes(1); + expect(EffectHelper.HasEffect).toHaveBeenCalledWith("userId", "unclaimed"); + + expect(GetCardsHelper.GetRandomCard).toHaveBeenCalledTimes(1); + + expect(GetUnclaimedCardsHelper.GetRandomCardUnclaimed).not.toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts b/tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts new file mode 100644 index 0000000..04f76fc --- /dev/null +++ b/tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts @@ -0,0 +1,19 @@ +describe("GetRandomCardUnclaimed", () => { + test.todo("GIVEN chance is within bronze chance, EXPECT bronze card returned"); + + test.todo("GIVEN chance is within silver chance, EXPECT silver card"); + + test.todo("GIVEN chance is within gold chance, EXPECT gold card returned"); + + test.todo("GIVEN chance is within manga chance, EXPECT manga card returned"); +}); + +describe("GetRandomCardByRarityUnclaimed", () => { + test.todo("GIVEN user has no claimed cards, EXPECT random card returned"); + + test.todo("GIVEN no cards are found in memory, EXPECT undefined returned"); + + test.todo("GIVEN no series metadata is found for random card, EXPECT undefined returned"); + + test.todo("GIVEN user has claimed cards, EXPECT random card to NOT be this card"); +}); \ No newline at end of file diff --git a/tests/helpers/EffectHelper.test.ts b/tests/helpers/EffectHelper.test.ts deleted file mode 100644 index 13dca37..0000000 --- a/tests/helpers/EffectHelper.test.ts +++ /dev/null @@ -1,380 +0,0 @@ -import {ActionRowBuilder, ButtonBuilder, EmbedBuilder} from "discord.js"; -import UserEffect from "../../src/database/entities/app/UserEffect"; -import EffectHelper from "../../src/helpers/EffectHelper"; - -describe("AddEffectToUserInventory", () => { - describe("GIVEN effect is in database", () => { - const effectMock = { - AddUnused: jest.fn(), - Save: jest.fn(), - }; - - beforeAll(async () => { - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(effectMock); - - await EffectHelper.AddEffectToUserInventory("userId", "name", 1); - }); - - test("EXPECT database to be fetched", () => { - expect(UserEffect.FetchOneByUserIdAndName).toHaveBeenCalledTimes(1); - expect(UserEffect.FetchOneByUserIdAndName).toHaveBeenCalledWith("userId", "name"); - }); - - test("EXPECT effect to be updated", () => { - expect(effectMock.AddUnused).toHaveBeenCalledTimes(1); - expect(effectMock.AddUnused).toHaveBeenCalledWith(1); - }); - - test("EXPECT effect to be saved", () => { - expect(effectMock.Save).toHaveBeenCalledTimes(1); - expect(effectMock.Save).toHaveBeenCalledWith(UserEffect, effectMock); - }); - }); - - describe("GIVEN effect is not in database", () => { - beforeAll(async () => { - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(null); - UserEffect.prototype.Save = jest.fn(); - - await EffectHelper.AddEffectToUserInventory("userId", "name", 1); - }); - - test("EXPECT effect to be saved", () => { - expect(UserEffect.prototype.Save).toHaveBeenCalledTimes(1); - expect(UserEffect.prototype.Save).toHaveBeenCalledWith(UserEffect, expect.any(UserEffect)); - }); - }); -}); - -describe("UseEffect", () => { - describe("GIVEN effect is in database", () => { - describe("GIVEN now is before effect.WhenExpires", () => { - let result: boolean | undefined; - - // nowMock < whenExpires - const nowMock = new Date(2024, 11, 3, 13, 30); - const whenExpires = new Date(2024, 11, 3, 14, 0); - - const userEffect = { - Unused: 1, - WhenExpires: whenExpires, - }; - - beforeAll(async () => { - jest.setSystemTime(nowMock); - - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); - - result = await EffectHelper.UseEffect("userId", "name", new Date()); - }); - - test("EXPECT false returned", () => { - expect(result).toBe(false); - }); - }); - - describe("GIVEN currently used effect is inactive", () => { - let result: boolean | undefined; - - // nowMock > whenExpires - const nowMock = new Date(2024, 11, 3, 13, 30); - const whenExpires = new Date(2024, 11, 3, 13, 0); - const whenExpiresNew = new Date(2024, 11, 3, 15, 0); - - const userEffect = { - Unused: 1, - WhenExpires: whenExpires, - UseEffect: jest.fn(), - Save: jest.fn(), - }; - - beforeAll(async () => { - jest.setSystemTime(nowMock); - - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); - - result = await EffectHelper.UseEffect("userId", "name", whenExpiresNew); - }); - - test("EXPECT UseEffect to be called", () => { - expect(userEffect.UseEffect).toHaveReturnedTimes(1); - expect(userEffect.UseEffect).toHaveBeenCalledWith(whenExpiresNew); - }); - - test("EXPECT effect to be saved", () => { - expect(userEffect.Save).toHaveBeenCalledTimes(1); - expect(userEffect.Save).toHaveBeenCalledWith(UserEffect, userEffect); - }); - - test("EXPECT true returned", () => { - expect(result).toBe(true); - }); - }); - - describe("GIVEN effect.WhenExpires is null", () => { - let result: boolean | undefined; - - // nowMock > whenExpires - const nowMock = new Date(2024, 11, 3, 13, 30); - const whenExpiresNew = new Date(2024, 11, 3, 15, 0); - - const userEffect = { - Unused: 1, - WhenExpires: null, - UseEffect: jest.fn(), - Save: jest.fn(), - }; - - beforeAll(async () => { - jest.setSystemTime(nowMock); - - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); - - result = await EffectHelper.UseEffect("userId", "name", whenExpiresNew); - }); - - test("EXPECT UseEffect to be called", () => { - expect(userEffect.UseEffect).toHaveBeenCalledTimes(1); - expect(userEffect.UseEffect).toHaveBeenCalledWith(whenExpiresNew); - }); - - test("EXPECT effect to be saved", () => { - expect(userEffect.Save).toHaveBeenCalledTimes(1); - expect(userEffect.Save).toHaveBeenCalledWith(UserEffect, userEffect); - }); - - test("EXPECT true returned", () => { - expect(result).toBe(true); - }); - }); - }); - - describe("GIVEN effect is not in database", () => { - let result: boolean | undefined; - - // nowMock > whenExpires - const nowMock = new Date(2024, 11, 3, 13, 30); - const whenExpiresNew = new Date(2024, 11, 3, 15, 0); - - beforeAll(async () => { - jest.setSystemTime(nowMock); - - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(null); - - result = await EffectHelper.UseEffect("userId", "name", whenExpiresNew); - }); - - test("EXPECT false returned", () => { - expect(result).toBe(false); - }); - }); - - describe("GIVEN effect.Unused is 0", () => { - let result: boolean | undefined; - - // nowMock > whenExpires - const nowMock = new Date(2024, 11, 3, 13, 30); - const whenExpiresNew = new Date(2024, 11, 3, 15, 0); - - const userEffect = { - Unused: 0, - WhenExpires: null, - UseEffect: jest.fn(), - Save: jest.fn(), - }; - - beforeAll(async () => { - jest.setSystemTime(nowMock); - - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); - - result = await EffectHelper.UseEffect("userId", "name", whenExpiresNew); - }); - - test("EXPECT false returned", () => { - expect(result).toBe(false); - }); - }); -}); - -describe("HasEffect", () => { - describe("GIVEN effect is in database", () => { - describe("GIVEN effect.WhenExpires is defined", () => { - describe("GIVEN now is before effect.WhenExpires", () => { - let result: boolean | undefined; - - const nowMock = new Date(2024, 11, 3, 13, 30); - const whenExpires = new Date(2024, 11, 3, 15, 0); - - const userEffect = { - WhenExpires: whenExpires, - }; - - beforeAll(async () => { - jest.setSystemTime(nowMock); - - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); - - result = await EffectHelper.HasEffect("userId", "name"); - }); - - test("EXPECT true returned", () => { - expect(result).toBe(true); - }); - }); - - describe("GIVEN now is after effect.WhenExpires", () => { - let result: boolean | undefined; - - const nowMock = new Date(2024, 11, 3, 16, 30); - const whenExpires = new Date(2024, 11, 3, 15, 0); - - const userEffect = { - WhenExpires: whenExpires, - }; - - beforeAll(async () => { - jest.setSystemTime(nowMock); - - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); - - result = await EffectHelper.HasEffect("userId", "name"); - }); - - test("EXPECT false returned", () => { - expect(result).toBe(false); - }); - }); - }); - - describe("GIVEN effect.WhenExpires is undefined", () => { - let result: boolean | undefined; - - const userEffect = { - WhenExpires: undefined, - }; - - beforeAll(async () => { - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(userEffect); - - result = await EffectHelper.HasEffect("userId", "name"); - }); - - test("EXPECT false returned", () => { - expect(result).toBe(false); - }); - }); - }); - - describe("GIVEN effect is not in database", () => { - let result: boolean | undefined; - - beforeAll(async () => { - UserEffect.FetchOneByUserIdAndName = jest.fn().mockResolvedValue(null); - - result = await EffectHelper.HasEffect("userId", "name"); - }); - - test("EXPECT false returned", () => { - expect(result).toBe(false); - }); - }); -}); - -describe("GenerateEffectEmbed", () => { - beforeEach(async () => { - UserEffect.FetchAllByUserIdPaginated = jest.fn() - .mockResolvedValue([ - [], - 0, - ]); - - await EffectHelper.GenerateEffectEmbed("userId", 1); - }); - - test("EXPECT UserEffect.FetchAllByUserIdPaginated to be called", () => { - expect(UserEffect.FetchAllByUserIdPaginated).toHaveBeenCalledTimes(1); - expect(UserEffect.FetchAllByUserIdPaginated).toHaveBeenCalledWith("userId", 0, 10); - }); - - describe("GIVEN there are no effects returned", () => { - let result: { - embed: EmbedBuilder, - row: ActionRowBuilder, - }; - - beforeEach(async () => { - UserEffect.FetchAllByUserIdPaginated = jest.fn() - .mockResolvedValue([ - [], - 0, - ]); - - result = await EffectHelper.GenerateEffectEmbed("userId", 1); - }); - - test("EXPECT result returned", () => { - expect(result).toMatchSnapshot(); - }); - }); - - describe("GIVEN there are effects returned", () => { - let result: { - embed: EmbedBuilder, - row: ActionRowBuilder, - }; - - beforeEach(async () => { - UserEffect.FetchAllByUserIdPaginated = jest.fn() - .mockResolvedValue([ - [ - { - Name: "name", - Unused: 1, - }, - ], - 1, - ]); - - result = await EffectHelper.GenerateEffectEmbed("userId", 1); - }); - - test("EXPECT result returned", () => { - expect(result).toMatchSnapshot(); - }); - - describe("AND it is the first page", () => { - beforeEach(async () => { - result = await EffectHelper.GenerateEffectEmbed("userId", 1) - }); - - test("EXPECT Previous button to be disabled", () => { - const button = result.row.components[0].data as unknown as { - label: string, - disabled: boolean - }; - - expect(button).toBeDefined(); - expect(button.label).toBe("Previous"); - expect(button.disabled).toBe(true); - }); - }); - - describe("AND it is the last page", () => { - beforeEach(async () => { - result = await EffectHelper.GenerateEffectEmbed("userId", 1) - }); - - test("EXPECT Next button to be disabled", () => { - const button = result.row.components[1].data as unknown as { - label: string, - disabled: boolean - }; - - expect(button).toBeDefined(); - expect(button.label).toBe("Next"); - expect(button.disabled).toBe(true); - }); - }); - }); -}); diff --git a/tests/helpers/TimeLengthInput.test.ts b/tests/helpers/TimeLengthInput.test.ts new file mode 100644 index 0000000..6a23d67 --- /dev/null +++ b/tests/helpers/TimeLengthInput.test.ts @@ -0,0 +1,38 @@ +import TimeLengthInput from "../../src/helpers/TimeLengthInput"; + +describe("ConvertFromMilliseconds", () => { + test("EXPECT 1000ms to be outputted as a second", () => { + const timeLength = TimeLengthInput.ConvertFromMilliseconds(1000); + expect(timeLength.GetLengthShort()).toBe("1s"); + }); + + test("EXPECT 60000ms to be outputted as a minute", () => { + const timeLength = TimeLengthInput.ConvertFromMilliseconds(60000); + expect(timeLength.GetLengthShort()).toBe("1m"); + }); + + test("EXPECT 3600000ms to be outputted as an hour", () => { + const timeLength = TimeLengthInput.ConvertFromMilliseconds(3600000); + expect(timeLength.GetLengthShort()).toBe("1h"); + }); + + test("EXPECT 86400000ms to be outputted as a day", () => { + const timeLength = TimeLengthInput.ConvertFromMilliseconds(86400000); + expect(timeLength.GetLengthShort()).toBe("1d"); + }); + + test("EXPECT a combination to be outputted correctly", () => { + const timeLength = TimeLengthInput.ConvertFromMilliseconds(90061000); + expect(timeLength.GetLengthShort()).toBe("1d 1h 1m 1s"); + }); + + test("EXPECT 0ms to be outputted as empty", () => { + const timeLength = TimeLengthInput.ConvertFromMilliseconds(0); + expect(timeLength.GetLengthShort()).toBe(""); + }); + + test("EXPECT 123456789ms to be outputted correctly", () => { + const timeLength = TimeLengthInput.ConvertFromMilliseconds(123456789); + expect(timeLength.GetLengthShort()).toBe("1d 10h 17m 36s"); + }); +}); \ No newline at end of file diff --git a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap deleted file mode 100644 index 6484acd..0000000 --- a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap +++ /dev/null @@ -1,71 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`GenerateEffectEmbed GIVEN there are effects returned EXPECT result returned 1`] = ` -{ - "embed": { - "color": 3166394, - "description": "name x1", - "footer": { - "icon_url": undefined, - "text": "Page 1 of 1", - }, - "title": "Effects", - }, - "row": { - "components": [ - { - "custom_id": "effects list 0", - "disabled": true, - "emoji": undefined, - "label": "Previous", - "style": 1, - "type": 2, - }, - { - "custom_id": "effects list 2", - "disabled": true, - "emoji": undefined, - "label": "Next", - "style": 1, - "type": 2, - }, - ], - "type": 1, - }, -} -`; - -exports[`GenerateEffectEmbed GIVEN there are no effects returned EXPECT result returned 1`] = ` -{ - "embed": { - "color": 3166394, - "description": "*none*", - "footer": { - "icon_url": undefined, - "text": "Page 1 of 1", - }, - "title": "Effects", - }, - "row": { - "components": [ - { - "custom_id": "effects list 0", - "disabled": true, - "emoji": undefined, - "label": "Previous", - "style": 1, - "type": 2, - }, - { - "custom_id": "effects list 2", - "disabled": true, - "emoji": undefined, - "label": "Next", - "style": 1, - "type": 2, - }, - ], - "type": 1, - }, -} -`; From c6b458199c1fbc578f2b6e471af3b53ec278a63f Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Mon, 3 Feb 2025 18:24:27 +0000 Subject: [PATCH 48/59] Add friendly name and active effect to user effect list embed (#422) # Description Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. - Add friendly name to list embed - Add currently active effect to list #379 ## Type of change Please delete options that are not relevant. - [x] New feature (non-breaking change which adds functionality) # How Has This Been Tested? Please describe the tests that you ran to verify the changes. Provide instructions so we can reproduce. Please also list any relevant details to your test configuration. # Checklist - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that provde my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/422 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/database/entities/app/UserEffect.ts | 14 +- src/helpers/EffectHelper.ts | 18 +- .../GetUnclaimedCardsHelper.test.ts | 19 -- tests/helpers/EffectHelper.test.ts | 115 ++++++++++ .../__snapshots__/EffectHelper.test.ts.snap | 216 ++++++++++++++++++ 5 files changed, 361 insertions(+), 21 deletions(-) delete mode 100644 tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts create mode 100644 tests/helpers/EffectHelper.test.ts create mode 100644 tests/helpers/__snapshots__/EffectHelper.test.ts.snap diff --git a/src/database/entities/app/UserEffect.ts b/src/database/entities/app/UserEffect.ts index 72fae5f..447b9c5 100644 --- a/src/database/entities/app/UserEffect.ts +++ b/src/database/entities/app/UserEffect.ts @@ -63,7 +63,7 @@ export default class UserEffect extends AppBaseEntity { const query = await repository.createQueryBuilder("effect") .where("effect.UserId = :userId", { userId }) - .where("effect.Unused > 0") + .andWhere("effect.Unused > 0") .orderBy("effect.Name", "ASC") .skip(page * itemsPerPage) .take(itemsPerPage) @@ -71,4 +71,16 @@ export default class UserEffect extends AppBaseEntity { return query; } + + public static async FetchActiveEffectByUserId(userId: string): Promise { + const repository = AppDataSource.getRepository(UserEffect); + + const query = await repository.createQueryBuilder("effect") + .where("effect.UserId = :userId", { userId }) + .andWhere("effect.WhenExpires IS NOT NULL") + .andWhere("effect.WhenExpires > :now", { now: new Date() }) + .getOne(); + + return query; + } } diff --git a/src/helpers/EffectHelper.ts b/src/helpers/EffectHelper.ts index d4673f4..6c38cac 100644 --- a/src/helpers/EffectHelper.ts +++ b/src/helpers/EffectHelper.ts @@ -73,6 +73,7 @@ export default class EffectHelper { const itemsPerPage = 10; const query = await UserEffect.FetchAllByUserIdPaginated(userId, page - 1, itemsPerPage); + const activeEffect = await UserEffect.FetchActiveEffectByUserId(userId); const effects = query[0]; const count = query[1]; @@ -82,7 +83,7 @@ export default class EffectHelper { let description = "*none*"; if (effects.length > 0) { - description = effects.map(x => `${x.Name} x${x.Unused}`).join("\n"); + description = effects.map(x => `${EffectDetails.get(x.Name)?.friendlyName} x${x.Unused}`).join("\n"); } const embed = new EmbedBuilder() @@ -91,6 +92,21 @@ export default class EffectHelper { .setColor(EmbedColours.Ok) .setFooter({ text: `Page ${page} of ${totalPages}` }); + if (activeEffect) { + embed.addFields([ + { + name: "Active", + value: `${EffectDetails.get(activeEffect.Name)?.friendlyName}`, + inline: true, + }, + { + name: "Expires", + value: ``, + inline: true, + }, + ]); + } + const row = new ActionRowBuilder() .addComponents( new ButtonBuilder() diff --git a/tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts b/tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts deleted file mode 100644 index 04f76fc..0000000 --- a/tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -describe("GetRandomCardUnclaimed", () => { - test.todo("GIVEN chance is within bronze chance, EXPECT bronze card returned"); - - test.todo("GIVEN chance is within silver chance, EXPECT silver card"); - - test.todo("GIVEN chance is within gold chance, EXPECT gold card returned"); - - test.todo("GIVEN chance is within manga chance, EXPECT manga card returned"); -}); - -describe("GetRandomCardByRarityUnclaimed", () => { - test.todo("GIVEN user has no claimed cards, EXPECT random card returned"); - - test.todo("GIVEN no cards are found in memory, EXPECT undefined returned"); - - test.todo("GIVEN no series metadata is found for random card, EXPECT undefined returned"); - - test.todo("GIVEN user has claimed cards, EXPECT random card to NOT be this card"); -}); \ No newline at end of file diff --git a/tests/helpers/EffectHelper.test.ts b/tests/helpers/EffectHelper.test.ts new file mode 100644 index 0000000..b0dd12d --- /dev/null +++ b/tests/helpers/EffectHelper.test.ts @@ -0,0 +1,115 @@ +import EffectHelper from "../../src/helpers/EffectHelper"; +import UserEffect from "../../src/database/entities/app/UserEffect"; + +jest.mock("../../src/database/entities/app/UserEffect"); + +describe("GenerateEffectEmbed", () => { + test("GIVEN user has an effect, EXPECT detailed embed to be returned", async () => { + // Arrange + (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ + [ + { + Name: "unclaimed", + Unused: 1, + } + ], + 1, + ]); + + // Act + const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + + // Assert + expect(result).toMatchSnapshot(); + }); + + test("GIVEN user has more than 1 page of effects, EXPECT pagination enabled", async () => { + const effects: { + Name: string, + Unused: number, + }[] = []; + + for (let i = 0; i < 15; i++) { + effects.push({ + Name: "unclaimed", + Unused: 1, + }); + } + + // Arrange + (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ + effects, + 15, + ]); + + // Act + const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + + // Assert + expect(result).toMatchSnapshot(); + }); + + test("GIVEN user is on a page other than 1, EXPECT pagination enabled", async () => { + const effects: { + Name: string, + Unused: number, + }[] = []; + + for (let i = 0; i < 15; i++) { + effects.push({ + Name: "unclaimed", + Unused: 1, + }); + } + + // Arrange + (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ + effects, + 15, + ]); + + // Act + const result = await EffectHelper.GenerateEffectEmbed("userId", 2); + + // Assert + expect(result).toMatchSnapshot(); + }); + + test("GIVEN user does NOT have an effect, EXPECT empty embed to be returned", async () => { + // Arrange + (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ + [], + 0, + ]); + + // Act + const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + + // Assert + expect(result).toMatchSnapshot(); + }); + + test("GIVEN there is an active effect, EXPECT field added", async () => { + // Arrange + (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ + [ + { + Name: "unclaimed", + Unused: 1, + } + ], + 1, + ]); + + (UserEffect.FetchActiveEffectByUserId as jest.Mock).mockResolvedValue({ + Name: "unclaimed", + WhenExpires: new Date(1738174052), + }); + + // Act + const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + + // Assert + expect(result).toMatchSnapshot(); + }); +}); \ No newline at end of file diff --git a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap new file mode 100644 index 0000000..f6e5e8e --- /dev/null +++ b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap @@ -0,0 +1,216 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`GenerateEffectEmbed GIVEN there is an active effect, EXPECT field added 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "Unclaimed Chance Up x1", + "fields": [ + { + "inline": true, + "name": "Active", + "value": "Unclaimed Chance Up", + }, + { + "inline": true, + "name": "Expires", + "value": "", + }, + ], + "footer": { + "icon_url": undefined, + "text": "Page 1 of 1", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 0", + "disabled": true, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 2", + "disabled": true, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; + +exports[`GenerateEffectEmbed GIVEN user does NOT have an effect, EXPECT empty embed to be returned 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "*none*", + "footer": { + "icon_url": undefined, + "text": "Page 1 of 1", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 0", + "disabled": true, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 2", + "disabled": true, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; + +exports[`GenerateEffectEmbed GIVEN user has an effect, EXPECT detailed embed to be returned 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "Unclaimed Chance Up x1", + "footer": { + "icon_url": undefined, + "text": "Page 1 of 1", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 0", + "disabled": true, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 2", + "disabled": true, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; + +exports[`GenerateEffectEmbed GIVEN user has more than 1 page of effects, EXPECT pagination enabled 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1", + "footer": { + "icon_url": undefined, + "text": "Page 1 of 2", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 0", + "disabled": true, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 2", + "disabled": false, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; + +exports[`GenerateEffectEmbed GIVEN user is on a page other than 1, EXPECT pagination enabled 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1", + "footer": { + "icon_url": undefined, + "text": "Page 2 of 2", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 1", + "disabled": false, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 3", + "disabled": true, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; From 5089ad6ab69a2f1e949368efe1d8f2c682055ae3 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Wed, 26 Mar 2025 18:30:16 +0000 Subject: [PATCH 49/59] Command to allow the user to buy more effects (#424) # Description - Create a command to generate an embed for the user to be able to buy more effects - This embed will contain the details about the effect as well as 2 buttons; Confirm and Cancel - The confirm button will call the button event to: - Remove the currency from the user - Give the user the effect to their inventory - The cancel button will just disable the buttons, so the user can't accidentally use it if they don't want to. #381 ## Type of change Please delete options that are not relevant. - [x] New feature (non-breaking change which adds functionality) # How Has This Been Tested? - Have created unit tests and tested locally # Checklist - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that provde my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/424 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/buttonEvents/Effects.ts | 4 + src/buttonEvents/Effects/Buy.ts | 120 ++++++ src/buttonEvents/Effects/List.ts | 2 +- src/commands/effects.ts | 104 ++---- src/commands/effects/Buy.ts | 22 ++ src/commands/effects/List.ts | 15 + src/commands/effects/Use.ts | 62 ++++ src/constants/EffectDetails.ts | 4 + src/helpers/EffectHelper.ts | 67 +++- .../GenerateButtonInteractionMock.ts | 2 + .../GenerateCommandInteractionMock.ts | 12 + tests/__types__/discord.js.ts | 9 + tests/buttonEvents/Effects.test.ts | 4 +- tests/buttonEvents/Effects/Buy.test.ts | 350 ++++++++++++++++++ tests/buttonEvents/Effects/List.test.ts | 8 +- .../__snapshots__/effects.test.ts.snap | 106 ++++++ tests/commands/effects.test.ts | 105 ++++++ tests/commands/effects/Buy.test.ts | 9 + tests/helpers/EffectHelper.test.ts | 24 +- .../__snapshots__/EffectHelper.test.ts.snap | 10 +- 20 files changed, 942 insertions(+), 97 deletions(-) create mode 100644 src/buttonEvents/Effects/Buy.ts create mode 100644 src/commands/effects/Buy.ts create mode 100644 src/commands/effects/List.ts create mode 100644 src/commands/effects/Use.ts create mode 100644 tests/__functions__/discord.js/GenerateCommandInteractionMock.ts create mode 100644 tests/buttonEvents/Effects/Buy.test.ts create mode 100644 tests/commands/__snapshots__/effects.test.ts.snap create mode 100644 tests/commands/effects.test.ts create mode 100644 tests/commands/effects/Buy.test.ts diff --git a/src/buttonEvents/Effects.ts b/src/buttonEvents/Effects.ts index 0f9686b..cd1a765 100644 --- a/src/buttonEvents/Effects.ts +++ b/src/buttonEvents/Effects.ts @@ -3,6 +3,7 @@ import { ButtonEvent } from "../type/buttonEvent"; import List from "./Effects/List"; import Use from "./Effects/Use"; import AppLogger from "../client/appLogger"; +import Buy from "./Effects/Buy"; export default class Effects extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -15,6 +16,9 @@ export default class Effects extends ButtonEvent { case "use": await Use.Execute(interaction); break; + case "buy": + await Buy.Execute(interaction); + break; default: AppLogger.LogError("Buttons/Effects", `Unknown action, ${action}`); } diff --git a/src/buttonEvents/Effects/Buy.ts b/src/buttonEvents/Effects/Buy.ts new file mode 100644 index 0000000..49cc75f --- /dev/null +++ b/src/buttonEvents/Effects/Buy.ts @@ -0,0 +1,120 @@ +import {ButtonInteraction} from "discord.js"; +import AppLogger from "../../client/appLogger"; +import EffectHelper from "../../helpers/EffectHelper"; +import EmbedColours from "../../constants/EmbedColours"; +import User from "../../database/entities/app/User"; +import {EffectDetails} from "../../constants/EffectDetails"; + +export default class Buy { + public static async Execute(interaction: ButtonInteraction) { + const subaction = interaction.customId.split(" ")[2]; + + switch (subaction) { + case "confirm": + await this.Confirm(interaction); + break; + case "cancel": + await this.Cancel(interaction); + break; + default: + AppLogger.LogError("Buy", `Unknown subaction, effects ${subaction}`); + } + } + + private static async Confirm(interaction: ButtonInteraction) { + const id = interaction.customId.split(" ")[3]; + const quantity = interaction.customId.split(" ")[4]; + + if (!id || !quantity) { + AppLogger.LogError("Buy Confirm", "Not enough parameters"); + return; + } + + const effectDetail = EffectDetails.get(id); + + if (!effectDetail) { + AppLogger.LogError("Buy Confirm", "Effect detail not found!"); + return; + } + + const quantityNumber = Number(quantity); + + if (!quantityNumber || quantityNumber < 1) { + AppLogger.LogError("Buy Confirm", "Invalid number"); + return; + } + + const totalCost = effectDetail.cost * quantityNumber; + + const user = await User.FetchOneById(User, interaction.user.id); + + if (!user) { + AppLogger.LogError("Buy Confirm", "Unable to find user"); + return; + } + + if (user.Currency < totalCost) { + interaction.reply(`You don't have enough currency to buy this! You have \`${user.Currency} Currency\` and need \`${totalCost} Currency\`!`); + return; + } + + user.RemoveCurrency(totalCost); + await user.Save(User, user); + + await EffectHelper.AddEffectToUserInventory(interaction.user.id, id, quantityNumber); + + const generatedEmbed = await EffectHelper.GenerateEffectBuyEmbed(interaction.user.id, id, quantityNumber, true); + + if (typeof generatedEmbed == "string") { + await interaction.reply(generatedEmbed); + return; + } + + generatedEmbed.embed.setColor(EmbedColours.Success); + generatedEmbed.embed.setFooter({ text: "Purchased" }); + + await interaction.update({ + embeds: [ generatedEmbed.embed ], + components: [ generatedEmbed.row ], + }); + } + + private static async Cancel(interaction: ButtonInteraction) { + const id = interaction.customId.split(" ")[3]; + const quantity = interaction.customId.split(" ")[4]; + + if (!id || !quantity) { + AppLogger.LogError("Buy Cancel", "Not enough parameters"); + return; + } + + const effectDetail = EffectDetails.get(id); + + if (!effectDetail) { + AppLogger.LogError("Buy Cancel", "Effect detail not found!"); + return; + } + + const quantityNumber = Number(quantity); + + if (!quantityNumber || quantityNumber < 1) { + AppLogger.LogError("Buy Cancel", "Invalid number"); + return; + } + + const generatedEmbed = await EffectHelper.GenerateEffectBuyEmbed(interaction.user.id, id, quantityNumber, true); + + if (typeof generatedEmbed == "string") { + await interaction.reply(generatedEmbed); + return; + } + + generatedEmbed.embed.setColor(EmbedColours.Error); + generatedEmbed.embed.setFooter({ text: "Cancelled" }); + + await interaction.update({ + embeds: [ generatedEmbed.embed ], + components: [ generatedEmbed.row ], + }); + } +} diff --git a/src/buttonEvents/Effects/List.ts b/src/buttonEvents/Effects/List.ts index 059623b..d86dfce 100644 --- a/src/buttonEvents/Effects/List.ts +++ b/src/buttonEvents/Effects/List.ts @@ -11,7 +11,7 @@ export default async function List(interaction: ButtonInteraction) { return; } - const result = await EffectHelper.GenerateEffectEmbed(interaction.user.id, page); + const result = await EffectHelper.GenerateEffectListEmbed(interaction.user.id, page); await interaction.update({ embeds: [ result.embed ], diff --git a/src/commands/effects.ts b/src/commands/effects.ts index 98727b9..cd6d1d4 100644 --- a/src/commands/effects.ts +++ b/src/commands/effects.ts @@ -1,10 +1,10 @@ -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; +import { CommandInteraction, SlashCommandBuilder } from "discord.js"; import { Command } from "../type/command"; -import EffectHelper from "../helpers/EffectHelper"; -import { EffectDetails } from "../constants/EffectDetails"; -import TimeLengthInput from "../helpers/TimeLengthInput"; -import EmbedColours from "../constants/EmbedColours"; +import { EffectChoices } from "../constants/EffectDetails"; import AppLogger from "../client/appLogger"; +import List from "./effects/List"; +import Use from "./effects/Use"; +import Buy from "./effects/Buy"; export default class Effects extends Command { constructor() { @@ -27,9 +27,19 @@ export default class Effects extends Command { .setName("id") .setDescription("The effect id to use") .setRequired(true) - .setChoices([ - { name: "Unclaimed Chance Up", value: "unclaimed" }, - ]))); + .setChoices(EffectChoices))) + .addSubcommand(x => x + .setName("buy") + .setDescription("Buy more effects") + .addStringOption(y => y + .setName("id") + .setDescription("The effect id to buy") + .setRequired(true) + .setChoices(EffectChoices)) + .addNumberOption(y => y + .setName("quantity") + .setDescription("The amount to buy") + .setMinValue(1))); } public override async execute(interaction: CommandInteraction) { @@ -39,80 +49,16 @@ export default class Effects extends Command { switch (subcommand) { case "list": - await this.List(interaction); + await List(interaction); break; case "use": - await this.Use(interaction); + await Use(interaction); break; + case "buy": + await Buy(interaction); + break; + default: + AppLogger.LogError("Commands/Effects", `Invalid subcommand: ${subcommand}`); } } - - private async List(interaction: CommandInteraction) { - const pageOption = interaction.options.get("page"); - - const page = !isNaN(Number(pageOption?.value)) ? Number(pageOption?.value) : 1; - - const result = await EffectHelper.GenerateEffectEmbed(interaction.user.id, page); - - await interaction.reply({ - embeds: [ result.embed ], - components: [ result.row ], - }); - } - - private async Use(interaction: CommandInteraction) { - const id = interaction.options.get("id", true).value!.toString(); - - const effectDetail = EffectDetails.get(id); - - if (!effectDetail) { - AppLogger.LogWarn("Commands/Effects", `Unable to find effect details for ${id}`); - - await interaction.reply("Unable to find effect!"); - return; - } - - const canUseEffect = await EffectHelper.CanUseEffect(interaction.user.id, id); - - if (!canUseEffect) { - await interaction.reply("Unable to use effect! Please make sure you have it in your inventory and is not on cooldown"); - return; - } - - const timeLengthInput = TimeLengthInput.ConvertFromMilliseconds(effectDetail.duration); - - const embed = new EmbedBuilder() - .setTitle("Effect Confirmation") - .setDescription("Would you like to use this effect?") - .setColor(EmbedColours.Ok) - .addFields([ - { - name: "Effect", - value: effectDetail.friendlyName, - inline: true, - }, - { - name: "Length", - value: timeLengthInput.GetLengthShort(), - inline: true, - }, - ]); - - const row = new ActionRowBuilder() - .addComponents([ - new ButtonBuilder() - .setLabel("Confirm") - .setCustomId(`effects use confirm ${effectDetail.id}`) - .setStyle(ButtonStyle.Primary), - new ButtonBuilder() - .setLabel("Cancel") - .setCustomId(`effects use cancel ${effectDetail.id}`) - .setStyle(ButtonStyle.Danger), - ]); - - await interaction.reply({ - embeds: [ embed ], - components: [ row ], - }); - } } diff --git a/src/commands/effects/Buy.ts b/src/commands/effects/Buy.ts new file mode 100644 index 0000000..3ebf587 --- /dev/null +++ b/src/commands/effects/Buy.ts @@ -0,0 +1,22 @@ +import { CommandInteraction } from "discord.js"; +import EffectHelper from "../../helpers/EffectHelper"; + +export default async function Buy(interaction: CommandInteraction) { + const id = interaction.options.get("id", true).value!; + const quantity = interaction.options.get("quantity")?.value ?? 1; + + const idValue = id.toString(); + const quantityValue = Number(quantity); + + const result = await EffectHelper.GenerateEffectBuyEmbed(interaction.user.id, idValue, quantityValue, false); + + if (typeof result == "string") { + await interaction.reply(result); + return; + } + + await interaction.reply({ + embeds: [ result.embed ], + components: [ result.row ], + }); +} \ No newline at end of file diff --git a/src/commands/effects/List.ts b/src/commands/effects/List.ts new file mode 100644 index 0000000..14e6085 --- /dev/null +++ b/src/commands/effects/List.ts @@ -0,0 +1,15 @@ +import { CommandInteraction } from "discord.js"; +import EffectHelper from "../../helpers/EffectHelper"; + +export default async function List(interaction: CommandInteraction) { + const pageOption = interaction.options.get("page"); + + const page = !isNaN(Number(pageOption?.value)) ? Number(pageOption?.value) : 1; + + const result = await EffectHelper.GenerateEffectListEmbed(interaction.user.id, page); + + await interaction.reply({ + embeds: [ result.embed ], + components: [ result.row ], + }); +} \ No newline at end of file diff --git a/src/commands/effects/Use.ts b/src/commands/effects/Use.ts new file mode 100644 index 0000000..9f72ae0 --- /dev/null +++ b/src/commands/effects/Use.ts @@ -0,0 +1,62 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder } from "discord.js"; +import { EffectDetails } from "../../constants/EffectDetails"; +import AppLogger from "../../client/appLogger"; +import EffectHelper from "../../helpers/EffectHelper"; +import TimeLengthInput from "../../helpers/TimeLengthInput"; +import EmbedColours from "../../constants/EmbedColours"; + +export default async function Use(interaction: CommandInteraction) { + const id = interaction.options.get("id", true).value!.toString(); + + const effectDetail = EffectDetails.get(id); + + if (!effectDetail) { + AppLogger.LogWarn("Commands/Effects", `Unable to find effect details for ${id}`); + + await interaction.reply("Unable to find effect!"); + return; + } + + const canUseEffect = await EffectHelper.CanUseEffect(interaction.user.id, id); + + if (!canUseEffect) { + await interaction.reply("Unable to use effect! Please make sure you have it in your inventory and is not on cooldown"); + return; + } + + const timeLengthInput = TimeLengthInput.ConvertFromMilliseconds(effectDetail.duration); + + const embed = new EmbedBuilder() + .setTitle("Effect Confirmation") + .setDescription("Would you like to use this effect?") + .setColor(EmbedColours.Ok) + .addFields([ + { + name: "Effect", + value: effectDetail.friendlyName, + inline: true, + }, + { + name: "Length", + value: timeLengthInput.GetLengthShort(), + inline: true, + }, + ]); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setLabel("Confirm") + .setCustomId(`effects use confirm ${effectDetail.id}`) + .setStyle(ButtonStyle.Primary), + new ButtonBuilder() + .setLabel("Cancel") + .setCustomId(`effects use cancel ${effectDetail.id}`) + .setStyle(ButtonStyle.Danger), + ]); + + await interaction.reply({ + embeds: [ embed ], + components: [ row ], + }); +} \ No newline at end of file diff --git a/src/constants/EffectDetails.ts b/src/constants/EffectDetails.ts index 4b84dad..9d1f2b6 100644 --- a/src/constants/EffectDetails.ts +++ b/src/constants/EffectDetails.ts @@ -17,3 +17,7 @@ class EffectDetail { export const EffectDetails = new Map([ [ "unclaimed", new EffectDetail("unclaimed", "Unclaimed Chance Up", 10 * 60 * 1000, 100, 3 * 60 * 60 * 1000) ], ]); + +export const EffectChoices = [ + { name: "Unclaimed Chance Up", value: "unclaimed" }, +]; diff --git a/src/helpers/EffectHelper.ts b/src/helpers/EffectHelper.ts index 6c38cac..235ea08 100644 --- a/src/helpers/EffectHelper.ts +++ b/src/helpers/EffectHelper.ts @@ -2,6 +2,9 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "disc import UserEffect from "../database/entities/app/UserEffect"; import EmbedColours from "../constants/EmbedColours"; import { EffectDetails } from "../constants/EffectDetails"; +import User from "../database/entities/app/User"; +import CardConstants from "../constants/CardConstants"; +import AppLogger from "../client/appLogger"; export default class EffectHelper { public static async AddEffectToUserInventory(userId: string, name: string, quantity: number = 1) { @@ -66,7 +69,7 @@ export default class EffectHelper { return true; } - public static async GenerateEffectEmbed(userId: string, page: number): Promise<{ + public static async GenerateEffectListEmbed(userId: string, page: number): Promise<{ embed: EmbedBuilder, row: ActionRowBuilder, }> { @@ -126,4 +129,66 @@ export default class EffectHelper { row, }; } + + public static async GenerateEffectBuyEmbed(userId: string, id: string, quantity: number, disabled: boolean): Promise<{ + embed: EmbedBuilder, + row: ActionRowBuilder, + } | string> { + const effectDetail = EffectDetails.get(id); + + if (!effectDetail) { + return "Effect detail not found!"; + } + + const totalCost = effectDetail.cost * quantity; + + let user = await User.FetchOneById(User, userId); + + if (!user) { + user = new User(userId, CardConstants.StartingCurrency); + await user.Save(User, user); + + AppLogger.LogInfo("EffectHelper", `Created initial user entity for : ${userId}`); + } + + if (user.Currency < totalCost) { + return `You don't have enough currency to buy this! You have \`${user.Currency} Currency\` and need \`${totalCost} Currency\`!`; + } + + const embed = new EmbedBuilder() + .setTitle("Buy Effect") + .setDescription(effectDetail.friendlyName) + .setColor(EmbedColours.Ok) + .addFields([ + { + name: "Cost", + value: `${totalCost}`, + inline: true, + }, + { + name: "Quantity", + value: `${quantity}`, + inline: true, + }, + ]); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setCustomId(`effects buy confirm ${id} ${quantity}`) + .setLabel("Confirm") + .setStyle(ButtonStyle.Success) + .setDisabled(disabled), + new ButtonBuilder() + .setCustomId(`effects buy cancel ${id} ${quantity}`) + .setLabel("Cancel") + .setStyle(ButtonStyle.Danger) + .setDisabled(disabled), + ]); + + return { + embed, + row, + } + } } diff --git a/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts b/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts index a1024ee..2199477 100644 --- a/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts +++ b/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts @@ -17,5 +17,7 @@ export default function GenerateButtonInteractionMock(): ButtonInteraction { id: "userId", }, customId: "customId", + update: jest.fn(), + reply: jest.fn(), }; } \ No newline at end of file diff --git a/tests/__functions__/discord.js/GenerateCommandInteractionMock.ts b/tests/__functions__/discord.js/GenerateCommandInteractionMock.ts new file mode 100644 index 0000000..26818b3 --- /dev/null +++ b/tests/__functions__/discord.js/GenerateCommandInteractionMock.ts @@ -0,0 +1,12 @@ +import { CommandInteraction } from "../../__types__/discord.js"; + +export default function GenerateCommandInteractionMock(options?: { + subcommand?: string, +}): CommandInteraction { + return { + isChatInputCommand: jest.fn().mockReturnValue(true), + options: { + getSubcommand: jest.fn().mockReturnValue(options?.subcommand), + }, + }; +} \ No newline at end of file diff --git a/tests/__types__/discord.js.ts b/tests/__types__/discord.js.ts index 6506b1d..afd1469 100644 --- a/tests/__types__/discord.js.ts +++ b/tests/__types__/discord.js.ts @@ -14,4 +14,13 @@ export type ButtonInteraction = { id: string, } | null, customId: string, + update: jest.Func, + reply: jest.Func, +} + +export type CommandInteraction = { + isChatInputCommand: jest.Func, + options: { + getSubcommand: jest.Func, + }, } \ No newline at end of file diff --git a/tests/buttonEvents/Effects.test.ts b/tests/buttonEvents/Effects.test.ts index f1f86be..8fb1023 100644 --- a/tests/buttonEvents/Effects.test.ts +++ b/tests/buttonEvents/Effects.test.ts @@ -49,6 +49,8 @@ test("GIVEN action is use, EXPECT use function to be called", async () => { expect(List).not.toHaveBeenCalled(); }); +test.todo("GIVEN action is buy, EXPECT buy function to be called"); + test("GIVEN action is invalid, EXPECT nothing to be called", async () => { // Arrange interaction.customId = "effects invalid"; @@ -63,4 +65,4 @@ test("GIVEN action is invalid, EXPECT nothing to be called", async () => { expect(AppLogger.LogError).toHaveBeenCalledTimes(1); expect(AppLogger.LogError).toHaveBeenCalledWith("Buttons/Effects", "Unknown action, invalid"); -}); \ No newline at end of file +}); diff --git a/tests/buttonEvents/Effects/Buy.test.ts b/tests/buttonEvents/Effects/Buy.test.ts new file mode 100644 index 0000000..3898504 --- /dev/null +++ b/tests/buttonEvents/Effects/Buy.test.ts @@ -0,0 +1,350 @@ +import {ButtonInteraction} from "discord.js"; +import Buy from "../../../src/buttonEvents/Effects/Buy"; +import GenerateButtonInteractionMock from "../../__functions__/discord.js/GenerateButtonInteractionMock"; +import { ButtonInteraction as ButtonInteractionType } from "../../__types__/discord.js"; +import AppLogger from "../../../src/client/appLogger"; +import EffectHelper from "../../../src/helpers/EffectHelper"; +import EmbedColours from "../../../src/constants/EmbedColours"; +import User from "../../../src/database/entities/app/User"; + +jest.mock("../../../src/client/appLogger"); +jest.mock("../../../src/helpers/EffectHelper"); +jest.mock("../../../src/database/entities/app/User"); + +let interaction: ButtonInteractionType; + +beforeEach(() => { + jest.resetAllMocks(); + + interaction = GenerateButtonInteractionMock(); + interaction.customId = "effects buy"; + +}); + +describe("Execute", () => { + test("GIVEN subaction is invalid, EXPECT error logged", async () => { + // Arrange + interaction.customId += " invalid"; + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buy", "Unknown subaction, effects invalid"); + }); +}); + +describe("Confirm", () => { + let user: User; + + beforeEach(() => { + interaction.customId += " confirm"; + + user = { + Currency: 1000, + Save: jest.fn(), + RemoveCurrency: jest.fn(), + } as unknown as User; + + (User.FetchOneById as jest.Mock).mockResolvedValue(user); + }); + + test("EXPECT success embed generated", async () => { + // Assert + interaction.customId += " unclaimed 1"; + + const embed = { + id: "embed", + setColor: jest.fn(), + setFooter: jest.fn(), + }; + const row = { + id: "row", + }; + + (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue({ + embed, + row, + }); + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.update).toHaveBeenCalledTimes(1); + expect(interaction.update).toHaveBeenCalledWith({ + embeds: [ embed ], + components: [ row ], + }); + + expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledTimes(1); + expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledWith("userId", "unclaimed", 1, true); + + expect(embed.setColor).toHaveBeenCalledTimes(1); + expect(embed.setColor).toHaveBeenCalledWith(EmbedColours.Success); + + expect(embed.setFooter).toHaveBeenCalledTimes(1); + expect(embed.setFooter).toHaveBeenCalledWith({ text: "Purchased" }); + + expect(interaction.reply).not.toHaveBeenCalled(); + expect(AppLogger.LogError).not.toHaveBeenCalled(); + + expect(User.FetchOneById).toHaveBeenCalledTimes(1); + expect(User.FetchOneById).toHaveBeenCalledWith(User, "userId"); + + expect(user.RemoveCurrency).toHaveBeenCalledTimes(1); + expect(user.RemoveCurrency).toHaveBeenCalledWith(100); + + expect(user.Save).toHaveBeenCalledTimes(1); + expect(user.Save).toHaveBeenCalledWith(User, user); + + expect(EffectHelper.AddEffectToUserInventory).toHaveBeenCalledTimes(1); + expect(EffectHelper.AddEffectToUserInventory).toHaveBeenCalledWith("userId", "unclaimed", 1); + }); + + test("GIVEN id is not supplied, EXPECT error", async () => { + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Confirm", "Not enough parameters"); + + expect(EffectHelper.GenerateEffectBuyEmbed).not.toHaveBeenCalled(); + expect(interaction.reply).not.toHaveBeenCalled(); + expect(interaction.update).not.toHaveBeenCalled(); + }); + + test("GIVEN quantity is not supplied, EXPECT error", async () => { + // Assert + interaction.customId += " unclaimed"; + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Confirm", "Not enough parameters"); + + expect(EffectHelper.GenerateEffectBuyEmbed).not.toHaveBeenCalled(); + expect(interaction.reply).not.toHaveBeenCalled(); + expect(interaction.update).not.toHaveBeenCalled(); + }); + + test("GIVEN quantity is not a number, EXPECT error", async () => { + // Assert + interaction.customId += " unclaimed invalid"; + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Confirm", "Invalid number"); + + expect(EffectHelper.GenerateEffectBuyEmbed).not.toHaveBeenCalled(); + expect(interaction.reply).not.toHaveBeenCalled(); + expect(interaction.update).not.toHaveBeenCalled(); + }); + + test("GIVEN quantity is 0, EXPECT error", async () => { + // Assert + interaction.customId += " unclaimed 0"; + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Confirm", "Invalid number"); + + expect(EffectHelper.GenerateEffectBuyEmbed).not.toHaveBeenCalled(); + expect(interaction.reply).not.toHaveBeenCalled(); + expect(interaction.update).not.toHaveBeenCalled(); + }); + + test("GIVEN user is not found, EXPECT error", async () => { + // Assert + interaction.customId += " unclaimed 1"; + + (User.FetchOneById as jest.Mock).mockResolvedValue(undefined); + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Confirm", "Unable to find user"); + + expect(EffectHelper.AddEffectToUserInventory).not.toHaveBeenCalled(); + + expect(interaction.update).not.toHaveBeenCalled(); + expect(interaction.reply).not.toHaveBeenCalled(); + }); + + test("GIVEN user does not have enough currency, EXPECT error", async () => { + // Assert + interaction.customId += " unclaimed 1"; + + user.Currency = 0; + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith("You don't have enough currency to buy this! You have `0 Currency` and need `100 Currency`!"); + + expect(EffectHelper.AddEffectToUserInventory).not.toHaveBeenCalled(); + + expect(interaction.update).not.toHaveBeenCalled(); + + expect(AppLogger.LogError).not.toHaveBeenCalled(); + }); + + test("GIVEN GenerateEffectBuyEmbed returns with a string, EXPECT error replied", async () => { + // Assert + interaction.customId += " unclaimed 1"; + + (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue("Test error"); + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith("Test error"); + + expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledTimes(1); + + expect(interaction.update).not.toHaveBeenCalled(); + expect(AppLogger.LogError).not.toHaveBeenCalled(); + }); +}); + +describe("Cancel", () => { + beforeEach(() => { + interaction.customId += " cancel"; + }); + + test("EXPECT embed generated", async () => { + // Assert + interaction.customId += " unclaimed 1"; + + const embed = { + id: "embed", + setColor: jest.fn(), + setFooter: jest.fn(), + }; + const row = { + id: "row", + }; + + (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue({ + embed, + row, + }); + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.update).toHaveBeenCalledTimes(1); + expect(interaction.update).toHaveBeenCalledWith({ + embeds: [ embed ], + components: [ row ], + }); + + expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledTimes(1); + expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledWith("userId", "unclaimed", 1, true); + + expect(embed.setColor).toHaveBeenCalledTimes(1); + expect(embed.setColor).toHaveBeenCalledWith(EmbedColours.Error); + + expect(embed.setFooter).toHaveBeenCalledTimes(1); + expect(embed.setFooter).toHaveBeenCalledWith({ text: "Cancelled" }); + + expect(interaction.reply).not.toHaveBeenCalled(); + expect(AppLogger.LogError).not.toHaveBeenCalled(); + }); + + test("GIVEN id is not supplied, EXPECT error", async () => { + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Cancel", "Not enough parameters"); + + expect(interaction.reply).not.toHaveBeenCalled(); + expect(interaction.update).not.toHaveBeenCalled(); + }); + + test("GIVEN quantity is not supplied, EXPECT error", async () => { + // Assert + interaction.customId += " unclaimed"; + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Cancel", "Not enough parameters"); + + expect(EffectHelper.GenerateEffectBuyEmbed).not.toHaveBeenCalled(); + expect(interaction.reply).not.toHaveBeenCalled(); + expect(interaction.update).not.toHaveBeenCalled(); + }); + + test("GIVEN quantity is not a number, EXPECT error", async () => { + // Assert + interaction.customId += " unclaimed invalid"; + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Cancel", "Invalid number"); + + expect(EffectHelper.GenerateEffectBuyEmbed).not.toHaveBeenCalled(); + expect(interaction.reply).not.toHaveBeenCalled(); + expect(interaction.update).not.toHaveBeenCalled(); + }); + + test("GIVEN quantity is 0, EXPECT error", async () => { + // Assert + interaction.customId += " unclaimed 0"; + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Cancel", "Invalid number"); + + expect(EffectHelper.GenerateEffectBuyEmbed).not.toHaveBeenCalled(); + expect(interaction.reply).not.toHaveBeenCalled(); + expect(interaction.update).not.toHaveBeenCalled(); + }); + + test("GIVEN GenerateEffectBuyEmbed returns with a string, EXPECT error replied", async () => { + // Assert + interaction.customId += " unclaimed 1"; + + (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue("Test error"); + + // Act + await Buy.Execute(interaction as unknown as ButtonInteraction); + + // Assert + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith("Test error"); + + expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledTimes(1); + + expect(interaction.update).not.toHaveBeenCalled(); + expect(AppLogger.LogError).not.toHaveBeenCalled(); + }); +}); diff --git a/tests/buttonEvents/Effects/List.test.ts b/tests/buttonEvents/Effects/List.test.ts index 52fa550..5b42c61 100644 --- a/tests/buttonEvents/Effects/List.test.ts +++ b/tests/buttonEvents/Effects/List.test.ts @@ -10,7 +10,7 @@ let interaction: ReturnType>; beforeEach(() => { jest.resetAllMocks(); - (EffectHelper.GenerateEffectEmbed as jest.Mock).mockResolvedValue({ + (EffectHelper.GenerateEffectListEmbed as jest.Mock).mockResolvedValue({ embed: mock(), row: mock>(), }); @@ -31,7 +31,7 @@ test("GIVEN pageOption is NOT a number, EXPECT error", async () => { expect(interaction.reply).toHaveBeenCalledTimes(1); expect(interaction.reply).toHaveBeenCalledWith("Page option is not a valid number") - expect(EffectHelper.GenerateEffectEmbed).not.toHaveBeenCalled(); + expect(EffectHelper.GenerateEffectListEmbed).not.toHaveBeenCalled(); expect(interaction.update).not.toHaveBeenCalled(); }); @@ -43,8 +43,8 @@ test("GIVEN pageOption is a number, EXPECT interaction updated", async () => { await List(interaction); // Assert - expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledTimes(1); - expect(EffectHelper.GenerateEffectEmbed).toHaveBeenCalledWith("userId", 1); + expect(EffectHelper.GenerateEffectListEmbed).toHaveBeenCalledTimes(1); + expect(EffectHelper.GenerateEffectListEmbed).toHaveBeenCalledWith("userId", 1); expect(interaction.update).toHaveBeenCalledTimes(1); }); \ No newline at end of file diff --git a/tests/commands/__snapshots__/effects.test.ts.snap b/tests/commands/__snapshots__/effects.test.ts.snap new file mode 100644 index 0000000..474b505 --- /dev/null +++ b/tests/commands/__snapshots__/effects.test.ts.snap @@ -0,0 +1,106 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EXPECT CommandBuilder to be defined 1`] = ` +{ + "contexts": undefined, + "default_member_permissions": undefined, + "default_permission": undefined, + "description": "Effects", + "description_localizations": undefined, + "dm_permission": undefined, + "integration_types": undefined, + "name": "effects", + "name_localizations": undefined, + "nsfw": undefined, + "options": [ + { + "description": "List all effects I have", + "description_localizations": undefined, + "name": "list", + "name_localizations": undefined, + "options": [ + { + "autocomplete": undefined, + "choices": undefined, + "description": "The page number", + "description_localizations": undefined, + "max_value": undefined, + "min_value": 1, + "name": "page", + "name_localizations": undefined, + "required": false, + "type": 10, + }, + ], + "type": 1, + }, + { + "description": "Use an effect in your inventory", + "description_localizations": undefined, + "name": "use", + "name_localizations": undefined, + "options": [ + { + "autocomplete": undefined, + "choices": [ + { + "name": "Unclaimed Chance Up", + "name_localizations": undefined, + "value": "unclaimed", + }, + ], + "description": "The effect id to use", + "description_localizations": undefined, + "max_length": undefined, + "min_length": undefined, + "name": "id", + "name_localizations": undefined, + "required": true, + "type": 3, + }, + ], + "type": 1, + }, + { + "description": "Buy more effects", + "description_localizations": undefined, + "name": "buy", + "name_localizations": undefined, + "options": [ + { + "autocomplete": undefined, + "choices": [ + { + "name": "Unclaimed Chance Up", + "name_localizations": undefined, + "value": "unclaimed", + }, + ], + "description": "The effect id to buy", + "description_localizations": undefined, + "max_length": undefined, + "min_length": undefined, + "name": "id", + "name_localizations": undefined, + "required": true, + "type": 3, + }, + { + "autocomplete": undefined, + "choices": undefined, + "description": "The amount to buy", + "description_localizations": undefined, + "max_value": undefined, + "min_value": 1, + "name": "quantity", + "name_localizations": undefined, + "required": false, + "type": 10, + }, + ], + "type": 1, + }, + ], + "type": 1, +} +`; diff --git a/tests/commands/effects.test.ts b/tests/commands/effects.test.ts new file mode 100644 index 0000000..33f612d --- /dev/null +++ b/tests/commands/effects.test.ts @@ -0,0 +1,105 @@ +import Effects from "../../src/commands/effects"; +import List from "../../src/commands/effects/List"; +import Use from "../../src/commands/effects/Use"; +import Buy from "../../src/commands/effects/Buy"; +import AppLogger from "../../src/client/appLogger"; +import GenerateCommandInteractionMock from "../__functions__/discord.js/GenerateCommandInteractionMock"; +import { CommandInteraction } from "discord.js"; + +jest.mock("../../src/commands/effects/List"); +jest.mock("../../src/commands/effects/Use"); +jest.mock("../../src/commands/effects/Buy"); +jest.mock("../../src/client/appLogger"); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +test("EXPECT CommandBuilder to be defined", async () => { + // Act + const effects = new Effects(); + + // Assert + expect(effects.CommandBuilder).toMatchSnapshot(); +}); + +describe("execute", () => { + test("GIVEN interaction subcommand is list, EXPECT buy function called", async () => { + // Arrange + const interaction = GenerateCommandInteractionMock({ + subcommand: "list", + }); + + // Act + const effects = new Effects(); + await effects.execute(interaction as unknown as CommandInteraction); + + // Assert + expect(List).toHaveBeenCalledTimes(1); + expect(List).toHaveBeenCalledWith(interaction); + + expect(Use).not.toHaveBeenCalled(); + expect(Buy).not.toHaveBeenCalled(); + + expect(AppLogger.LogError).not.toHaveBeenCalled(); + }); + + test("GIVEN interaction subcommand is use, EXPECT buy function called", async () => { + // Arrange + const interaction = GenerateCommandInteractionMock({ + subcommand: "use", + }); + + // Act + const effects = new Effects(); + await effects.execute(interaction as unknown as CommandInteraction); + + // Assert + expect(Use).toHaveBeenCalledTimes(1); + expect(Use).toHaveBeenCalledWith(interaction); + + expect(List).not.toHaveBeenCalled(); + expect(Buy).not.toHaveBeenCalled(); + + expect(AppLogger.LogError).not.toHaveBeenCalled(); + }); + + test("GIVEN interaction subcommand is buy, EXPECT buy function called", async () => { + // Arrange + const interaction = GenerateCommandInteractionMock({ + subcommand: "buy", + }); + + // Act + const effects = new Effects(); + await effects.execute(interaction as unknown as CommandInteraction); + + // Assert + expect(Buy).toHaveBeenCalledTimes(1); + expect(Buy).toHaveBeenCalledWith(interaction); + + expect(List).not.toHaveBeenCalled(); + expect(Use).not.toHaveBeenCalled(); + + expect(AppLogger.LogError).not.toHaveBeenCalled(); + }); + + test("GIVEN interaction subcommand is invalid, EXPECT error logged", async () => { + // Arrange + const interaction = GenerateCommandInteractionMock({ + subcommand: "invalid", + }); + + // Act + const effects = new Effects(); + await effects.execute(interaction as unknown as CommandInteraction); + + // Assert + expect(AppLogger.LogError).toHaveBeenCalledTimes(1); + expect(AppLogger.LogError).toHaveBeenCalledWith("Commands/Effects", "Invalid subcommand: invalid"); + + expect(List).not.toHaveBeenCalled(); + expect(Use).not.toHaveBeenCalled(); + expect(Buy).not.toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/tests/commands/effects/Buy.test.ts b/tests/commands/effects/Buy.test.ts new file mode 100644 index 0000000..87e4219 --- /dev/null +++ b/tests/commands/effects/Buy.test.ts @@ -0,0 +1,9 @@ +jest.mock("../../../src/helpers/EffectHelper"); + +describe("Buy", () => { + test.todo("GIVEN result returns a string, EXPECT interaction replied with string"); + + test.todo("GIVEN result returns an embed, EXPECT interaction replied with embed and row"); + + test.todo("GIVEN quantity option is not supplied, EXPECT quantity to default to 1"); +}); diff --git a/tests/helpers/EffectHelper.test.ts b/tests/helpers/EffectHelper.test.ts index b0dd12d..dcab744 100644 --- a/tests/helpers/EffectHelper.test.ts +++ b/tests/helpers/EffectHelper.test.ts @@ -3,7 +3,7 @@ import UserEffect from "../../src/database/entities/app/UserEffect"; jest.mock("../../src/database/entities/app/UserEffect"); -describe("GenerateEffectEmbed", () => { +describe("GenerateEffectListEmbed", () => { test("GIVEN user has an effect, EXPECT detailed embed to be returned", async () => { // Arrange (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ @@ -17,7 +17,7 @@ describe("GenerateEffectEmbed", () => { ]); // Act - const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + const result = await EffectHelper.GenerateEffectListEmbed("userId", 1); // Assert expect(result).toMatchSnapshot(); @@ -43,7 +43,7 @@ describe("GenerateEffectEmbed", () => { ]); // Act - const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + const result = await EffectHelper.GenerateEffectListEmbed("userId", 1); // Assert expect(result).toMatchSnapshot(); @@ -69,7 +69,7 @@ describe("GenerateEffectEmbed", () => { ]); // Act - const result = await EffectHelper.GenerateEffectEmbed("userId", 2); + const result = await EffectHelper.GenerateEffectListEmbed("userId", 2); // Assert expect(result).toMatchSnapshot(); @@ -83,7 +83,7 @@ describe("GenerateEffectEmbed", () => { ]); // Act - const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + const result = await EffectHelper.GenerateEffectListEmbed("userId", 1); // Assert expect(result).toMatchSnapshot(); @@ -107,9 +107,21 @@ describe("GenerateEffectEmbed", () => { }); // Act - const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + const result = await EffectHelper.GenerateEffectListEmbed("userId", 1); // Assert expect(result).toMatchSnapshot(); }); +}); + +describe("GenerateEffectBuyEmbed", () => { + test.todo("GIVEN Effect Details are not found, EXPECT error"); + + test.todo("GIVEN user is not in database, EXPECT blank user created"); + + test.todo("GIVEN user does not have enough currency, EXPECT error"); + + test.todo("GIVEN user does have enough currency, EXPECT embed returned"); + + test.todo("GIVEN disabled boolean is true, EXPECT buttons to be disabled"); }); \ No newline at end of file diff --git a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap index f6e5e8e..fc3317e 100644 --- a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap +++ b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`GenerateEffectEmbed GIVEN there is an active effect, EXPECT field added 1`] = ` +exports[`GenerateEffectListEmbed GIVEN there is an active effect, EXPECT field added 1`] = ` { "embed": { "color": 3166394, @@ -47,7 +47,7 @@ exports[`GenerateEffectEmbed GIVEN there is an active effect, EXPECT field added } `; -exports[`GenerateEffectEmbed GIVEN user does NOT have an effect, EXPECT empty embed to be returned 1`] = ` +exports[`GenerateEffectListEmbed GIVEN user does NOT have an effect, EXPECT empty embed to be returned 1`] = ` { "embed": { "color": 3166394, @@ -82,7 +82,7 @@ exports[`GenerateEffectEmbed GIVEN user does NOT have an effect, EXPECT empty em } `; -exports[`GenerateEffectEmbed GIVEN user has an effect, EXPECT detailed embed to be returned 1`] = ` +exports[`GenerateEffectListEmbed GIVEN user has an effect, EXPECT detailed embed to be returned 1`] = ` { "embed": { "color": 3166394, @@ -117,7 +117,7 @@ exports[`GenerateEffectEmbed GIVEN user has an effect, EXPECT detailed embed to } `; -exports[`GenerateEffectEmbed GIVEN user has more than 1 page of effects, EXPECT pagination enabled 1`] = ` +exports[`GenerateEffectListEmbed GIVEN user has more than 1 page of effects, EXPECT pagination enabled 1`] = ` { "embed": { "color": 3166394, @@ -166,7 +166,7 @@ Unclaimed Chance Up x1", } `; -exports[`GenerateEffectEmbed GIVEN user is on a page other than 1, EXPECT pagination enabled 1`] = ` +exports[`GenerateEffectListEmbed GIVEN user is on a page other than 1, EXPECT pagination enabled 1`] = ` { "embed": { "color": 3166394, From 0669dfb0d06adffa5a8493c98d03e61a8406a721 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 25 Apr 2025 09:17:36 +0100 Subject: [PATCH 50/59] Fix linting --- src/helpers/ImageHelper.ts | 2 +- yarn.lock | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/helpers/ImageHelper.ts b/src/helpers/ImageHelper.ts index 1b0c856..6156938 100644 --- a/src/helpers/ImageHelper.ts +++ b/src/helpers/ImageHelper.ts @@ -68,7 +68,7 @@ export default class ImageHelper { ctx.drawImage(image, imageX, imageY); } - catch (e) { + catch { // TODO: Enable once we've investigated a fix //AppLogger.CatchError("ImageHelper", e); } diff --git a/yarn.lock b/yarn.lock index 0171528..c63e681 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6121,6 +6121,11 @@ type-fest@^3.0.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== +type-fest@^4.18.2: + version "4.40.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.40.0.tgz#62bc09caccb99a75e1ad6b9b4653e8805e5e1eee" + integrity sha512-ABHZ2/tS2JkvH1PEjxFDTUWC8dB5OsIGZP4IFLhR293GqT5Y5qB1WwL2kMPYhQW9DVgVD8Hd7I8gjwPIf5GFkw== + type-fest@^4.21.0, type-fest@^4.6.0, type-fest@^4.7.1: version "4.26.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.26.1.tgz#a4a17fa314f976dd3e6d6675ef6c775c16d7955e" From 99b0caa7e47a2e7a53a0a808c4c3019e9410d76c Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 4 Apr 2025 18:56:13 +0100 Subject: [PATCH 51/59] Update drop mechanic to take currency on drop instead of claim --- src/buttonEvents/Claim.ts | 7 ------- src/buttonEvents/Reroll.ts | 4 +++- src/commands/drop.ts | 4 +++- src/helpers/DropHelpers/DropEmbedHelper.ts | 14 +++++++++----- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts index 97ee54d..df377f3 100644 --- a/src/buttonEvents/Claim.ts +++ b/src/buttonEvents/Claim.ts @@ -36,11 +36,6 @@ export default class Claim extends ButtonEvent { AppLogger.LogSilly("Button/Claim", `${user.Id} has ${user.Currency} currency`); - if (!user.RemoveCurrency(CardConstants.ClaimCost)) { - await interaction.channel.send(`${interaction.user}, Not enough currency! You need ${CardConstants.ClaimCost} currency, you have ${user.Currency}!`); - return; - } - const claimed = await eClaim.FetchOneByClaimId(claimId); if (claimed) { @@ -53,8 +48,6 @@ export default class Claim extends ButtonEvent { return; } - await user.Save(User, user); - let inventory = await Inventory.FetchOneByCardNumberAndUserId(userId, cardNumber); if (!inventory) { diff --git a/src/buttonEvents/Reroll.ts b/src/buttonEvents/Reroll.ts index e25e474..b1ac12c 100644 --- a/src/buttonEvents/Reroll.ts +++ b/src/buttonEvents/Reroll.ts @@ -35,11 +35,13 @@ export default class Reroll extends ButtonEvent { AppLogger.LogInfo("Commands/Drop", `New user (${interaction.user.id}) saved to the database`); } - if (user.Currency < CardConstants.ClaimCost) { + if (!user.RemoveCurrency(CardConstants.ClaimCost)) { await interaction.reply(`Not enough currency! You need ${CardConstants.ClaimCost} currency, you have ${user.Currency}!`); return; } + await user.Save(User, user); + const randomCard = await GetCardsHelper.FetchCard(interaction.user.id); if (!randomCard) { diff --git a/src/commands/drop.ts b/src/commands/drop.ts index 6c93af6..57a2123 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -43,11 +43,13 @@ export default class Drop extends Command { AppLogger.LogInfo("Commands/Drop", `New user (${interaction.user.id}) saved to the database`); } - if (user.Currency < CardConstants.ClaimCost) { + if (!user.RemoveCurrency(CardConstants.ClaimCost)) { await interaction.reply(ErrorMessages.NotEnoughCurrency(CardConstants.ClaimCost, user.Currency)); return; } + await user.Save(User, user); + const randomCard = await GetCardsHelper.FetchCard(interaction.user.id); if (!randomCard) { diff --git a/src/helpers/DropHelpers/DropEmbedHelper.ts b/src/helpers/DropHelpers/DropEmbedHelper.ts index c739de7..a50d2e9 100644 --- a/src/helpers/DropHelpers/DropEmbedHelper.ts +++ b/src/helpers/DropHelpers/DropEmbedHelper.ts @@ -1,7 +1,7 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; import { DropResult } from "../../contracts/SeriesMetadata"; import AppLogger from "../../client/appLogger"; -import { CardRarityToColour, CardRarityToString } from "../../constants/CardRarity"; +import { CardRarityToColour, CardRarityToString, GetSacrificeAmount } from "../../constants/CardRarity"; import StringTools from "../StringTools"; import CardConstants from "../../constants/CardConstants"; @@ -74,12 +74,16 @@ export default class DropEmbedHelper { .addComponents( new ButtonBuilder() .setCustomId(`claim ${drop.card.id} ${claimId} ${userId}`) - .setLabel(`Claim (${CardConstants.ClaimCost} 🪙)`) - .setStyle(ButtonStyle.Primary) + .setLabel("Claim") + .setStyle(ButtonStyle.Success) .setDisabled(disabled), + new ButtonBuilder() + .setCustomId(`sacrifice confirm ${userId} ${drop.card.id} 1`) + .setLabel(`Sacrifice`) + .setStyle(ButtonStyle.Danger), new ButtonBuilder() .setCustomId("reroll") - .setLabel("Reroll") - .setStyle(ButtonStyle.Secondary)); + .setEmoji("🔁") + .setStyle(ButtonStyle.Primary),); } } \ No newline at end of file From 6ed4c5084b25509fbe8f4f1f91d007145034e498 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 4 Apr 2025 18:56:58 +0100 Subject: [PATCH 52/59] Update the time until anyone can claim the card to 2 minutes --- src/buttonEvents/Claim.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts index df377f3..5f37b86 100644 --- a/src/buttonEvents/Claim.ts +++ b/src/buttonEvents/Claim.ts @@ -23,10 +23,10 @@ export default class Claim extends ButtonEvent { const userId = interaction.user.id; const whenDropped = interaction.message.createdAt; - const lastClaimableDate = new Date(Date.now() - (1000 * 60 * 5)); // 5 minutes ago + const lastClaimableDate = new Date(Date.now() - (1000 * 60 * 2)); // 2 minutes ago if (whenDropped < lastClaimableDate) { - await interaction.channel.send(`${interaction.user}, Cards can only be claimed within 5 minutes of it being dropped!`); + await interaction.channel.send(`${interaction.user}, Cards can only be claimed within 2 minutes of it being dropped!`); return; } From 5f64f15ffa9a0c9c2dc4cafd6d9e1fb9777ee4ab Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 4 Apr 2025 19:03:21 +0100 Subject: [PATCH 53/59] Update PurgeClaims timer to purge after 2 minutes --- src/timers/PurgeClaims.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/timers/PurgeClaims.ts b/src/timers/PurgeClaims.ts index a0ed9d0..4ca8902 100644 --- a/src/timers/PurgeClaims.ts +++ b/src/timers/PurgeClaims.ts @@ -4,7 +4,7 @@ import Claim from "../database/entities/app/Claim"; export default async function PurgeClaims() { const claims = await Claim.FetchAll(Claim); - const whenLastClaimable = new Date(Date.now() - (1000 * 60 * 5)); // 5 minutes ago + const whenLastClaimable = new Date(Date.now() - (1000 * 60 * 2)); // 2 minutes ago const expiredClaims = claims.filter(x => x.WhenCreated < whenLastClaimable); From 98ba35b6c18f93a9dd800df91a5f084a774510b4 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 4 Apr 2025 19:03:54 +0100 Subject: [PATCH 54/59] Remove restriction that the last drop can only be claimed by the user who dropped it --- src/buttonEvents/Claim.ts | 6 ------ src/buttonEvents/Reroll.ts | 2 -- src/client/client.ts | 1 - src/commands/drop.ts | 2 -- src/commands/stage/dropnumber.ts | 2 -- src/commands/stage/droprarity.ts | 2 -- 6 files changed, 15 deletions(-) diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts index 5f37b86..d139f42 100644 --- a/src/buttonEvents/Claim.ts +++ b/src/buttonEvents/Claim.ts @@ -1,7 +1,6 @@ import { ButtonInteraction } from "discord.js"; import { ButtonEvent } from "../type/buttonEvent"; import Inventory from "../database/entities/app/Inventory"; -import { CoreClient } from "../client/client"; import { default as eClaim } from "../database/entities/app/Claim"; import AppLogger from "../client/appLogger"; import User from "../database/entities/app/User"; @@ -43,11 +42,6 @@ export default class Claim extends ButtonEvent { return; } - if (claimId == CoreClient.ClaimId && userId != droppedBy) { - await interaction.channel.send(`${interaction.user}, The latest dropped card can only be claimed by the user who dropped it!`); - return; - } - let inventory = await Inventory.FetchOneByCardNumberAndUserId(userId, cardNumber); if (!inventory) { diff --git a/src/buttonEvents/Reroll.ts b/src/buttonEvents/Reroll.ts index b1ac12c..6d97024 100644 --- a/src/buttonEvents/Reroll.ts +++ b/src/buttonEvents/Reroll.ts @@ -80,8 +80,6 @@ export default class Reroll extends ButtonEvent { files: files, components: [ row ], }); - - CoreClient.ClaimId = claimId; } catch (e) { AppLogger.LogError("Button/Reroll", `Error sending next drop for card ${randomCard.card.id}: ${e}`); diff --git a/src/client/client.ts b/src/client/client.ts index 87b496e..57551fb 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -31,7 +31,6 @@ export class CoreClient extends Client { private _webhooks: Webhooks; private _timerHelper: TimerHelper; - public static ClaimId: string; public static Environment: Environment; public static AllowDrops: boolean; public static Cards: SeriesMetadata[]; diff --git a/src/commands/drop.ts b/src/commands/drop.ts index 57a2123..ac8008c 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -88,8 +88,6 @@ export default class Drop extends Command { components: [ row ], }); - CoreClient.ClaimId = claimId; - } catch (e) { AppLogger.LogError("Commands/Drop", `Error sending next drop for card ${randomCard.card.id}: ${e}`); diff --git a/src/commands/stage/dropnumber.ts b/src/commands/stage/dropnumber.ts index 2f81862..c61ed43 100644 --- a/src/commands/stage/dropnumber.ts +++ b/src/commands/stage/dropnumber.ts @@ -76,7 +76,5 @@ export default class Dropnumber extends Command { AppLogger.CatchError("Dropnumber", e); await interaction.editReply("Unable to send next drop. Please try again, and report this if it keeps happening"); } - - CoreClient.ClaimId = claimId; } } \ No newline at end of file diff --git a/src/commands/stage/droprarity.ts b/src/commands/stage/droprarity.ts index a535255..38e7973 100644 --- a/src/commands/stage/droprarity.ts +++ b/src/commands/stage/droprarity.ts @@ -81,7 +81,5 @@ export default class Droprarity extends Command { AppLogger.CatchError("Droprarity", e); await interaction.editReply("Unable to send next drop. Please try again, and report this if it keeps happening"); } - - CoreClient.ClaimId = claimId; } } \ No newline at end of file From e76864eb29a9449b2255ea0eaa1857c7929235eb Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Mon, 7 Apr 2025 18:11:01 +0100 Subject: [PATCH 55/59] Fix existing tests --- tests/buttonEvents/Claim.test.ts | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/tests/buttonEvents/Claim.test.ts b/tests/buttonEvents/Claim.test.ts index d9e7e6f..80cf78f 100644 --- a/tests/buttonEvents/Claim.test.ts +++ b/tests/buttonEvents/Claim.test.ts @@ -85,25 +85,7 @@ test("GIVEN interaction.message was created more than 5 minutes ago, EXPECT erro // Assert expect(interaction.channel!.send).toHaveBeenCalledTimes(1); - expect(interaction.channel!.send).toHaveBeenCalledWith("[object Object], Cards can only be claimed within 5 minutes of it being dropped!"); - - expect(interaction.editReply).not.toHaveBeenCalled(); -}); - -test("GIVEN user.RemoveCurrency fails, EXPECT error", async () => { - // Arrange - User.FetchOneById = jest.fn().mockResolvedValue({ - RemoveCurrency: jest.fn().mockReturnValue(false), - Currency: 5, - }); - - // Act - const claim = new Claim(); - await claim.execute(interaction as unknown as ButtonInteraction); - - // Assert - expect(interaction.channel!.send).toHaveBeenCalledTimes(1); - expect(interaction.channel!.send).toHaveBeenCalledWith("[object Object], Not enough currency! You need 10 currency, you have 5!"); + expect(interaction.channel!.send).toHaveBeenCalledWith("[object Object], Cards can only be claimed within 2 minutes of it being dropped!"); expect(interaction.editReply).not.toHaveBeenCalled(); }); \ No newline at end of file From c08401084b1ce319be7adaa76ad20be058e025b2 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Mon, 7 Apr 2025 18:42:47 +0100 Subject: [PATCH 56/59] Plan tests --- src/helpers/DropHelpers/DropEmbedHelper.ts | 3 +-- tests/buttonEvents/Claim.test.ts | 1 - tests/buttonEvents/Reroll.test.ts | 7 +++++++ tests/commands/drop.test.ts | 7 +++++++ tests/helpers/DropHelpers/DropEmbedHelper.test.ts | 3 +++ tests/timers/PurgeClaims.test.ts | 7 +++++++ 6 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 tests/buttonEvents/Reroll.test.ts create mode 100644 tests/commands/drop.test.ts create mode 100644 tests/helpers/DropHelpers/DropEmbedHelper.test.ts create mode 100644 tests/timers/PurgeClaims.test.ts diff --git a/src/helpers/DropHelpers/DropEmbedHelper.ts b/src/helpers/DropHelpers/DropEmbedHelper.ts index a50d2e9..08b5813 100644 --- a/src/helpers/DropHelpers/DropEmbedHelper.ts +++ b/src/helpers/DropHelpers/DropEmbedHelper.ts @@ -1,9 +1,8 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; import { DropResult } from "../../contracts/SeriesMetadata"; import AppLogger from "../../client/appLogger"; -import { CardRarityToColour, CardRarityToString, GetSacrificeAmount } from "../../constants/CardRarity"; +import { CardRarityToColour, CardRarityToString } from "../../constants/CardRarity"; import StringTools from "../StringTools"; -import CardConstants from "../../constants/CardConstants"; export default class DropEmbedHelper { public static GenerateDropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, claimedBy?: string, currency?: number): EmbedBuilder { diff --git a/tests/buttonEvents/Claim.test.ts b/tests/buttonEvents/Claim.test.ts index 80cf78f..1e7027c 100644 --- a/tests/buttonEvents/Claim.test.ts +++ b/tests/buttonEvents/Claim.test.ts @@ -1,7 +1,6 @@ import { ButtonInteraction, TextChannel } from "discord.js"; import Claim from "../../src/buttonEvents/Claim"; import { ButtonInteraction as ButtonInteractionType } from "../__types__/discord.js"; -import User from "../../src/database/entities/app/User"; import GenerateButtonInteractionMock from "../__functions__/discord.js/GenerateButtonInteractionMock"; jest.mock("../../src/client/appLogger"); diff --git a/tests/buttonEvents/Reroll.test.ts b/tests/buttonEvents/Reroll.test.ts new file mode 100644 index 0000000..2021aac --- /dev/null +++ b/tests/buttonEvents/Reroll.test.ts @@ -0,0 +1,7 @@ +describe("GIVEN valid conditions", () => { + test.todo("EXPECT user.RemoveCurrency to be called"); + + test.todo("GIVEN user is saved"); +}); + +test.todo("GIVEN user.RemoveCurrency fails, EXPECT error replied"); \ No newline at end of file diff --git a/tests/commands/drop.test.ts b/tests/commands/drop.test.ts new file mode 100644 index 0000000..2021aac --- /dev/null +++ b/tests/commands/drop.test.ts @@ -0,0 +1,7 @@ +describe("GIVEN valid conditions", () => { + test.todo("EXPECT user.RemoveCurrency to be called"); + + test.todo("GIVEN user is saved"); +}); + +test.todo("GIVEN user.RemoveCurrency fails, EXPECT error replied"); \ No newline at end of file diff --git a/tests/helpers/DropHelpers/DropEmbedHelper.test.ts b/tests/helpers/DropHelpers/DropEmbedHelper.test.ts new file mode 100644 index 0000000..743f6c7 --- /dev/null +++ b/tests/helpers/DropHelpers/DropEmbedHelper.test.ts @@ -0,0 +1,3 @@ +describe("GenerateDropButtons", () => { + test.todo("EXPECT row to be returned"); +}); \ No newline at end of file diff --git a/tests/timers/PurgeClaims.test.ts b/tests/timers/PurgeClaims.test.ts new file mode 100644 index 0000000..6d0d09b --- /dev/null +++ b/tests/timers/PurgeClaims.test.ts @@ -0,0 +1,7 @@ +describe("PurgeClaims", () => { + test.todo("EXPECT claims to be fetched"); + + test.todo("EXPECT Claim.RemoveMany to remove the claims older than 2 minutes"); + + test.todo("EXPECT info logged"); +}); \ No newline at end of file From d457a87fffac2bf5e4a84e427f224e58465f87a4 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Thu, 24 Apr 2025 19:56:07 +0100 Subject: [PATCH 57/59] WIP: Start of drop command tests --- .../GenerateCommandInteractionMock.ts | 5 + tests/__types__/discord.js.ts | 5 + tests/commands/drop.test.ts | 111 +++++++++++++++++- 3 files changed, 117 insertions(+), 4 deletions(-) diff --git a/tests/__functions__/discord.js/GenerateCommandInteractionMock.ts b/tests/__functions__/discord.js/GenerateCommandInteractionMock.ts index 26818b3..128c25b 100644 --- a/tests/__functions__/discord.js/GenerateCommandInteractionMock.ts +++ b/tests/__functions__/discord.js/GenerateCommandInteractionMock.ts @@ -4,9 +4,14 @@ export default function GenerateCommandInteractionMock(options?: { subcommand?: string, }): CommandInteraction { return { + deferReply: jest.fn(), + editReply: jest.fn(), isChatInputCommand: jest.fn().mockReturnValue(true), options: { getSubcommand: jest.fn().mockReturnValue(options?.subcommand), }, + user: { + id: "userId", + }, }; } \ No newline at end of file diff --git a/tests/__types__/discord.js.ts b/tests/__types__/discord.js.ts index afd1469..3304af4 100644 --- a/tests/__types__/discord.js.ts +++ b/tests/__types__/discord.js.ts @@ -19,8 +19,13 @@ export type ButtonInteraction = { } export type CommandInteraction = { + deferReply: jest.Func, + editReply: jest.Func, isChatInputCommand: jest.Func, options: { getSubcommand: jest.Func, }, + user: { + id: string, + }, } \ No newline at end of file diff --git a/tests/commands/drop.test.ts b/tests/commands/drop.test.ts index 2021aac..3dc4e96 100644 --- a/tests/commands/drop.test.ts +++ b/tests/commands/drop.test.ts @@ -1,7 +1,110 @@ -describe("GIVEN valid conditions", () => { - test.todo("EXPECT user.RemoveCurrency to be called"); +import { CommandInteraction } from "discord.js"; +import Drop from "../../src/commands/drop"; +import GenerateCommandInteractionMock from "../__functions__/discord.js/GenerateCommandInteractionMock"; +import { CommandInteraction as CommandInteractionMock } from "../__types__/discord.js"; +import { CoreClient } from "../../src/client/client"; +import Config from "../../src/database/entities/app/Config"; +import User from "../../src/database/entities/app/User"; +import GetCardsHelper from "../../src/helpers/DropHelpers/GetCardsHelper"; +import Inventory from "../../src/database/entities/app/Inventory"; +import DropEmbedHelper from "../../src/helpers/DropHelpers/DropEmbedHelper"; +import CardConstants from "../../src/constants/CardConstants"; - test.todo("GIVEN user is saved"); +jest.mock("../../src/database/entities/app/Config"); +jest.mock("../../src/database/entities/app/User"); +jest.mock("../../src/helpers/DropHelpers/GetCardsHelper"); +jest.mock("../../src/database/entities/app/Inventory"); +jest.mock("../../src/helpers/DropHelpers/DropEmbedHelper"); + +beforeEach(() => { + (Config.GetValue as jest.Mock).mockResolvedValue("false"); }); -test.todo("GIVEN user.RemoveCurrency fails, EXPECT error replied"); \ No newline at end of file +describe("execute", () => { + describe("GIVEN user is in the database", () => { + let interaction: CommandInteractionMock; + let user: User; + + beforeAll(async () => { + // Arrange + CoreClient.AllowDrops = true; + + interaction = GenerateCommandInteractionMock(); + + user = { + RemoveCurrency: jest.fn().mockReturnValue(true), + Save: jest.fn(), + } as unknown as User; + + (User.FetchOneById as jest.Mock).mockResolvedValue(user); + (GetCardsHelper.FetchCard as jest.Mock).mockResolvedValue({ + card: { + path: "https://google.com/", + } + }); + (Inventory.FetchOneByCardNumberAndUserId as jest.Mock).mockResolvedValue({ + Quantity: 1, + }); + (DropEmbedHelper.GenerateDropEmbed as jest.Mock).mockResolvedValue({ + type: "Embed", + }); + (DropEmbedHelper.GenerateDropButtons as jest.Mock).mockResolvedValue({ + type: "Button", + }); + + // Act + const drop = new Drop(); + await drop.execute(interaction as unknown as CommandInteraction); + }); + + test("EXPECT user to be fetched", () => { + expect(User.FetchOneById).toHaveBeenCalledTimes(1); + expect(User.FetchOneById).toHaveBeenCalledWith(User, "userId"); + }); + + test("EXPECT user.RemoveCurrency to be called", () => { + expect(user.RemoveCurrency).toHaveBeenCalledTimes(1); + expect(user.RemoveCurrency).toHaveBeenCalledWith(CardConstants.ClaimCost); + }); + + test.todo("EXPECT user to be saved"); + + test.todo("EXPECT random card to be fetched"); + + test.todo("EXPECT interaction to be deferred"); + + test.todo("EXPECT Inventory.FetchOneByCardNumberAndUserId to be called"); + + test.todo("EXPECT DropEmbedHelper.GenerateDropEmbed to be called"); + + test.todo("EXPECT DropEmbedHelper.GenerateDropButtons to be called"); + + test.todo("EXPECT interaction to be edited"); + + describe("AND randomCard path is not a url", () => { + test.todo("EXPECT image read from file system"); + + test.todo("EXPECT files on the embed to contain the image as an attachment"); + }); + }); + + describe("GIVEN user is not in the database", () => { + test.todo("EXPECT new user to be created"); + }); + + describe("GIVEN user.RemoveCurrency fails", () => { + test.todo("EXPECT error replied"); + }); + + describe("GIVEN randomCard returns null", () => { + test.todo("EXPECT error logged"); + + test.todo("EXPECT error replied"); + }); + + describe("GIVEN the code throws an error", () => { + test.todo("EXPECT error logged"); + + test.todo("EXPECT interaction edited with error"); + }); +}); \ No newline at end of file From f90384720415910a57ac00795c618b5952483246 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 4 May 2025 10:57:18 +0100 Subject: [PATCH 58/59] Update tests --- tests/commands/drop.test.ts | 62 ++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/tests/commands/drop.test.ts b/tests/commands/drop.test.ts index 3dc4e96..e97511c 100644 --- a/tests/commands/drop.test.ts +++ b/tests/commands/drop.test.ts @@ -9,6 +9,7 @@ import GetCardsHelper from "../../src/helpers/DropHelpers/GetCardsHelper"; import Inventory from "../../src/database/entities/app/Inventory"; import DropEmbedHelper from "../../src/helpers/DropHelpers/DropEmbedHelper"; import CardConstants from "../../src/constants/CardConstants"; +import * as uuid from "uuid"; jest.mock("../../src/database/entities/app/Config"); jest.mock("../../src/database/entities/app/User"); @@ -16,6 +17,8 @@ jest.mock("../../src/helpers/DropHelpers/GetCardsHelper"); jest.mock("../../src/database/entities/app/Inventory"); jest.mock("../../src/helpers/DropHelpers/DropEmbedHelper"); +jest.mock("uuid"); + beforeEach(() => { (Config.GetValue as jest.Mock).mockResolvedValue("false"); }); @@ -24,6 +27,12 @@ describe("execute", () => { describe("GIVEN user is in the database", () => { let interaction: CommandInteractionMock; let user: User; + let randomCard = { + card: { + id: "cardId", + path: "https://google.com/", + } + }; beforeAll(async () => { // Arrange @@ -32,26 +41,25 @@ describe("execute", () => { interaction = GenerateCommandInteractionMock(); user = { + Currency: 500, RemoveCurrency: jest.fn().mockReturnValue(true), Save: jest.fn(), } as unknown as User; (User.FetchOneById as jest.Mock).mockResolvedValue(user); - (GetCardsHelper.FetchCard as jest.Mock).mockResolvedValue({ - card: { - path: "https://google.com/", - } - }); + (GetCardsHelper.FetchCard as jest.Mock).mockResolvedValue(randomCard); (Inventory.FetchOneByCardNumberAndUserId as jest.Mock).mockResolvedValue({ Quantity: 1, }); - (DropEmbedHelper.GenerateDropEmbed as jest.Mock).mockResolvedValue({ + (DropEmbedHelper.GenerateDropEmbed as jest.Mock).mockReturnValue({ type: "Embed", }); - (DropEmbedHelper.GenerateDropButtons as jest.Mock).mockResolvedValue({ + (DropEmbedHelper.GenerateDropButtons as jest.Mock).mockReturnValue({ type: "Button", }); - + + (uuid.v4 as jest.Mock).mockReturnValue("uuid"); + // Act const drop = new Drop(); await drop.execute(interaction as unknown as CommandInteraction); @@ -67,19 +75,43 @@ describe("execute", () => { expect(user.RemoveCurrency).toHaveBeenCalledWith(CardConstants.ClaimCost); }); - test.todo("EXPECT user to be saved"); + test("EXPECT user to be saved", () => { + expect(user.Save).toHaveBeenCalledTimes(1); + expect(user.Save).toHaveBeenCalledWith(User, user); + }); - test.todo("EXPECT random card to be fetched"); + test("EXPECT random card to be fetched", () => { + expect(GetCardsHelper.FetchCard).toHaveBeenCalledTimes(1); + expect(GetCardsHelper.FetchCard).toHaveBeenCalledWith("userId"); + }); - test.todo("EXPECT interaction to be deferred"); + test("EXPECT interaction to be deferred", () => { + expect(interaction.deferReply).toHaveBeenCalledTimes(1); + }); - test.todo("EXPECT Inventory.FetchOneByCardNumberAndUserId to be called"); + test("EXPECT Inventory.FetchOneByCardNumberAndUserId to be called", () => { + expect(Inventory.FetchOneByCardNumberAndUserId).toHaveBeenCalledTimes(1); + expect(Inventory.FetchOneByCardNumberAndUserId).toHaveBeenCalledWith("userId", "cardId"); + }); - test.todo("EXPECT DropEmbedHelper.GenerateDropEmbed to be called"); + test("EXPECT DropEmbedHelper.GenerateDropEmbed to be called", () => { + expect(DropEmbedHelper.GenerateDropEmbed).toHaveBeenCalledTimes(1); + expect(DropEmbedHelper.GenerateDropEmbed).toHaveBeenCalledWith(randomCard, 1, "", undefined, 500); + }); - test.todo("EXPECT DropEmbedHelper.GenerateDropButtons to be called"); + test("EXPECT DropEmbedHelper.GenerateDropButtons to be called", () => { + expect(DropEmbedHelper.GenerateDropButtons).toHaveBeenCalledTimes(1); + expect(DropEmbedHelper.GenerateDropButtons).toHaveBeenCalledWith(randomCard, "uuid", "userId"); + }); - test.todo("EXPECT interaction to be edited"); + test("EXPECT interaction to be edited", () => { + expect(interaction.editReply).toHaveBeenCalledTimes(1); + expect(interaction.editReply).toHaveBeenCalledWith({ + embeds: [ { type: "Embed" } ], + files: [], + components: [ { type: "Button" } ], + }); + }); describe("AND randomCard path is not a url", () => { test.todo("EXPECT image read from file system"); From a29cd2ed200757f7074de85a6fbffca7f566c5bb Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 4 May 2025 10:59:05 +0100 Subject: [PATCH 59/59] Fix linting --- src/commands/stage/droprarity.ts | 3 +-- tests/commands/drop.test.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/commands/stage/droprarity.ts b/src/commands/stage/droprarity.ts index 38e7973..f776930 100644 --- a/src/commands/stage/droprarity.ts +++ b/src/commands/stage/droprarity.ts @@ -4,7 +4,6 @@ import { CardRarity, CardRarityChoices, CardRarityParse } from "../../constants/ import { readFileSync } from "fs"; import Inventory from "../../database/entities/app/Inventory"; import { v4 } from "uuid"; -import { CoreClient } from "../../client/client"; import path from "path"; import GetCardsHelper from "../../helpers/DropHelpers/GetCardsHelper"; import DropEmbedHelper from "../../helpers/DropHelpers/DropEmbedHelper"; @@ -42,7 +41,7 @@ export default class Droprarity extends Command { return; } - const card = await GetCardsHelper.GetRandomCardByRarity(rarityType); + const card = GetCardsHelper.GetRandomCardByRarity(rarityType); if (!card) { await interaction.reply("Card not found"); diff --git a/tests/commands/drop.test.ts b/tests/commands/drop.test.ts index e97511c..81b5f4a 100644 --- a/tests/commands/drop.test.ts +++ b/tests/commands/drop.test.ts @@ -27,7 +27,7 @@ describe("execute", () => { describe("GIVEN user is in the database", () => { let interaction: CommandInteractionMock; let user: User; - let randomCard = { + const randomCard = { card: { id: "cardId", path: "https://google.com/",