diff --git a/.env_example b/.env_example new file mode 100644 index 0000000..5b8a8a4 --- /dev/null +++ b/.env_example @@ -0,0 +1,3 @@ +BOT_TOKEN=your_bot_token +DB_PASSWORD=your_db_password +DB_USER=your_db_user \ No newline at end of file diff --git a/.gitignore b/.gitignore index fe299f5..9cc5c86 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,7 @@ idea/ dist /src/resources/sql/database.db -.env.development \ No newline at end of file +.env.development + +oggFiles +.env \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a34b7d0..2b15a29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,53 +1,94 @@ { - "name": "TelegramMemeSoundBot", + "name": "TGSoundBot", "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "TelegramMemeSoundBot", + "name": "TGSoundBot", "version": "2.0.0", "dependencies": { - "@types/node": "^18.16.1", + "@types/node": "^20.16.5", "audio-converter": "1.0.13", + "dotenv": "^16.4.5", "js-logger": "~1.6.1", - "node-telegram-bot-api": "^0.61.0", - "sqlite": "^5.0.1", - "sqlite3": "^5.1.6", - "typescript": "~5.1.6", - "uuid": "~9.0.0" + "node-cache": "~5.1.2", + "node-telegram-bot-api": "^0.66.0", + "pg": "^8.13.0", + "sqlite": "^5.1.1", + "sqlite3": "^5.1.7", + "typescript": "~5.6.2", + "uuid": "~10.0.0" }, "devDependencies": { - "@types/node-telegram-bot-api": "^0.61.6", + "@types/node-telegram-bot-api": "^0.64.7", + "@types/pg": "^8.11.10", "audio-converter": "1.0.13", - "prettier": "~3.0.0" + "prettier": "~3.3.3" } }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "optional": true + "node_modules/@cypress/request": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.5.tgz", + "integrity": "sha512-v+XHd9XmWbufxF1/bTaVm2yhbxY+TB4YtWRqF2zaXBlDNMkls34KiATz0AVDLavL3iB6bQk9/7n3oY1EoLSWGA==", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~4.0.0", + "http-signature": "~1.4.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "6.13.0", + "safe-buffer": "^5.1.2", + "tough-cookie": "^4.1.3", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "node_modules/@cypress/request-promise": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@cypress/request-promise/-/request-promise-5.0.0.tgz", + "integrity": "sha512-eKdYVpa9cBEw2kTBlHeu1PP16Blwtum6QHg/u9s/MoHkZfuo1pRGka1VlUHXF5kdew82BvOJVVGk0x8X0nbp+w==", + "license": "ISC", "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" + "bluebird": "^3.5.0", + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^4.1.3" + }, + "engines": { + "node": ">=0.10.0" }, + "peerDependencies": { + "@cypress/request": "^3.0.0" + } + }, + "node_modules/@cypress/request/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { - "node-pre-gyp": "bin/node-pre-gyp" + "uuid": "dist/bin/uuid" } }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "optional": true + }, "node_modules/@npmcli/fs": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", @@ -99,17 +140,97 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "18.16.19", - "license": "MIT" + "version": "20.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", + "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } }, "node_modules/@types/node-telegram-bot-api": { - "version": "0.61.6", + "version": "0.64.7", + "resolved": "https://registry.npmjs.org/@types/node-telegram-bot-api/-/node-telegram-bot-api-0.64.7.tgz", + "integrity": "sha512-nuvFFXnvU2sItucyEJ03I+m34z5st386isfEuF6BJTL7p3RjG7naMhvvXjY7oeKahTm1Jf0Gu4PrDa6jDt78/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/request": "*" + } + }, + "node_modules/@types/pg": { + "version": "8.11.10", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.10.tgz", + "integrity": "sha512-LczQUW4dbOQzsH2RQ5qoeJ6qJPdrcM/DcMLoqWQkMLMsq83J5lAX3LXjdkWdpscFy67JSOWDnh7Ny/sPFykmkg==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", - "@types/request": "*", - "eventemitter3": ">=3.0.0" + "pg-protocol": "*", + "pg-types": "^4.0.1" + } + }, + "node_modules/@types/pg/node_modules/pg-types": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz", + "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==", + "dev": true, + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.1.0", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/pg/node_modules/postgres-array": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/pg/node_modules/postgres-bytea": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "obuf": "~1.1.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/pg/node_modules/postgres-date": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz", + "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/pg/node_modules/postgres-interval": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" } }, "node_modules/@types/request": { @@ -144,12 +265,14 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, "dependencies": { "debug": "4" }, @@ -161,6 +284,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, "dependencies": { "ms": "2.1.2" }, @@ -176,7 +300,8 @@ "node_modules/agent-base/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==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true }, "node_modules/agentkeepalive": { "version": "4.3.0", @@ -230,7 +355,10 @@ }, "node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -246,6 +374,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "optional": true, "engines": { "node": ">=8" } @@ -253,32 +382,8 @@ "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true }, "node_modules/array.prototype.findindex": { "version": "2.2.1", @@ -292,6 +397,8 @@ }, "node_modules/asn1": { "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "license": "MIT", "dependencies": { "safer-buffer": "~2.1.0" @@ -299,6 +406,8 @@ }, "node_modules/assert-plus": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "license": "MIT", "engines": { "node": ">=0.8" @@ -327,26 +436,62 @@ }, "node_modules/aws-sign2": { "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "license": "Apache-2.0", "engines": { "node": "*" } }, "node_modules/aws4": { - "version": "1.11.0", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", "license": "MIT" }, "node_modules/balanced-match": { "version": "1.0.2", + "devOptional": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT" }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "license": "BSD-3-Clause", "dependencies": { "tweetnacl": "^0.14.3" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/bl": { "version": "1.2.3", "license": "MIT", @@ -357,16 +502,43 @@ }, "node_modules/bluebird": { "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", + "devOptional": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/cacache": { "version": "15.3.0", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", @@ -429,11 +601,19 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -441,6 +621,8 @@ }, "node_modules/caseless": { "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "license": "Apache-2.0" }, "node_modules/charm": { @@ -465,10 +647,19 @@ "node": ">=6" } }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true, "bin": { "color-support": "bin.js" } @@ -490,12 +681,14 @@ }, "node_modules/concat-map": { "version": "0.0.1", + "devOptional": true, "license": "MIT" }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true }, "node_modules/core-util-is": { "version": "1.0.3", @@ -503,6 +696,8 @@ }, "node_modules/dashdash": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "license": "MIT", "dependencies": { "assert-plus": "^1.0.0" @@ -518,6 +713,47 @@ "ms": "^2.1.1" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-properties": { "version": "1.1.4", "license": "MIT", @@ -542,7 +778,8 @@ "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true }, "node_modules/depd": { "version": "2.0.0", @@ -554,15 +791,30 @@ } }, "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", "engines": { "node": ">=8" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/ecc-jsbn": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "license": "MIT", "dependencies": { "jsbn": "~0.1.0", @@ -572,7 +824,8 @@ "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==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "optional": true }, "node_modules/encoding": { "version": "0.1.13", @@ -641,6 +894,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-shim-unscopables": { "version": "1.0.0", "license": "MIT", @@ -667,12 +941,25 @@ "version": "3.1.2", "license": "MIT" }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, "node_modules/extend": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, "node_modules/extsprintf": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "engines": [ "node >=0.6.0" ], @@ -680,11 +967,17 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT", + "peer": true }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT", + "peer": true }, "node_modules/file-type": { "version": "3.9.0", @@ -693,25 +986,41 @@ "node": ">=0.10.0" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, "node_modules/forever-agent": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "license": "Apache-2.0", "engines": { "node": "*" } }, "node_modules/form-data": { - "version": "2.3.3", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.12" + "node": ">= 6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -726,11 +1035,17 @@ "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==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "optional": true }, "node_modules/function-bind": { - "version": "1.1.1", - "license": "MIT" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.5", @@ -755,32 +1070,20 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/get-intrinsic": { - "version": "1.1.3", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -802,11 +1105,19 @@ }, "node_modules/getpass": { "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "license": "MIT", "dependencies": { "assert-plus": "^1.0.0" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, "node_modules/glob": { "version": "5.0.15", "dev": true, @@ -822,6 +1133,18 @@ "node": "*" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -830,14 +1153,21 @@ }, "node_modules/har-schema": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "license": "ISC", + "peer": true, "engines": { "node": ">=4" } }, "node_modules/har-validator": { "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", "license": "MIT", + "peer": true, "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -864,10 +1194,24 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -899,7 +1243,20 @@ "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/http-cache-semantics": { "version": "4.1.1", @@ -945,22 +1302,24 @@ "optional": true }, "node_modules/http-signature": { - "version": "1.2.0", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", + "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", "license": "MIT", "dependencies": { "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "jsprim": "^2.0.2", + "sshpk": "^1.18.0" }, "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "node": ">=0.10" } }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -973,6 +1332,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, "dependencies": { "ms": "2.1.2" }, @@ -988,7 +1348,8 @@ "node_modules/https-proxy-agent/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==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true }, "node_modules/humanize-ms": { "version": "1.2.1", @@ -1011,6 +1372,26 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -1037,6 +1418,7 @@ }, "node_modules/inflight": { "version": "1.0.6", + "devOptional": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -1047,6 +1429,12 @@ "version": "2.0.4", "license": "ISC" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, "node_modules/internal-slot": { "version": "1.0.3", "license": "MIT", @@ -1116,6 +1504,7 @@ "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==", + "optional": true, "engines": { "node": ">=8" } @@ -1201,6 +1590,8 @@ }, "node_modules/is-typedarray": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "license": "MIT" }, "node_modules/is-weakref": { @@ -1225,6 +1616,8 @@ }, "node_modules/isstream": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "license": "MIT" }, "node_modules/js-logger": { @@ -1233,35 +1626,48 @@ }, "node_modules/jsbn": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "license": "MIT" }, "node_modules/json-schema": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT", + "peer": true }, "node_modules/json-stringify-safe": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "license": "ISC" }, "node_modules/jsprim": { - "version": "1.4.2", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "engines": [ + "node >=0.6.0" + ], "license": "MIT", "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.4.0", "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" } }, "node_modules/lodash": { "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, "node_modules/lodash.chunk": { @@ -1285,28 +1691,6 @@ "node": ">=10" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/make-fetch-happen": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", @@ -1361,8 +1745,21 @@ "node": ">= 0.6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", + "devOptional": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -1373,7 +1770,6 @@ }, "node_modules/minimist": { "version": "1.2.7", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1478,10 +1874,22 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "license": "MIT" }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "license": "MIT" + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -1491,28 +1899,33 @@ "node": ">= 0.6" } }, + "node_modules/node-abi": { + "version": "3.67.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz", + "integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT" }, - "node_modules/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "node_modules/node-cache": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", + "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", "dependencies": { - "whatwg-url": "^5.0.0" + "clone": "2.x" }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "node": ">= 8.0.0" } }, "node_modules/node-gyp": { @@ -1621,18 +2034,20 @@ } }, "node_modules/node-telegram-bot-api": { - "version": "0.61.0", + "version": "0.66.0", + "resolved": "https://registry.npmjs.org/node-telegram-bot-api/-/node-telegram-bot-api-0.66.0.tgz", + "integrity": "sha512-s4Hrg5q+VPl4/tJVG++pImxF6eb8tNJNj4KnDqAOKL6zGU34lo9RXmyAN158njwGN+v8hdNf8s9fWIYW9hPb5A==", "license": "MIT", "dependencies": { + "@cypress/request": "^3.0.1", + "@cypress/request-promise": "^5.0.0", "array.prototype.findindex": "^2.0.2", "bl": "^1.2.3", "debug": "^3.2.7", "eventemitter3": "^3.0.0", "file-type": "^3.9.0", "mime": "^1.6.0", - "pump": "^2.0.0", - "request": "^2.83.0", - "request-promise": "^4.2.2" + "pump": "^2.0.0" }, "engines": { "node": ">=0.12" @@ -1642,6 +2057,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, "dependencies": { "abbrev": "1" }, @@ -1652,35 +2068,24 @@ "node": ">=6" } }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, "node_modules/oauth-sign": { "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "license": "Apache-2.0", + "peer": true, "engines": { "node": "*" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { - "version": "1.12.2", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1708,6 +2113,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true, + "license": "MIT" + }, "node_modules/once": { "version": "1.4.0", "license": "ISC", @@ -1742,6 +2154,7 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -1749,10 +2162,195 @@ }, "node_modules/performance-now": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT" + }, + "node_modules/pg": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.13.0.tgz", + "integrity": "sha512-34wkUTh3SxTClfoHB3pQ7bIMvw9dpFU1audQQeZG837fmHfHpr14n/AELVDoOYVDW2h5RDWU78tFjkD+erSBsw==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.7.0", + "pg-pool": "^3.7.0", + "pg-protocol": "^1.7.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz", + "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-numeric": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/pg-pool": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.7.0.tgz", + "integrity": "sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.7.0.tgz", + "integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-range": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz", + "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==", + "dev": true, "license": "MIT" }, + "node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/prettier": { - "version": "3.0.0", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "license": "MIT", "bin": { @@ -1790,6 +2388,8 @@ }, "node_modules/psl": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "license": "MIT" }, "node_modules/pump": { @@ -1801,7 +2401,9 @@ } }, "node_modules/punycode": { - "version": "2.1.1", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "license": "MIT", "engines": { "node": ">=6" @@ -1817,10 +2419,39 @@ } }, "node_modules/qs": { - "version": "6.5.3", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, "engines": { "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" } }, "node_modules/readable-stream": { @@ -1857,7 +2488,11 @@ }, "node_modules/request": { "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "license": "Apache-2.0", + "peer": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -1884,14 +2519,13 @@ "node": ">= 6" } }, - "node_modules/request-promise": { - "version": "4.2.6", + "node_modules/request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", "license": "ISC", "dependencies": { - "bluebird": "^3.5.0", - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" + "lodash": "^4.17.15" }, "engines": { "node": ">=0.10.0" @@ -1900,17 +2534,75 @@ "request": "^2.34" } }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "license": "ISC", + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "license": "MIT", + "peer": true, "dependencies": { - "lodash": "^4.17.19" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" }, - "peerDependencies": { - "request": "^2.34" + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/request/node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "license": "MIT", + "peer": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" } }, "node_modules/request/node_modules/uuid": { @@ -1918,10 +2610,18 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "peer": true, "bin": { "uuid": "bin/uuid" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", @@ -1935,6 +2635,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "optional": true, "dependencies": { "glob": "^7.1.3" }, @@ -1949,6 +2650,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "optional": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2015,15 +2717,39 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "optional": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/side-channel": { - "version": "1.0.4", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2032,7 +2758,53 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "optional": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } }, "node_modules/smart-buffer": { "version": "4.2.0", @@ -2095,18 +2867,31 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "optional": true }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/sqlite": { - "version": "5.0.1", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/sqlite/-/sqlite-5.1.1.tgz", + "integrity": "sha512-oBkezXa2hnkfuJwUo44Hl9hS3er+YFtueifoajrgidvqsJRQFpc5fKoAkAor1O5ZnLoa28GBScfHXs8j0K358Q==", "license": "MIT" }, "node_modules/sqlite3": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz", - "integrity": "sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz", + "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==", "hasInstallScript": true, + "license": "BSD-3-Clause", "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.0", - "node-addon-api": "^4.2.0", + "bindings": "^1.5.0", + "node-addon-api": "^7.0.0", + "prebuild-install": "^7.1.1", "tar": "^6.1.11" }, "optionalDependencies": { @@ -2122,7 +2907,9 @@ } }, "node_modules/sshpk": { - "version": "1.17.0", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", "license": "MIT", "dependencies": { "asn1": "~0.2.3", @@ -2158,6 +2945,8 @@ }, "node_modules/stealthy-require": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", "license": "ISC", "engines": { "node": ">=0.10.0" @@ -2178,6 +2967,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "optional": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2215,6 +3005,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2222,6 +3013,15 @@ "node": ">=8" } }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/tar": { "version": "6.1.15", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", @@ -2238,6 +3038,75 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/tar-fs/node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/tar/node_modules/minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -2258,23 +3127,24 @@ } }, "node_modules/tough-cookie": { - "version": "2.5.0", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "license": "BSD-3-Clause", "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" }, "engines": { - "node": ">=0.8" + "node": ">=6" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "node_modules/tunnel-agent": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -2285,10 +3155,14 @@ }, "node_modules/tweetnacl": { "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "license": "Unlicense" }, "node_modules/typescript": { - "version": "5.1.6", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -2311,6 +3185,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, "node_modules/unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", @@ -2329,27 +3209,56 @@ "imurmurhash": "^0.1.4" } }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "license": "BSD-2-Clause", + "peer": true, "dependencies": { "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "license": "MIT" }, "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/verror": { "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "engines": [ "node >=0.6.0" ], @@ -2362,22 +3271,10 @@ }, "node_modules/verror/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==", "license": "MIT" }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2411,6 +3308,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } @@ -2419,6 +3317,15 @@ "version": "1.0.2", "license": "ISC" }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index adfcc55..86bc110 100644 --- a/package.json +++ b/package.json @@ -10,18 +10,22 @@ "dev": "tsc && node dist/index.js" }, "dependencies": { - "@types/node": "^18.16.1", + "@types/node": "^20.16.5", "audio-converter": "1.0.13", "js-logger": "~1.6.1", - "node-telegram-bot-api": "^0.61.0", - "sqlite": "^5.0.1", - "sqlite3": "^5.1.6", - "typescript": "~5.1.6", - "uuid": "~9.0.0" + "node-telegram-bot-api": "^0.66.0", + "node-cache": "~5.1.2", + "sqlite": "^5.1.1", + "sqlite3": "^5.1.7", + "pg": "^8.13.0", + "typescript": "~5.6.2", + "dotenv": "^16.4.5", + "uuid": "~10.0.0" }, "devDependencies": { - "@types/node-telegram-bot-api": "^0.61.6", + "@types/node-telegram-bot-api": "^0.64.7", + "@types/pg": "^8.11.10", "audio-converter": "1.0.13", - "prettier": "~3.0.0" + "prettier": "~3.3.3" } } diff --git a/src/bot.ts b/src/bot.ts index 2b65bc9..17f3b36 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -1,5 +1,5 @@ import { MessageListener } from './eventListeners/messageListener'; -import { InlineQuery, Message, Metadata, User } from 'node-telegram-bot-api'; +import { CallbackQuery, ChosenInlineResult, InlineQuery, Message, Metadata, User } from 'node-telegram-bot-api'; import { InlineListener } from './eventListeners/inlineListener'; import { ILogger } from 'js-logger'; import { createLogger } from './utils/logger/logger'; @@ -7,31 +7,44 @@ import { BotConfig } from './config/BotConfig'; import { DataBase } from './config/database/DataBase'; import TelegramBot = require('node-telegram-bot-api'); import { ExtendedMessage } from './utils/types/type'; +import { CallbackQueryListener } from './eventListeners/callbackQueryListener'; +import * as NodeCache from 'node-cache'; +import {FileWriter} from "./utils/FileWriter"; export class Bot { private readonly logger: ILogger = createLogger('Bot'); private readonly db: DataBase; private readonly bot: TelegramBot; private readonly config: BotConfig; + private readonly fileWriter: FileWriter; + private readonly voiceCache = new NodeCache({ + checkperiod: 600 + }); private botId?: number; private inlineHandler: InlineListener; private messageHandler: MessageListener; + private callbackHandler: CallbackQueryListener; - constructor(token: string, config: BotConfig, db: DataBase) { + constructor(token: string, config: BotConfig, db: DataBase, fileWriter: FileWriter) { this.bot = new TelegramBot(token, { polling: true }); this.config = config; this.db = db; + this.fileWriter = fileWriter this.messageHandler = new MessageListener(this); this.inlineHandler = new InlineListener(this); + this.callbackHandler = new CallbackQueryListener(this); this.setupListeners(); - this.bot.getMe().then((user: User) => { - this.botId = user.id; - }).catch(err => { - this.logger.error(err); - throw new Error('Не удалось получить информацию о боте'); - }); + this.bot + .getMe() + .then((user: User) => { + this.botId = user.id; + }) + .catch((err) => { + this.logger.error(err); + throw new Error('Не удалось получить информацию о боте'); + }); } getBot(): TelegramBot { @@ -50,6 +63,14 @@ export class Bot { return this.botId; } + getVoiceCache(): NodeCache { + return this.voiceCache; + } + + getFileWriter(): FileWriter { + return this.fileWriter; + } + private setupListeners() { let handlerCount = 0; this.bot.on('message', (message: Message, metadata: Metadata) => { @@ -62,6 +83,10 @@ export class Bot { }); handlerCount++; + this.bot.on('callback_query', async (ctx: CallbackQuery) => { + await this.callbackHandler.handleMessage(ctx); + }); + this.logger.info(`Загружено ${handlerCount} обработчика событий`); } } diff --git a/src/config/BotConfig.ts b/src/config/BotConfig.ts index a25ea97..2cd0105 100644 --- a/src/config/BotConfig.ts +++ b/src/config/BotConfig.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import { Config } from '../utils/types/config'; +import { Config, DataBaseType } from '../utils/types/config'; import { promises as fsPromises } from 'fs'; import { ILogger } from 'js-logger'; import { createLogger } from '../utils/logger/logger'; @@ -12,12 +12,20 @@ export class BotConfig { initialize(): Promise { return new Promise((resolve, reject): void => { - fsPromises.readFile(this.configFilepath, { encoding: 'utf-8' }) + fsPromises + .readFile(this.configFilepath, { encoding: 'utf-8' }) .then((fileStr: string) => { this.config = JSON.parse(fileStr); + let dbUser = process.env.DB_USER; + let dbPassword = process.env.DB_PASSWORD; + + if (this.config?.database.type == DataBaseType.POSTGRESQL && dbUser && dbPassword) { + this.config.database.user = dbUser; + this.config.database.password = dbPassword; + } resolve(); }) - .catch(err => { + .catch((err) => { this.logger.error('Ошибка чтения файла конфигурации', err); reject(err); }); diff --git a/src/config/database/DataBase.ts b/src/config/database/DataBase.ts index 8b8a5a7..00b949b 100644 --- a/src/config/database/DataBase.ts +++ b/src/config/database/DataBase.ts @@ -18,11 +18,11 @@ export abstract class DataBase implements IDatabase { abstract queryInsert(sql: string, params?: any[]): Promise; - abstract getAllVoices(botId: number | undefined): Promise; + abstract getAllVoices(botId: number | undefined, isHidden: boolean, limit: number, offset: number): Promise; abstract getVoiceById(id: number): Promise; - abstract getVoiceByTitleInclude(title: string, botId: number | undefined): Promise; + abstract getVoiceByTitleInclude(title: string, botId: number | undefined, isHidden: boolean, limit: number, offset: number): Promise; abstract createTable(): Promise; diff --git a/src/config/database/PostgreSQL.ts b/src/config/database/PostgreSQL.ts new file mode 100644 index 0000000..0f15526 --- /dev/null +++ b/src/config/database/PostgreSQL.ts @@ -0,0 +1,214 @@ +import * as path from 'path'; +import { Client, QueryResultRow } from 'pg'; +import { DataBase } from './DataBase'; +import { BotConfig } from '../BotConfig'; +import { CustomVoice } from '../../utils/types/type'; +import { promises as fsPromises } from 'fs'; + +const Logger = require('js-logger'); + +export class PostgreSQL extends DataBase { + private readonly db: Client; + private readonly sqlConfigFilepath: string = path.resolve('src/resources/sql/'); + + constructor(config: BotConfig) { + super(); + + const dbConfig = config.getConfig()?.database; + + this.db = new Client({ + user: dbConfig?.user, + host: dbConfig?.host, + database: dbConfig?.databaseName, + password: dbConfig?.password, + port: dbConfig?.port + }); + + this.db.query(`SET search_path TO ${dbConfig?.schema}`, (err: Error) => { + if (err) { + this.logger(Logger.ERROR, 'Ошибка установки схемы', err); + } + }); + + this.db.connect((err: Error) => { + if (err) { + this.logger(Logger.ERROR, 'Ошибка подключения к базе данных PostgreSQL', err); + } else { + this.logger(Logger.INFO, 'База данных PostgreSQL - подключена'); + } + }); + } + + async createTable(): Promise { + let createTableSQL: string; + + await fsPromises + .readFile(`${this.sqlConfigFilepath}/initPostgreSQL.sql`, { encoding: 'utf-8' }) + .then((fileStr: string) => { + createTableSQL = fileStr; + }) + .catch((err) => this.logger(Logger.ERROR, 'Ошибка чтения файла конфигурации', err)); + + return new Promise((resolve, reject) => { + this.queryExecute(createTableSQL) + .then(() => { + this.logger(Logger.INFO, 'Таблица создана'); + resolve(); + }) + .catch((err) => reject(err)); + }); + } + + async saveVoice(voice: CustomVoice): Promise { + return new Promise((resolve, reject) => { + const voiceName: string = voice.title; + const voicePath: string = voice.voice_url; + const botId: number = voice.botId; + const isHidden: number = Number(voice.isHidden); + this.queryInsert( + `INSERT INTO audio_inline (inline_type, title, voice_url, bot_id, is_hidden) + VALUES ('voice', '${voiceName}', '${voicePath}', '${botId}', '${isHidden}')` + ) + .then(() => resolve()) + .catch((err) => reject(err)); + }); + } + + async getAllVoices( + botId: number | undefined, + isHidden: boolean, + limit: number, + offset: number + ): Promise { + return new Promise((resolve, reject) => { + this.queryAll( + `SELECT id, + inline_type AS inlineType, + title, + voice_url, + bot_id AS botId, + is_hidden AS isHidden + FROM audio_inline + WHERE bot_id = $1 AND is_hidden = 0 OR (is_hidden = 1 AND is_hidden = $2) + ORDER BY title + LIMIT $3 OFFSET $4`, + [botId, Number(isHidden), limit, offset] + ) + .then((rows) => resolve(rows)) + .catch((err) => reject(err)); + }); + } + + async getVoiceById(id: number): Promise { + return new Promise((resolve, reject) => { + this.queryGet( + `SELECT id, + inline_type AS inlineType, + title, + voice_url, + bot_id AS botId, + is_hidden AS isHidden + FROM audio_inline + WHERE id = $1 + LIMIT (1)`, + [id] + ) + .then((rows: CustomVoice[]) => resolve(rows[0])) + .catch((err) => reject(err)); + }); + } + + async getVoiceByTitleInclude( + title: string, + botId: number | undefined, + isHidden: boolean, + limit: number, + offset: number + ): Promise { + return new Promise((resolve, reject) => { + this.queryAll( + `SELECT id, + inline_type AS inlineType, + title, + voice_url, + bot_id AS botId, + is_hidden AS isHidden + FROM audio_inline + WHERE title LIKE $1 AND bot_id = $2 AND is_hidden = 0 + OR (is_hidden = 1 AND is_hidden = $3) + ORDER BY title + LIMIT $4 OFFSET $5`, + [`%${title}%`, botId, Number(isHidden), limit, offset] + ) + .then((rows: CustomVoice[]) => resolve(rows)) + .catch((err) => reject(err)); + }); + } + + async queryExecute(sql: string, params: any[] = []): Promise { + return new Promise((resolve, reject) => { + this.db.query(sql, params, (err: Error) => { + if (err) { + this.logger(Logger.ERROR, 'Ошибка выполнения запроса', err); + reject(err); + } else { + resolve([]); + } + }); + }); + } + + async queryAll(sql: string, params: any[] = []): Promise { + return new Promise((resolve, reject) => { + this.db.query(sql, params, (err: Error, result: QueryResultRow) => { + if (err) { + this.logger(Logger.ERROR, 'Ошибка выполнения запроса', err); + reject(err); + } else { + resolve(result.rows.map((row: T) => row as T)); + } + }); + }); + } + + // useless. like queryAll; + async queryGet(sql: string, params: any[] = []): Promise { + return new Promise((resolve, reject) => { + this.db.query(sql, params, (err: Error, result: QueryResultRow) => { + if (err) { + this.logger(Logger.ERROR, 'Ошибка выполнения запроса', err); + reject(err); + } else { + resolve(result.rows.map((row: T) => row as T)); + } + }); + }); + } + + async queryInsert(sql: string, params: any[] = []): Promise { + return new Promise((resolve, reject) => { + this.db.query(sql, params, (err: Error) => { + if (err) { + this.logger(Logger.ERROR, 'Ошибка выполнения запроса', err); + reject(err); + } else { + resolve(); + } + }); + }); + } + + async disconnect(): Promise { + return new Promise((resolve, reject) => { + this.db.end((err: Error | null) => { + if (err) { + this.logger(Logger.ERROR, 'Ошибка закрытия соединения с базой данных', err); + reject(err); + } else { + this.logger(Logger.INFO, 'Соединение с базой данных закрыто'); + resolve(); + } + }); + }); + } +} diff --git a/src/config/database/SQLite.ts b/src/config/database/SQLite.ts index c45131c..f332928 100644 --- a/src/config/database/SQLite.ts +++ b/src/config/database/SQLite.ts @@ -32,7 +32,7 @@ export class SQLite extends DataBase { async createTable(): Promise { let createTableSQL: string; - await fsPromises.readFile(`${this.sqlConfigFilepath}/init.sql`, { encoding: 'utf-8' }) + await fsPromises.readFile(`${this.sqlConfigFilepath}/initSQLite.sql`, { encoding: 'utf-8' }) .then((fileStr: string) => { createTableSQL = fileStr; }) @@ -51,19 +51,24 @@ export class SQLite extends DataBase { const voiceName: string = voice.title; const voicePath: string = voice.voice_url; const botId: number = voice.botId; - this.queryInsert(`INSERT INTO audio_inline (inline_type, title, voice_url, bot_id) - VALUES ('voice', '${voiceName}', '${voicePath}', '${botId}')`) + const isHidden: number = Number(voice.isHidden); + this.queryInsert(`INSERT INTO audio_inline (inline_type, title, voice_url, bot_id, is_hidden) + VALUES ('voice', '${voiceName}', '${voicePath}', '${botId}', '${isHidden}')`) .then(() => resolve()) .catch(err => reject(err)); }); } - async getAllVoices(botId: number | undefined): Promise { + async getAllVoices(botId: number | undefined, isHidden: boolean, limit: number, offset: number): Promise { return new Promise((resolve, reject) => { - this.queryAll(`SELECT * + this.queryAll(`SELECT id, inline_type AS inlineType, title, voice_url, bot_id AS botId, is_hidden AS isHidden FROM audio_inline WHERE bot_id = ? - ORDER BY title ASC`, [botId]) + AND is_hidden = 0 + OR (is_hidden = 1 AND is_hidden = ?) + ORDER BY title ASC + LIMIT ? + OFFSET ?`, [botId, Number(isHidden), limit, offset]) .then((rows) => resolve(rows)) .catch(err => reject(err)); }); @@ -71,7 +76,7 @@ export class SQLite extends DataBase { async getVoiceById(id: number): Promise { return new Promise((resolve, reject) => { - this.queryGet(`SELECT * + this.queryGet(`SELECT id, inline_type AS inlineType, title, voice_url, bot_id AS botId, is_hidden AS isHidden FROM audio_inline WHERE id = ? LIMIT (1)`, [id]) @@ -80,13 +85,16 @@ export class SQLite extends DataBase { }); } - async getVoiceByTitleInclude(title: string, botId: number | undefined): Promise { + async getVoiceByTitleInclude(title: string, botId: number | undefined, isHidden: boolean, limit: number, offset: number): Promise { return new Promise((resolve, reject) => { - this.queryAll(`SELECT * + this.queryAll(`SELECT id, inline_type AS inlineType, title, voice_url, bot_id AS botId, is_hidden AS isHidden FROM audio_inline WHERE title LIKE ? AND bot_id = ? - ORDER BY title ASC`, [`%${title}%`, botId]) + AND is_hidden = 0 OR (is_hidden = 1 AND is_hidden = ?) + ORDER BY title ASC + LIMIT ? + OFFSET ?`, [`%${title}%`, botId, Number(isHidden), limit, offset]) .then((rows: CustomVoice[]) => resolve(rows)) .catch(err => reject(err)); }); diff --git a/src/eventListeners/callbackQueryListener.ts b/src/eventListeners/callbackQueryListener.ts new file mode 100644 index 0000000..0167976 --- /dev/null +++ b/src/eventListeners/callbackQueryListener.ts @@ -0,0 +1,149 @@ +// Вспомогательный класс для обработки inline запросов +import { CallbackQuery } from 'node-telegram-bot-api'; +import { Bot } from '../bot'; +import { ILogger } from 'js-logger'; +import { createLogger } from '../utils/logger/logger'; +import { DataBase } from '../config/database/DataBase'; +import { CacheInfo, CallbackQueryInlineButtonType, CustomVoice } from '../utils/types/type'; +import * as NodeCache from 'node-cache'; +import { getReplayInlineKeyboard } from '../utils/inline/inlineKeyboard'; +import TelegramBot = require('node-telegram-bot-api'); + +export class CallbackQueryListener { + private readonly logger: ILogger = createLogger('CallbackQueryListener'); + private readonly bot: TelegramBot; + private readonly botInstance: Bot; + private readonly db: DataBase; + private readonly voiceCache: NodeCache; + + constructor(botInstance: Bot) { + this.bot = botInstance.getBot(); + this.botInstance = botInstance; + this.db = botInstance.getDB(); + this.voiceCache = botInstance.getVoiceCache(); + } + + public async handleMessage(ctx: CallbackQuery): Promise { + if (ctx.message?.chat === undefined) { + return; + } + + const callbackQueryInlineButtonType = ctx.data as CallbackQueryInlineButtonType; + const allCache = this.voiceCache.get(ctx.message.chat.id); + if (allCache === undefined) { + this.logger.error('Кэш не найден'); + return; + } + + const messageIdQuery = ctx.message.message_id; + const cache = allCache.find((cacheInfo: CacheInfo) => { + return cacheInfo.messageId === messageIdQuery - 1; + }); + + if (cache === undefined || cache.customVoice === undefined) { + this.logger.error('Не найдено голосовое сообщение в кэше'); + return; + } + + if (callbackQueryInlineButtonType === CallbackQueryInlineButtonType.SAVE) { + this.saveVoice(cache.customVoice) + .then(() => { + this.sendCompleteMessage(ctx, messageIdQuery); + if (ctx.message?.chat !== undefined) { + this.removeFromCache(ctx, messageIdQuery, ctx.message.chat.id); + } + this.botInstance.getFileWriter().deleteFile(cache.savedSoundFile) + }) + .catch((err) => { + this.logger.error('Ошибка при сохранении голосового сообщения', err); + }); + } else if (callbackQueryInlineButtonType === CallbackQueryInlineButtonType.CANCEL) { + this.sendCancelMessage(ctx, messageIdQuery); + if (ctx.message?.chat !== undefined) { + this.removeFromCache(ctx, messageIdQuery, ctx.message.chat.id); + } + } else if (callbackQueryInlineButtonType === CallbackQueryInlineButtonType.SWITCH_HIDDEN) { + const customVoice: CustomVoice = { ...cache.customVoice, isHidden: !cache.customVoice.isHidden }; + this.updateCacheCustomVoice(customVoice, ctx, messageIdQuery, ctx.message.chat.id); + this.updateInlineKeyboard(customVoice, ctx); + } + } + + private updateInlineKeyboard(customVoice: CustomVoice, ctx: CallbackQuery) { + + this.bot.editMessageReplyMarkup(getReplayInlineKeyboard(customVoice), { + chat_id: ctx.message?.chat.id, + message_id: ctx.message?.message_id + }).catch((err) => { + this.logger.error('Ошибка при отправке результата обработки сообщения', err); + }); + } + + private removeFromCache(ctx: CallbackQuery, messageIdQuery: number, chatId: number) { + if (ctx.message?.chat === undefined) { + this.logger.error('Не найдено голосовое сообщение в кэше'); + return; + } + + const cache = this.voiceCache.get(ctx.message.chat.id)?.filter((cacheInfo: CacheInfo) => cacheInfo.messageId !== messageIdQuery - 1); + + if (cache === undefined) { + this.logger.error('Не найдено голосовое сообщение в кэше'); + return; + } + + this.voiceCache.set(chatId, cache); + } + + private updateCacheCustomVoice(customVoice: CustomVoice, ctx: CallbackQuery, messageIdQuery: number, chatId: number) { + if (ctx.message?.chat === undefined) { + this.logger.error('Не найдено голосовое сообщение в кэше'); + return; + } + + const cache = this.voiceCache.get(ctx.message.chat.id)?.map((cacheInfo: CacheInfo) => { + if (cacheInfo.messageId == messageIdQuery - 1) { + return { ...cacheInfo, customVoice }; + } + return cacheInfo; + }); + + if (cache === undefined) { + this.logger.error('Не найдено голосовое сообщение в кэше'); + return; + } + + this.voiceCache.set(chatId, cache); + } + + private sendCompleteMessage(ctx: CallbackQuery, messageIdQuery: number) { + const completeMessage = ctx.message?.caption + '\n\n' + 'Голосовое сообщение успешно сохранено✅'; + + this.bot.editMessageCaption(completeMessage, { + chat_id: ctx.message?.chat.id, + message_id: messageIdQuery, + reply_markup: undefined, + caption_entities: ctx.message?.caption_entities + }); + } + + private sendCancelMessage(ctx: CallbackQuery, messageIdQuery: number) { + const cancelMessage = ctx.message?.caption + '\n\n' + 'Сохранение голосового сообщения отменено❌'; + this.bot.editMessageCaption(cancelMessage, { + chat_id: ctx.message?.chat.id, + message_id: messageIdQuery, + reply_markup: undefined, + parse_mode: 'HTML' + }); + } + + private async saveVoice(customVoice: CustomVoice): Promise { + await this.botInstance.getDB().saveVoice(customVoice) + .then(() => { + this.logger.debug(`Голосовое сообщение ${customVoice.title} успешно добавлено`); + }) + .catch((err) => { + this.logger.error('Ошибка при добавлении голосового сообщения', err); + }); + } +} diff --git a/src/eventListeners/inlineListener.ts b/src/eventListeners/inlineListener.ts index 9ed3523..cf1fce2 100644 --- a/src/eventListeners/inlineListener.ts +++ b/src/eventListeners/inlineListener.ts @@ -4,62 +4,80 @@ import { Bot } from '../bot'; import { ILogger } from 'js-logger'; import { createLogger } from '../utils/logger/logger'; import { DataBase } from '../config/database/DataBase'; -import TelegramBot = require('node-telegram-bot-api'); import { CustomVoice } from '../utils/types/type'; +import { BotConfig } from '../config/BotConfig'; +import TelegramBot = require('node-telegram-bot-api'); +/** + * [Дока InlineQueryResultVoice](https://core.telegram.org/bots/api/#inlinequeryresultvoice) + */ export class InlineListener { + private readonly offset: number = 15; private readonly logger: ILogger = createLogger('InlineListener'); private readonly bot: TelegramBot; private readonly botInstance: Bot; + private readonly config: BotConfig; private readonly db: DataBase; constructor(botInstance: Bot) { this.bot = botInstance.getBot(); this.botInstance = botInstance; + this.config = botInstance.getConfig(); this.db = botInstance.getDB(); } public async handleMessage(ctx: InlineQuery): Promise { const query: string = ctx.query; let resultAudioList: InlineQueryResultVoice[] = []; + const isAdmin: boolean = this.config.getConfig()?.adminList.includes(ctx.from.id) ?? false; + + const offset = Number(ctx.offset); + if (query !== '') { this.logger.debug(`${ctx.from.username} -> ${query}`); - await this.db.getVoiceByTitleInclude(query, this.botInstance.getBotId()) + await this.db + .getVoiceByTitleInclude(query, this.botInstance.getBotId(), isAdmin, this.offset, offset) .then((voices: CustomVoice[]) => { - this.logger.debug('voices', voices); if (voices === undefined || voices.length === 0) { return; } - resultAudioList = voices.map((voice: CustomVoice) => ( - { - id: voice.id, - title: voice.title, - voice_url: voice.voice_url, - type: 'voice' - } as InlineQueryResultVoice - )); + resultAudioList = voices.map( + (voice: CustomVoice, index) => + ({ + id: String(index), + title: voice.title, + voice_url: voice.voice_url, + type: 'voice', + caption: voice.title + }) as InlineQueryResultVoice + ); }); } else { - await this.db.getAllVoices(this.botInstance.getBotId()) + await this.db + .getAllVoices(this.botInstance.getBotId(), isAdmin, this.offset, offset) .then((voices: CustomVoice[]) => { if (voices === undefined || voices.length === 0) { return; } - resultAudioList = voices.map((voice: CustomVoice) => ( - { - id: voice.id, - title: voice.title, - voice_url: voice.voice_url, - type: 'voice' - } as InlineQueryResultVoice - )); + resultAudioList = voices.map( + (voice: CustomVoice, index) => + ({ + id: String(index), + title: voice.title, + voice_url: voice.voice_url, + type: 'voice', + // Можно добавить вот это все https://core.telegram.org/bots/api/#formatting-options + // в MarkdownV2 + caption: voice.title + }) as InlineQueryResultVoice + ); }); } - this.bot.answerInlineQuery(ctx.id, resultAudioList) + this.bot + .answerInlineQuery(ctx.id, resultAudioList, { next_offset: String(offset + this.offset) }) .catch((err) => { this.logger.error('err', err); }); } } - diff --git a/src/eventListeners/messageListener.ts b/src/eventListeners/messageListener.ts index 3c5a260..c616806 100644 --- a/src/eventListeners/messageListener.ts +++ b/src/eventListeners/messageListener.ts @@ -4,9 +4,11 @@ import { ILogger } from 'js-logger'; import { createLogger } from '../utils/logger/logger'; import { BotConfig } from '../config/BotConfig'; import { Bot } from '../bot'; -import { CustomVoice, ExtendedMessage, SoundFile, SoundType } from '../utils/types/type'; +import { CacheInfo, Command, CustomVoice, ExtendedMessage, SavedSoundFile, SoundType } from '../utils/types/type'; import { randomUUID } from 'crypto'; -import { WriteStream } from 'fs'; +import { getReplayInlineKeyboard } from '../utils/inline/inlineKeyboard'; +import * as NodeCache from 'node-cache'; +import { DataBase } from '../config/database/DataBase'; import TelegramBot = require('node-telegram-bot-api'); import fs = require('fs'); import ErrnoException = NodeJS.ErrnoException; @@ -16,11 +18,15 @@ export class MessageListener { private readonly bot: TelegramBot; private readonly botInstance: Bot; private readonly config: BotConfig; + private readonly voiceCache: NodeCache; + private readonly db: DataBase; constructor(botInstance: Bot) { this.botInstance = botInstance; this.bot = botInstance.getBot(); this.config = botInstance.getConfig(); + this.voiceCache = botInstance.getVoiceCache(); + this.db = botInstance.getDB(); } public handleMessage(msg: ExtendedMessage, metadata?: Metadata) { @@ -29,47 +35,110 @@ export class MessageListener { return; } - this.logger.debug(`${msg.from.username} -> [${msg.text}]`); + const isAudioMessage = this.checkMessageContainsAudio(msg); + + this.logger.debug(`${msg.from.username} -> [${(msg.text ?? isAudioMessage) ? 'audio/voice' : 'undefined'}]`); if (!this.config.getConfig()?.adminList.includes(msg.from.id)) { - this.bot.sendMessage(chatId, 'Загрузка аудио доступна только админам') + this.bot.sendMessage(chatId, 'Загрузка аудио доступна только админам').catch((err) => { + this.logger.error('Ошибка отправки сообщения', err); + }); + return; + } + + if (isAudioMessage) { + this.parseSoundFile(msg) + .then((savedSoundFile: SavedSoundFile) => { + this.saveAndSendVoice(msg, savedSoundFile); + }) .catch((err) => { - this.logger.error('Ошибка отправки сообщения', err); + this.logger.error('Ошибка при загрузке файла', err); }); return; } - this.parseSoundFile(msg) - .then((soundFile: SoundFile) => { - this.saveAndSendVoice(msg, soundFile); - }) - .catch((err) => { - this.logger.error('Ошибка при загрузке файла', err); - }); + if (!msg.text || !msg.text.startsWith('!')) { + return; + } + + const command = msg.text.slice(1, msg.text.length).toUpperCase(); + + switch (command) { + case Command.LIST: + this.sendList(chatId, false); + break; + case Command.LIST_SORT: + this.sendList(chatId, true); + break; + default: + return; + } + } + + private async sendList(chatId: number, isSorted: boolean): Promise { + let resultAudioList: CustomVoice[] = []; + + await this.db.getAllVoices(this.botInstance.getBotId(), true, 100, 0).then((voices: CustomVoice[]) => { + if (voices === undefined || voices.length === 0) { + return; + } + resultAudioList = [...voices]; + if (isSorted) { + resultAudioList.sort((a, b) => Number(a.id) - Number(b.id)); + } + }); + + let messageWithList = 'Список аудио:\n\n'; + let count = 1; + resultAudioList.forEach((voice) => { + const isHidden = Boolean(voice.isHidden) ? '(🔒)' : ''; + let messagePattern = `#${count} | id-${voice.id}) ${voice.title} ${isHidden}\n`; + messageWithList += messagePattern; + count++; + }); + + this.bot.sendMessage(chatId, messageWithList, { parse_mode: 'HTML' }).catch((err) => { + this.logger.error('Ошибка отправки сообщения', err); + }); } - private saveAndSendVoice(msg: ExtendedMessage, soundFile: SoundFile) { - fs.readFile(soundFile.filePath, (err: ErrnoException | null, data: Buffer) => { - this.bot.sendVoice(msg.chat.id, data, { caption: 'test2' }) + private saveAndSendVoice(msg: ExtendedMessage, savedSoundFile: SavedSoundFile) { + fs.readFile(savedSoundFile.filePath, (err: ErrnoException | null, data: Buffer) => { + this.bot + .sendVoice(msg.chat.id, data, { caption: 'test2' }) .then(async (result: Message): Promise => { if (result.voice === undefined || result.voice.file_id === undefined) { return; } const voiceId: string = result.voice.file_id; - const completeMessage = `Голосовое сообщение успешно загружено\n\nНазвание: ${msg.caption ?? soundFile.fileName} \n\nid: ${voiceId}`; - - this.saveVoice(msg, result, soundFile.fileName) - .then(() => { - this.bot.editMessageCaption(completeMessage, { - chat_id: msg.chat.id, - message_id: result.message_id - }).catch((err) => { - this.logger.error('Ошибка при отправке голосового сообщения', err); - }); + const completeMessage = + 'Голосовое сообщение предварительно загружено\n\nНазвание: ' + + (msg.caption ?? savedSoundFile.fileName) + + '\n\nid: ' + + voiceId + + ''; + + const customVoice: CustomVoice = this.getCustomVoice(msg, result, savedSoundFile.fileName); + + this.bot + .editMessageCaption(completeMessage, { + chat_id: msg.chat.id, + message_id: result.message_id, + reply_markup: getReplayInlineKeyboard(customVoice), + parse_mode: 'HTML' }) .catch((err) => { - this.logger.error('Ошибка при сохранении голосового сообщения', err); + this.logger.error('Ошибка при отправке результата обработки сообщения', err); }); + + const oldCache = this.voiceCache.get(msg.chat.id) ?? []; + const cacheInfo: CacheInfo = { + messageId: msg.message_id, + customVoice: customVoice, + savedSoundFile: savedSoundFile + }; + + this.voiceCache.set(msg.chat.id, [...oldCache, cacheInfo]); }) .catch((err) => { this.logger.error('Неизвестная ошибка при отправке голосового сообщения', err); @@ -77,28 +146,29 @@ export class MessageListener { }); } - private async saveVoice(originalMsg: ExtendedMessage, result: Message, fileName: string): Promise { - if (result.voice === undefined || result.voice.file_id === undefined) { - return; + private getCustomVoice(originalMsg: ExtendedMessage, result: Message, fileName: string): CustomVoice { + if (result.voice === undefined) { + throw new Error('Невозможно получить CustomVoice из сообщения'); } - const voice: CustomVoice = { + return { id: result.voice?.file_id, title: originalMsg.caption ?? fileName, voice_url: result.voice?.file_id, - botId: this.botInstance.getBotId() ?? 0 + botId: this.botInstance.getBotId() ?? 0, + isHidden: false }; + } - await this.botInstance.getDB().saveVoice(voice) - .then(() => { - this.logger.debug(`Голосовое сообщение ${voice.title} успешно добавлено`); - }) - .catch((err) => { - this.logger.error('Ошибка при добавлении голосового сообщения', err); - }); + private checkMessageContainsAudio(msg: ExtendedMessage): boolean { + if (msg.audio !== undefined || msg.voice !== undefined || msg.via_bot !== undefined) { + return true; + } else { + return false; + } } - private async parseSoundFile(msg: ExtendedMessage): Promise { + private async parseSoundFile(msg: ExtendedMessage): Promise { return new Promise((resolve, reject) => { let soundType: SoundType; if (msg.audio === undefined && msg.voice !== undefined && msg.via_bot === undefined) { @@ -119,19 +189,19 @@ export class MessageListener { return; } - const fileName: string = isAudio ? msg.audio?.file_name.split('.')[0] : customSoundName ?? randomUUID(); - const filePath = `D:\\oggFiles\\${fileName}-${fileId}.ogg`; - const fileIS: WriteStream = fs.createWriteStream(filePath); + const fileName: string = isAudio + ? msg.audio?.file_name.split('.')[0].replace(/ /g, '_') + : (customSoundName?.replace(/ /g, '_') ?? randomUUID()); - this.bot.getFileStream(fileId) - .on('data', (chunk: any) => { - fileIS.write(chunk); + this.botInstance + .getFileWriter() + .writeFile(fileName, fileId, this.bot.getFileStream(fileId)) + .then((savedSoundFile) => { + resolve(savedSoundFile); }) - .on('close', () => { - fileIS.end(); - resolve({ filePath, fileName }); + .catch((err) => { + reject(err); }); }); - } } diff --git a/src/index.ts b/src/index.ts index 63d0371..ff13a06 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,9 @@ import { SQLite } from './config/database/SQLite'; import { DataBase } from './config/database/DataBase'; import { DataBaseType } from './utils/types/config'; import { ILogger } from 'js-logger'; +import {FileWriter} from "./utils/FileWriter"; +import { config as dotenvConfig } from 'dotenv'; +import { PostgreSQL } from './config/database/PostgreSQL'; const logger: ILogger = createLogger('Main'); let database: DataBase; @@ -18,7 +21,8 @@ const initDatabase = async (config: BotConfig): Promise => { db = new SQLite(config); break; case 'POSTGRESQL': - throw new Error('PostgreSQL не поддерживается'); + db = new PostgreSQL(config); + break; default: db = new SQLite(config); break; @@ -37,15 +41,18 @@ const initConfig = async (): Promise => { const init = async (): Promise => { try { + dotenvConfig() const config: BotConfig = await initConfig(); const db: DataBase = await initDatabase(config); + const fileWriter = new FileWriter(config); database = db; - const token: string | undefined = config.getConfig()?.botToken; - if (!token) { - throw new Error('Токен не найден'); + const botToken = process.env.BOT_TOKEN; + if (!botToken) { + return Promise.reject(new Error('Переменная окружения BOT_TOKEN не найдена')); } - new Bot(token, config, db); + + new Bot(botToken, config, db, fileWriter); } catch (e) { logger.error(e); } diff --git a/src/resources/config.json b/src/resources/config.json index aa29684..be48f2f 100644 --- a/src/resources/config.json +++ b/src/resources/config.json @@ -3,8 +3,11 @@ 200681892 ], "database": { - "type": "SQLITE", - "databaseName": "database.db" + "type": "POSTGRESQL", + "databaseName": "ugar_sound_bot", + "host": "localhost", + "port": 5432, + "schema": "ugar_sound_bot" }, - "botToken": "your bot token" + "tempFileDir": "oggFiles" } \ No newline at end of file diff --git a/src/resources/sql/initPostgreSQL.sql b/src/resources/sql/initPostgreSQL.sql new file mode 100644 index 0000000..fcd130b --- /dev/null +++ b/src/resources/sql/initPostgreSQL.sql @@ -0,0 +1,10 @@ +-- language: PostgreSQL +CREATE TABLE IF NOT EXISTS audio_inline +( + id SERIAL PRIMARY KEY, + inline_type TEXT NOT NULL, + title TEXT NOT NULL, + voice_url TEXT NOT NULL, + bot_id BIGINT NOT NULL, + is_hidden INTEGER NOT NULL DEFAULT 0 +); \ No newline at end of file diff --git a/src/resources/sql/init.sql b/src/resources/sql/initSQLite.sql similarity index 65% rename from src/resources/sql/init.sql rename to src/resources/sql/initSQLite.sql index ff8eed6..8cbedc2 100644 --- a/src/resources/sql/init.sql +++ b/src/resources/sql/initSQLite.sql @@ -1,8 +1,10 @@ +-- language: SQLite CREATE TABLE IF NOT EXISTS audio_inline ( id INTEGER PRIMARY KEY autoincrement, inline_type TEXT NOT NULL, title TEXT NOT NULL, voice_url TEXT NOT NULL, - bot_id INTEGER NOT NULL + bot_id INTEGER NOT NULL, + is_hidden INTEGER NOT NULL DEFAULT 0 ); \ No newline at end of file diff --git a/src/utils/FileWriter.ts b/src/utils/FileWriter.ts new file mode 100644 index 0000000..c9c24fb --- /dev/null +++ b/src/utils/FileWriter.ts @@ -0,0 +1,47 @@ +import * as fs from 'fs'; +import { WriteStream } from 'fs'; +import * as path from 'path'; +import { BotConfig } from '../config/BotConfig'; +import {SavedSoundFile} from './types/type'; +import {ILogger} from "js-logger"; +import {createLogger} from "./logger/logger"; + +export class FileWriter { + private readonly logger: ILogger = createLogger('FileWriter'); + private readonly oggFilesDir: string; + + constructor(config: BotConfig) { + this.oggFilesDir = config.getConfig()?.tempFileDir || 'oggFiles'; + fs.mkdirSync(path.resolve(this.oggFilesDir), { recursive: true }); + } + + public writeFile(fileName: string, fileId: string, fileStream: NodeJS.ReadableStream): Promise { + return new Promise((resolve, reject) => { + const filePath = path.resolve(this.oggFilesDir, `${fileName}-${fileId}.ogg`); + const fileIS: WriteStream = fs.createWriteStream(filePath); + + fileStream + .on('data', (chunk: any) => { + fileIS.write(chunk); + }) + .on('close', () => { + fileIS.end(); + resolve({ filePath, fileName, fileId }); + }) + .on('error', (err) => { + reject(err); + }); + }); + } + + public deleteFile(savedSoundFile: SavedSoundFile): void { + const filePath = path.resolve(this.oggFilesDir, `${savedSoundFile.fileName}-${savedSoundFile.fileId}.ogg`); + fs.unlink(filePath, (err) => { + if (err) { + this.logger.error(`Ошибка при удалении файла: ${filePath}`, err); + } else { + this.logger.debug(`Файл успешно удален: ${filePath}`); + } + }); + } +} diff --git a/src/utils/inline/inlineKeyboard.ts b/src/utils/inline/inlineKeyboard.ts new file mode 100644 index 0000000..2e7b505 --- /dev/null +++ b/src/utils/inline/inlineKeyboard.ts @@ -0,0 +1,22 @@ +import { InlineKeyboardMarkup } from 'node-telegram-bot-api'; +import { CallbackQueryInlineButtonType, CustomVoice } from '../types/type'; + +export const getReplayInlineKeyboard = (customVoice: CustomVoice): InlineKeyboardMarkup => { + const isHiddenText = customVoice.isHidden ? 'Скрыто 🔒' : 'Открыто🔓'; + return { + inline_keyboard: [ + + [ + { + text: `Изменить видимость: ${isHiddenText}`, + callback_data: CallbackQueryInlineButtonType.SWITCH_HIDDEN + } + ], + [ + { text: 'Сохранить', callback_data: CallbackQueryInlineButtonType.SAVE }, + { text: 'Отменить', callback_data: CallbackQueryInlineButtonType.CANCEL } + ] + ] + }; + +}; \ No newline at end of file diff --git a/src/utils/types/IDatabase.ts b/src/utils/types/IDatabase.ts index 9b8eb5d..ec0c720 100644 --- a/src/utils/types/IDatabase.ts +++ b/src/utils/types/IDatabase.ts @@ -11,11 +11,11 @@ export interface IDatabase { queryInsert(sql: string, params?: any[]): Promise; - getAllVoices(botId: number | undefined): Promise; + getAllVoices(botId: number | undefined, isHidden: boolean, limit: number, offset: number): Promise; getVoiceById(id: number): Promise; - getVoiceByTitleInclude(title: string, botId: number | undefined): Promise; + getVoiceByTitleInclude(title: string, botId: number | undefined, isHidden: boolean, limit: number, offset: number): Promise; saveVoice(voice: CustomVoice): Promise; } \ No newline at end of file diff --git a/src/utils/types/config.ts b/src/utils/types/config.ts index 956368d..260ac43 100644 --- a/src/utils/types/config.ts +++ b/src/utils/types/config.ts @@ -1,12 +1,17 @@ export interface Config { adminList: number[]; database: Database; - botToken: string; + tempFileDir: string; } interface Database { type: DataBaseType; databaseName?: string; + user?: string; + password?: string; + host?: string; + port?: number; + schema?: string; } export enum DataBaseType { diff --git a/src/utils/types/type.ts b/src/utils/types/type.ts index 6897823..737b934 100644 --- a/src/utils/types/type.ts +++ b/src/utils/types/type.ts @@ -2,6 +2,7 @@ import { InlineQueryResultVoice, Message } from 'node-telegram-bot-api'; export interface CustomVoice extends Pick { botId: number; + isHidden: boolean | number; } export interface ExtendedMessage extends Message { @@ -15,13 +16,34 @@ export interface ExtendedMessage extends Message { file_name: string; }; } +export enum Command { + LIST = 'LIST', + LIST_SORT = 'LIST_SORT', + EDIT = 'EDIT' +} export enum SoundType { AUDIO = 'AUDIO', VOICE = 'VOICE', } +export enum CallbackQueryInlineButtonType { + SAVE = 'SAVE', + CANCEL = 'CANCEL', + SWITCH_HIDDEN = 'SWITCH_HIDDEN' +} + export interface SoundFile { filePath: string; fileName: string; +} + +export interface SavedSoundFile extends SoundFile { + fileId: string; +} + +export interface CacheInfo { + messageId: number; + customVoice: CustomVoice; + savedSoundFile: SavedSoundFile; } \ No newline at end of file