diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 88390710..04acc8c3 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1 @@ github: rauenzi -patreon: Zerebos -custom: ["https://paypal.me/ZackRauen"] diff --git a/README.md b/README.md index 935a1174..e3c0e8ac 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ A simple standalone program which automates the installation, removal and maintenance of BetterDiscord.

- + Chat diff --git a/package.json b/package.json index 99aff4f0..3943d6e8 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "source-map-support": "^0.5.16" }, "devDependencies": { - "electron": "13.6.9", - "electron-builder": "23.6.0", + "electron": "^13.6.9", + "electron-builder": "^23.6.0", "electron-webpack": "^2.8.2", "eslint": "^7.21.0", "eslint-plugin-svelte3": "^3.1.2", diff --git a/src/renderer/actions/install.js b/src/renderer/actions/install.js index e519a420..19767425 100644 --- a/src/renderer/actions/install.js +++ b/src/renderer/actions/install.js @@ -1,5 +1,5 @@ -import {progress} from "../stores/installation"; -import {remote} from "electron"; +import {progress, status} from "../stores/installation"; +import {remote, shell} from "electron"; import {promises as fs} from "fs"; import originalFs from "original-fs"; import path from "path"; @@ -15,46 +15,19 @@ import restart from "./utils/restart"; import {showRestartNotice, showKillNotice} from "./utils/notices"; import doSanityCheck from "./utils/sanity"; -const KILL_DISCORD_PROGRESS = 10; -const MAKE_DIR_PROGRESS = 20; -const CHECK_OLD_INSTALL = 30; -const TRANSFER_OLD_ADDONS = 40; +const MAKE_DIR_PROGRESS = 30; const DOWNLOAD_PACKAGE_PROGRESS = 60; const INJECT_SHIM_PROGRESS = 80; const RENAME_ASAR_PROGRESS = 90; const RESTART_DISCORD_PROGRESS = 100; -const oldBDFolder = path.join(remote.app.getPath("home"), "Library", "Preferences", "betterdiscord"); // Old MacOS +const RELEASE_API = "https://api.github.com/repos/BetterDiscord/BetterDiscord/releases"; + const bdFolder = path.join(remote.app.getPath("appData"), "BetterDiscord"); const bdDataFolder = path.join(bdFolder, "data"); const bdPluginsFolder = path.join(bdFolder, "plugins"); const bdThemesFolder = path.join(bdFolder, "themes"); -async function checkOldMacOS(folder) { - if (await exists(folder)) { - log(`⚠️ Found old BD installation: ${folder}`); - return true; - } - return false; -} - -async function transferOldAddons(oldFolder, newFolder) { - if (await exists(oldFolder)) { - const addons = await fs.readdir(oldFolder); - for (let a = 0; a < addons.length; a++) { - const oldName = path.join(oldFolder, addons[a]); - const newName = path.join(newFolder, addons[a]); - const stats = await fs.stat(oldName); - if (!stats.isFile()) continue; - try { - await fs.rename(oldName, newName); - } - catch (err) { - log(`❌ Failed to transfer: ${addons[a]}`); - } - } - } -} async function makeDirectories(...folders) { const progressPerLoop = (MAKE_DIR_PROGRESS - progress.value) / folders.length; @@ -77,13 +50,11 @@ async function makeDirectories(...folders) { } } -const getJSON = phin.defaults({method: "GET", parse: "json", followRedirects: true, headers: {"User-Agent": "BetterDiscord Installer"}}); -const downloadFile = phin.defaults({method: "GET", followRedirects: true, headers: {"User-Agent": "BetterDiscord Installer", "Accept": "application/octet-stream"}}); +const getJSON = phin.defaults({method: "GET", parse: "json", followRedirects: true, headers: {"User-Agent": "BetterDiscord/Installer"}}); +const downloadFile = phin.defaults({method: "GET", followRedirects: true, headers: {"User-Agent": "BetterDiscord/Installer", "Accept": "application/octet-stream"}}); const asarPath = path.join(bdDataFolder, "betterdiscord.asar"); async function downloadAsar() { - const releaseApiUrl = "https://api.github.com/repos/BetterDiscord/BetterDiscord/releases"; - try { - const response = await getJSON(releaseApiUrl); + const response = await getJSON(RELEASE_API); const releases = response.body; const asset = releases && releases.length && releases[0].assets && releases[0].assets.find(a => a.name.toLowerCase() === "betterdiscord.asar"); const assetUrl = asset && asset.url; @@ -96,8 +67,8 @@ async function downloadAsar() { } try { const resp = await downloadFile(assetUrl); - const ofs = originalFs.promises; // because electron doesn't like when I write asar files - await ofs.writeFile(asarPath, resp.body); + const originalFs = require("original-fs").promises; // because electron doesn't like when I write asar files + await originalFs.writeFile(asarPath, resp.body); } catch (error) { log(`❌ Failed to download package from ${assetUrl}`); @@ -106,7 +77,7 @@ async function downloadAsar() { } } catch (err) { - log(`❌ Failed to get asset url from ${releaseApiUrl}`); + log(`❌ Failed to get asset url from ${RELEASE_API}`); log(`❌ ${err.message}`); return err; } @@ -116,18 +87,8 @@ async function injectShims(paths) { const progressPerLoop = (INJECT_SHIM_PROGRESS - progress.value) / paths.length; for (const discordPath of paths) { log("Injecting into: " + discordPath); - const appPath = path.join(discordPath, "app"); - const pkgFile = path.join(appPath, "package.json"); - const indexFile = path.join(appPath, "index.js"); try { - if (process.platform === "win32" || process.platform === "darwin") { - if (!(await exists(appPath))) await fs.mkdir(appPath); - await fs.writeFile(pkgFile, JSON.stringify({name: "betterdiscord", main: "index.js"})); - await fs.writeFile(indexFile, `require("${asarPath.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}");`); - } - else { - await fs.writeFile(path.join(discordPath, "index.js"), `require("${asarPath.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}");\nmodule.exports = require("./core.asar");`); - } + await fs.writeFile(path.join(discordPath, "index.js"), `require("${asarPath.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}");\nmodule.exports = require("./core.asar");`); log("✅ Injection successful"); progress.set(progress.value + progressPerLoop); } @@ -188,29 +149,6 @@ export default async function(config) { if (makeDirErr) return fail(); log("✅ Directories created"); progress.set(MAKE_DIR_PROGRESS); - - - if (process.platform === "darwin") { - lognewline("Checking for old MacOS installation..."); - const found = await checkOldMacOS(oldBDFolder); - progress.set(CHECK_OLD_INSTALL); - if (found) { - const confirmation = await remote.dialog.showMessageBox(remote.BrowserWindow.getFocusedWindow(), { - type: "question", - title: "Old Install Found", - message: "Found an old BD installation, do you want to transfer your plugins and themes?", - noLink: true, - cancelId: 1, - buttons: ["Yes", "No"] - }); - - if (confirmation.response === 0) { - await transferOldAddons(path.join(oldBDFolder, "plugins"), path.join(bdFolder, "plugins")); - await transferOldAddons(path.join(oldBDFolder, "themes"), path.join(bdFolder, "themes")); - progress.set(TRANSFER_OLD_ADDONS); - } - } - } lognewline("Downloading asar file"); diff --git a/src/renderer/actions/paths.js b/src/renderer/actions/paths.js index 5e07e570..b434fd7d 100644 --- a/src/renderer/actions/paths.js +++ b/src/renderer/actions/paths.js @@ -15,27 +15,26 @@ const safeIsDir = (fullpath) => { }; const getDiscordPath = function(releaseChannel) { - let resourcePath = ""; + let desktopCorePath = ""; if (process.platform === "win32") { let basedir = path.join(process.env.LOCALAPPDATA, releaseChannel.replace(/ /g, "")); // Normal install path in AppData\Local if (!fs.existsSync(basedir)) basedir = path.join(process.env.PROGRAMDATA, process.env.USERNAME, releaseChannel.replace(/ /g, "")); // Atypical location in ProgramData\%username% if (!fs.existsSync(basedir)) return ""; const version = fs.readdirSync(basedir).filter(f => safeIsDir(path.join(basedir, f)) && f.split(".").length > 1).sort().reverse()[0]; if (!version) return ""; - resourcePath = path.join(basedir, version, "resources"); - } - else if (process.platform === "darwin") { - resourcePath = path.join("/Applications", `${releaseChannel}.app`, "Contents", "Resources"); + // To account for discord_desktop_core-1 or discord_dekstop_core-2 + const coreWrap = fs.readdirSync(path.join(basedir, version, "modules")).filter(e => e.indexOf("discord_desktop_core") === 0).sort().reverse()[0]; + desktopCorePath = path.join(basedir, version, "modules", coreWrap, "discord_desktop_core"); } else { const basedir = path.join(remote.app.getPath("userData"), "..", releaseChannel.toLowerCase().replace(" ", "")); if (!fs.existsSync(basedir)) return ""; const version = fs.readdirSync(basedir).filter(f => safeIsDir(path.join(basedir, f)) && f.split(".").length > 1).sort().reverse()[0]; if (!version) return ""; - resourcePath = path.join(basedir, version, "modules", "discord_desktop_core"); + desktopCorePath = path.join(basedir, version, "modules", "discord_desktop_core"); } - if (fs.existsSync(resourcePath)) return resourcePath; + if (fs.existsSync(desktopCorePath)) return desktopCorePath; return ""; }; @@ -45,14 +44,12 @@ for (const channel in platforms) { export const getBrowsePath = function(channel) { if (process.platform === "win32") return path.join(process.env.LOCALAPPDATA, platforms[channel].replace(" ", "")); - else if (process.platform === "darwin") return path.join("/Applications", `${platforms[channel]}.app`); return path.join(remote.app.getPath("userData"), "..", platforms[channel].toLowerCase().replace(" ", "")); }; export const validatePath = function(channel, proposedPath) { if (process.platform === "win32") return validateWindows(channel, proposedPath); - else if (process.platform === "darwin") return validateMac(channel, proposedPath); - return validateLinux(channel, proposedPath); + return validateLinuxMac(channel, proposedPath); }; const validateWindows = function(channel, proposedPath) { @@ -61,36 +58,30 @@ const validateWindows = function(channel, proposedPath) { const isParentDir = fs.existsSync(path.join(proposedPath, channelName)); if (isParentDir) proposedPath = path.join(proposedPath, channelName); - let resourcePath = ""; + let corePath = ""; const selected = path.basename(proposedPath); const isBaseDir = selected === channelName; if (isBaseDir) { const version = fs.readdirSync(proposedPath).filter(f => safeIsDir(path.join(proposedPath, f)) && f.split(".").length > 1).sort().reverse()[0]; if (!version) return ""; - resourcePath = path.join(proposedPath, version, "resources"); + // To account for discord_desktop_core-1 or discord_dekstop_core-2 + const coreWrap = fs.readdirSync(path.join(proposedPath, version, "modules")).filter(e => e.indexOf("discord_desktop_core") === 0).sort().reverse()[0]; + corePath = path.join(proposedPath, version, "modules", coreWrap, "discord_desktop_core"); } - if (selected.startsWith("app-") && selected.split(".").length > 2) resourcePath = path.join(proposedPath, "resources"); - if (selected === "resources") resourcePath = proposedPath; - - const executablePath = path.join(resourcePath, "..", `${channelName}.exe`); - if (fs.existsSync(executablePath)) return resourcePath; - return ""; -}; - -const validateMac = function(channel, proposedPath) { - let resourcePath = ""; - const selected = path.basename(proposedPath); - if (selected === `${platforms[channel]}.app`) resourcePath = path.join(proposedPath, "Contents", "Resources"); - if (selected === "Contents") resourcePath = path.join(proposedPath, "Resources"); - if (selected === "Resources") resourcePath = proposedPath; + if (selected.split(".").length > 2) { + // To account for discord_desktop_core-1 or discord_dekstop_core-2 + const coreWrap = fs.readdirSync(path.join(proposedPath), "modules").filter(e => e.indexOf("discord_desktop_core") === 0).sort().reverse()[0]; + corePath = path.join(proposedPath, "modules", coreWrap, "discord_desktop_core"); + } + if (selected === "discord_desktop_core") corePath = proposedPath; - const executablePath = path.join(resourcePath, "..", "MacOS", platforms[channel]); - if (fs.existsSync(executablePath)) return resourcePath; + const coreAsar = path.join(corePath, `core.asar`); + if (fs.existsSync(coreAsar)) return corePath; return ""; }; -const validateLinux = function(channel, proposedPath) { +const validateLinuxMac = function(channel, proposedPath) { if (proposedPath.includes("/snap/")) { remote.dialog.showErrorBox("BetterDiscord Incompatible", "BetterDiscord is currently incompatible with Snap installs of Discord. Support for snap installs is coming soon!"); return ""; diff --git a/src/renderer/actions/repair.js b/src/renderer/actions/repair.js index 5a5e86ad..8ac85f51 100644 --- a/src/renderer/actions/repair.js +++ b/src/renderer/actions/repair.js @@ -1,5 +1,5 @@ -import {progress, status} from "../stores/installation"; +import {progress} from "../stores/installation"; import {remote} from "electron"; import {promises as fs} from "fs"; import originalFs from "original-fs"; @@ -16,56 +16,30 @@ import {showKillNotice} from "./utils/notices"; import doSanityCheck from "./utils/sanity"; const KILL_DISCORD_PROGRESS = 20; -const DELETE_APP_DIRS_PROGRESS = 50; -const RENAME_ASAR_PROGRESS = 80; +const DELETE_SHIM_PROGRESS = 60; const DELETE_PLUGINS_JSON_PROGRESS = 100; -async function deleteAppDirs(paths) { - const progressPerLoop = (DELETE_APP_DIRS_PROGRESS - progress.value) / paths.length; - for (const discordPath of paths) { - log("Removing " + discordPath); - const appPath = path.join(discordPath, "app"); - if (await exists(appPath)) { - const error = await new Promise(resolve => rimraf(appPath, originalFs, resolve)); - if (error) { - log(`❌ Could not delete folder ${appPath}`); - log(`❌ ${error.message}`); - return error; - } - } - log("✅ Deletion successful"); - progress.set(progress.value + progressPerLoop); - } -} -async function renameAsar(paths) { - const progressPerLoop = (RENAME_ASAR_PROGRESS - progress.value) / paths.length; +async function deleteShims(paths) { + const progressPerLoop = (DELETE_SHIM_PROGRESS - progress.value) / paths.length; for (const discordPath of paths) { - const appAsar = path.join(discordPath, "app.asar"); - const discordAsar = path.join(discordPath, "discord.asar"); - log("Renaming " + discordAsar); + const indexFile = path.join(discordPath, "index.js"); + log("Removing " + indexFile); try { - const appAsarExists = originalFs.existsSync(appAsar); - const discordAsarExists = originalFs.existsSync(discordAsar); - if (!appAsarExists && !discordAsarExists) throw new Error("Discord installation corrupt, please reinstall."); - if (appAsarExists && discordAsarExists) originalFs.rmSync(appAsar); - if (discordAsarExists) originalFs.renameSync(discordAsar, appAsar); - log("✅ Rename successful"); + if (await exists(indexFile)) await fs.writeFile(indexFile, `module.exports = require("./core.asar");`); + log("✅ Deletion successful"); progress.set(progress.value + progressPerLoop); } - catch (error) { - log(`❌ Could not rename asar ${discordAsar}`); - log(`❌ ${error.message}`); - return error; + catch (err) { + log(`❌ Could not delete file ${indexFile}`); + log(`❌ ${err.message}`); + return err; } - } } - const bdFolder = path.join(remote.app.getPath("appData"), "BetterDiscord"); const bdDataFolder = path.join(bdFolder, "data"); - async function disableAllPlugins(channels) { const progressPerLoop = (DELETE_PLUGINS_JSON_PROGRESS - progress.value) / channels.length; for (const channel of channels) { @@ -134,27 +108,17 @@ export default async function(config) { await new Promise(r => setTimeout(r, 200)); lognewline("Deleting shims..."); - const deleteShimErr = await deleteAppDirs(paths); + const deleteShimErr = await deleteShims(paths); if (deleteShimErr) return fail(); log("✅ Shims deleted"); - progress.set(DELETE_APP_DIRS_PROGRESS); - - - if (process.platform === "win32" || process.platform === "darwin") { - await new Promise(r => setTimeout(r, 200)); - lognewline("Renaming asars..."); - const renameAsarErr = await renameAsar(paths); - if (renameAsarErr) return fail(); - log("✅ Asars renamed"); - progress.set(RENAME_ASAR_PROGRESS); - } + progress.set(DELETE_SHIM_PROGRESS); await new Promise(r => setTimeout(r, 200)); - lognewline("Deleting discord modules..."); + lognewline("Disabling all plugins..."); const deleteJsonErr = await disableAllPlugins(channels); if (deleteJsonErr) return fail(); - log("✅ Modules deleted"); + log("✅ Plugins disabled"); progress.set(DELETE_PLUGINS_JSON_PROGRESS); diff --git a/src/renderer/actions/uninstall.js b/src/renderer/actions/uninstall.js index 93463ea6..04e668a5 100644 --- a/src/renderer/actions/uninstall.js +++ b/src/renderer/actions/uninstall.js @@ -25,24 +25,15 @@ const RESTART_DISCORD_PROGRESS = 100; async function deleteShims(paths) { const progressPerLoop = (DELETE_SHIM_PROGRESS - progress.value) / paths.length; for (const discordPath of paths) { - log("Removing " + discordPath); - const appPath = path.join(discordPath, "app"); const indexFile = path.join(discordPath, "index.js"); + log("Removing " + indexFile); try { - if (process.platform === "win32" || process.platform === "darwin") { - if (await exists(appPath)) { - const error = await new Promise(r => rimraf(appPath, originalFs, r)); - if (error) throw error; // Throw instead because there are multiple throw points - } - } - else { - if (await exists(indexFile)) await fs.writeFile(indexFile, `module.exports = require("./core.asar");`); - } + if (await exists(indexFile)) await fs.writeFile(indexFile, `module.exports = require("./core.asar");`); log("✅ Deletion successful"); progress.set(progress.value + progressPerLoop); } catch (err) { - log(`❌ Could not delete folder ${appPath}`); + log(`❌ Could not delete file ${indexFile}`); log(`❌ ${err.message}`); return err; } diff --git a/yarn.lock b/yarn.lock index b8ec5052..717c1929 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1041,9 +1041,9 @@ integrity sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw== "@types/node@^14.6.2": - version "14.18.33" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.33.tgz#8c29a0036771569662e4635790ffa9e057db379b" - integrity sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg== + version "14.18.34" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.34.tgz#cd2e6fa0dbfb08a62582a7b967558e73c32061ec" + integrity sha512-hcU9AIQVHmPnmjRK+XUUYlILlr9pQrsqSrwov/JK1pnf3GTQowVBhx54FbvM0AU/VXGH4i3+vgXS5EguR7fysA== "@types/plist@^3.0.1": version "3.0.2" @@ -2902,7 +2902,7 @@ ejs@^3.1.7: dependencies: jake "^10.8.5" -electron-builder@23.6.0: +electron-builder@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-23.6.0.tgz#c79050cbdce90ed96c5feb67c34e9e0a21b5331b" integrity sha512-y8D4zO+HXGCNxFBV/JlyhFnoQ0Y0K7/sFH+XwIbj47pqaW8S6PGYQbjoObolKBR1ddQFPt4rwp4CnwMJrW3HAw== @@ -3006,7 +3006,7 @@ electron-webpack@^2.8.2: webpack-merge "^4.2.2" yargs "^15.3.1" -electron@13.6.9: +electron@^13.6.9: version "13.6.9" resolved "https://registry.yarnpkg.com/electron/-/electron-13.6.9.tgz#7bd83cc1662ceaaa09dcd132a7b507cec888b028" integrity sha512-Es/sBy85NIuqsO9MW41PUCpwIkeinlTQ7g0ainfnmRAM2rmog3GBxVCaoV5dzEjwTF7TKG1Yr/E7Z3qHmlfWAg== @@ -5067,6 +5067,13 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" +minipass@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.0.0.tgz#7cebb0f9fa7d56f0c5b17853cbe28838a8dbbd3b" + integrity sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw== + dependencies: + yallist "^4.0.0" + minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -6435,9 +6442,9 @@ signal-exit@^3.0.0: integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== simple-update-notifier@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz#7edf75c5bdd04f88828d632f762b2bc32996a9cc" - integrity sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew== + version "1.1.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" + integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== dependencies: semver "~7.0.0" @@ -6842,13 +6849,13 @@ tapable@^1.0.0, tapable@^1.1.3: integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== tar@^6.1.11: - version "6.1.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" - integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== + version "6.1.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" + integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" - minipass "^3.0.0" + minipass "^4.0.0" minizlib "^2.1.1" mkdirp "^1.0.3" yallist "^4.0.0" @@ -7573,7 +7580,7 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^21.0.0: +yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== @@ -7612,9 +7619,9 @@ yargs@^15.3.1: yargs-parser "^18.1.2" yargs@^17.5.1: - version "17.6.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.0.tgz#e134900fc1f218bc230192bdec06a0a5f973e46c" - integrity sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g== + version "17.6.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" + integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== dependencies: cliui "^8.0.1" escalade "^3.1.1" @@ -7622,7 +7629,7 @@ yargs@^17.5.1: require-directory "^2.1.1" string-width "^4.2.3" y18n "^5.0.5" - yargs-parser "^21.0.0" + yargs-parser "^21.1.1" yauzl@^2.10.0: version "2.10.0"