From bc43d842e382a88b53600e825ed973282813cede Mon Sep 17 00:00:00 2001 From: Daniel Scalzi Date: Mon, 24 Aug 2020 20:18:08 -0400 Subject: [PATCH] Pull out common got error handling for generic use. Initial distribution loading (no application state storage yet). --- package-lock.json | 654 ++++++++---------- package.json | 46 +- src/common/distribution/distribution.ts | 106 +++ src/common/got/RestResponse.ts | 43 ++ src/common/logging/loggerutil.ts | 6 +- .../mojang/model/internal/MojangResponse.ts | 87 +++ src/common/mojang/model/internal/Response.ts | 87 --- src/common/mojang/mojang.ts | 46 +- src/main/index.ts | 4 +- src/renderer/components/Application.tsx | 13 +- .../generic-overlay/GenericOverlay.tsx | 12 +- test/mojang/mojangTest.ts | 45 +- 12 files changed, 629 insertions(+), 520 deletions(-) create mode 100644 src/common/distribution/distribution.ts create mode 100644 src/common/got/RestResponse.ts create mode 100644 src/common/mojang/model/internal/MojangResponse.ts delete mode 100644 src/common/mojang/model/internal/Response.ts diff --git a/package-lock.json b/package-lock.json index f564cc3..8687ece 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1238,9 +1238,9 @@ }, "dependencies": { "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -1362,9 +1362,9 @@ } }, "@sindresorhus/is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.0.0.tgz", - "integrity": "sha512-kqA5I6Yun7PBHk8WN9BBP1c7FfN2SrD05GuVSEYPqDb4nerv7HqYfgBfMIKmT/EuejURkJKLZuLyGKGs6WEG9w==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.2.tgz", + "integrity": "sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ==" }, "@szmarczak/http-timer": { "version": "4.0.5", @@ -1404,13 +1404,6 @@ "@types/keyv": "*", "@types/node": "*", "@types/responselike": "*" - }, - "dependencies": { - "@types/node": { - "version": "14.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.23.tgz", - "integrity": "sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw==" - } } }, "@types/caseless": { @@ -1420,9 +1413,9 @@ "dev": true }, "@types/chai": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", - "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==", + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.12.tgz", + "integrity": "sha512-aN5IAC8QNtSUdQzxu7lGBgYAOuU1tmRU4c9dIq5OKGf/SBVjXo+ffM2wEjudAWbgpOhy60nLoAGH1xm8fpCKFQ==", "dev": true }, "@types/color-name": { @@ -1490,9 +1483,9 @@ "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==" }, "@types/jquery": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.0.tgz", - "integrity": "sha512-C7qQUjpMWDUNYQRTXsP5nbYYwCwwgy84yPgoTT7fPN69NH92wLeCtFaMsWeolJD1AF/6uQw3pYt62rzv83sMmw==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.1.tgz", + "integrity": "sha512-Tyctjh56U7eX2b9udu3wG853ASYP0uagChJcQJXLUXEU6C/JiW5qt5dl8ao01VRj1i5pgXPAf8f1mq4+FDLRQg==", "dev": true, "requires": { "@types/sizzle": "*" @@ -1516,19 +1509,12 @@ "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", "requires": { "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "14.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.23.tgz", - "integrity": "sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw==" - } } }, "@types/lodash": { - "version": "4.14.157", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.157.tgz", - "integrity": "sha512-Ft5BNFmv2pHDgxV5JDsndOWTRJ+56zte0ZpYLowp03tW+K+t8u8YMOzAnpuqPgzX6WO1XpDIUm7u04M8vdDiVQ==", + "version": "4.14.160", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.160.tgz", + "integrity": "sha512-aP03BShJoO+WVndoVj/WNcB/YBPt+CIU1mvaao2GRAHy2yg4pT/XS4XnVHEQBjPJGycWf/9seKEO9vopTJGkvA==", "dev": true }, "@types/minimatch": { @@ -1538,16 +1524,15 @@ "dev": true }, "@types/mocha": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.0.tgz", - "integrity": "sha512-jWeYcTo3sCH/rMgsdYXDTO85GNRyTCII5dayMIu/ZO4zbEot1E3iNGaOwpLReLUHjeNQFkgeNNVYlY4dX6azQQ==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.3.tgz", + "integrity": "sha512-vyxR57nv8NfcU0GZu8EUXZLTbCMupIUwy95LJ6lllN+JRPG25CwMHoB1q5xKh8YKhQnHYRAn4yW2yuHbf/5xgg==", "dev": true }, "@types/node": { - "version": "12.12.50", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.50.tgz", - "integrity": "sha512-5ImO01Fb8YsEOYpV+aeyGYztcYcjGsBvN4D7G5r1ef2cuQOpymjWNQi5V0rKHE6PC2ru3HkoUr/Br2/8GUA84w==", - "dev": true + "version": "12.12.54", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.54.tgz", + "integrity": "sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w==" }, "@types/prop-types": { "version": "15.7.3", @@ -1556,13 +1541,21 @@ "dev": true }, "@types/react": { - "version": "16.9.43", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.43.tgz", - "integrity": "sha512-PxshAFcnJqIWYpJbLPriClH53Z2WlJcVZE+NP2etUtWQs2s7yIMj3/LDKZT/5CHJ/F62iyjVCDu2H3jHEXIxSg==", + "version": "16.9.46", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.46.tgz", + "integrity": "sha512-dbHzO3aAq1lB3jRQuNpuZ/mnu+CdD3H0WVaaBQA8LTT3S33xhVBUj232T8M3tAhSWJs/D/UqORYUlJNl/8VQZg==", "dev": true, "requires": { "@types/prop-types": "*", - "csstype": "^2.2.0" + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz", + "integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==", + "dev": true + } } }, "@types/react-dom": { @@ -1626,29 +1619,12 @@ "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", "requires": { "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "14.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.23.tgz", - "integrity": "sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw==" - } } }, "@types/semver": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.1.tgz", - "integrity": "sha512-ooD/FJ8EuwlDKOI6D9HWxgIgJjMg2cuziXm/42npDC8y4NjxplBUn9loewZiBNCt44450lHAU0OSb51/UqXeag==", - "requires": { - "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "14.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.23.tgz", - "integrity": "sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw==" - } - } + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.3.tgz", + "integrity": "sha512-jQxClWFzv9IXdLdhSaTf16XI3NYe6zrEbckSpb5xhKfPbWgIyAY0AFyWWWfaiDcBuj3UHmMkCIwSRqpKMTZL2Q==" }, "@types/sizzle": { "version": "2.3.2", @@ -1694,9 +1670,9 @@ "dev": true }, "@types/triple-beam": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.1.tgz", - "integrity": "sha512-Hp2RwsY6bneFcyfl8Q4v1RTj9hCexh2JUXQtXNZt+GE2jWT+pbrcxJAb6iPml8FRJ5LWV0AvGi6LoCt5hbWIlw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz", + "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==", "dev": true }, "@types/uglify-js": { @@ -1769,12 +1745,12 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.6.1.tgz", - "integrity": "sha512-06lfjo76naNeOMDl+mWG9Fh/a0UHKLGhin+mGaIw72FUMbMGBkdi/FEJmgEDzh4eE73KIYzHWvOCYJ0ak7nrJQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.0.tgz", + "integrity": "sha512-Bbeg9JAnSzZ85Y0gpInZscSpifA6SbEgRryaKdP5ZlUjhTKsvZS4GUIE6xAZCjhNTrf4zXXsySo83ZdHL7it0w==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "3.6.1", + "@typescript-eslint/experimental-utils": "3.10.0", "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", @@ -1783,45 +1759,45 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.6.1.tgz", - "integrity": "sha512-oS+hihzQE5M84ewXrTlVx7eTgc52eu+sVmG7ayLfOhyZmJ8Unvf3osyFQNADHP26yoThFfbxcibbO0d2FjnYhg==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.0.tgz", + "integrity": "sha512-e5ZLSTuXgqC/Gq3QzK2orjlhTZVXzwxDujQmTBOM1NIVBZgW3wiIZjaXuVutk9R4UltFlwC9UD2+bdxsA7yyNg==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/types": "3.6.1", - "@typescript-eslint/typescript-estree": "3.6.1", + "@typescript-eslint/types": "3.10.0", + "@typescript-eslint/typescript-estree": "3.10.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" } }, "@typescript-eslint/parser": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.6.1.tgz", - "integrity": "sha512-SLihQU8RMe77YJ/jGTqOt0lMq7k3hlPVfp7v/cxMnXA9T0bQYoMDfTsNgHXpwSJM1Iq2aAJ8WqekxUwGv5F67Q==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.10.0.tgz", + "integrity": "sha512-iJyf3f2HVwscvJR7ySGMXw2DJgIAPKEz8TeU17XVKzgJRV4/VgCeDFcqLzueRe7iFI2gv+Tln4AV88ZOnsCNXg==", "dev": true, "requires": { "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "3.6.1", - "@typescript-eslint/types": "3.6.1", - "@typescript-eslint/typescript-estree": "3.6.1", + "@typescript-eslint/experimental-utils": "3.10.0", + "@typescript-eslint/types": "3.10.0", + "@typescript-eslint/typescript-estree": "3.10.0", "eslint-visitor-keys": "^1.1.0" } }, "@typescript-eslint/types": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.6.1.tgz", - "integrity": "sha512-NPxd5yXG63gx57WDTW1rp0cF3XlNuuFFB5G+Kc48zZ+51ZnQn9yjDEsjTPQ+aWM+V+Z0I4kuTFKjKvgcT1F7xQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.0.tgz", + "integrity": "sha512-ktUWSa75heQNwH85GRM7qP/UUrXqx9d6yIdw0iLO9/uE1LILW+i+3+B64dUodUS2WFWLzKTlwfi9giqrODibWg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.6.1.tgz", - "integrity": "sha512-G4XRe/ZbCZkL1fy09DPN3U0mR6SayIv1zSeBNquRFRk7CnVLgkC2ZPj8llEMJg5Y8dJ3T76SvTGtceytniaztQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.0.tgz", + "integrity": "sha512-yjuY6rmVHRhcUKgXaSPNVloRueGWpFNhxR5EQLzxXfiFSl1U/+FBqHhbaGwtPPEgCSt61QNhZgiFjWT27bgAyw==", "dev": true, "requires": { - "@typescript-eslint/types": "3.6.1", - "@typescript-eslint/visitor-keys": "3.6.1", + "@typescript-eslint/types": "3.10.0", + "@typescript-eslint/visitor-keys": "3.10.0", "debug": "^4.1.1", "glob": "^7.1.6", "is-glob": "^4.0.1", @@ -1831,9 +1807,9 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.6.1.tgz", - "integrity": "sha512-qC8Olwz5ZyMTZrh4Wl3K4U6tfms0R/mzU4/5W3XeUZptVraGVmbptJbn6h2Ey6Rb3hOs3zWoAUebZk8t47KGiQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.0.tgz", + "integrity": "sha512-g4qftk8lWb/rHZe9uEp8oZSvsJhUvR2cfp7F7qE6DyUD2SsovEs8JDQTRP1xHzsD+pERsEpYNqkDgQXW6+ob5A==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -2037,9 +2013,9 @@ } }, "acorn": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", - "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", "dev": true }, "acorn-jsx": { @@ -2181,23 +2157,23 @@ "dev": true }, "app-builder-lib": { - "version": "22.7.0", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.7.0.tgz", - "integrity": "sha512-blRKwV8h0ztualXS50ciCTo39tbuDGNS+ldcy8+KLvKXuT6OpYnSJ7M6MSfPT+xWatshMHJV1rJx3Tl+k/Sn/g==", + "version": "22.8.0", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.8.0.tgz", + "integrity": "sha512-RGaIRjCUrqkmh6QOGsyekQPEOaVynHfmeh8JZuyUymFYUOFdzBbPamkA2nhBVBTkkgfjRHsxK7LhedFKPzvWEQ==", "dev": true, "requires": { "7zip-bin": "~5.0.3", "@develar/schema-utils": "~2.6.5", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "22.7.0", - "builder-util-runtime": "8.7.1", + "builder-util": "22.8.0", + "builder-util-runtime": "8.7.2", "chromium-pickle-js": "^0.2.0", - "debug": "^4.2.0", + "debug": "^4.1.1", "ejs": "^3.1.3", - "electron-publish": "22.7.0", - "fs-extra": "^9.0.0", - "hosted-git-info": "^3.0.4", + "electron-publish": "22.8.0", + "fs-extra": "^9.0.1", + "hosted-git-info": "^3.0.5", "is-ci": "^2.0.0", "isbinaryfile": "^4.0.6", "js-yaml": "^3.14.0", @@ -2208,27 +2184,6 @@ "sanitize-filename": "^1.6.3", "semver": "^7.3.2", "temp-file": "^3.3.7" - }, - "dependencies": { - "builder-util-runtime": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.1.tgz", - "integrity": "sha512-uEBH1nAnTvzjcsrh2XI3qOzJ39h0+9kuIuwj+kCc3a07TZNGShfJcai8fFzL3mNgGjEFxoq+XMssR11r+FOFSg==", - "dev": true, - "requires": { - "debug": "^4.2.0", - "sax": "^1.2.4" - } - }, - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } } }, "aproba": { @@ -2339,14 +2294,15 @@ } }, "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dev": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" }, "dependencies": { "bn.js": { @@ -2645,9 +2601,9 @@ } }, "bn.js": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", - "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", "dev": true }, "body-parser": { @@ -2874,16 +2830,16 @@ } }, "browserify-sign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", - "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", "dev": true, "requires": { "bn.js": "^5.1.1", "browserify-rsa": "^4.0.1", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", + "elliptic": "^6.5.3", "inherits": "^2.0.4", "parse-asn1": "^5.1.5", "readable-stream": "^3.6.0", @@ -2945,9 +2901,9 @@ "dev": true }, "builder-util": { - "version": "22.7.0", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.7.0.tgz", - "integrity": "sha512-UV3MKL0mwjMq2y9JlBf28Cegpj0CrIXcjGkO0TXn+QZ6Yy9rY6lHOuUvpQ19ct2Qh1o+QSwH3Q1nKUf5viJBBg==", + "version": "22.8.0", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.8.0.tgz", + "integrity": "sha512-H80P1JzVy3TGpi63x81epQDK24XalL034+jAZlrPb5IhLtYmnNNdxCCAVJvg3VjSISd73Y71O+uhqCxWpqbPHw==", "dev": true, "requires": { "7zip-bin": "~5.0.3", @@ -2955,42 +2911,21 @@ "@types/fs-extra": "^9.0.1", "app-builder-bin": "3.5.9", "bluebird-lst": "^1.0.9", - "builder-util-runtime": "8.7.1", - "chalk": "^4.0.0", - "debug": "^4.2.0", - "fs-extra": "^9.0.0", + "builder-util-runtime": "8.7.2", + "chalk": "^4.1.0", + "debug": "^4.1.1", + "fs-extra": "^9.0.1", "is-ci": "^2.0.0", "js-yaml": "^3.14.0", "source-map-support": "^0.5.19", "stat-mode": "^1.0.0", "temp-file": "^3.3.7" - }, - "dependencies": { - "builder-util-runtime": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.1.tgz", - "integrity": "sha512-uEBH1nAnTvzjcsrh2XI3qOzJ39h0+9kuIuwj+kCc3a07TZNGShfJcai8fFzL3mNgGjEFxoq+XMssR11r+FOFSg==", - "dev": true, - "requires": { - "debug": "^4.2.0", - "sax": "^1.2.4" - } - }, - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } } }, "builder-util-runtime": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.0.tgz", - "integrity": "sha512-G1AqqVM2vYTrSFR982c1NNzwXKrGLQjVjaZaWQdn4O6Z3YKjdMDofw88aD9jpyK9ZXkrCxR0tI3Qe9wNbyTlXg==", + "version": "8.7.2", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.2.tgz", + "integrity": "sha512-xBqv+8bg6cfnzAQK1k3OGpfaHg+QkPgIgpEkXNhouZ0WiUkyZCftuRc2LYzQrLucFywpa14Xbc6+hTbpq83yRA==", "requires": { "debug": "^4.1.1", "sax": "^1.2.4" @@ -3630,13 +3565,13 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", "dev": true, "requires": { "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "elliptic": "^6.5.3" }, "dependencies": { "bn.js": { @@ -4094,24 +4029,24 @@ } }, "discord-rpc": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/discord-rpc/-/discord-rpc-3.1.1.tgz", - "integrity": "sha512-2nTB+82q4OnCtataJkWMQ2YBWs2UEjs490uC7/xSTvXAOb7I+ZDsweHWFL692sSpDzg7pRlmy1+XVyjWqleulg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/discord-rpc/-/discord-rpc-3.1.3.tgz", + "integrity": "sha512-V081xCPFm8YDNLJYJv3Vo2BrCv/Knh0mdvq37RIN1keh7VGpf7s1kypaFDIYiuUmAlZXI5pupthF5hCrx/CzhA==", "requires": { "node-fetch": "2.6.0", "ws": "7.1.2" } }, "dmg-builder": { - "version": "22.7.0", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.7.0.tgz", - "integrity": "sha512-5Ea2YEz6zSNbyGzZD+O9/MzmaXb6oa15cSKWo4JQ1xP4rorOpte7IOj2jcwYjtc+Los2gu1lvT314OC1OZIWgg==", + "version": "22.8.0", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.8.0.tgz", + "integrity": "sha512-orePWjcrl97SYLA8F/6UUtbXJSoZCYu5KOP1lVqD4LOomr8bjGDyEVYZmZYcg5WqKmXucdmO6OpqgzH/aRMMuA==", "dev": true, "requires": { - "app-builder-lib": "22.7.0", - "builder-util": "22.7.0", - "fs-extra": "^9.0.0", - "iconv-lite": "^0.5.1", + "app-builder-lib": "22.8.0", + "builder-util": "22.8.0", + "fs-extra": "^9.0.1", + "iconv-lite": "^0.6.2", "js-yaml": "^3.14.0", "sanitize-filename": "^1.6.3" } @@ -4314,18 +4249,18 @@ "dev": true }, "ejs": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz", - "integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz", + "integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==", "dev": true, "requires": { "jake": "^10.6.1" } }, "electron": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-9.1.0.tgz", - "integrity": "sha512-VRAF8KX1m0py9I9sf0kw1kWfeC87mlscfFcbcRdLBsNJ44/GrJhi3+E8rKbpHUeZNQxsPaVA5Zu5Lxb6dV/scQ==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-9.2.1.tgz", + "integrity": "sha512-ZsetaQjXB8+9/EFW1FnfK4ukpkwXCxMEaiKiUZhZ0ZLFlLnFCpe0Bg4vdDf7e4boWGcnlgN1jAJpBw7w0eXuqA==", "dev": true, "requires": { "@electron/get": "^1.0.1", @@ -4334,94 +4269,52 @@ } }, "electron-builder": { - "version": "22.7.0", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.7.0.tgz", - "integrity": "sha512-t6E3oMutpST64YWbZCg7HodEwJOsnjUF1vnDIHm2MW6CFZPX8tlCK6efqaV66LU0E0Nkp/JH6TE5bCqQ1+VdPQ==", + "version": "22.8.0", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.8.0.tgz", + "integrity": "sha512-dUv4F3srJouqxhWivtKqSoQP4Df6vYgjooGdzms+iYMTFi9f0b4LlEbr7kgsPvte8zAglee7VOGOODkCRJDkUQ==", "dev": true, "requires": { "@types/yargs": "^15.0.5", - "app-builder-lib": "22.7.0", + "app-builder-lib": "22.8.0", "bluebird-lst": "^1.0.9", - "builder-util": "22.7.0", - "builder-util-runtime": "8.7.1", - "chalk": "^4.0.0", - "dmg-builder": "22.7.0", - "fs-extra": "^9.0.0", + "builder-util": "22.8.0", + "builder-util-runtime": "8.7.2", + "chalk": "^4.1.0", + "dmg-builder": "22.8.0", + "fs-extra": "^9.0.1", "is-ci": "^2.0.0", "lazy-val": "^1.0.4", "read-config-file": "6.0.0", "sanitize-filename": "^1.6.3", "update-notifier": "^4.1.0", "yargs": "^15.3.1" - }, - "dependencies": { - "builder-util-runtime": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.1.tgz", - "integrity": "sha512-uEBH1nAnTvzjcsrh2XI3qOzJ39h0+9kuIuwj+kCc3a07TZNGShfJcai8fFzL3mNgGjEFxoq+XMssR11r+FOFSg==", - "dev": true, - "requires": { - "debug": "^4.2.0", - "sax": "^1.2.4" - } - }, - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } } }, "electron-devtools-installer": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.1.0.tgz", - "integrity": "sha512-qZd1Aoya8YOK6QauNX92V5qyKGtb4lbs238bP+qtMBkXts24xJ/1PtOVBPvdg5w3Ts9L5o6I9sDErKuzHeJFDA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.1.1.tgz", + "integrity": "sha512-g2D4J6APbpsiIcnLkFMyKZ6bOpEJ0Ltcc2m66F7oKUymyGAt628OWeU9nRZoh1cNmUs/a6Cls2UfOmsZtE496Q==", "dev": true, "requires": { "rimraf": "^3.0.2", "semver": "^7.2.1", - "unzip-crx": "^0.2.0" + "unzip-crx-3": "^0.2.0" } }, "electron-publish": { - "version": "22.7.0", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.7.0.tgz", - "integrity": "sha512-hmU69xlb6vvAV3QfpHYDlkdZMFdBAgDbptoxbLFrnTq5bOkcL8AaDbvxeoZ4+lvqgs29NwqGpkHo2oN+p/hCfg==", + "version": "22.8.0", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.8.0.tgz", + "integrity": "sha512-uM0Zdi9hUqqGOrPj478v7toTvV1Kgto1w11rIiI168batiXAJvNLD8VZRfehOrZT0ibUyZlw8FtxoGCrjyHUOw==", "dev": true, "requires": { "@types/fs-extra": "^9.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "22.7.0", - "builder-util-runtime": "8.7.1", - "chalk": "^4.0.0", - "fs-extra": "^9.0.0", + "builder-util": "22.8.0", + "builder-util-runtime": "8.7.2", + "chalk": "^4.1.0", + "fs-extra": "^9.0.1", "lazy-val": "^1.0.4", - "mime": "^2.4.5" - }, - "dependencies": { - "builder-util-runtime": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.1.tgz", - "integrity": "sha512-uEBH1nAnTvzjcsrh2XI3qOzJ39h0+9kuIuwj+kCc3a07TZNGShfJcai8fFzL3mNgGjEFxoq+XMssR11r+FOFSg==", - "dev": true, - "requires": { - "debug": "^4.2.0", - "sax": "^1.2.4" - } - }, - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } + "mime": "^2.4.6" } }, "electron-to-chromium": { @@ -4431,17 +4324,17 @@ "dev": true }, "electron-updater": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.3.1.tgz", - "integrity": "sha512-UDC5AHCgeiHJYDYWZG/rsl1vdAFKqI/Lm7whN57LKAk8EfhTewhcEHzheRcncLgikMcQL8gFo1KeX51tf5a5Wg==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.3.4.tgz", + "integrity": "sha512-ekpgxDrYl+Wi24ktO4qfj2CtCABxrmK1C/oekp0tai6q4VR4ZdPkit4CX8+GenvKMme7uMmfPFnLp/vwhP/ThQ==", "requires": { - "@types/semver": "^7.1.0", - "builder-util-runtime": "8.7.0", - "fs-extra": "^9.0.0", - "js-yaml": "^3.13.1", + "@types/semver": "^7.3.1", + "builder-util-runtime": "8.7.2", + "fs-extra": "^9.0.1", + "js-yaml": "^3.14.0", "lazy-val": "^1.0.4", "lodash.isequal": "^4.5.0", - "semver": "^7.1.3" + "semver": "^7.3.2" } }, "electron-webpack": { @@ -4774,9 +4667,9 @@ "optional": true }, "eslint": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.4.0.tgz", - "integrity": "sha512-gU+lxhlPHu45H3JkEGgYhWhkR9wLHHEXC9FbWFnTlEkbKyZKWgWRLgf61E8zWmBuI6g5xKBph9ltg3NtZMVF8g==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.7.0.tgz", + "integrity": "sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -4787,9 +4680,9 @@ "doctrine": "^3.0.0", "enquirer": "^2.3.5", "eslint-scope": "^5.1.0", - "eslint-utils": "^2.0.0", - "eslint-visitor-keys": "^1.2.0", - "espree": "^7.1.0", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^1.3.0", + "espree": "^7.2.0", "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", @@ -4803,7 +4696,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.14", + "lodash": "^4.17.19", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -4865,9 +4758,9 @@ } }, "eslint-plugin-react": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.3.tgz", - "integrity": "sha512-txbo090buDeyV0ugF3YMWrzLIUqpYTsWSDZV9xLSmExE1P/Kmgg9++PD931r+KEWS66O1c9R4srLVVHmeHpoAg==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.6.tgz", + "integrity": "sha512-kidMTE5HAEBSLu23CUDvj8dc3LdBU0ri1scwHBZjI41oDv4tjsWZKU7MQccFzH1QYPYhsnTF2ovh7JlcIcmxgg==", "dev": true, "requires": { "array-includes": "^3.1.1", @@ -4920,14 +4813,14 @@ "dev": true }, "espree": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", - "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", "dev": true, "requires": { - "acorn": "^7.2.0", + "acorn": "^7.4.0", "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.2.0" + "eslint-visitor-keys": "^1.3.0" } }, "esprima": { @@ -4945,9 +4838,9 @@ }, "dependencies": { "estraverse": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", - "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true } } @@ -4986,9 +4879,9 @@ "dev": true }, "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", "dev": true }, "eventsource": { @@ -5921,9 +5814,9 @@ "dev": true }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "requires": { "pump": "^3.0.0" } @@ -6123,9 +6016,9 @@ } }, "got": { - "version": "11.5.0", - "resolved": "https://registry.npmjs.org/got/-/got-11.5.0.tgz", - "integrity": "sha512-vOZEcEaK0b6x11uniY0HcblZObKPRO75Jvz53VKuqGSaKCM/zEt0sj2LGYVdqDYJzO3wYdG+FPQQ1hsgoXy7vQ==", + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/got/-/got-11.5.2.tgz", + "integrity": "sha512-yUhpEDLeuGiGJjRSzEq3kvt4zJtAcjKmhIiwNp/eUs75tRlXfWcHo5tcBaMQtnjHWC7nQYT5HkY/l0QOQTkVww==", "requires": { "@sindresorhus/is": "^3.0.0", "@szmarczak/http-timer": "^4.0.5", @@ -6134,7 +6027,7 @@ "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.1", "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.4.8", + "http2-wrapper": "^1.0.0-beta.5.0", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" @@ -6502,12 +6395,12 @@ "dev": true }, "iconv-lite": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", - "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "icss-utils": { @@ -6830,6 +6723,12 @@ "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", "dev": true }, + "is-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true + }, "is-npm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", @@ -7345,9 +7244,9 @@ } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.isequal": { "version": "4.5.0", @@ -7825,9 +7724,9 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "mocha": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.0.1.tgz", - "integrity": "sha512-vefaXfdYI8+Yo8nPZQQi0QO2o+5q9UIMX1jZ1XMmK3+4+CQjc7+B0hPdUeglXiTlr8IHMVRo63IhO9Mzt6fxOg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.1.1.tgz", + "integrity": "sha512-p7FuGlYH8t7gaiodlFreseLxEmxTgvyG9RgPHODFPySNhwUehu8NIb0vdSt3WFckSneswZ0Un5typYcWElk7HQ==", "dev": true, "requires": { "ansi-colors": "4.1.1", @@ -7846,7 +7745,7 @@ "ms": "2.1.2", "object.assign": "4.1.0", "promise.allsettled": "1.0.2", - "serialize-javascript": "3.0.0", + "serialize-javascript": "4.0.0", "strip-json-comments": "3.0.1", "supports-color": "7.1.0", "which": "2.0.2", @@ -7854,7 +7753,7 @@ "workerpool": "6.0.0", "yargs": "13.3.2", "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" + "yargs-unparser": "1.6.1" }, "dependencies": { "ansi-colors": { @@ -8024,10 +7923,13 @@ } }, "serialize-javascript": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz", - "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } }, "string-width": { "version": "3.1.0", @@ -8219,9 +8121,9 @@ } }, "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.4.tgz", + "integrity": "sha512-alqTV8Qt7TUbc74x1pKRLSENzfjp4nywovcJgi/1aXDiUxXdt7TkruSTF5MDWPP7UoPVgea4F9ghVdmX0xxnSA==", "dev": true, "requires": { "debug": "^4.1.0", @@ -8719,9 +8621,9 @@ }, "dependencies": { "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -8891,14 +8793,13 @@ } }, "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "dev": true, "requires": { - "asn1.js": "^4.0.0", + "asn1.js": "^5.2.0", "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.0", "pbkdf2": "^3.0.3", "safe-buffer": "^5.1.1" @@ -9584,9 +9485,9 @@ "dev": true }, "react-redux": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz", - "integrity": "sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.1.tgz", + "integrity": "sha512-T+VfD/bvgGTUA74iW9d2i5THrDQWbweXP0AVNI8tNd1Rk5ch1rnMiJkDD67ejw7YBKM4+REvcvqRuWJb7BLuEg==", "dev": true, "requires": { "@babel/runtime": "^7.5.5", @@ -10385,13 +10286,44 @@ "dev": true }, "side-channel": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", - "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.3.tgz", + "integrity": "sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g==", "dev": true, "requires": { - "es-abstract": "^1.17.0-next.1", - "object-inspect": "^1.7.0" + "es-abstract": "^1.18.0-next.0", + "object-inspect": "^1.8.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.0.tgz", + "integrity": "sha512-elZXTZXKn51hUBdJjSZGYRujuzilgXo8vSPQzjGYXLvSlGiCo8VO8ZGV3kjo9a0WNJJ57hENagwbtlRuHuzkcQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } } }, "signal-exit": { @@ -11598,9 +11530,9 @@ } }, "typescript": { - "version": "3.9.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.6.tgz", - "integrity": "sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw==", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", "dev": true }, "unicode-canonical-property-names-ecmascript": { @@ -11727,10 +11659,10 @@ } } }, - "unzip-crx": { + "unzip-crx-3": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/unzip-crx/-/unzip-crx-0.2.0.tgz", - "integrity": "sha1-TAuqi9rHViVnVL7KeEPBPXuFjBg=", + "resolved": "https://registry.npmjs.org/unzip-crx-3/-/unzip-crx-3-0.2.0.tgz", + "integrity": "sha512-0+JiUq/z7faJ6oifVB5nSwt589v1KCduqIJupNVDoWSXZtWDmjDGO3RAEOvwJ07w90aoXoP4enKsR7ecMrJtWQ==", "dev": true, "requires": { "jszip": "^3.1.0", @@ -11745,9 +11677,9 @@ "dev": true }, "update-notifier": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", - "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.1.tgz", + "integrity": "sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg==", "dev": true, "requires": { "boxen": "^4.2.0", @@ -11952,12 +11884,12 @@ "dev": true }, "watchpack": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", - "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", + "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", "dev": true, "requires": { - "chokidar": "^3.4.0", + "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", "neo-async": "^2.5.0", "watchpack-chokidar2": "^2.0.0" @@ -11992,9 +11924,9 @@ } }, "chokidar": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", - "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", "dev": true, "optional": true, "requires": { @@ -12094,9 +12026,9 @@ } }, "webpack": { - "version": "4.43.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", - "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz", + "integrity": "sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ==", "dev": true, "requires": { "@webassemblyjs/ast": "1.9.0", @@ -12107,7 +12039,7 @@ "ajv": "^6.10.2", "ajv-keywords": "^3.4.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", + "enhanced-resolve": "^4.3.0", "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", "loader-runner": "^2.4.0", @@ -12120,7 +12052,7 @@ "schema-utils": "^1.0.0", "tapable": "^1.1.3", "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.1", + "watchpack": "^1.7.4", "webpack-sources": "^1.4.1" }, "dependencies": { @@ -12223,6 +12155,15 @@ "ajv-keywords": "^3.1.0" } }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", @@ -12242,16 +12183,16 @@ } }, "terser-webpack-plugin": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz", - "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", "dev": true, "requires": { "cacache": "^12.0.2", "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^3.1.0", + "serialize-javascript": "^4.0.0", "source-map": "^0.6.1", "terser": "^4.1.2", "webpack-sources": "^1.4.0", @@ -13113,14 +13054,16 @@ } }, "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.1.tgz", + "integrity": "sha512-qZV14lK9MWsGCmcr7u5oXGH0dbGqZAIxTDrWXZDo5zUr6b6iUmelNKO6x6R1dQT24AH3LgRxJpr8meWy2unolA==", "dev": true, "requires": { + "camelcase": "^5.3.1", + "decamelize": "^1.2.0", "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "is-plain-obj": "^1.1.0", + "yargs": "^14.2.3" }, "dependencies": { "ansi-styles": { @@ -13200,12 +13143,13 @@ } }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", "dev": true, "requires": { "cliui": "^5.0.0", + "decamelize": "^1.2.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", @@ -13214,13 +13158,13 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "yargs-parser": "^15.0.1" } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", + "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index 36156a8..a6221f5 100644 --- a/package.json +++ b/package.json @@ -31,13 +31,13 @@ "dependencies": { "adm-zip": "^0.4.16", "async": "^3.2.0", - "discord-rpc": "^3.1.1", - "electron-updater": "^4.3.1", + "discord-rpc": "^3.1.3", + "electron-updater": "^4.3.4", "fs-extra": "^9.0.1", "github-syntax-dark": "^0.5.0", - "got": "^11.5.0", + "got": "^11.5.2", "jquery": "^3.5.1", - "lodash": "^4.17.19", + "lodash": "^4.17.20", "moment": "^2.27.0", "request": "^2.88.2", "semver": "^7.3.2", @@ -50,46 +50,46 @@ "@babel/preset-react": "^7.10.4", "@types/adm-zip": "^0.4.33", "@types/async": "^3.2.3", - "@types/chai": "^4.2.11", + "@types/chai": "^4.2.12", "@types/discord-rpc": "^3.0.4", "@types/fs-extra": "^9.0.1", - "@types/jquery": "^3.5.0", - "@types/lodash": "^4.14.157", - "@types/mocha": "^8.0.0", - "@types/node": "^12.12.50", - "@types/react": "^16.9.43", + "@types/jquery": "^3.5.1", + "@types/lodash": "^4.14.160", + "@types/mocha": "^8.0.3", + "@types/node": "^12.12.54", + "@types/react": "^16.9.46", "@types/react-dom": "^16.9.8", "@types/react-redux": "^7.1.9", "@types/react-transition-group": "^4.4.0", "@types/request": "^2.48.5", "@types/tar-fs": "^2.0.0", - "@types/triple-beam": "^1.3.1", + "@types/triple-beam": "^1.3.2", "@types/winreg": "^1.2.30", - "@typescript-eslint/eslint-plugin": "^3.6.1", - "@typescript-eslint/parser": "^3.6.1", + "@typescript-eslint/eslint-plugin": "^3.10.0", + "@typescript-eslint/parser": "^3.10.0", "chai": "^4.2.0", "cross-env": "^7.0.2", - "electron": "^9.1.0", - "electron-builder": "^22.7.0", - "electron-devtools-installer": "^3.1.0", + "electron": "^9.2.1", + "electron-builder": "^22.8.0", + "electron-devtools-installer": "^3.1.1", "electron-webpack": "^2.8.2", "electron-webpack-ts": "^4.0.1", - "eslint": "^7.4.0", - "eslint-plugin-react": "^7.20.3", + "eslint": "^7.7.0", + "eslint-plugin-react": "^7.20.6", "helios-distribution-types": "1.0.0-pre.1", - "mocha": "^8.0.1", - "nock": "^13.0.2", + "mocha": "^8.1.1", + "nock": "^13.0.4", "react": "^16.13.0", "react-dom": "^16.13.0", "react-hot-loader": "^4.12.21", - "react-redux": "^7.2.0", + "react-redux": "^7.2.1", "react-transition-group": "^4.4.1", "redux": "^4.0.5", "rimraf": "^3.0.2", "ts-node": "^8.10.2", "tsconfig-paths": "^3.9.0", - "typescript": "^3.9.6", - "webpack": "^4.43.0" + "typescript": "^3.9.7", + "webpack": "^4.44.1" }, "repository": { "type": "git", diff --git a/src/common/distribution/distribution.ts b/src/common/distribution/distribution.ts new file mode 100644 index 0000000..19c2579 --- /dev/null +++ b/src/common/distribution/distribution.ts @@ -0,0 +1,106 @@ +import { resolve } from 'path' +import { Distribution } from 'helios-distribution-types' +import got from 'got' +import { LoggerUtil } from 'common/logging/loggerutil' +import { RestResponse, handleGotError, RestResponseStatus } from 'common/got/RestResponse' +import { pathExists, readFile, writeFile } from 'fs-extra' + +export class DistributionAPI { + + private static readonly logger = LoggerUtil.getLogger('DistributionAPI') + + private readonly REMOTE_URL = 'http://mc.westeroscraft.com/WesterosCraftLauncher/distribution.json' + + private readonly DISTRO_FILE = 'distribution.json' + private readonly DISTRO_FILE_DEV = 'distribution_dev.json' + + private readonly DEV_MODE = false // placeholder + + private distroPath: string + private distroDevPath: string + + private rawDistribution!: Distribution + + constructor( + private launcherDirectory: string + ) { + this.distroPath = resolve(launcherDirectory, this.DISTRO_FILE) + this.distroDevPath = resolve(launcherDirectory, this.DISTRO_FILE_DEV) + } + + public async testLoad(): Promise { + await this.loadDistribution() + return this.rawDistribution + } + + protected async loadDistribution(): Promise { + + let distro + + if(!this.DEV_MODE) { + + distro = (await this.pullRemote()).data + if(distro == null) { + distro = await this.pullLocal(false) + } else { + this.writeDistributionToDisk(distro) + } + + } else { + distro = await this.pullLocal(true) + } + + if(distro == null) { + // TODO Bubble this up nicer + throw new Error('FATAL: Unable to load distribution from remote server or local disk.') + } + + this.rawDistribution = distro + } + + protected async pullRemote(): Promise> { + + try { + + const res = await got.get(this.REMOTE_URL, { responseType: 'json' }) + + return { + data: res.body, + responseStatus: RestResponseStatus.SUCCESS + } + + } catch(error) { + + return handleGotError('Pull Remote', error, DistributionAPI.logger, () => null) + + } + + } + + protected async writeDistributionToDisk(distribution: Distribution): Promise { + await writeFile(this.distroPath, distribution) + } + + protected async pullLocal(dev: boolean): Promise { + return await this.readDistributionFromFile(!dev ? this.distroPath : this.distroDevPath) + } + + + protected async readDistributionFromFile(path: string): Promise { + + if(await pathExists(path)) { + const raw = await readFile(path, 'utf-8') + try { + return JSON.parse(raw) + } catch(error) { + DistributionAPI.logger.error(`Malformed distribution file at ${path}`) + return null + } + } else { + DistributionAPI.logger.error(`No distribution file found at ${path}!`) + return null + } + + } + +} \ No newline at end of file diff --git a/src/common/got/RestResponse.ts b/src/common/got/RestResponse.ts new file mode 100644 index 0000000..7f0507f --- /dev/null +++ b/src/common/got/RestResponse.ts @@ -0,0 +1,43 @@ +import { RequestError, HTTPError, TimeoutError, ParseError } from 'got' +import { Logger } from 'winston' + +export enum RestResponseStatus { + + SUCCESS, + ERROR + +} + +export interface RestResponse { + + data: T + responseStatus: RestResponseStatus + error?: RequestError + +} + +export function handleGotError(operation: string, error: RequestError, logger: Logger, dataProvider: () => T): RestResponse { + const response: RestResponse = { + data: dataProvider(), + responseStatus: RestResponseStatus.ERROR, + error + } + + if(error instanceof HTTPError) { + logger.error(`Error during ${operation} request (HTTP Response ${error.response.statusCode})`, error) + logger.debug('Response Details:') + logger.debug('Body:', error.response.body) + logger.debug('Headers:', error.response.headers) + } else if(Object.getPrototypeOf(error) instanceof RequestError) { + logger.error(`${operation} request recieved no response (${error.code}).`, error) + } else if(error instanceof TimeoutError) { + logger.error(`${operation} request timed out (${error.timings.phases.total}ms).`) + } else if(error instanceof ParseError) { + logger.error(`${operation} request recieved unexepected body (Parse Error).`) + } else { + // CacheError, ReadError, MaxRedirectsError, UnsupportedProtocolError, CancelError + logger.error(`Error during ${operation} request.`, error) + } + + return response +} \ No newline at end of file diff --git a/src/common/logging/loggerutil.ts b/src/common/logging/loggerutil.ts index be79446..295bfbf 100644 --- a/src/common/logging/loggerutil.ts +++ b/src/common/logging/loggerutil.ts @@ -1,8 +1,12 @@ import { createLogger, format, transports, Logger } from 'winston' -import { SPLAT } from 'triple-beam' +import { SPLAT as SPLAT_Symbol } from 'triple-beam' import moment from 'moment' import { inspect } from 'util' +// Workaround until fixed. +// https://github.com/winstonjs/logform/issues/111 +const SPLAT = SPLAT_Symbol as unknown as string + export class LoggerUtil { public static getLogger(label: string): Logger { diff --git a/src/common/mojang/model/internal/MojangResponse.ts b/src/common/mojang/model/internal/MojangResponse.ts new file mode 100644 index 0000000..08b4082 --- /dev/null +++ b/src/common/mojang/model/internal/MojangResponse.ts @@ -0,0 +1,87 @@ +import { RestResponse } from 'common/got/RestResponse' + +/** + * @see https://wiki.vg/Authentication#Errors + */ +export enum MojangErrorCode { + ERROR_METHOD_NOT_ALLOWED, // INTERNAL + ERROR_NOT_FOUND, // INTERNAL + ERROR_USER_MIGRATED, + ERROR_INVALID_CREDENTIALS, + ERROR_RATELIMIT, + ERROR_INVALID_TOKEN, + ERROR_ACCESS_TOKEN_HAS_PROFILE, // ?? + ERROR_CREDENTIALS_ARE_NULL, // INTERNAL + ERROR_INVALID_SALT_VERSION, // ?? + ERROR_UNSUPPORTED_MEDIA_TYPE, // INTERNAL + UNKNOWN +} + +export interface MojangResponse extends RestResponse { + mojangErrorCode?: MojangErrorCode + isInternalError?: boolean +} + +export interface MojangErrorBody { + error: string + errorMessage: string + cause?: string +} + +/** + * Resolve the error response code from the response body. + * + * @param body The mojang error body response. + */ +export function decipherErrorCode(body: MojangErrorBody): MojangErrorCode { + + if(body.error === 'Method Not Allowed') { + return MojangErrorCode.ERROR_METHOD_NOT_ALLOWED + } else if(body.error === 'Not Found') { + return MojangErrorCode.ERROR_NOT_FOUND + } else if(body.error === 'Unsupported Media Type') { + return MojangErrorCode.ERROR_UNSUPPORTED_MEDIA_TYPE + } else if(body.error === 'ForbiddenOperationException') { + + if(body.cause && body.cause === 'UserMigratedException') { + return MojangErrorCode.ERROR_USER_MIGRATED + } + + if(body.errorMessage === 'Invalid credentials. Invalid username or password.') { + return MojangErrorCode.ERROR_INVALID_CREDENTIALS + } else if(body.errorMessage === 'Invalid credentials.') { + return MojangErrorCode.ERROR_RATELIMIT + } else if(body.errorMessage === 'Invalid token.') { + return MojangErrorCode.ERROR_INVALID_TOKEN + } + + } else if(body.error === 'IllegalArgumentException') { + + if(body.errorMessage === 'Access token already has a profile assigned.') { + return MojangErrorCode.ERROR_ACCESS_TOKEN_HAS_PROFILE + } else if(body.errorMessage === 'credentials is null') { + return MojangErrorCode.ERROR_CREDENTIALS_ARE_NULL + } else if(body.errorMessage === 'Invalid salt version') { + return MojangErrorCode.ERROR_INVALID_SALT_VERSION + } + + } + + return MojangErrorCode.UNKNOWN + +} + +// These indicate problems with the code and not the data. +export function isInternalError(errorCode: MojangErrorCode): boolean { + switch(errorCode) { + case MojangErrorCode.ERROR_METHOD_NOT_ALLOWED: // We've sent the wrong method to an endpoint. (ex. GET to POST) + case MojangErrorCode.ERROR_NOT_FOUND: // Indicates endpoint has changed. (404) + case MojangErrorCode.ERROR_ACCESS_TOKEN_HAS_PROFILE: // Selecting profiles isn't implemented yet. (Shouldnt happen) + case MojangErrorCode.ERROR_CREDENTIALS_ARE_NULL: // Username/password was not submitted. (UI should forbid this) + case MojangErrorCode.ERROR_INVALID_SALT_VERSION: // ??? (Shouldnt happen) + case MojangErrorCode.ERROR_UNSUPPORTED_MEDIA_TYPE: // Data was not submitted as application/json + return true + default: + return false + } +} \ No newline at end of file diff --git a/src/common/mojang/model/internal/Response.ts b/src/common/mojang/model/internal/Response.ts deleted file mode 100644 index 1fe2c50..0000000 --- a/src/common/mojang/model/internal/Response.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { RequestError } from 'got' - -/** - * @see https://wiki.vg/Authentication#Errors - */ -export enum MojangResponseCode { - SUCCESS, - ERROR, - ERROR_METHOD_NOT_ALLOWED, // INTERNAL - ERROR_NOT_FOUND, // INTERNAL - ERROR_USER_MIGRATED, - ERROR_INVALID_CREDENTIALS, - ERROR_RATELIMIT, - ERROR_INVALID_TOKEN, - ERROR_ACCESS_TOKEN_HAS_PROFILE, // ?? - ERROR_CREDENTIALS_ARE_NULL, // INTERNAL - ERROR_INVALID_SALT_VERSION, // ?? - ERROR_UNSUPPORTED_MEDIA_TYPE // INTERNAL -} - -export interface MojangResponse { - - data: T - responseCode: MojangResponseCode - error?: RequestError - isInternalError?: boolean - -} - -export interface MojangErrorBody { - error: string - errorMessage: string - cause?: string -} - -export function deciperResponseCode(body: MojangErrorBody): MojangResponseCode { - - if(body.error === 'Method Not Allowed') { - return MojangResponseCode.ERROR_METHOD_NOT_ALLOWED - } else if(body.error === 'Not Found') { - return MojangResponseCode.ERROR_NOT_FOUND - } else if(body.error === 'Unsupported Media Type') { - return MojangResponseCode.ERROR_UNSUPPORTED_MEDIA_TYPE - } else if(body.error === 'ForbiddenOperationException') { - - if(body.cause && body.cause === 'UserMigratedException') { - return MojangResponseCode.ERROR_USER_MIGRATED - } - - if(body.errorMessage === 'Invalid credentials. Invalid username or password.') { - return MojangResponseCode.ERROR_INVALID_CREDENTIALS - } else if(body.errorMessage === 'Invalid credentials.') { - return MojangResponseCode.ERROR_RATELIMIT - } else if(body.errorMessage === 'Invalid token.') { - return MojangResponseCode.ERROR_INVALID_TOKEN - } - - } else if(body.error === 'IllegalArgumentException') { - - if(body.errorMessage === 'Access token already has a profile assigned.') { - return MojangResponseCode.ERROR_ACCESS_TOKEN_HAS_PROFILE - } else if(body.errorMessage === 'credentials is null') { - return MojangResponseCode.ERROR_CREDENTIALS_ARE_NULL - } else if(body.errorMessage === 'Invalid salt version') { - return MojangResponseCode.ERROR_INVALID_SALT_VERSION - } - - } - - return MojangResponseCode.ERROR - -} - -// These indicate problems with the code and not the data. -export function isInternalError(responseCode: MojangResponseCode): boolean { - switch(responseCode) { - case MojangResponseCode.ERROR_METHOD_NOT_ALLOWED: // We've sent the wrong method to an endpoint. (ex. GET to POST) - case MojangResponseCode.ERROR_NOT_FOUND: // Indicates endpoint has changed. (404) - case MojangResponseCode.ERROR_ACCESS_TOKEN_HAS_PROFILE: // Selecting profiles isn't implemented yet. (Shouldnt happen) - case MojangResponseCode.ERROR_CREDENTIALS_ARE_NULL: // Username/password was not submitted. (UI should forbid this) - case MojangResponseCode.ERROR_INVALID_SALT_VERSION: // ??? (Shouldnt happen) - case MojangResponseCode.ERROR_UNSUPPORTED_MEDIA_TYPE: // Data was not submitted as application/json - return true - default: - return false - } -} \ No newline at end of file diff --git a/src/common/mojang/mojang.ts b/src/common/mojang/mojang.ts index f910b7b..bdcb8d9 100644 --- a/src/common/mojang/mojang.ts +++ b/src/common/mojang/mojang.ts @@ -1,10 +1,11 @@ import { LoggerUtil } from '../logging/loggerutil' import { Agent } from './model/auth/Agent' import { Status, StatusColor } from './model/internal/Status' -import got, { RequestError, HTTPError, TimeoutError, ParseError } from 'got' +import got, { RequestError, HTTPError } from 'got' import { Session } from './model/auth/Session' import { AuthPayload } from './model/auth/AuthPayload' -import { MojangResponse, MojangResponseCode, deciperResponseCode, isInternalError, MojangErrorBody } from './model/internal/Response' +import { MojangResponse, MojangErrorCode, decipherErrorCode, isInternalError, MojangErrorBody } from './model/internal/MojangResponse' +import { RestResponseStatus, handleGotError } from 'common/got/RestResponse' export class Mojang { @@ -90,31 +91,16 @@ export class Mojang { } private static handleGotError(operation: string, error: RequestError, dataProvider: () => T): MojangResponse { - const response: MojangResponse = { - data: dataProvider(), - responseCode: MojangResponseCode.ERROR, - error - } - + + const response: MojangResponse = handleGotError(operation, error, Mojang.logger, dataProvider) + if(error instanceof HTTPError) { - response.responseCode = deciperResponseCode(error.response.body as MojangErrorBody) - Mojang.logger.error(`Error during ${operation} request (HTTP Response ${error.response.statusCode})`, error) - Mojang.logger.debug('Response Details:') - Mojang.logger.debug('Body:', error.response.body) - Mojang.logger.debug('Headers:', error.response.headers) - } else if(Object.getPrototypeOf(error) instanceof RequestError) { - Mojang.logger.error(`${operation} request recieved no response (${error.code}).`, error) - } else if(error instanceof TimeoutError) { - Mojang.logger.error(`${operation} request timed out (${error.timings.phases.total}ms).`) - } else if(error instanceof ParseError) { - Mojang.logger.error(`${operation} request recieved unexepected body (Parse Error).`) + response.mojangErrorCode = decipherErrorCode(error.response.body as MojangErrorBody) } else { - // CacheError, ReadError, MaxRedirectsError, UnsupportedProtocolError, CancelError - Mojang.logger.error(`Error during ${operation} request.`, error) + response.mojangErrorCode = MojangErrorCode.UNKNOWN } - - response.isInternalError = isInternalError(response.responseCode) - + response.isInternalError = isInternalError(response.mojangErrorCode) + return response } @@ -151,7 +137,7 @@ export class Mojang { return { data: Mojang.statuses, - responseCode: MojangResponseCode.SUCCESS + responseStatus: RestResponseStatus.SUCCESS } } catch(error) { @@ -201,7 +187,7 @@ export class Mojang { Mojang.expectSpecificSuccess('Mojang Authenticate', 200, res.statusCode) return { data: res.body, - responseCode: MojangResponseCode.SUCCESS + responseStatus: RestResponseStatus.SUCCESS } } catch(err) { @@ -233,14 +219,14 @@ export class Mojang { return { data: res.statusCode === 204, - responseCode: MojangResponseCode.SUCCESS + responseStatus: RestResponseStatus.SUCCESS } } catch(err) { if(err instanceof HTTPError && err.response.statusCode === 403) { return { data: false, - responseCode: MojangResponseCode.SUCCESS + responseStatus: RestResponseStatus.SUCCESS } } return Mojang.handleGotError('Mojang Validate', err, () => false) @@ -271,7 +257,7 @@ export class Mojang { return { data: undefined, - responseCode: MojangResponseCode.SUCCESS + responseStatus: RestResponseStatus.SUCCESS } } catch(err) { @@ -306,7 +292,7 @@ export class Mojang { return { data: res.body, - responseCode: MojangResponseCode.SUCCESS + responseStatus: RestResponseStatus.SUCCESS } } catch(err) { diff --git a/src/main/index.ts b/src/main/index.ts index 8361ab8..08aabac 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -113,7 +113,9 @@ async function createWindow() { webPreferences: { preload: join(__dirname, '..', 'out', 'preloader.js'), nodeIntegration: true, - contextIsolation: false + contextIsolation: false, + enableRemoteModule: true, + worldSafeExecuteJavaScript: true }, backgroundColor: '#171614' }) diff --git a/src/renderer/components/Application.tsx b/src/renderer/components/Application.tsx index 561efe6..8df98d6 100644 --- a/src/renderer/components/Application.tsx +++ b/src/renderer/components/Application.tsx @@ -17,6 +17,8 @@ import { join } from 'path' import Overlay from './overlay/Overlay' import { OverlayPushAction, OverlayActionDispatch } from '../redux/actions/overlayActions' +import { DistributionAPI } from 'common/distribution/distribution' + import './Application.css' declare const __static: string @@ -120,9 +122,14 @@ class Application extends React.Component { //this.props.setView(View.WELCOME) this.props.pushGenericOverlay({ - title: 'Test Title', - description: 'Test Description', - dismissible: true + title: 'Load Distribution', + description: 'This is a test. Will load the distribution.', + dismissible: false, + acknowledgeCallback: async () => { + const distro = new DistributionAPI('C:\\Users\\user\\AppData\\Roaming\\Helios Launcher') + const x = await distro.testLoad() + console.log(x) + } }) this.props.pushGenericOverlay({ title: 'Test Title 2', diff --git a/src/renderer/components/overlay/generic-overlay/GenericOverlay.tsx b/src/renderer/components/overlay/generic-overlay/GenericOverlay.tsx index 3770b82..ba23f6d 100644 --- a/src/renderer/components/overlay/generic-overlay/GenericOverlay.tsx +++ b/src/renderer/components/overlay/generic-overlay/GenericOverlay.tsx @@ -10,8 +10,8 @@ export interface GenericOverlayProps { acknowledgeText?: string dismissText?: string dismissible: boolean - acknowledgeCallback?: (event: React.MouseEvent) => void - dismissCallback?: (event: React.MouseEvent) => void + acknowledgeCallback?: (event: React.MouseEvent) => Promise + dismissCallback?: (event: React.MouseEvent) => Promise } const mapDispatch = { @@ -30,16 +30,16 @@ class GenericOverlay extends React.Component { return this.props.dismissText || 'Dismiss' } - private onAcknowledgeClick = (event: React.MouseEvent): void => { + private onAcknowledgeClick = async (event: React.MouseEvent): Promise => { if(this.props.acknowledgeCallback) { - this.props.acknowledgeCallback(event) + await this.props.acknowledgeCallback(event) } this.props.popOverlayContent() } - private onDismissClick = (event: React.MouseEvent): void => { + private onDismissClick = async (event: React.MouseEvent): Promise => { if(this.props.dismissCallback) { - this.props.dismissCallback(event) + await this.props.dismissCallback(event) } this.props.popOverlayContent() } diff --git a/test/mojang/mojangTest.ts b/test/mojang/mojangTest.ts index f780245..d0d9875 100644 --- a/test/mojang/mojangTest.ts +++ b/test/mojang/mojangTest.ts @@ -1,17 +1,33 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { Mojang } from 'common/mojang/mojang' import { expect } from 'chai' import nock from 'nock' import { Session } from 'common/mojang/model/auth/Session' -import { MojangResponseCode } from 'common/mojang/model/internal/Response' +import { MojangErrorCode, MojangResponse } from 'common/mojang/model/internal/MojangResponse' +import { RestResponseStatus, RestResponse } from 'common/got/RestResponse' -function expectMojangResponse(res: any, responseCode: MojangResponseCode, negate = false) { +function assertResponse(res: RestResponse) { expect(res).to.not.be.an('error') expect(res).to.be.an('object') - expect(res).to.have.property('responseCode') +} + +function expectSuccess(res: RestResponse) { + assertResponse(res) + expect(res).to.have.property('responseStatus') + expect(res.responseStatus).to.equal(RestResponseStatus.SUCCESS) +} + +function expectFailure(res: RestResponse) { + expect(res.responseStatus).to.not.equal(RestResponseStatus.SUCCESS) +} + +function expectMojangResponse(res: MojangResponse, responseCode: MojangErrorCode, negate = false) { + assertResponse(res) + expect(res).to.have.property('mojangErrorCode') if(!negate) { - expect(res.responseCode).to.equal(responseCode) + expect(res.mojangErrorCode).to.equal(responseCode) } else { - expect(res.responseCode).to.not.equal(responseCode) + expect(res.mojangErrorCode).to.not.equal(responseCode) } } @@ -30,7 +46,7 @@ describe('Mojang Errors', () => { .reply(500, 'Service temprarily offline.') const res = await Mojang.status() - expectMojangResponse(res, MojangResponseCode.SUCCESS, true) + expectFailure(res) expect(res.data).to.be.an('array') expect(res.data).to.deep.equal(defStatusHack) @@ -40,7 +56,8 @@ describe('Mojang Errors', () => { nock(Mojang.AUTH_ENDPOINT) .post('/authenticate') - .reply(403, (uri, requestBody: any): { error: string, errorMessage: string } => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + .reply(403, (uri, requestBody: unknown): { error: string, errorMessage: string } => { return { error: 'ForbiddenOperationException', errorMessage: 'Invalid credentials. Invalid username or password.' @@ -48,7 +65,7 @@ describe('Mojang Errors', () => { }) const res = await Mojang.authenticate('user', 'pass', 'xxx', true) - expectMojangResponse(res, MojangResponseCode.ERROR_INVALID_CREDENTIALS) + expectMojangResponse(res, MojangErrorCode.ERROR_INVALID_CREDENTIALS) expect(res.data).to.be.a('null') expect(res.error).to.not.be.a('null') @@ -66,7 +83,7 @@ describe('Mojang Status', () => { .reply(200, defStatusHack) const res = await Mojang.status() - expectMojangResponse(res, MojangResponseCode.SUCCESS) + expectSuccess(res) expect(res.data).to.be.an('array') expect(res.data).to.deep.equal(defStatusHack) @@ -101,7 +118,7 @@ describe('Mojang Auth', () => { }) const res = await Mojang.authenticate('user', 'pass', 'xxx', true) - expectMojangResponse(res, MojangResponseCode.SUCCESS) + expectSuccess(res) expect(res.data!.clientToken).to.equal('xxx') expect(res.data).to.have.property('user') @@ -120,13 +137,13 @@ describe('Mojang Auth', () => { const res = await Mojang.validate('abc', 'def') - expectMojangResponse(res, MojangResponseCode.SUCCESS) + expectSuccess(res) expect(res.data).to.be.a('boolean') expect(res.data).to.equal(true) const res2 = await Mojang.validate('def', 'def') - expectMojangResponse(res2, MojangResponseCode.SUCCESS) + expectSuccess(res2) expect(res2.data).to.be.a('boolean') expect(res2.data).to.equal(false) @@ -140,7 +157,7 @@ describe('Mojang Auth', () => { const res = await Mojang.invalidate('adc', 'def') - expectMojangResponse(res, MojangResponseCode.SUCCESS) + expectSuccess(res) }) @@ -169,7 +186,7 @@ describe('Mojang Auth', () => { }) const res = await Mojang.refresh('gfd', 'xxx', true) - expectMojangResponse(res, MojangResponseCode.SUCCESS) + expectSuccess(res) expect(res.data!.clientToken).to.equal('xxx') expect(res.data).to.have.property('user')