diff --git a/.drone.yml b/.drone.yml index 91d3643..962eb6c 100644 --- a/.drone.yml +++ b/.drone.yml @@ -93,6 +93,12 @@ steps: commands: - npm ci - npm run build + +- name: lint + image: node + commands: + - npm run lint + - name: test image: node commands: 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/package-lock.json b/package-lock.json index c56c9e3..c8b0b7c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,9 @@ }, "devDependencies": { "@types/node": "^20.0.0", + "@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" }, @@ -34,6 +37,15 @@ "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", @@ -790,6 +802,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 +944,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", @@ -1647,6 +1865,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, @@ -1688,6 +1912,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", @@ -1735,6 +1965,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", @@ -1761,6 +2299,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", @@ -1827,6 +2386,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, @@ -1994,6 +2569,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", @@ -3275,6 +3859,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", @@ -3570,6 +4160,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, @@ -3719,6 +4321,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", @@ -3730,6 +4586,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", @@ -3901,6 +4799,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, @@ -3927,6 +4831,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", @@ -3976,6 +4892,26 @@ "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", @@ -4323,6 +5259,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", @@ -6102,6 +7044,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", @@ -6148,6 +7102,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" @@ -6489,6 +7456,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" @@ -7760,6 +8733,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, @@ -8305,6 +9295,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/pretty-format": { "version": "29.7.0", "license": "MIT", @@ -8396,6 +9395,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, @@ -9581,6 +10589,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", @@ -9660,6 +10674,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", @@ -9731,6 +10757,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", @@ -10091,6 +11129,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 e3bc5f4..1dbe07e 100644 --- a/package.json +++ b/package.json @@ -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", @@ -43,6 +45,9 @@ }, "devDependencies": { "@types/node": "^20.0.0", + "@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/src/Functions/CardMetadataFunction.ts b/src/Functions/CardMetadataFunction.ts index eefe2a7..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.env.DATA_DIR!, '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 d880244..912fa3e 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -23,7 +23,7 @@ const requiredConfigs: string[] = [ "DB_LOGGING", "EXPRESS_PORT", "GDRIVESYNC_WHITELIST", -] +]; requiredConfigs.forEach(config => { if (!process.env[config]) { @@ -40,7 +40,7 @@ Registry.RegisterCommands(); Registry.RegisterEvents(); Registry.RegisterButtonEvents(); -if (!existsSync(`${process.env.DATA_DIR}/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; @@ -50,7 +50,7 @@ if (!existsSync(`${process.env.DATA_DIR}/cards`) && process.env.GDRIVESYNC_AUTO 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 index 63ea5a4..6a71029 100644 --- a/src/buttonEvents/Inventory.ts +++ b/src/buttonEvents/Inventory.ts @@ -4,8 +4,8 @@ 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]; + const userid = interaction.customId.split(" ")[1]; + const page = interaction.customId.split(" ")[2]; try { const embed = await InventoryHelper.GenerateInventoryPage(interaction.user.username, userid, Number(page)); diff --git a/src/buttonEvents/Reroll.ts b/src/buttonEvents/Reroll.ts index 7241db7..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.env.DATA_DIR!, '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 85ef43e..ca2fba3 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -1,24 +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 InventoryHelper from "../helpers/InventoryHelper"; +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; @@ -34,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[] { @@ -47,7 +45,6 @@ export class CoreClient extends Client { dotenv.config(); CoreClient._commandItems = []; - CoreClient._eventItems = []; CoreClient._buttonEvents = []; this._events = new Events(); @@ -75,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); } @@ -95,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 ], + }; } } @@ -119,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 fe08241..3e7101b 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -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.env.DATA_DIR!, '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 169e63c..2429b4d 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.GDRIVESYNC_WHITELIST!.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.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/inventory.ts b/src/commands/inventory.ts index 39d0881..7ab951f 100644 --- a/src/commands/inventory.ts +++ b/src/commands/inventory.ts @@ -7,16 +7,16 @@ export default class Inventory extends Command { super(); this.CommandBuilder = new SlashCommandBuilder() - .setName('inventory') - .setDescription('View your inventory') + .setName("inventory") + .setDescription("View your inventory") .addNumberOption(x => x - .setName('page') - .setDescription('The page to start with')); + .setName("page") + .setDescription("The page to start with")); } public override async execute(interaction: CommandInteraction) { - const page = interaction.options.get('page'); + const page = interaction.options.get("page"); try { let pageNumber = 0; diff --git a/src/commands/resync.ts b/src/commands/resync.ts index f1684b6..ace4c39 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.GDRIVESYNC_WHITELIST!.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 ddb53b1..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.env.DATA_DIR!, '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 b3e3bb7..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.env.DATA_DIR!, '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 cfe8c3d..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; 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..38d8304 100644 --- a/src/helpers/CardDropHelperMetadata.ts +++ b/src/helpers/CardDropHelperMetadata.ts @@ -47,7 +47,7 @@ export default class CardDropHelperMetadata { }; } - public static GenerateDropEmbed(drop: DropResult, quantityClaimed: Number, imageFileName: string): EmbedBuilder { + public static GenerateDropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string): EmbedBuilder { let description = ""; description += `Series: ${drop.series.name}\n`; description += `Claimed: ${quantityClaimed}\n`; @@ -68,7 +68,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 index ad4bf85..3f4e4e9 100644 --- a/src/helpers/InventoryHelper.ts +++ b/src/helpers/InventoryHelper.ts @@ -1,7 +1,6 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; import Inventory from "../database/entities/app/Inventory"; import { CoreClient } from "../client/client"; -import SeriesMetadata from "../contracts/SeriesMetadata"; import EmbedColours from "../constants/EmbedColours"; import { CardRarity, CardRarityToString } from "../constants/CardRarity"; @@ -37,14 +36,14 @@ export default class InventoryHelper { const pages: InventoryPage[] = []; - for (let series of allSeriesClaimed) { + 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 (let card of cards) { + for (const card of cards) { const item = inventory.find(x => x.CardNumber == card.id); if (!item) { @@ -77,7 +76,7 @@ export default class InventoryHelper { 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')}`) + .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); 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 679c70e..ab4dfad 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -20,15 +20,15 @@ import Reroll from "./buttonEvents/Reroll"; 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('inventory', new Inventory()); - CoreClient.RegisterCommand('resync', new Resync()); + CoreClient.RegisterCommand("about", new About()); + CoreClient.RegisterCommand("drop", new Drop()); + CoreClient.RegisterCommand("gdrivesync", new Gdrivesync()); + 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() { @@ -36,8 +36,8 @@ export default class Registry { } public static RegisterButtonEvents() { - CoreClient.RegisterButtonEvent('claim', new Claim()); - CoreClient.RegisterButtonEvent('inventory', new InventoryButtonEvent); - 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() {