From 47991395ef5d5ecb6ec9c1ecfe34adb1e6f3ecd7 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 17 Jul 2024 17:28:14 +0100 Subject: [PATCH 01/94] Update appleboy/ssh-action action to v1.0.3 (#303) 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 | patch | `v1.0.0` -> `v1.0.3` | --- ### Release Notes
appleboy/ssh-action (appleboy/ssh-action) ### [`v1.0.3`](https://github.com/appleboy/ssh-action/releases/tag/v1.0.3) [Compare Source](https://github.com/appleboy/ssh-action/compare/v1.0.2...v1.0.3) - Support the new parameter `request_pty` to request a pseudo-terminal from the server, addressing the sudo command issue. https://github.com/appleboy/ssh-action/pull/288 ### [`v1.0.2`](https://github.com/appleboy/ssh-action/releases/tag/v1.0.2) [Compare Source](https://github.com/appleboy/ssh-action/compare/v1.0.1...v1.0.2) upgrade ssh-proxy for security patch ### [`v1.0.1`](https://github.com/appleboy/ssh-action/releases/tag/v1.0.1): for security patch [Compare Source](https://github.com/appleboy/ssh-action/compare/v1.0.0...v1.0.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/303 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 1bbf28f..1dd774e 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.0 + - uses: https://github.com/appleboy/ssh-action@v1.0.3 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 b245d95..8903a70 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.0 + - uses: https://github.com/appleboy/ssh-action@v1.0.3 env: DB_NAME: ${{ secrets.STAGE_DB_NAME }} DB_AUTH_USER: ${{ secrets.STAGE_DB_AUTH_USER }} From b0b478e1205cd9cbfb2bbdeb187a61909bb40bc0 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 17 Jul 2024 17:35:09 +0100 Subject: [PATCH 02/94] Update dependency glob to v10.4.5 (#304) 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 | |---|---|---|---| | [glob](https://github.com/isaacs/node-glob) | dependencies | patch | [`10.4.3` -> `10.4.5`](https://renovatebot.com/diffs/npm/glob/10.4.3/10.4.5) | --- ### Release Notes
isaacs/node-glob (glob) ### [`v10.4.5`](https://github.com/isaacs/node-glob/compare/v10.4.4...v10.4.5) [Compare Source](https://github.com/isaacs/node-glob/compare/v10.4.4...v10.4.5) ### [`v10.4.4`](https://github.com/isaacs/node-glob/compare/v10.4.3...v10.4.4) [Compare Source](https://github.com/isaacs/node-glob/compare/v10.4.3...v10.4.4)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] 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/304 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 04ff1b7..fcc0360 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3217,9 +3217,9 @@ glob-parent@^6.0.2: is-glob "^4.0.3" glob@^10.3.10: - version "10.4.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.3.tgz#e0ba2253dd21b3d0acdfb5d507c59a29f513fc7a" - integrity sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg== + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== dependencies: foreground-child "^3.1.0" jackspeak "^3.1.2" @@ -3942,9 +3942,9 @@ istanbul-reports@^3.1.3: istanbul-lib-report "^3.0.0" jackspeak@^3.1.2: - version "3.4.1" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.1.tgz#145422416740568e9fc357bf60c844b3c1585f09" - integrity sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg== + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== dependencies: "@isaacs/cliui" "^8.0.2" optionalDependencies: @@ -4610,9 +4610,9 @@ lru-cache@^10.0.1: integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ== lru-cache@^10.2.0: - version "10.3.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.3.1.tgz#a37050586f84ccfdb570148a253bf1632a29ef44" - integrity sha512-9/8QXrtbGeMB6LxwQd4x1tIMnsmUxMvIH/qWGsccz6bt9Uln3S+sgAaqfQNhbGA8ufzs2fHuP/yqapGgP9Hh2g== + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== lru-cache@^5.1.1: version "5.1.1" From f28254e407fd37eee5cb5815584fec645a1e70fd Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Thu, 18 Jul 2024 19:46:23 +0100 Subject: [PATCH 03/94] Add a subseries field to card metadata (#305) - Add an optional "subseries" field to the card metadata function - If this is present, it overrides the main series field #301 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/305 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/contracts/SeriesMetadata.ts | 1 + src/helpers/CardDropHelperMetadata.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/contracts/SeriesMetadata.ts b/src/contracts/SeriesMetadata.ts index c363028..4a989bc 100644 --- a/src/contracts/SeriesMetadata.ts +++ b/src/contracts/SeriesMetadata.ts @@ -11,6 +11,7 @@ export interface CardMetadata { name: string, type: CardRarity, path: string, + subseries?: string, } export interface DropResult { diff --git a/src/helpers/CardDropHelperMetadata.ts b/src/helpers/CardDropHelperMetadata.ts index 982661e..84bcdfa 100644 --- a/src/helpers/CardDropHelperMetadata.ts +++ b/src/helpers/CardDropHelperMetadata.ts @@ -81,7 +81,7 @@ export default class CardDropHelperMetadata { 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.series.name; + const description = drop.card.subseries ?? drop.series.name; const embed = new EmbedBuilder() .setTitle(drop.card.name) From b8cd73c5700853ef9176dc59686720ead25d31fa Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 20 Jul 2024 21:42:37 +0100 Subject: [PATCH 04/94] Create allbalance command to get list of everyone's currency (#306) - Create `/allbalance` command for server administrators to be able to get a list of everyone's currency - This will allow admins to adjust and rebalance currency as desired #260 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/306 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/commands/allbalance.ts | 28 ++++++++++++++++++++++++++++ src/registry.ts | 2 ++ 2 files changed, 30 insertions(+) create mode 100644 src/commands/allbalance.ts diff --git a/src/commands/allbalance.ts b/src/commands/allbalance.ts new file mode 100644 index 0000000..7db050a --- /dev/null +++ b/src/commands/allbalance.ts @@ -0,0 +1,28 @@ +import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js"; +import EmbedColours from "../constants/EmbedColours"; +import { Command } from "../type/command"; +import User from "../database/entities/app/User"; + +export default class AllBalance extends Command { + constructor() { + super(); + + this.CommandBuilder = new SlashCommandBuilder() + .setName("allbalance") + .setDescription("Get everyone's currency balance") + .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator); + } + + public override async execute(interaction: CommandInteraction) { + const users = await User.FetchAll(User); + + const filteredUsers = users.filter(x => x.Currency > 0); + + const embed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("All Balances") + .setDescription(filteredUsers.map(x => `<@${x.Id}> ${x.Currency}`).join("\n")); + + await interaction.reply({ embeds: [ embed ], ephemeral: true }); + } +} \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index 182418e..86b2b68 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -3,6 +3,7 @@ import { Environment } from "./constants/Environment"; // Global Command Imports import About from "./commands/about"; +import AllBalance from "./commands/allbalance"; import Balance from "./commands/balance"; import Daily from "./commands/daily"; import Drop from "./commands/drop"; @@ -31,6 +32,7 @@ export default class Registry { public static RegisterCommands() { // Global Commands CoreClient.RegisterCommand("about", new About()); + CoreClient.RegisterCommand("allbalance", new AllBalance()); CoreClient.RegisterCommand("balance", new Balance()); CoreClient.RegisterCommand("daily", new Daily()); CoreClient.RegisterCommand("drop", new Drop()); From 341f3d2bd83e075a3ed86fdc8e587c176842c7c6 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 22 Jul 2024 18:26:09 +0100 Subject: [PATCH 05/94] Update dependency @types/node to v20.14.11 (#307) 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.10` -> `20.14.11`](https://renovatebot.com/diffs/npm/@types%2fnode/20.14.10/20.14.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/307 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 fcc0360..9e7e9a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1259,9 +1259,9 @@ integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== "@types/node@^20.0.0": - version "20.14.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.10.tgz#a1a218290f1b6428682e3af044785e5874db469a" - integrity sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ== + version "20.14.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.11.tgz#09b300423343460455043ddd4d0ded6ac579b74b" + integrity sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA== dependencies: undici-types "~5.26.4" From a55a5cf5da0b496dfd40feb33498125f74fb0729 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 22 Jul 2024 18:27:30 +0100 Subject: [PATCH 06/94] Update dependency winston to v3.13.1 (#308) 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 | patch | [`3.13.0` -> `3.13.1`](https://renovatebot.com/diffs/npm/winston/3.13.0/3.13.1) | --- ### Release Notes
winstonjs/winston (winston) ### [`v3.13.1`](https://github.com/winstonjs/winston/releases/tag/v3.13.1) [Compare Source](https://github.com/winstonjs/winston/compare/v3.13.0...v3.13.1) - revert to rimraf 5.0.1, last known version to work with node 18 for now [`1b3a500`](https://github.com/winstonjs/winston/commit/1b3a500) - Merge branch 'master' of github.com:winstonjs/winston [`b56117e`](https://github.com/winstonjs/winston/commit/b56117e) - Update dependencies [`a5853b5`](https://github.com/winstonjs/winston/commit/a5853b5) - Bump [@​types/node](https://github.com/types/node) from 20.12.7 to 20.14.10 ([#​2483](https://github.com/winstonjs/winston/issues/2483)) [`93b52ac`](https://github.com/winstonjs/winston/commit/93b52ac) - Bump mocha from 10.3.0 to 10.6.0 ([#​2484](https://github.com/winstonjs/winston/issues/2484)) [`33611c9`](https://github.com/winstonjs/winston/commit/33611c9) - Bump [@​babel/preset-env](https://github.com/babel/preset-env) from 7.24.0 to 7.24.7 ([#​2475](https://github.com/winstonjs/winston/issues/2475)) [`4aa6550`](https://github.com/winstonjs/winston/commit/4aa6550) - Update minimum version logform ([#​2472](https://github.com/winstonjs/winston/issues/2472)) [`7f5f014`](https://github.com/winstonjs/winston/commit/7f5f014) - Add Parseable transport ([#​2466](https://github.com/winstonjs/winston/issues/2466)) [`debf4fa`](https://github.com/winstonjs/winston/commit/debf4fa) - chore(docs): Update w/ MySQL transport ([#​2456](https://github.com/winstonjs/winston/issues/2456)) [`d567c57`](https://github.com/winstonjs/winston/commit/d567c57) - fix typo at test/unit/winston/transports/http.test.js ([#​2453](https://github.com/winstonjs/winston/issues/2453)) [`1d5d527`](https://github.com/winstonjs/winston/commit/1d5d527) - Bump [@​babel/cli](https://github.com/babel/cli) from 7.23.9 to 7.24.5 ([#​2454](https://github.com/winstonjs/winston/issues/2454)) [`d89a34e`](https://github.com/winstonjs/winston/commit/d89a34e) - Bump [@​types/node](https://github.com/types/node) from 20.11.29 to 20.12.7 ([#​2448](https://github.com/winstonjs/winston/issues/2448)) [`947fa79`](https://github.com/winstonjs/winston/commit/947fa79) - Bump [@​babel/core](https://github.com/babel/core) from 7.24.0 to 7.24.5 ([#​2455](https://github.com/winstonjs/winston/issues/2455)) [`8c58d0a`](https://github.com/winstonjs/winston/commit/8c58d0a)
--- ### 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/308 Reviewed-by: Vylpes Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- yarn.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9e7e9a4..48fe278 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4582,10 +4582,10 @@ logform@2.1.2: ms "^2.1.1" triple-beam "^1.3.0" -logform@^2.3.2, logform@^2.4.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.0.tgz#8c82a983f05d6eaeb2d75e3decae7a768b2bf9b5" - integrity sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ== +logform@^2.6.0, logform@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.1.tgz#71403a7d8cae04b2b734147963236205db9b3df0" + integrity sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA== dependencies: "@colors/colors" "1.6.0" "@types/triple-beam" "^1.3.2" @@ -5650,7 +5650,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.4.0, readable-stream@^3.6.0, readable-stream@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -6741,24 +6741,24 @@ winston-transport@4.3.0: triple-beam "^1.2.0" winston-transport@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.7.0.tgz#e302e6889e6ccb7f383b926df6936a5b781bd1f0" - integrity sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg== + version "4.7.1" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.7.1.tgz#52ff1bcfe452ad89991a0aaff9c3b18e7f392569" + integrity sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA== dependencies: - logform "^2.3.2" - readable-stream "^3.6.0" + logform "^2.6.1" + readable-stream "^3.6.2" triple-beam "^1.3.0" winston@^3.11.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.13.0.tgz#e76c0d722f78e04838158c61adc1287201de7ce3" - integrity sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ== + version "3.13.1" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.13.1.tgz#53ddadb9c2332eb12cff8306413b3480dc82b6c3" + integrity sha512-SvZit7VFNvXRzbqGHsv5KSmgbEYR5EiQfDAL9gxYkRqa934Hnk++zze0wANKtMHcy/gI4W/3xmSDwlhf865WGw== dependencies: "@colors/colors" "^1.6.0" "@dabh/diagnostics" "^2.0.2" async "^3.2.3" is-stream "^2.0.0" - logform "^2.4.0" + logform "^2.6.0" one-time "^1.0.0" readable-stream "^3.4.0" safe-stable-stringify "^2.3.1" From fef80709eefc87056ca1bc9f0704ed05c18bbb80 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 26 Jul 2024 18:28:32 +0100 Subject: [PATCH 07/94] Resolve ws to ^8.17.1 (#319) - Upgrade ws to ^8.17.1 to fix vulnerability #269 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/319 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- package.json | 8 ++++---- yarn.lock | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index f37eae6..102b607 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,11 @@ "db:create": "typeorm migration:create ./src/database/migrations/app/new", "release": "np --no-publish" }, - "repository": "https://gitea.vylpes.xyz/External/card-drop.git", + "repository": "https://git.vylpes.xyz/External/card-drop.git", "author": "Ethan Lane ", "license": "MIT", "bugs": { - "url": "https//gitea.vylpes.xyz/External/card-drop/issues", + "url": "https//git.vylpes.xyz/External/card-drop/issues", "email": "helpdesk@vylpes.com" }, "homepage": "https://gitea.vylpes.xyz/External/card-drop", @@ -49,8 +49,8 @@ "winston-daily-rotate-file": "^5.0.0", "winston-discord-transport": "^1.3.0" }, - "overrides": { - "undici": "^5.28.3" + "resolutions": { + "**/ws": "^8.17.1" }, "devDependencies": { "@types/node": "^20.0.0", diff --git a/yarn.lock b/yarn.lock index 48fe278..b953c94 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6838,10 +6838,10 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@^8.16.0: - version "8.17.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.0.tgz#d145d18eca2ed25aaf791a183903f7be5e295fea" - integrity sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow== +ws@^8.16.0, ws@^8.17.1: + 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: version "5.1.0" From 097b7284e6b910352313ff0c6d581792c694e01c Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 26 Jul 2024 18:29:57 +0100 Subject: [PATCH 08/94] Fix list not being sorted (#320) - Fix list on `/allbalance` command not being sorted by currency #260 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/320 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/commands/allbalance.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/commands/allbalance.ts b/src/commands/allbalance.ts index 7db050a..0874e54 100644 --- a/src/commands/allbalance.ts +++ b/src/commands/allbalance.ts @@ -16,7 +16,8 @@ export default class AllBalance extends Command { public override async execute(interaction: CommandInteraction) { const users = await User.FetchAll(User); - const filteredUsers = users.filter(x => x.Currency > 0); + const filteredUsers = users.filter(x => x.Currency > 0) + .sort((a, b) => b.Currency - a.Currency); const embed = new EmbedBuilder() .setColor(EmbedColours.Ok) From ff9f3e458eaec933c95dc86745f1ebec88fc59b2 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 26 Jul 2024 18:31:06 +0100 Subject: [PATCH 09/94] Add some unit tests (#321) - Add some unit tests to the project - These aren't massive, more just checks to ensure certain things are as they should - Such as checking all commands are actually registered #15 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/321 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- package.json | 2 +- tests/registry.test.ts | 66 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/registry.test.ts diff --git a/package.json b/package.json index 102b607..3488a56 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": "jest --passWithNoTests", + "test": "jest", "lint": "eslint .", "lint:fix": "eslint . --fix", "db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js", diff --git a/tests/registry.test.ts b/tests/registry.test.ts new file mode 100644 index 0000000..71d80db --- /dev/null +++ b/tests/registry.test.ts @@ -0,0 +1,66 @@ +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 55e3f5e5dd14607ee2725d44e1404622a3d3c8ba Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 26 Jul 2024 18:32:12 +0100 Subject: [PATCH 10/94] Document how to start the bot (#322) - Add documentation on how to start the bot #81 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/322 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- README.md | 60 ++++++++++++++++++++++++- docs/cards.md | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 docs/cards.md diff --git a/README.md b/README.md index 94f0c9c..ca4b03f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,60 @@ -# card-drop +# Card Drop + +Card Drop is a Discord Bot designed to allow users to "drop" random cards into +a channel and have the ability to claim them for themselves or let others if +they so choose. + +The cards are randomly chosen based on weights of their card type (i.e. Bronze +is more common than Gold). The user who ran the drop command has 5 minutes to +choose if they want the card to themselves before its claimable by anyone, or +until the drop command is ran again. + +## Installation + +Downloads of the latest version can be found from the [GitHub Releases](https://github.com/vylpes/card-drop/releases) +or [Forgejo Releases](https://git.vylpes.xyz/external/card-drop/releases) page. + +Copy the config template file and fill in the strings. + +## Requirements + +- NodeJS +- Yarn +- Docker + +## Usage + +Install the dependencies and build the app: + +```bash +yarn Install +yarn build +``` + +Setup the database (Recommended to use the docker-compose file + +```bash +docker compose up -d +``` + +Copy and edit the settings file + +```bash +cp .env.template .env +``` + +> **NOTE:** Make sure you do *not* check in these files! These contain +sensitive information and should be treated as private. + +If you're not using `DB_SYNC=true` in `.env`, make sure to migrate the database + +```bash +yarn db:up +``` + +Start the bot + +```bash +yarn start +``` diff --git a/docs/cards.md b/docs/cards.md new file mode 100644 index 0000000..f0be28f --- /dev/null +++ b/docs/cards.md @@ -0,0 +1,120 @@ +# Cards + +This document will describe how to add cards to the bot. This is from the +perspective of the development side and doesn't go into details of syncing +from an external place such as with the Google Drive Sync function. + +The cards will be put into the `$DATA_DIR/cards` folder. `$DATA_DIR` is +configured in the `.env` file. + +## Folder Structure + +The general structure of the cards folder is as follows: + +``` +cards # The main cards folder +| Series 1 # Series folder +| | BRONZE # Type folder +| | | 1000.jpg # Card image +| | | 1001.jpg +| | 1.json # Card metadata file +| Series 2 +| | SILVER +| | | 2000.jpg +| | 2.json +``` + +- The root of the cards folder will have a folder foor each series +- Each series will contain folders for each of the card types containing the + card images. +- The series folder will also contain a metadata JSON folder containing the + metadata of the cards within that series. + +The bot when loading will search the cards folder recursively for each json, +and then read them to determine what cards should be used for the bot. + +## Series Metadata + +An example of what the metadata files could look like are as follows: + +```json +[ + { + "id": 1, + "name": "Series 1", + "cards": [ + { + "id": "1000", + "name": "Card 1000 of Series 1", + "type": 1, + "path": "Series 1/BRONZE/1000.jpg" + }, + { + "id": "1001", + "name": "Card 1001 of Series 1", + "type": 1, + "path": "Series 2/BRONZE?1001.jpg", + "subseries": "Custom Series Name" + } + ] + } +] +``` + +This file will load a series called "Series 1" with the id of 1, containing 2 +cards: +- Card 1000, with type 1 (Bronze), with its image located at (from root) + "Series 1/BRONZE/1000.jpg" +- Card 1001 is the same, except has a custom "subseries" name which will + override the main series name if shown, helpful for an "other" category. + +### Card Type + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NumberNameChanceSacrifice Cost (Coins)
0Unknown--
1Bronze62%5
2Silver31%10
3Gold4.4%30
4Manga2%40
5Legendary0.6%100
From a290eb945aaf83b53e09e2b1094c38fd586e1217 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 27 Jul 2024 16:03:42 +0100 Subject: [PATCH 11/94] 0.8.0 --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 009d99c..00a861f 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=0.7.0 +BOT_VER=0.8.0 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=682942374040961060 From f7a7a3781a8951157691dd241bd5168157e9ed0e Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 27 Jul 2024 16:06:21 +0100 Subject: [PATCH 12/94] Remove tests for now --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3488a56..f67d12f 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": "jest", + "test": "echo true", "lint": "eslint .", "lint:fix": "eslint . --fix", "db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js", From 6025e2b269560f059d9810da32c6b084d0464168 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 27 Jul 2024 16:06:26 +0100 Subject: [PATCH 13/94] v0.8.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f67d12f..9126a28 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "card-drop", - "version": "0.7.0", + "version": "0.8.0", "main": "./dist/bot.js", "typings": "./dist", "scripts": { @@ -50,7 +50,7 @@ "winston-discord-transport": "^1.3.0" }, "resolutions": { - "**/ws": "^8.17.1" + "**/ws": "^8.17.1" }, "devDependencies": { "@types/node": "^20.0.0", From bf9b748f4f1102fc2e0675e4a1cb3c08acf6e858 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 29 Jul 2024 18:18:11 +0100 Subject: [PATCH 14/94] 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 15/94] 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 16/94] 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 17/94] 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 18/94] 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 19/94] 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 20/94] 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 21/94] 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 22/94] 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 23/94] 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 24/94] 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 25/94] 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 26/94] 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 27/94] 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 28/94] 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 29/94] 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 a10eaf7d751eb3aa9ffee29edf1af0f4d89cbe79 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Thu, 29 Aug 2024 18:53:09 +0100 Subject: [PATCH 30/94] Make the rarity text on the series embed lower case To be more consistent with the inventory command #348 --- src/helpers/SeriesHelper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/SeriesHelper.ts b/src/helpers/SeriesHelper.ts index c3a22d6..5469938 100644 --- a/src/helpers/SeriesHelper.ts +++ b/src/helpers/SeriesHelper.ts @@ -31,7 +31,7 @@ export default class SeriesHelper { const cardsOnPage = series.cards.splice(page * itemsPerPage, itemsPerPage); const description = cardsOnPage - .map(x => `[${x.id}] ${x.name} ${CardRarityToString(x.type).toUpperCase()}`) + .map(x => `[${x.id}] ${x.name} (${CardRarityToString(x.type)})`) .join("\n"); const embed = new EmbedBuilder() From 5deb6fcc1488a7b8d17edd401eb7f8df72ad9490 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Thu, 29 Aug 2024 19:21:53 +0100 Subject: [PATCH 31/94] Add a colour override for embed colours - Using a new optional value in the JSON, if set overrides the default one set by the rarity - Added a failsafe if the override colour is invalid to default and log a warning #349 --- src/contracts/SeriesMetadata.ts | 1 + src/helpers/CardDropHelperMetadata.ts | 16 +++++++++++++++- src/helpers/StringTools.ts | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/contracts/SeriesMetadata.ts b/src/contracts/SeriesMetadata.ts index 4a989bc..4dd2eb9 100644 --- a/src/contracts/SeriesMetadata.ts +++ b/src/contracts/SeriesMetadata.ts @@ -12,6 +12,7 @@ export interface CardMetadata { type: CardRarity, path: string, subseries?: string, + colour?: string, } export interface DropResult { diff --git a/src/helpers/CardDropHelperMetadata.ts b/src/helpers/CardDropHelperMetadata.ts index 84bcdfa..bc59e93 100644 --- a/src/helpers/CardDropHelperMetadata.ts +++ b/src/helpers/CardDropHelperMetadata.ts @@ -5,6 +5,7 @@ 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 { @@ -82,12 +83,25 @@ export default class CardDropHelperMetadata { 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}`); + } const embed = new EmbedBuilder() .setTitle(drop.card.name) .setDescription(description) .setFooter({ text: `${CardRarityToString(drop.card.type)} · ${drop.card.id}` }) - .setColor(CardRarityToColour(drop.card.type)) + .setColor(colour) .setImage(`attachment://${imageFileName}`) .addFields([ { diff --git a/src/helpers/StringTools.ts b/src/helpers/StringTools.ts index cb5591a..1e43ded 100644 --- a/src/helpers/StringTools.ts +++ b/src/helpers/StringTools.ts @@ -39,4 +39,18 @@ export default class StringTools { public static ReplaceAll(str: string, find: string, replace: string) { return str.replace(new RegExp(find, "g"), replace); } + + public static IsHexCode(str: string): boolean { + if (str.length != 6) return false; + + const characters = "0123456789abcdefABCDEF"; + + for (let i = 0; i < 6; i++) { + const char = str[i]; + + if (!characters.includes(char)) return false; + } + + return true; + } } \ No newline at end of file From e8b20004bd7fdf88e60c311abed9647904401f3a Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 30 Aug 2024 18:47:04 +0100 Subject: [PATCH 32/94] Create an admin command to give a breakdown of card stats - Created a command for admins to see what cards have been added by type - Added this information to the logger #350 --- src/Functions/CardMetadataFunction.ts | 18 +++++++++- src/commands/stats.ts | 51 +++++++++++++++++++++++++++ src/registry.ts | 2 ++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/commands/stats.ts diff --git a/src/Functions/CardMetadataFunction.ts b/src/Functions/CardMetadataFunction.ts index a2499d9..9b10665 100644 --- a/src/Functions/CardMetadataFunction.ts +++ b/src/Functions/CardMetadataFunction.ts @@ -5,6 +5,7 @@ import { glob } from "glob"; import { SeriesMetadata } from "../contracts/SeriesMetadata"; import { CoreClient } from "../client/client"; import AppLogger from "../client/appLogger"; +import {CardRarity} from "../constants/CardRarity"; export interface CardMetadataResult { IsSuccess: boolean; @@ -37,7 +38,22 @@ export default class CardMetadataFunction { if (cardResult.IsSuccess) { CoreClient.Cards = cardResult.Result!; - AppLogger.LogInfo("Functions/CardMetadataFunction", `Loaded ${CoreClient.Cards.flatMap(x => x.cards).length} cards to database`); + + const allCards = CoreClient.Cards.flatMap(x => x.cards); + + const totalCards = allCards.length; + const bronzeCards = allCards.filter(x => x.type == CardRarity.Bronze) + .length; + const silverCards = allCards.filter(x => x.type == CardRarity.Silver) + .length; + const goldCards = allCards.filter(x => x.type == CardRarity.Gold) + .length; + const mangaCards = allCards.filter(x => x.type == CardRarity.Manga) + .length; + const legendaryCards = allCards.filter(x => x.type == CardRarity.Legendary) + .length; + + AppLogger.LogInfo("Functions/CardMetadataFunction", `Loaded ${totalCards} cards to database (${bronzeCards} bronze, ${silverCards} silver, ${goldCards} gold, ${mangaCards} manga, ${legendaryCards} legendary)`); const duplicateCards = CoreClient.Cards.flatMap(x => x.cards) .filter((card, index, self) => self.findIndex(c => c.id === card.id) !== index); diff --git a/src/commands/stats.ts b/src/commands/stats.ts new file mode 100644 index 0000000..e65ab93 --- /dev/null +++ b/src/commands/stats.ts @@ -0,0 +1,51 @@ +import {CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder} from "discord.js"; +import {Command} from "../type/command"; +import {CoreClient} from "../client/client"; +import {CardRarity} from "../constants/CardRarity"; +import EmbedColours from "../constants/EmbedColours"; + +export default class Stats extends Command { + constructor() { + super(); + + this.CommandBuilder = new SlashCommandBuilder() + .setName("stats") + .setDescription("Get bot stats such as card info") + .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator); + } + + public override async execute(interaction: CommandInteraction) { + const allCards = CoreClient.Cards.flatMap(x => x.cards); + + const totalCards = allCards.length; + const bronzeCards = allCards.filter(x => x.type == CardRarity.Bronze) + .length; + const silverCards = allCards.filter(x => x.type == CardRarity.Silver) + .length; + const goldCards = allCards.filter(x => x.type == CardRarity.Gold) + .length; + const mangaCards = allCards.filter(x => x.type == CardRarity.Manga) + .length; + const legendaryCards = allCards.filter(x => x.type == CardRarity.Legendary) + .length; + + const description = [ + `${totalCards} Total`, + `${bronzeCards} Bronze`, + `${silverCards} Silver`, + `${goldCards} Gold`, + `${mangaCards} Manga`, + `${legendaryCards} Legendary`, + ].join("\n"); + + const embed = new EmbedBuilder() + .setTitle("Stats") + .setDescription(description) + .setColor(EmbedColours.Ok); + + await interaction.reply({ + embeds: [ embed ], + ephemeral: true, + }); + } +} diff --git a/src/registry.ts b/src/registry.ts index 86b2b68..5ba3af6 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -13,6 +13,7 @@ import Inventory from "./commands/inventory"; import Resync from "./commands/resync"; import Sacrifice from "./commands/sacrifice"; import Series from "./commands/series"; +import Stats from "./commands/stats"; import Trade from "./commands/trade"; import View from "./commands/view"; @@ -42,6 +43,7 @@ export default class Registry { CoreClient.RegisterCommand("resync", new Resync()); CoreClient.RegisterCommand("sacrifice", new Sacrifice()); CoreClient.RegisterCommand("series", new Series()); + CoreClient.RegisterCommand("stats", new Stats()); CoreClient.RegisterCommand("trade", new Trade()); CoreClient.RegisterCommand("view", new View()); From 93b12bbbf6b1da8bc5cb14e5df245fc14cee52cd Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 31 Aug 2024 13:37:16 +0100 Subject: [PATCH 33/94] 0.8.1 --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 00a861f..8f1bfc6 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=0.8.0 +BOT_VER=0.8.1 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=682942374040961060 From 65a55895e75ac548bba6516c179ca2ef2fe309ed Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 31 Aug 2024 13:37:22 +0100 Subject: [PATCH 34/94] v0.8.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9126a28..292f0c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "card-drop", - "version": "0.8.0", + "version": "0.8.1", "main": "./dist/bot.js", "typings": "./dist", "scripts": { From 761c58fb106b4cd907851d42abaf8682d70dcbfd Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 31 Aug 2024 17:59:56 +0100 Subject: [PATCH 35/94] 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 36/94] 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 37/94] 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 38/94] 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 39/94] 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 40/94] 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 41/94] 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 42/94] 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 43/94] 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 44/94] 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 45/94] 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 46/94] 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 47/94] 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 48/94] 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 49/94] 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 50/94] 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 51/94] 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 ffdf2eb04c07c6d26fe79832a0e363cf3b7b5937 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 12 Oct 2024 20:51:22 +0100 Subject: [PATCH 52/94] Fix Trade command not giving a card if they don't already have it in their inventory --- src/buttonEvents/Trade.ts | 12 ++++++------ src/database/entities/app/Inventory.ts | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/buttonEvents/Trade.ts b/src/buttonEvents/Trade.ts index d0d7b38..ef0d1c5 100644 --- a/src/buttonEvents/Trade.ts +++ b/src/buttonEvents/Trade.ts @@ -72,8 +72,8 @@ export default class Trade extends ButtonEvent { return; } - user1UserInventory1.SetQuantity(user1UserInventory1.Quantity - 1); - user2UserInventory1.SetQuantity(user2UserInventory1.Quantity - 1); + user1UserInventory1.RemoveQuantity(1); + user2UserInventory1.RemoveQuantity(1); await user1UserInventory1.Save(Inventory, user1UserInventory1); await user2UserInventory1.Save(Inventory, user2UserInventory1); @@ -82,15 +82,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, 1); } else { - user1UserInventory2.SetQuantity(user1UserInventory2.Quantity + 1); + user1UserInventory2.AddQuantity(1); } if (!user2UserInventory2) { - user2UserInventory2 = new Inventory(user2UserId, user2CardNumber, 1); + user2UserInventory2 = new Inventory(user2UserId, user1CardNumber, 1); } else { - user2UserInventory2.SetQuantity(user2UserInventory2.Quantity + 1); + user2UserInventory2.AddQuantity(1); } await user1UserInventory2.Save(Inventory, user1UserInventory2); diff --git a/src/database/entities/app/Inventory.ts b/src/database/entities/app/Inventory.ts index 7d659fe..469cbdc 100644 --- a/src/database/entities/app/Inventory.ts +++ b/src/database/entities/app/Inventory.ts @@ -29,6 +29,10 @@ 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 2b3649eb395e84c4f7b80bb2177959d2600a9579 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 12 Oct 2024 20:52:24 +0100 Subject: [PATCH 53/94] 0.8.2 --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 8f1bfc6..4515de6 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=0.8.1 +BOT_VER=0.8.2 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=682942374040961060 From f812467f5e6e27dd2322fe9b213c7367ecffc43a Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 12 Oct 2024 20:53:05 +0100 Subject: [PATCH 54/94] v0.8.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 292f0c6..69f3158 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "card-drop", - "version": "0.8.1", + "version": "0.8.2", "main": "./dist/bot.js", "typings": "./dist", "scripts": { From 73caf9315d90277e3db2e4cf040c1179b4cd539b Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 12 Oct 2024 20:56:13 +0100 Subject: [PATCH 55/94] 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 56/94] 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 57/94] 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 58/94] 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 59/94] 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 60/94] 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 61/94] 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 62/94] 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 63/94] 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 c4abf21013d02aa43140a6ee5b714bff681cd497 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 10 Dec 2024 10:39:24 +0000 Subject: [PATCH 64/94] Use rsync -rvzP --- .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 1dd774e..d939ef7 100644 --- a/.forgejo/workflows/production.yml +++ b/.forgejo/workflows/production.yml @@ -23,7 +23,7 @@ jobs: - run: yarn lint - name: "Copy files over to location" - run: cp -r . ${{ secrets.PROD_REPO_PATH }} + run: rsync -rvzP . ${{ secrets.PROD_REPO_PATH }} deploy: environment: prod diff --git a/.forgejo/workflows/stage.yml b/.forgejo/workflows/stage.yml index 8903a70..51b5fb9 100644 --- a/.forgejo/workflows/stage.yml +++ b/.forgejo/workflows/stage.yml @@ -23,7 +23,7 @@ jobs: - run: yarn lint - name: "Copy files over to location" - run: cp -r . ${{ secrets.STAGE_REPO_PATH }} + run: rsync -rvzP . ${{ secrets.STAGE_REPO_PATH }} deploy: environment: prod From 5db7cd9f11527ca5b71bc4176caf33750c4e7902 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 10 Dec 2024 10:57:50 +0000 Subject: [PATCH 65/94] 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 66/94] 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 67/94] 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 d9d0243c3c3e31e465434ff9663c8f6dd739b47e Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 10 Dec 2024 11:07:55 +0000 Subject: [PATCH 68/94] Use node 20 --- .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 d939ef7..110f5e8 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 51b5fb9..149a78e 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 From b8623398a61d2b51b4bc31dd5091dbd665e2abad Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 19 Jan 2025 15:07:40 +0000 Subject: [PATCH 69/94] Implement ability to add images in the drop via an external url --- src/buttonEvents/Reroll.ts | 15 +++++++++++---- src/commands/drop.ts | 15 +++++++++++---- src/commands/stage/dropnumber.ts | 20 ++++++++++---------- src/commands/stage/droprarity.ts | 22 ++++++++++------------ src/commands/view.ts | 20 +++++++++----------- src/helpers/CardDropHelperMetadata.ts | 10 ++++++++-- 6 files changed, 59 insertions(+), 43 deletions(-) diff --git a/src/buttonEvents/Reroll.ts b/src/buttonEvents/Reroll.ts index 12578db..dc9622a 100644 --- a/src/buttonEvents/Reroll.ts +++ b/src/buttonEvents/Reroll.ts @@ -51,10 +51,17 @@ export default class Reroll extends ButtonEvent { try { AppLogger.LogVerbose("Button/Reroll", `Sending next drop: ${randomCard.card.id} (${randomCard.card.name})`); - const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path)); - const imageFileName = randomCard.card.path.split("/").pop()!; + const files = []; + let imageFileName = ""; - const attachment = new AttachmentBuilder(image, { name: imageFileName }); + if (!(randomCard.card.path.startsWith("http://") || randomCard.card.path.startsWith("https://"))) { + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path)); + imageFileName = randomCard.card.path.split("/").pop()!; + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + files.push(attachment); + } const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; @@ -67,7 +74,7 @@ export default class Reroll extends ButtonEvent { await interaction.editReply({ embeds: [ embed ], - files: [ attachment ], + files: files, components: [ row ], }); diff --git a/src/commands/drop.ts b/src/commands/drop.ts index 6f74d3a..66558e3 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -59,10 +59,17 @@ export default class Drop extends Command { 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 files = []; + let imageFileName = ""; - const attachment = new AttachmentBuilder(image, { name: imageFileName }); + if (!(randomCard.card.path.startsWith("http://") || randomCard.card.path.startsWith("https://"))) { + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path)); + imageFileName = randomCard.card.path.split("/").pop()!; + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + files.push(attachment); + } const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; @@ -75,7 +82,7 @@ export default class Drop extends Command { await interaction.editReply({ embeds: [ embed ], - files: [ attachment ], + files: files, components: [ row ], }); diff --git a/src/commands/stage/dropnumber.ts b/src/commands/stage/dropnumber.ts index 0642327..750210d 100644 --- a/src/commands/stage/dropnumber.ts +++ b/src/commands/stage/dropnumber.ts @@ -43,20 +43,20 @@ export default class Dropnumber 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 { - await interaction.reply(`Unable to fetch image for card ${card.id}`); - return; + 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()!; + + 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; @@ -69,7 +69,7 @@ export default class Dropnumber extends Command { try { await interaction.editReply({ embeds: [ embed ], - files: [ attachment ], + files: files, components: [ row ], }); } catch (e) { diff --git a/src/commands/stage/droprarity.ts b/src/commands/stage/droprarity.ts index be0a62d..0e95db0 100644 --- a/src/commands/stage/droprarity.ts +++ b/src/commands/stage/droprarity.ts @@ -46,20 +46,18 @@ export default class Droprarity extends Command { return; } - let image: Buffer; - const imageFileName = card.card.path.split("/").pop()!; + const files = []; + let imageFileName = ""; - try { - image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.card.path)); - } catch { - await interaction.reply(`Unable to fetch image for card ${card.card.id}`); - return; + if (!(card.card.path.startsWith("http://") || card.card.path.startsWith("https://"))) { + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.card.path)); + imageFileName = card.card.path.split("/").pop()!; + + 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.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; @@ -72,7 +70,7 @@ export default class Droprarity extends Command { try { await interaction.editReply({ embeds: [ embed ], - files: [ attachment ], + files: files, components: [ row ], }); } catch (e) { diff --git a/src/commands/view.ts b/src/commands/view.ts index ce6f9cb..0e29db5 100644 --- a/src/commands/view.ts +++ b/src/commands/view.ts @@ -43,22 +43,20 @@ export default class View 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 View 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}`); diff --git a/src/helpers/CardDropHelperMetadata.ts b/src/helpers/CardDropHelperMetadata.ts index bc59e93..342f347 100644 --- a/src/helpers/CardDropHelperMetadata.ts +++ b/src/helpers/CardDropHelperMetadata.ts @@ -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}`); } @@ -97,12 +97,18 @@ export default class CardDropHelperMetadata { 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(`attachment://${imageFileName}`) + .setImage(imageUrl) .addFields([ { name: "Claimed", From c53e09f510fc5968ef6bff765d61c8bf730ed083 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 19 Jan 2025 15:09:17 +0000 Subject: [PATCH 70/94] 0.8.3 --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 4515de6..44016d2 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=0.8.2 +BOT_VER=0.8.3 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=682942374040961060 From ce0bc15c029d9b37138a60cae4b2fe9db9f4e719 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 19 Jan 2025 15:11:41 +0000 Subject: [PATCH 71/94] v0.8.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 69f3158..d7178df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "card-drop", - "version": "0.8.2", + "version": "0.8.3", "main": "./dist/bot.js", "typings": "./dist", "scripts": { From 3e81f8ce1d4b01fb5fc4e4ee710b5ed95fa34202 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 19 Jan 2025 15:19:28 +0000 Subject: [PATCH 72/94] 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 73/94] 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 74/94] 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 75/94] 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 ad34cc7b7f6b90ef71da900778e1945ea1b4daa9 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 20 Apr 2025 10:52:54 +0100 Subject: [PATCH 76/94] Fix remote image urls not showing up in image grids (#430) - Update the Image Grid helper to download images that are urls instead of trying (and failing) to load them locally #425 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/430 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- .forgejo/workflows/test.yml | 2 +- package.json | 3 +- src/helpers/ImageHelper.ts | 21 +- yarn.lock | 748 +++++++++++++++++++----------------- 4 files changed, 424 insertions(+), 350 deletions(-) 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 diff --git a/package.json b/package.json index d7178df..69ff2a9 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@types/express": "^4.17.20", "@types/jest": "^29.0.0", "@types/uuid": "^9.0.0", + "axios": "^1.8.4", "body-parser": "^1.20.2", "canvas": "^2.11.2", "clone-deep": "^4.0.1", @@ -40,7 +41,7 @@ "glob": "^10.3.10", "jest": "^29.0.0", "jest-mock-extended": "^3.0.0", - "jimp": "^0.22.12", + "jimp": "^1.6.0", "minimatch": "9.0.5", "mysql": "^2.18.1", "ts-jest": "^29.0.0", diff --git a/src/helpers/ImageHelper.ts b/src/helpers/ImageHelper.ts index be3d083..79c1c6b 100644 --- a/src/helpers/ImageHelper.ts +++ b/src/helpers/ImageHelper.ts @@ -3,7 +3,8 @@ 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 { Bitmap, Jimp } from "jimp"; +import axios from "axios"; interface CardInput { id: string; @@ -29,14 +30,24 @@ export default class ImageHelper { const filePath = path.join(process.env.DATA_DIR!, "cards", card.path); - const exists = existsSync(filePath); + let bitmap: Bitmap; - if (!exists) { + if (existsSync(filePath)) { + const data = await Jimp.read(filePath); + + bitmap = data.bitmap; + } else if (card.path.startsWith("http://") || card.path.startsWith("https://")) { + const response = await axios.get(card.path, { responseType: "arraybuffer" }); + const buffer = Buffer.from(response.data); + const data = await Jimp.fromBuffer(buffer); + + bitmap = data.bitmap; + } else { AppLogger.LogError("ImageHelper/GenerateCardImageGrid", `Failed to load image from path ${card.path}`); continue; } - const imageData = await Jimp.read(filePath); + const imageData = Jimp.fromBitmap(bitmap); if (userId != null) { const claimed = await Inventory.FetchOneByCardNumberAndUserId(userId, card.id); @@ -46,7 +57,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 b953c94..23f0771 100644 --- a/yarn.lock +++ b/yarn.lock @@ -666,262 +666,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" @@ -1676,6 +1692,20 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +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== + +axios@^1.8.4: + version "1.8.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.4.tgz#78990bb4bc63d2cae072952d374835950a82f447" + integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -1765,10 +1795,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.2, body-parser@^1.20.2: version "1.20.2" @@ -1855,17 +1885,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== @@ -1934,6 +1959,14 @@ cacheable-request@^7.0.2: normalize-url "^6.0.1" responselike "^2.0.0" +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + call-bind@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" @@ -1984,13 +2017,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" @@ -2560,11 +2586,6 @@ doctrine@^3.0.0: 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" @@ -2584,6 +2605,15 @@ dotenv@^16.0.0, dotenv@^16.0.3: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -2650,11 +2680,33 @@ es-define-property@^1.0.0: dependencies: get-intrinsic "^1.2.4" +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + es-errors@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + dependencies: + es-errors "^1.3.0" + +es-set-tostringtag@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" + integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== + dependencies: + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + has-tostringtag "^1.0.2" + hasown "^2.0.2" + escalade@^3.1.1, escalade@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" @@ -2998,7 +3050,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== @@ -3094,6 +3146,16 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.2.tgz#35cabbdd30c3ce73deb2c42d3c8d3ed9ca51794c" + integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + es-set-tostringtag "^2.1.0" + mime-types "^2.1.12" + formidable@^1.2.1: version "1.2.6" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.6.tgz#d2a51d60162bbc9b4a055d8457a7c75315d1a168" @@ -3167,11 +3229,35 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: has-symbols "^1.0.3" hasown "^2.0.0" +get-intrinsic@^1.2.6: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -3254,14 +3340,6 @@ global-dirs@^3.0.0: 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" @@ -3304,6 +3382,11 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + got@^11.8.5: version "11.8.6" resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" @@ -3387,6 +3470,18 @@ has-symbols@^1.0.3: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + +has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -3397,7 +3492,7 @@ has-yarn@^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== @@ -3698,11 +3793,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" @@ -3875,14 +3965,6 @@ 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" @@ -4315,15 +4397,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" @@ -4481,20 +4586,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" @@ -4657,6 +4748,11 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -4707,11 +4803,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" @@ -4757,13 +4858,6 @@ mimic-response@^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" @@ -4908,7 +5002,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== @@ -5061,7 +5155,7 @@ object-inspect@^1.13.1: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== -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== @@ -5278,17 +5372,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== @@ -5296,11 +5390,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" @@ -5409,13 +5498,6 @@ 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, picocolors@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" @@ -5431,12 +5513,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" @@ -5452,16 +5534,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" @@ -5481,11 +5563,6 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -process@^0.11.10: - version "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" @@ -5512,6 +5589,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -5671,11 +5753,6 @@ 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" @@ -5984,6 +6061,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" @@ -6335,11 +6417,6 @@ 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" @@ -6604,7 +6681,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== @@ -6679,11 +6756,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" @@ -6848,16 +6920,6 @@ xdg-basedir@^5.0.1, xdg-basedir@^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" @@ -6876,11 +6938,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" @@ -6936,3 +6993,8 @@ 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== + +zod@^3.23.8: + version "3.24.3" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.3.tgz#1f40f750a05e477396da64438e0e1c0995dafd87" + integrity sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg== From 9b34bc65a75793b41a5bbb65c25079a952990747 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 22 Apr 2025 15:12:10 +0100 Subject: [PATCH 77/94] Fix droprarity and dropnumber commands (#431) - Fix the droprarity and dropnumber commands with the changes previously made regarding image urls - Add a `CatchError` function to the app logger to easily send caught errors to the error logs - Add choices to the droprarity command to make them easier to select #429 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/431 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/client/appLogger.ts | 8 +++++ src/commands/stage/dropnumber.ts | 51 ++++++++++++++-------------- src/commands/stage/droprarity.ts | 57 ++++++++++++++++---------------- src/constants/CardRarity.ts | 23 +++++++++++++ 4 files changed, 83 insertions(+), 56 deletions(-) diff --git a/src/client/appLogger.ts b/src/client/appLogger.ts index f1ba1dc..6c33609 100644 --- a/src/client/appLogger.ts +++ b/src/client/appLogger.ts @@ -86,4 +86,12 @@ export default class AppLogger { public static LogSilly(label: string, message: string) { AppLogger.Logger.silly({ label, message }); } + + public static CatchError(label: string, error: unknown) { + if (error instanceof Error) { + AppLogger.Logger.error({ label, message: error.message }); + } else { + AppLogger.Logger.error({ label, message: error }); + } + } } diff --git a/src/commands/stage/dropnumber.ts b/src/commands/stage/dropnumber.ts index 750210d..caeccd0 100644 --- a/src/commands/stage/dropnumber.ts +++ b/src/commands/stage/dropnumber.ts @@ -1,4 +1,4 @@ -import { AttachmentBuilder, CacheType, CommandInteraction, DiscordAPIError, SlashCommandBuilder } from "discord.js"; +import { AttachmentBuilder, CacheType, CommandInteraction, SlashCommandBuilder } from "discord.js"; import { Command } from "../../type/command"; import { readFileSync } from "fs"; import Inventory from "../../database/entities/app/Inventory"; @@ -6,6 +6,7 @@ import { v4 } from "uuid"; import { CoreClient } from "../../client/client"; import path from "path"; import CardDropHelperMetadata from "../../helpers/CardDropHelperMetadata"; +import AppLogger from "../../client/appLogger"; export default class Dropnumber extends Command { constructor() { @@ -43,43 +44,39 @@ export default class Dropnumber extends Command { const series = CoreClient.Cards .find(x => x.cards.includes(card))!; - const files = []; - let imageFileName = ""; + const claimId = v4(); - 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()!; - - const attachment = new AttachmentBuilder(image, { name: imageFileName }); - - files.push(attachment); - } await interaction.deferReply(); - 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 claimId = v4(); - - const row = CardDropHelperMetadata.GenerateDropButtons({ card, series }, claimId, interaction.user.id); - try { + const files = []; + let imageFileName = ""; + + 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()!; + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + files.push(attachment); + } + + 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 row = CardDropHelperMetadata.GenerateDropButtons({ card, series }, claimId, interaction.user.id); + await interaction.editReply({ embeds: [ embed ], files: files, components: [ row ], }); } catch (e) { - console.error(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"); - } + 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; diff --git a/src/commands/stage/droprarity.ts b/src/commands/stage/droprarity.ts index 0e95db0..cf2eded 100644 --- a/src/commands/stage/droprarity.ts +++ b/src/commands/stage/droprarity.ts @@ -1,12 +1,13 @@ -import { AttachmentBuilder, CacheType, CommandInteraction, DiscordAPIError, SlashCommandBuilder } from "discord.js"; +import { AttachmentBuilder, CacheType, CommandInteraction, SlashCommandBuilder } from "discord.js"; import { Command } from "../../type/command"; -import { CardRarity, CardRarityParse } from "../../constants/CardRarity"; +import { CardRarity, CardRarityChoices, CardRarityParse } from "../../constants/CardRarity"; 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 AppLogger from "../../client/appLogger"; export default class Droprarity extends Command { constructor() { @@ -19,7 +20,8 @@ export default class Droprarity extends Command { x .setName("rarity") .setDescription("The rarity you want to summon") - .setRequired(true)); + .setRequired(true) + .setChoices(CardRarityChoices)); } public override async execute(interaction: CommandInteraction) { @@ -39,48 +41,45 @@ export default class Droprarity extends Command { return; } - const card = await CardDropHelperMetadata.GetRandomCardByRarity(rarityType); + const card = CardDropHelperMetadata.GetRandomCardByRarity(rarityType); if (!card) { await interaction.reply("Card not found"); return; } - const files = []; - let imageFileName = ""; - - if (!(card.card.path.startsWith("http://") || card.card.path.startsWith("https://"))) { - const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.card.path)); - imageFileName = card.card.path.split("/").pop()!; - - const attachment = new AttachmentBuilder(image, { name: imageFileName }); - - files.push(attachment); - } - - 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 claimId = v4(); - const row = CardDropHelperMetadata.GenerateDropButtons(card, claimId, interaction.user.id); + await interaction.deferReply(); try { + const files = []; + let imageFileName = ""; + + if (!(card.card.path.startsWith("http://") || card.card.path.startsWith("https://"))) { + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.card.path)); + imageFileName = card.card.path.split("/").pop()!; + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + files.push(attachment); + } + + 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 row = CardDropHelperMetadata.GenerateDropButtons(card, claimId, interaction.user.id); + await interaction.editReply({ embeds: [ embed ], files: files, components: [ row ], }); } catch (e) { - console.error(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"); - } + 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; diff --git a/src/constants/CardRarity.ts b/src/constants/CardRarity.ts index 8817172..0fcdec7 100644 --- a/src/constants/CardRarity.ts +++ b/src/constants/CardRarity.ts @@ -9,6 +9,29 @@ export enum CardRarity { Legendary, } +export const CardRarityChoices = [ + { + name: "Bronze", + value: "bronze", + }, + { + name: "Silver", + value: "silver", + }, + { + name: "Gold", + value: "gold", + }, + { + name: "Manga", + value: "manga", + }, + { + name: "Legendary", + value: "legendary", + }, +]; + export function CardRarityToString(rarity: CardRarity): string { switch (rarity) { case CardRarity.Unknown: From 51a8e177aea51090a4f87f1423a5507555eb8ec5 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 22 Apr 2025 15:13:33 +0100 Subject: [PATCH 78/94] 0.8.4 --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 44016d2..dc7d96e 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=0.8.3 +BOT_VER=0.8.4 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=682942374040961060 From 211ef74410b31f5b5e433c762550df331835b29a Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 22 Apr 2025 15:21:19 +0100 Subject: [PATCH 79/94] v0.8.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 69ff2a9..0e0ce30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "card-drop", - "version": "0.8.3", + "version": "0.8.4", "main": "./dist/bot.js", "typings": "./dist", "scripts": { From 1796f2519e03055ba18275f84d1d07a7725fc466 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Tue, 22 Apr 2025 16:12:04 +0100 Subject: [PATCH 80/94] Add error handler to series view command --- src/commands/series.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/commands/series.ts b/src/commands/series.ts index e268db9..16ae0db 100644 --- a/src/commands/series.ts +++ b/src/commands/series.ts @@ -60,13 +60,18 @@ export default class Series extends Command { return; } - const embed = await SeriesHelper.GenerateSeriesViewPage(series.id, 0, interaction.user.id); + try { + const embed = await SeriesHelper.GenerateSeriesViewPage(series.id, 0, interaction.user.id); - await interaction.followUp({ - embeds: [ embed!.embed ], - components: [ embed!.row ], - files: [ embed!.image ], - }); + await interaction.followUp({ + embeds: [ embed!.embed ], + components: [ embed!.row ], + files: [ embed!.image ], + }); + } catch (e) { + await interaction.followUp("An error has occured generating the series grid."); + AppLogger.CatchError("Series", e); + } } private async ListSeries(interaction: CommandInteraction) { From 659906e562e796b7a5f31b6a22b7738f4dfd2861 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Wed, 23 Apr 2025 10:40:06 +0100 Subject: [PATCH 81/94] Add catch to image grid generator --- src/helpers/ImageHelper.ts | 71 ++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/src/helpers/ImageHelper.ts b/src/helpers/ImageHelper.ts index 79c1c6b..163c8ec 100644 --- a/src/helpers/ImageHelper.ts +++ b/src/helpers/ImageHelper.ts @@ -26,46 +26,51 @@ export default class ImageHelper { const ctx = canvas.getContext("2d"); for (let i = 0; i < cards.length; i++) { - const card = cards[i]; + try { + const card = cards[i]; - const filePath = path.join(process.env.DATA_DIR!, "cards", card.path); + const filePath = path.join(process.env.DATA_DIR!, "cards", card.path); - let bitmap: Bitmap; + let bitmap: Bitmap; - if (existsSync(filePath)) { - const data = await Jimp.read(filePath); + if (existsSync(filePath)) { + const data = await Jimp.read(filePath); - bitmap = data.bitmap; - } else if (card.path.startsWith("http://") || card.path.startsWith("https://")) { - const response = await axios.get(card.path, { responseType: "arraybuffer" }); - const buffer = Buffer.from(response.data); - const data = await Jimp.fromBuffer(buffer); + bitmap = data.bitmap; + } else if (card.path.startsWith("http://") || card.path.startsWith("https://")) { + const response = await axios.get(card.path, { responseType: "arraybuffer" }); + const buffer = Buffer.from(response.data); + const data = await Jimp.fromBuffer(buffer); - bitmap = data.bitmap; - } else { - AppLogger.LogError("ImageHelper/GenerateCardImageGrid", `Failed to load image from path ${card.path}`); - continue; - } - - const imageData = Jimp.fromBitmap(bitmap); - - if (userId != null) { - const claimed = await Inventory.FetchOneByCardNumberAndUserId(userId, card.id); - - if (!claimed || claimed.Quantity == 0) { - imageData.greyscale(); + bitmap = data.bitmap; + } else { + AppLogger.LogError("ImageHelper/GenerateCardImageGrid", `Failed to load image from path ${card.path}`); + continue; } + + const imageData = Jimp.fromBitmap(bitmap); + + if (userId != null) { + const claimed = await Inventory.FetchOneByCardNumberAndUserId(userId, card.id); + + if (!claimed || claimed.Quantity == 0) { + imageData.greyscale(); + } + } + + const image = await loadImage(await imageData.getBuffer("image/png")); + + const x = i % gridWidth; + const y = Math.floor(i / gridWidth); + + const imageX = imageWidth * x; + const imageY = imageHeight * y; + + ctx.drawImage(image, imageX, imageY); + } + catch (e) { + AppLogger.CatchError("ImageHelper", e); } - - const image = await loadImage(await imageData.getBuffer("image/png")); - - const x = i % gridWidth; - const y = Math.floor(i / gridWidth); - - const imageX = imageWidth * x; - const imageY = imageHeight * y; - - ctx.drawImage(image, imageX, imageY); } return canvas.toBuffer(); From c4e345cc466e2837155aa1f509871a6e62d8a30b Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Wed, 23 Apr 2025 10:41:20 +0100 Subject: [PATCH 82/94] Fix linting --- src/helpers/ImageHelper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/ImageHelper.ts b/src/helpers/ImageHelper.ts index 163c8ec..6bda409 100644 --- a/src/helpers/ImageHelper.ts +++ b/src/helpers/ImageHelper.ts @@ -67,7 +67,7 @@ export default class ImageHelper { const imageY = imageHeight * y; ctx.drawImage(image, imageX, imageY); - } + } catch (e) { AppLogger.CatchError("ImageHelper", e); } From 812e36329c99b0573fbaf4eaf1852ff943ec78c0 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 25 Apr 2025 09:14:30 +0100 Subject: [PATCH 83/94] Disable error for series helper temporarily --- src/helpers/ImageHelper.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/helpers/ImageHelper.ts b/src/helpers/ImageHelper.ts index 6bda409..1b0c856 100644 --- a/src/helpers/ImageHelper.ts +++ b/src/helpers/ImageHelper.ts @@ -69,7 +69,8 @@ export default class ImageHelper { ctx.drawImage(image, imageX, imageY); } catch (e) { - AppLogger.CatchError("ImageHelper", e); + // TODO: Enable once we've investigated a fix + //AppLogger.CatchError("ImageHelper", e); } } From 0669dfb0d06adffa5a8493c98d03e61a8406a721 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 25 Apr 2025 09:17:36 +0100 Subject: [PATCH 84/94] 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 730af871a0f3ad4ee832dc97bdddac00602c1ea2 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 16 May 2025 17:37:57 +0100 Subject: [PATCH 85/94] Update the drop mechanic to take currency on drop instead of claim (#428) # Description - Update the drop mechanic to take currency on drop instead of claim - Update the time until anyone can claim the card to 2 minutes - Remove the restriction that the last drop can only be claimed by the user who dropped it - Now just controlled by the 2 minutes rule #415 ## 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/428 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/buttonEvents/Claim.ts | 17 +-- src/buttonEvents/Reroll.ts | 6 +- src/client/client.ts | 1 - src/commands/drop.ts | 6 +- src/commands/stage/dropnumber.ts | 2 - src/commands/stage/droprarity.ts | 5 +- src/helpers/DropHelpers/DropEmbedHelper.ts | 13 +- src/timers/PurgeClaims.ts | 2 +- .../GenerateCommandInteractionMock.ts | 5 + tests/__types__/discord.js.ts | 5 + tests/buttonEvents/Claim.test.ts | 21 +-- tests/buttonEvents/Reroll.test.ts | 7 + tests/commands/drop.test.ts | 142 ++++++++++++++++++ .../DropHelpers/DropEmbedHelper.test.ts | 3 + tests/timers/PurgeClaims.test.ts | 7 + 15 files changed, 188 insertions(+), 54 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/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts index 97ee54d..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"; @@ -23,10 +22,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; } @@ -36,11 +35,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) { @@ -48,13 +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; - } - - 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..6d97024 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) { @@ -78,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 6c93af6..ac8008c 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) { @@ -86,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..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"); @@ -81,7 +80,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 diff --git a/src/helpers/DropHelpers/DropEmbedHelper.ts b/src/helpers/DropHelpers/DropEmbedHelper.ts index c739de7..08b5813 100644 --- a/src/helpers/DropHelpers/DropEmbedHelper.ts +++ b/src/helpers/DropHelpers/DropEmbedHelper.ts @@ -3,7 +3,6 @@ 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 { @@ -74,12 +73,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 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); 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/buttonEvents/Claim.test.ts b/tests/buttonEvents/Claim.test.ts index d9e7e6f..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"); @@ -85,25 +84,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 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..81b5f4a --- /dev/null +++ b/tests/commands/drop.test.ts @@ -0,0 +1,142 @@ +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"; +import * as uuid from "uuid"; + +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"); + +jest.mock("uuid"); + +beforeEach(() => { + (Config.GetValue as jest.Mock).mockResolvedValue("false"); +}); + +describe("execute", () => { + describe("GIVEN user is in the database", () => { + let interaction: CommandInteractionMock; + let user: User; + const randomCard = { + card: { + id: "cardId", + path: "https://google.com/", + } + }; + + beforeAll(async () => { + // Arrange + CoreClient.AllowDrops = true; + + 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(randomCard); + (Inventory.FetchOneByCardNumberAndUserId as jest.Mock).mockResolvedValue({ + Quantity: 1, + }); + (DropEmbedHelper.GenerateDropEmbed as jest.Mock).mockReturnValue({ + type: "Embed", + }); + (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); + }); + + 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("EXPECT user to be saved", () => { + expect(user.Save).toHaveBeenCalledTimes(1); + expect(user.Save).toHaveBeenCalledWith(User, user); + }); + + test("EXPECT random card to be fetched", () => { + expect(GetCardsHelper.FetchCard).toHaveBeenCalledTimes(1); + expect(GetCardsHelper.FetchCard).toHaveBeenCalledWith("userId"); + }); + + test("EXPECT interaction to be deferred", () => { + expect(interaction.deferReply).toHaveBeenCalledTimes(1); + }); + + test("EXPECT Inventory.FetchOneByCardNumberAndUserId to be called", () => { + expect(Inventory.FetchOneByCardNumberAndUserId).toHaveBeenCalledTimes(1); + expect(Inventory.FetchOneByCardNumberAndUserId).toHaveBeenCalledWith("userId", "cardId"); + }); + + test("EXPECT DropEmbedHelper.GenerateDropEmbed to be called", () => { + expect(DropEmbedHelper.GenerateDropEmbed).toHaveBeenCalledTimes(1); + expect(DropEmbedHelper.GenerateDropEmbed).toHaveBeenCalledWith(randomCard, 1, "", undefined, 500); + }); + + test("EXPECT DropEmbedHelper.GenerateDropButtons to be called", () => { + expect(DropEmbedHelper.GenerateDropButtons).toHaveBeenCalledTimes(1); + expect(DropEmbedHelper.GenerateDropButtons).toHaveBeenCalledWith(randomCard, "uuid", "userId"); + }); + + 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"); + + 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 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 62bcd6914c9f59c209b5cc1d03f52b9fa1d9b978 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 18 May 2025 11:26:00 +0100 Subject: [PATCH 86/94] v0.9.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 137ca15..5a0ef42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "card-drop", - "version": "0.8.4", + "version": "0.9.0", "main": "./dist/bot.js", "typings": "./dist", "scripts": { From f2c949c78a8b08aa012352f627aecca52aed7f72 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 24 May 2025 10:04:24 +0100 Subject: [PATCH 87/94] Fix multidrop not handling externally hosted images correctly (#447) - Fix multidrop command not handling externally hosted images correctly - It was trying to find the `https://` link in the file system, which it couldn't find - Fixed by copying existing logic from the drop command into the multidrop command #442 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/447 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/buttonEvents/Multidrop.ts | 16 ++++++++++++---- src/commands/multidrop.ts | 15 +++++++++++---- tests/buttonEvents/Multidrop.test.ts | 13 +++++++++++++ tests/commands/multidrop.test.ts | 13 +++++++++++++ 4 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 tests/buttonEvents/Multidrop.test.ts create mode 100644 tests/commands/multidrop.test.ts diff --git a/src/buttonEvents/Multidrop.ts b/src/buttonEvents/Multidrop.ts index e6ea7c2..e88d6ef 100644 --- a/src/buttonEvents/Multidrop.ts +++ b/src/buttonEvents/Multidrop.ts @@ -98,10 +98,18 @@ export default class Multidrop extends ButtonEvent { 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 files = []; + let imageFileName = ""; + + if (!(randomCard.card.path.startsWith("http://") || randomCard.card.path.startsWith("https://"))) { + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path)); + imageFileName = randomCard.card.path.split("/").pop()!; + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + files.push(attachment); + } - const attachment = new AttachmentBuilder(image, { name: imageFileName }); const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; @@ -112,7 +120,7 @@ export default class Multidrop extends ButtonEvent { await interaction.editReply({ embeds: [ embed ], - files: [ attachment ], + files: files, components: [ row ], }); } catch (e) { diff --git a/src/commands/multidrop.ts b/src/commands/multidrop.ts index aa42686..82d19fe 100644 --- a/src/commands/multidrop.ts +++ b/src/commands/multidrop.ts @@ -62,10 +62,17 @@ export default class Multidrop extends Command { 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 files = []; + let imageFileName = ""; - const attachment = new AttachmentBuilder(image, { name: imageFileName }); + if (!(randomCard.card.path.startsWith("http://") || randomCard.card.path.startsWith("https://"))) { + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path)); + imageFileName = randomCard.card.path.split("/").pop()!; + + const attachment = new AttachmentBuilder(image, { name: imageFileName }); + + files.push(attachment); + } const inventory = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, randomCard.card.id); const quantityClaimed = inventory ? inventory.Quantity : 0; @@ -76,7 +83,7 @@ export default class Multidrop extends Command { await interaction.editReply({ embeds: [ embed ], - files: [ attachment ], + files: files, components: [ row ], }); } catch (e) { diff --git a/tests/buttonEvents/Multidrop.test.ts b/tests/buttonEvents/Multidrop.test.ts new file mode 100644 index 0000000..5c9da42 --- /dev/null +++ b/tests/buttonEvents/Multidrop.test.ts @@ -0,0 +1,13 @@ +describe("execute", () => { + describe("GIVEN randomCard image is hosted locally", () => { + test.todo("EXPECT image to be uploaded directly"); + }); + + describe("GIVEN randomCard image is hosted via http", () => { + test.todo("EXPECT image link to be directly added to embed"); + }); + + describe("GIVEN randomCard image is hosted via https", () => { + test.todo("EXPECT image link to be directly added to embed"); + }); +}); diff --git a/tests/commands/multidrop.test.ts b/tests/commands/multidrop.test.ts new file mode 100644 index 0000000..5c9da42 --- /dev/null +++ b/tests/commands/multidrop.test.ts @@ -0,0 +1,13 @@ +describe("execute", () => { + describe("GIVEN randomCard image is hosted locally", () => { + test.todo("EXPECT image to be uploaded directly"); + }); + + describe("GIVEN randomCard image is hosted via http", () => { + test.todo("EXPECT image link to be directly added to embed"); + }); + + describe("GIVEN randomCard image is hosted via https", () => { + test.todo("EXPECT image link to be directly added to embed"); + }); +}); From ecc879cf13616bd2d280547130fa178e2e733f59 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 24 May 2025 10:05:49 +0100 Subject: [PATCH 88/94] Fix sacrificing a dropped card taking from your inventory first (#448) - Fix sacrificing a dropped card trying to take it from your inventory instead of just directly from the drop - Did it by creating a separate subaction for the sacrifice command, which does the same logic except without checking your inventory, since it wont be coming from there. - Fix the sacrificed card image showing outside of the embed #435, #436 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/448 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/buttonEvents/Sacrifice.ts | 76 ++++++++++++++++++++++ src/helpers/DropHelpers/DropEmbedHelper.ts | 2 +- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/buttonEvents/Sacrifice.ts b/src/buttonEvents/Sacrifice.ts index de0bb77..1626cf6 100644 --- a/src/buttonEvents/Sacrifice.ts +++ b/src/buttonEvents/Sacrifice.ts @@ -5,6 +5,7 @@ import { CardRarityToString, GetSacrificeAmount } from "../constants/CardRarity" import EmbedColours from "../constants/EmbedColours"; import User from "../database/entities/app/User"; import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; +import CardConstants from "../constants/CardConstants"; export default class Sacrifice extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -17,6 +18,8 @@ export default class Sacrifice extends ButtonEvent { case "cancel": await this.cancel(interaction); break; + case "give": + await this.give(interaction); } } @@ -168,4 +171,77 @@ export default class Sacrifice extends ButtonEvent { components: [ row ], }); } + + private async give(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."); + return; + } + + const cardData = GetCardsHelper.GetCardByCardNumber(cardNumber); + + if (!cardData) { + await interaction.reply("Unable to find card in the database."); + return; + } + + let user = await User.FetchOneById(User, userId); + + if (!user) { + user = new User(userId, CardConstants.StartingCurrency); + } + + const cardInInventory = await Inventory.FetchOneByCardNumberAndUserId(userId, cardNumber); + let cardQuantity = 0; + + if (cardInInventory) { + cardQuantity = cardInInventory.Quantity; + } + + const cardValue = GetSacrificeAmount(cardData.card.type) * quantity; + const cardRarityString = CardRarityToString(cardData.card.type); + + user.AddCurrency(cardValue); + + await user.Save(User, user); + + const description = [ + `Card: ${cardData.card.name}`, + `Series: ${cardData.series.name}`, + `Rarity: ${cardRarityString}`, + `Quantity Owned: ${cardQuantity}`, + `Quantity To Sacrifice: ${quantity}`, + `Sacrifice Amount: ${cardValue}`, + ]; + + const embed = new EmbedBuilder() + .setTitle("Card Sacrificed") + .setDescription(description.join("\n")) + .setColor(EmbedColours.Green) + .setFooter({ text: `${interaction.user.username}` }); + + const row = new ActionRowBuilder() + .addComponents([ + new ButtonBuilder() + .setCustomId(`sacrifice confirm ${interaction.user.id} ${cardNumber}`) + .setLabel("Confirm") + .setStyle(ButtonStyle.Success) + .setDisabled(true), + new ButtonBuilder() + .setCustomId("sacrifice cancel") + .setLabel("Cancel") + .setStyle(ButtonStyle.Secondary) + .setDisabled(true), + ]); + + await interaction.update({ + embeds: [ embed ], + components: [ row ], + attachments: [], + }); + } } \ No newline at end of file diff --git a/src/helpers/DropHelpers/DropEmbedHelper.ts b/src/helpers/DropHelpers/DropEmbedHelper.ts index 08b5813..5956a27 100644 --- a/src/helpers/DropHelpers/DropEmbedHelper.ts +++ b/src/helpers/DropHelpers/DropEmbedHelper.ts @@ -77,7 +77,7 @@ export default class DropEmbedHelper { .setStyle(ButtonStyle.Success) .setDisabled(disabled), new ButtonBuilder() - .setCustomId(`sacrifice confirm ${userId} ${drop.card.id} 1`) + .setCustomId(`sacrifice give ${userId} ${drop.card.id} 1`) .setLabel(`Sacrifice`) .setStyle(ButtonStyle.Danger), new ButtonBuilder() From ead53ba062b3e0b27d4540e614af1cd78bbcb3a1 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 24 May 2025 10:39:34 +0100 Subject: [PATCH 89/94] Add guards to the drop and reroll commands in case the card fetcher fails (#449) #446 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/449 Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/buttonEvents/Reroll.ts | 15 ++++++++++++--- src/commands/drop.ts | 15 +++++++++++++-- src/helpers/DropHelpers/GetCardsHelper.ts | 2 +- .../DropHelpers/GetUnclaimedCardsHelper.ts | 17 ++++++++++++++--- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/buttonEvents/Reroll.ts b/src/buttonEvents/Reroll.ts index 6d97024..6ad855e 100644 --- a/src/buttonEvents/Reroll.ts +++ b/src/buttonEvents/Reroll.ts @@ -11,6 +11,7 @@ import User from "../database/entities/app/User"; import CardConstants from "../constants/CardConstants"; import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; import DropEmbedHelper from "../helpers/DropHelpers/DropEmbedHelper"; +import {DropResult} from "../contracts/SeriesMetadata"; export default class Reroll extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { @@ -32,7 +33,7 @@ export default class Reroll extends ButtonEvent { user = new User(interaction.user.id, CardConstants.StartingCurrency); await user.Save(User, user); - AppLogger.LogInfo("Commands/Drop", `New user (${interaction.user.id}) saved to the database`); + AppLogger.LogInfo("Button/Reroll", `New user (${interaction.user.id}) saved to the database`); } if (!user.RemoveCurrency(CardConstants.ClaimCost)) { @@ -40,9 +41,15 @@ export default class Reroll extends ButtonEvent { return; } - await user.Save(User, user); + let randomCard: DropResult | undefined; - const randomCard = await GetCardsHelper.FetchCard(interaction.user.id); + try { + randomCard = await GetCardsHelper.FetchCard(interaction.user.id); + } catch (e) { + AppLogger.CatchError("Button/Reroll", e); + + await interaction.reply("Unable to fetch card, please try again."); + } if (!randomCard) { await interaction.reply("Unable to fetch card, please try again."); @@ -75,6 +82,8 @@ export default class Reroll extends ButtonEvent { const row = DropEmbedHelper.GenerateDropButtons(randomCard, claimId, interaction.user.id); + await user.Save(User, user); + await interaction.editReply({ embeds: [ embed ], files: files, diff --git a/src/commands/drop.ts b/src/commands/drop.ts index ac8008c..b6ad224 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -12,6 +12,7 @@ import CardConstants from "../constants/CardConstants"; import ErrorMessages from "../constants/ErrorMessages"; import GetCardsHelper from "../helpers/DropHelpers/GetCardsHelper"; import DropEmbedHelper from "../helpers/DropHelpers/DropEmbedHelper"; +import {DropResult} from "../contracts/SeriesMetadata"; export default class Drop extends Command { constructor() { @@ -48,9 +49,16 @@ export default class Drop extends Command { return; } - await user.Save(User, user); + let randomCard: DropResult | undefined; + + try { + randomCard = await GetCardsHelper.FetchCard(interaction.user.id); + } catch (e) { + AppLogger.CatchError("Commands/Drop", e); + + await interaction.reply(ErrorMessages.UnableToFetchCard); + } - const randomCard = await GetCardsHelper.FetchCard(interaction.user.id); if (!randomCard) { AppLogger.LogWarn("Commands/Drop", ErrorMessages.UnableToFetchCard); @@ -82,6 +90,9 @@ export default class Drop extends Command { const row = DropEmbedHelper.GenerateDropButtons(randomCard, claimId, interaction.user.id); + await user.Save(User, user); + + await interaction.editReply({ embeds: [ embed ], files: files, diff --git a/src/helpers/DropHelpers/GetCardsHelper.ts b/src/helpers/DropHelpers/GetCardsHelper.ts index 8bc4fe7..4c8648f 100644 --- a/src/helpers/DropHelpers/GetCardsHelper.ts +++ b/src/helpers/DropHelpers/GetCardsHelper.ts @@ -55,7 +55,7 @@ export default class GetCardsHelper { .find(x => x.cards.includes(card)); if (!series) { - AppLogger.LogWarn("CardDropHelperMetadata/GetRandomCardByRarity", `Series not found for card ${card.id}`); + AppLogger.LogError("CardDropHelperMetadata/GetRandomCardByRarity", `Series not found for card ${card.id}`); return undefined; } diff --git a/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts b/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts index 87fafea..3264a98 100644 --- a/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts +++ b/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts @@ -31,7 +31,7 @@ export default class GetUnclaimedCardsHelper { public static async GetRandomCardByRarityUnclaimed(rarity: CardRarity, userId: string): Promise { const claimedCards = await Inventory.FetchAllByUserId(userId); - if (!claimedCards) { + if (!claimedCards || claimedCards.length == 0) { // They don't have any cards, so safe to get any random card return GetCardsHelper.GetRandomCardByRarity(rarity); } @@ -41,16 +41,27 @@ export default class GetUnclaimedCardsHelper { .filter(x => x.type == rarity) .filter(x => !claimedCards.find(y => y.CardNumber == x.id)); - if (!allCards) return undefined; + if (!allCards) { + AppLogger.LogError("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `No cards found to randomise from, User Id: ${userId}, rarity: ${rarity}`); + + return undefined; + }; const randomCardIndex = Math.floor(Math.random() * allCards.length); const card = allCards[randomCardIndex]; + + if (!card) { + AppLogger.LogError("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `Card not found in index, ${randomCardIndex} of ${allCards.length}, User Id: ${userId}, rarity: ${rarity}`); + + return undefined; + } + const series = CoreClient.Cards .find(x => x.cards.includes(card)); if (!series) { - AppLogger.LogWarn("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `Series not found for card ${card.id}`); + AppLogger.LogError("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `Series not found for card ${card.id}, User Id: ${userId}, rarity: ${rarity}`); return undefined; } From 8e63f26747667b86af98b061c428c63a3213d85e Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 24 May 2025 11:51:56 +0100 Subject: [PATCH 90/94] Update inventory dropdown logic to use a range around the current page so that we can remain within the 25 pages discord allows (#450) #443 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/450 Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/helpers/InventoryHelper.ts | 43 +++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/helpers/InventoryHelper.ts b/src/helpers/InventoryHelper.ts index 3a7fbff..15c9c92 100644 --- a/src/helpers/InventoryHelper.ts +++ b/src/helpers/InventoryHelper.ts @@ -115,17 +115,48 @@ export default class InventoryHelper { let pageNum = 0; + const maxLength = 25; // Discord API limit + + const allPageOptions = 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 currentPageIndex = allPageOptions.indexOf(allPageOptions.find(x => x.data.default)!); + + let pageOptions: StringSelectMenuOptionBuilder[] = []; + + if (allPageOptions.length <= maxLength) { + pageOptions = allPageOptions; + } else { + let startIndex = currentPageIndex - Math.floor((maxLength - 1) / 2); + let endIndexOffset = 0; + + if (startIndex < 0) { + endIndexOffset = 0 - startIndex; + + startIndex = 0; + } + + let endIndex = currentPageIndex + Math.floor((maxLength - 1) / 2) + endIndexOffset; + + if (endIndex + 1 > allPageOptions.length) { + endIndex = allPageOptions.length; + } + + for (let i = startIndex; i < endIndex; i++) { + pageOptions.push(allPageOptions[i]); + } + } + 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++}`)))); + .addOptions(pageOptions)); const buffer = await ImageHelper.GenerateCardImageGrid(currentPage.cards.map(x => ({ id: x.id, path: x.path }))); const image = new AttachmentBuilder(buffer, { name: "page.png" }); From 7d9c1bda627d052b1a4cad9a34b9539eca6a1129 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 25 May 2025 17:00:43 +0100 Subject: [PATCH 91/94] v0.9.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5a0ef42..84734e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "card-drop", - "version": "0.9.0", + "version": "0.9.1", "main": "./dist/bot.js", "typings": "./dist", "scripts": { From 434f162a01b584b4f91546852a33c4b85f07cd1f Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Wed, 28 May 2025 16:07:38 +0100 Subject: [PATCH 92/94] Update unclaimed card filter to fallback to any card if all cards are claimed (#452) #451 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/452 Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts b/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts index 3264a98..94ce894 100644 --- a/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts +++ b/src/helpers/DropHelpers/GetUnclaimedCardsHelper.ts @@ -39,12 +39,11 @@ export default class GetUnclaimedCardsHelper { const allCards = CoreClient.Cards .flatMap(x => x.cards) .filter(x => x.type == rarity) - .filter(x => !claimedCards.find(y => y.CardNumber == x.id)); + .filter(x => !claimedCards.find(y => y.CardNumber == x.id && y.Quantity > 0)); - if (!allCards) { - AppLogger.LogError("CardDropHelperMetadata/GetRandomCardByRarityUnclaimed", `No cards found to randomise from, User Id: ${userId}, rarity: ${rarity}`); - - return undefined; + if (!allCards || allCards.length == 0) { + // There is no card left unclaimed, fallback to any card + return GetCardsHelper.GetRandomCardByRarity(rarity); }; const randomCardIndex = Math.floor(Math.random() * allCards.length); From c9f7c443cfa9a8e83a376d7800b82a7fd026c1fd Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Wed, 28 May 2025 16:14:42 +0100 Subject: [PATCH 93/94] Fix effects helper returning an error when the buttons are disabled (#454) -This caused an issue with the updated embed after confirming to buy an effect it checking you had enough currency after taking the currency away #453 Reviewed-on: https://git.vylpes.xyz/External/card-drop/pulls/454 Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- src/helpers/EffectHelper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/EffectHelper.ts b/src/helpers/EffectHelper.ts index 235ea08..09e096c 100644 --- a/src/helpers/EffectHelper.ts +++ b/src/helpers/EffectHelper.ts @@ -151,7 +151,7 @@ export default class EffectHelper { AppLogger.LogInfo("EffectHelper", `Created initial user entity for : ${userId}`); } - if (user.Currency < totalCost) { + if (!disabled && user.Currency < totalCost) { return `You don't have enough currency to buy this! You have \`${user.Currency} Currency\` and need \`${totalCost} Currency\`!`; } From fc3c98f1bba88e0da844561fb2c021ad8bec6a03 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Wed, 28 May 2025 18:17:48 +0100 Subject: [PATCH 94/94] v0.9.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 84734e7..b8c7536 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "card-drop", - "version": "0.9.1", + "version": "0.9.2", "main": "./dist/bot.js", "typings": "./dist", "scripts": {