diff --git a/packages/artifacts/package-lock.json b/packages/artifacts/package-lock.json new file mode 100644 index 0000000000..3988cdf841 --- /dev/null +++ b/packages/artifacts/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "@cherry-studio/artifacts", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@cherry-studio/artifacts", + "version": "0.1.0", + "license": "ISC" + } + } +} diff --git a/packages/database/package-lock.json b/packages/database/package-lock.json new file mode 100644 index 0000000000..98e02d049c --- /dev/null +++ b/packages/database/package-lock.json @@ -0,0 +1,1358 @@ +{ + "name": "@cherry-studio/database", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@cherry-studio/database", + "dependencies": { + "csv-parser": "^3.0.0", + "sqlite3": "^5.1.7" + } + }, + "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", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "optional": true, + "dependencies": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "node_modules/@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "optional": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "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==", + "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" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "optional": true, + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "optional": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "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" + } + }, + "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==", + "optional": true + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "optional": true + }, + "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" + } + ] + }, + "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==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "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" + } + ], + "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", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "optional": true, + "dependencies": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "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" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "optional": true + }, + "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==", + "optional": true + }, + "node_modules/csv-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-3.2.0.tgz", + "integrity": "sha512-fgKbp+AJbn1h2dcAHKIdKNSSjfp43BZZykXsCjzALjKy80VXQNHPFJ6T9Afwdzoj24aMkq8GwDS7KGcDPpejrA==", + "bin": { + "csv-parser": "bin/csv-parser" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "optional": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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==", + "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==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=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==", + "optional": true + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "optional": true + }, + "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==", + "engines": { + "node": ">=6" + } + }, + "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==" + }, + "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==" + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "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==", + "optional": true + }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.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==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "optional": true + }, + "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==", + "optional": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "optional": true + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "optional": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "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" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "optional": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "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" + } + ] + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "optional": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "optional": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "optional": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "optional": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "optional": true + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "optional": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "optional": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-fetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", + "optional": true, + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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==" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "optional": true + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==" + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-abi": { + "version": "3.74.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz", + "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==" + }, + "node_modules/node-gyp": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", + "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "optional": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^9.1.0", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "optional": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "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": "^2.0.0", + "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/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "optional": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "optional": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "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": { + "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" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "optional": true + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "optional": true + }, + "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==", + "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" + } + ] + }, + "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" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "optional": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz", + "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", + "optional": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "optional": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "optional": true + }, + "node_modules/sqlite3": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz", + "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "node-addon-api": "^7.0.0", + "prebuild-install": "^7.1.1", + "tar": "^6.1.11" + }, + "optionalDependencies": { + "node-gyp": "8.x" + }, + "peerDependencies": { + "node-gyp": "8.x" + }, + "peerDependenciesMeta": { + "node-gyp": { + "optional": true + } + } + }, + "node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "optional": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "optional": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", + "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", + "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==" + }, + "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==", + "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/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "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==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "optional": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "optional": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "optional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wide-align": { + "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" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } +} diff --git a/packages/database/yarn.lock b/packages/database/yarn.lock index f044300033..77d0009fe8 100644 --- a/packages/database/yarn.lock +++ b/packages/database/yarn.lock @@ -1,1643 +1,863 @@ -# This file is generated by running "yarn install" inside your project. -# Manual changes might be lost - proceed with caution! +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 -__metadata: - version: 8 - cacheKey: 10c0 -"@cherry-studio/database@workspace:.": - version: 0.0.0-use.local - resolution: "@cherry-studio/database@workspace:." +"@gar/promisify@^1.0.1": + version "1.1.3" + resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + +"@npmcli/fs@^1.0.0": + version "1.1.1" + resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz" + integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== dependencies: - csv-parser: "npm:^3.0.0" - sqlite3: "npm:^5.1.7" - languageName: unknown - linkType: soft - -"@gar/promisify@npm:^1.0.1": - version: 1.1.3 - resolution: "@gar/promisify@npm:1.1.3" - checksum: 10c0/0b3c9958d3cd17f4add3574975e3115ae05dc7f1298a60810414b16f6f558c137b5fb3cd3905df380bacfd955ec13f67c1e6710cbb5c246a7e8d65a8289b2bff - languageName: node - linkType: hard - -"@isaacs/cliui@npm:^8.0.2": - version: 8.0.2 - resolution: "@isaacs/cliui@npm:8.0.2" - dependencies: - string-width: "npm:^5.1.2" - string-width-cjs: "npm:string-width@^4.2.0" - strip-ansi: "npm:^7.0.1" - strip-ansi-cjs: "npm:strip-ansi@^6.0.1" - wrap-ansi: "npm:^8.1.0" - wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" - checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e - languageName: node - linkType: hard - -"@npmcli/agent@npm:^2.0.0": - version: 2.2.2 - resolution: "@npmcli/agent@npm:2.2.2" - dependencies: - agent-base: "npm:^7.1.0" - http-proxy-agent: "npm:^7.0.0" - https-proxy-agent: "npm:^7.0.1" - lru-cache: "npm:^10.0.1" - socks-proxy-agent: "npm:^8.0.3" - checksum: 10c0/325e0db7b287d4154ecd164c0815c08007abfb07653cc57bceded17bb7fd240998a3cbdbe87d700e30bef494885eccc725ab73b668020811d56623d145b524ae - languageName: node - linkType: hard - -"@npmcli/fs@npm:^1.0.0": - version: 1.1.1 - resolution: "@npmcli/fs@npm:1.1.1" - dependencies: - "@gar/promisify": "npm:^1.0.1" - semver: "npm:^7.3.5" - checksum: 10c0/4143c317a7542af9054018b71601e3c3392e6704e884561229695f099a71336cbd580df9a9ffb965d0024bf0ed593189ab58900fd1714baef1c9ee59c738c3e2 - languageName: node - linkType: hard - -"@npmcli/fs@npm:^3.1.0": - version: 3.1.1 - resolution: "@npmcli/fs@npm:3.1.1" - dependencies: - semver: "npm:^7.3.5" - checksum: 10c0/c37a5b4842bfdece3d14dfdb054f73fe15ed2d3da61b34ff76629fb5b1731647c49166fd2a8bf8b56fcfa51200382385ea8909a3cbecdad612310c114d3f6c99 - languageName: node - linkType: hard - -"@npmcli/move-file@npm:^1.0.1": - version: 1.1.2 - resolution: "@npmcli/move-file@npm:1.1.2" - dependencies: - mkdirp: "npm:^1.0.4" - rimraf: "npm:^3.0.2" - checksum: 10c0/02e946f3dafcc6743132fe2e0e2b585a96ca7265653a38df5a3e53fcf26c7c7a57fc0f861d7c689a23fdb6d6836c7eea5050c8086abf3c994feb2208d1514ff0 - languageName: node - linkType: hard - -"@pkgjs/parseargs@npm:^0.11.0": - version: 0.11.0 - resolution: "@pkgjs/parseargs@npm:0.11.0" - checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd - languageName: node - linkType: hard - -"@tootallnate/once@npm:1": - version: 1.1.2 - resolution: "@tootallnate/once@npm:1.1.2" - checksum: 10c0/8fe4d006e90422883a4fa9339dd05a83ff626806262e1710cee5758d493e8cbddf2db81c0e4690636dc840b02c9fda62877866ea774ebd07c1777ed5fafbdec6 - languageName: node - linkType: hard - -"abbrev@npm:1": - version: 1.1.1 - resolution: "abbrev@npm:1.1.1" - checksum: 10c0/3f762677702acb24f65e813070e306c61fafe25d4b2583f9dfc935131f774863f3addd5741572ed576bd69cabe473c5af18e1e108b829cb7b6b4747884f726e6 - languageName: node - linkType: hard - -"abbrev@npm:^2.0.0": - version: 2.0.0 - resolution: "abbrev@npm:2.0.0" - checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372 - languageName: node - linkType: hard - -"agent-base@npm:6, agent-base@npm:^6.0.2": - version: 6.0.2 - resolution: "agent-base@npm:6.0.2" - dependencies: - debug: "npm:4" - checksum: 10c0/dc4f757e40b5f3e3d674bc9beb4f1048f4ee83af189bae39be99f57bf1f48dde166a8b0a5342a84b5944ee8e6ed1e5a9d801858f4ad44764e84957122fe46261 - languageName: node - linkType: hard - -"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": - version: 7.1.1 - resolution: "agent-base@npm:7.1.1" - dependencies: - debug: "npm:^4.3.4" - checksum: 10c0/e59ce7bed9c63bf071a30cc471f2933862044c97fd9958967bfe22521d7a0f601ce4ed5a8c011799d0c726ca70312142ae193bbebb60f576b52be19d4a363b50 - languageName: node - linkType: hard - -"agentkeepalive@npm:^4.1.3": - version: 4.5.0 - resolution: "agentkeepalive@npm:4.5.0" - dependencies: - humanize-ms: "npm:^1.2.1" - checksum: 10c0/394ea19f9710f230722996e156607f48fdf3a345133b0b1823244b7989426c16019a428b56c82d3eabef616e938812981d9009f4792ecc66bd6a59e991c62612 - languageName: node - linkType: hard - -"aggregate-error@npm:^3.0.0": - version: 3.1.0 - resolution: "aggregate-error@npm:3.1.0" - dependencies: - clean-stack: "npm:^2.0.0" - indent-string: "npm:^4.0.0" - checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039 - languageName: node - linkType: hard - -"ansi-regex@npm:^5.0.1": - version: 5.0.1 - resolution: "ansi-regex@npm:5.0.1" - checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 - languageName: node - linkType: hard - -"ansi-regex@npm:^6.0.1": - version: 6.0.1 - resolution: "ansi-regex@npm:6.0.1" - checksum: 10c0/cbe16dbd2c6b2735d1df7976a7070dd277326434f0212f43abf6d87674095d247968209babdaad31bb00882fa68807256ba9be340eec2f1004de14ca75f52a08 - languageName: node - linkType: hard - -"ansi-styles@npm:^4.0.0": - version: 4.3.0 - resolution: "ansi-styles@npm:4.3.0" - dependencies: - color-convert: "npm:^2.0.1" - checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 - languageName: node - linkType: hard - -"ansi-styles@npm:^6.1.0": - version: 6.2.1 - resolution: "ansi-styles@npm:6.2.1" - checksum: 10c0/5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c - languageName: node - linkType: hard - -"aproba@npm:^1.0.3 || ^2.0.0": - version: 2.0.0 - resolution: "aproba@npm:2.0.0" - checksum: 10c0/d06e26384a8f6245d8c8896e138c0388824e259a329e0c9f196b4fa533c82502a6fd449586e3604950a0c42921832a458bb3aa0aa9f0ba449cfd4f50fd0d09b5 - languageName: node - linkType: hard - -"are-we-there-yet@npm:^3.0.0": - version: 3.0.1 - resolution: "are-we-there-yet@npm:3.0.1" - dependencies: - delegates: "npm:^1.0.0" - readable-stream: "npm:^3.6.0" - checksum: 10c0/8373f289ba42e4b5ec713bb585acdac14b5702c75f2a458dc985b9e4fa5762bc5b46b40a21b72418a3ed0cfb5e35bdc317ef1ae132f3035f633d581dd03168c3 - languageName: node - linkType: hard - -"balanced-match@npm:^1.0.0": - version: 1.0.2 - resolution: "balanced-match@npm:1.0.2" - checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee - languageName: node - linkType: hard - -"base64-js@npm:^1.3.1": - version: 1.5.1 - resolution: "base64-js@npm:1.5.1" - checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf - languageName: node - linkType: hard - -"bindings@npm:^1.5.0": - version: 1.5.0 - resolution: "bindings@npm:1.5.0" - dependencies: - file-uri-to-path: "npm:1.0.0" - checksum: 10c0/3dab2491b4bb24124252a91e656803eac24292473e56554e35bbfe3cc1875332cfa77600c3bac7564049dc95075bf6fcc63a4609920ff2d64d0fe405fcf0d4ba - languageName: node - linkType: hard - -"bl@npm:^4.0.3": - version: 4.1.0 - resolution: "bl@npm:4.1.0" - dependencies: - buffer: "npm:^5.5.0" - inherits: "npm:^2.0.4" - readable-stream: "npm:^3.4.0" - checksum: 10c0/02847e1d2cb089c9dc6958add42e3cdeaf07d13f575973963335ac0fdece563a50ac770ac4c8fa06492d2dd276f6cc3b7f08c7cd9c7a7ad0f8d388b2a28def5f - languageName: node - linkType: hard - -"brace-expansion@npm:^1.1.7": - version: 1.1.11 - resolution: "brace-expansion@npm:1.1.11" - dependencies: - balanced-match: "npm:^1.0.0" - concat-map: "npm:0.0.1" - checksum: 10c0/695a56cd058096a7cb71fb09d9d6a7070113c7be516699ed361317aca2ec169f618e28b8af352e02ab4233fb54eb0168460a40dc320bab0034b36ab59aaad668 - languageName: node - linkType: hard - -"brace-expansion@npm:^2.0.1": - version: 2.0.1 - resolution: "brace-expansion@npm:2.0.1" - dependencies: - balanced-match: "npm:^1.0.0" - checksum: 10c0/b358f2fe060e2d7a87aa015979ecea07f3c37d4018f8d6deb5bd4c229ad3a0384fe6029bb76cd8be63c81e516ee52d1a0673edbe2023d53a5191732ae3c3e49f - languageName: node - linkType: hard - -"buffer@npm:^5.5.0": - version: 5.7.1 - resolution: "buffer@npm:5.7.1" - dependencies: - base64-js: "npm:^1.3.1" - ieee754: "npm:^1.1.13" - checksum: 10c0/27cac81cff434ed2876058d72e7c4789d11ff1120ef32c9de48f59eab58179b66710c488987d295ae89a228f835fc66d088652dffeb8e3ba8659f80eb091d55e - languageName: node - linkType: hard - -"cacache@npm:^15.2.0": - version: 15.3.0 - resolution: "cacache@npm:15.3.0" - dependencies: - "@npmcli/fs": "npm:^1.0.0" - "@npmcli/move-file": "npm:^1.0.1" - chownr: "npm:^2.0.0" - fs-minipass: "npm:^2.0.0" - glob: "npm:^7.1.4" - infer-owner: "npm:^1.0.4" - lru-cache: "npm:^6.0.0" - minipass: "npm:^3.1.1" - minipass-collect: "npm:^1.0.2" - minipass-flush: "npm:^1.0.5" - minipass-pipeline: "npm:^1.2.2" - mkdirp: "npm:^1.0.3" - p-map: "npm:^4.0.0" - promise-inflight: "npm:^1.0.1" - rimraf: "npm:^3.0.2" - ssri: "npm:^8.0.1" - tar: "npm:^6.0.2" - unique-filename: "npm:^1.1.1" - checksum: 10c0/886fcc0acc4f6fd5cd142d373d8276267bc6d655d7c4ce60726fbbec10854de3395ee19bbf9e7e73308cdca9fdad0ad55060ff3bd16c6d4165c5b8d21515e1d8 - languageName: node - linkType: hard - -"cacache@npm:^18.0.0": - version: 18.0.4 - resolution: "cacache@npm:18.0.4" - dependencies: - "@npmcli/fs": "npm:^3.1.0" - fs-minipass: "npm:^3.0.0" - glob: "npm:^10.2.2" - lru-cache: "npm:^10.0.1" - minipass: "npm:^7.0.3" - minipass-collect: "npm:^2.0.1" - minipass-flush: "npm:^1.0.5" - minipass-pipeline: "npm:^1.2.4" - p-map: "npm:^4.0.0" - ssri: "npm:^10.0.0" - tar: "npm:^6.1.11" - unique-filename: "npm:^3.0.0" - checksum: 10c0/6c055bafed9de4f3dcc64ac3dc7dd24e863210902b7c470eb9ce55a806309b3efff78033e3d8b4f7dcc5d467f2db43c6a2857aaaf26f0094b8a351d44c42179f - languageName: node - linkType: hard - -"chownr@npm:^1.1.1": - version: 1.1.4 - resolution: "chownr@npm:1.1.4" - checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db - languageName: node - linkType: hard - -"chownr@npm:^2.0.0": - version: 2.0.0 - resolution: "chownr@npm:2.0.0" - checksum: 10c0/594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6 - languageName: node - linkType: hard - -"clean-stack@npm:^2.0.0": - version: 2.2.0 - resolution: "clean-stack@npm:2.2.0" - checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1 - languageName: node - linkType: hard - -"color-convert@npm:^2.0.1": - version: 2.0.1 - resolution: "color-convert@npm:2.0.1" - dependencies: - color-name: "npm:~1.1.4" - checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 - languageName: node - linkType: hard - -"color-name@npm:~1.1.4": - version: 1.1.4 - resolution: "color-name@npm:1.1.4" - checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 - languageName: node - linkType: hard - -"color-support@npm:^1.1.3": - version: 1.1.3 - resolution: "color-support@npm:1.1.3" - bin: - color-support: bin.js - checksum: 10c0/8ffeaa270a784dc382f62d9be0a98581db43e11eee301af14734a6d089bd456478b1a8b3e7db7ca7dc5b18a75f828f775c44074020b51c05fc00e6d0992b1cc6 - languageName: node - linkType: hard - -"concat-map@npm:0.0.1": - version: 0.0.1 - resolution: "concat-map@npm:0.0.1" - checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f - languageName: node - linkType: hard - -"console-control-strings@npm:^1.1.0": - version: 1.1.0 - resolution: "console-control-strings@npm:1.1.0" - checksum: 10c0/7ab51d30b52d461412cd467721bb82afe695da78fff8f29fe6f6b9cbaac9a2328e27a22a966014df9532100f6dd85370460be8130b9c677891ba36d96a343f50 - languageName: node - linkType: hard - -"cross-spawn@npm:^7.0.0": - version: 7.0.3 - resolution: "cross-spawn@npm:7.0.3" - dependencies: - path-key: "npm:^3.1.0" - shebang-command: "npm:^2.0.0" - which: "npm:^2.0.1" - checksum: 10c0/5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750 - languageName: node - linkType: hard - -"csv-parser@npm:^3.0.0": - version: 3.0.0 - resolution: "csv-parser@npm:3.0.0" - dependencies: - minimist: "npm:^1.2.0" - bin: - csv-parser: bin/csv-parser - checksum: 10c0/206aef102c10d532a31c7d85e6b1b0e53c7cb8346037eb9f23e0bd7369788960d8f2431639ea9f62e34ddf54d0182dfb345691c11c666802324f25c51dba79bc - languageName: node - linkType: hard - -"debug@npm:4, debug@npm:^4.3.3, debug@npm:^4.3.4": - version: 4.3.5 - resolution: "debug@npm:4.3.5" - dependencies: - ms: "npm:2.1.2" - peerDependenciesMeta: - supports-color: - optional: true - checksum: 10c0/082c375a2bdc4f4469c99f325ff458adad62a3fc2c482d59923c260cb08152f34e2659f72b3767db8bb2f21ca81a60a42d1019605a412132d7b9f59363a005cc - languageName: node - linkType: hard - -"decompress-response@npm:^6.0.0": - version: 6.0.0 - resolution: "decompress-response@npm:6.0.0" - dependencies: - mimic-response: "npm:^3.1.0" - checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e - languageName: node - linkType: hard - -"deep-extend@npm:^0.6.0": - version: 0.6.0 - resolution: "deep-extend@npm:0.6.0" - checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566 - languageName: node - linkType: hard - -"delegates@npm:^1.0.0": - version: 1.0.0 - resolution: "delegates@npm:1.0.0" - checksum: 10c0/ba05874b91148e1db4bf254750c042bf2215febd23a6d3cda2e64896aef79745fbd4b9996488bd3cafb39ce19dbce0fd6e3b6665275638befffe1c9b312b91b5 - languageName: node - linkType: hard - -"detect-libc@npm:^2.0.0": - version: 2.0.3 - resolution: "detect-libc@npm:2.0.3" - checksum: 10c0/88095bda8f90220c95f162bf92cad70bd0e424913e655c20578600e35b91edc261af27531cf160a331e185c0ced93944bc7e09939143225f56312d7fd800fdb7 - languageName: node - linkType: hard - -"eastasianwidth@npm:^0.2.0": - version: 0.2.0 - resolution: "eastasianwidth@npm:0.2.0" - checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 - languageName: node - linkType: hard - -"emoji-regex@npm:^8.0.0": - version: 8.0.0 - resolution: "emoji-regex@npm:8.0.0" - checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 - languageName: node - linkType: hard - -"emoji-regex@npm:^9.2.2": - version: 9.2.2 - resolution: "emoji-regex@npm:9.2.2" - checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 - languageName: node - linkType: hard - -"encoding@npm:^0.1.12, encoding@npm:^0.1.13": - version: 0.1.13 - resolution: "encoding@npm:0.1.13" - dependencies: - iconv-lite: "npm:^0.6.2" - checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039 - languageName: node - linkType: hard - -"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": - version: 1.4.4 - resolution: "end-of-stream@npm:1.4.4" - dependencies: - once: "npm:^1.4.0" - checksum: 10c0/870b423afb2d54bb8d243c63e07c170409d41e20b47eeef0727547aea5740bd6717aca45597a9f2745525667a6b804c1e7bede41f856818faee5806dd9ff3975 - languageName: node - linkType: hard - -"env-paths@npm:^2.2.0": - version: 2.2.1 - resolution: "env-paths@npm:2.2.1" - checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 - languageName: node - linkType: hard - -"err-code@npm:^2.0.2": - version: 2.0.3 - resolution: "err-code@npm:2.0.3" - checksum: 10c0/b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66 - languageName: node - linkType: hard - -"expand-template@npm:^2.0.3": - version: 2.0.3 - resolution: "expand-template@npm:2.0.3" - checksum: 10c0/1c9e7afe9acadf9d373301d27f6a47b34e89b3391b1ef38b7471d381812537ef2457e620ae7f819d2642ce9c43b189b3583813ec395e2938319abe356a9b2f51 - languageName: node - linkType: hard - -"exponential-backoff@npm:^3.1.1": - version: 3.1.1 - resolution: "exponential-backoff@npm:3.1.1" - checksum: 10c0/160456d2d647e6019640bd07111634d8c353038d9fa40176afb7cd49b0548bdae83b56d05e907c2cce2300b81cae35d800ef92fefb9d0208e190fa3b7d6bb579 - languageName: node - linkType: hard - -"file-uri-to-path@npm:1.0.0": - version: 1.0.0 - resolution: "file-uri-to-path@npm:1.0.0" - checksum: 10c0/3b545e3a341d322d368e880e1c204ef55f1d45cdea65f7efc6c6ce9e0c4d22d802d5629320eb779d006fe59624ac17b0e848d83cc5af7cd101f206cb704f5519 - languageName: node - linkType: hard - -"foreground-child@npm:^3.1.0": - version: 3.2.1 - resolution: "foreground-child@npm:3.2.1" - dependencies: - cross-spawn: "npm:^7.0.0" - signal-exit: "npm:^4.0.1" - checksum: 10c0/9a53a33dbd87090e9576bef65fb4a71de60f6863a8062a7b11bc1cbe3cc86d428677d7c0b9ef61cdac11007ac580006f78bd5638618d564cfd5e6fd713d6878f - languageName: node - linkType: hard - -"fs-constants@npm:^1.0.0": - version: 1.0.0 - resolution: "fs-constants@npm:1.0.0" - checksum: 10c0/a0cde99085f0872f4d244e83e03a46aa387b74f5a5af750896c6b05e9077fac00e9932fdf5aef84f2f16634cd473c63037d7a512576da7d5c2b9163d1909f3a8 - languageName: node - linkType: hard - -"fs-minipass@npm:^2.0.0": - version: 2.1.0 - resolution: "fs-minipass@npm:2.1.0" - dependencies: - minipass: "npm:^3.0.0" - checksum: 10c0/703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004 - languageName: node - linkType: hard - -"fs-minipass@npm:^3.0.0": - version: 3.0.3 - resolution: "fs-minipass@npm:3.0.3" - dependencies: - minipass: "npm:^7.0.3" - checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94 - languageName: node - linkType: hard - -"fs.realpath@npm:^1.0.0": - version: 1.0.0 - resolution: "fs.realpath@npm:1.0.0" - checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948 - languageName: node - linkType: hard - -"gauge@npm:^4.0.3": - version: 4.0.4 - resolution: "gauge@npm:4.0.4" - dependencies: - aproba: "npm:^1.0.3 || ^2.0.0" - color-support: "npm:^1.1.3" - console-control-strings: "npm:^1.1.0" - has-unicode: "npm:^2.0.1" - signal-exit: "npm:^3.0.7" - string-width: "npm:^4.2.3" - strip-ansi: "npm:^6.0.1" - wide-align: "npm:^1.1.5" - checksum: 10c0/ef10d7981113d69225135f994c9f8c4369d945e64a8fc721d655a3a38421b738c9fe899951721d1b47b73c41fdb5404ac87cc8903b2ecbed95d2800363e7e58c - languageName: node - linkType: hard - -"github-from-package@npm:0.0.0": - version: 0.0.0 - resolution: "github-from-package@npm:0.0.0" - checksum: 10c0/737ee3f52d0a27e26332cde85b533c21fcdc0b09fb716c3f8e522cfaa9c600d4a631dec9fcde179ec9d47cca89017b7848ed4d6ae6b6b78f936c06825b1fcc12 - languageName: node - linkType: hard - -"glob@npm:^10.2.2, glob@npm:^10.3.10": - version: 10.4.5 - resolution: "glob@npm:10.4.5" - dependencies: - foreground-child: "npm:^3.1.0" - jackspeak: "npm:^3.1.2" - minimatch: "npm:^9.0.4" - minipass: "npm:^7.1.2" - package-json-from-dist: "npm:^1.0.0" - path-scurry: "npm:^1.11.1" - bin: - glob: dist/esm/bin.mjs - checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e - languageName: node - linkType: hard - -"glob@npm:^7.1.3, glob@npm:^7.1.4": - version: 7.2.3 - resolution: "glob@npm:7.2.3" - dependencies: - fs.realpath: "npm:^1.0.0" - inflight: "npm:^1.0.4" - inherits: "npm:2" - minimatch: "npm:^3.1.1" - once: "npm:^1.3.0" - path-is-absolute: "npm:^1.0.0" - checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe - languageName: node - linkType: hard - -"graceful-fs@npm:^4.2.6": - version: 4.2.11 - resolution: "graceful-fs@npm:4.2.11" - checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 - languageName: node - linkType: hard - -"has-unicode@npm:^2.0.1": - version: 2.0.1 - resolution: "has-unicode@npm:2.0.1" - checksum: 10c0/ebdb2f4895c26bb08a8a100b62d362e49b2190bcfd84b76bc4be1a3bd4d254ec52d0dd9f2fbcc093fc5eb878b20c52146f9dfd33e2686ed28982187be593b47c - languageName: node - linkType: hard - -"http-cache-semantics@npm:^4.1.0, http-cache-semantics@npm:^4.1.1": - version: 4.1.1 - resolution: "http-cache-semantics@npm:4.1.1" - checksum: 10c0/ce1319b8a382eb3cbb4a37c19f6bfe14e5bb5be3d09079e885e8c513ab2d3cd9214902f8a31c9dc4e37022633ceabfc2d697405deeaf1b8f3552bb4ed996fdfc - languageName: node - linkType: hard - -"http-proxy-agent@npm:^4.0.1": - version: 4.0.1 - resolution: "http-proxy-agent@npm:4.0.1" - dependencies: - "@tootallnate/once": "npm:1" - agent-base: "npm:6" - debug: "npm:4" - checksum: 10c0/4fa4774d65b5331814b74ac05cefea56854fc0d5989c80b13432c1b0d42a14c9f4342ca3ad9f0359a52e78da12b1744c9f8a28e50042136ea9171675d972a5fd - languageName: node - linkType: hard - -"http-proxy-agent@npm:^7.0.0": - version: 7.0.2 - resolution: "http-proxy-agent@npm:7.0.2" - dependencies: - agent-base: "npm:^7.1.0" - debug: "npm:^4.3.4" - checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921 - languageName: node - linkType: hard - -"https-proxy-agent@npm:^5.0.0": - version: 5.0.1 - resolution: "https-proxy-agent@npm:5.0.1" - dependencies: - agent-base: "npm:6" - debug: "npm:4" - checksum: 10c0/6dd639f03434003577c62b27cafdb864784ef19b2de430d8ae2a1d45e31c4fd60719e5637b44db1a88a046934307da7089e03d6089ec3ddacc1189d8de8897d1 - languageName: node - linkType: hard - -"https-proxy-agent@npm:^7.0.1": - version: 7.0.5 - resolution: "https-proxy-agent@npm:7.0.5" - dependencies: - agent-base: "npm:^7.0.2" - debug: "npm:4" - checksum: 10c0/2490e3acec397abeb88807db52cac59102d5ed758feee6df6112ab3ccd8325e8a1ce8bce6f4b66e5470eca102d31e425ace904242e4fa28dbe0c59c4bafa7b2c - languageName: node - linkType: hard - -"humanize-ms@npm:^1.2.1": - version: 1.2.1 - resolution: "humanize-ms@npm:1.2.1" - dependencies: - ms: "npm:^2.0.0" - checksum: 10c0/f34a2c20161d02303c2807badec2f3b49cbfbbb409abd4f95a07377ae01cfe6b59e3d15ac609cffcd8f2521f0eb37b7e1091acf65da99aa2a4f1ad63c21e7e7a - languageName: node - linkType: hard - -"iconv-lite@npm:^0.6.2": - version: 0.6.3 - resolution: "iconv-lite@npm:0.6.3" - dependencies: - safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 - languageName: node - linkType: hard - -"ieee754@npm:^1.1.13": - version: 1.2.1 - resolution: "ieee754@npm:1.2.1" - checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb - languageName: node - linkType: hard - -"imurmurhash@npm:^0.1.4": - version: 0.1.4 - resolution: "imurmurhash@npm:0.1.4" - checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 - languageName: node - linkType: hard - -"indent-string@npm:^4.0.0": - version: 4.0.0 - resolution: "indent-string@npm:4.0.0" - checksum: 10c0/1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f - languageName: node - linkType: hard - -"infer-owner@npm:^1.0.4": - version: 1.0.4 - resolution: "infer-owner@npm:1.0.4" - checksum: 10c0/a7b241e3149c26e37474e3435779487f42f36883711f198c45794703c7556bc38af224088bd4d1a221a45b8208ae2c2bcf86200383621434d0c099304481c5b9 - languageName: node - linkType: hard - -"inflight@npm:^1.0.4": - version: 1.0.6 - resolution: "inflight@npm:1.0.6" - dependencies: - once: "npm:^1.3.0" - wrappy: "npm:1" - checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2 - languageName: node - linkType: hard - -"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4": - version: 2.0.4 - resolution: "inherits@npm:2.0.4" - checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 - languageName: node - linkType: hard - -"ini@npm:~1.3.0": - version: 1.3.8 - resolution: "ini@npm:1.3.8" - checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a - languageName: node - linkType: hard - -"ip-address@npm:^9.0.5": - version: 9.0.5 - resolution: "ip-address@npm:9.0.5" - dependencies: - jsbn: "npm:1.1.0" - sprintf-js: "npm:^1.1.3" - checksum: 10c0/331cd07fafcb3b24100613e4b53e1a2b4feab11e671e655d46dc09ee233da5011284d09ca40c4ecbdfe1d0004f462958675c224a804259f2f78d2465a87824bc - languageName: node - linkType: hard - -"is-fullwidth-code-point@npm:^3.0.0": - version: 3.0.0 - resolution: "is-fullwidth-code-point@npm:3.0.0" - checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc - languageName: node - linkType: hard - -"is-lambda@npm:^1.0.1": - version: 1.0.1 - resolution: "is-lambda@npm:1.0.1" - checksum: 10c0/85fee098ae62ba6f1e24cf22678805473c7afd0fb3978a3aa260e354cb7bcb3a5806cf0a98403188465efedec41ab4348e8e4e79305d409601323855b3839d4d - languageName: node - linkType: hard - -"isexe@npm:^2.0.0": - version: 2.0.0 - resolution: "isexe@npm:2.0.0" - checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d - languageName: node - linkType: hard - -"isexe@npm:^3.1.1": - version: 3.1.1 - resolution: "isexe@npm:3.1.1" - checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 - languageName: node - linkType: hard - -"jackspeak@npm:^3.1.2": - version: 3.4.3 - resolution: "jackspeak@npm:3.4.3" - dependencies: - "@isaacs/cliui": "npm:^8.0.2" - "@pkgjs/parseargs": "npm:^0.11.0" - dependenciesMeta: - "@pkgjs/parseargs": - optional: true - checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9 - languageName: node - linkType: hard - -"jsbn@npm:1.1.0": - version: 1.1.0 - resolution: "jsbn@npm:1.1.0" - checksum: 10c0/4f907fb78d7b712e11dea8c165fe0921f81a657d3443dde75359ed52eb2b5d33ce6773d97985a089f09a65edd80b11cb75c767b57ba47391fee4c969f7215c96 - languageName: node - linkType: hard - -"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": - version: 10.4.3 - resolution: "lru-cache@npm:10.4.3" - checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb - languageName: node - linkType: hard - -"lru-cache@npm:^6.0.0": - version: 6.0.0 - resolution: "lru-cache@npm:6.0.0" - dependencies: - yallist: "npm:^4.0.0" - checksum: 10c0/cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9 - languageName: node - linkType: hard - -"make-fetch-happen@npm:^13.0.0": - version: 13.0.1 - resolution: "make-fetch-happen@npm:13.0.1" - dependencies: - "@npmcli/agent": "npm:^2.0.0" - cacache: "npm:^18.0.0" - http-cache-semantics: "npm:^4.1.1" - is-lambda: "npm:^1.0.1" - minipass: "npm:^7.0.2" - minipass-fetch: "npm:^3.0.0" - minipass-flush: "npm:^1.0.5" - minipass-pipeline: "npm:^1.2.4" - negotiator: "npm:^0.6.3" - proc-log: "npm:^4.2.0" - promise-retry: "npm:^2.0.1" - ssri: "npm:^10.0.0" - checksum: 10c0/df5f4dbb6d98153b751bccf4dc4cc500de85a96a9331db9805596c46aa9f99d9555983954e6c1266d9f981ae37a9e4647f42b9a4bb5466f867f4012e582c9e7e - languageName: node - linkType: hard - -"make-fetch-happen@npm:^9.1.0": - version: 9.1.0 - resolution: "make-fetch-happen@npm:9.1.0" - dependencies: - agentkeepalive: "npm:^4.1.3" - cacache: "npm:^15.2.0" - http-cache-semantics: "npm:^4.1.0" - http-proxy-agent: "npm:^4.0.1" - https-proxy-agent: "npm:^5.0.0" - is-lambda: "npm:^1.0.1" - lru-cache: "npm:^6.0.0" - minipass: "npm:^3.1.3" - minipass-collect: "npm:^1.0.2" - minipass-fetch: "npm:^1.3.2" - minipass-flush: "npm:^1.0.5" - minipass-pipeline: "npm:^1.2.4" - negotiator: "npm:^0.6.2" - promise-retry: "npm:^2.0.1" - socks-proxy-agent: "npm:^6.0.0" - ssri: "npm:^8.0.0" - checksum: 10c0/2c737faf6a7f67077679da548b5bfeeef890595bf8c4323a1f76eae355d27ebb33dcf9cf1a673f944cf2f2a7cbf4e2b09f0a0a62931737728f210d902c6be966 - languageName: node - linkType: hard - -"mimic-response@npm:^3.1.0": - version: 3.1.0 - resolution: "mimic-response@npm:3.1.0" - checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 - languageName: node - linkType: hard - -"minimatch@npm:^3.1.1": - version: 3.1.2 - resolution: "minimatch@npm:3.1.2" - dependencies: - brace-expansion: "npm:^1.1.7" - checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311 - languageName: node - linkType: hard - -"minimatch@npm:^9.0.4": - version: 9.0.5 - resolution: "minimatch@npm:9.0.5" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed - languageName: node - linkType: hard - -"minimist@npm:^1.2.0, minimist@npm:^1.2.3": - version: 1.2.8 - resolution: "minimist@npm:1.2.8" - checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 - languageName: node - linkType: hard - -"minipass-collect@npm:^1.0.2": - version: 1.0.2 - resolution: "minipass-collect@npm:1.0.2" - dependencies: - minipass: "npm:^3.0.0" - checksum: 10c0/8f82bd1f3095b24f53a991b04b67f4c710c894e518b813f0864a31de5570441a509be1ca17e0bb92b047591a8fdbeb886f502764fefb00d2f144f4011791e898 - languageName: node - linkType: hard - -"minipass-collect@npm:^2.0.1": - version: 2.0.1 - resolution: "minipass-collect@npm:2.0.1" - dependencies: - minipass: "npm:^7.0.3" - checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e - languageName: node - linkType: hard - -"minipass-fetch@npm:^1.3.2": - version: 1.4.1 - resolution: "minipass-fetch@npm:1.4.1" - dependencies: - encoding: "npm:^0.1.12" - minipass: "npm:^3.1.0" - minipass-sized: "npm:^1.0.3" - minizlib: "npm:^2.0.0" - dependenciesMeta: - encoding: - optional: true - checksum: 10c0/a43da7401cd7c4f24b993887d41bd37d097356083b0bb836fd655916467463a1e6e9e553b2da4fcbe8745bf23d40c8b884eab20745562199663b3e9060cd8e7a - languageName: node - linkType: hard - -"minipass-fetch@npm:^3.0.0": - version: 3.0.5 - resolution: "minipass-fetch@npm:3.0.5" - dependencies: - encoding: "npm:^0.1.13" - minipass: "npm:^7.0.3" - minipass-sized: "npm:^1.0.3" - minizlib: "npm:^2.1.2" - dependenciesMeta: - encoding: - optional: true - checksum: 10c0/9d702d57f556274286fdd97e406fc38a2f5c8d15e158b498d7393b1105974b21249289ec571fa2b51e038a4872bfc82710111cf75fae98c662f3d6f95e72152b - languageName: node - linkType: hard - -"minipass-flush@npm:^1.0.5": - version: 1.0.5 - resolution: "minipass-flush@npm:1.0.5" - dependencies: - minipass: "npm:^3.0.0" - checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd - languageName: node - linkType: hard - -"minipass-pipeline@npm:^1.2.2, minipass-pipeline@npm:^1.2.4": - version: 1.2.4 - resolution: "minipass-pipeline@npm:1.2.4" - dependencies: - minipass: "npm:^3.0.0" - checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2 - languageName: node - linkType: hard - -"minipass-sized@npm:^1.0.3": - version: 1.0.3 - resolution: "minipass-sized@npm:1.0.3" - dependencies: - minipass: "npm:^3.0.0" - checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb - languageName: node - linkType: hard - -"minipass@npm:^3.0.0, minipass@npm:^3.1.0, minipass@npm:^3.1.1, minipass@npm:^3.1.3": - version: 3.3.6 - resolution: "minipass@npm:3.3.6" - dependencies: - yallist: "npm:^4.0.0" - checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c - languageName: node - linkType: hard - -"minipass@npm:^5.0.0": - version: 5.0.0 - resolution: "minipass@npm:5.0.0" - checksum: 10c0/a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462 - languageName: node - linkType: hard - -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": - version: 7.1.2 - resolution: "minipass@npm:7.1.2" - checksum: 10c0/b0fd20bb9fb56e5fa9a8bfac539e8915ae07430a619e4b86ff71f5fc757ef3924b23b2c4230393af1eda647ed3d75739e4e0acb250a6b1eb277cf7f8fe449557 - languageName: node - linkType: hard - -"minizlib@npm:^2.0.0, minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": - version: 2.1.2 - resolution: "minizlib@npm:2.1.2" - dependencies: - minipass: "npm:^3.0.0" - yallist: "npm:^4.0.0" - checksum: 10c0/64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78 - languageName: node - linkType: hard - -"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": - version: 0.5.3 - resolution: "mkdirp-classic@npm:0.5.3" - checksum: 10c0/95371d831d196960ddc3833cc6907e6b8f67ac5501a6582f47dfae5eb0f092e9f8ce88e0d83afcae95d6e2b61a01741ba03714eeafb6f7a6e9dcc158ac85b168 - languageName: node - linkType: hard - -"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": - version: 1.0.4 - resolution: "mkdirp@npm:1.0.4" - bin: - mkdirp: bin/cmd.js - checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf - languageName: node - linkType: hard - -"ms@npm:2.1.2": - version: 2.1.2 - resolution: "ms@npm:2.1.2" - checksum: 10c0/a437714e2f90dbf881b5191d35a6db792efbca5badf112f87b9e1c712aace4b4b9b742dd6537f3edf90fd6f684de897cec230abde57e87883766712ddda297cc - languageName: node - linkType: hard - -"ms@npm:^2.0.0": - version: 2.1.3 - resolution: "ms@npm:2.1.3" - checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 - languageName: node - linkType: hard - -"napi-build-utils@npm:^1.0.1": - version: 1.0.2 - resolution: "napi-build-utils@npm:1.0.2" - checksum: 10c0/37fd2cd0ff2ad20073ce78d83fd718a740d568b225924e753ae51cb69d68f330c80544d487e5e5bd18e28702ed2ca469c2424ad948becd1862c1b0209542b2e9 - languageName: node - linkType: hard - -"negotiator@npm:^0.6.2, negotiator@npm:^0.6.3": - version: 0.6.3 - resolution: "negotiator@npm:0.6.3" - checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 - languageName: node - linkType: hard - -"node-abi@npm:^3.3.0": - version: 3.65.0 - resolution: "node-abi@npm:3.65.0" - dependencies: - semver: "npm:^7.3.5" - checksum: 10c0/112672015d8f27d6be2f18d64569f28f5d6a15a94cc510da513c69c3e3ab5df6dac196ef13ff115a8fadb69b554974c47ef89b4f6350a2b02de2bca5c23db1e5 - languageName: node - linkType: hard - -"node-addon-api@npm:^7.0.0": - version: 7.1.1 - resolution: "node-addon-api@npm:7.1.1" - dependencies: - node-gyp: "npm:latest" - checksum: 10c0/fb32a206276d608037fa1bcd7e9921e177fe992fc610d098aa3128baca3c0050fc1e014fa007e9b3874cf865ddb4f5bd9f43ccb7cbbbe4efaff6a83e920b17e9 - languageName: node - linkType: hard - -"node-gyp@npm:8.x": - version: 8.4.1 - resolution: "node-gyp@npm:8.4.1" - dependencies: - env-paths: "npm:^2.2.0" - glob: "npm:^7.1.4" - graceful-fs: "npm:^4.2.6" - make-fetch-happen: "npm:^9.1.0" - nopt: "npm:^5.0.0" - npmlog: "npm:^6.0.0" - rimraf: "npm:^3.0.2" - semver: "npm:^7.3.5" - tar: "npm:^6.1.2" - which: "npm:^2.0.2" - bin: - node-gyp: bin/node-gyp.js - checksum: 10c0/80ef333b3a882eb6a2695a8e08f31d618f4533eff192864e4a3a16b67ff0abc9d8c1d5fac0395550ec699326b9248c5e2b3be178492f7f4d1ccf97d2cf948021 - languageName: node - linkType: hard - -"node-gyp@npm:latest": - version: 10.2.0 - resolution: "node-gyp@npm:10.2.0" - dependencies: - env-paths: "npm:^2.2.0" - exponential-backoff: "npm:^3.1.1" - glob: "npm:^10.3.10" - graceful-fs: "npm:^4.2.6" - make-fetch-happen: "npm:^13.0.0" - nopt: "npm:^7.0.0" - proc-log: "npm:^4.1.0" - semver: "npm:^7.3.5" - tar: "npm:^6.2.1" - which: "npm:^4.0.0" - bin: - node-gyp: bin/node-gyp.js - checksum: 10c0/00630d67dbd09a45aee0a5d55c05e3916ca9e6d427ee4f7bc392d2d3dc5fad7449b21fc098dd38260a53d9dcc9c879b36704a1994235d4707e7271af7e9a835b - languageName: node - linkType: hard - -"nopt@npm:^5.0.0": - version: 5.0.0 - resolution: "nopt@npm:5.0.0" - dependencies: - abbrev: "npm:1" - bin: - nopt: bin/nopt.js - checksum: 10c0/fc5c4f07155cb455bf5fc3dd149fac421c1a40fd83c6bfe83aa82b52f02c17c5e88301321318adaa27611c8a6811423d51d29deaceab5fa158b585a61a551061 - languageName: node - linkType: hard - -"nopt@npm:^7.0.0": - version: 7.2.1 - resolution: "nopt@npm:7.2.1" - dependencies: - abbrev: "npm:^2.0.0" - bin: - nopt: bin/nopt.js - checksum: 10c0/a069c7c736767121242037a22a788863accfa932ab285a1eb569eb8cd534b09d17206f68c37f096ae785647435e0c5a5a0a67b42ec743e481a455e5ae6a6df81 - languageName: node - linkType: hard - -"npmlog@npm:^6.0.0": - version: 6.0.2 - resolution: "npmlog@npm:6.0.2" - dependencies: - are-we-there-yet: "npm:^3.0.0" - console-control-strings: "npm:^1.1.0" - gauge: "npm:^4.0.3" - set-blocking: "npm:^2.0.0" - checksum: 10c0/0cacedfbc2f6139c746d9cd4a85f62718435ad0ca4a2d6459cd331dd33ae58206e91a0742c1558634efcde3f33f8e8e7fd3adf1bfe7978310cf00bd55cccf890 - languageName: node - linkType: hard - -"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": - version: 1.4.0 - resolution: "once@npm:1.4.0" - dependencies: - wrappy: "npm:1" - checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 - languageName: node - linkType: hard - -"p-map@npm:^4.0.0": - version: 4.0.0 - resolution: "p-map@npm:4.0.0" - dependencies: - aggregate-error: "npm:^3.0.0" - checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75 - languageName: node - linkType: hard - -"package-json-from-dist@npm:^1.0.0": - version: 1.0.0 - resolution: "package-json-from-dist@npm:1.0.0" - checksum: 10c0/e3ffaf6ac1040ab6082a658230c041ad14e72fabe99076a2081bb1d5d41210f11872403fc09082daf4387fc0baa6577f96c9c0e94c90c394fd57794b66aa4033 - languageName: node - linkType: hard - -"path-is-absolute@npm:^1.0.0": - version: 1.0.1 - resolution: "path-is-absolute@npm:1.0.1" - checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078 - languageName: node - linkType: hard - -"path-key@npm:^3.1.0": - version: 3.1.1 - resolution: "path-key@npm:3.1.1" - checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c - languageName: node - linkType: hard - -"path-scurry@npm:^1.11.1": - version: 1.11.1 - resolution: "path-scurry@npm:1.11.1" - dependencies: - lru-cache: "npm:^10.2.0" - minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - checksum: 10c0/32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d - languageName: node - linkType: hard - -"prebuild-install@npm:^7.1.1": - version: 7.1.2 - resolution: "prebuild-install@npm:7.1.2" - dependencies: - detect-libc: "npm:^2.0.0" - expand-template: "npm:^2.0.3" - github-from-package: "npm:0.0.0" - minimist: "npm:^1.2.3" - mkdirp-classic: "npm:^0.5.3" - napi-build-utils: "npm:^1.0.1" - node-abi: "npm:^3.3.0" - pump: "npm:^3.0.0" - rc: "npm:^1.2.7" - simple-get: "npm:^4.0.0" - tar-fs: "npm:^2.0.0" - tunnel-agent: "npm:^0.6.0" - bin: - prebuild-install: bin.js - checksum: 10c0/e64868ba9ef2068fd7264f5b03e5298a901e02a450acdb1f56258d88c09dea601eefdb3d1dfdff8513fdd230a92961712be0676192626a3b4d01ba154d48bdd3 - languageName: node - linkType: hard - -"proc-log@npm:^4.1.0, proc-log@npm:^4.2.0": - version: 4.2.0 - resolution: "proc-log@npm:4.2.0" - checksum: 10c0/17db4757c2a5c44c1e545170e6c70a26f7de58feb985091fb1763f5081cab3d01b181fb2dd240c9f4a4255a1d9227d163d5771b7e69c9e49a561692db865efb9 - languageName: node - linkType: hard - -"promise-inflight@npm:^1.0.1": - version: 1.0.1 - resolution: "promise-inflight@npm:1.0.1" - checksum: 10c0/d179d148d98fbff3d815752fa9a08a87d3190551d1420f17c4467f628214db12235ae068d98cd001f024453676d8985af8f28f002345646c4ece4600a79620bc - languageName: node - linkType: hard - -"promise-retry@npm:^2.0.1": - version: 2.0.1 - resolution: "promise-retry@npm:2.0.1" - dependencies: - err-code: "npm:^2.0.2" - retry: "npm:^0.12.0" - checksum: 10c0/9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96 - languageName: node - linkType: hard - -"pump@npm:^3.0.0": - version: 3.0.0 - resolution: "pump@npm:3.0.0" - dependencies: - end-of-stream: "npm:^1.1.0" - once: "npm:^1.3.1" - checksum: 10c0/bbdeda4f747cdf47db97428f3a135728669e56a0ae5f354a9ac5b74556556f5446a46f720a8f14ca2ece5be9b4d5d23c346db02b555f46739934cc6c093a5478 - languageName: node - linkType: hard - -"rc@npm:^1.2.7": - version: 1.2.8 - resolution: "rc@npm:1.2.8" - dependencies: - deep-extend: "npm:^0.6.0" - ini: "npm:~1.3.0" - minimist: "npm:^1.2.0" - strip-json-comments: "npm:~2.0.1" - bin: - rc: ./cli.js - checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15 - languageName: node - linkType: hard - -"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": - version: 3.6.2 - resolution: "readable-stream@npm:3.6.2" - dependencies: - inherits: "npm:^2.0.3" - string_decoder: "npm:^1.1.1" - util-deprecate: "npm:^1.0.1" - checksum: 10c0/e37be5c79c376fdd088a45fa31ea2e423e5d48854be7a22a58869b4e84d25047b193f6acb54f1012331e1bcd667ffb569c01b99d36b0bd59658fb33f513511b7 - languageName: node - linkType: hard - -"retry@npm:^0.12.0": - version: 0.12.0 - resolution: "retry@npm:0.12.0" - checksum: 10c0/59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe - languageName: node - linkType: hard - -"rimraf@npm:^3.0.2": - version: 3.0.2 - resolution: "rimraf@npm:3.0.2" - dependencies: - glob: "npm:^7.1.3" - bin: - rimraf: bin.js - checksum: 10c0/9cb7757acb489bd83757ba1a274ab545eafd75598a9d817e0c3f8b164238dd90eba50d6b848bd4dcc5f3040912e882dc7ba71653e35af660d77b25c381d402e8 - languageName: node - linkType: hard - -"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": - version: 5.2.1 - resolution: "safe-buffer@npm:5.2.1" - checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 - languageName: node - linkType: hard - -"safer-buffer@npm:>= 2.1.2 < 3.0.0": - version: 2.1.2 - resolution: "safer-buffer@npm:2.1.2" - checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 - languageName: node - linkType: hard - -"semver@npm:^7.3.5": - version: 7.6.3 - resolution: "semver@npm:7.6.3" - bin: - semver: bin/semver.js - checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf - languageName: node - linkType: hard - -"set-blocking@npm:^2.0.0": - version: 2.0.0 - resolution: "set-blocking@npm:2.0.0" - checksum: 10c0/9f8c1b2d800800d0b589de1477c753492de5c1548d4ade52f57f1d1f5e04af5481554d75ce5e5c43d4004b80a3eb714398d6907027dc0534177b7539119f4454 - languageName: node - linkType: hard - -"shebang-command@npm:^2.0.0": - version: 2.0.0 - resolution: "shebang-command@npm:2.0.0" - dependencies: - shebang-regex: "npm:^3.0.0" - checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e - languageName: node - linkType: hard - -"shebang-regex@npm:^3.0.0": - version: 3.0.0 - resolution: "shebang-regex@npm:3.0.0" - checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 - languageName: node - linkType: hard - -"signal-exit@npm:^3.0.7": - version: 3.0.7 - resolution: "signal-exit@npm:3.0.7" - checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 - languageName: node - linkType: hard - -"signal-exit@npm:^4.0.1": - version: 4.1.0 - resolution: "signal-exit@npm:4.1.0" - checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 - languageName: node - linkType: hard - -"simple-concat@npm:^1.0.0": - version: 1.0.1 - resolution: "simple-concat@npm:1.0.1" - checksum: 10c0/62f7508e674414008910b5397c1811941d457dfa0db4fd5aa7fa0409eb02c3609608dfcd7508cace75b3a0bf67a2a77990711e32cd213d2c76f4fd12ee86d776 - languageName: node - linkType: hard - -"simple-get@npm:^4.0.0": - version: 4.0.1 - resolution: "simple-get@npm:4.0.1" - dependencies: - decompress-response: "npm:^6.0.0" - once: "npm:^1.3.1" - simple-concat: "npm:^1.0.0" - checksum: 10c0/b0649a581dbca741babb960423248899203165769747142033479a7dc5e77d7b0fced0253c731cd57cf21e31e4d77c9157c3069f4448d558ebc96cf9e1eebcf0 - languageName: node - linkType: hard - -"smart-buffer@npm:^4.2.0": - version: 4.2.0 - resolution: "smart-buffer@npm:4.2.0" - checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539 - languageName: node - linkType: hard - -"socks-proxy-agent@npm:^6.0.0": - version: 6.2.1 - resolution: "socks-proxy-agent@npm:6.2.1" - dependencies: - agent-base: "npm:^6.0.2" - debug: "npm:^4.3.3" - socks: "npm:^2.6.2" - checksum: 10c0/d75c1cf1fdd7f8309a43a77f84409b793fc0f540742ef915154e70ac09a08b0490576fe85d4f8d68bbf80e604a62957a17ab5ef50d312fe1442b0ab6f8f6e6f6 - languageName: node - linkType: hard - -"socks-proxy-agent@npm:^8.0.3": - version: 8.0.4 - resolution: "socks-proxy-agent@npm:8.0.4" - dependencies: - agent-base: "npm:^7.1.1" - debug: "npm:^4.3.4" - socks: "npm:^2.8.3" - checksum: 10c0/345593bb21b95b0508e63e703c84da11549f0a2657d6b4e3ee3612c312cb3a907eac10e53b23ede3557c6601d63252103494caa306b66560f43af7b98f53957a - languageName: node - linkType: hard - -"socks@npm:^2.6.2, socks@npm:^2.8.3": - version: 2.8.3 - resolution: "socks@npm:2.8.3" - dependencies: - ip-address: "npm:^9.0.5" - smart-buffer: "npm:^4.2.0" - checksum: 10c0/d54a52bf9325165770b674a67241143a3d8b4e4c8884560c4e0e078aace2a728dffc7f70150660f51b85797c4e1a3b82f9b7aa25e0a0ceae1a243365da5c51a7 - languageName: node - linkType: hard - -"sprintf-js@npm:^1.1.3": - version: 1.1.3 - resolution: "sprintf-js@npm:1.1.3" - checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec - languageName: node - linkType: hard - -"sqlite3@npm:^5.1.7": - version: 5.1.7 - resolution: "sqlite3@npm:5.1.7" - dependencies: - bindings: "npm:^1.5.0" - node-addon-api: "npm:^7.0.0" - node-gyp: "npm:8.x" - prebuild-install: "npm:^7.1.1" - tar: "npm:^6.1.11" - peerDependencies: - node-gyp: 8.x - dependenciesMeta: - node-gyp: - optional: true - peerDependenciesMeta: - node-gyp: - optional: true - checksum: 10c0/10daab5d7854bd0ec3c7690c00359cd3444eabc869b68c68dcb61374a8fa5e2f4be06cf0aba78f7a16336d49e83e4631e8af98f8bd33c772fe8d60b45fa60bc1 - languageName: node - linkType: hard - -"ssri@npm:^10.0.0": - version: 10.0.6 - resolution: "ssri@npm:10.0.6" - dependencies: - minipass: "npm:^7.0.3" - checksum: 10c0/e5a1e23a4057a86a97971465418f22ea89bd439ac36ade88812dd920e4e61873e8abd6a9b72a03a67ef50faa00a2daf1ab745c5a15b46d03e0544a0296354227 - languageName: node - linkType: hard - -"ssri@npm:^8.0.0, ssri@npm:^8.0.1": - version: 8.0.1 - resolution: "ssri@npm:8.0.1" - dependencies: - minipass: "npm:^3.1.1" - checksum: 10c0/5cfae216ae02dcd154d1bbed2d0a60038a4b3a2fcaac3c7e47401ff4e058e551ee74cfdba618871bf168cd583db7b8324f94af6747d4303b73cd4c3f6dc5c9c2 - languageName: node - linkType: hard - -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.3": - version: 4.2.3 - resolution: "string-width@npm:4.2.3" - dependencies: - emoji-regex: "npm:^8.0.0" - is-fullwidth-code-point: "npm:^3.0.0" - strip-ansi: "npm:^6.0.1" - checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b - languageName: node - linkType: hard - -"string-width@npm:^5.0.1, string-width@npm:^5.1.2": - version: 5.1.2 - resolution: "string-width@npm:5.1.2" - dependencies: - eastasianwidth: "npm:^0.2.0" - emoji-regex: "npm:^9.2.2" - strip-ansi: "npm:^7.0.1" - checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca - languageName: node - linkType: hard - -"string_decoder@npm:^1.1.1": - version: 1.3.0 - resolution: "string_decoder@npm:1.3.0" - dependencies: - safe-buffer: "npm:~5.2.0" - checksum: 10c0/810614ddb030e271cd591935dcd5956b2410dd079d64ff92a1844d6b7588bf992b3e1b69b0f4d34a3e06e0bd73046ac646b5264c1987b20d0601f81ef35d731d - languageName: node - linkType: hard - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": - version: 6.0.1 - resolution: "strip-ansi@npm:6.0.1" - dependencies: - ansi-regex: "npm:^5.0.1" - checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 - languageName: node - linkType: hard - -"strip-ansi@npm:^7.0.1": - version: 7.1.0 - resolution: "strip-ansi@npm:7.1.0" - dependencies: - ansi-regex: "npm:^6.0.1" - checksum: 10c0/a198c3762e8832505328cbf9e8c8381de14a4fa50a4f9b2160138158ea88c0f5549fb50cb13c651c3088f47e63a108b34622ec18c0499b6c8c3a5ddf6b305ac4 - languageName: node - linkType: hard - -"strip-json-comments@npm:~2.0.1": - version: 2.0.1 - resolution: "strip-json-comments@npm:2.0.1" - checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43 - languageName: node - linkType: hard - -"tar-fs@npm:^2.0.0": - version: 2.1.1 - resolution: "tar-fs@npm:2.1.1" - dependencies: - chownr: "npm:^1.1.1" - mkdirp-classic: "npm:^0.5.2" - pump: "npm:^3.0.0" - tar-stream: "npm:^2.1.4" - checksum: 10c0/871d26a934bfb7beeae4c4d8a09689f530b565f79bd0cf489823ff0efa3705da01278160da10bb006d1a793fa0425cf316cec029b32a9159eacbeaff4965fb6d - languageName: node - linkType: hard - -"tar-stream@npm:^2.1.4": - version: 2.2.0 - resolution: "tar-stream@npm:2.2.0" - dependencies: - bl: "npm:^4.0.3" - end-of-stream: "npm:^1.4.1" - fs-constants: "npm:^1.0.0" - inherits: "npm:^2.0.3" - readable-stream: "npm:^3.1.1" - checksum: 10c0/2f4c910b3ee7196502e1ff015a7ba321ec6ea837667220d7bcb8d0852d51cb04b87f7ae471008a6fb8f5b1a1b5078f62f3a82d30c706f20ada1238ac797e7692 - languageName: node - linkType: hard - -"tar@npm:^6.0.2, tar@npm:^6.1.11, tar@npm:^6.1.2, tar@npm:^6.2.1": - version: 6.2.1 - resolution: "tar@npm:6.2.1" - dependencies: - chownr: "npm:^2.0.0" - fs-minipass: "npm:^2.0.0" - minipass: "npm:^5.0.0" - minizlib: "npm:^2.1.1" - mkdirp: "npm:^1.0.3" - yallist: "npm:^4.0.0" - checksum: 10c0/a5eca3eb50bc11552d453488344e6507156b9193efd7635e98e867fab275d527af53d8866e2370cd09dfe74378a18111622ace35af6a608e5223a7d27fe99537 - languageName: node - linkType: hard - -"tunnel-agent@npm:^0.6.0": - version: 0.6.0 - resolution: "tunnel-agent@npm:0.6.0" - dependencies: - safe-buffer: "npm:^5.0.1" - checksum: 10c0/4c7a1b813e7beae66fdbf567a65ec6d46313643753d0beefb3c7973d66fcec3a1e7f39759f0a0b4465883499c6dc8b0750ab8b287399af2e583823e40410a17a - languageName: node - linkType: hard - -"unique-filename@npm:^1.1.1": - version: 1.1.1 - resolution: "unique-filename@npm:1.1.1" - dependencies: - unique-slug: "npm:^2.0.0" - checksum: 10c0/d005bdfaae6894da8407c4de2b52f38b3c58ec86e79fc2ee19939da3085374413b073478ec54e721dc8e32b102cf9e50d0481b8331abdc62202e774b789ea874 - languageName: node - linkType: hard - -"unique-filename@npm:^3.0.0": - version: 3.0.0 - resolution: "unique-filename@npm:3.0.0" - dependencies: - unique-slug: "npm:^4.0.0" - checksum: 10c0/6363e40b2fa758eb5ec5e21b3c7fb83e5da8dcfbd866cc0c199d5534c42f03b9ea9ab069769cc388e1d7ab93b4eeef28ef506ab5f18d910ef29617715101884f - languageName: node - linkType: hard - -"unique-slug@npm:^2.0.0": - version: 2.0.2 - resolution: "unique-slug@npm:2.0.2" - dependencies: - imurmurhash: "npm:^0.1.4" - checksum: 10c0/9eabc51680cf0b8b197811a48857e41f1364b25362300c1ff636c0eca5ec543a92a38786f59cf0697e62c6f814b11ecbe64e8093db71246468a1f03b80c83970 - languageName: node - linkType: hard - -"unique-slug@npm:^4.0.0": - version: 4.0.0 - resolution: "unique-slug@npm:4.0.0" - dependencies: - imurmurhash: "npm:^0.1.4" - checksum: 10c0/cb811d9d54eb5821b81b18205750be84cb015c20a4a44280794e915f5a0a70223ce39066781a354e872df3572e8155c228f43ff0cce94c7cbf4da2cc7cbdd635 - languageName: node - linkType: hard - -"util-deprecate@npm:^1.0.1": - version: 1.0.2 - resolution: "util-deprecate@npm:1.0.2" - checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 - languageName: node - linkType: hard - -"which@npm:^2.0.1, which@npm:^2.0.2": - version: 2.0.2 - resolution: "which@npm:2.0.2" - dependencies: - isexe: "npm:^2.0.0" - bin: - node-which: ./bin/node-which - checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f - languageName: node - linkType: hard - -"which@npm:^4.0.0": - version: 4.0.0 - resolution: "which@npm:4.0.0" - dependencies: - isexe: "npm:^3.1.1" - bin: - node-which: bin/which.js - checksum: 10c0/449fa5c44ed120ccecfe18c433296a4978a7583bf2391c50abce13f76878d2476defde04d0f79db8165bdf432853c1f8389d0485ca6e8ebce3bbcded513d5e6a - languageName: node - linkType: hard - -"wide-align@npm:^1.1.5": - version: 1.1.5 - resolution: "wide-align@npm:1.1.5" - dependencies: - string-width: "npm:^1.0.2 || 2 || 3 || 4" - checksum: 10c0/1d9c2a3e36dfb09832f38e2e699c367ef190f96b82c71f809bc0822c306f5379df87bab47bed27ea99106d86447e50eb972d3c516c2f95782807a9d082fbea95 - languageName: node - linkType: hard - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version: 7.0.0 - resolution: "wrap-ansi@npm:7.0.0" - dependencies: - ansi-styles: "npm:^4.0.0" - string-width: "npm:^4.1.0" - strip-ansi: "npm:^6.0.0" - checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da - languageName: node - linkType: hard - -"wrap-ansi@npm:^8.1.0": - version: 8.1.0 - resolution: "wrap-ansi@npm:8.1.0" + "@gar/promisify" "^1.0.1" + semver "^7.3.5" + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== dependencies: - ansi-styles: "npm:^6.1.0" - string-width: "npm:^5.0.1" - strip-ansi: "npm:^7.0.1" - checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 - languageName: node - linkType: hard - -"wrappy@npm:1": - version: 1.0.2 - resolution: "wrappy@npm:1.0.2" - checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 - languageName: node - linkType: hard - -"yallist@npm:^4.0.0": - version: 4.0.0 - resolution: "yallist@npm:4.0.0" - checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a - languageName: node - linkType: hard + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +abbrev@1: + version "1.1.1" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +agent-base@^6.0.2, agent-base@6: + version "6.0.2" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@^4.1.3: + version "4.6.0" + resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz" + integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== + dependencies: + humanize-ms "^1.2.1" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +"aproba@^1.0.3 || ^2.0.0": + 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== + +are-we-there-yet@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz" + integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +cacache@^15.2.0: + version "15.3.0" + resolved "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz" + integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== + dependencies: + "@npmcli/fs" "^1.0.0" + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +color-support@^1.1.3: + 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== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + +csv-parser@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/csv-parser/-/csv-parser-3.2.0.tgz" + integrity sha512-fgKbp+AJbn1h2dcAHKIdKNSSjfp43BZZykXsCjzALjKy80VXQNHPFJ6T9Afwdzoj24aMkq8GwDS7KGcDPpejrA== + +debug@^4.3.3, debug@4: + version "4.4.0" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + +detect-libc@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + +expand-template@^2.0.3: + 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== + +file-uri-to-path@1.0.0: + 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== + +fs-constants@^1.0.0: + 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== + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + +github-from-package@0.0.0: + 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== + +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.2.6: + version "4.2.11" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + +http-cache-semantics@^4.1.0: + version "4.1.1" + resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + 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== + dependencies: + agent-base "6" + debug "4" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@^2.0.3, inherits@^2.0.4, inherits@2: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +ip-address@^9.0.5: + version "9.0.5" + resolved "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz" + integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== + dependencies: + jsbn "1.1.0" + sprintf-js "^1.1.3" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz" + integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-fetch-happen@^9.1.0: + version "9.1.0" + resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz" + integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.2.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.2" + promise-retry "^2.0.1" + socks-proxy-agent "^6.0.0" + ssri "^8.0.0" + +mimic-response@^3.1.0: + 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== + +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3: + version "1.2.8" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^1.3.2: + version "1.4.1" + resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz" + integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: + version "3.3.6" + resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +minizlib@^2.0.0, minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mkdirp@^1.0.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ms@^2.0.0, ms@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +napi-build-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz" + integrity sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA== + +negotiator@^0.6.2: + version "0.6.4" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== + +node-abi@^3.3.0: + version "3.74.0" + resolved "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz" + integrity sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w== + dependencies: + semver "^7.3.5" + +node-addon-api@^7.0.0: + version "7.1.1" + resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz" + integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ== + +node-gyp@8.x: + version "8.4.1" + resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz" + integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^9.1.0" + nopt "^5.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + +npmlog@^6.0.0: + version "6.0.2" + resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +prebuild-install@^7.1.1: + version "7.1.3" + resolved "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz" + integrity sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug== + 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 "^2.0.0" + 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" + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + +pump@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz" + integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: + 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" + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@^5.0.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^7.3.5: + version "7.7.1" + resolved "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz" + integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socks-proxy-agent@^6.0.0: + version "6.2.1" + resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz" + integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks@^2.6.2: + version "2.8.4" + resolved "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz" + integrity sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ== + dependencies: + ip-address "^9.0.5" + smart-buffer "^4.2.0" + +sprintf-js@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + +sqlite3@^5.1.7: + version "5.1.7" + resolved "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz" + integrity sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog== + dependencies: + bindings "^1.5.0" + node-addon-api "^7.0.0" + prebuild-install "^7.1.1" + tar "^6.1.11" + optionalDependencies: + node-gyp "8.x" + +ssri@^8.0.0, ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + +tar-fs@^2.0.0: + version "2.1.2" + resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz" + integrity sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + 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" + +tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: + version "6.2.1" + resolved "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +which@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/resources/scripts/install-node.js b/resources/scripts/install-node.js new file mode 100644 index 0000000000..7ddf7579ef --- /dev/null +++ b/resources/scripts/install-node.js @@ -0,0 +1,314 @@ +const fs = require('fs') +const path = require('path') +const os = require('os') +const https = require('https') +const { execSync } = require('child_process') + +// 配置 +const NODE_VERSION = process.env.NODE_VERSION || '18.18.0' // 默认版本 +const NODE_RELEASE_BASE_URL = 'https://nodejs.org/dist' + +// 平台映射 +const NODE_PACKAGES = { + 'darwin-arm64': `node-v${NODE_VERSION}-darwin-arm64.tar.gz`, + 'darwin-x64': `node-v${NODE_VERSION}-darwin-x64.tar.gz`, + 'win32-x64': `node-v${NODE_VERSION}-win32-x64.zip`, + 'win32-ia32': `node-v${NODE_VERSION}-win32-x86.zip`, + 'linux-x64': `node-v${NODE_VERSION}-linux-x64.tar.gz`, + 'linux-arm64': `node-v${NODE_VERSION}-linux-arm64.tar.gz`, +} + +// 辅助函数 - 递归复制目录 +function copyFolderRecursiveSync(source, target) { + // 检查目标目录是否存在,不存在则创建 + if (!fs.existsSync(target)) { + fs.mkdirSync(target, { recursive: true }); + } + + // 读取源目录中的所有文件和文件夹 + const files = fs.readdirSync(source); + + // 循环处理每个文件/文件夹 + for (const file of files) { + const sourcePath = path.join(source, file); + const targetPath = path.join(target, file); + + // 检查是文件还是文件夹 + if (fs.statSync(sourcePath).isDirectory()) { + // 如果是文件夹,递归复制 + copyFolderRecursiveSync(sourcePath, targetPath); + } else { + // 如果是文件,直接复制 + fs.copyFileSync(sourcePath, targetPath); + } + } +} + +// 二进制文件存放目录 +const binariesDir = path.join(os.homedir(), '.cherrystudio', 'bin') + +// 创建二进制文件存放目录 +async function createBinariesDir() { + if (!fs.existsSync(binariesDir)) { + console.log(`Creating binaries directory at ${binariesDir}`) + fs.mkdirSync(binariesDir, { recursive: true }) + } +} + +// 获取当前平台对应的包名 +function getPackageForPlatform() { + const platform = os.platform() + const arch = os.arch() + const key = `${platform}-${arch}` + + console.log(`Current platform: ${platform}, architecture: ${arch}`) + + if (!NODE_PACKAGES[key]) { + throw new Error(`Unsupported platform/architecture: ${key}`) + } + + return NODE_PACKAGES[key] +} + +// 下载 Node.js +async function downloadNodeJs() { + const packageName = getPackageForPlatform() + const downloadUrl = `${NODE_RELEASE_BASE_URL}/v${NODE_VERSION}/${packageName}` + const tempFilePath = path.join(os.tmpdir(), packageName) + + console.log(`Downloading Node.js v${NODE_VERSION} from ${downloadUrl}`) + console.log(`Temp file path: ${tempFilePath}`) + + // 如果临时文件已存在,先删除 + if (fs.existsSync(tempFilePath)) { + fs.unlinkSync(tempFilePath) + } + + return new Promise((resolve, reject) => { + const file = fs.createWriteStream(tempFilePath) + + https.get(downloadUrl, (response) => { + if (response.statusCode !== 200) { + reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`)) + return + } + + console.log(`Download started, status code: ${response.statusCode}`) + + response.pipe(file) + + file.on('finish', () => { + file.close() + console.log('Download completed') + resolve(tempFilePath) + }) + + file.on('error', (err) => { + fs.unlinkSync(tempFilePath) + reject(err) + }) + }).on('error', (err) => { + if (fs.existsSync(tempFilePath)) { + fs.unlinkSync(tempFilePath) + } + reject(err) + }) + }) +} + +// 解压 Node.js 包 +async function extractNodeJs(filePath) { + const platform = os.platform() + const extractDir = path.join(os.tmpdir(), `node-v${NODE_VERSION}-extract`) + + if (fs.existsSync(extractDir)) { + console.log(`Removing existing extract directory: ${extractDir}`) + fs.rmSync(extractDir, { recursive: true, force: true }) + } + + console.log(`Creating extract directory: ${extractDir}`) + fs.mkdirSync(extractDir, { recursive: true }) + + console.log(`Extracting to ${extractDir}`) + + if (platform === 'win32') { + // Windows 使用内置的解压工具 + try { + const AdmZip = require('adm-zip') + console.log(`Using adm-zip to extract ${filePath}`) + const zip = new AdmZip(filePath) + zip.extractAllTo(extractDir, true) + console.log(`Extraction completed using adm-zip`) + } catch (error) { + console.error(`Error using adm-zip: ${error}`) + throw error + } + } else { + // Linux/Mac 使用 tar + try { + console.log(`Using tar to extract ${filePath} to ${extractDir}`) + execSync(`tar -xzf "${filePath}" -C "${extractDir}"`, { stdio: 'inherit' }) + console.log(`Extraction completed using tar`) + } catch (error) { + console.error(`Error using tar: ${error}`) + throw error + } + } + + return extractDir +} + +// 安装 Node.js +async function installNodeJs(extractDir) { + const platform = os.platform() + console.log(`Finding extracted Node.js directory in ${extractDir}`) + + const items = fs.readdirSync(extractDir) + console.log(`Found items in extract directory: ${items.join(', ')}`) + + // 找到包含"node-v"的目录名 + const folderName = items.find(item => item.startsWith('node-v')) + + if (!folderName) { + throw new Error(`Could not find Node.js directory in ${extractDir}`) + } + + console.log(`Found Node.js directory: ${folderName}`) + const nodeBinPath = path.join(extractDir, folderName, 'bin') + + console.log(`Node.js bin path: ${nodeBinPath}`) + + // 复制 node 和 npm + if (platform === 'win32') { + // Windows + console.log('Installing Node.js binaries for Windows') + fs.copyFileSync( + path.join(extractDir, folderName, 'node.exe'), + path.join(binariesDir, 'node.exe') + ) + console.log(`Copied node.exe to ${path.join(binariesDir, 'node.exe')}`) + + fs.copyFileSync( + path.join(extractDir, folderName, 'npm.cmd'), + path.join(binariesDir, 'npm.cmd') + ) + console.log(`Copied npm.cmd to ${path.join(binariesDir, 'npm.cmd')}`) + + fs.copyFileSync( + path.join(extractDir, folderName, 'npx.cmd'), + path.join(binariesDir, 'npx.cmd') + ) + console.log(`Copied npx.cmd to ${path.join(binariesDir, 'npx.cmd')}`) + } else { + // Linux/Mac + console.log('Installing Node.js binaries for Linux/Mac') + fs.copyFileSync( + path.join(nodeBinPath, 'node'), + path.join(binariesDir, 'node') + ) + console.log(`Copied node to ${path.join(binariesDir, 'node')}`) + + // 创建npm脚本,指向正确路径 + const npmScript = `#!/usr/bin/env node +require("./node_modules/npm/lib/cli.js")(process)`; + fs.writeFileSync(path.join(binariesDir, 'npm'), npmScript); + console.log(`Created npm script at ${path.join(binariesDir, 'npm')}`); + + // 创建npx脚本,指向正确路径 + const npxScript = `#!/usr/bin/env node +require("./node_modules/npm/bin/npx-cli.js")`; + fs.writeFileSync(path.join(binariesDir, 'npx'), npxScript); + console.log(`Created npx script at ${path.join(binariesDir, 'npx')}`); + + // 设置执行权限 + execSync(`chmod +x "${path.join(binariesDir, 'node')}"`) + execSync(`chmod +x "${path.join(binariesDir, 'npm')}"`) + execSync(`chmod +x "${path.join(binariesDir, 'npx')}"`) + console.log('Set executable permissions for Node.js binaries') + } + + // 复制 npm 相关文件和目录 + const npmDir = path.join(binariesDir, 'node_modules', 'npm') + fs.mkdirSync(npmDir, { recursive: true }) + console.log(`Created npm directory at ${npmDir}`) + + // 复制 npm 目录的内容 + const srcNpmDir = path.join(extractDir, folderName, 'lib', 'node_modules', 'npm') + console.log(`Copying npm files from ${srcNpmDir} to ${npmDir}`) + + const files = fs.readdirSync(srcNpmDir) + + for (const file of files) { + const srcPath = path.join(srcNpmDir, file) + const destPath = path.join(npmDir, file) + + if (fs.lstatSync(srcPath).isDirectory()) { + // 使用自定义函数代替fs.cpSync,确保兼容性 + console.log(`Copying directory: ${file}`) + copyFolderRecursiveSync(srcPath, destPath) + } else { + console.log(`Copying file: ${file}`) + fs.copyFileSync(srcPath, destPath) + } + } + + console.log('Node.js installation completed successfully') +} + +// 清理临时文件 +async function cleanup(filePath, extractDir) { + try { + if (fs.existsSync(filePath)) { + console.log(`Cleaning up temp file: ${filePath}`) + fs.unlinkSync(filePath) + } + + if (fs.existsSync(extractDir)) { + console.log(`Cleaning up extract directory: ${extractDir}`) + fs.rmSync(extractDir, { recursive: true, force: true }) + } + + console.log('Cleaned up temporary files') + } catch (error) { + console.error('Error during cleanup:', error) + } +} + +// 主安装函数 +async function install() { + try { + console.log(`Starting Node.js v${NODE_VERSION} installation...`) + + await createBinariesDir() + console.log('Binary directory created/verified') + + const filePath = await downloadNodeJs() + console.log(`Downloaded Node.js to ${filePath}`) + + const extractDir = await extractNodeJs(filePath) + console.log(`Extracted Node.js to ${extractDir}`) + + await installNodeJs(extractDir) + console.log('Installed Node.js binaries') + + await cleanup(filePath, extractDir) + console.log('Cleanup completed') + + console.log(`Node.js v${NODE_VERSION} has been installed successfully at ${binariesDir}`) + return true + } catch (error) { + console.error('Installation failed:', error) + throw error + } +} + +// 执行安装 +install() + .then(() => { + console.log('Installation process completed successfully') + process.exit(0) + }) + .catch((error) => { + console.error('Fatal error during installation:', error) + process.exit(1) + }) diff --git a/src/@types/index.d.ts b/src/@types/index.d.ts new file mode 100644 index 0000000000..224d56d229 --- /dev/null +++ b/src/@types/index.d.ts @@ -0,0 +1,16 @@ +export interface NodeAppType { + id: string + name: string + type: string + description?: string + author?: string + homepage?: string + repositoryUrl?: string + port?: number + installCommand?: string + buildCommand?: string + startCommand?: string + isInstalled: boolean + isRunning: boolean + url?: string +} diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 0c7d23e784..3eca63c014 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -24,6 +24,7 @@ import { getResourcePath } from './utils' import { decrypt, encrypt } from './utils/aes' import { getFilesDir } from './utils/file' import { compress, decompress } from './utils/zip' +import NodeAppService from './services/NodeAppService' const fileManager = new FileStorage() const backupManager = new BackupManager() @@ -243,6 +244,17 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { ipcMain.handle('mcp:cleanup', async () => mcpService.cleanup()) + // Shell API + ipcMain.handle('shell:openExternal', async (_, url: string) => { + try { + log.info(`Opening external URL: ${url}`) + return await shell.openExternal(url) + } catch (error) { + log.error('Error opening external URL:', error) + throw error + } + }) + ipcMain.handle('app:is-binary-exist', (_, name: string) => isBinaryExists(name)) ipcMain.handle('app:get-binary-path', (_, name: string) => getBinaryPath(name)) ipcMain.handle('app:install-uv-binary', () => runInstallScript('install-uv.js')) @@ -262,4 +274,53 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { ipcMain.handle('copilot:get-token', CopilotService.getToken) ipcMain.handle('copilot:logout', CopilotService.logout) ipcMain.handle('copilot:get-user', CopilotService.getUser) + + // Node app management + const nodeAppService = NodeAppService.getInstance() + + ipcMain.handle('nodeapp:list', async () => await nodeAppService.getAllApps()) + + ipcMain.handle('nodeapp:add', async (_, app) => await nodeAppService.addApp(app)) + + ipcMain.handle('nodeapp:install', async (_, appId) => await nodeAppService.installApp(appId)) + + ipcMain.handle('nodeapp:update', async (_, appId) => await nodeAppService.updateApp(appId)) + + ipcMain.handle('nodeapp:start', async (_, appId) => await nodeAppService.startApp(appId)) + + ipcMain.handle('nodeapp:stop', async (_, appId) => await nodeAppService.stopApp(appId)) + + ipcMain.handle('nodeapp:uninstall', async (_, appId) => await nodeAppService.uninstallApp(appId)) + + ipcMain.handle('nodeapp:deploy-zip', async (_, zipPath, options) => await nodeAppService.deployFromZip(zipPath, options)) + + ipcMain.handle('nodeapp:deploy-git', async (_, repoUrl, options) => await nodeAppService.deployFromGit(repoUrl, options)) + + ipcMain.handle('nodeapp:check-node', async () => { + const isNodeInstalled = await isBinaryExists('node') + return isNodeInstalled + }) + + ipcMain.handle('nodeapp:install-node', async () => { + return await nodeAppService.installNodeJs() + }) + + // Listen for changes in Node.js apps and notify renderer + nodeAppService.on('apps-updated', (apps) => { + mainWindow?.webContents.send('nodeapp:updated', apps) + }) + + app.on('before-quit', () => nodeAppService.cleanup()) + + // 运行简单命令 + ipcMain.handle('app:run-command', async (_, command: string) => { + try { + const { execSync } = require('child_process') + const result = execSync(command).toString() + return result + } catch (error) { + log.error('Error running command:', error) + throw error + } + }) } diff --git a/src/main/services/NodeAppService.ts b/src/main/services/NodeAppService.ts new file mode 100644 index 0000000000..a7631612fb --- /dev/null +++ b/src/main/services/NodeAppService.ts @@ -0,0 +1,1351 @@ +import { exec, spawn } from 'child_process' +import log from 'electron-log' +import { app } from 'electron' +import fs from 'fs-extra' +import os from 'os' +import path from 'path' +import { promisify } from 'util' +import { v4 as uuidv4 } from 'uuid' +import { EventEmitter } from 'events' +import { NodeAppType } from '@types' +import { getBinaryPath, isBinaryExists, runInstallScript } from '@main/utils/process' +import { getResourcePath } from '@main/utils' +import { configManager } from './ConfigManager' + +const execAsync = promisify(exec) + +/** + * Service for managing Node.js applications in Cherry Studio + */ +export default class NodeAppService extends EventEmitter { + private static instance: NodeAppService | null = null + private nodeApps: NodeAppType[] = [] + private runningApps: Map = new Map() + private appsDir: string + private initialized = false + private nodePath: string = 'node' + private npmPath: string = 'npm' + private hasInternalNode: boolean = false + + constructor() { + super() + this.appsDir = path.join(app.getPath('userData'), 'node-apps') + this.ensureAppDirectory() + this.initializeNodeEnvironment() + } + + /** + * Get the singleton instance of NodeAppService + */ + public static getInstance(): NodeAppService { + if (!NodeAppService.instance) { + NodeAppService.instance = new NodeAppService() + } + return NodeAppService.instance + } + + /** + * Ensure the apps directory exists + */ + private ensureAppDirectory(): void { + try { + fs.ensureDirSync(this.appsDir) + log.info(`[NodeAppService] Apps directory exists at: ${this.appsDir}`) + } catch (err) { + log.error('[NodeAppService] Failed to create apps directory:', err) + } + } + + /** + * Initialize the service + */ + public async init(): Promise { + if (this.initialized) return + + try { + log.info('[NodeAppService] Initializing...') + + // Load installed apps + await this.loadInstalledApps() + + this.initialized = true + log.info('[NodeAppService] Initialization complete') + } catch (err) { + log.error('[NodeAppService] Initialization failed:', err) + throw err + } + } + + /** + * Load all installed Node.js apps + */ + private async loadInstalledApps(): Promise { + try { + const appDirs = await fs.readdir(this.appsDir) + + const loadPromises = appDirs.map(async (dirName) => { + const appDir = path.join(this.appsDir, dirName) + const stats = await fs.stat(appDir) + + if (stats.isDirectory()) { + const metadataPath = path.join(appDir, 'metadata.json') + + if (await fs.pathExists(metadataPath)) { + const metadata = await fs.readJson(metadataPath) + return { + ...metadata, + isInstalled: true, + isRunning: this.runningApps.has(metadata.id) + } as NodeAppType + } + } + return null + }) + + const loadedApps = (await Promise.all(loadPromises)).filter(Boolean) as NodeAppType[] + this.nodeApps = loadedApps + + log.info(`[NodeAppService] Loaded ${loadedApps.length} installed apps`) + } catch (err) { + log.error('[NodeAppService] Failed to load installed apps:', err) + throw err + } + } + + /** + * Get all registered Node.js apps + */ + public async getAllApps(): Promise { + if (!this.initialized) { + await this.init() + } + return this.nodeApps + } + + /** + * Add a new Node.js app from repository + */ + public async addApp(app: NodeAppType): Promise { + if (!this.initialized) { + await this.init() + } + + // Generate ID if not provided + const newApp: NodeAppType = { + ...app, + id: app.id || uuidv4(), + isInstalled: false, + isRunning: false + } + + // Add to the list + this.nodeApps.push(newApp) + + // Notify of change + this.emit('apps-updated', this.nodeApps) + + return newApp + } + + /** + * Install a Node.js app from repository + */ + public async installApp(appId: string): Promise { + if (!this.initialized) { + await this.init() + } + + const app = this.nodeApps.find(app => app.id === appId) + if (!app || !app.repositoryUrl) { + log.error(`[NodeAppService] App with ID ${appId} not found or missing repository URL`) + return null + } + + try { + log.info(`[NodeAppService] Installing app ${app.name} from ${app.repositoryUrl}`) + + // Create app directory + const appDir = path.join(this.appsDir, appId.toString()) + await fs.ensureDir(appDir) + + // Clone repository + await execAsync(`git clone ${app.repositoryUrl} "${appDir}"`) + + // Run install command if specified, otherwise use default npm install + const installCommand = app.installCommand || 'npm install' + await execAsync(installCommand, { cwd: appDir }) + + // Save metadata + const metadata: NodeAppType = { + ...app, + isInstalled: true, + isRunning: false + } + + await fs.writeJson(path.join(appDir, 'metadata.json'), metadata, { spaces: 2 }) + + // Update app in the list + const appIndex = this.nodeApps.findIndex(a => a.id === appId) + if (appIndex !== -1) { + this.nodeApps[appIndex] = metadata + } + + // Notify of change + this.emit('apps-updated', this.nodeApps) + + log.info(`[NodeAppService] Successfully installed app ${app.name}`) + return metadata + } catch (err) { + log.error(`[NodeAppService] Failed to install app ${app.name}:`, err) + // Clean up failed installation + try { + const appDir = path.join(this.appsDir, appId.toString()) + await fs.remove(appDir) + } catch (cleanupErr) { + log.error('[NodeAppService] Failed to clean up after installation error:', cleanupErr) + } + throw err + } + } + + /** + * Update an existing app + */ + public async updateApp(appId: string): Promise { + if (!this.initialized) { + await this.init() + } + + const app = this.nodeApps.find(app => app.id === appId) + if (!app || !app.isInstalled) { + log.error(`[NodeAppService] App with ID ${appId} not found or not installed`) + return null + } + + try { + log.info(`[NodeAppService] Updating app ${app.name}`) + + const appDir = path.join(this.appsDir, appId.toString()) + + // Pull latest changes + await execAsync('git pull', { cwd: appDir }) + + // Update dependencies + const installCommand = app.installCommand || 'npm install' + await execAsync(installCommand, { cwd: appDir }) + + log.info(`[NodeAppService] Successfully updated app ${app.name}`) + return app + } catch (err) { + log.error(`[NodeAppService] Failed to update app ${app.name}:`, err) + throw err + } + } + + /** + * Start a Node.js app + */ + public async startApp(appId: string): Promise<{ port: number; url: string } | null> { + if (!this.initialized) { + await this.init() + } + + const app = this.nodeApps.find(app => app.id === appId) + if (!app || !app.isInstalled) { + log.error(`[NodeAppService] App with ID ${appId} not found or not installed`) + return null + } + + if (this.runningApps.has(appId)) { + log.warn(`[NodeAppService] App ${app.name} is already running`) + const existingApp = this.runningApps.get(appId) + return { + port: existingApp.port, + url: `http://localhost:${existingApp.port}` + } + } + + try { + log.info(`[NodeAppService] Starting app ${app.name}`) + + const appDir = path.join(this.appsDir, appId.toString()) + + // Determine port to use + const port = app.port || await this.findAvailablePort(3000) + + // Set environment variables for the app + const env: any = { + ...process.env, + PORT: port.toString(), + NODE_ENV: 'production' + } + + // Start command (default to npm start if not specified) + const startCommand = app.startCommand || 'npm start' + const [cmd, ...args] = startCommand.split(' ') + + // Start the process + const childProcess = spawn(cmd, args, { + cwd: appDir, + env, + shell: true + }) + + // Log output + childProcess.stdout.on('data', (data) => { + log.info(`[${app.name}] ${data.toString().trim()}`) + }) + + childProcess.stderr.on('data', (data) => { + log.error(`[${app.name}] ${data.toString().trim()}`) + }) + + // Handle process exit + childProcess.on('close', (code) => { + log.info(`[NodeAppService] App ${app.name} exited with code ${code}`) + this.runningApps.delete(appId) + + // Update the app status + const appIndex = this.nodeApps.findIndex(a => a.id === appId) + if (appIndex !== -1) { + this.nodeApps[appIndex] = { + ...this.nodeApps[appIndex], + isRunning: false + } + } + + this.emit('apps-updated', this.nodeApps) + }) + + // Store the running app information + this.runningApps.set(appId, { + process: childProcess, + port + }) + + // Update the app status + const appIndex = this.nodeApps.findIndex(a => a.id === appId) + if (appIndex !== -1) { + this.nodeApps[appIndex] = { + ...this.nodeApps[appIndex], + isRunning: true + } + } + + // Notify of status change + this.emit('apps-updated', this.nodeApps) + + // Wait for app to start by checking the port + await this.waitForPortToBeReady(port, 30) + + log.info(`[NodeAppService] App ${app.name} started on port ${port}`) + return { + port, + url: `http://localhost:${port}` + } + } catch (err) { + log.error(`[NodeAppService] Failed to start app ${app.name}:`, err) + + // Clean up if process was started + if (this.runningApps.has(appId)) { + const runningApp = this.runningApps.get(appId) + if (runningApp.process) { + runningApp.process.kill() + } + this.runningApps.delete(appId) + } + + throw err + } + } + + /** + * Stop a running Node.js app + */ + public async stopApp(appId: string): Promise { + if (!this.initialized) { + await this.init() + } + + const app = this.nodeApps.find(app => app.id === appId) + if (!app) { + log.error(`[NodeAppService] App with ID ${appId} not found`) + return false + } + + if (!this.runningApps.has(appId)) { + log.warn(`[NodeAppService] App ${app.name} is not running`) + return false + } + + try { + log.info(`[NodeAppService] Stopping app ${app.name}`) + + const runningApp = this.runningApps.get(appId) + + if (runningApp && runningApp.process) { + // Kill the process + runningApp.process.kill() + this.runningApps.delete(appId) + + // Update the app status + const appIndex = this.nodeApps.findIndex(a => a.id === appId) + if (appIndex !== -1) { + this.nodeApps[appIndex] = { + ...this.nodeApps[appIndex], + isRunning: false + } + } + + // Notify of status change + this.emit('apps-updated', this.nodeApps) + + log.info(`[NodeAppService] Successfully stopped app ${app.name}`) + return true + } + + return false + } catch (err) { + log.error(`[NodeAppService] Failed to stop app ${app.name}:`, err) + throw err + } + } + + /** + * Uninstall a Node.js app + */ + public async uninstallApp(appId: string): Promise { + if (!this.initialized) { + await this.init() + } + + const app = this.nodeApps.find(app => app.id === appId) + if (!app || !app.isInstalled) { + log.error(`[NodeAppService] App with ID ${appId} not found or not installed`) + return false + } + + try { + log.info(`[NodeAppService] Uninstalling app ${app.name}`) + + // Stop the app if it's running + if (app.isRunning) { + await this.stopApp(appId) + } + + // Remove the app directory + const appDir = path.join(this.appsDir, appId.toString()) + await fs.remove(appDir) + + // Update the app in the list or remove it + const appIndex = this.nodeApps.findIndex(a => a.id === appId) + if (appIndex !== -1) { + this.nodeApps.splice(appIndex, 1) + } + + // Notify of change + this.emit('apps-updated', this.nodeApps) + + log.info(`[NodeAppService] Successfully uninstalled app ${app.name}`) + return true + } catch (err) { + log.error(`[NodeAppService] Failed to uninstall app ${app.name}:`, err) + throw err + } + } + + /** + * Find an available port starting from the given port + */ + private async findAvailablePort(startPort: number): Promise { + const isPortAvailable = async (port: number): Promise => { + return new Promise((resolve) => { + const net = require('net') + const server = net.createServer() + + server.once('error', () => { + resolve(false) + }) + + server.once('listening', () => { + server.close() + resolve(true) + }) + + server.listen(port) + }) + } + + let port = startPort + while (!(await isPortAvailable(port))) { + port++ + } + + return port + } + + /** + * Wait for a port to be ready (app to start) + */ + private waitForPortToBeReady(port: number, maxAttempts = 30): Promise { + return new Promise((resolve, reject) => { + const checkPort = async (attemptsLeft: number) => { + if (attemptsLeft <= 0) { + return reject(new Error(`Timeout waiting for port ${port} to be ready`)) + } + + try { + const net = require('net') + const socket = new net.Socket() + + const onError = () => { + socket.destroy() + setTimeout(() => checkPort(attemptsLeft - 1), 500) + } + + socket.once('error', onError) + socket.once('connect', () => { + socket.destroy() + resolve() + }) + + socket.connect(port, '127.0.0.1') + } catch (err) { + setTimeout(() => checkPort(attemptsLeft - 1), 500) + } + } + + checkPort(maxAttempts) + }) + } + + /** + * Clean up all running apps when shutting down + */ + public async cleanup(): Promise { + log.info('[NodeAppService] Cleaning up running apps') + + const stopPromises = Array.from(this.runningApps.keys()).map(appId => + this.stopApp(appId).catch(err => { + log.error(`[NodeAppService] Error stopping app ${appId} during cleanup:`, err) + }) + ) + + await Promise.all(stopPromises) + + log.info('[NodeAppService] Cleanup complete') + } + + /** + * Deploy a Node.js app from a ZIP file + * @param zipFile Path to the ZIP file containing Node.js app code + * @param options Optional configuration for the app + */ + public async deployFromZip(zipFile: string, options?: { + name?: string; + port?: number; + startCommand?: string; + installCommand?: string; + buildCommand?: string; + }): Promise<{ port: number; url: string } | null> { + try { + log.info(`[NodeAppService] Deploying app from ZIP file: ${zipFile}`) + + // Generate a unique app ID + const appId = `app-${Date.now()}` + const appName = options?.name || `App-${appId}` + + // Create app directory + const appDir = path.join(this.appsDir, appId) + await fs.ensureDir(appDir) + + // Extract ZIP content + const extract = require('extract-zip') + await new Promise((resolve, reject) => { + extract(zipFile, { dir: appDir }, (err) => { + if (err) { + reject(err) + } else { + resolve(null) + } + }) + }) + + log.info(`[NodeAppService] Extracted ZIP to ${appDir}`) + + // Check if the ZIP contains a single top-level directory (common in GitHub downloads) + const items = await fs.readdir(appDir) + if (items.length === 1) { + const firstItem = path.join(appDir, items[0]) + const stats = await fs.stat(firstItem) + + if (stats.isDirectory()) { + log.info(`[NodeAppService] ZIP contains a single top-level directory: ${items[0]}`) + + // Move all contents from the subdirectory to the app directory + const subDirContents = await fs.readdir(firstItem) + + for (const item of subDirContents) { + const sourcePath = path.join(firstItem, item) + const destPath = path.join(appDir, item) + await fs.move(sourcePath, destPath) + } + + // Remove the now-empty directory + await fs.remove(firstItem) + + log.info(`[NodeAppService] Moved contents from subdirectory to root app directory`) + } + } + + // Check if package.json exists, if not create a simple one + const packageJsonPath = path.join(appDir, 'package.json') + let packageJson: any; + + if (!await fs.pathExists(packageJsonPath)) { + packageJson = { + name: appName.toLowerCase().replace(/\s+/g, '-'), + version: '1.0.0', + description: 'Deployed Node.js app', + main: 'index.js', + scripts: { + start: 'node index.js' + } + } + + await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 }) + log.info(`[NodeAppService] Created package.json as it was missing`) + } else { + // Load existing package.json + packageJson = await fs.readJson(packageJsonPath); + + // Check and fix potential ES modules issues + try { + // If we find any .js files using ES module syntax but package.json doesn't have type: "module", + // add it to help prevent ES module errors + const jsFiles = await this.findJavaScriptFiles(appDir) + for (const file of jsFiles) { + const content = await fs.readFile(file, 'utf8') + if (content.includes('export default') || content.includes('import ') && !content.includes('require(')) { + // This file appears to use ES module syntax + if (!packageJson.type) { + packageJson.type = "module" + await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 }) + log.info(`[NodeAppService] Added "type": "module" to package.json to support ES modules`) + break + } + } + } + } catch (error) { + log.warn(`[NodeAppService] Error checking for ES modules compatibility: ${error}`) + } + + // Check for Next.js and ensure start script is correct if needed + if (packageJson.dependencies && (packageJson.dependencies.next || packageJson.devDependencies?.next)) { + log.info(`[NodeAppService] Detected Next.js application`) + + // Ensure scripts has required commands + packageJson.scripts = packageJson.scripts || {}; + if (!packageJson.scripts.build) { + packageJson.scripts.build = "next build"; + log.info(`[NodeAppService] Added 'next build' script to package.json`); + } + if (!packageJson.scripts.start) { + packageJson.scripts.start = "next start"; + log.info(`[NodeAppService] Added 'next start' script to package.json`); + } + + // 强制添加构建命令,如果是Next.js应用必须先构建 + if (!options?.buildCommand) { + options = options || {}; + options.buildCommand = "npm run build"; + log.info(`[NodeAppService] Automatically added 'npm run build' step for Next.js application`); + } + + // 检查next.config.js文件,查看是否使用了standalone输出 + const nextConfigPath = path.join(appDir, 'next.config.js'); + let isStandaloneOutput = false; + + if (fs.existsSync(nextConfigPath)) { + try { + const nextConfigContent = fs.readFileSync(nextConfigPath, 'utf8'); + // 简单检测是否包含standalone配置 + isStandaloneOutput = nextConfigContent.includes('output:') && + nextConfigContent.includes('standalone'); + + if (isStandaloneOutput) { + log.info(`[NodeAppService] Detected Next.js with 'output: standalone' configuration`); + // 针对standalone模式修改启动命令 + options.startCommand = "node .next/standalone/server.js"; + log.info(`[NodeAppService] Using 'node .next/standalone/server.js' for standalone mode`); + } + } catch (error) { + log.error(`[NodeAppService] Error checking Next.js config:`, error); + } + } + + // Save the updated package.json + await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 }); + } + } + + // Check if main file (index.js) exists + const indexJsPath = path.join(appDir, 'index.js') + if (!await fs.pathExists(indexJsPath) && !packageJson.dependencies?.next) { + // Look for any .js file to use as main + const files = await fs.readdir(appDir) + const jsFiles = files.filter(file => file.endsWith('.js')) + + if (jsFiles.length > 0) { + // Update package.json to use the first JS file as main + packageJson.main = jsFiles[0] + packageJson.scripts = packageJson.scripts || {} + packageJson.scripts.start = `node ${jsFiles[0]}` + await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 }) + log.info(`[NodeAppService] Updated package.json to use ${jsFiles[0]} as main`) + } else { + // No JS files found, create a simple index.js + const defaultCode = `const http = require('http'); + +const server = http.createServer((req, res) => { + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end('

App deployed from ZIP

'); +}); + +const PORT = process.env.PORT || 3000; +server.listen(PORT, () => { + console.log(\`Server running on port \${PORT}\`); +});` + + await fs.writeFile(indexJsPath, defaultCode) + log.info(`[NodeAppService] Created default index.js as no JS files were found`) + } + } + + // Run install command if specified or default + const installCommand = options?.installCommand || 'npm install' + log.info(`[NodeAppService] Running install command: ${installCommand}`) + + try { + if (installCommand.startsWith('npm ')) { + const npmArgs = installCommand.substring(4).trim() + await this.runNpmCommand(npmArgs, appDir) + } else { + await execAsync(installCommand, { cwd: appDir }) + } + } catch (error) { + log.error(`[NodeAppService] Error running install command: ${error}`) + // Continue despite install error + } + + // Run build command if specified + if (options?.buildCommand) { + log.info(`[NodeAppService] Running build command: ${options.buildCommand}`) + try { + // 为Next.js应用设置标准环境变量 + const buildEnv = { ...process.env }; + + if (packageJson.dependencies?.next || packageJson.devDependencies?.next) { + log.info(`[NodeAppService] Setting standard environment for Next.js build`); + buildEnv.NODE_ENV = 'production'; + buildEnv.NEXT_TELEMETRY_DISABLED = '1'; + } + + if (options.buildCommand.startsWith('npm ')) { + const npmArgs = options.buildCommand.substring(4).trim() + await this.runNpmCommand(npmArgs, appDir, buildEnv) + } else { + await execAsync(options.buildCommand, { cwd: appDir, env: buildEnv }) + } + log.info(`[NodeAppService] Build completed successfully`) + } catch (error) { + log.error(`[NodeAppService] Error running build command: ${error}`) + // 处理构建失败的情况,特别是Next.js应用 + if (packageJson.dependencies?.next || packageJson.devDependencies?.next) { + // 检查.next目录是否存在且包含必要文件 + const nextDir = path.join(appDir, '.next'); + const prerenderFile = path.join(nextDir, 'prerender-manifest.json'); + + if (!await fs.pathExists(prerenderFile)) { + log.error(`[NodeAppService] Next.js build failed: prerender-manifest.json not found`); + throw new Error('App build failed. Please fix the code issues and try again.'); + } + } + } + } + + // 针对Next.js应用,在启动前额外检查构建产物 + if (packageJson.dependencies?.next || packageJson.devDependencies?.next) { + const nextDir = path.join(appDir, '.next'); + + if (!await fs.pathExists(nextDir)) { + log.error(`[NodeAppService] Next.js build artifacts not found. Run build first.`); + throw new Error('Next.js application must be built before starting. Run "npm run build" first.'); + } + + // 检查关键文件 + const prerenderFile = path.join(nextDir, 'prerender-manifest.json'); + if (!await fs.pathExists(prerenderFile)) { + log.error(`[NodeAppService] prerender-manifest.json not found. Build may have failed.`); + throw new Error('Next.js build appears to be incomplete. Check for errors in your code.'); + } + } + + // Determine port to use + const port = options?.port || await this.findAvailablePort(3000) + + // Set environment variables for the app + const env: any = { + ...process.env, + PORT: port.toString(), + NODE_ENV: 'production' + } + + // 为Next.js应用设置特定环境变量 + if (packageJson.dependencies?.next || packageJson.devDependencies?.next) { + env.NEXT_TELEMETRY_DISABLED = '1'; + + // 对于standalone模式,设置特定环境变量 + if (options?.startCommand && options.startCommand.includes('.next/standalone/server.js')) { + env.PORT = port.toString(); + env.HOSTNAME = '0.0.0.0'; // 允许外部访问 + } + } + + // Start command (default to npm start if not specified) + const startCommand = options?.startCommand || 'npm start' + + // Special handling for npm commands + let cmd: string, args: string[] + + if (startCommand.startsWith('npm ')) { + const npmArgs = startCommand.substring(4).trim() + cmd = this.hasInternalNode ? this.npmPath : 'npm' + args = npmArgs.split(' ') + } else if (startCommand.startsWith('node ')) { + const nodeArgs = startCommand.substring(5).trim() + cmd = this.hasInternalNode ? this.nodePath : 'node' + args = nodeArgs.split(' ') + } else { + // Custom command + const parts = startCommand.split(' ') + cmd = parts[0] + args = parts.slice(1) + } + + log.info(`[NodeAppService] Starting app with command: ${cmd} ${args.join(' ')}`) + + // Start the process + const childProcess = spawn(cmd, args, { + cwd: appDir, + env, + shell: true + }) + + // Log output + childProcess.stdout.on('data', (data) => { + log.info(`[${appName}] ${data.toString().trim()}`) + }) + + childProcess.stderr.on('data', (data) => { + log.error(`[${appName}] ${data.toString().trim()}`) + }) + + // Generate a metadata file for the app + const metadata: NodeAppType = { + id: appId, + name: appName, + type: 'node', + isInstalled: true, + isRunning: true, + installCommand, + buildCommand: options?.buildCommand, + startCommand, + port, + url: `http://localhost:${port}` + } + + await fs.writeJson(path.join(appDir, 'metadata.json'), metadata, { spaces: 2 }) + + // Store the running app information + this.runningApps.set(appId, { + process: childProcess, + port, + directory: appDir + }) + + // Add to the list of apps + this.nodeApps.push(metadata) + + // Handle process exit + childProcess.on('close', (code) => { + log.info(`[NodeAppService] App ${appName} exited with code ${code}`) + this.runningApps.delete(appId) + + // Update the app status + const appIndex = this.nodeApps.findIndex(a => a.id === appId) + if (appIndex !== -1) { + this.nodeApps[appIndex] = { + ...this.nodeApps[appIndex], + isRunning: false + } + } + + this.emit('apps-updated', this.nodeApps) + }) + + // Notify of app creation and status + this.emit('apps-updated', this.nodeApps) + + // Wait for app to start by checking the port + await this.waitForPortToBeReady(port, 30) + + log.info(`[NodeAppService] App ${appName} deployed and started on port ${port}`) + return { + port, + url: `http://localhost:${port}` + } + } catch (err: any) { + log.error(`[NodeAppService] Failed to deploy app from ZIP:`, err) + + // 提供更友好的错误信息 + if (err.message && ( + err.message.includes('Next.js') || + err.message.includes('prerender-manifest.json') || + err.message.includes('build failed') + )) { + // 这是一个Next.js构建错误 + throw new Error(`Next.js应用构建失败: ${err.message}. 请修复代码中的错误后重试。常见问题: 1) 元素错误使用 2) 缺少依赖 3) 代码语法错误`); + } + + return null; + } + } + + /** + * Deploy a Node.js app from a Git repository URL + * @param repoUrl Git repository URL (e.g. https://github.com/user/repo) + * @param options Optional configuration for the app + */ + public async deployFromGit(repoUrl: string, options?: { + name?: string; + port?: number; + startCommand?: string; + installCommand?: string; + buildCommand?: string; + }): Promise<{ port: number; url: string } | null> { + try { + log.info(`[NodeAppService] Deploying app from Git repository: ${repoUrl}`) + + // Generate a unique app ID + const appId = `app-${Date.now()}` + + // Extract repo name from URL for better naming + let appName = options?.name; + if (!appName) { + try { + // Try to extract name from URL + const urlParts = repoUrl.split('/'); + const repoName = urlParts[urlParts.length - 1].replace('.git', '') || + urlParts[urlParts.length - 2] || + `App-${appId}`; + appName = repoName; + } catch (e) { + appName = `App-${appId}`; + } + } + + // Create app directory + const appDir = path.join(this.appsDir, appId) + await fs.ensureDir(appDir) + + // Clone the repository + log.info(`[NodeAppService] Cloning repository to ${appDir}`) + await execAsync(`git clone ${repoUrl} "${appDir}"`) + + // Check if package.json exists + const packageJsonPath = path.join(appDir, 'package.json') + let packageJson: any; + + if (!await fs.pathExists(packageJsonPath)) { + log.error(`[NodeAppService] package.json not found in the repository`) + throw new Error('Repository does not contain a package.json file'); + } else { + // Load existing package.json + packageJson = await fs.readJson(packageJsonPath); + + // Check for Next.js and ensure start script is correct if needed + if (packageJson.dependencies && (packageJson.dependencies.next || packageJson.devDependencies?.next)) { + log.info(`[NodeAppService] Detected Next.js application`) + + // Ensure scripts has required commands + packageJson.scripts = packageJson.scripts || {}; + if (!packageJson.scripts.build) { + packageJson.scripts.build = "next build"; + log.info(`[NodeAppService] Added 'next build' script to package.json`); + } + if (!packageJson.scripts.start) { + packageJson.scripts.start = "next start"; + log.info(`[NodeAppService] Added 'next start' script to package.json`); + } + + // 强制添加构建命令,如果是Next.js应用必须先构建 + if (!options?.buildCommand) { + options = options || {}; + options.buildCommand = "npm run build"; + log.info(`[NodeAppService] Automatically added 'npm run build' step for Next.js application`); + } + + // 检查next.config.js文件,查看是否使用了standalone输出 + const nextConfigPath = path.join(appDir, 'next.config.js'); + let isStandaloneOutput = false; + + if (fs.existsSync(nextConfigPath)) { + try { + const nextConfigContent = fs.readFileSync(nextConfigPath, 'utf8'); + // 简单检测是否包含standalone配置 + isStandaloneOutput = nextConfigContent.includes('output:') && + nextConfigContent.includes('standalone'); + + if (isStandaloneOutput) { + log.info(`[NodeAppService] Detected Next.js with 'output: standalone' configuration`); + // 针对standalone模式修改启动命令 + options.startCommand = "node .next/standalone/server.js"; + log.info(`[NodeAppService] Using 'node .next/standalone/server.js' for standalone mode`); + } + } catch (error) { + log.error(`[NodeAppService] Error checking Next.js config:`, error); + } + } + + // Save the updated package.json + await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 }); + } + } + + // Run install command if specified or default + const installCommand = options?.installCommand || 'npm install' + log.info(`[NodeAppService] Running install command: ${installCommand}`) + + try { + if (installCommand.startsWith('npm ')) { + const npmArgs = installCommand.substring(4).trim() + await this.runNpmCommand(npmArgs, appDir) + } else { + await execAsync(installCommand, { cwd: appDir }) + } + } catch (error) { + log.error(`[NodeAppService] Error running install command: ${error}`) + // Continue despite install error + } + + // Run build command if specified + if (options?.buildCommand) { + log.info(`[NodeAppService] Running build command: ${options.buildCommand}`) + try { + // 为Next.js应用设置标准环境变量 + const buildEnv = { ...process.env }; + + if (packageJson.dependencies?.next || packageJson.devDependencies?.next) { + log.info(`[NodeAppService] Setting standard environment for Next.js build`); + buildEnv.NODE_ENV = 'production'; + buildEnv.NEXT_TELEMETRY_DISABLED = '1'; + } + + if (options.buildCommand.startsWith('npm ')) { + const npmArgs = options.buildCommand.substring(4).trim() + await this.runNpmCommand(npmArgs, appDir, buildEnv) + } else { + await execAsync(options.buildCommand, { cwd: appDir, env: buildEnv }) + } + log.info(`[NodeAppService] Build completed successfully`) + } catch (error) { + log.error(`[NodeAppService] Error running build command: ${error}`) + // 处理构建失败的情况,特别是Next.js应用 + if (packageJson.dependencies?.next || packageJson.devDependencies?.next) { + // 检查.next目录是否存在且包含必要文件 + const nextDir = path.join(appDir, '.next'); + const prerenderFile = path.join(nextDir, 'prerender-manifest.json'); + + if (!await fs.pathExists(prerenderFile)) { + log.error(`[NodeAppService] Next.js build failed: prerender-manifest.json not found`); + throw new Error('App build failed. Please fix the code issues and try again.'); + } + } + } + } + + // 针对Next.js应用,在启动前额外检查构建产物 + if (packageJson.dependencies?.next || packageJson.devDependencies?.next) { + const nextDir = path.join(appDir, '.next'); + + if (!await fs.pathExists(nextDir)) { + log.error(`[NodeAppService] Next.js build artifacts not found. Run build first.`); + throw new Error('Next.js application must be built before starting. Run "npm run build" first.'); + } + + // 检查关键文件 + const prerenderFile = path.join(nextDir, 'prerender-manifest.json'); + if (!await fs.pathExists(prerenderFile)) { + log.error(`[NodeAppService] prerender-manifest.json not found. Build may have failed.`); + throw new Error('Next.js build appears to be incomplete. Check for errors in your code.'); + } + } + + // Determine port to use + const port = options?.port || await this.findAvailablePort(3000) + + // Set environment variables for the app + const env: any = { + ...process.env, + PORT: port.toString(), + NODE_ENV: 'production' + } + + // 为Next.js应用设置特定环境变量 + if (packageJson.dependencies?.next || packageJson.devDependencies?.next) { + env.NEXT_TELEMETRY_DISABLED = '1'; + + // 对于standalone模式,设置特定环境变量 + if (options?.startCommand && options.startCommand.includes('.next/standalone/server.js')) { + env.PORT = port.toString(); + env.HOSTNAME = '0.0.0.0'; // 允许外部访问 + } + } + + // Start command (default to npm start if not specified) + const startCommand = options?.startCommand || 'npm start' + + // Special handling for npm commands + let cmd: string, args: string[] + + if (startCommand.startsWith('npm ')) { + const npmArgs = startCommand.substring(4).trim() + cmd = this.hasInternalNode ? this.npmPath : 'npm' + args = npmArgs.split(' ') + } else if (startCommand.startsWith('node ')) { + const nodeArgs = startCommand.substring(5).trim() + cmd = this.hasInternalNode ? this.nodePath : 'node' + args = nodeArgs.split(' ') + } else { + // Custom command + const parts = startCommand.split(' ') + cmd = parts[0] + args = parts.slice(1) + } + + log.info(`[NodeAppService] Starting app with command: ${cmd} ${args.join(' ')}`) + + // Start the process + const childProcess = spawn(cmd, args, { + cwd: appDir, + env, + shell: true + }) + + // Log output + childProcess.stdout.on('data', (data) => { + log.info(`[${appName}] ${data.toString().trim()}`) + }) + + childProcess.stderr.on('data', (data) => { + log.error(`[${appName}] ${data.toString().trim()}`) + }) + + // Generate a metadata file for the app + const metadata: NodeAppType = { + id: appId, + name: appName, + type: 'node', + isInstalled: true, + isRunning: true, + repositoryUrl: repoUrl, // 记录仓库URL,以便后续更新 + installCommand, + buildCommand: options?.buildCommand, + startCommand, + port, + url: `http://localhost:${port}` + } + + await fs.writeJson(path.join(appDir, 'metadata.json'), metadata, { spaces: 2 }) + + // Store the running app information + this.runningApps.set(appId, { + process: childProcess, + port, + directory: appDir + }) + + // Add to the list of apps + this.nodeApps.push(metadata) + + // Handle process exit + childProcess.on('close', (code) => { + log.info(`[NodeAppService] App ${appName} exited with code ${code}`) + this.runningApps.delete(appId) + + // Update the app status + const appIndex = this.nodeApps.findIndex(a => a.id === appId) + if (appIndex !== -1) { + this.nodeApps[appIndex] = { + ...this.nodeApps[appIndex], + isRunning: false + } + } + + this.emit('apps-updated', this.nodeApps) + }) + + // Notify of app creation and status + this.emit('apps-updated', this.nodeApps) + + // Wait for app to start by checking the port + await this.waitForPortToBeReady(port, 30) + + log.info(`[NodeAppService] App ${appName} deployed from Git and started on port ${port}`) + return { + port, + url: `http://localhost:${port}` + } + } catch (err: any) { + log.error(`[NodeAppService] Failed to deploy app from Git:`, err) + + // 提供更友好的错误信息 + if (err.message && ( + err.message.includes('Next.js') || + err.message.includes('prerender-manifest.json') || + err.message.includes('build failed') + )) { + // 这是一个Next.js构建错误 + throw new Error(`Next.js应用构建失败: ${err.message}. 请修复代码中的错误后重试。常见问题: 1) 元素错误使用 2) 缺少依赖 3) 代码语法错误`); + } + + if (err.message && err.message.includes('git clone')) { + throw new Error(`Git仓库克隆失败: ${err.message}. 请检查仓库地址是否正确,以及是否为公开仓库。`); + } + + return null; + } + } + + /** + * Find JavaScript files in a directory recursively + */ + private async findJavaScriptFiles(dir: string): Promise { + let results: string[] = [] + const items = await fs.readdir(dir) + + for (const item of items) { + const itemPath = path.join(dir, item) + const stats = await fs.stat(itemPath) + + if (stats.isDirectory()) { + // Skip node_modules + if (item === 'node_modules') { + continue + } + const subDirResults = await this.findJavaScriptFiles(itemPath) + results = results.concat(subDirResults) + } else if (item.endsWith('.js') || item.endsWith('.mjs')) { + results.push(itemPath) + } + } + + return results + } + + /** + * Initialize the Node.js environment + * Check if internal Node.js exists, if not, use system Node.js + */ + private async initializeNodeEnvironment(): Promise { + try { + // Try to get internal Node.js path + const hasNode = await isBinaryExists('node') + const hasNpm = await isBinaryExists('npm') + + if (hasNode) { + this.nodePath = await getBinaryPath('node') + log.info(`[NodeAppService] Using internal Node.js: ${this.nodePath}`) + this.hasInternalNode = true + } else { + log.info(`[NodeAppService] Internal Node.js not found, using system Node.js`) + } + + if (hasNpm) { + this.npmPath = await getBinaryPath('npm') + log.info(`[NodeAppService] Using internal npm: ${this.npmPath}`) + } else { + log.info(`[NodeAppService] Internal npm not found, using system npm`) + } + + // If no internal Node.js, check system Node.js + if (!this.hasInternalNode) { + try { + await execAsync('node --version') + log.info(`[NodeAppService] System Node.js is available`) + } catch (error) { + log.error(`[NodeAppService] No Node.js available in system`) + // TODO: Show error to user or try to install Node.js + } + } + } catch (error) { + log.error(`[NodeAppService] Error initializing Node.js environment:`, error) + } + } + + /** + * Install internal Node.js if not exists + */ + public async installNodeJs(): Promise { + try { + log.info(`[NodeAppService] Installing internal Node.js`) + + // 从配置中获取要安装的Node.js版本 + const nodeVersion = configManager.get('NODE_VERSION') || '18.18.0' // 默认版本 + + // 使用环境变量传递版本信息 + const env = { + ...process.env, + NODE_VERSION: String(nodeVersion) + } + + // 运行安装脚本 + await runInstallScript('install-node.js', env) + + // 将当前安装的版本保存到配置中 + configManager.set('NODE_VERSION', nodeVersion) + + // 检查安装是否成功 + const hasNode = await isBinaryExists('node') + if (hasNode) { + this.nodePath = await getBinaryPath('node') + this.hasInternalNode = true + log.info(`[NodeAppService] Internal Node.js v${nodeVersion} installed successfully: ${this.nodePath}`) + return true + } else { + log.error(`[NodeAppService] Failed to install internal Node.js v${nodeVersion}`) + return false + } + } catch (error) { + log.error(`[NodeAppService] Error installing internal Node.js:`, error) + return false + } + } + + private async runNpmCommand(command: string, cwd: string, env?: any): Promise { + try { + // Use the appropriate npm path + const npmCmd = this.hasInternalNode ? this.npmPath : 'npm' + + const { stdout, stderr } = await execAsync(`"${npmCmd}" ${command}`, { cwd, env }) + if (stderr) { + log.warn(`[NodeAppService] npm command warning: ${stderr}`) + } + return stdout + } catch (error) { + log.error(`[NodeAppService] Error running npm command: ${error}`) + throw error + } + } +} diff --git a/src/main/utils/process.ts b/src/main/utils/process.ts index e4151c01ef..4a0ccf3a4d 100644 --- a/src/main/utils/process.ts +++ b/src/main/utils/process.ts @@ -6,13 +6,13 @@ import path from 'path' import { getResourcePath } from '.' -export function runInstallScript(scriptPath: string): Promise { +export function runInstallScript(scriptPath: string, env?: NodeJS.ProcessEnv): Promise { return new Promise((resolve, reject) => { const installScriptPath = path.join(getResourcePath(), 'scripts', scriptPath) log.info(`Running script at: ${installScriptPath}`) const nodeProcess = spawn(process.execPath, [installScriptPath], { - env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' } + env: { ...process.env, ELECTRON_RUN_AS_NODE: '1', ...env } }) nodeProcess.stdout.on('data', (data) => { diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index 27e1473582..7a20ae202b 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -154,10 +154,37 @@ declare global { logout: () => Promise getUser: (token: string) => Promise<{ login: string; avatar: string }> } + nodeapp: { + list: () => Promise + add: (app: any) => Promise + install: (appId: string) => Promise + update: (appId: string) => Promise + start: (appId: string) => Promise<{ port: number; url: string } | null> + stop: (appId: string) => Promise + uninstall: (appId: string) => Promise + deployZip: (zipPath: string, options?: { + name?: string; + port?: number; + startCommand?: string; + installCommand?: string; + buildCommand?: string; + }) => Promise<{ port: number; url: string } | null> + deployGit: (repoUrl: string, options?: { + name?: string; + port?: number; + startCommand?: string; + installCommand?: string; + buildCommand?: string; + }) => Promise<{ port: number; url: string } | null> + checkNode: () => Promise + installNode: () => Promise + onUpdated: (callback: (apps: any[]) => void) => () => void + } isBinaryExist: (name: string) => Promise getBinaryPath: (name: string) => Promise installUVBinary: () => Promise installBunBinary: () => Promise + run: (command: string) => Promise } } } diff --git a/src/preload/index.ts b/src/preload/index.ts index 16505ae6b6..6d6b167217 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -29,6 +29,38 @@ const api = { ipcRenderer.invoke('backup:backupToWebdav', data, webdavConfig), restoreFromWebdav: (webdavConfig: WebDavConfig) => ipcRenderer.invoke('backup:restoreFromWebdav', webdavConfig) }, + nodeapp: { + list: () => ipcRenderer.invoke('nodeapp:list'), + add: (app: any) => ipcRenderer.invoke('nodeapp:add', app), + install: (appId: string) => ipcRenderer.invoke('nodeapp:install', appId), + update: (appId: string) => ipcRenderer.invoke('nodeapp:update', appId), + start: (appId: string) => ipcRenderer.invoke('nodeapp:start', appId), + stop: (appId: string) => ipcRenderer.invoke('nodeapp:stop', appId), + uninstall: (appId: string) => ipcRenderer.invoke('nodeapp:uninstall', appId), + deployZip: (zipPath: string, options?: { + name?: string; + port?: number; + startCommand?: string; + installCommand?: string; + buildCommand?: string; + }) => ipcRenderer.invoke('nodeapp:deploy-zip', zipPath, options), + deployGit: (repoUrl: string, options?: { + name?: string; + port?: number; + startCommand?: string; + installCommand?: string; + buildCommand?: string; + }) => ipcRenderer.invoke('nodeapp:deploy-git', repoUrl, options), + checkNode: () => ipcRenderer.invoke('nodeapp:check-node'), + installNode: () => ipcRenderer.invoke('nodeapp:install-node'), + onUpdated: (callback: (apps: any[]) => void) => { + const eventListener = (_: any, apps: any[]) => callback(apps) + ipcRenderer.on('nodeapp:updated', eventListener) + return () => { + ipcRenderer.removeListener('nodeapp:updated', eventListener) + } + } + }, file: { select: (options?: OpenDialogOptions) => ipcRenderer.invoke('file:select', options), upload: (filePath: string) => ipcRenderer.invoke('file:upload', filePath), @@ -121,7 +153,7 @@ const api = { cleanup: () => ipcRenderer.invoke('mcp:cleanup') }, shell: { - openExternal: shell.openExternal + openExternal: (url: string) => ipcRenderer.invoke('shell:openExternal', url) }, copilot: { getAuthMessage: (headers?: Record) => ipcRenderer.invoke('copilot:get-auth-message', headers), @@ -137,7 +169,8 @@ const api = { isBinaryExist: (name: string) => ipcRenderer.invoke('app:is-binary-exist', name), getBinaryPath: (name: string) => ipcRenderer.invoke('app:get-binary-path', name), installUVBinary: () => ipcRenderer.invoke('app:install-uv-binary'), - installBunBinary: () => ipcRenderer.invoke('app:install-bun-binary') + installBunBinary: () => ipcRenderer.invoke('app:install-bun-binary'), + run: (command: string) => ipcRenderer.invoke('app:run-command', command) } // Use `contextBridge` APIs to expose Electron APIs to diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index e820866b47..fbb838f567 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -17,6 +17,7 @@ import AppsPage from './pages/apps/AppsPage' import FilesPage from './pages/files/FilesPage' import HomePage from './pages/home/HomePage' import KnowledgePage from './pages/knowledge/KnowledgePage' +import NodeAppsPage from './pages/nodeapps/NodeAppsPage' import PaintingsPage from './pages/paintings/PaintingsPage' import SettingsPage from './pages/settings/SettingsPage' import TranslatePage from './pages/translate/TranslatePage' @@ -41,6 +42,7 @@ function App(): JSX.Element { } /> } /> } /> + } /> } /> diff --git a/src/renderer/src/components/app/Sidebar.tsx b/src/renderer/src/components/app/Sidebar.tsx index 015f49f682..b40015b6bd 100644 --- a/src/renderer/src/components/app/Sidebar.tsx +++ b/src/renderer/src/components/app/Sidebar.tsx @@ -130,6 +130,7 @@ const MainMenus: FC = () => { paintings: , translate: , minapp: , + nodeapps: , knowledge: , files: } @@ -140,6 +141,7 @@ const MainMenus: FC = () => { paintings: '/paintings', translate: '/translate', minapp: '/apps', + nodeapps: '/nodeapps', knowledge: '/knowledge', files: '/files' } diff --git a/src/renderer/src/env.d.ts b/src/renderer/src/env.d.ts index ec6be6b337..15e7e51e15 100644 --- a/src/renderer/src/env.d.ts +++ b/src/renderer/src/env.d.ts @@ -20,5 +20,7 @@ declare global { keyv: KeyvStorage mermaid: any store: any + backupToWebdav: (data: string, webdavConfig: WebDavConfig) => Promise + restoreFromWebdav: (webdavConfig: WebDavConfig) => Promise<{ data: string; success: boolean }> } } diff --git a/src/renderer/src/hooks/useNodeApps.ts b/src/renderer/src/hooks/useNodeApps.ts new file mode 100644 index 0000000000..71472865c3 --- /dev/null +++ b/src/renderer/src/hooks/useNodeApps.ts @@ -0,0 +1,88 @@ +import { NodeAppType } from '@renderer/types' +import { useCallback, useEffect, useState } from 'react' + +export function useNodeApps() { + const [apps, setApps] = useState([]) + const [loading, setLoading] = useState(true) + + // Load apps + const loadApps = useCallback(async () => { + try { + setLoading(true) + const result = await window.api.nodeapp.list() + setApps(result || []) + } catch (error) { + console.error('Error loading node apps:', error) + } finally { + setLoading(false) + } + }, []) + + // Add app + const addApp = useCallback(async (app: NodeAppType) => { + const result = await window.api.nodeapp.add(app) + await loadApps() + return result + }, [loadApps]) + + // Install app + const installApp = useCallback(async (appId: string) => { + const result = await window.api.nodeapp.install(appId) + await loadApps() + return result + }, [loadApps]) + + // Update app + const updateApp = useCallback(async (appId: string) => { + const result = await window.api.nodeapp.update(appId) + await loadApps() + return result + }, [loadApps]) + + // Start app + const startApp = useCallback(async (appId: string) => { + const result = await window.api.nodeapp.start(appId) + await loadApps() + return result + }, [loadApps]) + + // Stop app + const stopApp = useCallback(async (appId: string) => { + const result = await window.api.nodeapp.stop(appId) + await loadApps() + return result + }, [loadApps]) + + // Uninstall app + const uninstallApp = useCallback(async (appId: string) => { + const result = await window.api.nodeapp.uninstall(appId) + await loadApps() + return result + }, [loadApps]) + + // Initialize + useEffect(() => { + loadApps() + + // Subscribe to app updates + const unsubscribe = window.api.nodeapp.onUpdated((updatedApps) => { + setApps(updatedApps || []) + }) + + return () => { + unsubscribe() + } + }, [loadApps]) + + return { + apps, + loading, + addApp, + installApp, + updateApp, + startApp, + stopApp, + uninstallApp, + refresh: loadApps + } +} diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index 4d11d0836d..8bd67e8473 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -483,12 +483,21 @@ "upgrade.success.content": "Please restart the application to complete the upgrade", "upgrade.success.title": "Upgrade successfully", "warn.notion.exporting": "Exporting to Notion, please do not request export repeatedly!", - "warning.rate.limit": "Too many requests. Please wait {{seconds}} seconds before trying again." + "warning.rate.limit": "Too many requests. Please wait {{seconds}} seconds before trying again.", + "nextJsInfo": "Next.js Application Note", + "nextJsDescription": "Next.js applications require a build step before they can be started. Make sure to check 'This is a Next.js application' or manually add 'npm run build' as the build command." }, "minapp": { - "sidebar.add.title": "Add to sidebar", - "sidebar.remove.title": "Remove from sidebar", - "title": "MinApp" + "add": "Add", + "apps.tab.search": "Search apps", + "apps.tab.title": "Apps", + "empty": "No mini apps", + "find": "Find more", + "more": "More", + "settings.disabled_apps": "Disabled Apps", + "sidebar.add.title": "Add to Sidebar", + "sidebar.remove.title": "Remove from Sidebar", + "title": "Web Apps" }, "miniwindow": { "clipboard": { @@ -1104,6 +1113,74 @@ "title": "Tavily" }, "title": "Web Search" + }, + "nodeRequired": "Node.js Required", + "nodeSettings": { + "title": "Node.js Environment Settings", + "description": "Manage the built-in Node.js environment for Cherry Studio. You can select which version of Node.js to install for optimal compatibility.", + "status": "Status", + "checking": "Checking...", + "installed": "Installed", + "notInstalled": "Not Installed", + "refresh": "Refresh", + "version": "Node.js Version", + "versionHelp": "Select the version of Node.js to install", + "customVersion": "Custom Version", + "customVersionHelp": "If you need a specific version, enter it here (e.g., 18.16.1)", + "install": "Install Node.js", + "reinstall": "Reinstall Node.js", + "installSuccess": "Node.js v{{version}} installed successfully", + "installFailed": "Failed to install Node.js" + }, + "nodeSettingsTab": "Node.js Environment", + "appsManagerTab": "Apps Manager", + "packageDeployerTab": "Deploy Package", + "packageDeployer": { + "advancedOptions": "Advanced Options", + "deploy": "Deploy", + "deployFailed": "Failed to deploy package", + "deploySuccess": "{{name}} has been successfully deployed on port {{port}}", + "description": "Upload a ZIP file containing Node.js application code. The package will be automatically extracted and installed.", + "fileSelectError": "Error selecting file", + "installNode": "Install Node.js", + "installNodePrompt": "Node.js is required to deploy applications. Would you like to install it now?", + "namePlaceholder": "Enter a name for your deployed application", + "nodeInstallFailed": "Failed to install Node.js", + "nodeInstallSuccess": "Node.js installed successfully", + "nodeNeeded": "Built-in Node.js is required to run applications.", + "nodeNotAvailable": "Node.js is not available", + "nodeRequired": "Node.js Required", + "noFileSelected": "Please select a ZIP file to deploy", + "open": "Open in Browser", + "selectZip": "Click to select ZIP file", + "title": "Deploy Code Package", + "moduleTypeError": "Module Type Error", + "esModuleError": "ES module syntax detected. Set \"type\": \"module\" in package.json or use .mjs extension.", + "convertToCommonJS": "Convert to CommonJS syntax", + "nextJsDetected": "Next.js Application Detected", + "buildStepAdded": "Build step has been automatically added for Next.js application.", + "nextJsInfo": "Next.js Application Note", + "nextJsDescription": "Next.js applications require a build step before they can be started. Make sure to check 'This is a Next.js application' or manually add 'npm run build' as the build command.", + "deployPackage": "Deploy Package", + "deployFromZip": "From ZIP", + "deployFromGit": "From Git", + "selectZipFile": "Select ZIP File", + "appName": "Application Name", + "appNamePlaceholder": "My Application", + "port": "Port", + "portPlaceholder": "3000", + "portTooltip": "The port on which your application will run. Leave empty for automatic port assignment.", + "showAdvanced": "Show Advanced Options", + "hideAdvanced": "Hide Advanced Options", + "installCommand": "Install Command", + "buildCommand": "Build Command", + "startCommand": "Start Command", + "isNextJs": "This is a Next.js application", + "deploy": "Deploy", + "repoUrl": "Git Repository URL", + "repoUrlRequired": "Please enter a Git repository URL", + "noRepoUrlProvided": "Please provide a Git repository URL", + "packageRequired": "Please select a package file" } }, "translate": { @@ -1141,6 +1218,146 @@ "quit": "Quit", "show_window": "Show Window", "visualization": "Visualization" + }, + "nodeapp": { + "add": "Add App", + "addNew": "Add New Node.js App", + "addSuccess": "App added successfully", + "author": "Author", + "codeRunner": { + "description": "Enter your Node.js code below and click 'Run' to execute it. Your code will be run in a temporary Node.js environment.", + "emptyCode": "Please enter some code to run", + "open": "Open in Browser", + "output": "Output", + "placeholder": "// Enter your Node.js code here\n// Example:\nconst http = require('http');\n\nconst server = http.createServer((req, res) => {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end('

Hello from Cherry Studio!

');\n});\n\nconst PORT = process.env.PORT || 3000;\nserver.listen(PORT, () => {\n console.log(`Server running on port ${PORT}`);\n});", + "run": "Run Code", + "success": "Code is running on port {{port}}", + "title": "Code Runner" + }, + "codeRunnerTab": "Code Runner", + "empty": "No Node.js apps found", + "featured": "Featured Apps", + "form": { + "author": "Author", + "authorPlaceholder": "The author of the app", + "description": "Description", + "descriptionPlaceholder": "Brief description of the app's functionality", + "homepage": "Homepage", + "homepagePlaceholder": "Homepage URL for the application", + "installCommand": "Install Command", + "installCommandHelp": "Command to install dependencies (defaults to 'npm install')", + "buildCommand": "Build Command", + "buildCommandHelp": "Command to build the application before starting (e.g. 'npm run build')", + "isNextJs": "This is a Next.js application", + "nextJsHelp": "Apply Next.js-specific optimizations for deployment", + "name": "App Name", + "nameRequired": "App name is required", + "namePlaceholder": "Name of your Node.js application", + "port": "Port", + "portHelp": "Port the app will run on (detected automatically if not specified)" + }, + "install": "Install", + "installSuccess": "{{name}} installed successfully", + "installed": "Installed", + "marketplaceTab": "Marketplace", + "more": "More", + "notInstalled": "Not Installed", + "packageDeployer": { + "advancedOptions": "Advanced Options", + "deploy": "Deploy", + "deployFailed": "Failed to deploy package", + "deploySuccess": "{{name}} has been successfully deployed on port {{port}}", + "description": "Upload a ZIP file containing Node.js application code. The package will be automatically extracted and installed.", + "fileSelectError": "Error selecting file", + "installNode": "Install Node.js", + "installNodePrompt": "Node.js is required to deploy applications. Would you like to install it now?", + "namePlaceholder": "Enter a name for your deployed application", + "nodeInstallFailed": "Failed to install Node.js", + "nodeInstallSuccess": "Node.js installed successfully", + "nodeNeeded": "Built-in Node.js is required to run applications.", + "nodeNotAvailable": "Node.js is not available", + "nodeRequired": "Node.js Required", + "noFileSelected": "Please select a ZIP file to deploy", + "open": "Open in Browser", + "selectZip": "Click to select ZIP file", + "title": "Deploy Code Package", + "moduleTypeError": "Module Type Error", + "esModuleError": "ES module syntax detected. Set \"type\": \"module\" in package.json or use .mjs extension.", + "convertToCommonJS": "Convert to CommonJS syntax", + "nextJsDetected": "Next.js Application Detected", + "buildStepAdded": "Build step has been automatically added for Next.js application.", + "nextJsInfo": "Next.js Application Note", + "nextJsDescription": "Next.js applications require a build step before they can be started. Make sure to check 'This is a Next.js application' or manually add 'npm run build' as the build command.", + "deployPackage": "Deploy Package", + "deployFromZip": "From ZIP", + "deployFromGit": "From Git", + "selectZipFile": "Select ZIP File", + "appName": "Application Name", + "appNamePlaceholder": "My Application", + "port": "Port", + "portPlaceholder": "3000", + "portTooltip": "The port on which your application will run. Leave empty for automatic port assignment.", + "showAdvanced": "Show Advanced Options", + "hideAdvanced": "Hide Advanced Options", + "installCommand": "Install Command", + "buildCommand": "Build Command", + "startCommand": "Start Command", + "isNextJs": "This is a Next.js application", + "deploy": "Deploy", + "repoUrl": "Git Repository URL", + "repoUrlRequired": "Please enter a Git repository URL", + "noRepoUrlProvided": "Please provide a Git repository URL", + "packageRequired": "Please select a package file" + }, + "packageDeployerTab": "Deploy Package", + "running": "Running", + "start": "Start", + "startSuccess": "{{name}} started on port {{port}}", + "stop": "Stop", + "stopSuccess": "{{name}} stopped successfully", + "title": "Node.js Apps", + "uninstall": "Uninstall", + "uninstallSuccess": "{{name}} uninstalled successfully", + "update": "Update", + "updateSuccess": "{{name}} updated successfully", + "version": "Version", + "viewRepository": "View Repository" + }, + "model": { + "add_parameter": "Add Parameter", + "all": "All", + "custom_parameters": "Custom Parameters", + "dimensions": "Dimensions {{dimensions}}", + "edit": "Edit Model", + "embedding": "Embedding", + "embedding_model": "Embedding Model", + "embedding_model_tooltip": "Add in Settings->Model Provider->Manage", + "free": "Free", + "no_matches": "No models available", + "parameter_name": "Parameter Name", + "parameter_type": { + "boolean": "Boolean", + "json": "JSON", + "number": "Number", + "string": "Text" + }, + "pinned": "Pinned", + "reasoning": "Reasoning", + "search": "Search models...", + "stream_output": "Stream output", + "function_calling": "Function Calling", + "type": { + "embedding": "Embedding", + "reasoning": "Reasoning", + "select": "Select Model Types", + "text": "Text", + "vision": "Vision", + "function_calling": "Function Calling" + }, + "vision": "Vision", + "websearch": "WebSearch", + "rerank_model": "Reordering Model", + "rerank_model_tooltip": "Click the Manage button in Settings -> Model Services to add." } } } diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 496809a33e..d173e5bb5f 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -1104,6 +1104,53 @@ "title": "Tavily" }, "title": "网络搜索" + }, + "nodeRequired": "需要 Node.js", + "nodeSettings": { + "title": "Node.js 环境设置", + "description": "管理 Cherry Studio 内置的 Node.js 环境。您可以选择要安装的 Node.js 版本,以确保最佳的兼容性。", + "status": "状态", + "checking": "检查中...", + "installed": "已安装", + "notInstalled": "未安装", + "refresh": "刷新", + "version": "Node.js 版本", + "versionHelp": "选择要安装的 Node.js 版本", + "customVersion": "自定义版本", + "customVersionHelp": "如果您需要特定版本,请在此输入版本号(如 18.16.1)", + "install": "安装 Node.js", + "reinstall": "重新安装 Node.js", + "installSuccess": "Node.js v{{version}} 安装成功", + "installFailed": "Node.js 安装失败" + }, + "nodeSettingsTab": "Node.js 环境", + "appsManagerTab": "应用管理", + "packageDeployerTab": "部署代码包", + "packageDeployer": { + "advancedOptions": "高级选项", + "deploy": "部署", + "deployFailed": "部署包失败", + "deploySuccess": "{{name}} 已成功部署在端口 {{port}} 上", + "description": "上传包含 Node.js 应用程序代码的 ZIP 文件。该包将被自动解压和安装。", + "fileSelectError": "选择文件时出错", + "installNode": "安装 Node.js", + "installNodePrompt": "部署应用程序需要 Node.js。您要现在安装吗?", + "namePlaceholder": "为您部署的应用输入名称", + "nodeInstallFailed": "安装 Node.js 失败", + "nodeInstallSuccess": "Node.js 安装成功", + "nodeNeeded": "运行应用程序需要内置 Node.js。", + "nodeNotAvailable": "Node.js 不可用", + "noFileSelected": "请选择要部署的 ZIP 文件", + "open": "在浏览器中打开", + "selectZip": "点击选择 ZIP 文件", + "title": "部署代码包", + "moduleTypeError": "模块类型错误", + "esModuleError": "发现 ES 模块语法。请在 package.json 中设置 \"type\": \"module\" 或使用 .mjs 扩展名。", + "convertToCommonJS": "转换为 CommonJS 语法", + "nextJsDetected": "检测到 Next.js 应用", + "buildStepAdded": "已自动添加构建步骤:将在启动应用前执行 'npm run build'。", + "nextJsInfo": "Next.js 应用注意事项", + "nextJsDescription": "Next.js 应用需要先构建后才能启动。请确保勾选\"这是一个 Next.js 应用\"或手动添加\"npm run build\"作为构建命令。" } }, "translate": { @@ -1141,6 +1188,32 @@ "quit": "退出", "show_window": "显示窗口", "visualization": "可视化" + }, + "nodeapp": { + "add": "添加", + "addApp": "添加应用", + "appName": "应用名称", + "appsManager": { + "confirmDelete": "确定要删除此应用吗?", + "confirmStop": "确定要停止此应用吗?", + "description": "管理应用", + "install": "安装", + "noApps": "暂无应用,请添加新应用或从代码部署", + "port": "端口", + "repository": "仓库", + "start": "启动", + "status": "状态", + "stop": "停止", + "title": "应用管理", + "uninstall": "卸载", + "update": "更新", + "updateProgress": "更新进度", + "updateSuccess": "{{name}} 更新成功", + "version": "版本", + "viewRepository": "查看仓库" + }, + "nextJsInfo": "Next.js 应用注意事项", + "nextJsDescription": "Next.js 应用需要先构建后才能启动。请确保勾选\"这是一个 Next.js 应用\"或手动添加\"npm run build\"作为构建命令。" } } } diff --git a/src/renderer/src/pages/nodeapps/NodeApp.tsx b/src/renderer/src/pages/nodeapps/NodeApp.tsx new file mode 100644 index 0000000000..f8873f7592 --- /dev/null +++ b/src/renderer/src/pages/nodeapps/NodeApp.tsx @@ -0,0 +1,301 @@ +import { DownloadOutlined, GithubOutlined, LoadingOutlined, PlayCircleOutlined, ReloadOutlined, StopOutlined } from '@ant-design/icons' +import { useNodeApps } from '@renderer/hooks/useNodeApps' +import { NodeAppType } from '@renderer/types' +import { Avatar, Button, Card, Dropdown, Menu, Space, Tag, Tooltip, Typography, notification } from 'antd' +import { FC, useState } from 'react' +import { useTranslation } from 'react-i18next' +import styled from 'styled-components' + +const { Title, Paragraph, Text } = Typography + +interface Props { + app: NodeAppType +} + +const NodeApp: FC = ({ app }) => { + const { t } = useTranslation() + const { installApp, updateApp, startApp, stopApp, uninstallApp } = useNodeApps() + const [loading, setLoading] = useState(false) + const [actionType, setActionType] = useState('') + + // Handle installation + const handleInstall = async () => { + try { + setLoading(true) + setActionType('install') + await installApp(app.id as string) + notification.success({ + message: t('common.success'), + description: t('nodeapp.installSuccess', { name: app.name }) + }) + } catch (err) { + notification.error({ + message: t('common.error'), + description: err instanceof Error ? err.message : String(err) + }) + } finally { + setLoading(false) + setActionType('') + } + } + + // Handle update + const handleUpdate = async () => { + try { + setLoading(true) + setActionType('update') + await updateApp(app.id as string) + notification.success({ + message: t('common.success'), + description: t('nodeapp.updateSuccess', { name: app.name }) + }) + } catch (err) { + notification.error({ + message: t('common.error'), + description: err instanceof Error ? err.message : String(err) + }) + } finally { + setLoading(false) + setActionType('') + } + } + + // Handle start + const handleStart = async () => { + try { + setLoading(true) + setActionType('start') + const result = await startApp(app.id as string) + if (result) { + notification.success({ + message: t('common.success'), + description: t('nodeapp.startSuccess', { name: app.name, port: result.port }) + }) + window.api.openWebsite(result.url) + } + } catch (err) { + notification.error({ + message: t('common.error'), + description: err instanceof Error ? err.message : String(err) + }) + } finally { + setLoading(false) + setActionType('') + } + } + + // Handle stop + const handleStop = async () => { + try { + setLoading(true) + setActionType('stop') + await stopApp(app.id as string) + notification.success({ + message: t('common.success'), + description: t('nodeapp.stopSuccess', { name: app.name }) + }) + } catch (err) { + notification.error({ + message: t('common.error'), + description: err instanceof Error ? err.message : String(err) + }) + } finally { + setLoading(false) + setActionType('') + } + } + + // Handle uninstall + const handleUninstall = async () => { + try { + setLoading(true) + setActionType('uninstall') + await uninstallApp(app.id as string) + notification.success({ + message: t('common.success'), + description: t('nodeapp.uninstallSuccess', { name: app.name }) + }) + } catch (err) { + notification.error({ + message: t('common.error'), + description: err instanceof Error ? err.message : String(err) + }) + } finally { + setLoading(false) + setActionType('') + } + } + + // Open GitHub repository + const openRepository = () => { + if (app.repositoryUrl) { + window.api.openWebsite(app.repositoryUrl) + } + } + + // Open app homepage + const openHomepage = () => { + if (app.homepage) { + window.api.openWebsite(app.homepage) + } + } + + // Render app status tag + const renderStatusTag = () => { + if (app.isRunning) { + return {t('nodeapp.running')} + } + if (app.isInstalled) { + return {t('nodeapp.installed')} + } + return {t('nodeapp.notInstalled')} + } + + return ( + + {app.logo ? ( + {app.name} + ) : ( + + + {app.name.substring(0, 2).toUpperCase()} + + + )} + {renderStatusTag()} + + } + actions={[ + // Show different actions based on app status + app.isInstalled ? ( + app.isRunning ? ( + + + + + )} + + } + /> + + ) +} + +const CardCoverContainer = styled.div` + position: relative; + min-height: 140px; + display: flex; + align-items: center; + justify-content: center; + background-color: #f0f2f5; + + .ant-tag { + position: absolute; + top: 8px; + right: 8px; + } +` + +const AppLogo = styled.div` + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 140px; +` + +export default NodeApp diff --git a/src/renderer/src/pages/nodeapps/NodeAppForm.tsx b/src/renderer/src/pages/nodeapps/NodeAppForm.tsx new file mode 100644 index 0000000000..f7c67af580 --- /dev/null +++ b/src/renderer/src/pages/nodeapps/NodeAppForm.tsx @@ -0,0 +1,118 @@ +import { NodeAppType } from '@renderer/types' +import { Button, Form, Input, Space } from 'antd' +import { FC } from 'react' +import { useTranslation } from 'react-i18next' + +interface Props { + onSubmit: (values: NodeAppType) => void + onCancel: () => void + loading: boolean + initialValues?: Partial +} + +const NodeAppForm: FC = ({ onSubmit, onCancel, loading, initialValues }) => { + const { t } = useTranslation() + const [form] = Form.useForm() + + const handleSubmit = (values: any) => { + onSubmit({ + ...values, + type: 'node', + isInstalled: false, + isRunning: false + } as NodeAppType) + } + + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ) +} + +export default NodeAppForm diff --git a/src/renderer/src/pages/nodeapps/NodeAppsPage.tsx b/src/renderer/src/pages/nodeapps/NodeAppsPage.tsx new file mode 100644 index 0000000000..9ac42cba03 --- /dev/null +++ b/src/renderer/src/pages/nodeapps/NodeAppsPage.tsx @@ -0,0 +1,171 @@ +import { PlusOutlined, SearchOutlined } from '@ant-design/icons' +import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar' +import { Center } from '@renderer/components/Layout' +import { useNodeApps } from '@renderer/hooks/useNodeApps' +import { NodeAppType } from '@renderer/types' +import { Button, Col, Empty, Input, Modal, Row, Spin, Tabs, Typography, notification } from 'antd' +import { isEmpty } from 'lodash' +import React, { FC, useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import styled from 'styled-components' + +import NodeApp from './NodeApp' +import NodeAppForm from './NodeAppForm' +import PackageDeployer from './PackageDeployer' + +const { Title } = Typography +const { TabPane } = Tabs + +const NodeAppsPage: FC = () => { + const { t } = useTranslation() + const [search, setSearch] = useState('') + const { apps, loading, addApp, refresh } = useNodeApps() + const [isModalVisible, setIsModalVisible] = useState(false) + const [formLoading, setFormLoading] = useState(false) + + // Filter apps based on search + const filteredApps = search + ? apps.filter( + (app) => + app.name.toLowerCase().includes(search.toLowerCase()) || + app.description?.toLowerCase().includes(search.toLowerCase()) || + app.author?.toLowerCase().includes(search.toLowerCase()) + ) + : apps + + // Handle adding a new app + const handleAddApp = useCallback(async (values: NodeAppType) => { + try { + setFormLoading(true) + await addApp({ + ...values, + type: 'node' + }) + setIsModalVisible(false) + notification.success({ + message: t('common.success'), + description: t('nodeapp.addSuccess', { name: values.name }) + }) + } catch (err) { + notification.error({ + message: t('common.error'), + description: err instanceof Error ? err.message : String(err) + }) + } finally { + setFormLoading(false) + } + }, [addApp, t]) + + // Disable right-click menu in blank area + const handleContextMenu = (e: React.MouseEvent) => { + e.preventDefault() + } + + // Handle successful package deployment + const handleDeployed = useCallback(() => { + refresh() + }, [refresh]) + + return ( + + + + {t('nodeapp.title')} +
+ } + value={search} + onChange={(e) => setSearch(e.target.value)} + /> + +
+
+ + + + + + + {loading ? ( +
+ +
+ ) : isEmpty(filteredApps) ? ( +
+ +

{t('nodeapp.empty')}

+ +
+ } + /> + + ) : ( +
+ {t('nodeapp.featured')} + + {filteredApps.map((app) => ( + + + + ))} + +
+ )} + + + + + + + + setIsModalVisible(false)} + footer={null} + width={600} + > + setIsModalVisible(false)} + loading={formLoading} + /> + +
+ ) +} + +const Container = styled.div` + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; +` + +const ContentContainer = styled.div` + flex: 1; + overflow: auto; + padding-bottom: 20px; +` + +export default NodeAppsPage diff --git a/src/renderer/src/pages/nodeapps/NodeSettings.tsx b/src/renderer/src/pages/nodeapps/NodeSettings.tsx new file mode 100644 index 0000000000..76aafc9bad --- /dev/null +++ b/src/renderer/src/pages/nodeapps/NodeSettings.tsx @@ -0,0 +1,198 @@ +import React, { FC, useEffect, useState } from 'react' +import { Button, Card, Form, Input, Select, Typography, notification, Space } from 'antd' +import { useTranslation } from 'react-i18next' +import styled from 'styled-components' +import { LoadingOutlined, SyncOutlined } from '@ant-design/icons' + +const { Title, Text } = Typography +const { Option } = Select + +const NodeSettings: FC = () => { + const { t } = useTranslation() + const [form] = Form.useForm() + const [loading, setLoading] = useState(false) + const [checkingVersion, setCheckingVersion] = useState(false) + const [nodeInstalled, setNodeInstalled] = useState(false) + const [currentVersion, setCurrentVersion] = useState('') + + // 默认提供的Node.js版本选项 + const nodeVersions = [ + { value: '20.11.1', label: 'v20.11.1 (LTS)' }, + { value: '18.18.0', label: 'v18.18.0 (LTS)' }, + { value: '16.20.2', label: 'v16.20.2 (LTS)' }, + { value: '14.21.3', label: 'v14.21.3 (LTS)' } + ] + + // 检查Node.js是否已安装 + const checkNodeStatus = async () => { + try { + setCheckingVersion(true) + const isNodeInstalled = await window.api.nodeapp.checkNode() + setNodeInstalled(isNodeInstalled) + + if (isNodeInstalled) { + try { + // 获取当前安装的Node.js版本 + // 使用ipc调用获取Node.js版本 + const versionFromConfig = await window.api.config.get('NODE_VERSION') + if (versionFromConfig) { + setCurrentVersion(versionFromConfig) + } else { + setCurrentVersion('Unknown') + } + } catch (error) { + console.error('Error getting Node.js version:', error) + setCurrentVersion('Unknown') + } + } + } catch (error) { + console.error('Error checking Node.js status:', error) + } finally { + setCheckingVersion(false) + } + } + + // 组件加载时检查状态 + useEffect(() => { + checkNodeStatus() + }, []) + + // 安装Node.js + const handleInstall = async (values: any) => { + try { + setLoading(true) + + // 设置环境变量来指定要安装的Node.js版本 + if (values.nodeVersion) { + await window.api.config.set('NODE_VERSION', values.nodeVersion) + } + + const success = await window.api.nodeapp.installNode() + + if (success) { + notification.success({ + message: t('common.success'), + description: t('nodeapp.nodeSettings.installSuccess', { + version: values.nodeVersion + }) + }) + + // 重新检查状态 + await checkNodeStatus() + } else { + notification.error({ + message: t('common.error'), + description: t('nodeapp.nodeSettings.installFailed') + }) + } + } catch (error) { + console.error('Error installing Node.js:', error) + notification.error({ + message: t('common.error'), + description: error instanceof Error ? error.message : String(error) + }) + } finally { + setLoading(false) + } + } + + return ( + + {t('nodeapp.nodeSettings.title')}}> + + {t('nodeapp.nodeSettings.description')} + + + {t('nodeapp.nodeSettings.status')}: + {checkingVersion ? ( + + + {t('nodeapp.nodeSettings.checking')} + + ) : nodeInstalled ? ( + + {t('nodeapp.nodeSettings.installed')} + {currentVersion && ` (${currentVersion})`} + + ) : ( + {t('nodeapp.nodeSettings.notInstalled')} + )} + + + +
+ + + + + + { + if (e.target.value) { + form.setFieldsValue({ nodeVersion: e.target.value }) + } + }} + /> + + + + + +
+
+
+
+ ) +} + +const Container = styled.div` + margin: 16px; +` + +const StatusSection = styled.div` + display: flex; + align-items: center; + gap: 8px; + margin: 16px 0; + padding: 12px; + background-color: #f5f5f5; + border-radius: 4px; +` + +export default NodeSettings diff --git a/src/renderer/src/pages/nodeapps/PackageDeployer.tsx b/src/renderer/src/pages/nodeapps/PackageDeployer.tsx new file mode 100644 index 0000000000..ded6bcaca1 --- /dev/null +++ b/src/renderer/src/pages/nodeapps/PackageDeployer.tsx @@ -0,0 +1,580 @@ +import { CloudUploadOutlined, GithubOutlined, LoadingOutlined, SettingOutlined, InfoCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons' +import { FileType } from '@renderer/types' +import { + Alert, + Button, + Card, + Collapse, + Form, + Input, + Modal, + Space, + Spin, + Tabs, + Typography, + Upload, + notification, + Popover, + Select, + Checkbox +} from 'antd' +import React, { FC, useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import styled from 'styled-components' + +const { Title, Text } = Typography +const { Panel } = Collapse +const { TabPane } = Tabs +const { Option } = Select + +interface Props { + onDeployed?: (result: { port: number; url: string }) => void +} + +const PackageDeployer: FC = ({ onDeployed }) => { + const { t } = useTranslation() + const [form] = Form.useForm() + const [gitForm] = Form.useForm() + const [loading, setLoading] = useState(false) + const [gitLoading, setGitLoading] = useState(false) + const [file, setFile] = useState(null) + const [advancedVisible, setAdvancedVisible] = useState(false) + const [gitAdvancedVisible, setGitAdvancedVisible] = useState(false) + const [isNodeAvailable, setIsNodeAvailable] = useState(null) + const [isInstallingNode, setIsInstallingNode] = useState(false) + const [uploadUrl, setUploadUrl] = useState('') + const [activeTab, setActiveTab] = useState('zip') + + // Check if Node.js is available + useEffect(() => { + const checkNodeAvailability = async () => { + try { + const isAvailable = await window.api.nodeapp.checkNode() + setIsNodeAvailable(isAvailable) + } catch (error) { + console.error('Error checking Node.js availability:', error) + setIsNodeAvailable(false) + } + } + + checkNodeAvailability() + }, []) + + // Handle Node.js installation + const handleInstallNode = async () => { + try { + setIsInstallingNode(true) + const success = await window.api.nodeapp.installNode() + + if (success) { + setIsNodeAvailable(true) + notification.success({ + message: t('common.success'), + description: t('nodeapp.packageDeployer.nodeInstallSuccess') + }) + } else { + notification.error({ + message: t('common.error'), + description: t('nodeapp.packageDeployer.nodeInstallFailed') + }) + } + } catch (error) { + console.error('Error installing Node.js:', error) + notification.error({ + message: t('common.error'), + description: error instanceof Error ? error.message : String(error) + }) + } finally { + setIsInstallingNode(false) + } + } + + const handleFileSelect = async () => { + try { + const files = await window.api.file.select({ + filters: [ + { name: 'ZIP Files', extensions: ['zip'] } + ], + properties: ['openFile'] + }) + + if (files && files.length > 0) { + setFile(files[0]) + form.setFieldsValue({ + name: files[0].name.replace(/\.zip$/, ''), + file: files[0] + }) + setUploadUrl(files[0].path) + } + } catch (error) { + console.error('Error selecting file:', error) + } + } + + const handleDeploy = async (values: any) => { + // First check if Node.js is available + if (isNodeAvailable === false) { + Modal.confirm({ + title: t('nodeapp.packageDeployer.nodeRequired'), + content: t('nodeapp.packageDeployer.installNodePrompt'), + okText: t('nodeapp.packageDeployer.installNode'), + cancelText: t('common.cancel'), + onOk: handleInstallNode + }) + return + } + + if (!file) { + notification.warning({ + message: t('common.warning'), + description: t('nodeapp.packageDeployer.noFileSelected') + }) + return + } + + try { + setLoading(true) + + // 检测是否为Next.js应用,如果文件名包含next或文件是从next.js项目导出的 + const isNextJs = file.name.toLowerCase().includes('next') || + (values.isNextJs === true); + + // 如果是Next.js应用,自动设置构建步骤 + if (isNextJs && !values.buildCommand) { + values.buildCommand = 'npm run build'; + notification.info({ + message: t('nodeapp.packageDeployer.nextJsDetected'), + description: t('nodeapp.packageDeployer.buildStepAdded'), + duration: 5 + }); + } + + // Display note about ES modules compatibility + if (file.name.includes('react') || file.name.includes('next') || file.name.includes('vue')) { + notification.info({ + message: t('nodeapp.packageDeployer.moduleTypeError'), + description: t('nodeapp.packageDeployer.esModuleError'), + duration: 8 + }) + } + + // Deploy the ZIP package + const result = await window.api.nodeapp.deployZip(file.path, { + name: values.name, + port: values.port ? parseInt(values.port) : undefined, + startCommand: values.startCommand, + installCommand: values.installCommand, + buildCommand: values.buildCommand + }) + + if (result) { + notification.success({ + message: t('common.success'), + description: t('nodeapp.packageDeployer.deploySuccess', { + name: values.name, + port: result.port + }), + btn: ( + + ) + }) + + // Reset form and state + form.resetFields() + setFile(null) + setAdvancedVisible(false) + setUploadUrl('') + + // Notify parent + if (onDeployed) { + onDeployed(result) + } + } else { + notification.error({ + message: t('common.error'), + description: t('nodeapp.packageDeployer.deployFailed') + }) + } + } catch (error) { + console.error('Error deploying ZIP:', error) + notification.error({ + message: t('common.error'), + description: error instanceof Error ? error.message : String(error) + }) + } finally { + setLoading(false) + } + } + + const handleDeployGit = async (values: any) => { + // First check if Node.js is available + if (isNodeAvailable === false) { + Modal.confirm({ + title: t('nodeapp.packageDeployer.nodeRequired'), + content: t('nodeapp.packageDeployer.installNodePrompt'), + okText: t('nodeapp.packageDeployer.installNode'), + cancelText: t('common.cancel'), + onOk: handleInstallNode + }) + return + } + + if (!values.repoUrl) { + notification.warning({ + message: t('common.warning'), + description: t('nodeapp.packageDeployer.noRepoUrlProvided') + }) + return + } + + try { + setGitLoading(true) + + // 检测是否为Next.js应用 + const isNextJs = values.repoUrl.toLowerCase().includes('next') || + (values.isNextJs === true); + + // 如果是Next.js应用,自动设置构建步骤 + if (isNextJs && !values.buildCommand) { + values.buildCommand = 'npm run build'; + notification.info({ + message: t('nodeapp.packageDeployer.nextJsDetected'), + description: t('nodeapp.packageDeployer.buildStepAdded'), + duration: 5 + }); + } + + // Deploy from Git repository + const result = await window.api.nodeapp.deployGit(values.repoUrl, { + name: values.name, + port: values.port ? parseInt(values.port) : undefined, + startCommand: values.startCommand, + installCommand: values.installCommand, + buildCommand: values.buildCommand + }) + + if (result) { + notification.success({ + message: t('common.success'), + description: t('nodeapp.packageDeployer.deploySuccess', { + name: values.name || 'Git App', + port: result.port + }), + btn: ( + + ) + }) + + // Reset form and state + gitForm.resetFields() + setGitAdvancedVisible(false) + + // Notify parent + if (onDeployed) { + onDeployed(result) + } + } else { + notification.error({ + message: t('common.error'), + description: t('nodeapp.packageDeployer.deployFailed') + }) + } + } catch (error) { + console.error('Error deploying from Git:', error) + notification.error({ + message: t('common.error'), + description: error instanceof Error ? error.message : String(error) + }) + } finally { + setGitLoading(false) + } + } + + return ( + + + {isNodeAvailable === false && ( + + {t('nodeapp.packageDeployer.nodeNeeded')} + + + } + style={{ marginBottom: 16 }} + /> + )} + + + + {t('nodeapp.packageDeployer.deployFromZip')} + + } + key="zip" + > +
+ + {t('nodeapp.packageDeployer.description')} + + + {file ? ( + +
+ + {file.name} +
+ +
+ ) : ( + + +
{t('nodeapp.packageDeployer.selectZip')}
+
+ )} +
+ + + + + + setAdvancedVisible(!advancedVisible)} + > + + + {t('nodeapp.packageDeployer.advancedOptions')} + + } + key="1" + > + + + + + + + + + + + + + + + + + + { + if (e.target.checked) { + form.setFieldsValue({ + buildCommand: 'npm run build', + startCommand: 'npm run start', + installCommand: 'npm install --legacy-peer-deps' + }); + } + }}>{t('nodeapp.form.isNextJs')} + + + + + + + + + +
+
+
+ + + {t('nodeapp.packageDeployer.deployFromGit')} + + } + key="git" + > +
+ + + + + + + + + + {t('nodeapp.form.port')} + + + + + } + > + + + + + + {gitAdvancedVisible && ( + + + + + + + + + + + + + + + + { + if (e.target.checked) { + gitForm.setFieldsValue({ + buildCommand: 'npm run build', + startCommand: 'npm run start', + installCommand: 'npm install --legacy-peer-deps' + }); + } + }}>{t('nodeapp.form.isNextJs')} + + + + )} + + + + +
+
+
+
+
+ ) +} + +const Container = styled.div` + margin: 16px; +` + +const UploadContainer = styled.div` + margin-bottom: 16px; + border: 1px dashed #d9d9d9; + border-radius: 4px; + background-color: #fafafa; + transition: border-color 0.3s; + + &:hover { + border-color: #1890ff; + } +` + +const UploadButton = styled.div` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100px; + cursor: pointer; + padding: 16px; +` + +const FileInfo = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px; +` + +export default PackageDeployer diff --git a/src/renderer/src/pages/nodeapps/index.tsx b/src/renderer/src/pages/nodeapps/index.tsx new file mode 100644 index 0000000000..971979f7d5 --- /dev/null +++ b/src/renderer/src/pages/nodeapps/index.tsx @@ -0,0 +1,39 @@ +import React, { useState } from 'react' +import { Tabs } from 'antd' +import { useTranslation } from 'react-i18next' +import styled from 'styled-components' +import AppsManager from './AppsManager' +import PackageDeployer from './PackageDeployer' +import NodeSettings from './NodeSettings' + +const NodeAppsPage: React.FC = () => { + const { t } = useTranslation() + const [activeTab, setActiveTab] = useState('apps') + + const handleTabChange = (key: string) => { + setActiveTab(key) + } + + return ( + + + + + + + + + + + + + + ) +} + +const Container = styled.div` + padding: 0; + height: 100%; +` + +export default NodeAppsPage diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts index 0f4b5a423a..8722de153a 100644 --- a/src/renderer/src/store/index.ts +++ b/src/renderer/src/store/index.ts @@ -12,6 +12,7 @@ import mcp from './mcp' import messagesReducer from './messages' import migrate from './migrate' import minapps from './minapps' +import nodeapps from './nodeapps' import paintings from './paintings' import runtime from './runtime' import settings from './settings' @@ -31,6 +32,7 @@ const rootReducer = combineReducers({ websearch, mcp, copilot, + nodeapps, messages: messagesReducer }) diff --git a/src/renderer/src/store/nodeapps.ts b/src/renderer/src/store/nodeapps.ts new file mode 100644 index 0000000000..3f4c51a053 --- /dev/null +++ b/src/renderer/src/store/nodeapps.ts @@ -0,0 +1,71 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit' +import { NodeAppType } from '@renderer/types' + +// Define featured Node.js apps - you can add more as needed +export const FEATURED_NODE_APPS: NodeAppType[] = [ + { + id: 'writing-helper', + name: 'Writing Helper', + url: 'http://localhost:3000', + type: 'node', + repositoryUrl: 'https://github.com/GeekyWizKid/writing-helper', + description: 'AI writing assistant supporting multiple LLM APIs with rich style customization features.', + author: 'GeekyWizKid', + homepage: 'https://github.com/GeekyWizKid/writing-helper', + installCommand: 'npm install', + startCommand: 'npm run dev', + isInstalled: false, + isRunning: false + } +] + +export interface NodeAppsState { + apps: NodeAppType[] + loading: boolean + error: string | null +} + +const initialState: NodeAppsState = { + apps: [...FEATURED_NODE_APPS], + loading: false, + error: null +} + +const nodeAppsSlice = createSlice({ + name: 'nodeApps', + initialState, + reducers: { + setNodeApps: (state, action: PayloadAction) => { + state.apps = action.payload + }, + addNodeApp: (state, action: PayloadAction) => { + state.apps.push(action.payload) + }, + updateNodeApp: (state, action: PayloadAction) => { + const index = state.apps.findIndex(app => app.id === action.payload.id) + if (index !== -1) { + state.apps[index] = action.payload + } + }, + removeNodeApp: (state, action: PayloadAction) => { + state.apps = state.apps.filter(app => app.id !== action.payload) + }, + setLoading: (state, action: PayloadAction) => { + state.loading = action.payload + }, + setError: (state, action: PayloadAction) => { + state.error = action.payload + } + } +}) + +export const { + setNodeApps, + addNodeApp, + updateNodeApp, + removeNodeApp, + setLoading, + setError +} = nodeAppsSlice.actions + +export default nodeAppsSlice.reducer diff --git a/src/renderer/src/store/settings.ts b/src/renderer/src/store/settings.ts index 21c03934b5..24bb95b24a 100644 --- a/src/renderer/src/store/settings.ts +++ b/src/renderer/src/store/settings.ts @@ -4,7 +4,7 @@ import { CodeStyleVarious, LanguageVarious, ThemeMode, TranslateLanguageVarious export type SendMessageShortcut = 'Enter' | 'Shift+Enter' | 'Ctrl+Enter' | 'Command+Enter' -export type SidebarIcon = 'assistants' | 'agents' | 'paintings' | 'translate' | 'minapp' | 'knowledge' | 'files' +export type SidebarIcon = 'assistants' | 'agents' | 'paintings' | 'translate' | 'minapp' | 'nodeapps' | 'knowledge' | 'files' export const DEFAULT_SIDEBAR_ICONS: SidebarIcon[] = [ 'assistants', @@ -12,6 +12,7 @@ export const DEFAULT_SIDEBAR_ICONS: SidebarIcon[] = [ 'paintings', 'translate', 'minapp', + 'nodeapps', 'knowledge', 'files' ] diff --git a/src/renderer/src/types/index.ts b/src/renderer/src/types/index.ts index f520895f8b..1217b213a1 100644 --- a/src/renderer/src/types/index.ts +++ b/src/renderer/src/types/index.ts @@ -164,6 +164,21 @@ export type MinAppType = { style?: React.CSSProperties } +export type NodeAppType = MinAppType & { + type: 'node' + repositoryUrl?: string + version?: string + description?: string + author?: string + homepage?: string + installCommand?: string + buildCommand?: string + startCommand?: string + port?: number + isInstalled?: boolean + isRunning?: boolean +} + export interface FileType { id: string name: string