diff --git a/.dev.env b/.dev.env index d1b74b1..28da9df 100644 --- a/.dev.env +++ b/.dev.env @@ -7,15 +7,18 @@ # any secret values. BOT_TOKEN= -BOT_VER=0.3.1 +BOT_VER=0.4.0 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=682942374040961060 BOT_ENV=4 +BOT_ADMINS=147392775707426816,887272961504071690 ABOUT_FUNDING= ABOUT_REPO= +DATA_DIR= + DB_HOST=127.0.0.1 DB_PORT=3301 DB_NAME=carddrop @@ -28,5 +31,4 @@ DB_CARD_FILE=:memory: EXPRESS_PORT=3303 -GDRIVESYNC_WHITELIST=147392775707426816,887272961504071690 GDRIVESYNC_AUTO=true diff --git a/.drone.yml b/.drone.yml index 3756b47..962eb6c 100644 --- a/.drone.yml +++ b/.drone.yml @@ -4,16 +4,36 @@ kind: pipeline name: deployment steps: -- name: deploy - image: appleboy/drone-ssh +- name: build + image: node + commands: + - npm ci + - npm run build +- name: test + image: node + commands: + - npm test +- name: deploy to prod + image: drillster/drone-rsync + secrets: [ ssh_key, bot_token_prod ] settings: - host: 192.168.68.120 - username: vylpes - password: - from_secret: ssh_password - port: 22 + hosts: + - 192.168.68.120 + user: vylpes + key: + from_secret: ssh_key + source: . + target: ~/apps/card-drop/card-drop_prod + recursive: true script: - - sh /home/vylpes/scripts/card-drop/deploy_prod.sh + - export PATH="$HOME/.yarn/bin:$PATH" + - export PATH="$HOME/.nodeuse/bin:$PATH" + - export BOT_TOKEN="$BOT_TOKEN_PROD" + - cd ~/apps/card-drop/card-drop_prod + - docker compose --file docker-compose.prod.yml up -d + - sleep 10 + - cp .prod.env .env + - pm2 restart card-drop_prod || pm2 start --name card-drop_prod dist/bot.js trigger: event: @@ -25,16 +45,36 @@ kind: pipeline name: staging steps: -- name: stage - image: appleboy/drone-ssh +- name: build + image: node + commands: + - npm ci + - npm run build +- name: test + image: node + commands: + - npm test +- name: deploy to stage + image: drillster/drone-rsync + secrets: [ ssh_key, bot_token_stage ] settings: - host: 192.168.68.120 - username: vylpes - password: - from_secret: ssh_password - port: 22 + hosts: + - 192.168.68.120 + user: vylpes + key: + from_secret: ssh_key + source: . + target: ~/apps/card-drop/card-drop_stage + recursive: true script: - - sh /home/vylpes/scripts/card-drop/deploy_stage.sh + - export PATH="$HOME/.yarn/bin:$PATH" + - export PATH="$HOME/.nodeuse/bin:$PATH" + - export BOT_TOKEN="$BOT_TOKEN_STAGE" + - cd ~/apps/card-drop/card-drop_stage + - docker compose --file docker-compose.stage.yml up -d + - sleep 10 + - cp .stage.env .env + - pm2 restart card-drop_stage || pm2 start --name card-drop_stage dist/bot.js trigger: branch: @@ -54,16 +94,18 @@ steps: - npm ci - npm run build +- name: lint + image: node + commands: + - npm run lint + - name: test image: node commands: - - npm ci - npm test trigger: branch: - - main - - develop - hotfix/* - feature/* - renovate/* diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..29f04b8 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,45 @@ +{ + "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/.gitignore b/.gitignore index a354170..aecb458 100644 --- a/.gitignore +++ b/.gitignore @@ -107,5 +107,5 @@ config.json .DS_Store ormconfig.json gdrive-credentials.json -cards/ +data/ *.db \ No newline at end of file diff --git a/.prod.env b/.prod.env index 0755c1e..79e98fb 100644 --- a/.prod.env +++ b/.prod.env @@ -7,15 +7,18 @@ # any secret values. BOT_TOKEN= -BOT_VER=0.3.1 +BOT_VER=0.4.0 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=1093810443589529631 BOT_ENV=1 +BOT_ADMINS=147392775707426816,887272961504071690 ABOUT_FUNDING= ABOUT_REPO= +DATA_DIR=/home/vylpes/appdata/card-drop/card-drop_prod + DB_HOST=127.0.0.1 DB_PORT=3321 DB_NAME=carddrop @@ -28,5 +31,4 @@ DB_CARD_FILE=:memory: EXPRESS_PORT=3323 -GDRIVESYNC_WHITELIST=147392775707426816,887272961504071690 GDRIVESYNC_AUTO=false diff --git a/.stage.env b/.stage.env index 4f70991..8db9eb5 100644 --- a/.stage.env +++ b/.stage.env @@ -7,15 +7,18 @@ # any secret values. BOT_TOKEN= -BOT_VER=0.3.1 +BOT_VER=0.4.0 BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=1147976642942214235 BOT_ENV=2 +BOT_ADMINS=147392775707426816,887272961504071690 ABOUT_FUNDING= ABOUT_REPO= +DATA_DIR=/home/vylpes/appdata/card-drop/card-drop_stage + DB_HOST=127.0.0.1 DB_PORT=3311 DB_NAME=carddrop @@ -28,5 +31,4 @@ DB_CARD_FILE=:memory: EXPRESS_PORT=3313 -GDRIVESYNC_WHITELIST=147392775707426816,887272961504071690 GDRIVESYNC_AUTO=false diff --git a/package-lock.json b/package-lock.json index ab404e8..39befbb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "card-drop", - "version": "0.3.1", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "card-drop", - "version": "0.3.1", + "version": "0.4.0", "license": "MIT", "dependencies": { "@discordjs/rest": "^2.0.0", @@ -23,17 +23,29 @@ "minimatch": "9.0.3", "mysql": "^2.18.1", "ts-jest": "^29.0.0", - "typeorm": "0.3.17" + "typeorm": "0.3.19" }, "devDependencies": { "@types/node": "^20.0.0", - "np": "^8.0.4", + "@typescript-eslint/eslint-plugin": "^6.16.0", + "@typescript-eslint/parser": "^6.16.0", + "eslint": "^8.56.0", + "np": "^9.0.0", "typescript": "^5.0.0" }, "funding": { "url": "https://ko-fi.com/vylpes" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "license": "Apache-2.0", @@ -558,16 +570,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.22.10", - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/template": { "version": "7.22.15", "license": "MIT", @@ -790,6 +792,134 @@ "@types/node": "*" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@fastify/busboy": { "version": "2.1.0", "license": "MIT", @@ -804,6 +934,84 @@ "optional": true, "peer": true }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1249,9 +1457,13 @@ } }, "node_modules/@ljharb/through": { - "version": "2.3.9", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.11.tgz", + "integrity": "sha512-ccfcIDlogiXNq5KcbAwbaO7lMh3Tm1i3khMPYpxlK8hH/W53zN81KM9coerRLOnTGu3nfXIniAmQbRI9OxbC0w==", "dev": true, - "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, "engines": { "node": ">= 0.4" } @@ -1643,6 +1855,12 @@ "pretty-format": "^29.0.0" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "node_modules/@types/keyv": { "version": "3.1.4", "dev": true, @@ -1656,9 +1874,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", - "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "version": "20.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.7.tgz", + "integrity": "sha512-fRbIKb8C/Y2lXxB5eVMj4IU7xpdox0Lh8bUPEdtLysaylsml1hOOx1+STloRs/B9nf7C6kPRmmg/V7aQW7usNg==", "dependencies": { "undici-types": "~5.26.4" } @@ -1684,6 +1902,12 @@ "@types/node": "*" } }, + "node_modules/@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, "node_modules/@types/send": { "version": "0.17.4", "license": "MIT", @@ -1731,6 +1955,314 @@ "version": "21.0.3", "license": "MIT" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.16.0.tgz", + "integrity": "sha512-O5f7Kv5o4dLWQtPX4ywPPa+v9G+1q1x8mz0Kr0pXUtKsevo+gIJHLkGc8RxaZWtP8RrhwhSNIWThnW42K9/0rQ==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.16.0", + "@typescript-eslint/type-utils": "6.16.0", + "@typescript-eslint/utils": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.16.0.tgz", + "integrity": "sha512-H2GM3eUo12HpKZU9njig3DF5zJ58ja6ahj1GoHEHOgQvYxzoFJJEvC1MQ7T2l9Ha+69ZSOn7RTxOdpC/y3ikMw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.16.0", + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/typescript-estree": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.16.0.tgz", + "integrity": "sha512-0N7Y9DSPdaBQ3sqSCwlrm9zJwkpOuc6HYm7LpzLAPqBL7dmzAUimr4M29dMkOP/tEwvOCC/Cxo//yOfJD3HUiw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.16.0.tgz", + "integrity": "sha512-ThmrEOcARmOnoyQfYkHw/DX2SEYBalVECmoldVuH6qagKROp/jMnfXpAU/pAIWub9c4YTxga+XwgAkoA0pxfmg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.16.0", + "@typescript-eslint/utils": "6.16.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@typescript-eslint/types": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.16.0.tgz", + "integrity": "sha512-hvDFpLEvTJoHutVl87+MG/c5C8I6LOgEx05zExTSJDEVU7hhR3jhV8M5zuggbdFCw98+HhZWPHZeKS97kS3JoQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.16.0.tgz", + "integrity": "sha512-VTWZuixh/vr7nih6CfrdpmFNLEnoVBF1skfjdyGnNwXOH1SLeHItGdZDHhhAIzd3ACazyY2Fg76zuzOVTaknGA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.16.0.tgz", + "integrity": "sha512-T83QPKrBm6n//q9mv7oiSvy/Xq/7Hyw9SzSEhMHJwznEmQayfBM87+oAlkNAMEO7/MjIwKyOHgBJbxB0s7gx2A==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.16.0", + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/typescript-estree": "6.16.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.16.0.tgz", + "integrity": "sha512-QSFQLruk7fhs91a/Ep/LqRdbJCZ1Rq03rqBdKT5Ky17Sz8zRLUksqIe9DW0pKtg/Z35/ztbLQ6qpOCN6rOC11A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@vladfrangu/async_event_emitter": { "version": "2.2.4", "license": "MIT", @@ -1757,6 +2289,27 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -1823,6 +2376,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/all-package-names": { "version": "2.0.713", "dev": true, @@ -1990,6 +2559,15 @@ "version": "1.1.1", "license": "MIT" }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/babel-jest": { "version": "29.7.0", "license": "MIT", @@ -2647,6 +3225,33 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chalk-template": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz", + "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==", + "dev": true, + "dependencies": { + "chalk": "^5.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/char-regex": { "version": "1.0.2", "license": "MIT", @@ -3108,13 +3713,14 @@ "license": "MIT" }, "node_modules/cosmiconfig": { - "version": "8.2.0", + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, - "license": "MIT", "dependencies": { - "import-fresh": "^3.2.1", + "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", + "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "engines": { @@ -3122,6 +3728,14 @@ }, "funding": { "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/create-jest": { @@ -3180,19 +3794,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/date-fns": { - "version": "2.30.0", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.21.0" - }, - "engines": { - "node": ">=0.11" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" - } + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" }, "node_modules/debug": { "version": "2.6.9", @@ -3235,6 +3840,12 @@ "node": ">=4.0.0" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "node_modules/deepmerge": { "version": "4.3.1", "license": "MIT", @@ -3396,9 +4007,10 @@ } }, "node_modules/del": { - "version": "7.0.0", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-7.1.0.tgz", + "integrity": "sha512-v2KyNk7efxhlyHpjEvfyxaAihKKK0nWCuf6ZtqZcFFpQRG0bJ12Qsr0RpvsICMjAAZ8DOVCxrlqpxISlMHC4Kg==", "dev": true, - "license": "MIT", "dependencies": { "globby": "^13.1.2", "graceful-fs": "^4.2.10", @@ -3529,6 +4141,18 @@ "node": ">=16.11.0" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/dot-prop": { "version": "7.2.0", "dev": true, @@ -3678,6 +4302,260 @@ "node": ">=0.8.0" } }, + "node_modules/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/esprima": { "version": "4.0.1", "license": "BSD-2-Clause", @@ -3689,6 +4567,48 @@ "node": ">=4" } }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/etag": { "version": "1.8.1", "license": "MIT", @@ -3724,11 +4644,12 @@ } }, "node_modules/exit-hook": { - "version": "3.2.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-4.0.0.tgz", + "integrity": "sha512-Fqs7ChZm72y40wKjOFXBKg7nJZvQJmewP5/7LtePDdnah/+FH9Hp5sgMujSCMPXlxOAW2//1jrW9pnsY7o20vQ==", "dev": true, - "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3859,6 +4780,12 @@ "version": "2.1.0", "license": "MIT" }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, "node_modules/fastq": { "version": "1.15.0", "dev": true, @@ -3885,6 +4812,18 @@ "node": ">=4" } }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "license": "MIT", @@ -3922,6 +4861,38 @@ "node": ">=8" } }, + "node_modules/find-up-simple": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", + "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, "node_modules/foreground-child": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", @@ -4148,6 +5119,30 @@ "node": ">= 6" } }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-directory/node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/global-dirs": { "version": "3.0.1", "dev": true, @@ -4245,6 +5240,12 @@ "version": "4.2.11", "license": "ISC" }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/has": { "version": "1.0.4", "license": "MIT", @@ -4324,22 +5325,24 @@ } }, "node_modules/hosted-git-info": { - "version": "6.1.1", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", + "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", "dev": true, - "license": "ISC", "dependencies": { - "lru-cache": "^7.5.1" + "lru-cache": "^10.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "7.18.3", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", "dev": true, - "license": "ISC", "engines": { - "node": ">=12" + "node": "14 || >=16.14" } }, "node_modules/html-escaper": { @@ -4596,6 +5599,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/index-to-position": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", + "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -4621,11 +5636,12 @@ "license": "ISC" }, "node_modules/inquirer": { - "version": "9.2.10", + "version": "9.2.12", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.12.tgz", + "integrity": "sha512-mg3Fh9g2zfuVWJn6lhST0O7x4n03k7G8Tx5nvikJkbq8/CK47WDVm+UznF0G6s5Zi0KcyUisr6DU8T67N5U+1Q==", "dev": true, - "license": "MIT", "dependencies": { - "@ljharb/through": "^2.3.9", + "@ljharb/through": "^2.3.11", "ansi-escapes": "^4.3.2", "chalk": "^5.3.0", "cli-cursor": "^3.1.0", @@ -4954,17 +5970,6 @@ "version": "0.2.1", "license": "MIT" }, - "node_modules/is-ci": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, "node_modules/is-core-module": { "version": "2.13.0", "license": "MIT", @@ -5022,6 +6027,21 @@ "node": ">=0.10.0" } }, + "node_modules/is-in-ci": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-0.1.0.tgz", + "integrity": "sha512-d9PXLEY0v1iJ64xLiQMJ51J128EYHAaOR4yZqQi8aHGfw6KgifM3/Viw1oZZ1GCVmb3gBuyhLyHj0HgR2DhSXQ==", + "dev": true, + "bin": { + "is-in-ci": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-inside-container": { "version": "1.0.0", "dev": true, @@ -5227,14 +6247,6 @@ "node": ">=8" } }, - "node_modules/is-yarn-global": { - "version": "0.4.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, "node_modules/isarray": { "version": "1.0.0", "license": "MIT" @@ -6013,6 +7025,18 @@ "version": "2.3.1", "license": "MIT" }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, "node_modules/json5": { "version": "2.2.3", "license": "MIT", @@ -6059,6 +7083,19 @@ "node": ">=6" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "license": "MIT" @@ -6400,6 +7437,12 @@ "version": "4.1.2", "license": "MIT" }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/lodash.snakecase": { "version": "4.1.1", "license": "MIT" @@ -6410,15 +7453,16 @@ "license": "MIT" }, "node_modules/log-symbols": { - "version": "5.1.0", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", "dev": true, - "license": "MIT", "dependencies": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6613,9 +7657,10 @@ } }, "node_modules/meow": { - "version": "12.1.0", + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", "dev": true, - "license": "MIT", "engines": { "node": ">=16.10" }, @@ -6695,6 +7740,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mimic-function": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.0.tgz", + "integrity": "sha512-RBfQ+9X9DpXdEoK7Bu+KeEU6vFhumEIiXKWECPzRBmDserEq4uR2b/VCm0LwpMSosoq2k+Zuxj/GzOr0Fn6h/g==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mimic-response": { "version": "3.1.0", "dev": true, @@ -7188,31 +8245,6 @@ "node": ">=6" } }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/normalize-package-data/node_modules/hosted-git-info": { - "version": "4.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "license": "MIT", @@ -7232,54 +8264,57 @@ } }, "node_modules/np": { - "version": "8.0.4", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/np/-/np-9.2.0.tgz", + "integrity": "sha512-VYA8IKyx5XJqROr2vu8NAstfgBznrnOu3PUByFl3TBwzQVkeGC+gzOPzGbvYKM1QwlX6Gt7kVSPMzDP4qkSs1g==", "dev": true, - "license": "MIT", "dependencies": { - "chalk": "^5.2.0", - "cosmiconfig": "^8.1.3", - "del": "^7.0.0", + "chalk": "^5.3.0", + "chalk-template": "^1.1.0", + "cosmiconfig": "^8.3.6", + "del": "^7.1.0", "escape-goat": "^4.0.0", "escape-string-regexp": "^5.0.0", - "execa": "^7.1.1", - "exit-hook": "^3.2.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": "^6.1.1", + "hosted-git-info": "^7.0.1", "ignore-walk": "^6.0.3", "import-local": "^3.1.0", - "inquirer": "^9.2.6", - "is-installed-globally": "^0.4.0", + "inquirer": "^9.2.12", + "is-installed-globally": "^1.0.0", "is-interactive": "^2.0.0", "is-scoped": "^3.0.0", "issue-regex": "^4.1.0", "listr": "^0.14.3", "listr-input": "^0.2.1", - "log-symbols": "^5.1.0", - "meow": "^12.0.1", + "log-symbols": "^6.0.0", + "meow": "^12.1.1", "new-github-release-url": "^2.0.0", - "npm-name": "^7.1.0", - "onetime": "^6.0.0", + "npm-name": "^7.1.1", + "onetime": "^7.0.0", "open": "^9.1.0", "ow": "^1.1.1", "p-memoize": "^7.1.1", - "p-timeout": "^6.1.1", + "p-timeout": "^6.1.2", "path-exists": "^5.0.0", - "pkg-dir": "^7.0.0", - "read-pkg-up": "^9.1.0", + "pkg-dir": "^8.0.0", + "read-package-up": "^11.0.0", + "read-pkg": "^9.0.1", "rxjs": "^7.8.1", - "semver": "^7.5.1", + "semver": "^7.5.4", "symbol-observable": "^4.0.0", "terminal-link": "^3.0.0", - "update-notifier": "^6.0.2" + "update-notifier": "^7.0.0" }, "bin": { "np": "source/cli.js" }, "engines": { "git": ">=2.11.0", - "node": ">=16.6.0", - "npm": ">=7.19.0", + "node": ">=18", + "npm": ">=9", "yarn": ">=1.7.0" }, "funding": { @@ -7288,8 +8323,9 @@ }, "node_modules/np/node_modules/chalk": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -7299,8 +8335,9 @@ }, "node_modules/np/node_modules/escape-string-regexp": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -7309,39 +8346,97 @@ } }, "node_modules/np/node_modules/execa": { - "version": "7.2.0", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, - "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", + "get-stream": "^8.0.1", + "human-signals": "^5.0.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", + "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" }, "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + "node": ">=16.17" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/np/node_modules/human-signals": { - "version": "4.3.1", + "node_modules/np/node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, - "license": "Apache-2.0", + "dependencies": { + "mimic-fn": "^4.0.0" + }, "engines": { - "node": ">=14.18.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/np/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/np/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/np/node_modules/is-installed-globally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-1.0.0.tgz", + "integrity": "sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==", + "dev": true, + "dependencies": { + "global-directory": "^4.0.1", + "is-path-inside": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/np/node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/np/node_modules/is-stream": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -7349,10 +8444,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/np/node_modules/npm-run-path": { - "version": "5.1.0", + "node_modules/np/node_modules/normalize-package-data": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", + "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/np/node_modules/npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -7364,14 +8475,32 @@ } }, "node_modules/np/node_modules/onetime": { - "version": "6.0.0", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, - "license": "MIT", "dependencies": { - "mimic-fn": "^4.0.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/np/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + }, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -7379,16 +8508,18 @@ }, "node_modules/np/node_modules/path-exists": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", "dev": true, - "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/np/node_modules/path-key": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -7396,18 +8527,51 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/np/node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/np/node_modules/rxjs": { "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, + "node_modules/np/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/np/node_modules/strip-final-newline": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -7415,10 +8579,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm-name": { - "version": "7.1.0", + "node_modules/np/node_modules/type-fest": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.3.tgz", + "integrity": "sha512-//BaTm14Q/gHBn09xlnKNqfI8t6bmdzx2DXYfPBNofN0WUybCEUDcbCWcTa0oF09lzLjZgPphXAsvRiMK0V6Bw==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-name": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/npm-name/-/npm-name-7.1.1.tgz", + "integrity": "sha512-lyOwsFndLoozriMEsaqJ5lXvhCATYOEhDvxlom8TNvB9a/htDXuLgpVhMUOBd9zCewUXCyBXAPxrGr2TK2adgQ==", "dev": true, - "license": "MIT", "dependencies": { "got": "^11.8.5", "is-name-taken": "^2.0.0", @@ -7537,6 +8714,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/ora": { "version": "5.4.1", "dev": true, @@ -8068,93 +9262,27 @@ } }, "node_modules/pkg-dir": { - "version": "7.0.0", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-8.0.0.tgz", + "integrity": "sha512-4peoBq4Wks0riS0z8741NVv+/8IiTvqnZAr8QGgtdifrtpdXbNw/FxRS1l6NFqm4EMzuS0EDqNNx4XGaz8cuyQ==", "dev": true, - "license": "MIT", "dependencies": { - "find-up": "^6.3.0" + "find-up-simple": "^1.0.0" }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "6.3.0", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/pkg-dir/node_modules/yocto-queue": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8.0" } }, "node_modules/pretty-format": { @@ -8248,6 +9376,15 @@ "once": "^1.3.1" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/pupa": { "version": "3.1.0", "dev": true, @@ -8387,110 +9524,81 @@ "types-json": "^1.0.6" } }, - "node_modules/read-pkg": { - "version": "7.1.0", + "node_modules/read-package-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", + "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", "dev": true, - "license": "MIT", "dependencies": { - "@types/normalize-package-data": "^2.4.1", - "normalize-package-data": "^3.0.2", - "parse-json": "^5.2.0", - "type-fest": "^2.0.0" + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" }, "engines": { - "node": ">=12.20" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up": { - "version": "9.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^6.3.0", - "read-pkg": "^7.1.0", - "type-fest": "^2.5.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "6.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { + "node_modules/read-package-up/node_modules/normalize-package-data": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", + "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", "dev": true, - "license": "MIT", "dependencies": { - "p-limit": "^4.0.0" + "hosted-git-info": "^7.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/read-package-up/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + }, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "5.0.0", + "node_modules/read-package-up/node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", "dev": true, - "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up/node_modules/yocto-queue": { - "version": "1.0.0", + "node_modules/read-package-up/node_modules/type-fest": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.3.tgz", + "integrity": "sha512-//BaTm14Q/gHBn09xlnKNqfI8t6bmdzx2DXYfPBNofN0WUybCEUDcbCWcTa0oF09lzLjZgPphXAsvRiMK0V6Bw==", "dev": true, - "license": "MIT", "engines": { - "node": ">=12.20" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8517,10 +9625,6 @@ "version": "0.1.13", "license": "Apache-2.0" }, - "node_modules/regenerator-runtime": { - "version": "0.14.0", - "license": "MIT" - }, "node_modules/registry-auth-token": { "version": "4.2.2", "dev": true, @@ -9462,6 +10566,12 @@ "node": "*" } }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, "node_modules/thenify": { "version": "3.3.1", "license": "MIT", @@ -9541,6 +10651,18 @@ "optional": true, "peer": true }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/ts-essentials": { "version": "7.0.3", "license": "MIT", @@ -9612,6 +10734,18 @@ "version": "2.6.2", "license": "0BSD" }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-detect": { "version": "4.0.8", "license": "MIT", @@ -9650,18 +10784,19 @@ } }, "node_modules/typeorm": { - "version": "0.3.17", - "license": "MIT", + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.19.tgz", + "integrity": "sha512-OGelrY5qEoAU80mR1iyvmUHiKCPUydL6xp6bebXzS7jyv/X70Gp/jBWRAfF4qGOfy2A7orMiGRfwsBUNbEL65g==", "dependencies": { "@sqltools/formatter": "^1.2.5", "app-root-path": "^3.1.0", "buffer": "^6.0.3", "chalk": "^4.1.2", "cli-highlight": "^2.1.11", - "date-fns": "^2.29.3", + "dayjs": "^1.11.9", "debug": "^4.3.4", "dotenv": "^16.0.3", - "glob": "^8.1.0", + "glob": "^10.3.10", "mkdirp": "^2.1.3", "reflect-metadata": "^0.1.13", "sha.js": "^2.4.11", @@ -9683,13 +10818,13 @@ "peerDependencies": { "@google-cloud/spanner": "^5.18.0", "@sap/hana-client": "^2.12.25", - "better-sqlite3": "^7.1.2 || ^8.0.0", + "better-sqlite3": "^7.1.2 || ^8.0.0 || ^9.0.0", "hdb-pool": "^0.1.6", "ioredis": "^5.0.4", - "mongodb": "^5.2.0", - "mssql": "^9.1.1", + "mongodb": "^5.8.0", + "mssql": "^9.1.1 || ^10.0.1", "mysql2": "^2.2.5 || ^3.0.1", - "oracledb": "^5.1.0", + "oracledb": "^6.3.0", "pg": "^8.5.1", "pg-native": "^3.0.0", "pg-query-stream": "^4.0.0", @@ -9755,7 +10890,8 @@ }, "node_modules/typeorm/node_modules/debug": { "version": "4.3.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, @@ -9768,36 +10904,10 @@ } } }, - "node_modules/typeorm/node_modules/glob": { - "version": "8.1.0", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/typeorm/node_modules/minimatch": { - "version": "5.1.6", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/typeorm/node_modules/ms": { "version": "2.1.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/types-eslintrc": { "version": "1.0.3", @@ -9822,8 +10932,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "license": "Apache-2.0", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9846,6 +10957,18 @@ "version": "5.26.5", "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", @@ -9924,27 +11047,26 @@ } }, "node_modules/update-notifier": { - "version": "6.0.2", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-7.0.0.tgz", + "integrity": "sha512-Hv25Bh+eAbOLlsjJreVPOs4vd51rrtCrmhyOJtbpAojro34jS4KQaEp4/EvlHJX7jSO42VvEFpkastVyXyIsdQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "boxen": "^7.0.0", - "chalk": "^5.0.1", + "boxen": "^7.1.1", + "chalk": "^5.3.0", "configstore": "^6.0.0", - "has-yarn": "^3.0.0", "import-lazy": "^4.0.0", - "is-ci": "^3.0.1", + "is-in-ci": "^0.1.0", "is-installed-globally": "^0.4.0", "is-npm": "^6.0.0", - "is-yarn-global": "^0.4.0", "latest-version": "^7.0.0", "pupa": "^3.1.0", - "semver": "^7.3.7", + "semver": "^7.5.4", "semver-diff": "^4.0.0", "xdg-basedir": "^5.1.0" }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/yeoman/update-notifier?sponsor=1" @@ -9961,6 +11083,15 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "license": "MIT" diff --git a/package.json b/package.json index a70138f..c878094 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "card-drop", - "version": "0.3.1", + "version": "0.4.0", "main": "./dist/bot.js", "typings": "./dist", "scripts": { @@ -8,6 +8,8 @@ "build": "tsc", "start": "node ./dist/bot.js", "test": "jest --passWithNoTests", + "lint": "eslint .", + "lint:fix": "eslint . --fix", "db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js", "db:down": "typeorm migration:revert -d dist/database/dataSources/appDataSource.js", "db:create": "typeorm migration:create ./src/database/migrations/app/new", @@ -37,14 +39,15 @@ "minimatch": "9.0.3", "mysql": "^2.18.1", "ts-jest": "^29.0.0", - "typeorm": "0.3.17" - }, - "resolutions": { - "**/undici": "^5.26.2" + "typeorm": "0.3.19" }, + "resolutions": {}, "devDependencies": { "@types/node": "^20.0.0", - "np": "^8.0.4", + "@typescript-eslint/eslint-plugin": "^6.16.0", + "@typescript-eslint/parser": "^6.16.0", + "eslint": "^8.56.0", + "np": "^9.0.0", "typescript": "^5.0.0" } } diff --git a/renovate.json b/renovate.json index e36bf04..7fa351c 100644 --- a/renovate.json +++ b/renovate.json @@ -1,4 +1,5 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "baseBranches": ["develop"] + "baseBranches": ["develop"], + "labels": ["type/dependencies"] } diff --git a/src/Functions/CardMetadataFunction.ts b/src/Functions/CardMetadataFunction.ts index 1d52a27..99a162e 100644 --- a/src/Functions/CardMetadataFunction.ts +++ b/src/Functions/CardMetadataFunction.ts @@ -2,12 +2,12 @@ import { readFileSync } from "fs"; import path from "path"; import Config from "../database/entities/app/Config"; import { glob } from "glob"; -import SeriesMetadata from "../contracts/SeriesMetadata"; +import { SeriesMetadata } from "../contracts/SeriesMetadata"; import { CoreClient } from "../client/client"; export default class CardMetadataFunction { public static async Execute(overrideSafeMode: boolean = false): Promise { - if (!overrideSafeMode && await Config.GetValue('safemode') == "true") return false; + if (!overrideSafeMode && await Config.GetValue("safemode") == "true") return false; try { CoreClient.Cards = await this.FindMetadataJSONs(); @@ -16,7 +16,7 @@ export default class CardMetadataFunction { } catch (e) { console.error(e); - await Config.SetValue('safemode', 'true'); + await Config.SetValue("safemode", "true"); return false; } @@ -26,9 +26,9 @@ export default class CardMetadataFunction { private static async FindMetadataJSONs(): Promise { const res: SeriesMetadata[] = []; - const seriesJSONs = await glob(path.join(process.cwd(), 'cards', '/**/*.json')); + const seriesJSONs = await glob(path.join(process.env.DATA_DIR!, "cards", "/**/*.json")); - for (let jsonPath of seriesJSONs) { + for (const jsonPath of seriesJSONs) { console.log(`Reading file ${jsonPath}`); const jsonFile = readFileSync(jsonPath); const parsedJson: SeriesMetadata[] = JSON.parse(jsonFile.toString()); diff --git a/src/bot.ts b/src/bot.ts index 8bddbf4..87008c5 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -14,6 +14,8 @@ const requiredConfigs: string[] = [ "BOT_OWNERID", "BOT_CLIENTID", "BOT_ENV", + "BOT_ADMINS", + "DATA_DIR", "DB_HOST", "DB_PORT", "DB_AUTH_USER", @@ -21,8 +23,7 @@ const requiredConfigs: string[] = [ "DB_SYNC", "DB_LOGGING", "EXPRESS_PORT", - "GDRIVESYNC_WHITELIST", -] +]; requiredConfigs.forEach(config => { if (!process.env[config]) { @@ -39,7 +40,7 @@ Registry.RegisterCommands(); Registry.RegisterEvents(); Registry.RegisterButtonEvents(); -if (!existsSync(`${process.cwd()}/cards`) && process.env.GDRIVESYNC_AUTO && process.env.GDRIVESYNC_AUTO == 'true') { +if (!existsSync(`${process.env.DATA_DIR}/cards`) && process.env.GDRIVESYNC_AUTO && process.env.GDRIVESYNC_AUTO == "true") { console.log("Card directory not found, syncing..."); CoreClient.AllowDrops = false; @@ -49,7 +50,7 @@ if (!existsSync(`${process.cwd()}/cards`) && process.env.GDRIVESYNC_AUTO && proc console.error(error.code); throw `Error while running sync command. Code: ${error.code}`; } else { - console.log('Synced successfully.'); + console.log("Synced successfully."); CoreClient.AllowDrops = true; } }); diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts index 0db89fe..dd9ef5d 100644 --- a/src/buttonEvents/Claim.ts +++ b/src/buttonEvents/Claim.ts @@ -8,20 +8,20 @@ export default class Claim extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { if (!interaction.guild || !interaction.guildId) return; - const cardNumber = interaction.customId.split(' ')[1]; - const claimId = interaction.customId.split(' ')[2]; - const droppedBy = interaction.customId.split(' ')[3]; + const cardNumber = interaction.customId.split(" ")[1]; + const claimId = interaction.customId.split(" ")[2]; + const droppedBy = interaction.customId.split(" ")[3]; const userId = interaction.user.id; const claimed = await eClaim.FetchOneByClaimId(claimId); if (claimed) { - await interaction.reply('This card has already been claimed'); + await interaction.reply("This card has already been claimed"); return; } if (claimId == CoreClient.ClaimId && userId != droppedBy) { - await interaction.reply('The latest dropped card can only be claimed by the user who dropped it'); + await interaction.reply("The latest dropped card can only be claimed by the user who dropped it"); return; } diff --git a/src/buttonEvents/Inventory.ts b/src/buttonEvents/Inventory.ts new file mode 100644 index 0000000..6a71029 --- /dev/null +++ b/src/buttonEvents/Inventory.ts @@ -0,0 +1,21 @@ +import { ButtonInteraction } from "discord.js"; +import { ButtonEvent } from "../type/buttonEvent"; +import InventoryHelper from "../helpers/InventoryHelper"; + +export default class Inventory extends ButtonEvent { + public override async execute(interaction: ButtonInteraction) { + const userid = interaction.customId.split(" ")[1]; + const page = interaction.customId.split(" ")[2]; + + try { + const embed = await InventoryHelper.GenerateInventoryPage(interaction.user.username, userid, Number(page)); + + await interaction.update({ + embeds: [ embed.embed ], + components: [ embed.row ], + }); + } catch { + await interaction.reply("No page for user found."); + } + } +} \ No newline at end of file diff --git a/src/buttonEvents/Reroll.ts b/src/buttonEvents/Reroll.ts index 3b86e72..a647acd 100644 --- a/src/buttonEvents/Reroll.ts +++ b/src/buttonEvents/Reroll.ts @@ -1,4 +1,4 @@ -import { AttachmentBuilder, ButtonInteraction, DiscordAPIError } from "discord.js"; +import { AttachmentBuilder, ButtonInteraction } from "discord.js"; import { ButtonEvent } from "../type/buttonEvent"; import { readFileSync } from "fs"; import { v4 } from "uuid"; @@ -11,28 +11,26 @@ import path from "path"; export default class Reroll extends ButtonEvent { public override async execute(interaction: ButtonInteraction) { if (!CoreClient.AllowDrops) { - await interaction.reply('Bot is currently syncing, please wait until its done.'); + await interaction.reply("Bot is currently syncing, please wait until its done."); return; } - if (await Config.GetValue('safemode') == "true") { - await interaction.reply('Safe Mode has been activated, please resync to continue.'); + if (await Config.GetValue("safemode") == "true") { + await interaction.reply("Safe Mode has been activated, please resync to continue."); return; } const randomCard = CardDropHelperMetadata.GetRandomCard(); if (!randomCard) { - await interaction.reply('Unable to fetch card, please try again.'); + await interaction.reply("Unable to fetch card, please try again."); return; } try { - let image: Buffer; + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path)); const imageFileName = randomCard.card.path.split("/").pop()!; - image = readFileSync(path.join(process.cwd(), 'cards', randomCard.card.path)); - await interaction.deferReply(); const attachment = new AttachmentBuilder(image, { name: imageFileName }); diff --git a/src/client/client.ts b/src/client/client.ts index 643036d..ca2fba3 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -1,23 +1,22 @@ -import { Client } from "discord.js"; +import { Client, DMChannel, Guild, GuildBan, GuildMember, Message, NonThreadGuildBasedChannel, PartialGuildMember, PartialMessage } from "discord.js"; import * as dotenv from "dotenv"; -import { EventType } from "../constants/EventType"; import ICommandItem from "../contracts/ICommandItem"; -import IEventItem from "../contracts/IEventItem"; +import EventExecutors from "../contracts/EventExecutors"; import { Command } from "../type/command"; import { Events } from "./events"; import { Util } from "./util"; -import IButtonEventItem from "../contracts/IButtonEventItem"; +import IButtonEventItem from "../contracts/ButtonEventItem"; import { ButtonEvent } from "../type/buttonEvent"; import AppDataSource from "../database/dataSources/appDataSource"; import { Environment } from "../constants/Environment"; import Webhooks from "../webhooks"; import CardMetadataFunction from "../Functions/CardMetadataFunction"; -import SeriesMetadata from "../contracts/SeriesMetadata"; +import { SeriesMetadata } from "../contracts/SeriesMetadata"; export class CoreClient extends Client { private static _commandItems: ICommandItem[]; - private static _eventItems: IEventItem[]; + private static _eventExecutors: EventExecutors; private static _buttonEvents: IButtonEventItem[]; private _events: Events; @@ -33,8 +32,8 @@ export class CoreClient extends Client { return this._commandItems; } - public static get eventItems(): IEventItem[] { - return this._eventItems; + public static get eventExecutors(): EventExecutors { + return this._eventExecutors; } public static get buttonEvents(): IButtonEventItem[] { @@ -46,7 +45,6 @@ export class CoreClient extends Client { dotenv.config(); CoreClient._commandItems = []; - CoreClient._eventItems = []; CoreClient._buttonEvents = []; this._events = new Events(); @@ -74,15 +72,11 @@ export class CoreClient extends Client { await CardMetadataFunction.Execute(true); - this._util.loadEvents(this, CoreClient._eventItems); + this._util.loadEvents(this, CoreClient._eventExecutors); this._util.loadSlashCommands(this); this._webhooks.start(); - console.log(`Registered Commands: ${CoreClient._commandItems.flatMap(x => x.Name).join(", ")}`); - console.log(`Registered Events: ${CoreClient._eventItems.flatMap(x => x.EventType).join(", ")}`); - console.log(`Registered Buttons: ${CoreClient._buttonEvents.flatMap(x => x.ButtonId).join(", ")}`); - await super.login(process.env.BOT_TOKEN); } @@ -94,20 +88,260 @@ export class CoreClient extends Client { ServerId: serverId, }; - if (environment &= CoreClient.Environment) { + if ((environment & CoreClient.Environment) == CoreClient.Environment) { CoreClient._commandItems.push(item); } } - public static RegisterEvent(eventType: EventType, func: Function, environment: Environment = Environment.All) { - const item: IEventItem = { - EventType: eventType, - ExecutionFunction: func, - Environment: environment, - }; + public static RegisterChannelCreateEvent(fn: (channel: NonThreadGuildBasedChannel) => void) { + if (this._eventExecutors) { + this._eventExecutors.ChannelCreate.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [ fn ], + ChannelDelete: [], + ChannelUpdate: [], + GuildBanAdd: [], + GuildBanRemove: [], + GuildCreate: [], + GuildMemberAdd: [], + GuildMemberRemove: [], + GuildMemebrUpdate: [], + MessageCreate: [], + MessageDelete: [], + MessageUpdate: [], + }; + } + } - if (environment &= CoreClient.Environment) { - CoreClient._eventItems.push(item); + public static RegisterChannelDeleteEvent(fn: (channel: DMChannel | NonThreadGuildBasedChannel) => void) { + if (this._eventExecutors) { + this._eventExecutors.ChannelDelete.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [ fn ], + ChannelUpdate: [], + GuildBanAdd: [], + GuildBanRemove: [], + GuildCreate: [], + GuildMemberAdd: [], + GuildMemberRemove: [], + GuildMemebrUpdate: [], + MessageCreate: [], + MessageDelete: [], + MessageUpdate: [], + }; + } + } + + public static RegisterChannelUpdateEvent(fn: (channel: DMChannel | NonThreadGuildBasedChannel) => void) { + if (this._eventExecutors) { + this._eventExecutors.ChannelCreate.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [], + ChannelUpdate: [ fn ], + GuildBanAdd: [], + GuildBanRemove: [], + GuildCreate: [], + GuildMemberAdd: [], + GuildMemberRemove: [], + GuildMemebrUpdate: [], + MessageCreate: [], + MessageDelete: [], + MessageUpdate: [], + }; + } + } + + public static RegisterGuildBanAddEvent(fn: (ban: GuildBan) => void) { + if (this._eventExecutors) { + this._eventExecutors.GuildBanAdd.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [], + ChannelUpdate: [], + GuildBanAdd: [ fn ], + GuildBanRemove: [], + GuildCreate: [], + GuildMemberAdd: [], + GuildMemberRemove: [], + GuildMemebrUpdate: [], + MessageCreate: [], + MessageDelete: [], + MessageUpdate: [], + }; + } + } + + public static RegisterGuildBanRemoveEvent(fn: (channel: GuildBan) => void) { + if (this._eventExecutors) { + this._eventExecutors.GuildBanRemove.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [], + ChannelUpdate: [], + GuildBanAdd: [], + GuildBanRemove: [ fn ], + GuildCreate: [], + GuildMemberAdd: [], + GuildMemberRemove: [], + GuildMemebrUpdate: [], + MessageCreate: [], + MessageDelete: [], + MessageUpdate: [], + }; + } + } + + public static RegisterGuildCreateEvent(fn: (guild: Guild) => void) { + if (this._eventExecutors) { + this._eventExecutors.GuildCreate.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [], + ChannelUpdate: [], + GuildBanAdd: [], + GuildBanRemove: [], + GuildCreate: [ fn ], + GuildMemberAdd: [], + GuildMemberRemove: [], + GuildMemebrUpdate: [], + MessageCreate: [], + MessageDelete: [], + MessageUpdate: [], + }; + } + } + + public static RegisterGuildMemberAddEvent(fn: (member: GuildMember) => void) { + if (this._eventExecutors) { + this._eventExecutors.GuildMemberAdd.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [], + ChannelUpdate: [], + GuildBanAdd: [], + GuildBanRemove: [], + GuildCreate: [], + GuildMemberAdd: [ fn ], + GuildMemberRemove: [], + GuildMemebrUpdate: [], + MessageCreate: [], + MessageDelete: [], + MessageUpdate: [], + }; + } + } + + public static RegisterGuildMemberRemoveEvent(fn: (member: GuildMember | PartialGuildMember) => void) { + if (this._eventExecutors) { + this._eventExecutors.GuildMemberRemove.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [], + ChannelUpdate: [], + GuildBanAdd: [], + GuildBanRemove: [], + GuildCreate: [], + GuildMemberAdd: [], + GuildMemberRemove: [ fn ], + GuildMemebrUpdate: [], + MessageCreate: [], + MessageDelete: [], + MessageUpdate: [], + }; + } + } + + public static GuildMemebrUpdate(fn: (oldMember: GuildMember | PartialGuildMember, newMember: GuildMember) => void) { + if (this._eventExecutors) { + this._eventExecutors.GuildMemebrUpdate.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [], + ChannelUpdate: [], + GuildBanAdd: [], + GuildBanRemove: [], + GuildCreate: [], + GuildMemberAdd: [], + GuildMemberRemove: [], + GuildMemebrUpdate: [ fn ], + MessageCreate: [], + MessageDelete: [], + MessageUpdate: [], + }; + } + } + + public static RegisterMessageCreateEvent(fn: (message: Message) => void) { + if (this._eventExecutors) { + this._eventExecutors.MessageCreate.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [], + ChannelUpdate: [], + GuildBanAdd: [], + GuildBanRemove: [], + GuildCreate: [], + GuildMemberAdd: [], + GuildMemberRemove: [], + GuildMemebrUpdate: [], + MessageCreate: [ fn ], + MessageDelete: [], + MessageUpdate: [], + }; + } + } + + public static RegisterMessageDeleteEvent(fn: (message: Message | PartialMessage) => void) { + if (this._eventExecutors) { + this._eventExecutors.MessageDelete.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [], + ChannelUpdate: [], + GuildBanAdd: [], + GuildBanRemove: [], + GuildCreate: [], + GuildMemberAdd: [], + GuildMemberRemove: [], + GuildMemebrUpdate: [], + MessageCreate: [], + MessageDelete: [ fn ], + MessageUpdate: [], + }; + } + } + + public static RegisterMessageUpdateEvent(fn: (oldMessage: Message | PartialMessage, newMessage: Message | PartialMessage) => void) { + if (this._eventExecutors) { + this._eventExecutors.MessageUpdate.push(fn); + } else { + this._eventExecutors = { + ChannelCreate: [], + ChannelDelete: [], + ChannelUpdate: [], + GuildBanAdd: [], + GuildBanRemove: [], + GuildCreate: [], + GuildMemberAdd: [], + GuildMemberRemove: [], + GuildMemebrUpdate: [], + MessageCreate: [], + MessageDelete: [], + MessageUpdate: [ fn ], + }; } } @@ -118,7 +352,7 @@ export class CoreClient extends Client { Environment: environment, }; - if (environment &= CoreClient.Environment) { + if ((environment & CoreClient.Environment) == CoreClient.Environment) { CoreClient._buttonEvents.push(item); } } diff --git a/src/client/interactionCreate/Button.ts b/src/client/interactionCreate/Button.ts index 165e426..fac2b78 100644 --- a/src/client/interactionCreate/Button.ts +++ b/src/client/interactionCreate/Button.ts @@ -1,14 +1,14 @@ -import { ButtonInteraction, Interaction } from "discord.js"; +import { ButtonInteraction } from "discord.js"; import { CoreClient } from "../client"; export default class Button { public static async onButtonClicked(interaction: ButtonInteraction) { if (!interaction.isButton) return; - const item = CoreClient.buttonEvents.find(x => x.ButtonId == interaction.customId.split(' ')[0]); + const item = CoreClient.buttonEvents.find(x => x.ButtonId == interaction.customId.split(" ")[0]); if (!item) { - await interaction.reply('Event not found'); + await interaction.reply("Event not found"); return; } diff --git a/src/client/interactionCreate/ChatInputCommand.ts b/src/client/interactionCreate/ChatInputCommand.ts index d483f1d..3890744 100644 --- a/src/client/interactionCreate/ChatInputCommand.ts +++ b/src/client/interactionCreate/ChatInputCommand.ts @@ -13,7 +13,7 @@ export default class ChatInputCommand { if (!itemForServer) { if (!item) { - await interaction.reply('Command not found'); + await interaction.reply("Command not found"); return; } diff --git a/src/client/util.ts b/src/client/util.ts index 41b7f27..ddd84fc 100644 --- a/src/client/util.ts +++ b/src/client/util.ts @@ -1,6 +1,5 @@ import { Client, REST, Routes, SlashCommandBuilder } from "discord.js"; -import { EventType } from "../constants/EventType"; -import IEventItem from "../contracts/IEventItem"; +import EventExecutors from "../contracts/EventExecutors"; import { CoreClient } from "./client"; export class Util { @@ -10,25 +9,25 @@ export class Util { const globalCommands = registeredCommands.filter(x => !x.ServerId); const guildCommands = registeredCommands.filter(x => x.ServerId); - const globalCommandData: SlashCommandBuilder[] = []; + const globalCommandData: Omit[] = []; - for (let command of globalCommands) { + for (const command of globalCommands) { if (!command.Command.CommandBuilder) continue; - if (command.Environment &= CoreClient.Environment) { + if ((command.Environment & CoreClient.Environment) == CoreClient.Environment) { globalCommandData.push(command.Command.CommandBuilder); } } const guildIds: string[] = []; - for (let command of guildCommands) { + for (const command of guildCommands) { if (!guildIds.find(x => x == command.ServerId)) { guildIds.push(command.ServerId!); } } - const rest = new REST({ version: '10' }).setToken(process.env.BOT_TOKEN!); + const rest = new REST({ version: "10" }).setToken(process.env.BOT_TOKEN!); rest.put( Routes.applicationCommands(process.env.BOT_CLIENTID!), @@ -37,13 +36,13 @@ export class Util { } ); - for (let guild of guildIds) { - const guildCommandData: SlashCommandBuilder[] = []; + for (const guild of guildIds) { + const guildCommandData: Omit[] = []; - for (let command of guildCommands.filter(x => x.ServerId == guild)) { + for (const command of guildCommands.filter(x => x.ServerId == guild)) { if (!command.Command.CommandBuilder) continue; - if (command.Environment &= CoreClient.Environment) { + if ((command.Environment & CoreClient.Environment) == CoreClient.Environment) { guildCommandData.push(command.Command.CommandBuilder); } } @@ -55,53 +54,23 @@ export class Util { { body: guildCommandData } - ) + ); } } // Load the events - loadEvents(client: Client, events: IEventItem[]) { - events.forEach((e) => { - switch(e.EventType) { - case EventType.ChannelCreate: - client.on('channelCreate', (channel) => e.ExecutionFunction(channel)); - break; - case EventType.ChannelDelete: - client.on('channelDelete', (channel) => e.ExecutionFunction(channel)); - break; - case EventType.ChannelUpdate: - client.on('channelUpdate', (channel) => e.ExecutionFunction(channel)); - break; - case EventType.GuildBanAdd: - client.on('guildBanAdd', (ban) => e.ExecutionFunction(ban)); - break; - case EventType.GuildBanRemove: - client.on('guildBanRemove', (ban) => e.ExecutionFunction(ban)); - break; - case EventType.GuildCreate: - client.on('guildCreate', (guild) => e.ExecutionFunction(guild)); - break; - case EventType.GuildMemberAdd: - client.on('guildMemberAdd', (member) => e.ExecutionFunction(member)); - break; - case EventType.GuildMemberRemove: - client.on('guildMemberRemove', (member) => e.ExecutionFunction(member)); - break; - case EventType.GuildMemberUpdate: - client.on('guildMemberUpdate', (oldMember, newMember) => e.ExecutionFunction(oldMember, newMember)); - break; - case EventType.MessageCreate: - client.on('messageCreate', (message) => e.ExecutionFunction(message)); - break; - case EventType.MessageDelete: - client.on('messageDelete', (message) => e.ExecutionFunction(message)); - break; - case EventType.MessageUpdate: - client.on('messageUpdate', (oldMessage, newMessage) => e.ExecutionFunction(oldMessage, newMessage)); - break; - default: - console.error('Event not implemented.'); - } - }); + loadEvents(client: Client, events: EventExecutors) { + client.on("channelCreate", (channel) => events.ChannelCreate.forEach((fn) => fn(channel))); + client.on("channelDelete", (channel) => events.ChannelDelete.forEach((fn) => fn(channel))); + client.on("channelUpdate", (channel) => events.ChannelUpdate.forEach((fn) => fn(channel))); + client.on("guildBanAdd", (ban) => events.GuildBanAdd.forEach((fn) => fn(ban))); + client.on("guildBanRemove", (ban) => events.GuildBanRemove.forEach((fn) => fn(ban))); + client.on("guildCreate", (guild) => events.GuildCreate.forEach((fn) => fn(guild))); + client.on("guildMemberAdd", (member) => events.GuildMemberAdd.forEach((fn) => fn(member))); + client.on("guildMemberRemove", (member) => events.GuildMemberRemove.forEach((fn) => fn(member))); + client.on("guildMemberUpdate", (oldMember, newMember) => events.GuildMemebrUpdate.forEach((fn) => fn(oldMember, newMember))); + client.on("messageCreate", (message) => events.MessageCreate.forEach((fn) => fn(message))); + client.on("messageDelete", (message) => events.MessageDelete.forEach((fn) => fn(message))); + client.on("messageUpdate", (oldMessage, newMessage) => events.MessageUpdate.forEach((fn) => fn(oldMessage, newMessage))); } } diff --git a/src/commands/about.ts b/src/commands/about.ts index 6e065cc..3bfcdac 100644 --- a/src/commands/about.ts +++ b/src/commands/about.ts @@ -6,9 +6,9 @@ export default class About extends Command { constructor() { super(); - super.CommandBuilder = new SlashCommandBuilder() - .setName('about') - .setDescription('About Bot'); + this.CommandBuilder = new SlashCommandBuilder() + .setName("about") + .setDescription("About Bot"); } public override async execute(interaction: CommandInteraction) { diff --git a/src/commands/drop.ts b/src/commands/drop.ts index 5a8ccd9..3e7101b 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -1,4 +1,4 @@ -import { AttachmentBuilder, CommandInteraction, DiscordAPIError, SlashCommandBuilder } from "discord.js"; +import { AttachmentBuilder, CommandInteraction, SlashCommandBuilder } from "discord.js"; import { Command } from "../type/command"; import { readFileSync } from "fs"; import { CoreClient } from "../client/client"; @@ -12,35 +12,33 @@ export default class Drop extends Command { constructor() { super(); - super.CommandBuilder = new SlashCommandBuilder() - .setName('drop') - .setDescription('Summon a new card drop'); + this.CommandBuilder = new SlashCommandBuilder() + .setName("drop") + .setDescription("Summon a new card drop"); } public override async execute(interaction: CommandInteraction) { if (!CoreClient.AllowDrops) { - await interaction.reply('Bot is currently syncing, please wait until its done.'); + await interaction.reply("Bot is currently syncing, please wait until its done."); return; } - if (await Config.GetValue('safemode') == "true") { - await interaction.reply('Safe Mode has been activated, please resync to continue.'); + if (await Config.GetValue("safemode") == "true") { + await interaction.reply("Safe Mode has been activated, please resync to continue."); return; } const randomCard = CardDropHelperMetadata.GetRandomCard(); if (!randomCard) { - await interaction.reply('Unable to fetch card, please try again.'); + await interaction.reply("Unable to fetch card, please try again."); return; } try { - let image: Buffer; + const image = readFileSync(path.join(process.env.DATA_DIR!, "cards", randomCard.card.path)); const imageFileName = randomCard.card.path.split("/").pop()!; - image = readFileSync(path.join(process.cwd(), 'cards', randomCard.card.path)); - await interaction.deferReply(); const attachment = new AttachmentBuilder(image, { name: imageFileName }); diff --git a/src/commands/gdrivesync.ts b/src/commands/gdrivesync.ts index 8b60722..be36fc1 100644 --- a/src/commands/gdrivesync.ts +++ b/src/commands/gdrivesync.ts @@ -9,37 +9,37 @@ export default class Gdrivesync extends Command { constructor() { super(); - super.CommandBuilder = new SlashCommandBuilder() - .setName('gdrivesync') - .setDescription('Sync google drive to the bot') + this.CommandBuilder = new SlashCommandBuilder() + .setName("gdrivesync") + .setDescription("Sync google drive to the bot") .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator); } public override async execute(interaction: CommandInteraction) { if (!interaction.isChatInputCommand()) return; - const whitelistedUsers = process.env.GDRIVESYNC_WHITELIST!.split(','); + const whitelistedUsers = process.env.BOT_ADMINS!.split(","); if (!whitelistedUsers.find(x => x == interaction.user.id)) { await interaction.reply("Only whitelisted users can use this command."); return; } - await interaction.reply('Syncing, this might take a while...'); + await interaction.reply("Syncing, this might take a while..."); CoreClient.AllowDrops = false; - exec(`rclone sync card-drop-gdrive: ${process.cwd()}/cards`, async (error: ExecException | null) => { + exec(`rclone sync card-drop-gdrive: ${process.env.DATA_DIR}/cards`, async (error: ExecException | null) => { if (error) { await interaction.editReply(`Error while running sync command. Safe Mode has been activated. Code: ${error.code}`); - await Config.SetValue('safemode', 'true'); + await Config.SetValue("safemode", "true"); } else { await CardMetadataFunction.Execute(); - await interaction.editReply('Synced successfully.'); + await interaction.editReply("Synced successfully."); CoreClient.AllowDrops = true; - await Config.SetValue('safemode', 'false'); + await Config.SetValue("safemode", "false"); } }); } diff --git a/src/commands/give.ts b/src/commands/give.ts new file mode 100644 index 0000000..ad360a9 --- /dev/null +++ b/src/commands/give.ts @@ -0,0 +1,68 @@ +import { CacheType, CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; +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"; + +export default class Give extends Command { + constructor() { + super(); + + this.CommandBuilder = new SlashCommandBuilder() + .setName("give") + .setDescription("Give a user a card manually, in case bot breaks") + .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator) + .addStringOption(x => + x + .setName("cardnumber") + .setDescription("G") + .setRequired(true)) + .addUserOption(x => + x + .setName("user") + .setDescription("The user to give the card to") + .setRequired(true)); + } + + public override async execute(interaction: CommandInteraction) { + if (!CoreClient.AllowDrops) { + await interaction.reply("Bot is currently syncing, please wait until its done."); + return; + } + + if (await Config.GetValue("safemode") == "true") { + await interaction.reply("Safe Mode has been activated, please resync to continue."); + return; + } + + const whitelistedUsers = process.env.BOT_ADMINS!.split(","); + + if (!whitelistedUsers.find(x => x == interaction.user.id)) { + await interaction.reply("Only whitelisted users can use this command."); + return; + } + + const cardNumber = interaction.options.get("cardnumber", true); + const user = interaction.options.getUser("user", true); + + const card = CardDropHelperMetadata.GetCardByCardNumber(cardNumber.value!.toString()); + + if (!card) { + await interaction.reply("Unable to fetch card, please try again."); + return; + } + + let inventory = await Inventory.FetchOneByCardNumberAndUserId(user.id, card.id); + + if (!inventory) { + inventory = new Inventory(user.id, card.id, 1); + } else { + inventory.SetQuantity(inventory.Quantity + 1); + } + + await inventory.Save(Inventory, inventory); + + await interaction.reply(`${card.name} given to ${interaction.user}, they now have ${inventory.Quantity}`); + } +} \ No newline at end of file diff --git a/src/commands/inventory.ts b/src/commands/inventory.ts new file mode 100644 index 0000000..7ab951f --- /dev/null +++ b/src/commands/inventory.ts @@ -0,0 +1,38 @@ +import { CommandInteraction, SlashCommandBuilder } from "discord.js"; +import { Command } from "../type/command"; +import InventoryHelper from "../helpers/InventoryHelper"; + +export default class Inventory extends Command { + constructor() { + super(); + + this.CommandBuilder = new SlashCommandBuilder() + .setName("inventory") + .setDescription("View your inventory") + .addNumberOption(x => + x + .setName("page") + .setDescription("The page to start with")); + } + + public override async execute(interaction: CommandInteraction) { + const page = interaction.options.get("page"); + + try { + let pageNumber = 0; + + if (page && page.value) { + pageNumber = Number(page.value) - 1; + } + + const embed = await InventoryHelper.GenerateInventoryPage(interaction.user.username, interaction.user.id, pageNumber); + + await interaction.reply({ + embeds: [ embed.embed ], + components: [ embed.row ], + }); + } catch { + await interaction.reply("No page for user found."); + } + } +} \ No newline at end of file diff --git a/src/commands/resync.ts b/src/commands/resync.ts index f1684b6..7040d52 100644 --- a/src/commands/resync.ts +++ b/src/commands/resync.ts @@ -7,27 +7,27 @@ export default class Resync extends Command { constructor() { super(); - super.CommandBuilder = new SlashCommandBuilder() - .setName('resync') - .setDescription('Resync the card database') + this.CommandBuilder = new SlashCommandBuilder() + .setName("resync") + .setDescription("Resync the card database") .setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator); } public override async execute(interaction: CommandInteraction) { if (!interaction.isChatInputCommand()) return; - const whitelistedUsers = process.env.GDRIVESYNC_WHITELIST!.split(','); + const whitelistedUsers = process.env.BOT_ADMINS!.split(","); if (!whitelistedUsers.find(x => x == interaction.user.id)) { await interaction.reply("Only whitelisted users can use this command."); return; } - let result = await CardMetadataFunction.Execute(true); + const result = await CardMetadataFunction.Execute(true); if (result) { - if (await Config.GetValue('safemode') == "true") { - await Config.SetValue('safemode', 'false'); + if (await Config.GetValue("safemode") == "true") { + await Config.SetValue("safemode", "false"); await interaction.reply("Resynced database and disabled safe mode."); return; diff --git a/src/commands/stage/dropnumber.ts b/src/commands/stage/dropnumber.ts index a7de021..0642327 100644 --- a/src/commands/stage/dropnumber.ts +++ b/src/commands/stage/dropnumber.ts @@ -11,23 +11,23 @@ export default class Dropnumber extends Command { constructor() { super(); - super.CommandBuilder = new SlashCommandBuilder() - .setName('dropnumber') - .setDescription('(TEST) Summon a specific card') + this.CommandBuilder = new SlashCommandBuilder() + .setName("dropnumber") + .setDescription("(TEST) Summon a specific card") .addStringOption(x => x - .setName('cardnumber') - .setDescription('The card number to summon') + .setName("cardnumber") + .setDescription("The card number to summon") .setRequired(true)); } public override async execute(interaction: CommandInteraction) { if (!interaction.isChatInputCommand()) return; - const cardNumber = interaction.options.get('cardnumber'); + const cardNumber = interaction.options.get("cardnumber"); if (!cardNumber || !cardNumber.value) { - await interaction.reply('Card Number is required'); + await interaction.reply("Card Number is required"); return; } @@ -36,7 +36,7 @@ export default class Dropnumber extends Command { .find(x => x.id == cardNumber.value); if (!card) { - await interaction.reply('Card not found'); + await interaction.reply("Card not found"); return; } @@ -47,7 +47,7 @@ export default class Dropnumber extends Command { const imageFileName = card.path.split("/").pop()!; try { - image = readFileSync(path.join(process.cwd(), 'cards', card.path)); + image = readFileSync(path.join(process.env.DATA_DIR!, "cards", card.path)); } catch { await interaction.reply(`Unable to fetch image for card ${card.id}`); return; @@ -78,7 +78,7 @@ export default class Dropnumber extends Command { 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`); + 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/stage/droprarity.ts b/src/commands/stage/droprarity.ts index efe431f..be0a62d 100644 --- a/src/commands/stage/droprarity.ts +++ b/src/commands/stage/droprarity.ts @@ -12,37 +12,37 @@ export default class Droprarity extends Command { constructor() { super(); - super.CommandBuilder = new SlashCommandBuilder() - .setName('droprarity') - .setDescription('(TEST) Summon a random card of a specific rarity') + this.CommandBuilder = new SlashCommandBuilder() + .setName("droprarity") + .setDescription("(TEST) Summon a random card of a specific rarity") .addStringOption(x => x - .setName('rarity') - .setDescription('The rarity you want to summon') + .setName("rarity") + .setDescription("The rarity you want to summon") .setRequired(true)); } public override async execute(interaction: CommandInteraction) { if (!interaction.isChatInputCommand()) return; - const rarity = interaction.options.get('rarity'); + const rarity = interaction.options.get("rarity"); if (!rarity || !rarity.value) { - await interaction.reply('Rarity is required'); + await interaction.reply("Rarity is required"); return; } const rarityType = CardRarityParse(rarity.value.toString()); if (rarityType == CardRarity.Unknown) { - await interaction.reply('Invalid rarity'); + await interaction.reply("Invalid rarity"); return; } const card = await CardDropHelperMetadata.GetRandomCardByRarity(rarityType); if (!card) { - await interaction.reply('Card not found'); + await interaction.reply("Card not found"); return; } @@ -50,7 +50,7 @@ export default class Droprarity extends Command { const imageFileName = card.card.path.split("/").pop()!; try { - image = readFileSync(path.join(process.cwd(), 'cards', card.card.path)); + 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; @@ -81,7 +81,7 @@ export default class Droprarity extends Command { 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`); + await interaction.editReply("Unable to send next drop. Please try again, and report this if it keeps happening. Code: UNKNOWN"); } } diff --git a/src/constants/CardRarity.ts b/src/constants/CardRarity.ts index 629130a..8202a12 100644 --- a/src/constants/CardRarity.ts +++ b/src/constants/CardRarity.ts @@ -11,51 +11,51 @@ export enum CardRarity { export function CardRarityToString(rarity: CardRarity): string { switch (rarity) { - case CardRarity.Unknown: - return "Unknown"; - case CardRarity.Bronze: - return "Bronze"; - case CardRarity.Silver: - return "Silver"; - case CardRarity.Gold: - return "Gold"; - case CardRarity.Legendary: - return "Legendary"; - case CardRarity.Manga: - return "Manga"; + case CardRarity.Unknown: + return "Unknown"; + case CardRarity.Bronze: + return "Bronze"; + case CardRarity.Silver: + return "Silver"; + case CardRarity.Gold: + return "Gold"; + case CardRarity.Legendary: + return "Legendary"; + case CardRarity.Manga: + return "Manga"; } } export function CardRarityToColour(rarity: CardRarity): number { switch (rarity) { - case CardRarity.Unknown: - return EmbedColours.Grey; - case CardRarity.Bronze: - return EmbedColours.BronzeCard; - case CardRarity.Silver: - return EmbedColours.SilverCard; - case CardRarity.Gold: - return EmbedColours.GoldCard; - case CardRarity.Legendary: - return EmbedColours.LegendaryCard; - case CardRarity.Manga: - return EmbedColours.MangaCard; + case CardRarity.Unknown: + return EmbedColours.Grey; + case CardRarity.Bronze: + return EmbedColours.BronzeCard; + case CardRarity.Silver: + return EmbedColours.SilverCard; + case CardRarity.Gold: + return EmbedColours.GoldCard; + case CardRarity.Legendary: + return EmbedColours.LegendaryCard; + case CardRarity.Manga: + return EmbedColours.MangaCard; } } export function CardRarityParse(rarity: string): CardRarity { switch (rarity.toLowerCase()) { - case "bronze": - return CardRarity.Bronze; - case "silver": - return CardRarity.Silver; - case "gold": - return CardRarity.Gold; - case "legendary": - return CardRarity.Legendary; - case "manga": - return CardRarity.Manga; - default: - return CardRarity.Unknown; + case "bronze": + return CardRarity.Bronze; + case "silver": + return CardRarity.Silver; + case "gold": + return CardRarity.Gold; + case "legendary": + return CardRarity.Legendary; + case "manga": + return CardRarity.Manga; + default: + return CardRarity.Unknown; } } \ No newline at end of file diff --git a/src/contracts/AppBaseEntity.ts b/src/contracts/AppBaseEntity.ts index 8419f00..b9ca565 100644 --- a/src/contracts/AppBaseEntity.ts +++ b/src/contracts/AppBaseEntity.ts @@ -11,13 +11,13 @@ export default class AppBaseEntity { } @PrimaryColumn() - Id: string; + Id: string; @Column() - WhenCreated: Date; + WhenCreated: Date; @Column() - WhenUpdated: Date; + WhenUpdated: Date; public async Save(target: EntityTarget, entity: DeepPartial): Promise { this.WhenUpdated = new Date(); diff --git a/src/contracts/IButtonEventItem.ts b/src/contracts/ButtonEventItem.ts similarity index 74% rename from src/contracts/IButtonEventItem.ts rename to src/contracts/ButtonEventItem.ts index 061a9c9..e139334 100644 --- a/src/contracts/IButtonEventItem.ts +++ b/src/contracts/ButtonEventItem.ts @@ -1,8 +1,10 @@ import { Environment } from "../constants/Environment"; import { ButtonEvent } from "../type/buttonEvent"; -export default interface IButtonEventItem { +interface ButtonEventItem { ButtonId: string, Event: ButtonEvent, Environment: Environment, -} \ No newline at end of file +} + +export default ButtonEventItem; \ No newline at end of file diff --git a/src/contracts/EventExecutors.ts b/src/contracts/EventExecutors.ts new file mode 100644 index 0000000..0696f45 --- /dev/null +++ b/src/contracts/EventExecutors.ts @@ -0,0 +1,19 @@ + +import { DMChannel, Guild, GuildBan, GuildMember, Message, NonThreadGuildBasedChannel, PartialGuildMember, PartialMessage } from "discord.js"; + +interface EventExecutors { + ChannelCreate: ((channel: NonThreadGuildBasedChannel) => void)[], + ChannelDelete: ((channel: DMChannel | NonThreadGuildBasedChannel) => void)[], + ChannelUpdate: ((channel: DMChannel | NonThreadGuildBasedChannel) => void)[], + GuildBanAdd: ((ban: GuildBan) => void)[], + GuildBanRemove: ((ban: GuildBan) => void)[], + GuildCreate: ((guild: Guild) => void)[], + GuildMemberAdd: ((member: GuildMember) => void)[], + GuildMemberRemove: ((member: GuildMember | PartialGuildMember) => void)[], + GuildMemebrUpdate: ((oldMember: GuildMember | PartialGuildMember, newMember: GuildMember) => void)[], + MessageCreate: ((message: Message) => void)[], + MessageDelete: ((message: Message | PartialMessage) => void)[], + MessageUpdate: ((oldMessage: Message | PartialMessage, newMessage: Message | PartialMessage) => void)[], +} + +export default EventExecutors; \ No newline at end of file diff --git a/src/contracts/ICommandItem.ts b/src/contracts/ICommandItem.ts index 3ebc670..0524a8d 100644 --- a/src/contracts/ICommandItem.ts +++ b/src/contracts/ICommandItem.ts @@ -1,9 +1,11 @@ import { Environment } from "../constants/Environment"; import { Command } from "../type/command"; -export default interface ICommandItem { +interface ICommandItem { Name: string, Command: Command, Environment: Environment, ServerId?: string, -} \ No newline at end of file +} + +export default ICommandItem; \ No newline at end of file diff --git a/src/contracts/IEventItem.ts b/src/contracts/IEventItem.ts deleted file mode 100644 index b7cc7bf..0000000 --- a/src/contracts/IEventItem.ts +++ /dev/null @@ -1,9 +0,0 @@ - -import { Environment } from "../constants/Environment"; -import { EventType } from "../constants/EventType"; - -export default interface IEventItem { - EventType: EventType, - ExecutionFunction: Function, - Environment: Environment, -} \ No newline at end of file diff --git a/src/contracts/IGDriveFolderListing.ts b/src/contracts/IGDriveFolderListing.ts index 95e8609..1187bca 100644 --- a/src/contracts/IGDriveFolderListing.ts +++ b/src/contracts/IGDriveFolderListing.ts @@ -1,4 +1,4 @@ -export default interface IGDriveFolderListing { +export interface IGDriveFolderListing { id: string, name: string, -}; \ No newline at end of file +} \ No newline at end of file diff --git a/src/contracts/SeriesMetadata.ts b/src/contracts/SeriesMetadata.ts index 3ef95c0..c363028 100644 --- a/src/contracts/SeriesMetadata.ts +++ b/src/contracts/SeriesMetadata.ts @@ -1,6 +1,6 @@ import { CardRarity } from "../constants/CardRarity"; -export default interface SeriesMetadata { +export interface SeriesMetadata { id: number, name: string, cards: CardMetadata[], diff --git a/src/database/entities/app/Claim.ts b/src/database/entities/app/Claim.ts index b4cde5e..7cdee38 100644 --- a/src/database/entities/app/Claim.ts +++ b/src/database/entities/app/Claim.ts @@ -12,10 +12,10 @@ export default class Claim extends AppBaseEntity { } @Column() - ClaimId: string; + ClaimId: string; @ManyToOne(() => Inventory, x => x.Claims) - Inventory: Inventory; + Inventory: Inventory; public SetInventory(inventory: Inventory) { this.Inventory = inventory; diff --git a/src/database/entities/app/Config.ts b/src/database/entities/app/Config.ts index 50915d0..e97728a 100644 --- a/src/database/entities/app/Config.ts +++ b/src/database/entities/app/Config.ts @@ -12,10 +12,10 @@ export default class Config extends AppBaseEntity { } @Column() - Key: string; + Key: string; @Column() - Value: string; + Value: string; public SetValue(value: string) { this.Value = value; diff --git a/src/database/entities/app/Inventory.ts b/src/database/entities/app/Inventory.ts index adec824..bde4450 100644 --- a/src/database/entities/app/Inventory.ts +++ b/src/database/entities/app/Inventory.ts @@ -14,16 +14,16 @@ export default class Inventory extends AppBaseEntity { } @Column() - UserId: string; + UserId: string; @Column() - CardNumber: string; + CardNumber: string; @Column() - Quantity: number; + Quantity: number; @OneToMany(() => Claim, x => x.Inventory) - Claims: Claim[]; + Claims: Claim[]; public SetQuantity(quantity: number) { this.Quantity = quantity; @@ -40,4 +40,12 @@ export default class Inventory extends AppBaseEntity { return single; } + + public static async FetchAllByUserId(userId: string): Promise { + const repository = AppDataSource.getRepository(Inventory); + + const all = await repository.find({ where: { UserId: userId }}); + + return all; + } } \ No newline at end of file diff --git a/src/database/migrations/app/0.1.5/1694609771821-CreateClaim.ts b/src/database/migrations/app/0.1.5/1694609771821-CreateClaim.ts index 22fe74c..ed048c7 100644 --- a/src/database/migrations/app/0.1.5/1694609771821-CreateClaim.ts +++ b/src/database/migrations/app/0.1.5/1694609771821-CreateClaim.ts @@ -1,17 +1,17 @@ -import { MigrationInterface, QueryRunner } from "typeorm" -import MigrationHelper from "../../../../helpers/MigrationHelper" +import { MigrationInterface, QueryRunner } from "typeorm"; +import MigrationHelper from "../../../../helpers/MigrationHelper"; export class CreateClaim1694609771821 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { - MigrationHelper.Up('1694609771821-CreateClaim', '0.1.5', [ - '01-CreateClaim', - '02-MoveToClaim', - '03-AlterInventory', + MigrationHelper.Up("1694609771821-CreateClaim", "0.1.5", [ + "01-CreateClaim", + "02-MoveToClaim", + "03-AlterInventory", ], queryRunner); } - public async down(queryRunner: QueryRunner): Promise { + public async down(): Promise { } } diff --git a/src/database/migrations/app/0.1/1693769942868-CreateBase.ts b/src/database/migrations/app/0.1/1693769942868-CreateBase.ts index 709cd3d..006aa55 100644 --- a/src/database/migrations/app/0.1/1693769942868-CreateBase.ts +++ b/src/database/migrations/app/0.1/1693769942868-CreateBase.ts @@ -1,15 +1,15 @@ -import { MigrationInterface, QueryRunner } from "typeorm" -import MigrationHelper from "../../../../helpers/MigrationHelper" +import { MigrationInterface, QueryRunner } from "typeorm"; +import MigrationHelper from "../../../../helpers/MigrationHelper"; export class CreateBase1693769942868 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { - MigrationHelper.Up('1693769942868-CreateBase', '0.1', [ + MigrationHelper.Up("1693769942868-CreateBase", "0.1", [ "01-table/Inventory", ], queryRunner); } - public async down(queryRunner: QueryRunner): Promise { + public async down(): Promise { } } diff --git a/src/database/migrations/app/0.2/1699814500650-createConfig.ts b/src/database/migrations/app/0.2/1699814500650-createConfig.ts index 0a1f22e..2725eee 100644 --- a/src/database/migrations/app/0.2/1699814500650-createConfig.ts +++ b/src/database/migrations/app/0.2/1699814500650-createConfig.ts @@ -1,15 +1,15 @@ -import { MigrationInterface, QueryRunner } from "typeorm" -import MigrationHelper from "../../../../helpers/MigrationHelper" +import { MigrationInterface, QueryRunner } from "typeorm"; +import MigrationHelper from "../../../../helpers/MigrationHelper"; export class CreateConfig1699814500650 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { - MigrationHelper.Up('1699814500650-createConfig', '0.2', [ + MigrationHelper.Up("1699814500650-createConfig", "0.2", [ "01-table/Config", ], queryRunner); } - public async down(queryRunner: QueryRunner): Promise { + public async down(): Promise { } } diff --git a/src/helpers/CardDropHelperMetadata.ts b/src/helpers/CardDropHelperMetadata.ts index 9d26609..27eebb8 100644 --- a/src/helpers/CardDropHelperMetadata.ts +++ b/src/helpers/CardDropHelperMetadata.ts @@ -1,7 +1,7 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; import { CardRarity, CardRarityToColour, CardRarityToString } from "../constants/CardRarity"; import CardRarityChances from "../constants/CardRarityChances"; -import { DropResult } from "../contracts/SeriesMetadata"; +import { CardMetadata, DropResult } from "../contracts/SeriesMetadata"; import { CoreClient } from "../client/client"; export default class CardDropHelperMetadata { @@ -47,7 +47,15 @@ export default class CardDropHelperMetadata { }; } - public static GenerateDropEmbed(drop: DropResult, quantityClaimed: Number, imageFileName: string): EmbedBuilder { + public static GetCardByCardNumber(cardNumber: string): CardMetadata | undefined { + const card = CoreClient.Cards + .flatMap(x => x.cards) + .find(x => x.id == cardNumber); + + return card; + } + + public static GenerateDropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string): EmbedBuilder { let description = ""; description += `Series: ${drop.series.name}\n`; description += `Claimed: ${quantityClaimed}\n`; @@ -68,7 +76,7 @@ export default class CardDropHelperMetadata { .setLabel("Claim") .setStyle(ButtonStyle.Primary), new ButtonBuilder() - .setCustomId(`reroll`) + .setCustomId("reroll") .setLabel("Reroll") .setStyle(ButtonStyle.Secondary)); } diff --git a/src/helpers/InventoryHelper.ts b/src/helpers/InventoryHelper.ts new file mode 100644 index 0000000..3f4e4e9 --- /dev/null +++ b/src/helpers/InventoryHelper.ts @@ -0,0 +1,98 @@ +import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; +import Inventory from "../database/entities/app/Inventory"; +import { CoreClient } from "../client/client"; +import EmbedColours from "../constants/EmbedColours"; +import { CardRarity, CardRarityToString } from "../constants/CardRarity"; + +interface InventoryPage { + id: number, + name: string, + cards: InventoryPageCards[], + seriesSubpage: number, +} + +interface InventoryPageCards { + id: string, + name: string, + type: CardRarity, + quantity: number, +} + +export default class InventoryHelper { + public static async GenerateInventoryPage(username: string, userid: string, page: number): Promise<{ embed: EmbedBuilder, row: ActionRowBuilder }> { + const cardsPerPage = 15; + + const inventory = await Inventory.FetchAllByUserId(userid); + + const allSeriesClaimed = CoreClient.Cards + .sort((a, b) => a.id - b.id) + .filter(x => { + x.cards = x.cards + .sort((a, b) => b.type - a.type) + .filter(y => inventory.find(z => z.CardNumber == y.id)); + + return x; + }); + + const pages: InventoryPage[] = []; + + for (const series of allSeriesClaimed) { + const seriesCards = series.cards; + + for (let i = 0; i < seriesCards.length; i+= cardsPerPage) { + const cards = series.cards.slice(i, i + cardsPerPage); + const pageCards: InventoryPageCards[] = []; + + for (const card of cards) { + const item = inventory.find(x => x.CardNumber == card.id); + + if (!item) { + continue; + } + + pageCards.push({ + id: card.id, + name: card.name, + type: card.type, + quantity: item.Quantity, + }); + } + + pages.push({ + id: series.id, + name: series.name, + cards: pageCards, + seriesSubpage: i / cardsPerPage, + }); + } + } + + const currentPage = pages[page]; + + if (!currentPage) { + console.error("Unable to find page"); + return Promise.reject("Unable to find page"); + } + + const embed = new EmbedBuilder() + .setTitle(username) + .setDescription(`**${currentPage.name} (${currentPage.seriesSubpage + 1})**\n${currentPage.cards.map(x => `[${x.id}] ${x.name} (${CardRarityToString(x.type)}) x${x.quantity}`).join("\n")}`) + .setFooter({ text: `Page ${page + 1} of ${pages.length}` }) + .setColor(EmbedColours.Ok); + + const row = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId(`inventory ${userid} ${page - 1}`) + .setLabel("Previous") + .setStyle(ButtonStyle.Primary) + .setDisabled(page == 0), + new ButtonBuilder() + .setCustomId(`inventory ${userid} ${page + 1}`) + .setLabel("Next") + .setStyle(ButtonStyle.Primary) + .setDisabled(page + 1 == pages.length)); + + return { embed, row }; + } +} \ No newline at end of file diff --git a/src/helpers/MigrationHelper.ts b/src/helpers/MigrationHelper.ts index 69fee4a..5946cb1 100644 --- a/src/helpers/MigrationHelper.ts +++ b/src/helpers/MigrationHelper.ts @@ -3,7 +3,7 @@ import { QueryRunner } from "typeorm"; export default class MigrationHelper { public static Up(migrationName: string, version: string, queryFiles: string[], queryRunner: QueryRunner) { - for (let path of queryFiles) { + for (const path of queryFiles) { const query = readFileSync(`${process.cwd()}/database/${version}/${migrationName}/Up/${path}.sql`).toString(); queryRunner.query(query); @@ -11,7 +11,7 @@ export default class MigrationHelper { } public static Down(migrationName: string, version: string, queryFiles: string[], queryRunner: QueryRunner) { - for (let path of queryFiles) { + for (const path of queryFiles) { const query = readFileSync(`${process.cwd()}/database/${version}/${migrationName}/Down/${path}.sql`).toString(); queryRunner.query(query); diff --git a/src/helpers/StringTools.ts b/src/helpers/StringTools.ts index 0254dc5..cb5591a 100644 --- a/src/helpers/StringTools.ts +++ b/src/helpers/StringTools.ts @@ -1,7 +1,7 @@ export default class StringTools { public static Capitalise(str: string): string { const words = str.split(" "); - let result: string[] = []; + const result: string[] = []; words.forEach(word => { const firstLetter = word.substring(0, 1).toUpperCase(); @@ -26,17 +26,17 @@ export default class StringTools { public static RandomString(length: number) { let result = ""; - const characters = 'abcdefghkmnpqrstuvwxyz23456789'; + const characters = "abcdefghkmnpqrstuvwxyz23456789"; const charactersLength = characters.length; - for ( var i = 0; i < length; i++ ) { - result += characters.charAt(Math.floor(Math.random() * charactersLength)); + for ( let i = 0; i < length; i++ ) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } public static ReplaceAll(str: string, find: string, replace: string) { - return str.replace(new RegExp(find, 'g'), replace); + return str.replace(new RegExp(find, "g"), replace); } } \ No newline at end of file diff --git a/src/helpers/TimeLengthInput.ts b/src/helpers/TimeLengthInput.ts index 95befa6..d1d8734 100644 --- a/src/helpers/TimeLengthInput.ts +++ b/src/helpers/TimeLengthInput.ts @@ -4,23 +4,23 @@ export default class TimeLengthInput { public readonly value: string; constructor(input: string) { - this.value = StringTools.ReplaceAll(input, ',', ''); + this.value = StringTools.ReplaceAll(input, ",", ""); } public GetDays(): number { - return this.GetValue('d'); + return this.GetValue("d"); } public GetHours(): number { - return this.GetValue('h'); + return this.GetValue("h"); } public GetMinutes(): number { - return this.GetValue('m'); + return this.GetValue("m"); } public GetSeconds(): number { - return this.GetValue('s'); + return this.GetValue("s"); } public GetMilliseconds(): number { @@ -106,7 +106,7 @@ export default class TimeLengthInput { } private GetValue(designation: string): number { - const valueSplit = this.value.split(' '); + const valueSplit = this.value.split(" "); const desString = valueSplit.find(x => x.charAt(x.length - 1) == designation); diff --git a/src/hooks/ReloadDB.ts b/src/hooks/ReloadDB.ts index 72da369..0f1c026 100644 --- a/src/hooks/ReloadDB.ts +++ b/src/hooks/ReloadDB.ts @@ -2,7 +2,7 @@ import { Request, Response } from "express"; import CardMetadataFunction from "../Functions/CardMetadataFunction"; export default async function ReloadDB(req: Request, res: Response) { - console.log('Reloading Card DB...'); + console.log("Reloading Card DB..."); await CardMetadataFunction.Execute(); diff --git a/src/registry.ts b/src/registry.ts index e602198..a7cf494 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -1,9 +1,12 @@ import { CoreClient } from "./client/client"; +import { Environment } from "./constants/Environment"; // Global Command Imports import About from "./commands/about"; import Drop from "./commands/drop"; import Gdrivesync from "./commands/gdrivesync"; +import Give from "./commands/give"; +import Inventory from "./commands/inventory"; import Resync from "./commands/resync"; // Test Command Imports @@ -12,20 +15,22 @@ import Droprarity from "./commands/stage/droprarity"; // Button Event Imports import Claim from "./buttonEvents/Claim"; +import InventoryButtonEvent from "./buttonEvents/Inventory"; import Reroll from "./buttonEvents/Reroll"; -import { Environment } from "./constants/Environment"; export default class Registry { public static RegisterCommands() { // Global Commands - CoreClient.RegisterCommand('about', new About()); - CoreClient.RegisterCommand('drop', new Drop()); - CoreClient.RegisterCommand('gdrivesync', new Gdrivesync()); - CoreClient.RegisterCommand('resync', new Resync()); + CoreClient.RegisterCommand("about", new About()); + CoreClient.RegisterCommand("drop", new Drop()); + CoreClient.RegisterCommand("gdrivesync", new Gdrivesync()); + CoreClient.RegisterCommand("give", new Give()); + CoreClient.RegisterCommand("inventory", new Inventory()); + CoreClient.RegisterCommand("resync", new Resync()); // Test Commands - CoreClient.RegisterCommand('dropnumber', new Dropnumber(), Environment.Test); - CoreClient.RegisterCommand('droprarity', new Droprarity(), Environment.Test); + CoreClient.RegisterCommand("dropnumber", new Dropnumber(), Environment.Test); + CoreClient.RegisterCommand("droprarity", new Droprarity(), Environment.Test); } public static RegisterEvents() { @@ -33,7 +38,8 @@ export default class Registry { } public static RegisterButtonEvents() { - CoreClient.RegisterButtonEvent('claim', new Claim()); - CoreClient.RegisterButtonEvent('reroll', new Reroll()); + CoreClient.RegisterButtonEvent("claim", new Claim()); + CoreClient.RegisterButtonEvent("inventory", new InventoryButtonEvent); + CoreClient.RegisterButtonEvent("reroll", new Reroll()); } } \ No newline at end of file diff --git a/src/type/buttonEvent.ts b/src/type/buttonEvent.ts index 3a691cf..8a45bd0 100644 --- a/src/type/buttonEvent.ts +++ b/src/type/buttonEvent.ts @@ -1,7 +1,5 @@ import { ButtonInteraction } from "discord.js"; -export class ButtonEvent { - public execute(interaction: ButtonInteraction) { - - } +export abstract class ButtonEvent { + abstract execute(interaction: ButtonInteraction): Promise; } \ No newline at end of file diff --git a/src/type/command.ts b/src/type/command.ts index 10d091d..20f5e3a 100644 --- a/src/type/command.ts +++ b/src/type/command.ts @@ -1,9 +1,7 @@ -import { CommandInteraction } from "discord.js"; +import { CommandInteraction, SlashCommandBuilder } from "discord.js"; -export class Command { - public CommandBuilder: any; - - public execute(interaction: CommandInteraction) { +export abstract class Command { + public CommandBuilder: Omit; - } + abstract execute(interaction: CommandInteraction): Promise; } diff --git a/src/webhooks.ts b/src/webhooks.ts index ec30720..cccb598 100644 --- a/src/webhooks.ts +++ b/src/webhooks.ts @@ -19,7 +19,7 @@ export default class Webhooks { } private setupRoutes() { - this.app.post('/api/reload-db', ReloadDB); + this.app.post("/api/reload-db", ReloadDB); } private setupListen() {