From b801d59352d02a8b5035ac5112ebd53248638877 Mon Sep 17 00:00:00 2001 From: Kallum Jones Date: Fri, 5 Aug 2022 16:56:04 +0100 Subject: [PATCH] Changed Minecraft Version tracking to manual input rather than auto-detecting --- package-lock.json | 431 +++++++++++++++++++++++++- package.json | 2 + src/commands/init_command.ts | 4 +- src/errors/minecraft_version_error.ts | 7 + src/io/file_downloder.ts | 4 +- src/mod-manager.ts | 16 +- src/mods/mods.ts | 14 +- src/util/initialiser.ts | 51 ++- src/util/minecraft_utils.ts | 44 ++- 9 files changed, 513 insertions(+), 60 deletions(-) create mode 100644 src/errors/minecraft_version_error.ts diff --git a/package-lock.json b/package-lock.json index b41f9d7..466cfe3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,12 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@types/inquirer": "^9.0.0", "as-table": "^1.0.55", "axios": "^0.27.2", "chalk": "^5.0.1", "commander": "^9.4.0", + "inquirer": "^9.1.0", "ora": "^6.1.2", "pino": "^8.3.1", "string-format": "^2.0.0", @@ -23,11 +25,27 @@ "typescript": "^4.7.4" } }, + "node_modules/@types/inquirer": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.0.tgz", + "integrity": "sha512-4sncHTq3AWbLWZOs83DQlrKxhdehs2AW79Dp1amoGGc6B+oJal7fQJa/EO1Taa5CQLSywEMAgw2SFB1fZIX3PQ==", + "dependencies": { + "@types/through": "*", + "rxjs": "^7.2.0" + } + }, "node_modules/@types/node": { "version": "18.6.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz", - "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==", - "dev": true + "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==" + }, + "node_modules/@types/through": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", + "integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==", + "dependencies": { + "@types/node": "*" + } }, "node_modules/abort-controller": { "version": "3.0.0", @@ -40,6 +58,20 @@ "node": ">=6.5" } }, + "node_modules/ansi-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "dependencies": { + "type-fest": "^1.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -51,6 +83,17 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, + "node_modules/ansi-styles": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz", + "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/as-table": { "version": "1.0.55", "resolved": "https://registry.npmjs.org/as-table/-/as-table-1.0.55.tgz", @@ -144,6 +187,11 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -169,6 +217,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-width": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.0.0.tgz", + "integrity": "sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw==", + "engines": { + "node": ">= 12" + } + }, "node_modules/clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", @@ -212,6 +268,27 @@ "node": ">=0.4.0" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -220,6 +297,19 @@ "node": ">=6" } }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/fast-redact": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.1.tgz", @@ -228,6 +318,21 @@ "node": ">=6" } }, + "node_modules/figures": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/figures/-/figures-4.0.1.tgz", + "integrity": "sha512-rElJwkA/xS04Vfg+CaZodpso7VqBknOYbzi6I76hI4X80RUjkSxO2oAyPmGbuXUppywjqndOrQDl817hDnI++w==", + "dependencies": { + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/follow-redirects": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", @@ -260,6 +365,17 @@ "node": ">= 6" } }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -284,6 +400,31 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/inquirer": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.1.0.tgz", + "integrity": "sha512-eukdjrBljg9t55ZnvJjvGi1OyYEzVBFsO/8o5d2MV3mc28u3x4X2kS4eJ/+9U10KiREfPkEBSeCrU/S2G/uRtw==", + "dependencies": { + "ansi-escapes": "^5.0.0", + "chalk": "^5.0.1", + "cli-cursor": "^4.0.0", + "cli-width": "^4.0.0", + "external-editor": "^3.0.3", + "figures": "^4.0.1", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^6.1.2", + "run-async": "^2.4.0", + "rxjs": "^7.5.6", + "string-width": "^5.1.2", + "strip-ansi": "^7.0.1", + "through": "^2.3.6", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/is-interactive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", @@ -306,6 +447,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/log-symbols": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", @@ -348,6 +494,11 @@ "node": ">=6" } }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, "node_modules/on-exit-leak-free": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", @@ -389,6 +540,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pino": { "version": "8.3.1", "resolved": "https://registry.npmjs.org/pino/-/pino-8.3.1.tgz", @@ -486,6 +645,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz", + "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -513,6 +688,11 @@ "node": ">=10" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -552,6 +732,22 @@ "resolved": "https://registry.npmjs.org/string-similarity-js/-/string-similarity-js-2.1.4.tgz", "integrity": "sha512-uApODZNjCHGYROzDSAdCmAHf60L/pMDHnP/yk6TAbvGg7JSPZlSto/ceCI7hZEqzc53/juU2aOJFkM2yUVTMTA==" }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-ansi": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", @@ -582,6 +778,38 @@ "node": ">= 12.13.0" } }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", @@ -607,14 +835,46 @@ "dependencies": { "defaults": "^1.0.3" } + }, + "node_modules/wrap-ansi": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.0.1.tgz", + "integrity": "sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } } }, "dependencies": { + "@types/inquirer": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.0.tgz", + "integrity": "sha512-4sncHTq3AWbLWZOs83DQlrKxhdehs2AW79Dp1amoGGc6B+oJal7fQJa/EO1Taa5CQLSywEMAgw2SFB1fZIX3PQ==", + "requires": { + "@types/through": "*", + "rxjs": "^7.2.0" + } + }, "@types/node": { "version": "18.6.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz", - "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==", - "dev": true + "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==" + }, + "@types/through": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", + "integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==", + "requires": { + "@types/node": "*" + } }, "abort-controller": { "version": "3.0.0", @@ -624,11 +884,24 @@ "event-target-shim": "^5.0.0" } }, + "ansi-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "requires": { + "type-fest": "^1.0.2" + } + }, "ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" }, + "ansi-styles": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz", + "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==" + }, "as-table": { "version": "1.0.55", "resolved": "https://registry.npmjs.org/as-table/-/as-table-1.0.55.tgz", @@ -685,6 +958,11 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==" }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -698,6 +976,11 @@ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==" }, + "cli-width": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.0.0.tgz", + "integrity": "sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw==" + }, "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", @@ -729,16 +1012,50 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" + }, "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "fast-redact": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.1.tgz", "integrity": "sha512-odVmjC8x8jNeMZ3C+rPMESzXVSEU8tSWSHv9HFxP2mm89G/1WwqhrerJDQm9Zus8X6aoRgQDThKqptdNA6bt+A==" }, + "figures": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/figures/-/figures-4.0.1.tgz", + "integrity": "sha512-rElJwkA/xS04Vfg+CaZodpso7VqBknOYbzi6I76hI4X80RUjkSxO2oAyPmGbuXUppywjqndOrQDl817hDnI++w==", + "requires": { + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" + } + }, "follow-redirects": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", @@ -754,6 +1071,14 @@ "mime-types": "^2.1.12" } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -764,6 +1089,28 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "inquirer": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.1.0.tgz", + "integrity": "sha512-eukdjrBljg9t55ZnvJjvGi1OyYEzVBFsO/8o5d2MV3mc28u3x4X2kS4eJ/+9U10KiREfPkEBSeCrU/S2G/uRtw==", + "requires": { + "ansi-escapes": "^5.0.0", + "chalk": "^5.0.1", + "cli-cursor": "^4.0.0", + "cli-width": "^4.0.0", + "external-editor": "^3.0.3", + "figures": "^4.0.1", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^6.1.2", + "run-async": "^2.4.0", + "rxjs": "^7.5.6", + "string-width": "^5.1.2", + "strip-ansi": "^7.0.1", + "through": "^2.3.6", + "wrap-ansi": "^8.0.1" + } + }, "is-interactive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", @@ -774,6 +1121,11 @@ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.2.0.tgz", "integrity": "sha512-wH+U77omcRzevfIG8dDhTS0V9zZyweakfD01FULl97+0EHiJTTZtJqxPSkIIo/SDPv/i07k/C9jAPY+jwLLeUQ==" }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "log-symbols": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", @@ -801,6 +1153,11 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, "on-exit-leak-free": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", @@ -830,6 +1187,11 @@ "wcwidth": "^1.0.1" } }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" + }, "pino": { "version": "8.3.1", "resolved": "https://registry.npmjs.org/pino/-/pino-8.3.1.tgz", @@ -911,6 +1273,19 @@ "signal-exit": "^3.0.2" } }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + }, + "rxjs": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz", + "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", + "requires": { + "tslib": "^2.1.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -921,6 +1296,11 @@ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz", "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==" }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -957,6 +1337,16 @@ "resolved": "https://registry.npmjs.org/string-similarity-js/-/string-similarity-js-2.1.4.tgz", "integrity": "sha512-uApODZNjCHGYROzDSAdCmAHf60L/pMDHnP/yk6TAbvGg7JSPZlSto/ceCI7hZEqzc53/juU2aOJFkM2yUVTMTA==" }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, "strip-ansi": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", @@ -980,6 +1370,29 @@ } } }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==" + }, "typescript": { "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", @@ -998,6 +1411,16 @@ "requires": { "defaults": "^1.0.3" } + }, + "wrap-ansi": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.0.1.tgz", + "integrity": "sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==", + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } } } } diff --git a/package.json b/package.json index b08d752..11f6264 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,12 @@ "author": "", "license": "ISC", "dependencies": { + "@types/inquirer": "^9.0.0", "as-table": "^1.0.55", "axios": "^0.27.2", "chalk": "^5.0.1", "commander": "^9.4.0", + "inquirer": "^9.1.0", "ora": "^6.1.2", "pino": "^8.3.1", "string-format": "^2.0.0", diff --git a/src/commands/init_command.ts b/src/commands/init_command.ts index 7ea26dd..72c40ed 100644 --- a/src/commands/init_command.ts +++ b/src/commands/init_command.ts @@ -6,8 +6,8 @@ export default class InitCommand implements Subcommand { registerCommand(program: Command) { program.command("init") .description("Initialises mod manager") - .action(() => { - Initialiser.initialise(); + .action(async () => { + await Initialiser.initialise(); }); } } \ No newline at end of file diff --git a/src/errors/minecraft_version_error.ts b/src/errors/minecraft_version_error.ts new file mode 100644 index 0000000..81f0fa5 --- /dev/null +++ b/src/errors/minecraft_version_error.ts @@ -0,0 +1,7 @@ +export default class MinecraftVersionError extends Error { + constructor(message: string | undefined) { + super(message); + this.name = this.constructor.name; + Error.captureStackTrace(this, this.constructor); + } +} \ No newline at end of file diff --git a/src/io/file_downloder.ts b/src/io/file_downloder.ts index 6db782e..a0e11ca 100644 --- a/src/io/file_downloder.ts +++ b/src/io/file_downloder.ts @@ -2,13 +2,13 @@ import path from "path"; import * as https from "https"; import {createWriteStream} from "fs"; import DownloadError from "../errors/download_error.js"; -import Mods from "../mods/mods.js"; +import ModManager from "../mod-manager.js"; export default class FileDownloader { static downloadMod(task: DownloadTask): void { https.get(task.url, res => { - const filePath = path.join(Mods.MODS_FOLDER_PATH, task.fileName); + const filePath = path.join(ModManager.FilePaths.MODS_FOLDER_PATH, task.fileName); const writeStream = createWriteStream(filePath); res.pipe(writeStream); writeStream.on("finish", () => writeStream.close()); diff --git a/src/mod-manager.ts b/src/mod-manager.ts index 38d9edd..cde7c26 100644 --- a/src/mod-manager.ts +++ b/src/mod-manager.ts @@ -15,7 +15,6 @@ import {readFileSync, unlinkSync} from "fs"; export default class ModManager { public static logger: Logger | null = null; - private static readonly LOG_FILE: string = path.join(Initialiser.getModManagerFolderPath(), "logs", `${new Date().valueOf()}.log.json`); private static program: Command = new Command(); @@ -27,6 +26,15 @@ export default class ModManager { new EssentialCommand() ]; + static FilePaths = class { + public static readonly MOD_MANAGER_FOLDER_PATH = path.join(".mod-manager"); + public static readonly LOGS_FOLDER = path.join(this.MOD_MANAGER_FOLDER_PATH, "logs"); + public static readonly LOG_FILE: string = path.join(this.LOGS_FOLDER, `${new Date().valueOf()}.log.json`); + public static readonly MOD_FILE_PATH = path.join(this.MOD_MANAGER_FOLDER_PATH, "mods.json"); + public static readonly VERSION_FILE_PATH = path.join(this.MOD_MANAGER_FOLDER_PATH, "version") + public static readonly MODS_FOLDER_PATH = path.join("mods") + } + static init() { if (Initialiser.isInitialised()) { this.logger = ModManager.createLogger(); @@ -58,7 +66,7 @@ export default class ModManager { hostname: undefined} }, pino.destination({ - dest: this.LOG_FILE, + dest: ModManager.FilePaths.LOG_FILE, sync: true }) ); @@ -71,8 +79,8 @@ export default class ModManager { // If no errors are logged, cleanup the log file when the process exits process.on("exit", () => { // If file is only whitespace, i.e. blank - if (!readFileSync(this.LOG_FILE, "utf-8")?.trim().length) { - unlinkSync(this.LOG_FILE) + if (!readFileSync(ModManager.FilePaths.LOG_FILE, "utf-8")?.trim().length) { + unlinkSync(ModManager.FilePaths.LOG_FILE) } }) diff --git a/src/mods/mods.ts b/src/mods/mods.ts index 1223553..cf5d428 100644 --- a/src/mods/mods.ts +++ b/src/mods/mods.ts @@ -1,16 +1,14 @@ import path from "path"; -import Initialiser from "../util/initialiser.js"; import PrintUtils from "../util/print_utils.js"; import ModrinthSource from "./sources/modrinth_source.js"; import ModSource from "./sources/mod_source.js"; import ModNotFoundError from "../errors/mod_not_found_error.js"; import {readFileSync, unlinkSync, writeFileSync} from "fs"; import Util from "../util/util.js"; +import ModManager from "../mod-manager.js"; export default class Mods { - public static readonly MOD_FILE = "mods.json"; - public static readonly MODS_FOLDER_PATH: string = path.join("mods"); private static readonly MOD_SOURCES: Array = [ new ModrinthSource() ]; @@ -64,10 +62,6 @@ export default class Mods { } } - public static getModFilePath(): string { - return path.join(Initialiser.getModManagerFolderPath(), this.MOD_FILE); - } - private static trackMod(mod: Mod): void { // Read current file const mods = this.getTrackedMods(); @@ -80,12 +74,12 @@ export default class Mods { } public static getTrackedMods(): Array { - const file = readFileSync(this.getModFilePath(), "utf-8"); + const file = readFileSync(ModManager.FilePaths.MOD_FILE_PATH, "utf-8"); return JSON.parse(file); } public static writeFile(mods: Array): void { - writeFileSync(this.getModFilePath(), JSON.stringify(mods, null, 4)); + writeFileSync(ModManager.FilePaths.MOD_FILE_PATH, JSON.stringify(mods, null, 4)); } private static isModInstalled(id: string): boolean { @@ -103,7 +97,7 @@ export default class Mods { let mods: Array = this.getTrackedMods(); // Remove mod from list and uninstall it - unlinkSync(path.join(this.MODS_FOLDER_PATH, modToUninstall.fileName)); + unlinkSync(path.join(ModManager.FilePaths.MOD_FILE_PATH, modToUninstall.fileName)); mods = mods.filter(item => !Mods.areModsEqual(item, modToUninstall)); this.writeFile(mods); spinner.succeed(`${modToUninstall.name} successfully uninstalled!`) diff --git a/src/util/initialiser.ts b/src/util/initialiser.ts index 73c00cf..f5dd158 100644 --- a/src/util/initialiser.ts +++ b/src/util/initialiser.ts @@ -1,18 +1,21 @@ import {existsSync, mkdirSync, writeFileSync} from "fs"; import path from "path"; -import Mods from "../mods/mods.js"; import PrintUtils from "./print_utils.js"; import ModManager from "../mod-manager.js"; +import inquirer from "inquirer"; +import MinecraftUtils from "./minecraft_utils.js"; +import MinecraftVersionError from "../errors/minecraft_version_error.js"; export default class Initialiser { - private static readonly MOD_MANAGER_FOLDER = ".mod-manager" - - public static initialise(): void { + public static async initialise(): Promise { if (!this.isInitialised()) { if (this.isDirFabricServer()) { const success: boolean = this.setupFolderStructure(); if (success) { + const version = await this.getMinecraftVersionFromInput(); + await MinecraftUtils.updateCurrentMinecraftVersion(version) + PrintUtils.success("Sucessfully initialised Mod Manager!"); // Initialise a logger when Mod Manager is initialised @@ -32,11 +35,7 @@ export default class Initialiser { } public static isInitialised(): boolean { - return existsSync(this.getModManagerFolderPath()); - } - - public static getModManagerFolderPath(): string { - return path.join(this.MOD_MANAGER_FOLDER); + return existsSync(ModManager.FilePaths.MOD_MANAGER_FOLDER_PATH); } private static isDirFabricServer(): boolean { @@ -47,14 +46,40 @@ export default class Initialiser { } private static setupFolderStructure(): boolean { - if (!existsSync(this.getModManagerFolderPath())) { - mkdirSync(this.getModManagerFolderPath()); - writeFileSync(Mods.getModFilePath(), "[]"); - mkdirSync(path.join(this.getModManagerFolderPath(), "logs")) + if (!existsSync(ModManager.FilePaths.MOD_MANAGER_FOLDER_PATH)) { + mkdirSync(ModManager.FilePaths.MOD_MANAGER_FOLDER_PATH); + writeFileSync(ModManager.FilePaths.MOD_FILE_PATH, "[]"); + mkdirSync(ModManager.FilePaths.LOGS_FOLDER) + writeFileSync(ModManager.FilePaths.VERSION_FILE_PATH, "") return true; } else { return false; } } + private static async getMinecraftVersionFromInput() { + let isVersionValid = false; + + let version: string | undefined = undefined; + while (!isVersionValid) { + const answer = await inquirer.prompt([{ + type: "input", + name: "minecraft_version", + message: "What version of Minecraft is the server running?" + }]) + version = answer.minecraft_version; + + if (await MinecraftUtils.isValidVersion(version)) { + isVersionValid = true; + } else { + PrintUtils.error(`${version} is not a valid Minecraft version for a Fabric server. Please try again`); + } + } + + if (version == undefined) { + throw new MinecraftVersionError("Escaped version input without a valid version") + } + + return version; + } } \ No newline at end of file diff --git a/src/util/minecraft_utils.ts b/src/util/minecraft_utils.ts index 2b58c2b..59c9de9 100644 --- a/src/util/minecraft_utils.ts +++ b/src/util/minecraft_utils.ts @@ -1,14 +1,19 @@ -import {readdirSync} from "fs"; -import path from "path"; +import {readFileSync, writeFileSync} from "fs"; import axios from "axios"; +import ModManager from "../mod-manager.js"; +import MinecraftVersionError from "../errors/minecraft_version_error.js"; export default class MinecraftUtils { static async getCurrentMinecraftVersion(): Promise { - // Get installed versions as strings - const installedVersions: Array = readdirSync(this.getVersionsFolderPath(), {withFileTypes: true}) - .filter(entry => entry.isDirectory()) - .map(entry => entry.name); + return readFileSync(ModManager.FilePaths.VERSION_FILE_PATH, "utf-8"); + } + static async isValidVersion(version: any) { + const allMinecraftVersions = await this.getAllMinecraftVersions(); + return allMinecraftVersions.includes(version); + } + + static async getAllMinecraftVersions(): Promise> { // Get a list of Minecraft Versions const response = await axios.get("https://meta.fabricmc.net/v2/versions/game"); const data = await response.data; @@ -18,27 +23,16 @@ export default class MinecraftUtils { minecraftVersions.push(ele.version); } - // Find the latest version that is currently installed - let index = Number.MAX_VALUE; - for (let version of installedVersions) { - let currentIndex = minecraftVersions.indexOf(version); - - // If this version, is newer than the previous newest, save it's index - if (currentIndex < index) { - index = currentIndex; - } - } - - const latestVersion = minecraftVersions[index]; - if (latestVersion == undefined) { - throw new Error("There are no Minecraft versions available in this server. Is this a valid server installation?"); - } - - return latestVersion; + return minecraftVersions; } - static getVersionsFolderPath(): string { - return path.join("versions") + static async updateCurrentMinecraftVersion(version: string) { + if (await MinecraftUtils.isValidVersion(version)) { + writeFileSync(ModManager.FilePaths.VERSION_FILE_PATH, version); + } else { + throw new MinecraftVersionError(`Attempted to update version file with invalid version: ${version}`) + } } + }