From 9701e375441eeacb593da5757ab1e653eef3805e Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Tue, 2 Jan 2024 03:18:47 +0300 Subject: [PATCH 01/25] chore: npm install -D typescript --- package-lock.json | 24 ++++++++++++++++++++++-- package.json | 3 ++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 12f623b..2585ce6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "node.js-chatgpt-bot", "version": "1.1.2", - "license": "ISC", + "license": "MIT License", "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", "@grammyjs/ratelimiter": "^1.2.0", @@ -26,7 +26,8 @@ "cross-env": "^7.0.3", "eslint": "^8.53.0", "eslint-config-google": "^0.14.0", - "nodemon": "^2.0.22" + "nodemon": "^2.0.22", + "typescript": "^5.3.3" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -2525,6 +2526,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", @@ -4418,6 +4432,12 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true + }, "undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", diff --git a/package.json b/package.json index 8e4da64..aafbb44 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "cross-env": "^7.0.3", "eslint": "^8.53.0", "eslint-config-google": "^0.14.0", - "nodemon": "^2.0.22" + "nodemon": "^2.0.22", + "typescript": "^5.3.3" }, "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", From 02d2e6c82be6fa8e815b32ba76546d27794fbc26 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Fri, 5 Jan 2024 04:37:17 +0300 Subject: [PATCH 02/25] fix: fix error with redis and change configuration filling --- src/index.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/index.js b/src/index.js index cf9155b..4acfc06 100644 --- a/src/index.js +++ b/src/index.js @@ -7,7 +7,6 @@ import { sendMessages } from './utils/sendMessages.js'; import { LEXICON_EN } from './lexicon/lexicon_en.js'; import { setMenu } from './keyboards/set_menu.js'; import { deleteWebHook } from './utils/deleteWebhook.js'; - import UserHandlers from './handlers/userHandlers.js'; import OpenAIHandlers from './handlers/openaiHandlers.js'; import AdminHandlers from './handlers/adminHandlers.js'; @@ -15,15 +14,11 @@ import AdminHandlers from './handlers/adminHandlers.js'; import { Redis } from '@telegraf/session/redis'; import { limit } from '@grammyjs/ratelimiter'; -let config; - -if (process.env.NODE_ENV === 'production') { - config = JSON.parse(fs.readFileSync('config/production.json', 'utf8')); -} else { - config = JSON.parse(fs.readFileSync('config/default.json', 'utf8')); -} +let config = process.env.NODE_ENV === 'production' ? + JSON.parse(fs.readFileSync('config/production.json', 'utf8')) : + JSON.parse(fs.readFileSync('config/default.json', 'utf8')); -const store = Redis({ +const store = new Redis({ store: { host: config.REDIS_HOST, port: config.REDIS_PORT, From 17330b308db73e7c0f000885666e69239b53332e Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Fri, 5 Jan 2024 04:39:44 +0300 Subject: [PATCH 03/25] feat: add `tsconfig.json` --- tsconfig.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tsconfig.json diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..eacfec1 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,17 @@ +{ + "include": ["src/**/*"], + "compilerOptions": { + "baseUrl": "./", + "rootDir": "./src", + "outDir": "./build", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "resolveJsonModule": true, + "target": "ES6", + "strict": false, + "allowJs": true, + "checkJs": false, + "alwaysStrict": false, + "removeComments": true, + } +} \ No newline at end of file From 58f0e4c316eba910d9d420d7dc63d47546eae762 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Fri, 5 Jan 2024 04:40:49 +0300 Subject: [PATCH 04/25] dev!: add commands for production and development --- package-lock.json | 1857 ++++++++++++++++++++++++++++++++++++++++++--- package.json | 14 +- 2 files changed, 1782 insertions(+), 89 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2585ce6..fb18b8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,19 +14,23 @@ "@telegraf/session": "^2.0.0-beta.6", "axios": "^1.6.0", "config": "^3.3.9", + "copyfiles": "^2.4.1", "fluent-ffmpeg": "^2.1.2", "https-proxy-agent": "^7.0.2", "openai": "^4.20.0", "redis": "^4.6.10", "request": "^2.88.2", + "rimraf": "^5.0.5", "telegraf": "^4.12.2", "telegraf-ratelimit": "^2.0.0" }, "devDependencies": { + "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.53.0", "eslint-config-google": "^0.14.0", "nodemon": "^2.0.22", + "ts-node": "^10.9.2", "typescript": "^5.3.3" } }, @@ -39,6 +43,30 @@ "node": ">=0.10.0" } }, + "node_modules/@babel/runtime": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.7.tgz", + "integrity": "sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, "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", @@ -296,6 +324,72 @@ "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", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -331,6 +425,15 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@redis/bloom": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", @@ -430,6 +533,30 @@ "resolved": "https://registry.npmjs.org/@telegraf/types/-/types-6.9.1.tgz", "integrity": "sha512-bzqwhicZq401T0e09tu8b1KvGfJObPmzKU/iKCT5V466AsAZZWQrBYQ5edbmD1VZuHLEwopoOVY5wPP4HaLtug==" }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "node_modules/@types/node": { "version": "18.18.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", @@ -491,6 +618,15 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", + "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", @@ -553,7 +689,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -562,7 +697,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -586,6 +720,12 @@ "node": ">= 8" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -644,8 +784,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base-64": { "version": "0.1.0", @@ -673,7 +812,6 @@ "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" @@ -796,6 +934,50 @@ "fsevents": "~2.3.2" } }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/cluster-key-slot": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", @@ -808,7 +990,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -819,8 +1000,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -836,9 +1016,137 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concurrently": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", + "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/concurrently/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/concurrently/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/concurrently/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/config": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/config/-/config-3.3.9.tgz", @@ -850,11 +1158,54 @@ "node": ">= 10.0.0" } }, + "node_modules/copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", + "dependencies": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + }, + "bin": { + "copyfiles": "copyfiles", + "copyup": "copyfiles" + } + }, + "node_modules/copyfiles/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -877,7 +1228,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -906,6 +1256,22 @@ "node": ">=0.10" } }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -928,6 +1294,15 @@ "node": ">=0.4.0" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/digest-fetch": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz", @@ -949,6 +1324,11 @@ "node": ">=6.0.0" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -958,6 +1338,19 @@ "safer-buffer": "^2.1.0" } }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1259,6 +1652,41 @@ "node": ">=12.0.0" } }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/flatted": { "version": "3.2.9", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", @@ -1307,6 +1735,21 @@ } } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -1356,8 +1799,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/generic-pool": { "version": "3.9.0", @@ -1367,6 +1809,14 @@ "node": ">= 4" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -1376,20 +1826,21 @@ } }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1407,6 +1858,28 @@ "node": ">= 6" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "13.23.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", @@ -1557,7 +2030,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1566,8 +2038,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -1595,6 +2066,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -1630,6 +2109,11 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1640,6 +2124,23 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1746,12 +2247,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "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/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -1785,7 +2306,6 @@ "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" }, @@ -1793,6 +2313,25 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -1877,6 +2416,15 @@ "url": "https://opencollective.com/nodemon" } }, + "node_modules/noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + } + }, "node_modules/nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -1913,7 +2461,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -2017,7 +2564,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2026,11 +2572,25 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -2057,6 +2617,11 @@ "node": ">= 0.8.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -2109,6 +2674,17 @@ } ] }, + "node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -2134,6 +2710,12 @@ "@redis/time-series": "1.0.5" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -2178,6 +2760,14 @@ "node": ">= 0.12" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -2198,15 +2788,17 @@ } }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dependencies": { - "glob": "^7.1.3" + "glob": "^10.3.7" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -2235,6 +2827,15 @@ "queue-microtask": "^1.2.2" } }, + "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, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2288,7 +2889,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -2300,11 +2900,30 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/simple-update-notifier": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", @@ -2326,6 +2945,12 @@ "semver": "bin/semver.js" } }, + "node_modules/spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", + "dev": true + }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", @@ -2350,11 +2975,87 @@ "node": ">=0.10.0" } }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2445,6 +3146,47 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2486,6 +3228,64 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -2550,6 +3350,14 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "engines": { + "node": ">=8" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -2558,6 +3366,11 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "node_modules/uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -2567,6 +3380,12 @@ "uuid": "bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -2606,7 +3425,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -2617,17 +3435,171 @@ "node": ">= 8" } }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -2648,6 +3620,24 @@ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true }, + "@babel/runtime": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.7.tgz", + "integrity": "sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2811,6 +3801,56 @@ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2837,6 +3877,12 @@ "fastq": "^1.6.0" } }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true + }, "@redis/bloom": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", @@ -2888,6 +3934,30 @@ "resolved": "https://registry.npmjs.org/@telegraf/types/-/types-6.9.1.tgz", "integrity": "sha512-bzqwhicZq401T0e09tu8b1KvGfJObPmzKU/iKCT5V466AsAZZWQrBYQ5edbmD1VZuHLEwopoOVY5wPP4HaLtug==" }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "@types/node": { "version": "18.18.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", @@ -2938,6 +4008,12 @@ "dev": true, "requires": {} }, + "acorn-walk": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", + "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", + "dev": true + }, "agent-base": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", @@ -2983,14 +4059,12 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -3005,6 +4079,12 @@ "picomatch": "^2.0.4" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3057,8 +4137,7 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "base-64": { "version": "0.1.0", @@ -3083,7 +4162,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3176,6 +4254,43 @@ "readdirp": "~3.6.0" } }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, "cluster-key-slot": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", @@ -3185,7 +4300,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -3193,8 +4307,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "combined-stream": { "version": "1.0.8", @@ -3207,8 +4320,101 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "concurrently": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", + "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } }, "config": { "version": "3.3.9", @@ -3218,11 +4424,46 @@ "json5": "^2.2.3" } }, + "copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", + "requires": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -3236,7 +4477,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3256,6 +4496,15 @@ "assert-plus": "^1.0.0" } }, + "date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.21.0" + } + }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -3275,6 +4524,12 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "digest-fetch": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz", @@ -3293,6 +4548,11 @@ "esutils": "^2.0.2" } }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -3302,6 +4562,16 @@ "safer-buffer": "^2.1.0" } }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3521,6 +4791,31 @@ "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "flatted": { @@ -3553,6 +4848,15 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -3592,14 +4896,18 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "generic-pool": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==" }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3609,17 +4917,33 @@ } }, "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "glob-parent": { @@ -3740,7 +5064,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -3749,8 +5072,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "is-binary-path": { "version": "2.1.0", @@ -3772,6 +5094,11 @@ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -3798,6 +5125,11 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3808,6 +5140,15 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -3893,12 +5234,29 @@ "p-locate": "^5.0.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "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 }, + "lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==" + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -3926,11 +5284,20 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==" + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, "mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -3978,6 +5345,15 @@ "undefsafe": "^2.0.5" } }, + "noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + } + }, "nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -4002,7 +5378,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "requires": { "wrappy": "1" } @@ -4078,14 +5453,21 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "requires": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + } }, "performance-now": { "version": "2.1.0", @@ -4104,6 +5486,11 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -4136,6 +5523,17 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -4158,6 +5556,12 @@ "@redis/time-series": "1.0.5" } }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -4197,6 +5601,11 @@ } } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4210,12 +5619,11 @@ "dev": true }, "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "requires": { - "glob": "^7.1.3" + "glob": "^10.3.7" } }, "run-parallel": { @@ -4227,6 +5635,15 @@ "queue-microtask": "^1.2.2" } }, + "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, + "requires": { + "tslib": "^2.1.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4260,7 +5677,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -4268,9 +5684,19 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, "simple-update-notifier": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", @@ -4288,6 +5714,12 @@ } } }, + "spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", + "dev": true + }, "sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", @@ -4304,11 +5736,65 @@ "tweetnacl": "~0.14.0" } }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + } + } + }, "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, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } @@ -4372,6 +5858,49 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4404,6 +5933,39 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -4449,6 +6011,11 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==" + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -4457,11 +6024,22 @@ "punycode": "^2.1.0" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -4495,22 +6073,129 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index aafbb44..c403661 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,16 @@ { "name": "node.js-chatgpt-bot", "version": "1.1.2", - "description": "\"\"", + "description": "СhatGPT bot for telegram written on node.js", "main": "index.js", "type": "module", "scripts": { - "dev": "cross-env NODE_ENV=development nodemon ./src/index.js", - "start": "cross-env NODE_ENV=production node ./src/index.js" + "clean": "rimraf build/", + "build": "npm run clean && tsc", + "start": "cross-env NODE_ENV=production node build/index.js", + "watch-ts": "tsc -w", + "serve-debug": "cross-env NODE_ENV=development nodemon --inspect build/index.js", + "dev": "concurrently -k -p \"[{name}]\" -n \"watch-ts,serve-debug\" -c \"cyan.bold,green.bold\" \"npm run watch-ts\" \"npm run serve-debug\"" }, "repository": { "type": "git", @@ -20,10 +24,12 @@ }, "homepage": "https://github.com/BLazzeD21/Node.js-ChatGPT-Bot#readme", "devDependencies": { + "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.53.0", "eslint-config-google": "^0.14.0", "nodemon": "^2.0.22", + "ts-node": "^10.9.2", "typescript": "^5.3.3" }, "dependencies": { @@ -32,11 +38,13 @@ "@telegraf/session": "^2.0.0-beta.6", "axios": "^1.6.0", "config": "^3.3.9", + "copyfiles": "^2.4.1", "fluent-ffmpeg": "^2.1.2", "https-proxy-agent": "^7.0.2", "openai": "^4.20.0", "redis": "^4.6.10", "request": "^2.88.2", + "rimraf": "^5.0.5", "telegraf": "^4.12.2", "telegraf-ratelimit": "^2.0.0" } From 90602fcbb2fd2353095dc53cdfc36eed703fe7aa Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Fri, 5 Jan 2024 04:43:21 +0300 Subject: [PATCH 05/25] chore: add the build directory to .gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cc37c84..eab1e8f 100644 --- a/.gitignore +++ b/.gitignore @@ -132,4 +132,7 @@ dist # Configuration files config/default.json -config/production.json \ No newline at end of file +config/production.json + +# Compiled version of project +build \ No newline at end of file From de903f9cd5d4d874c75893f69ac6666dea89bd19 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Fri, 5 Jan 2024 20:05:40 +0300 Subject: [PATCH 06/25] version: 1.1.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index fb18b8d..69b8a1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "node.js-chatgpt-bot", - "version": "1.1.2", + "version": "1.1.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "node.js-chatgpt-bot", - "version": "1.1.2", + "version": "1.1.3", "license": "MIT License", "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", diff --git a/package.json b/package.json index c403661..04e1cac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node.js-chatgpt-bot", - "version": "1.1.2", + "version": "1.1.3", "description": "СhatGPT bot for telegram written on node.js", "main": "index.js", "type": "module", From 0ed42512c9c94335ada9e00086db7ce48e7b62c0 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 6 Jan 2024 01:20:00 +0300 Subject: [PATCH 07/25] fix: limit requests only to handlers using openai API --- src/index.js | 47 ++++++++++++++++++++++++--------------- src/lexicon/lexicon_en.js | 2 +- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/index.js b/src/index.js index 4acfc06..4bc4757 100644 --- a/src/index.js +++ b/src/index.js @@ -14,11 +14,12 @@ import AdminHandlers from './handlers/adminHandlers.js'; import { Redis } from '@telegraf/session/redis'; import { limit } from '@grammyjs/ratelimiter'; -let config = process.env.NODE_ENV === 'production' ? +let config = + process.env.NODE_ENV === 'production' ? JSON.parse(fs.readFileSync('config/production.json', 'utf8')) : JSON.parse(fs.readFileSync('config/default.json', 'utf8')); -const store = new Redis({ +const redisStorage = new Redis({ store: { host: config.REDIS_HOST, port: config.REDIS_PORT, @@ -30,35 +31,44 @@ const updateConfigValue = async (updatedConfig) => { }; const requestslimit = limit({ - timeFrame: 2500, - limit: 1, + timeFrame: 60000, + limit: 3, onLimitExceeded: (ctx) => { - ctx?.reply(LEXICON_EN['tooManyRequests']); + ctx.reply(LEXICON_EN['tooManyRequests']); }, }); const bot = new Telegraf(config.BOT_TOKEN, { handlerTimeout: 180_000 }); -bot.use(session({ store })); -bot.use(requestslimit); +bot.use(session({ redisStorage })); -bot.command('start', UserHandlers.startHandler(store)); +bot.command('start', UserHandlers.startHandler(redisStorage)); bot.command('add', AdminHandlers.addHandler(config, updateConfigValue)); bot.command('remove', AdminHandlers.removeHandler(config, updateConfigValue)); bot.command('show', AdminHandlers.showHandler(config)); -bot.command('new', UserHandlers.newHandler(config, store)); +bot.command('new', UserHandlers.newHandler(config, redisStorage)); bot.command('help', UserHandlers.helpHandler(config)); bot.command('password', UserHandlers.passwordHandler()); -bot.command('image', OpenAIHandlers.imageHandler(config)); bot.hears(LEXICON_EN['getIDs_btn'], UserHandlers.chatIDHandler()); bot.hears(LEXICON_EN['password_btn'], UserHandlers.passwordHandler()); -bot.hears(LEXICON_EN['reset_btn'], UserHandlers.newHandler(config, store)); - -bot.on(message('text'), OpenAIHandlers.textHandler(config, store)); -bot.on(message('voice'), OpenAIHandlers.voiceHandler(config, store)); +bot.hears(LEXICON_EN['reset_btn'], + UserHandlers.newHandler(config, redisStorage)); + +bot.command('image', + requestslimit, + OpenAIHandlers.imageHandler(config), +); +bot.on(message('text'), + requestslimit, + OpenAIHandlers.textHandler(config, redisStorage), +); +bot.on(message('voice'), + requestslimit, + OpenAIHandlers.voiceHandler(config, redisStorage), +); bot.catch(async (error, ctx) => { if (error.name === 'TimeoutError') { @@ -71,12 +81,13 @@ if (process.env.NODE_ENV === 'production') { deleteWebHook(bot); } - process.once('SIGINT', () => bot.stop('SIGINT')); process.once('SIGTERM', () => bot.stop('SIGTERM')); -bot.launch({ dropPendingUpdates: true }) +bot + .launch({ dropPendingUpdates: true }) .then( - process.env.NODE_ENV === 'production' ? - sendMessages(bot, await getUsersArray(config)) : 0, + process.env.NODE_ENV === 'production' ? + sendMessages(bot, await getUsersArray(config)) : + 0, ); diff --git a/src/lexicon/lexicon_en.js b/src/lexicon/lexicon_en.js index 95f65f6..911e5dc 100644 --- a/src/lexicon/lexicon_en.js +++ b/src/lexicon/lexicon_en.js @@ -43,7 +43,7 @@ export const LEXICON_EN = { errorSending: 'Error sending message to: ', waiting: 'The server timed out waiting for a response ⚠️', noUser: 'There is no user with this ID ⚠️', - tooManyRequests: 'Please refrain from sending too many requests 🔔', + tooManyRequests: 'API requests are only available 3 times every 60 seconds 🔔', UserNotExists: 'User ID does not exist 🔒', }; From 1dd486a9ba87ed209a6f490ac8be92c5d2811af7 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 6 Jan 2024 01:42:23 +0300 Subject: [PATCH 08/25] refactor: separate handler registration into a function `registerHandlers` --- src/handlers/adminHandlers.js | 6 +-- src/handlers/errorHandler.js | 4 +- src/handlers/handlersRegistration.js | 64 ++++++++++++++++++++++++++++ src/handlers/openaiHandlers.js | 6 +-- src/index.js | 41 +++--------------- 5 files changed, 78 insertions(+), 43 deletions(-) create mode 100644 src/handlers/handlersRegistration.js diff --git a/src/handlers/adminHandlers.js b/src/handlers/adminHandlers.js index a548b68..6cd15df 100644 --- a/src/handlers/adminHandlers.js +++ b/src/handlers/adminHandlers.js @@ -31,7 +31,7 @@ class AdminHandlers { const output =`Added ID: ${requestText}\n\n` + `${LEXICON_EN['add']}`; - ctx.reply(output, { parse_mode: 'HTML' }); + await ctx.reply(output, { parse_mode: 'HTML' }); } catch (e) { console.log(LEXICON_EN['errorSending'], requestText); } @@ -56,7 +56,7 @@ class AdminHandlers { const usersID = config.USERS_ID.split(','); if (!usersID.includes(requestText.toString())) { - ctx.reply(LEXICON_EN['UserNotExists']); + await ctx.reply(LEXICON_EN['UserNotExists']); return; } const filteredUsers = usersID @@ -78,7 +78,7 @@ class AdminHandlers { const output =`Removed ID: ${requestText}\n\n` + `${LEXICON_EN['remove']}`; - ctx.reply(output, { parse_mode: 'HTML' }); + await ctx.reply(output, { parse_mode: 'HTML' }); } catch (e) { console.log(LEXICON_EN['errorSending'], requestText); } diff --git a/src/handlers/errorHandler.js b/src/handlers/errorHandler.js index d624439..ad7ff88 100644 --- a/src/handlers/errorHandler.js +++ b/src/handlers/errorHandler.js @@ -3,10 +3,10 @@ import { menuKeyboard } from '../keyboards/keyboards.js'; class ErrorHandler { responseError(ctx, handler) { - return (error) => { + return async (error) => { console.log(`${ctx.from.id} - ${error.name} ${handler}: ${error.message}`, menuKeyboard); - ctx.reply( + await ctx.reply( `${LEXICON_EN['noResponce']}\n\n${error.name}: ${error.message}`, { disable_web_page_preview: true }, ); diff --git a/src/handlers/handlersRegistration.js b/src/handlers/handlersRegistration.js new file mode 100644 index 0000000..b3eaf19 --- /dev/null +++ b/src/handlers/handlersRegistration.js @@ -0,0 +1,64 @@ +import UserHandlers from './userHandlers.js'; +import OpenAIHandlers from './openaiHandlers.js'; +import AdminHandlers from './adminHandlers.js'; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; +import { message } from 'telegraf/filters'; + +export const registerHandlers = async ( + bot, + config, + redisStorage, + updateConfigValue, + requestslimit, +) => { + bot.command('start', + UserHandlers.startHandler(redisStorage)); + bot.command('add', + AdminHandlers.addHandler(config, updateConfigValue)); + bot.command('remove', + AdminHandlers.removeHandler(config, updateConfigValue)); + bot.command('show', + AdminHandlers.showHandler(config)); + bot.command('new', + UserHandlers.newHandler(config, redisStorage)); + bot.command('help', + UserHandlers.helpHandler(config)); + bot.command('password', + UserHandlers.passwordHandler()); + bot.hears( + LEXICON_EN['getIDs_btn'], + UserHandlers.chatIDHandler(), + ); + + bot.hears( + LEXICON_EN['password_btn'], + UserHandlers.passwordHandler(), + ); + + bot.hears( + LEXICON_EN['reset_btn'], + UserHandlers.newHandler(config, redisStorage), + ); + + bot.command( + 'image', + requestslimit, + OpenAIHandlers.imageHandler(config), + ); + bot.on( + message('text'), + requestslimit, + OpenAIHandlers.textHandler(config, redisStorage), + ); + bot.on( + message('voice'), + requestslimit, + OpenAIHandlers.voiceHandler(config, redisStorage), + ); + + bot.catch(async (error, ctx) => { + if (error.name === 'TimeoutError') { + await ctx.reply(LEXICON_EN['waiting']); + } + }); +}; diff --git a/src/handlers/openaiHandlers.js b/src/handlers/openaiHandlers.js index ec4dbf5..a8d8604 100644 --- a/src/handlers/openaiHandlers.js +++ b/src/handlers/openaiHandlers.js @@ -40,7 +40,7 @@ class OpenAIHandlers { code(LEXICON_EN['processingText']), menuKeyboard); - ctx.sendChatAction('typing'); + await ctx.sendChatAction('typing'); const content = ctx.message.text; @@ -70,7 +70,7 @@ class OpenAIHandlers { code(LEXICON_EN['processingTranscription']), menuKeyboard); - ctx.sendChatAction('typing'); + await ctx.sendChatAction('typing'); const link = await ctx.telegram.getFileLink(ctx.message.voice.file_id); const userId = String(ctx.message.from.id); @@ -113,7 +113,7 @@ class OpenAIHandlers { const processing = await ctx.reply( code(LEXICON_EN['processingImage']), menuKeyboard); - ctx.sendChatAction('upload_photo'); + await ctx.sendChatAction('upload_photo'); const requestText = ctx.message.text.replace('/image', '').trim(); diff --git a/src/index.js b/src/index.js index 4bc4757..02a0421 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,4 @@ import { Telegraf, session } from 'telegraf'; -import { message } from 'telegraf/filters'; import fs from 'fs'; import { getUsersArray } from './utils/checkAccess.js'; @@ -7,12 +6,10 @@ import { sendMessages } from './utils/sendMessages.js'; import { LEXICON_EN } from './lexicon/lexicon_en.js'; import { setMenu } from './keyboards/set_menu.js'; import { deleteWebHook } from './utils/deleteWebhook.js'; -import UserHandlers from './handlers/userHandlers.js'; -import OpenAIHandlers from './handlers/openaiHandlers.js'; -import AdminHandlers from './handlers/adminHandlers.js'; import { Redis } from '@telegraf/session/redis'; import { limit } from '@grammyjs/ratelimiter'; +import { registerHandlers } from './handlers/handlersRegistration.js'; let config = process.env.NODE_ENV === 'production' ? @@ -42,40 +39,14 @@ const bot = new Telegraf(config.BOT_TOKEN, { handlerTimeout: 180_000 }); bot.use(session({ redisStorage })); -bot.command('start', UserHandlers.startHandler(redisStorage)); - -bot.command('add', AdminHandlers.addHandler(config, updateConfigValue)); -bot.command('remove', AdminHandlers.removeHandler(config, updateConfigValue)); -bot.command('show', AdminHandlers.showHandler(config)); - -bot.command('new', UserHandlers.newHandler(config, redisStorage)); -bot.command('help', UserHandlers.helpHandler(config)); -bot.command('password', UserHandlers.passwordHandler()); - -bot.hears(LEXICON_EN['getIDs_btn'], UserHandlers.chatIDHandler()); -bot.hears(LEXICON_EN['password_btn'], UserHandlers.passwordHandler()); -bot.hears(LEXICON_EN['reset_btn'], - UserHandlers.newHandler(config, redisStorage)); - -bot.command('image', - requestslimit, - OpenAIHandlers.imageHandler(config), -); -bot.on(message('text'), - requestslimit, - OpenAIHandlers.textHandler(config, redisStorage), -); -bot.on(message('voice'), +registerHandlers( + bot, + config, + redisStorage, + updateConfigValue, requestslimit, - OpenAIHandlers.voiceHandler(config, redisStorage), ); -bot.catch(async (error, ctx) => { - if (error.name === 'TimeoutError') { - return ctx.reply(LEXICON_EN['waiting']); - } -}); - if (process.env.NODE_ENV === 'production') { setMenu(bot); deleteWebHook(bot); From 570eaf8d6838cdccdd952dd14596b6eaeb006230 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 6 Jan 2024 02:07:50 +0300 Subject: [PATCH 09/25] fix!: add a check for the existence of the voice directory --- src/handlers/openaiHandlers.js | 10 +++++++++- src/lexicon/lexicon_en.js | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/handlers/openaiHandlers.js b/src/handlers/openaiHandlers.js index a8d8604..c04bf83 100644 --- a/src/handlers/openaiHandlers.js +++ b/src/handlers/openaiHandlers.js @@ -1,6 +1,7 @@ +import fs from 'fs'; import { code } from 'telegraf/format'; -import { LEXICON_EN } from '../lexicon/lexicon_en.js'; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; import { openai } from '../openai.js'; import { converter } from '../converter.js'; import { deleteFile } from '../utils/deleteFile.js'; @@ -72,6 +73,13 @@ class OpenAIHandlers { await ctx.sendChatAction('typing'); + if (!fs.existsSync('build/voices')) { + fs.mkdir('build/voices', (error) => { + if (error) throw error; + console.log(LEXICON_EN['folderCreated']); + }); + } + const link = await ctx.telegram.getFileLink(ctx.message.voice.file_id); const userId = String(ctx.message.from.id); diff --git a/src/lexicon/lexicon_en.js b/src/lexicon/lexicon_en.js index 911e5dc..24ff804 100644 --- a/src/lexicon/lexicon_en.js +++ b/src/lexicon/lexicon_en.js @@ -11,8 +11,8 @@ export const LEXICON_EN = { botStarted: `Bot has been started! 🤖\n\n${date}`, commands: 'Custom commands set successfully', webhook: 'Webhook deleted successfully', - start: - 'Hello, welcome to an artificial intelligence chatbot ' + + folderCreated: 'Folder created successfully', + start: 'Hello, welcome to an artificial intelligence chatbot ' + 'that will help you with everything! 🤖\n\nYou can find ' + 'the source code of the bot here: [click](https://github.com/BLazzeD21/Node.js-ChatGPT-Bot)\n' + 'Developer: @blazzed21\n', From 5ecbea3e6921706455eae3a197647cc107f55dad Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 6 Jan 2024 02:08:15 +0300 Subject: [PATCH 10/25] version: 1.1.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 69b8a1d..b586ddd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "node.js-chatgpt-bot", - "version": "1.1.3", + "version": "1.1.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "node.js-chatgpt-bot", - "version": "1.1.3", + "version": "1.1.4", "license": "MIT License", "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", diff --git a/package.json b/package.json index 04e1cac..13d2928 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node.js-chatgpt-bot", - "version": "1.1.3", + "version": "1.1.4", "description": "СhatGPT bot for telegram written on node.js", "main": "index.js", "type": "module", From 337e16ffcf1834377dae6fd233b938b932e96f53 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 6 Jan 2024 03:05:06 +0300 Subject: [PATCH 11/25] fix: fix keyboard call with menu commands --- src/handlers/adminHandlers.js | 15 ++++++++++----- src/handlers/errorHandler.js | 7 ++++--- src/handlers/openaiHandlers.js | 7 +++++-- src/handlers/userHandlers.js | 20 +++++++++++--------- src/utils/sendMessages.js | 3 +-- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/handlers/adminHandlers.js b/src/handlers/adminHandlers.js index 6cd15df..ccaaa4d 100644 --- a/src/handlers/adminHandlers.js +++ b/src/handlers/adminHandlers.js @@ -1,6 +1,7 @@ import fs from 'fs'; import { LEXICON_EN } from '../lexicon/lexicon_en.js'; import { getUsersArray } from '../utils/checkAccess.js'; +import { menuKeyboard } from '../keyboards/keyboards.js'; class AdminHandlers { addHandler = (config, callback) => { @@ -12,7 +13,9 @@ class AdminHandlers { .trim()); if (!requestText) { - await ctx.reply(LEXICON_EN['emptyAdd'], { parse_mode: 'HTML' }); + await ctx.reply(LEXICON_EN['emptyAdd'], + { parse_mode: 'HTML', ...menuKeyboard }, + ); return; } @@ -31,7 +34,7 @@ class AdminHandlers { const output =`Added ID: ${requestText}\n\n` + `${LEXICON_EN['add']}`; - await ctx.reply(output, { parse_mode: 'HTML' }); + await ctx.reply(output, { parse_mode: 'HTML', ...menuKeyboard }); } catch (e) { console.log(LEXICON_EN['errorSending'], requestText); } @@ -50,7 +53,9 @@ class AdminHandlers { .trim()); if (!requestText) { - await ctx.reply(LEXICON_EN['removeAdd'], { parse_mode: 'HTML' }); + await ctx.reply(LEXICON_EN['removeAdd'], + { parse_mode: 'HTML', ...menuKeyboard }, + ); return; } const usersID = config.USERS_ID.split(','); @@ -78,7 +83,7 @@ class AdminHandlers { const output =`Removed ID: ${requestText}\n\n` + `${LEXICON_EN['remove']}`; - await ctx.reply(output, { parse_mode: 'HTML' }); + await ctx.reply(output, { parse_mode: 'HTML', ...menuKeyboard }); } catch (e) { console.log(LEXICON_EN['errorSending'], requestText); } @@ -112,7 +117,7 @@ class AdminHandlers { output += `👤 ${id}\n`; }); - await ctx.reply(output, { parse_mode: 'HTML' }); + await ctx.reply(output, { parse_mode: 'HTML', ...menuKeyboard }); await callback(config); } else { diff --git a/src/handlers/errorHandler.js b/src/handlers/errorHandler.js index ad7ff88..0b3d2ab 100644 --- a/src/handlers/errorHandler.js +++ b/src/handlers/errorHandler.js @@ -4,11 +4,12 @@ import { menuKeyboard } from '../keyboards/keyboards.js'; class ErrorHandler { responseError(ctx, handler) { return async (error) => { - console.log(`${ctx.from.id} - ${error.name} ${handler}: ${error.message}`, - menuKeyboard); + console.log( + `${ctx.from.id} - ${error.name} ${handler}: ${error.message}`, + ); await ctx.reply( `${LEXICON_EN['noResponce']}\n\n${error.name}: ${error.message}`, - { disable_web_page_preview: true }, + { disable_web_page_preview: true, ...menuKeyboard }, ); }; } diff --git a/src/handlers/openaiHandlers.js b/src/handlers/openaiHandlers.js index c04bf83..3cb7e5d 100644 --- a/src/handlers/openaiHandlers.js +++ b/src/handlers/openaiHandlers.js @@ -23,7 +23,8 @@ class OpenAIHandlers { } await ctx.reply( - response.content, { parse_mode: 'Markdown' }, menuKeyboard, + response.content, + { parse_mode: 'Markdown', ...menuKeyboard }, ).catch( async () => await ctx.reply(response.content, menuKeyboard), ); @@ -127,7 +128,9 @@ class OpenAIHandlers { if (!requestText) { await ctx.deleteMessage(processing.message_id); - await ctx.reply(LEXICON_EN['empty'], { parse_mode: 'HTML' }); + await ctx.reply(LEXICON_EN['empty'], + { parse_mode: 'HTML', ...menuKeyboard }, + ); return; } diff --git a/src/handlers/userHandlers.js b/src/handlers/userHandlers.js index a64096a..de53264 100644 --- a/src/handlers/userHandlers.js +++ b/src/handlers/userHandlers.js @@ -12,10 +12,11 @@ class UserHandlers { startHandler = (sessions) => { return async (ctx) => { const sessionId = ctx.message.chat.id; + sessions[sessionId] = createInitialSession(); + await ctx.reply(LEXICON_EN['start'], - { parse_mode: 'Markdown' }, - menuKeyboard, + { parse_mode: 'Markdown', ...menuKeyboard }, ); }; }; @@ -23,7 +24,8 @@ class UserHandlers { helpHandler = (config) => { return async (ctx) => { if (await checkAccess(config, ctx)) return; - await ctx.reply(await getHelp(), menuKeyboard); + + await ctx.reply(getHelp(), menuKeyboard); }; }; @@ -33,9 +35,8 @@ class UserHandlers { const chatId = ctx.message.chat.id; await ctx.reply( - await getIDs(chatId, userId), - { parse_mode: 'HTML' }, - menuKeyboard, + getIDs(chatId, userId), + { parse_mode: 'HTML', ...menuKeyboard }, ); }; }; @@ -43,10 +44,11 @@ class UserHandlers { passwordHandler = () => { return async (ctx) => { const password = await generatePassword(); + await ctx.reply( - await printPassword(password), - { parse_mode: 'HTML' }, - menuKeyboard); + printPassword(password), + { parse_mode: 'HTML', ...menuKeyboard }, + ); }; }; diff --git a/src/utils/sendMessages.js b/src/utils/sendMessages.js index ae538a2..57f2f1e 100644 --- a/src/utils/sendMessages.js +++ b/src/utils/sendMessages.js @@ -1,10 +1,9 @@ -import { LEXICON_EN, messageSent } from '../lexicon/lexicon_en.js'; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; export const sendMessages = async (bot, allowedUserId) => { for (const recipient of allowedUserId) { try { await bot.telegram.sendMessage(recipient, LEXICON_EN['botStarted']); - console.log(await messageSent(recipient)); } catch (error) { console.error(LEXICON_EN['errorSending'], recipient.toString()); } From 2fe15b4ab61884073d8aeb217dd4925919340e83 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 6 Jan 2024 03:07:01 +0300 Subject: [PATCH 12/25] feat: `lexicon` rewritten for typescript --- src/lexicon/{lexicon_en.js => lexicon_en.ts} | 28 +++++++++----------- 1 file changed, 13 insertions(+), 15 deletions(-) rename src/lexicon/{lexicon_en.js => lexicon_en.ts} (82%) diff --git a/src/lexicon/lexicon_en.js b/src/lexicon/lexicon_en.ts similarity index 82% rename from src/lexicon/lexicon_en.js rename to src/lexicon/lexicon_en.ts index 24ff804..e142b3b 100644 --- a/src/lexicon/lexicon_en.js +++ b/src/lexicon/lexicon_en.ts @@ -1,11 +1,16 @@ -export const commands = [ +interface Command { + command: string; + description: string; +} + +export const commands: Command[] = [ { command: 'start', description: 'Update the bot' }, { command: 'new', description: 'Open a new session' }, { command: 'help', description: 'Find out the bot\'s capabilities' }, { command: 'image', description: 'Creating an image based on a text query' }, ]; -const date = new Date(); +const date: Date = new Date(); export const LEXICON_EN = { botStarted: `Bot has been started! 🤖\n\n${date}`, @@ -47,13 +52,13 @@ export const LEXICON_EN = { UserNotExists: 'User ID does not exist 🔒', }; -export const getIDs = async (chatId, userId) => { - return `Your ID: ${userId}\n`+ - `This chat ID: ${chatId}`; +export const getIDs = (chatId: number, userId: number) => { + return `Your ID: ${userId.toString()}\n`+ + `This chat ID: ${chatId.toString()}`; }; -export const getHelp = async () => { - let helpMessage = 'Commands available in the bot:\n'; +export const getHelp = () => { + let helpMessage: string = 'Commands available in the bot:\n'; for (const key in commands) { helpMessage += `/${commands[key]['command']}` + @@ -64,14 +69,7 @@ export const getHelp = async () => { return helpMessage; }; -export const messageSent = async (recipientId) => { - return `Message sent to user ID: ${recipientId}`; -}; - -export const errorWhileSending = async (error) => { - return `Error sending message: ${error}`; -}; -export const printPassword = async (password) => { +export const printPassword = (password: string) => { return `Generated password:\n${password}`; }; From 355d81416c36fb7ec280ef0fcb3139bf66155df1 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 6 Jan 2024 03:07:25 +0300 Subject: [PATCH 13/25] version: 1.1.5 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b586ddd..4a0d1d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "node.js-chatgpt-bot", - "version": "1.1.4", + "version": "1.1.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "node.js-chatgpt-bot", - "version": "1.1.4", + "version": "1.1.5", "license": "MIT License", "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", diff --git a/package.json b/package.json index 13d2928..ead68fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node.js-chatgpt-bot", - "version": "1.1.4", + "version": "1.1.5", "description": "СhatGPT bot for telegram written on node.js", "main": "index.js", "type": "module", From 3fedab1902da83459722e0830e3eaef57835885a Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Wed, 17 Jan 2024 20:02:33 +0300 Subject: [PATCH 14/25] chore: add noEmitOnError --- tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tsconfig.json b/tsconfig.json index eacfec1..e339bac 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,5 +13,6 @@ "checkJs": false, "alwaysStrict": false, "removeComments": true, + "noEmitOnError": true } } \ No newline at end of file From a39a3898151d88b2fc59e053db2e86fd41ef5f12 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 18:39:45 +0300 Subject: [PATCH 15/25] chore: npm i --save-dev @types/config --- package-lock.json | 13 +++++++++++++ package.json | 1 + 2 files changed, 14 insertions(+) diff --git a/package-lock.json b/package-lock.json index 4a0d1d3..cb612db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "telegraf-ratelimit": "^2.0.0" }, "devDependencies": { + "@types/config": "^3.3.3", "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.53.0", @@ -557,6 +558,12 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@types/config": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@types/config/-/config-3.3.3.tgz", + "integrity": "sha512-BB8DBAud88EgiAKlz8WQStzI771Kb6F3j4dioRJ4GD+tP4tzcZyMlz86aXuZT4s9hyesFORehMQE6eqtA5O+Vg==", + "dev": true + }, "node_modules/@types/node": { "version": "18.18.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", @@ -3958,6 +3965,12 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "@types/config": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@types/config/-/config-3.3.3.tgz", + "integrity": "sha512-BB8DBAud88EgiAKlz8WQStzI771Kb6F3j4dioRJ4GD+tP4tzcZyMlz86aXuZT4s9hyesFORehMQE6eqtA5O+Vg==", + "dev": true + }, "@types/node": { "version": "18.18.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", diff --git a/package.json b/package.json index ead68fb..03790e4 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ }, "homepage": "https://github.com/BLazzeD21/Node.js-ChatGPT-Bot#readme", "devDependencies": { + "@types/config": "^3.3.3", "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.53.0", From e576b3258b30641bd18ff9905bf6b4932518a1d1 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 18:40:31 +0300 Subject: [PATCH 16/25] feat: add typescript types --- src/types.d.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/types.d.ts diff --git a/src/types.d.ts b/src/types.d.ts new file mode 100644 index 0000000..9303a72 --- /dev/null +++ b/src/types.d.ts @@ -0,0 +1,27 @@ +interface Messages { + role: 'assistant' | 'user', + content: string, +} + +interface Command { + command: string, + description: string, +} + +interface RedisStore { + host: string, + port: string +} + +interface Config { + BOT_TOKEN: string, + OPENAI_KEY: string, + USERS_ID: string, + SUPER_USER: string, + REDIS_URL: string, + PROXY_URL: string, +} + +interface UpdateConfigValue { + (updatedConfig: Config): Promise, +} From b1016460d46eff37464da718bbd0a92e646ee058 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 19:13:49 +0300 Subject: [PATCH 17/25] feat!: rewrite the entire bot in typescript --- src/converter.js | 60 ------- src/converter.ts | 60 +++++++ src/handlers/adminHandlers.js | 130 -------------- src/handlers/adminHandlers.ts | 158 ++++++++++++++++ src/handlers/errorHandler.js | 18 -- src/handlers/errorHandler.ts | 19 ++ src/handlers/handlersRegistration.js | 64 ------- src/handlers/handlersRegistration.ts | 48 +++++ src/handlers/openaiHandlers.js | 159 ---------------- src/handlers/openaiHandlers.ts | 170 ++++++++++++++++++ .../{userHandlers.js => userHandlers.ts} | 30 ++-- src/index.js | 64 ------- src/index.ts | 56 ++++++ src/keyboards/keyboards.js | 11 -- src/keyboards/keyboards.ts | 11 ++ src/keyboards/set_menu.js | 13 -- src/keyboards/set_menu.ts | 14 ++ src/lexicon/lexicon_en.ts | 107 +++++------ src/{openai.js => openai.ts} | 41 ++--- src/utils/checkAccess.js | 24 --- src/utils/checkAccess.ts | 22 +++ .../{createSession.js => createSession.ts} | 0 src/utils/{deleteFile.js => deleteFile.ts} | 4 +- src/utils/deleteWebhook.js | 12 -- src/utils/deleteWebhook.ts | 13 ++ src/utils/generatePassword.js | 30 ---- src/utils/generatePassword.ts | 31 ++++ src/utils/sendMessages.js | 11 -- src/utils/sendMessages.ts | 12 ++ 29 files changed, 708 insertions(+), 684 deletions(-) delete mode 100644 src/converter.js create mode 100644 src/converter.ts delete mode 100644 src/handlers/adminHandlers.js create mode 100644 src/handlers/adminHandlers.ts delete mode 100644 src/handlers/errorHandler.js create mode 100644 src/handlers/errorHandler.ts delete mode 100644 src/handlers/handlersRegistration.js create mode 100644 src/handlers/handlersRegistration.ts delete mode 100644 src/handlers/openaiHandlers.js create mode 100644 src/handlers/openaiHandlers.ts rename src/handlers/{userHandlers.js => userHandlers.ts} (61%) delete mode 100644 src/index.js create mode 100644 src/index.ts delete mode 100644 src/keyboards/keyboards.js create mode 100644 src/keyboards/keyboards.ts delete mode 100644 src/keyboards/set_menu.js create mode 100644 src/keyboards/set_menu.ts rename src/{openai.js => openai.ts} (51%) delete mode 100644 src/utils/checkAccess.js create mode 100644 src/utils/checkAccess.ts rename src/utils/{createSession.js => createSession.ts} (100%) rename src/utils/{deleteFile.js => deleteFile.ts} (58%) delete mode 100644 src/utils/deleteWebhook.js create mode 100644 src/utils/deleteWebhook.ts delete mode 100644 src/utils/generatePassword.js create mode 100644 src/utils/generatePassword.ts delete mode 100644 src/utils/sendMessages.js create mode 100644 src/utils/sendMessages.ts diff --git a/src/converter.js b/src/converter.js deleted file mode 100644 index b3c4dcf..0000000 --- a/src/converter.js +++ /dev/null @@ -1,60 +0,0 @@ -import axios from 'axios'; -import installer from '@ffmpeg-installer/ffmpeg'; -import ffmpeg from 'fluent-ffmpeg'; - -import { createWriteStream } from 'fs'; -import { dirname, resolve } from 'path'; -import { fileURLToPath } from 'url'; - -import { deleteFile } from './utils/deleteFile.js'; - -const __dirname = dirname(fileURLToPath(import.meta.url)); - -class OggConverter { - constructor() { - ffmpeg.setFfmpegPath(installer.path); - } - - toMp3(input, output) { - try { - const outputPath = resolve( - __dirname, - '..', - dirname(input), - `${output}.mp3`, - ); - - return new Promise((resolve, reject) => { - ffmpeg(input) - .inputOption('-t 30') - .output(outputPath) - .on('end', () => { - deleteFile(input); - resolve(outputPath); - }) - .on('error', (err) => reject(err.message)) - .run(); - }); - } catch (error) { - console.log('Error create:' + error.message); - } - } - - async create(url, filename) { - try { - const oggPath = resolve(__dirname, 'voices', `${filename}.ogg`); - const response = await axios.get(url, { - responseType: 'stream', - }); - return new Promise((resolve) => { - const stream = createWriteStream(oggPath); - response.data.pipe(stream); - stream.on('finish', () => resolve(oggPath)); - }); - } catch (error) { - console.log('Error create:' + error.message); - } - } -} - -export const converter = new OggConverter(); diff --git a/src/converter.ts b/src/converter.ts new file mode 100644 index 0000000..d29a7d4 --- /dev/null +++ b/src/converter.ts @@ -0,0 +1,60 @@ +import axios from "axios"; +import installer from "@ffmpeg-installer/ffmpeg"; +import ffmpeg from "fluent-ffmpeg"; + +import { createWriteStream } from "fs"; +import { dirname, resolve } from "path"; +import { fileURLToPath } from "url"; + +import { deleteFile } from "./utils/deleteFile.js"; + +const __dirname: string = dirname(fileURLToPath(import.meta.url)); + +class OggConverter { + constructor() { + ffmpeg.setFfmpegPath(installer.path); + } + + toMp3(input: string, output: string) { + try { + const outputPath = resolve( + __dirname, + "..", + dirname(input), + `${output}.mp3` + ); + + return new Promise((resolve, reject) => { + ffmpeg(input) + .inputOption("-t 30") + .output(outputPath) + .on("end", () => { + deleteFile(input); + resolve(outputPath); + }) + .on("error", (error: Error) => reject(error.message)) + .run(); + }); + } catch (error) { + console.log("Error create:" + error.message); + } + } + + async create(url: string, filename: string) { + try { + const oggPath: string = resolve(__dirname, "voices", `${filename}.ogg`); + const response = await axios.get(url, { + responseType: "stream", + }); + return new Promise((resolve) => { + const stream = createWriteStream(oggPath); + response.data.pipe(stream); + stream.on("finish", () => resolve(oggPath)); + }); + } catch (error) { + console.log("Error create:" + error.message); + } + } +} + +export const converter = new OggConverter(); diff --git a/src/handlers/adminHandlers.js b/src/handlers/adminHandlers.js deleted file mode 100644 index ccaaa4d..0000000 --- a/src/handlers/adminHandlers.js +++ /dev/null @@ -1,130 +0,0 @@ -import fs from 'fs'; -import { LEXICON_EN } from '../lexicon/lexicon_en.js'; -import { getUsersArray } from '../utils/checkAccess.js'; -import { menuKeyboard } from '../keyboards/keyboards.js'; - -class AdminHandlers { - addHandler = (config, callback) => { - return async (ctx) => { - if (ctx.from.id == config.SUPER_USER) { - try { - const requestText = parseInt(ctx.message.text - .replace('/add', '') - .trim()); - - if (!requestText) { - await ctx.reply(LEXICON_EN['emptyAdd'], - { parse_mode: 'HTML', ...menuKeyboard }, - ); - return; - } - - config.USERS_ID += `,${requestText}`; - - if (process.env.NODE_ENV === 'production') { - fs.writeFileSync('config/production.json', - JSON.stringify(config, null, 2), 'utf8'); - } else { - fs.writeFileSync('config/default.json', - JSON.stringify(config, null, 2), 'utf8'); - } - - await callback(config); - - const output =`Added ID: ${requestText}\n\n` + - `${LEXICON_EN['add']}`; - - await ctx.reply(output, { parse_mode: 'HTML', ...menuKeyboard }); - } catch (e) { - console.log(LEXICON_EN['errorSending'], requestText); - } - } else { - await ctx.reply(LEXICON_EN['super']); - } - }; - }; - - removeHandler = (config, callback) => { - return async (ctx) => { - if (ctx.from.id == config.SUPER_USER) { - try { - const requestText = parseInt(ctx.message.text - .replace('/remove', '') - .trim()); - - if (!requestText) { - await ctx.reply(LEXICON_EN['removeAdd'], - { parse_mode: 'HTML', ...menuKeyboard }, - ); - return; - } - const usersID = config.USERS_ID.split(','); - - if (!usersID.includes(requestText.toString())) { - await ctx.reply(LEXICON_EN['UserNotExists']); - return; - } - const filteredUsers = usersID - .filter((id) => id !== requestText.toString()) - .join(','); - - config.USERS_ID = filteredUsers; - - if (process.env.NODE_ENV === 'production') { - fs.writeFileSync('config/production.json', - JSON.stringify(config, null, 2), 'utf8'); - } else { - fs.writeFileSync('config/default.json', - JSON.stringify(config, null, 2), 'utf8'); - } - - await callback(config); - - const output =`Removed ID: ${requestText}\n\n` + - `${LEXICON_EN['remove']}`; - - await ctx.reply(output, { parse_mode: 'HTML', ...menuKeyboard }); - } catch (e) { - console.log(LEXICON_EN['errorSending'], requestText); - } - } else { - await ctx.reply(LEXICON_EN['super']); - } - }; - }; - - showHandler = (config) => { - return async (ctx) => { - if (ctx.from.id == config.SUPER_USER) { - const users = await getUsersArray(config); - - const uniqueIDs = [...new Set(users)]; - - config.USERS_ID = uniqueIDs.join(','); - - if (process.env.NODE_ENV === 'production') { - fs.writeFileSync('config/production.json', - JSON.stringify(config, null, 2), 'utf8'); - } else { - fs.writeFileSync('config/default.json', - JSON.stringify(config, null, 2), 'utf8'); - } - - let output = '🗃 Bot users:\n\n'; - - uniqueIDs.forEach( - (id) => { - output += `👤 ${id}\n`; - }); - - await ctx.reply(output, { parse_mode: 'HTML', ...menuKeyboard }); - - await callback(config); - } else { - await ctx.reply(LEXICON_EN['super']); - } - }; - }; -} - -export default new AdminHandlers(); diff --git a/src/handlers/adminHandlers.ts b/src/handlers/adminHandlers.ts new file mode 100644 index 0000000..4f521a8 --- /dev/null +++ b/src/handlers/adminHandlers.ts @@ -0,0 +1,158 @@ +import fs from "fs"; +import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { getUsersArray } from "../utils/checkAccess.js"; +import { menuKeyboard } from "../keyboards/keyboards.js"; +import { Context } from "telegraf"; + +class AdminHandlers { + addHandler = (config: Config, callback: UpdateConfigValue) => { + return async (ctx: Context) => { + const chat_id: string = ctx.from.id.toString(); + if (chat_id != config.SUPER_USER) { + await ctx.reply(LEXICON_EN["super"]); + return; + } + + if (!(ctx.message && "text" in ctx.message)) return; + const requestText: string = ctx.message.text.replace("/add", "").trim(); + + try { + if (!requestText) { + await ctx.reply(LEXICON_EN["emptyAdd"], { + parse_mode: "HTML", + ...menuKeyboard, + }); + return; + } + + config.USERS_ID += `,${requestText}`; + + if (process.env.NODE_ENV === "production") { + fs.writeFileSync( + "config/production.json", + JSON.stringify(config, null, 2), + "utf8" + ); + } else { + fs.writeFileSync( + "config/default.json", + JSON.stringify(config, null, 2), + "utf8" + ); + } + + await callback(config); + + const output: string = + `Added ID: ${requestText}\n\n` + + `${LEXICON_EN["add"]}`; + + await ctx.reply(output, { parse_mode: "HTML", ...menuKeyboard }); + } catch (error) { + console.log(LEXICON_EN["errorSending"], error); + } + }; + }; + + removeHandler = (config: Config, callback: UpdateConfigValue) => { + return async (ctx: Context) => { + const chat_id = ctx.from.id.toString(); + if (chat_id != config.SUPER_USER) { + await ctx.reply(LEXICON_EN["super"]); + return; + } + + if (!(ctx.message && "text" in ctx.message)) return; + const requestText: string = ctx.message.text + .replace("/remove", "") + .trim(); + + try { + if (!requestText) { + await ctx.reply(LEXICON_EN["removeAdd"], { + parse_mode: "HTML", + ...menuKeyboard, + }); + return; + } + const usersID: string[] = config.USERS_ID.split(","); + + if (!usersID.includes(requestText.toString())) { + await ctx.reply(LEXICON_EN["UserNotExists"]); + return; + } + const filteredUsers = usersID + .filter((id: string) => id !== requestText.toString()) + .join(","); + + config.USERS_ID = filteredUsers; + + if (process.env.NODE_ENV === "production") { + fs.writeFileSync( + "config/production.json", + JSON.stringify(config, null, 2), + "utf8" + ); + } else { + fs.writeFileSync( + "config/default.json", + JSON.stringify(config, null, 2), + "utf8" + ); + } + + await callback(config); + + const output: string = + `Removed ID: ${requestText}\n\n` + + `${LEXICON_EN["remove"]}`; + + await ctx.reply(output, { parse_mode: "HTML", ...menuKeyboard }); + } catch (error) { + console.log(LEXICON_EN["errorSending"], error); + } + }; + }; + + showHandler = (config: Config, callback: UpdateConfigValue) => { + return async (ctx: Context) => { + const chat_id = ctx.from.id.toString(); + if (chat_id != config.SUPER_USER) { + await ctx.reply(LEXICON_EN["super"]); + return; + } + + const users: number[] = await getUsersArray(config); + + const uniqueIDs: number[] = [...new Set(users)]; + + config.USERS_ID = uniqueIDs.join(","); + + if (process.env.NODE_ENV === "production") { + fs.writeFileSync( + "config/production.json", + JSON.stringify(config, null, 2), + "utf8" + ); + } else { + fs.writeFileSync( + "config/default.json", + JSON.stringify(config, null, 2), + "utf8" + ); + } + + let output: string = "🗃 Bot users:\n\n"; + + uniqueIDs.forEach((id) => { + output += `👤 ${id}\n`; + }); + + await ctx.reply(output, { parse_mode: "HTML", ...menuKeyboard }); + + await callback(config); + }; + }; +} + +export default new AdminHandlers(); diff --git a/src/handlers/errorHandler.js b/src/handlers/errorHandler.js deleted file mode 100644 index 0b3d2ab..0000000 --- a/src/handlers/errorHandler.js +++ /dev/null @@ -1,18 +0,0 @@ -import { LEXICON_EN } from '../lexicon/lexicon_en.js'; -import { menuKeyboard } from '../keyboards/keyboards.js'; - -class ErrorHandler { - responseError(ctx, handler) { - return async (error) => { - console.log( - `${ctx.from.id} - ${error.name} ${handler}: ${error.message}`, - ); - await ctx.reply( - `${LEXICON_EN['noResponce']}\n\n${error.name}: ${error.message}`, - { disable_web_page_preview: true, ...menuKeyboard }, - ); - }; - } -} - -export default new ErrorHandler(); diff --git a/src/handlers/errorHandler.ts b/src/handlers/errorHandler.ts new file mode 100644 index 0000000..89917b3 --- /dev/null +++ b/src/handlers/errorHandler.ts @@ -0,0 +1,19 @@ +import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { menuKeyboard } from "../keyboards/keyboards.js"; +import { Context } from "telegraf"; + +class ErrorHandler { + responseError(ctx: Context, handler: string) { + return async (error: Error) => { + console.log( + `${ctx.from.id} - ${error.name} ${handler}: ${error.message}` + ); + await ctx.reply( + `${LEXICON_EN["noResponce"]}\n\n${error.name}: ${error.message}`, + { disable_web_page_preview: true, ...menuKeyboard } + ); + }; + } +} + +export default new ErrorHandler(); diff --git a/src/handlers/handlersRegistration.js b/src/handlers/handlersRegistration.js deleted file mode 100644 index b3eaf19..0000000 --- a/src/handlers/handlersRegistration.js +++ /dev/null @@ -1,64 +0,0 @@ -import UserHandlers from './userHandlers.js'; -import OpenAIHandlers from './openaiHandlers.js'; -import AdminHandlers from './adminHandlers.js'; -import { LEXICON_EN } from '../lexicon/lexicon_en.js'; -import { message } from 'telegraf/filters'; - -export const registerHandlers = async ( - bot, - config, - redisStorage, - updateConfigValue, - requestslimit, -) => { - bot.command('start', - UserHandlers.startHandler(redisStorage)); - bot.command('add', - AdminHandlers.addHandler(config, updateConfigValue)); - bot.command('remove', - AdminHandlers.removeHandler(config, updateConfigValue)); - bot.command('show', - AdminHandlers.showHandler(config)); - bot.command('new', - UserHandlers.newHandler(config, redisStorage)); - bot.command('help', - UserHandlers.helpHandler(config)); - bot.command('password', - UserHandlers.passwordHandler()); - bot.hears( - LEXICON_EN['getIDs_btn'], - UserHandlers.chatIDHandler(), - ); - - bot.hears( - LEXICON_EN['password_btn'], - UserHandlers.passwordHandler(), - ); - - bot.hears( - LEXICON_EN['reset_btn'], - UserHandlers.newHandler(config, redisStorage), - ); - - bot.command( - 'image', - requestslimit, - OpenAIHandlers.imageHandler(config), - ); - bot.on( - message('text'), - requestslimit, - OpenAIHandlers.textHandler(config, redisStorage), - ); - bot.on( - message('voice'), - requestslimit, - OpenAIHandlers.voiceHandler(config, redisStorage), - ); - - bot.catch(async (error, ctx) => { - if (error.name === 'TimeoutError') { - await ctx.reply(LEXICON_EN['waiting']); - } - }); -}; diff --git a/src/handlers/handlersRegistration.ts b/src/handlers/handlersRegistration.ts new file mode 100644 index 0000000..0e2c9f3 --- /dev/null +++ b/src/handlers/handlersRegistration.ts @@ -0,0 +1,48 @@ +import UserHandlers from "./userHandlers.js"; +import OpenAIHandlers from "./openaiHandlers.js"; +import AdminHandlers from "./adminHandlers.js"; +import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { message } from "telegraf/filters"; +import { Context, Telegraf, SessionStore } from "telegraf"; + +export const registerHandlers = async ( + bot: Telegraf, + config: Config, + redisStorage: SessionStore, + updateConfigValue: UpdateConfigValue, + requestslimit: (ctx: Context, next: Function) => Promise +) => { + bot.command("start", UserHandlers.startHandler(redisStorage)); + bot.command("add", AdminHandlers.addHandler(config, updateConfigValue)); + bot.command("remove", AdminHandlers.removeHandler(config, updateConfigValue)); + bot.command("show", AdminHandlers.showHandler(config, updateConfigValue)); + bot.command("new", UserHandlers.newHandler(config, redisStorage)); + bot.command("help", UserHandlers.helpHandler(config)); + bot.command("password", UserHandlers.passwordHandler()); + bot.hears(LEXICON_EN["getIDs_btn"], UserHandlers.chatIDHandler()); + + bot.hears(LEXICON_EN["password_btn"], UserHandlers.passwordHandler()); + + bot.hears( + LEXICON_EN["reset_btn"], + UserHandlers.newHandler(config, redisStorage) + ); + + bot.command("image", requestslimit, OpenAIHandlers.imageHandler(config)); + bot.on( + message("text"), + requestslimit, + OpenAIHandlers.textHandler(config, redisStorage) + ); + bot.on( + message("voice"), + requestslimit, + OpenAIHandlers.voiceHandler(config, redisStorage) + ); + + bot.catch(async (error: Error, ctx: Context) => { + if (error.name === "TimeoutError") { + await ctx.reply(LEXICON_EN["waiting"]); + } + }); +}; diff --git a/src/handlers/openaiHandlers.js b/src/handlers/openaiHandlers.js deleted file mode 100644 index 3cb7e5d..0000000 --- a/src/handlers/openaiHandlers.js +++ /dev/null @@ -1,159 +0,0 @@ -import fs from 'fs'; -import { code } from 'telegraf/format'; - -import { LEXICON_EN } from '../lexicon/lexicon_en.js'; -import { openai } from '../openai.js'; -import { converter } from '../converter.js'; -import { deleteFile } from '../utils/deleteFile.js'; - -import { menuKeyboard } from '../keyboards/keyboards.js'; -import { createInitialSession } from '../utils/createSession.js'; -import { checkAccess } from '../utils/checkAccess.js'; - -import ErrorHandler from './errorHandler.js'; - -class OpenAIHandlers { - sendResponse = (ctx, sessions, sessionId) => { - return async (response) => { - if (response && response.content) { - sessions[sessionId].messages.push({ - role: openai.roles.ASSISTANT, - content: response.content, - }); - } - - await ctx.reply( - response.content, - { parse_mode: 'Markdown', ...menuKeyboard }, - ).catch( - async () => await ctx.reply(response.content, menuKeyboard), - ); - }; - }; - - textHandler = (config, sessions) => { - return async (ctx) => { - if (await checkAccess(config, ctx)) return; - - const sessionId = ctx.message.chat.id; - sessions[sessionId] ??= createInitialSession(); - - const processing = await ctx.reply( - code(LEXICON_EN['processingText']), - menuKeyboard); - - await ctx.sendChatAction('typing'); - - const content = ctx.message.text; - - sessions[sessionId].messages.push({ - role: openai.roles.USER, - content: content, - }); - - openai - .chat(sessions[sessionId].messages) - .then(this.sendResponse(ctx, sessions, sessionId), - ).catch(ErrorHandler.responseError(ctx, 'textHandler'), - ).finally(async () => { - await ctx.deleteMessage(processing.message_id); - }); - }; - }; - - voiceHandler = (config, sessions) => { - return async (ctx) => { - if (await checkAccess(config, ctx)) return; - - const sessionId = ctx.message.chat.id; - sessions[sessionId] ??= createInitialSession(); - - const processingTranscription = await ctx.reply( - code(LEXICON_EN['processingTranscription']), - menuKeyboard); - - await ctx.sendChatAction('typing'); - - if (!fs.existsSync('build/voices')) { - fs.mkdir('build/voices', (error) => { - if (error) throw error; - console.log(LEXICON_EN['folderCreated']); - }); - } - - const link = await ctx.telegram.getFileLink(ctx.message.voice.file_id); - const userId = String(ctx.message.from.id); - - const oggPath = await converter.create(link.href, userId); - const mp3Path = await converter.toMp3(oggPath, userId); - - openai - .transcription(mp3Path) - .then(async (text) => { - const processingVoice = await ctx.reply( - code(LEXICON_EN['processingVoice']), - menuKeyboard); - - sessions[sessionId].messages.push({ - role: openai.roles.USER, - content: text, - }); - - openai - .chat(sessions[sessionId].messages) - .then(this.sendResponse(ctx, sessions, sessionId)) - .catch(ErrorHandler.responseError(ctx, 'transcription')) - .finally(async () => { - await ctx.deleteMessage(processingVoice.message_id); - }); - }) - .catch(ErrorHandler.responseError(ctx, 'voiceHandler')) - .finally(async () => { - await deleteFile(mp3Path); - await ctx.deleteMessage(processingTranscription.message_id); - }); - }; - }; - - imageHandler = (config) => { - return async (ctx) => { - if (await checkAccess(config, ctx)) return; - - const processing = await ctx.reply( - code(LEXICON_EN['processingImage']), - menuKeyboard); - await ctx.sendChatAction('upload_photo'); - - const requestText = ctx.message.text.replace('/image', '').trim(); - - if (!requestText) { - await ctx.deleteMessage(processing.message_id); - await ctx.reply(LEXICON_EN['empty'], - { parse_mode: 'HTML', ...menuKeyboard }, - ); - return; - } - - const size = '1024x1024'; - const count = 1; - - openai - .getImage(requestText, size, count) - .then(async (response) => { - if (response) { - await ctx.replyWithPhoto( - { url: response }, { caption: requestText }, - menuKeyboard, - ); - return; - } - }) - .catch(ErrorHandler.responseError(ctx, 'textHandler')) - .finally(async () => { - await ctx.deleteMessage(processing.message_id); - }); - }; - }; -} - -export default new OpenAIHandlers(); diff --git a/src/handlers/openaiHandlers.ts b/src/handlers/openaiHandlers.ts new file mode 100644 index 0000000..545c249 --- /dev/null +++ b/src/handlers/openaiHandlers.ts @@ -0,0 +1,170 @@ +import { Context, SessionStore } from "telegraf"; +import fs from "fs"; +import { code } from "telegraf/format"; +import { OpenAI } from "openai"; + +import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { openai } from "../openai.js"; + +import { converter } from "../converter.js"; +import { deleteFile } from "../utils/deleteFile.js"; + +import { menuKeyboard } from "../keyboards/keyboards.js"; +import { createInitialSession } from "../utils/createSession.js"; +import { checkAccess } from "../utils/checkAccess.js"; + +import ErrorHandler from "./errorHandler.js"; + +class OpenAIHandlers { + sendResponse = ( + ctx: Context, + redisStorage: SessionStore, + userId: string + ) => { + return async (response: OpenAI.Chat.Completions.ChatCompletionMessage) => { + if (response && response.content) { + redisStorage[userId].messages.push({ + role: openai.roles.ASSISTANT, + content: response.content, + }); + } + + await ctx + .reply(response.content, { parse_mode: "Markdown", ...menuKeyboard }) + .catch(async () => await ctx.reply(response.content, menuKeyboard)); + }; + }; + + textHandler = (config: Config, redisStorage: SessionStore) => { + return async (ctx: Context) => { + if (await checkAccess(config, ctx)) return; + + const userId: string = ctx.message.chat.id.toString(); + redisStorage[userId] ??= createInitialSession(); + + const processing = await ctx.reply( + code(LEXICON_EN["processingText"]), + menuKeyboard + ); + + await ctx.sendChatAction("typing"); + + if (!(ctx.message && "text" in ctx.message)) return; + const content = ctx.message.text; + + redisStorage[userId].messages.push({ + role: openai.roles.USER, + content: content, + }); + + openai + .chat(redisStorage[userId].messages) + .then(this.sendResponse(ctx, redisStorage, userId)) + .catch(ErrorHandler.responseError(ctx, "textHandler")) + .finally(async () => { + await ctx.deleteMessage(processing.message_id); + }); + }; + }; + + voiceHandler = (config: Config, redisStorage: SessionStore) => { + return async (ctx: Context) => { + if (await checkAccess(config, ctx)) return; + + const userId: string = ctx.message.chat.id.toString(); + redisStorage[userId] ??= createInitialSession(); + + const processingTranscription = await ctx.reply( + code(LEXICON_EN["processingTranscription"]), + menuKeyboard + ); + + await ctx.sendChatAction("typing"); + + if (!fs.existsSync("build/voices")) { + fs.mkdir("build/voices", (error) => { + if (error) throw error; + console.log(LEXICON_EN["folderCreated"]); + }); + } + + if (!(ctx.message && "voice" in ctx.message)) return; + const link = await ctx.telegram.getFileLink(ctx.message.voice.file_id); + + const oggPath = await converter.create(link.href, userId); + const mp3Path = await converter.toMp3(oggPath.toString(), userId); + + openai + .transcription(mp3Path.toString()) + .then(async (text) => { + const processingVoice = await ctx.reply( + code(LEXICON_EN["processingVoice"]), + menuKeyboard + ); + + redisStorage[userId].messages.push({ + role: openai.roles.USER, + content: text, + }); + + openai + .chat(redisStorage[userId].messages) + .then(this.sendResponse(ctx, redisStorage, userId)) + .catch(ErrorHandler.responseError(ctx, "transcription")) + .finally(async () => { + await ctx.deleteMessage(processingVoice.message_id); + }); + }) + .catch(ErrorHandler.responseError(ctx, "voiceHandler")) + .finally(async () => { + await deleteFile(mp3Path.toString()); + await ctx.deleteMessage(processingTranscription.message_id); + }); + }; + }; + + imageHandler = (config: Config) => { + return async (ctx: Context) => { + if (await checkAccess(config, ctx)) return; + + const processing = await ctx.reply( + code(LEXICON_EN["processingImage"]), + menuKeyboard + ); + await ctx.sendChatAction("upload_photo"); + + if (!(ctx.message && "text" in ctx.message)) return; + const requestText = ctx.message.text.replace("/image", "").trim(); + + if (!requestText) { + await ctx.deleteMessage(processing.message_id); + await ctx.reply(LEXICON_EN["empty"], { + parse_mode: "HTML", + ...menuKeyboard, + }); + return; + } + + const size = "1024x1024"; + const count = 1; + + openai + .getImage(requestText, size, count) + .then(async (response) => { + if (response) { + await ctx.replyWithPhoto( + { url: response }, + { caption: requestText, ...menuKeyboard } + ); + return; + } + }) + .catch(ErrorHandler.responseError(ctx, "textHandler")) + .finally(async () => { + await ctx.deleteMessage(processing.message_id); + }); + }; + }; +} + +export default new OpenAIHandlers(); diff --git a/src/handlers/userHandlers.js b/src/handlers/userHandlers.ts similarity index 61% rename from src/handlers/userHandlers.js rename to src/handlers/userHandlers.ts index de53264..5aecbc3 100644 --- a/src/handlers/userHandlers.js +++ b/src/handlers/userHandlers.ts @@ -7,13 +7,14 @@ import { menuKeyboard } from '../keyboards/keyboards.js'; import { createInitialSession } from '../utils/createSession.js'; import { checkAccess } from '../utils/checkAccess.js'; import { generatePassword } from '../utils/generatePassword.js'; +import { Context, SessionStore } from 'telegraf'; class UserHandlers { - startHandler = (sessions) => { - return async (ctx) => { - const sessionId = ctx.message.chat.id; + startHandler = (redisStorage: SessionStore) => { + return async (ctx: Context) => { + const sessionId: number = ctx.message.chat.id; - sessions[sessionId] = createInitialSession(); + redisStorage[sessionId] = createInitialSession(); await ctx.reply(LEXICON_EN['start'], { parse_mode: 'Markdown', ...menuKeyboard }, @@ -21,8 +22,8 @@ class UserHandlers { }; }; - helpHandler = (config) => { - return async (ctx) => { + helpHandler = (config: Config) => { + return async (ctx: Context) => { if (await checkAccess(config, ctx)) return; await ctx.reply(getHelp(), menuKeyboard); @@ -30,9 +31,9 @@ class UserHandlers { }; chatIDHandler = () => { - return async (ctx) => { - const userId = ctx.from.id; - const chatId = ctx.message.chat.id; + return async (ctx: Context) => { + const userId: number = ctx.from.id; + const chatId: number = ctx.message.chat.id; await ctx.reply( getIDs(chatId, userId), @@ -42,7 +43,7 @@ class UserHandlers { }; passwordHandler = () => { - return async (ctx) => { + return async (ctx: Context) => { const password = await generatePassword(); await ctx.reply( @@ -52,12 +53,13 @@ class UserHandlers { }; }; - newHandler = (config, sessions) => { - return async (ctx) => { + newHandler = (config: Config, redisStorage: SessionStore) => { + return async (ctx: Context) => { if (await checkAccess(config, ctx)) return; - const sessionId = ctx.message.chat.id; - sessions[sessionId] = createInitialSession(); + const sessionId: number = ctx.message.chat.id; + + redisStorage[sessionId] = createInitialSession(); await ctx.reply(LEXICON_EN['reset'], menuKeyboard); }; diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 02a0421..0000000 --- a/src/index.js +++ /dev/null @@ -1,64 +0,0 @@ -import { Telegraf, session } from 'telegraf'; -import fs from 'fs'; - -import { getUsersArray } from './utils/checkAccess.js'; -import { sendMessages } from './utils/sendMessages.js'; -import { LEXICON_EN } from './lexicon/lexicon_en.js'; -import { setMenu } from './keyboards/set_menu.js'; -import { deleteWebHook } from './utils/deleteWebhook.js'; - -import { Redis } from '@telegraf/session/redis'; -import { limit } from '@grammyjs/ratelimiter'; -import { registerHandlers } from './handlers/handlersRegistration.js'; - -let config = - process.env.NODE_ENV === 'production' ? - JSON.parse(fs.readFileSync('config/production.json', 'utf8')) : - JSON.parse(fs.readFileSync('config/default.json', 'utf8')); - -const redisStorage = new Redis({ - store: { - host: config.REDIS_HOST, - port: config.REDIS_PORT, - }, -}); - -const updateConfigValue = async (updatedConfig) => { - config = updatedConfig; -}; - -const requestslimit = limit({ - timeFrame: 60000, - limit: 3, - onLimitExceeded: (ctx) => { - ctx.reply(LEXICON_EN['tooManyRequests']); - }, -}); - -const bot = new Telegraf(config.BOT_TOKEN, { handlerTimeout: 180_000 }); - -bot.use(session({ redisStorage })); - -registerHandlers( - bot, - config, - redisStorage, - updateConfigValue, - requestslimit, -); - -if (process.env.NODE_ENV === 'production') { - setMenu(bot); - deleteWebHook(bot); -} - -process.once('SIGINT', () => bot.stop('SIGINT')); -process.once('SIGTERM', () => bot.stop('SIGTERM')); - -bot - .launch({ dropPendingUpdates: true }) - .then( - process.env.NODE_ENV === 'production' ? - sendMessages(bot, await getUsersArray(config)) : - 0, - ); diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..52cb98f --- /dev/null +++ b/src/index.ts @@ -0,0 +1,56 @@ +import { SessionStore } from "telegraf"; +import { Context, Telegraf, session } from "telegraf"; +import { Redis } from "@telegraf/session/redis"; +import { limit } from "@grammyjs/ratelimiter"; +import fs from "fs"; + +import { registerHandlers } from "./handlers/handlersRegistration.js"; +import { getUsersArray } from "./utils/checkAccess.js"; +import { sendMessages } from "./utils/sendMessages.js"; +import { LEXICON_EN } from "./lexicon/lexicon_en.js"; +import { setMenu } from "./keyboards/set_menu.js"; +import { deleteWebHook } from "./utils/deleteWebhook.js"; + +let config: Config = + process.env.NODE_ENV === "production" + ? JSON.parse(fs.readFileSync("config/production.json", "utf8")) + : JSON.parse(fs.readFileSync("config/default.json", "utf8")); + +const redisStorage: SessionStore = Redis({ + url: config.REDIS_URL, +}); + +const updateConfigValue: UpdateConfigValue = async (updatedConfig: Config) => { + config = updatedConfig; +}; + +const requestslimit: (ctx: Context, next: Function) => Promise = limit({ + timeFrame: 60000, + limit: 3, + onLimitExceeded: (ctx: Context) => { + ctx.reply(LEXICON_EN["tooManyRequests"]); + }, +}); + +const bot: Telegraf = new Telegraf(config.BOT_TOKEN, { + handlerTimeout: 180_000, +}); + +bot.use(session({ store: redisStorage })); + +registerHandlers(bot, config, redisStorage, updateConfigValue, requestslimit); + +if (process.env.NODE_ENV === "production") { + setMenu(bot); + deleteWebHook(bot); +} + +process.once("SIGINT", () => bot.stop("SIGINT")); +process.once("SIGTERM", () => bot.stop("SIGTERM")); + +bot.launch({ dropPendingUpdates: true }).then(async () => { + if (process.env.NODE_ENV === "production") { + const usersArray = await getUsersArray(config); + await sendMessages(bot, usersArray); + } +}); diff --git a/src/keyboards/keyboards.js b/src/keyboards/keyboards.js deleted file mode 100644 index 323d5c1..0000000 --- a/src/keyboards/keyboards.js +++ /dev/null @@ -1,11 +0,0 @@ -import { LEXICON_EN } from '../lexicon/lexicon_en.js'; -import { Markup } from 'telegraf'; - -export function createMenuKeyboard() { - return Markup.keyboard( - [[LEXICON_EN['reset_btn']], - [LEXICON_EN['password_btn'], LEXICON_EN['getIDs_btn']]], - ).resize(); -} - -export const menuKeyboard = createMenuKeyboard(); diff --git a/src/keyboards/keyboards.ts b/src/keyboards/keyboards.ts new file mode 100644 index 0000000..bfd70c4 --- /dev/null +++ b/src/keyboards/keyboards.ts @@ -0,0 +1,11 @@ +import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { Markup } from "telegraf"; + +export function createMenuKeyboard() { + return Markup.keyboard([ + [LEXICON_EN["reset_btn"]], + [LEXICON_EN["password_btn"], LEXICON_EN["getIDs_btn"]], + ]).resize(); +} + +export const menuKeyboard = createMenuKeyboard(); diff --git a/src/keyboards/set_menu.js b/src/keyboards/set_menu.js deleted file mode 100644 index be9c248..0000000 --- a/src/keyboards/set_menu.js +++ /dev/null @@ -1,13 +0,0 @@ -import { commands } from '../lexicon/lexicon_en.js'; -import { LEXICON_EN } from '../lexicon/lexicon_en.js'; - -export const setMenu = async (bot) => { - bot.telegram - .setMyCommands(commands) - .then(() => { - console.log(LEXICON_EN['commands']); - }) - .catch((error) => { - console.log(`${error.name} setmenu: ${error.message}`); - }); -}; diff --git a/src/keyboards/set_menu.ts b/src/keyboards/set_menu.ts new file mode 100644 index 0000000..2676f0a --- /dev/null +++ b/src/keyboards/set_menu.ts @@ -0,0 +1,14 @@ +import { Telegraf } from "telegraf"; +import { commands } from "../lexicon/lexicon_en.js"; +import { LEXICON_EN } from "../lexicon/lexicon_en.js"; + +export const setMenu = async (bot: Telegraf) => { + bot.telegram + .setMyCommands(commands) + .then(() => { + console.log(LEXICON_EN["commands"]); + }) + .catch((error: Error) => { + console.log(`${error.name} setmenu: ${error.message}`); + }); +}; diff --git a/src/lexicon/lexicon_en.ts b/src/lexicon/lexicon_en.ts index e142b3b..b96a818 100644 --- a/src/lexicon/lexicon_en.ts +++ b/src/lexicon/lexicon_en.ts @@ -1,75 +1,78 @@ -interface Command { - command: string; - description: string; -} - export const commands: Command[] = [ - { command: 'start', description: 'Update the bot' }, - { command: 'new', description: 'Open a new session' }, - { command: 'help', description: 'Find out the bot\'s capabilities' }, - { command: 'image', description: 'Creating an image based on a text query' }, + { command: "start", description: "Update the bot" }, + { command: "new", description: "Open a new session" }, + { command: "help", description: "Find out the bot's capabilities" }, + { command: "image", description: "Creating an image based on a text query" }, ]; const date: Date = new Date(); export const LEXICON_EN = { botStarted: `Bot has been started! 🤖\n\n${date}`, - commands: 'Custom commands set successfully', - webhook: 'Webhook deleted successfully', - folderCreated: 'Folder created successfully', - start: 'Hello, welcome to an artificial intelligence chatbot ' + - 'that will help you with everything! 🤖\n\nYou can find ' + - 'the source code of the bot here: [click](https://github.com/BLazzeD21/Node.js-ChatGPT-Bot)\n' + - 'Developer: @blazzed21\n', - deniedAccess: 'This functionality is not available to you ⛔️', - processingText: 'Text accepted for processing', - processingTranscription: 'Voice message accepted for translation into text', - processingVoice: 'Voice message accepted for processing', - processingImage: 'The request to generate an'+ - 'image was accepted for processing', - responseError: 'Your request could not be processed or ' + - 'the number of requests has been exceeded, please try again. ' + - '\n\nIf the problem is not solved, ' + - 'create a new session via /new or wait a little. ⚠️', - noResponce: 'Sorry, no response received from the server ⛔️', - empty: 'Make the right request\n\nWrite the command like this:\ - /image request text', - emptyAdd: 'Make the right request\n\nWrite the command like this:\ - /add id', - removeAdd: 'Make the right request\n\nWrite the command like this:\ - /remove id', - reset: 'The context has been reset.', - reset_btn: 'Reset context 🗑', - getIDs_btn: 'Get IDs 🗃', - password_btn: 'Generate password 🎲', - add: 'New user ID added successfully ⏬', - remove: 'user ID deleted ⏫', - super: 'You are not a super user 🔒', - errorSending: 'Error sending message to: ', - waiting: 'The server timed out waiting for a response ⚠️', - noUser: 'There is no user with this ID ⚠️', - tooManyRequests: 'API requests are only available 3 times every 60 seconds 🔔', - UserNotExists: 'User ID does not exist 🔒', + commands: "Custom commands set successfully", + webhook: "Webhook deleted successfully", + folderCreated: "Folder created successfully", + start: + "Hello, welcome to an artificial intelligence chatbot " + + "that will help you with everything! 🤖\n\nYou can find " + + "the source code of the bot here: [click](https://github.com/BLazzeD21/Node.js-ChatGPT-Bot)\n" + + "Developer: @blazzed21\n", + deniedAccess: "This functionality is not available to you ⛔️", + processingText: "Text accepted for processing", + processingTranscription: "Voice message accepted for translation into text", + processingVoice: "Voice message accepted for processing", + processingImage: + "The request to generate an" + "image was accepted for processing", + responseError: + "Your request could not be processed or " + + "the number of requests has been exceeded, please try again. " + + "\n\nIf the problem is not solved, " + + "create a new session via /new or wait a little. ⚠️", + noResponce: "Sorry, no response received from the server ⛔️", + empty: + "Make the right request\n\nWrite the command like this:\ + /image request text", + emptyAdd: + "Make the right request\n\nWrite the command like this:\ + /add id", + removeAdd: + "Make the right request\n\nWrite the command like this:\ + /remove id", + reset: "The context has been reset.", + reset_btn: "Reset context 🗑", + getIDs_btn: "Get IDs 🗃", + password_btn: "Generate password 🎲", + add: "New user ID added successfully ⏬", + remove: "user ID deleted ⏫", + super: "You are not a super user 🔒", + errorSending: "Error sending message to: ", + waiting: "The server timed out waiting for a response ⚠️", + noUser: "There is no user with this ID ⚠️", + tooManyRequests: + "API requests are only available 3 times every 60 seconds 🔔", + UserNotExists: "User ID does not exist 🔒", }; export const getIDs = (chatId: number, userId: number) => { - return `Your ID: ${userId.toString()}\n`+ - `This chat ID: ${chatId.toString()}`; + return ( + `Your ID: ${userId.toString()}\n` + + `This chat ID: ${chatId.toString()}` + ); }; export const getHelp = () => { - let helpMessage: string = 'Commands available in the bot:\n'; + let helpMessage: string = "Commands available in the bot:\n"; for (const key in commands) { - helpMessage += `/${commands[key]['command']}` + - ' - ' + - `${commands[key]['description']}\n`; + helpMessage += + `/${commands[key]["command"]}` + + " - " + + `${commands[key]["description"]}\n`; } return helpMessage; }; - export const printPassword = (password: string) => { return `Generated password:\n${password}`; }; diff --git a/src/openai.js b/src/openai.ts similarity index 51% rename from src/openai.js rename to src/openai.ts index 1a371ea..f6e3d1b 100644 --- a/src/openai.js +++ b/src/openai.ts @@ -1,23 +1,24 @@ -import { OpenAI } from 'openai'; - -import { HttpsProxyAgent } from 'https-proxy-agent'; -import config from 'config'; -import { createReadStream } from 'fs'; +import { OpenAI } from "openai"; +import { HttpsProxyAgent } from "https-proxy-agent"; +import config from "config"; +import { createReadStream } from "fs"; class OpenAIApi { - roles = { - ASSISTANT: 'assistant', - USER: 'user', - SYSTEM: 'system', + private openai: OpenAI; + + public roles = { + ASSISTANT: "assistant", + USER: "user", + SYSTEM: "system", }; - models = { - generateText: 'gpt-3.5-turbo-1106', - transcription: 'whisper-1', - createImages: 'dall-e-2', + public models = { + generateText: "gpt-3.5-turbo-1106", + transcription: "whisper-1", + createImages: "dall-e-2", }; - constructor(apiKey, proxyUrl) { + constructor(apiKey: string, proxyUrl: string) { this.openai = new OpenAI({ maxRetries: 0, apiKey: apiKey, @@ -25,7 +26,7 @@ class OpenAIApi { }); } - async chat(messages) { + public async chat(messages: Messages[]) { const response = await this.openai.chat.completions.create({ messages, model: this.models.generateText, @@ -34,7 +35,7 @@ class OpenAIApi { return response.choices[0].message; } - async transcription(filepath) { + public async transcription(filepath: string) { const response = await this.openai.audio.transcriptions.create({ file: createReadStream(filepath), model: this.models.transcription, @@ -42,7 +43,7 @@ class OpenAIApi { return response.text; } - async getImage(text, size, count) { + public async getImage(text: string, size: "1024x1024" | "512x512", count: number) { const response = await this.openai.images.generate({ model: this.models.createImages, prompt: text, @@ -56,7 +57,7 @@ class OpenAIApi { } } -export const openai = new OpenAIApi( - config.get('OPENAI_KEY'), - config.get('PROXY_URL'), +export const openai: OpenAIApi = new OpenAIApi( + config.get("OPENAI_KEY"), + config.get("PROXY_URL") ); diff --git a/src/utils/checkAccess.js b/src/utils/checkAccess.js deleted file mode 100644 index daf8afa..0000000 --- a/src/utils/checkAccess.js +++ /dev/null @@ -1,24 +0,0 @@ -import { LEXICON_EN } from '../lexicon/lexicon_en.js'; - -export async function getUsersArray(config) { - let usersArray = config - .USERS_ID - .split(',') - .map((id) => parseInt(id)); - - if (usersArray.includes(NaN)) { - usersArray = [config.SUPER_USER]; - } - - return usersArray; -} - -export async function checkAccess(config, ctx) { - const allowedUserId = await getUsersArray(config); - - if (!allowedUserId.includes(ctx.from.id)) { - await ctx.reply(LEXICON_EN['deniedAccess']); - return true; - } - return false; -} diff --git a/src/utils/checkAccess.ts b/src/utils/checkAccess.ts new file mode 100644 index 0000000..a3e95b6 --- /dev/null +++ b/src/utils/checkAccess.ts @@ -0,0 +1,22 @@ +import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { Context } from "telegraf"; + +export async function getUsersArray(config: Config) { + let usersArray = config.USERS_ID.split(",").map((id: string) => parseInt(id)); + + if (usersArray.includes(NaN)) { + usersArray = [parseInt(config.SUPER_USER)]; + } + + return usersArray; +} + +export async function checkAccess(config: Config, ctx: Context) { + const allowedUserId = await getUsersArray(config); + + if (!allowedUserId.includes(ctx.from.id)) { + await ctx.reply(LEXICON_EN["deniedAccess"]); + return true; + } + return false; +} diff --git a/src/utils/createSession.js b/src/utils/createSession.ts similarity index 100% rename from src/utils/createSession.js rename to src/utils/createSession.ts diff --git a/src/utils/deleteFile.js b/src/utils/deleteFile.ts similarity index 58% rename from src/utils/deleteFile.js rename to src/utils/deleteFile.ts index e63921f..fccc23f 100644 --- a/src/utils/deleteFile.js +++ b/src/utils/deleteFile.ts @@ -1,6 +1,6 @@ -import { unlink } from 'fs/promises'; +import { unlink } from "fs/promises"; -export async function deleteFile(path) { +export async function deleteFile(path: string) { try { await unlink(path); } catch (error) { diff --git a/src/utils/deleteWebhook.js b/src/utils/deleteWebhook.js deleted file mode 100644 index 2968e72..0000000 --- a/src/utils/deleteWebhook.js +++ /dev/null @@ -1,12 +0,0 @@ -import { LEXICON_EN } from '../lexicon/lexicon_en.js'; - -export const deleteWebHook = async (bot) => { - bot.telegram - .deleteWebhook() - .then(() => { - console.log(LEXICON_EN['webhook']); - }) - .catch((error) => { - console.log(`${error.name} webhook: ${error.message}`); - }); -}; diff --git a/src/utils/deleteWebhook.ts b/src/utils/deleteWebhook.ts new file mode 100644 index 0000000..2830a44 --- /dev/null +++ b/src/utils/deleteWebhook.ts @@ -0,0 +1,13 @@ +import { Telegraf } from "telegraf"; +import { LEXICON_EN } from "../lexicon/lexicon_en.js"; + +export const deleteWebHook = async (bot: Telegraf) => { + bot.telegram + .deleteWebhook() + .then(() => { + console.log(LEXICON_EN["webhook"]); + }) + .catch((error: Error) => { + console.log(`${error.name} webhook: ${error.message}`); + }); +}; diff --git a/src/utils/generatePassword.js b/src/utils/generatePassword.js deleted file mode 100644 index 7e1e37e..0000000 --- a/src/utils/generatePassword.js +++ /dev/null @@ -1,30 +0,0 @@ -export const generatePassword = async () => { - const template = '*******-*******-*******'; - let password = ''; - - for (let i = 0; i < template.length; i++) { - if (template[i] === '*') { - const randomChar = - Math.random() < 0.5 ? - await generateRandomLetter() : - await generateRandomDigit(); - password += randomChar; - } else { - password += template[i]; - } - } - - return password; -}; - -const generateRandomLetter = async () => { - const letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - const randomIndex = Math.floor(Math.random() * letters.length); - return letters[randomIndex]; -}; - -const generateRandomDigit = async () => { - const digits = '0123456789'; - const randomIndex = Math.floor(Math.random() * digits.length); - return digits[randomIndex]; -}; diff --git a/src/utils/generatePassword.ts b/src/utils/generatePassword.ts new file mode 100644 index 0000000..3217b96 --- /dev/null +++ b/src/utils/generatePassword.ts @@ -0,0 +1,31 @@ +export const generatePassword = async () => { + const template: string = "*******-*******-*******"; + let password: string = ""; + + for (let i = 0; i < template.length; i++) { + if (template[i] === "*") { + const randomChar = + Math.random() < 0.5 + ? await generateRandomLetter() + : await generateRandomDigit(); + password += randomChar; + } else { + password += template[i]; + } + } + + return password; +}; + +const generateRandomLetter = async () => { + const letters: string = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const randomIndex: number = Math.floor(Math.random() * letters.length); + return letters[randomIndex]; +}; + +const generateRandomDigit = async () => { + const digits: string = "0123456789"; + const randomIndex: number = Math.floor(Math.random() * digits.length); + return digits[randomIndex]; +}; diff --git a/src/utils/sendMessages.js b/src/utils/sendMessages.js deleted file mode 100644 index 57f2f1e..0000000 --- a/src/utils/sendMessages.js +++ /dev/null @@ -1,11 +0,0 @@ -import { LEXICON_EN } from '../lexicon/lexicon_en.js'; - -export const sendMessages = async (bot, allowedUserId) => { - for (const recipient of allowedUserId) { - try { - await bot.telegram.sendMessage(recipient, LEXICON_EN['botStarted']); - } catch (error) { - console.error(LEXICON_EN['errorSending'], recipient.toString()); - } - } -}; diff --git a/src/utils/sendMessages.ts b/src/utils/sendMessages.ts new file mode 100644 index 0000000..52a840f --- /dev/null +++ b/src/utils/sendMessages.ts @@ -0,0 +1,12 @@ +import { Telegraf } from "telegraf"; +import { LEXICON_EN } from "../lexicon/lexicon_en.js"; + +export const sendMessages = async (bot: Telegraf, allowedUserId: number[]) => { + for (const recipient of allowedUserId) { + try { + await bot.telegram.sendMessage(recipient, LEXICON_EN["botStarted"]); + } catch (error) { + console.error(LEXICON_EN["errorSending"], recipient.toString()); + } + } +}; From 159fe3110f3e4c31455249508ace65fcad6d9e65 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 21:14:55 +0300 Subject: [PATCH 18/25] fix: fix sending messages when starting the bot --- src/index.ts | 53 +++++++++++++++++++++------------------ src/utils/sendMessages.ts | 14 +++++++---- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/index.ts b/src/index.ts index 52cb98f..a33fa86 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,20 +1,24 @@ -import { SessionStore } from "telegraf"; -import { Context, Telegraf, session } from "telegraf"; -import { Redis } from "@telegraf/session/redis"; -import { limit } from "@grammyjs/ratelimiter"; -import fs from "fs"; - -import { registerHandlers } from "./handlers/handlersRegistration.js"; -import { getUsersArray } from "./utils/checkAccess.js"; -import { sendMessages } from "./utils/sendMessages.js"; -import { LEXICON_EN } from "./lexicon/lexicon_en.js"; -import { setMenu } from "./keyboards/set_menu.js"; -import { deleteWebHook } from "./utils/deleteWebhook.js"; +import { SessionStore } from 'telegraf'; +import { Context, Telegraf, session } from 'telegraf'; +import { Redis } from '@telegraf/session/redis'; +import { limit } from '@grammyjs/ratelimiter'; +import fs from 'fs'; + +import { registerHandlers } from './handlers/handlersRegistration.js'; +import { sendMessages } from './utils/sendMessages.js'; +import { LEXICON_EN } from './lexicon/lexicon_en.js'; +import { setMenu } from './keyboards/set_menu.js'; +import { deleteWebHook } from './utils/deleteWebhook.js'; + +interface MyContext extends Context { + myProp?: string + myOtherProp?: number +} let config: Config = - process.env.NODE_ENV === "production" - ? JSON.parse(fs.readFileSync("config/production.json", "utf8")) - : JSON.parse(fs.readFileSync("config/default.json", "utf8")); + process.env.NODE_ENV === 'production' ? + JSON.parse(fs.readFileSync('config/production.json', 'utf8')) : + JSON.parse(fs.readFileSync('config/default.json', 'utf8')); const redisStorage: SessionStore = Redis({ url: config.REDIS_URL, @@ -28,11 +32,11 @@ const requestslimit: (ctx: Context, next: Function) => Promise = limit({ timeFrame: 60000, limit: 3, onLimitExceeded: (ctx: Context) => { - ctx.reply(LEXICON_EN["tooManyRequests"]); + ctx.reply(LEXICON_EN['tooManyRequests']); }, }); -const bot: Telegraf = new Telegraf(config.BOT_TOKEN, { +const bot: Telegraf = new Telegraf(config.BOT_TOKEN, { handlerTimeout: 180_000, }); @@ -40,17 +44,16 @@ bot.use(session({ store: redisStorage })); registerHandlers(bot, config, redisStorage, updateConfigValue, requestslimit); -if (process.env.NODE_ENV === "production") { +if (process.env.NODE_ENV === 'production') { setMenu(bot); deleteWebHook(bot); } -process.once("SIGINT", () => bot.stop("SIGINT")); -process.once("SIGTERM", () => bot.stop("SIGTERM")); +process.once('SIGINT', () => bot.stop('SIGINT')); +process.once('SIGTERM', () => bot.stop('SIGTERM')); + +bot.launch({ dropPendingUpdates: true }); -bot.launch({ dropPendingUpdates: true }).then(async () => { - if (process.env.NODE_ENV === "production") { - const usersArray = await getUsersArray(config); - await sendMessages(bot, usersArray); - } +bot.telegram.getMe().then(async () => { + await sendMessages(bot, config); }); diff --git a/src/utils/sendMessages.ts b/src/utils/sendMessages.ts index 52a840f..958af81 100644 --- a/src/utils/sendMessages.ts +++ b/src/utils/sendMessages.ts @@ -1,12 +1,16 @@ -import { Telegraf } from "telegraf"; -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { Telegraf } from 'telegraf'; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; +import { getUsersArray } from './checkAccess.js'; + +export const sendMessages = async (bot: Telegraf, config: Config) => { + const allowedUserId = await getUsersArray(config); -export const sendMessages = async (bot: Telegraf, allowedUserId: number[]) => { for (const recipient of allowedUserId) { try { - await bot.telegram.sendMessage(recipient, LEXICON_EN["botStarted"]); + await bot.telegram.sendMessage(recipient, LEXICON_EN['botStarted']); + console.log(`Message sent to user: ${recipient}`) } catch (error) { - console.error(LEXICON_EN["errorSending"], recipient.toString()); + console.error(LEXICON_EN['errorSending'], recipient.toString()); } } }; From 67ec79521fa08d2374afb57f765037a6f7c966ca Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 21:15:59 +0300 Subject: [PATCH 19/25] chore: change configuration for typescript --- .eslintrc.cjs | 26 +- package-lock.json | 842 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + 3 files changed, 856 insertions(+), 14 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 20c8ac8..56c0ae1 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -3,24 +3,18 @@ module.exports = { 'browser': true, 'es2021': true, }, - 'extends': 'google', - 'overrides': [ - { - 'env': { - 'node': true, - }, - 'files': [ - '.eslintrc.{js,cjs}', - ], - 'parserOptions': { - 'sourceType': 'script', - }, - }, + 'extends': [ + 'google', + 'plugin:@typescript-eslint/recommended', ], + 'parser': '@typescript-eslint/parser', 'parserOptions': { - 'ecmaVersion': 'latest', + 'ecmaVersion': 2021, 'sourceType': 'module', }, + 'plugins': [ + '@typescript-eslint', + ], 'rules': { 'no-unused-vars': 1, 'import/extensions': 0, @@ -30,5 +24,9 @@ module.exports = { 'quotes': ['error', 'single'], 'no-multi-str': 0, 'guard-for-in': 0, + 'new-cap': 0, + '@typescript-eslint/no-explicit-any': 0, + '@typescript-eslint/ban-types': 0, + '@typescript-eslint/no-unused-vars': 'warning', }, }; diff --git a/package-lock.json b/package-lock.json index cb612db..d8f27e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,8 @@ }, "devDependencies": { "@types/config": "^3.3.3", + "@typescript-eslint/eslint-plugin": "^6.19.0", + "@typescript-eslint/parser": "^6.19.0", "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.53.0", @@ -564,6 +566,12 @@ "integrity": "sha512-BB8DBAud88EgiAKlz8WQStzI771Kb6F3j4dioRJ4GD+tP4tzcZyMlz86aXuZT4s9hyesFORehMQE6eqtA5O+Vg==", "dev": true }, + "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/node": { "version": "18.18.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", @@ -581,6 +589,399 @@ "form-data": "^4.0.0" } }, + "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/@typescript-eslint/eslint-plugin": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.0.tgz", + "integrity": "sha512-DUCUkQNklCQYnrBSSikjVChdc84/vMPDQSgJTHBZ64G9bA9w0Crc0rd2diujKbTdp6w2J47qkeHQLoi0rpLCdg==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.19.0", + "@typescript-eslint/type-utils": "6.19.0", + "@typescript-eslint/utils": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.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/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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/eslint-plugin/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.0.tgz", + "integrity": "sha512-1DyBLG5SH7PYCd00QlroiW60YJ4rWMuUGa/JBV0iZuqi4l4IK3twKPq5ZkEebmGqRjXWVgsUzfd3+nZveewgow==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.19.0", + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/typescript-estree": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.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.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.0.tgz", + "integrity": "sha512-dO1XMhV2ehBI6QN8Ufi7I10wmUovmLU0Oru3n5LVlM2JuzB4M+dVphCPLkVpKvGij2j/pHBWuJ9piuXx+BhzxQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.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.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.0.tgz", + "integrity": "sha512-mcvS6WSWbjiSxKCwBcXtOM5pRkPQ6kcDds/juxcy/727IQr3xMEcwr/YLHW2A2+Fp5ql6khjbKBzOyjuPqGi/w==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.19.0", + "@typescript-eslint/utils": "6.19.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.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.0.tgz", + "integrity": "sha512-lFviGV/vYhOy3m8BJ/nAKoAyNhInTdXpftonhWle66XHAtT1ouBlkjL496b5H5hb8dWXHwtypTqgtb/DEa+j5A==", + "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.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.0.tgz", + "integrity": "sha512-o/zefXIbbLBZ8YJ51NlkSAt2BamrK6XOmuxSR3hynMIzzyMY33KuJ9vuMdFSXW+H0tVvdF9qBPTHA91HDb4BIQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.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/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "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/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/typescript-estree/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.0.tgz", + "integrity": "sha512-QR41YXySiuN++/dC9UArYOg4X86OAYP83OWTewpVx5ct1IZhjjgTLocj7QNxGhWoTqknsgpl7L+hGygCO+sdYw==", + "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.19.0", + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/typescript-estree": "6.19.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/utils/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.0.tgz", + "integrity": "sha512-hZaUCORLgubBvtGpp1JEFEazcuEdfxta9j4iUwdSAr7mEsYYAp3EAUyCZk3VEEqGj6W+AV4uWyrDGtrlawAsgQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.19.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", @@ -739,6 +1140,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "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/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -1319,6 +1729,18 @@ "md5": "^2.3.0" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -1585,6 +2007,22 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -1902,6 +2340,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "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/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -2290,6 +2748,28 @@ "is-buffer": "~1.1.6" } }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -2598,6 +3078,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -2952,6 +3441,15 @@ "semver": "bin/semver.js" } }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/spawn-command": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", @@ -3244,6 +3742,18 @@ "tree-kill": "cli.js" } }, + "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-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -3971,6 +4481,12 @@ "integrity": "sha512-BB8DBAud88EgiAKlz8WQStzI771Kb6F3j4dioRJ4GD+tP4tzcZyMlz86aXuZT4s9hyesFORehMQE6eqtA5O+Vg==", "dev": true }, + "@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 + }, "@types/node": { "version": "18.18.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", @@ -3988,6 +4504,255 @@ "form-data": "^4.0.0" } }, + "@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.0.tgz", + "integrity": "sha512-DUCUkQNklCQYnrBSSikjVChdc84/vMPDQSgJTHBZ64G9bA9w0Crc0rd2diujKbTdp6w2J47qkeHQLoi0rpLCdg==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.19.0", + "@typescript-eslint/type-utils": "6.19.0", + "@typescript-eslint/utils": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.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" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "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 + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.0.tgz", + "integrity": "sha512-1DyBLG5SH7PYCd00QlroiW60YJ4rWMuUGa/JBV0iZuqi4l4IK3twKPq5ZkEebmGqRjXWVgsUzfd3+nZveewgow==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "6.19.0", + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/typescript-estree": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.0", + "debug": "^4.3.4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "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 + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.0.tgz", + "integrity": "sha512-dO1XMhV2ehBI6QN8Ufi7I10wmUovmLU0Oru3n5LVlM2JuzB4M+dVphCPLkVpKvGij2j/pHBWuJ9piuXx+BhzxQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.0.tgz", + "integrity": "sha512-mcvS6WSWbjiSxKCwBcXtOM5pRkPQ6kcDds/juxcy/727IQr3xMEcwr/YLHW2A2+Fp5ql6khjbKBzOyjuPqGi/w==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "6.19.0", + "@typescript-eslint/utils": "6.19.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "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 + } + } + }, + "@typescript-eslint/types": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.0.tgz", + "integrity": "sha512-lFviGV/vYhOy3m8BJ/nAKoAyNhInTdXpftonhWle66XHAtT1ouBlkjL496b5H5hb8dWXHwtypTqgtb/DEa+j5A==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.0.tgz", + "integrity": "sha512-o/zefXIbbLBZ8YJ51NlkSAt2BamrK6XOmuxSR3hynMIzzyMY33KuJ9vuMdFSXW+H0tVvdF9qBPTHA91HDb4BIQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.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" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "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 + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.0.tgz", + "integrity": "sha512-QR41YXySiuN++/dC9UArYOg4X86OAYP83OWTewpVx5ct1IZhjjgTLocj7QNxGhWoTqknsgpl7L+hGygCO+sdYw==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.19.0", + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/typescript-estree": "6.19.0", + "semver": "^7.5.4" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.0.tgz", + "integrity": "sha512-hZaUCORLgubBvtGpp1JEFEazcuEdfxta9j4iUwdSAr7mEsYYAp3EAUyCZk3VEEqGj6W+AV4uWyrDGtrlawAsgQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.19.0", + "eslint-visitor-keys": "^3.4.1" + } + }, "@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -4104,6 +4869,12 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "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 + }, "asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -4552,6 +5323,15 @@ "md5": "^2.3.0" } }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -4747,6 +5527,19 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -4977,6 +5770,20 @@ "type-fest": "^0.20.2" } }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "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" + } + }, "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -5280,6 +6087,22 @@ "is-buffer": "~1.1.6" } }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -5482,6 +6305,12 @@ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -5727,6 +6556,12 @@ } } }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "spawn-command": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", @@ -5952,6 +6787,13 @@ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, + "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, + "requires": {} + }, "ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", diff --git a/package.json b/package.json index 03790e4..6b37797 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,8 @@ "homepage": "https://github.com/BLazzeD21/Node.js-ChatGPT-Bot#readme", "devDependencies": { "@types/config": "^3.3.3", + "@typescript-eslint/eslint-plugin": "^6.19.0", + "@typescript-eslint/parser": "^6.19.0", "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.53.0", From 8be8b206eea6360478e3c1a551fb4c3da5d421a7 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 21:31:54 +0300 Subject: [PATCH 20/25] refactor: move the check inside functions --- src/keyboards/set_menu.ts | 12 +++++++----- src/utils/deleteWebhook.ts | 10 ++++++---- src/utils/sendMessages.ts | 16 +++++++++------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/keyboards/set_menu.ts b/src/keyboards/set_menu.ts index 2676f0a..79520ac 100644 --- a/src/keyboards/set_menu.ts +++ b/src/keyboards/set_menu.ts @@ -1,14 +1,16 @@ -import { Telegraf } from "telegraf"; -import { commands } from "../lexicon/lexicon_en.js"; -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { Telegraf } from 'telegraf'; +import { commands } from '../lexicon/lexicon_en.js'; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; export const setMenu = async (bot: Telegraf) => { - bot.telegram + if (process.env.NODE_ENV === 'production') { + bot.telegram .setMyCommands(commands) .then(() => { - console.log(LEXICON_EN["commands"]); + console.log(LEXICON_EN['commands']); }) .catch((error: Error) => { console.log(`${error.name} setmenu: ${error.message}`); }); + } }; diff --git a/src/utils/deleteWebhook.ts b/src/utils/deleteWebhook.ts index 2830a44..7dd97e4 100644 --- a/src/utils/deleteWebhook.ts +++ b/src/utils/deleteWebhook.ts @@ -1,13 +1,15 @@ -import { Telegraf } from "telegraf"; -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { Telegraf } from 'telegraf'; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; export const deleteWebHook = async (bot: Telegraf) => { - bot.telegram + if(process.env.NODE_ENV === 'production') { + bot.telegram .deleteWebhook() .then(() => { - console.log(LEXICON_EN["webhook"]); + console.log(LEXICON_EN['webhook']); }) .catch((error: Error) => { console.log(`${error.name} webhook: ${error.message}`); }); + } }; diff --git a/src/utils/sendMessages.ts b/src/utils/sendMessages.ts index 958af81..543bed9 100644 --- a/src/utils/sendMessages.ts +++ b/src/utils/sendMessages.ts @@ -3,14 +3,16 @@ import { LEXICON_EN } from '../lexicon/lexicon_en.js'; import { getUsersArray } from './checkAccess.js'; export const sendMessages = async (bot: Telegraf, config: Config) => { - const allowedUserId = await getUsersArray(config); + if(process.env.NODE_ENV === 'production') { + const allowedUserId = await getUsersArray(config); - for (const recipient of allowedUserId) { - try { - await bot.telegram.sendMessage(recipient, LEXICON_EN['botStarted']); - console.log(`Message sent to user: ${recipient}`) - } catch (error) { - console.error(LEXICON_EN['errorSending'], recipient.toString()); + for (const recipient of allowedUserId) { + try { + await bot.telegram.sendMessage(recipient, LEXICON_EN['botStarted']); + console.log(`Message sent to user: ${recipient}`) + } catch (error) { + console.error(LEXICON_EN['errorSending'], recipient.toString()); + } } } }; From 55b4c9f68feb5909df8a8188deee53642b461d84 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 21:42:21 +0300 Subject: [PATCH 21/25] refactor: add types for class methods --- src/converter.ts | 52 ++++----- src/handlers/adminHandlers.ts | 120 +++++++++---------- src/handlers/errorHandler.ts | 14 +-- src/handlers/handlersRegistration.ts | 62 +++++----- src/handlers/openaiHandlers.ts | 166 +++++++++++++-------------- src/handlers/userHandlers.ts | 14 +-- src/keyboards/keyboards.ts | 8 +- src/openai.ts | 32 +++--- src/utils/checkAccess.ts | 8 +- src/utils/deleteFile.ts | 2 +- src/utils/generatePassword.ts | 16 +-- 11 files changed, 249 insertions(+), 245 deletions(-) diff --git a/src/converter.ts b/src/converter.ts index d29a7d4..5f1abda 100644 --- a/src/converter.ts +++ b/src/converter.ts @@ -1,12 +1,12 @@ -import axios from "axios"; -import installer from "@ffmpeg-installer/ffmpeg"; -import ffmpeg from "fluent-ffmpeg"; +import axios from 'axios'; +import installer from '@ffmpeg-installer/ffmpeg'; +import ffmpeg from 'fluent-ffmpeg'; -import { createWriteStream } from "fs"; -import { dirname, resolve } from "path"; -import { fileURLToPath } from "url"; +import { createWriteStream } from 'fs'; +import { dirname, resolve } from 'path'; +import { fileURLToPath } from 'url'; -import { deleteFile } from "./utils/deleteFile.js"; +import { deleteFile } from './utils/deleteFile.js'; const __dirname: string = dirname(fileURLToPath(import.meta.url)); @@ -15,44 +15,44 @@ class OggConverter { ffmpeg.setFfmpegPath(installer.path); } - toMp3(input: string, output: string) { + public async toMp3(input: string, output: string) { try { const outputPath = resolve( - __dirname, - "..", - dirname(input), - `${output}.mp3` + __dirname, + '..', + dirname(input), + `${output}.mp3`, ); return new Promise((resolve, reject) => { ffmpeg(input) - .inputOption("-t 30") - .output(outputPath) - .on("end", () => { - deleteFile(input); - resolve(outputPath); - }) - .on("error", (error: Error) => reject(error.message)) - .run(); + .inputOption('-t 30') + .output(outputPath) + .on('end', () => { + deleteFile(input); + resolve(outputPath); + }) + .on('error', (error: Error) => reject(error.message)) + .run(); }); } catch (error) { - console.log("Error create:" + error.message); + console.log('Error create:' + error.message); } } - async create(url: string, filename: string) { + public async create(url: string, filename: string) { try { - const oggPath: string = resolve(__dirname, "voices", `${filename}.ogg`); + const oggPath: string = resolve(__dirname, 'voices', `${filename}.ogg`); const response = await axios.get(url, { - responseType: "stream", + responseType: 'stream', }); return new Promise((resolve) => { const stream = createWriteStream(oggPath); response.data.pipe(stream); - stream.on("finish", () => resolve(oggPath)); + stream.on('finish', () => resolve(oggPath)); }); } catch (error) { - console.log("Error create:" + error.message); + console.log('Error create:' + error.message); } } } diff --git a/src/handlers/adminHandlers.ts b/src/handlers/adminHandlers.ts index 4f521a8..102750a 100644 --- a/src/handlers/adminHandlers.ts +++ b/src/handlers/adminHandlers.ts @@ -1,25 +1,25 @@ -import fs from "fs"; -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; -import { getUsersArray } from "../utils/checkAccess.js"; -import { menuKeyboard } from "../keyboards/keyboards.js"; -import { Context } from "telegraf"; +import fs from 'fs'; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; +import { getUsersArray } from '../utils/checkAccess.js'; +import { menuKeyboard } from '../keyboards/keyboards.js'; +import { Context } from 'telegraf'; class AdminHandlers { - addHandler = (config: Config, callback: UpdateConfigValue) => { + public addHandler = (config: Config, callback: UpdateConfigValue) => { return async (ctx: Context) => { - const chat_id: string = ctx.from.id.toString(); - if (chat_id != config.SUPER_USER) { - await ctx.reply(LEXICON_EN["super"]); + const ChatId: string = ctx.from.id.toString(); + if (ChatId != config.SUPER_USER) { + await ctx.reply(LEXICON_EN['super']); return; } - if (!(ctx.message && "text" in ctx.message)) return; - const requestText: string = ctx.message.text.replace("/add", "").trim(); + if (!(ctx.message && 'text' in ctx.message)) return; + const requestText: string = ctx.message.text.replace('/add', '').trim(); try { if (!requestText) { - await ctx.reply(LEXICON_EN["emptyAdd"], { - parse_mode: "HTML", + await ctx.reply(LEXICON_EN['emptyAdd'], { + parse_mode: 'HTML', ...menuKeyboard, }); return; @@ -27,17 +27,17 @@ class AdminHandlers { config.USERS_ID += `,${requestText}`; - if (process.env.NODE_ENV === "production") { + if (process.env.NODE_ENV === 'production') { fs.writeFileSync( - "config/production.json", - JSON.stringify(config, null, 2), - "utf8" + 'config/production.json', + JSON.stringify(config, null, 2), + 'utf8', ); } else { fs.writeFileSync( - "config/default.json", - JSON.stringify(config, null, 2), - "utf8" + 'config/default.json', + JSON.stringify(config, null, 2), + 'utf8', ); } @@ -45,59 +45,59 @@ class AdminHandlers { const output: string = `Added ID: ${requestText}\n\n` + - `${LEXICON_EN["add"]}`; + `${LEXICON_EN['add']}`; - await ctx.reply(output, { parse_mode: "HTML", ...menuKeyboard }); + await ctx.reply(output, { parse_mode: 'HTML', ...menuKeyboard }); } catch (error) { - console.log(LEXICON_EN["errorSending"], error); + console.log(LEXICON_EN['errorSending'], error); } }; }; - removeHandler = (config: Config, callback: UpdateConfigValue) => { + public removeHandler = (config: Config, callback: UpdateConfigValue) => { return async (ctx: Context) => { - const chat_id = ctx.from.id.toString(); - if (chat_id != config.SUPER_USER) { - await ctx.reply(LEXICON_EN["super"]); + const ChatId = ctx.from.id.toString(); + if (ChatId != config.SUPER_USER) { + await ctx.reply(LEXICON_EN['super']); return; } - if (!(ctx.message && "text" in ctx.message)) return; + if (!(ctx.message && 'text' in ctx.message)) return; const requestText: string = ctx.message.text - .replace("/remove", "") - .trim(); + .replace('/remove', '') + .trim(); try { if (!requestText) { - await ctx.reply(LEXICON_EN["removeAdd"], { - parse_mode: "HTML", + await ctx.reply(LEXICON_EN['removeAdd'], { + parse_mode: 'HTML', ...menuKeyboard, }); return; } - const usersID: string[] = config.USERS_ID.split(","); + const usersID: string[] = config.USERS_ID.split(','); if (!usersID.includes(requestText.toString())) { - await ctx.reply(LEXICON_EN["UserNotExists"]); + await ctx.reply(LEXICON_EN['UserNotExists']); return; } const filteredUsers = usersID - .filter((id: string) => id !== requestText.toString()) - .join(","); + .filter((id: string) => id !== requestText.toString()) + .join(','); config.USERS_ID = filteredUsers; - if (process.env.NODE_ENV === "production") { + if (process.env.NODE_ENV === 'production') { fs.writeFileSync( - "config/production.json", - JSON.stringify(config, null, 2), - "utf8" + 'config/production.json', + JSON.stringify(config, null, 2), + 'utf8', ); } else { fs.writeFileSync( - "config/default.json", - JSON.stringify(config, null, 2), - "utf8" + 'config/default.json', + JSON.stringify(config, null, 2), + 'utf8', ); } @@ -105,20 +105,20 @@ class AdminHandlers { const output: string = `Removed ID: ${requestText}\n\n` + - `${LEXICON_EN["remove"]}`; + `${LEXICON_EN['remove']}`; - await ctx.reply(output, { parse_mode: "HTML", ...menuKeyboard }); + await ctx.reply(output, { parse_mode: 'HTML', ...menuKeyboard }); } catch (error) { - console.log(LEXICON_EN["errorSending"], error); + console.log(LEXICON_EN['errorSending'], error); } }; }; - showHandler = (config: Config, callback: UpdateConfigValue) => { + public showHandler = (config: Config, callback: UpdateConfigValue) => { return async (ctx: Context) => { - const chat_id = ctx.from.id.toString(); - if (chat_id != config.SUPER_USER) { - await ctx.reply(LEXICON_EN["super"]); + const ChatId = ctx.from.id.toString(); + if (ChatId != config.SUPER_USER) { + await ctx.reply(LEXICON_EN['super']); return; } @@ -126,29 +126,29 @@ class AdminHandlers { const uniqueIDs: number[] = [...new Set(users)]; - config.USERS_ID = uniqueIDs.join(","); + config.USERS_ID = uniqueIDs.join(','); - if (process.env.NODE_ENV === "production") { + if (process.env.NODE_ENV === 'production') { fs.writeFileSync( - "config/production.json", - JSON.stringify(config, null, 2), - "utf8" + 'config/production.json', + JSON.stringify(config, null, 2), + 'utf8', ); } else { fs.writeFileSync( - "config/default.json", - JSON.stringify(config, null, 2), - "utf8" + 'config/default.json', + JSON.stringify(config, null, 2), + 'utf8', ); } - let output: string = "🗃 Bot users:\n\n"; + let output: string = '🗃 Bot users:\n\n'; uniqueIDs.forEach((id) => { output += `👤 ${id}\n`; }); - await ctx.reply(output, { parse_mode: "HTML", ...menuKeyboard }); + await ctx.reply(output, { parse_mode: 'HTML', ...menuKeyboard }); await callback(config); }; diff --git a/src/handlers/errorHandler.ts b/src/handlers/errorHandler.ts index 89917b3..6b7d488 100644 --- a/src/handlers/errorHandler.ts +++ b/src/handlers/errorHandler.ts @@ -1,16 +1,16 @@ -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; -import { menuKeyboard } from "../keyboards/keyboards.js"; -import { Context } from "telegraf"; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; +import { menuKeyboard } from '../keyboards/keyboards.js'; +import { Context } from 'telegraf'; class ErrorHandler { - responseError(ctx: Context, handler: string) { + public responseError(ctx: Context, handler: string) { return async (error: Error) => { console.log( - `${ctx.from.id} - ${error.name} ${handler}: ${error.message}` + `${ctx.from.id} - ${error.name} ${handler}: ${error.message}`, ); await ctx.reply( - `${LEXICON_EN["noResponce"]}\n\n${error.name}: ${error.message}`, - { disable_web_page_preview: true, ...menuKeyboard } + `${LEXICON_EN['noResponce']}\n\n${error.name}: ${error.message}`, + { disable_web_page_preview: true, ...menuKeyboard }, ); }; } diff --git a/src/handlers/handlersRegistration.ts b/src/handlers/handlersRegistration.ts index 0e2c9f3..00ba5dd 100644 --- a/src/handlers/handlersRegistration.ts +++ b/src/handlers/handlersRegistration.ts @@ -1,48 +1,48 @@ -import UserHandlers from "./userHandlers.js"; -import OpenAIHandlers from "./openaiHandlers.js"; -import AdminHandlers from "./adminHandlers.js"; -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; -import { message } from "telegraf/filters"; -import { Context, Telegraf, SessionStore } from "telegraf"; +import UserHandlers from './userHandlers.js'; +import OpenAIHandlers from './openaiHandlers.js'; +import AdminHandlers from './adminHandlers.js'; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; +import { message } from 'telegraf/filters'; +import { Context, Telegraf, SessionStore } from 'telegraf'; export const registerHandlers = async ( - bot: Telegraf, - config: Config, - redisStorage: SessionStore, - updateConfigValue: UpdateConfigValue, - requestslimit: (ctx: Context, next: Function) => Promise + bot: Telegraf, + config: Config, + redisStorage: SessionStore, + updateConfigValue: UpdateConfigValue, + requestslimit: (ctx: Context, next: Function) => Promise, ) => { - bot.command("start", UserHandlers.startHandler(redisStorage)); - bot.command("add", AdminHandlers.addHandler(config, updateConfigValue)); - bot.command("remove", AdminHandlers.removeHandler(config, updateConfigValue)); - bot.command("show", AdminHandlers.showHandler(config, updateConfigValue)); - bot.command("new", UserHandlers.newHandler(config, redisStorage)); - bot.command("help", UserHandlers.helpHandler(config)); - bot.command("password", UserHandlers.passwordHandler()); - bot.hears(LEXICON_EN["getIDs_btn"], UserHandlers.chatIDHandler()); + bot.command('start', UserHandlers.startHandler(redisStorage)); + bot.command('add', AdminHandlers.addHandler(config, updateConfigValue)); + bot.command('remove', AdminHandlers.removeHandler(config, updateConfigValue)); + bot.command('show', AdminHandlers.showHandler(config, updateConfigValue)); + bot.command('new', UserHandlers.newHandler(config, redisStorage)); + bot.command('help', UserHandlers.helpHandler(config)); + bot.command('password', UserHandlers.passwordHandler()); + bot.hears(LEXICON_EN['getIDs_btn'], UserHandlers.chatIDHandler()); - bot.hears(LEXICON_EN["password_btn"], UserHandlers.passwordHandler()); + bot.hears(LEXICON_EN['password_btn'], UserHandlers.passwordHandler()); bot.hears( - LEXICON_EN["reset_btn"], - UserHandlers.newHandler(config, redisStorage) + LEXICON_EN['reset_btn'], + UserHandlers.newHandler(config, redisStorage), ); - bot.command("image", requestslimit, OpenAIHandlers.imageHandler(config)); + bot.command('image', requestslimit, OpenAIHandlers.imageHandler(config)); bot.on( - message("text"), - requestslimit, - OpenAIHandlers.textHandler(config, redisStorage) + message('text'), + requestslimit, + OpenAIHandlers.textHandler(config, redisStorage), ); bot.on( - message("voice"), - requestslimit, - OpenAIHandlers.voiceHandler(config, redisStorage) + message('voice'), + requestslimit, + OpenAIHandlers.voiceHandler(config, redisStorage), ); bot.catch(async (error: Error, ctx: Context) => { - if (error.name === "TimeoutError") { - await ctx.reply(LEXICON_EN["waiting"]); + if (error.name === 'TimeoutError') { + await ctx.reply(LEXICON_EN['waiting']); } }); }; diff --git a/src/handlers/openaiHandlers.ts b/src/handlers/openaiHandlers.ts index 545c249..221a687 100644 --- a/src/handlers/openaiHandlers.ts +++ b/src/handlers/openaiHandlers.ts @@ -1,25 +1,25 @@ -import { Context, SessionStore } from "telegraf"; -import fs from "fs"; -import { code } from "telegraf/format"; -import { OpenAI } from "openai"; +import { Context, SessionStore } from 'telegraf'; +import fs from 'fs'; +import { code } from 'telegraf/format'; +import { OpenAI } from 'openai'; -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; -import { openai } from "../openai.js"; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; +import { openai } from '../openai.js'; -import { converter } from "../converter.js"; -import { deleteFile } from "../utils/deleteFile.js"; +import { converter } from '../converter.js'; +import { deleteFile } from '../utils/deleteFile.js'; -import { menuKeyboard } from "../keyboards/keyboards.js"; -import { createInitialSession } from "../utils/createSession.js"; -import { checkAccess } from "../utils/checkAccess.js"; +import { menuKeyboard } from '../keyboards/keyboards.js'; +import { createInitialSession } from '../utils/createSession.js'; +import { checkAccess } from '../utils/checkAccess.js'; -import ErrorHandler from "./errorHandler.js"; +import ErrorHandler from './errorHandler.js'; class OpenAIHandlers { - sendResponse = ( - ctx: Context, - redisStorage: SessionStore, - userId: string + private sendResponse = ( + ctx: Context, + redisStorage: SessionStore, + userId: string, ) => { return async (response: OpenAI.Chat.Completions.ChatCompletionMessage) => { if (response && response.content) { @@ -30,12 +30,12 @@ class OpenAIHandlers { } await ctx - .reply(response.content, { parse_mode: "Markdown", ...menuKeyboard }) - .catch(async () => await ctx.reply(response.content, menuKeyboard)); + .reply(response.content, { parse_mode: 'Markdown', ...menuKeyboard }) + .catch(async () => await ctx.reply(response.content, menuKeyboard)); }; }; - textHandler = (config: Config, redisStorage: SessionStore) => { + public textHandler = (config: Config, redisStorage: SessionStore) => { return async (ctx: Context) => { if (await checkAccess(config, ctx)) return; @@ -43,13 +43,13 @@ class OpenAIHandlers { redisStorage[userId] ??= createInitialSession(); const processing = await ctx.reply( - code(LEXICON_EN["processingText"]), - menuKeyboard + code(LEXICON_EN['processingText']), + menuKeyboard, ); - await ctx.sendChatAction("typing"); + await ctx.sendChatAction('typing'); - if (!(ctx.message && "text" in ctx.message)) return; + if (!(ctx.message && 'text' in ctx.message)) return; const content = ctx.message.text; redisStorage[userId].messages.push({ @@ -58,16 +58,16 @@ class OpenAIHandlers { }); openai - .chat(redisStorage[userId].messages) - .then(this.sendResponse(ctx, redisStorage, userId)) - .catch(ErrorHandler.responseError(ctx, "textHandler")) - .finally(async () => { - await ctx.deleteMessage(processing.message_id); - }); + .chat(redisStorage[userId].messages) + .then(this.sendResponse(ctx, redisStorage, userId)) + .catch(ErrorHandler.responseError(ctx, 'textHandler')) + .finally(async () => { + await ctx.deleteMessage(processing.message_id); + }); }; }; - voiceHandler = (config: Config, redisStorage: SessionStore) => { + public voiceHandler = (config: Config, redisStorage: SessionStore) => { return async (ctx: Context) => { if (await checkAccess(config, ctx)) return; @@ -75,94 +75,94 @@ class OpenAIHandlers { redisStorage[userId] ??= createInitialSession(); const processingTranscription = await ctx.reply( - code(LEXICON_EN["processingTranscription"]), - menuKeyboard + code(LEXICON_EN['processingTranscription']), + menuKeyboard, ); - await ctx.sendChatAction("typing"); + await ctx.sendChatAction('typing'); - if (!fs.existsSync("build/voices")) { - fs.mkdir("build/voices", (error) => { + if (!fs.existsSync('build/voices')) { + fs.mkdir('build/voices', (error) => { if (error) throw error; - console.log(LEXICON_EN["folderCreated"]); + console.log(LEXICON_EN['folderCreated']); }); } - if (!(ctx.message && "voice" in ctx.message)) return; + if (!(ctx.message && 'voice' in ctx.message)) return; const link = await ctx.telegram.getFileLink(ctx.message.voice.file_id); const oggPath = await converter.create(link.href, userId); const mp3Path = await converter.toMp3(oggPath.toString(), userId); openai - .transcription(mp3Path.toString()) - .then(async (text) => { - const processingVoice = await ctx.reply( - code(LEXICON_EN["processingVoice"]), - menuKeyboard - ); - - redisStorage[userId].messages.push({ - role: openai.roles.USER, - content: text, - }); + .transcription(mp3Path.toString()) + .then(async (text) => { + const processingVoice = await ctx.reply( + code(LEXICON_EN['processingVoice']), + menuKeyboard, + ); - openai - .chat(redisStorage[userId].messages) - .then(this.sendResponse(ctx, redisStorage, userId)) - .catch(ErrorHandler.responseError(ctx, "transcription")) - .finally(async () => { - await ctx.deleteMessage(processingVoice.message_id); + redisStorage[userId].messages.push({ + role: openai.roles.USER, + content: text, }); - }) - .catch(ErrorHandler.responseError(ctx, "voiceHandler")) - .finally(async () => { - await deleteFile(mp3Path.toString()); - await ctx.deleteMessage(processingTranscription.message_id); - }); + + openai + .chat(redisStorage[userId].messages) + .then(this.sendResponse(ctx, redisStorage, userId)) + .catch(ErrorHandler.responseError(ctx, 'transcription')) + .finally(async () => { + await ctx.deleteMessage(processingVoice.message_id); + }); + }) + .catch(ErrorHandler.responseError(ctx, 'voiceHandler')) + .finally(async () => { + await deleteFile(mp3Path.toString()); + await ctx.deleteMessage(processingTranscription.message_id); + }); }; }; - imageHandler = (config: Config) => { + public imageHandler = (config: Config) => { return async (ctx: Context) => { if (await checkAccess(config, ctx)) return; const processing = await ctx.reply( - code(LEXICON_EN["processingImage"]), - menuKeyboard + code(LEXICON_EN['processingImage']), + menuKeyboard, ); - await ctx.sendChatAction("upload_photo"); + await ctx.sendChatAction('upload_photo'); - if (!(ctx.message && "text" in ctx.message)) return; - const requestText = ctx.message.text.replace("/image", "").trim(); + if (!(ctx.message && 'text' in ctx.message)) return; + const requestText = ctx.message.text.replace('/image', '').trim(); if (!requestText) { await ctx.deleteMessage(processing.message_id); - await ctx.reply(LEXICON_EN["empty"], { - parse_mode: "HTML", + await ctx.reply(LEXICON_EN['empty'], { + parse_mode: 'HTML', ...menuKeyboard, }); return; } - const size = "1024x1024"; + const size = '1024x1024'; const count = 1; openai - .getImage(requestText, size, count) - .then(async (response) => { - if (response) { - await ctx.replyWithPhoto( - { url: response }, - { caption: requestText, ...menuKeyboard } - ); - return; - } - }) - .catch(ErrorHandler.responseError(ctx, "textHandler")) - .finally(async () => { - await ctx.deleteMessage(processing.message_id); - }); + .getImage(requestText, size, count) + .then(async (response) => { + if (response) { + await ctx.replyWithPhoto( + { url: response }, + { caption: requestText, ...menuKeyboard }, + ); + return; + } + }) + .catch(ErrorHandler.responseError(ctx, 'textHandler')) + .finally(async () => { + await ctx.deleteMessage(processing.message_id); + }); }; }; } diff --git a/src/handlers/userHandlers.ts b/src/handlers/userHandlers.ts index 5aecbc3..1ae8bd9 100644 --- a/src/handlers/userHandlers.ts +++ b/src/handlers/userHandlers.ts @@ -10,7 +10,7 @@ import { generatePassword } from '../utils/generatePassword.js'; import { Context, SessionStore } from 'telegraf'; class UserHandlers { - startHandler = (redisStorage: SessionStore) => { + public startHandler = (redisStorage: SessionStore) => { return async (ctx: Context) => { const sessionId: number = ctx.message.chat.id; @@ -22,7 +22,7 @@ class UserHandlers { }; }; - helpHandler = (config: Config) => { + public helpHandler = (config: Config) => { return async (ctx: Context) => { if (await checkAccess(config, ctx)) return; @@ -30,10 +30,10 @@ class UserHandlers { }; }; - chatIDHandler = () => { + public chatIDHandler = () => { return async (ctx: Context) => { const userId: number = ctx.from.id; - const chatId: number = ctx.message.chat.id; + const chatId: number = ctx.chat.id; await ctx.reply( getIDs(chatId, userId), @@ -42,7 +42,7 @@ class UserHandlers { }; }; - passwordHandler = () => { + public passwordHandler = () => { return async (ctx: Context) => { const password = await generatePassword(); @@ -53,12 +53,12 @@ class UserHandlers { }; }; - newHandler = (config: Config, redisStorage: SessionStore) => { + public newHandler = (config: Config, redisStorage: SessionStore) => { return async (ctx: Context) => { if (await checkAccess(config, ctx)) return; const sessionId: number = ctx.message.chat.id; - + redisStorage[sessionId] = createInitialSession(); await ctx.reply(LEXICON_EN['reset'], menuKeyboard); diff --git a/src/keyboards/keyboards.ts b/src/keyboards/keyboards.ts index bfd70c4..11331e2 100644 --- a/src/keyboards/keyboards.ts +++ b/src/keyboards/keyboards.ts @@ -1,10 +1,10 @@ -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; -import { Markup } from "telegraf"; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; +import { Markup } from 'telegraf'; export function createMenuKeyboard() { return Markup.keyboard([ - [LEXICON_EN["reset_btn"]], - [LEXICON_EN["password_btn"], LEXICON_EN["getIDs_btn"]], + [LEXICON_EN['reset_btn']], + [LEXICON_EN['password_btn'], LEXICON_EN['getIDs_btn']], ]).resize(); } diff --git a/src/openai.ts b/src/openai.ts index f6e3d1b..41b3883 100644 --- a/src/openai.ts +++ b/src/openai.ts @@ -1,21 +1,21 @@ -import { OpenAI } from "openai"; -import { HttpsProxyAgent } from "https-proxy-agent"; -import config from "config"; -import { createReadStream } from "fs"; +import { OpenAI } from 'openai'; +import { HttpsProxyAgent } from 'https-proxy-agent'; +import config from 'config'; +import { createReadStream } from 'fs'; class OpenAIApi { private openai: OpenAI; public roles = { - ASSISTANT: "assistant", - USER: "user", - SYSTEM: "system", + ASSISTANT: 'assistant', + USER: 'user', + SYSTEM: 'system', }; public models = { - generateText: "gpt-3.5-turbo-1106", - transcription: "whisper-1", - createImages: "dall-e-2", + generateText: 'gpt-3.5-turbo-1106', + transcription: 'whisper-1', + createImages: 'dall-e-2', }; constructor(apiKey: string, proxyUrl: string) { @@ -43,7 +43,11 @@ class OpenAIApi { return response.text; } - public async getImage(text: string, size: "1024x1024" | "512x512", count: number) { + public async getImage( + text: string, + size: '1024x1024' | '512x512', + count: number, + ) { const response = await this.openai.images.generate({ model: this.models.createImages, prompt: text, @@ -57,7 +61,7 @@ class OpenAIApi { } } -export const openai: OpenAIApi = new OpenAIApi( - config.get("OPENAI_KEY"), - config.get("PROXY_URL") +export const openai = new OpenAIApi( + config.get('OPENAI_KEY'), + config.get('PROXY_URL'), ); diff --git a/src/utils/checkAccess.ts b/src/utils/checkAccess.ts index a3e95b6..8592bf2 100644 --- a/src/utils/checkAccess.ts +++ b/src/utils/checkAccess.ts @@ -1,8 +1,8 @@ -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; -import { Context } from "telegraf"; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; +import { Context } from 'telegraf'; export async function getUsersArray(config: Config) { - let usersArray = config.USERS_ID.split(",").map((id: string) => parseInt(id)); + let usersArray = config.USERS_ID.split(',').map((id: string) => parseInt(id)); if (usersArray.includes(NaN)) { usersArray = [parseInt(config.SUPER_USER)]; @@ -15,7 +15,7 @@ export async function checkAccess(config: Config, ctx: Context) { const allowedUserId = await getUsersArray(config); if (!allowedUserId.includes(ctx.from.id)) { - await ctx.reply(LEXICON_EN["deniedAccess"]); + await ctx.reply(LEXICON_EN['deniedAccess']); return true; } return false; diff --git a/src/utils/deleteFile.ts b/src/utils/deleteFile.ts index fccc23f..9156334 100644 --- a/src/utils/deleteFile.ts +++ b/src/utils/deleteFile.ts @@ -1,4 +1,4 @@ -import { unlink } from "fs/promises"; +import { unlink } from 'fs/promises'; export async function deleteFile(path: string) { try { diff --git a/src/utils/generatePassword.ts b/src/utils/generatePassword.ts index 3217b96..79d8c7c 100644 --- a/src/utils/generatePassword.ts +++ b/src/utils/generatePassword.ts @@ -1,13 +1,13 @@ export const generatePassword = async () => { - const template: string = "*******-*******-*******"; - let password: string = ""; + const template: string = '*******-*******-*******'; + let password: string = ''; for (let i = 0; i < template.length; i++) { - if (template[i] === "*") { + if (template[i] === '*') { const randomChar = - Math.random() < 0.5 - ? await generateRandomLetter() - : await generateRandomDigit(); + Math.random() < 0.5 ? + await generateRandomLetter() : + await generateRandomDigit(); password += randomChar; } else { password += template[i]; @@ -19,13 +19,13 @@ export const generatePassword = async () => { const generateRandomLetter = async () => { const letters: string = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; const randomIndex: number = Math.floor(Math.random() * letters.length); return letters[randomIndex]; }; const generateRandomDigit = async () => { - const digits: string = "0123456789"; + const digits: string = '0123456789'; const randomIndex: number = Math.floor(Math.random() * digits.length); return digits[randomIndex]; }; From cc4f4d6bbe4b7ab37aaa07d081e4a742afaf1d41 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 21:44:01 +0300 Subject: [PATCH 22/25] version: 2.0.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d8f27e3..1561a22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "node.js-chatgpt-bot", - "version": "1.1.5", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "node.js-chatgpt-bot", - "version": "1.1.5", + "version": "2.0.0", "license": "MIT License", "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", diff --git a/package.json b/package.json index 6b37797..3686cb7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node.js-chatgpt-bot", - "version": "1.1.5", + "version": "2.0.0", "description": "СhatGPT bot for telegram written on node.js", "main": "index.js", "type": "module", From e647f4e9e4940a11a5ef66b639b2e960be62c5b0 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 21:56:24 +0300 Subject: [PATCH 23/25] chore: add command for building --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f6503cc..dea3001 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,4 +14,4 @@ ENV PORT=3000 EXPOSE $PORT -CMD sh -c "redis-server --daemonize yes && npm start" \ No newline at end of file +CMD sh -c "redis-server --daemonize yes && npm run build && npm start" \ No newline at end of file From 51c1b198e52c17bf29a6127590f5ebfcfe07e517 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 21:58:27 +0300 Subject: [PATCH 24/25] docs: add `REDIS_URL` --- config/config.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/config.md b/config/config.md index afd89c9..3342260 100644 --- a/config/config.md +++ b/config/config.md @@ -8,8 +8,7 @@ First file `default.json` with code: "OPENAI_KEY": "OpenAI Key", "USERS_ID": "User IDs separated by commas without spaces", "SUPER_USER": "ID", - "REDIS_HOST": "127.0.0.1", - "REDIS_PORT": "6379", + "REDIS_URL": "redis://127.0.0.1:6379/1", "PROXY_URL": "http://user:password@host:port" } ``` @@ -22,8 +21,7 @@ Second file `production.json` with code: "OPENAI_KEY": "OpenAI Key", "USERS_ID": "User IDs separated by commas without spaces", "SUPER_USER": "ID", - "REDIS_HOST": "127.0.0.1", - "REDIS_PORT": "6379", + "REDIS_URL": "redis://127.0.0.1:6379/1", "PROXY_URL": "http://user:password@host:port" } ``` @@ -34,3 +32,5 @@ Telegram token you can get in [BotFather](https://t.me/BotFather) Secret API key from openai you can get in [API keys](https://platform.openai.com/account/api-keys) +Redis `redis[s]://[[username][:password]@][host][:port][/db-number]` + From c875210fbe0ab6c253287f243022a30aa3cd0ffb Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Thu, 18 Jan 2024 21:58:51 +0300 Subject: [PATCH 25/25] version: 2.0.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1561a22..dee985e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "node.js-chatgpt-bot", - "version": "2.0.0", + "version": "2.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "node.js-chatgpt-bot", - "version": "2.0.0", + "version": "2.0.1", "license": "MIT License", "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", diff --git a/package.json b/package.json index 3686cb7..0c35686 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node.js-chatgpt-bot", - "version": "2.0.0", + "version": "2.0.1", "description": "СhatGPT bot for telegram written on node.js", "main": "index.js", "type": "module",