From 90d8aef1f2695e520e07d5199e35cc11d1bbc87a Mon Sep 17 00:00:00 2001 From: joshmlxn Date: Mon, 3 Jun 2024 23:07:31 +0100 Subject: [PATCH] (WIP) Fix public OTA --- electron/.eslintrc.json | 5 +- electron/constants/publishOptions.js | 3 +- electron/install.js | 52 +++--- electron/main.js | 231 ++++++++++++++------------- electron/update.js | 47 ++++-- package.json | 3 +- yarn.lock | 69 ++++++-- 7 files changed, 239 insertions(+), 171 deletions(-) diff --git a/electron/.eslintrc.json b/electron/.eslintrc.json index 1aca62fc..7b4801c6 100644 --- a/electron/.eslintrc.json +++ b/electron/.eslintrc.json @@ -1,6 +1,6 @@ { "extends": ["eslint:recommended", "plugin:prettier/recommended"], - "plugins": ["prettier"], + "plugins": ["prettier", "no-unused-imports"], "ignorePatterns": [".next/"], "rules": { "prettier/prettier": [ @@ -11,7 +11,8 @@ "singleQuote": true } ], - "no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }] + "no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }], + "no-unused-imports/no-unused-imports": "error" }, "parserOptions": { "ecmaVersion": "latest", diff --git a/electron/constants/publishOptions.js b/electron/constants/publishOptions.js index f94f7670..c35e6464 100644 --- a/electron/constants/publishOptions.js +++ b/electron/constants/publishOptions.js @@ -5,7 +5,8 @@ const publishOptions = { releaseType: 'draft', token: process.env.GH_TOKEN, private: false, - publishAutoUpdate: false, + publishAutoUpdate: true, + }; module.exports = { publishOptions }; diff --git a/electron/install.js b/electron/install.js index 944ceac5..f80852e5 100644 --- a/electron/install.js +++ b/electron/install.js @@ -6,7 +6,7 @@ const fs = require('fs'); const os = require('os'); const sudo = require('sudo-prompt'); const process = require('process'); -const axios = require("axios") +const axios = require('axios'); const Docker = require('dockerode'); const { spawnSync } = require('child_process'); @@ -29,18 +29,21 @@ const SudoOptions = { }; const TendermintUrls = { darwin: { - x64: "https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_darwin_amd64.tar.gz", - arm64: "https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_darwin_arm64.tar.gz", + x64: 'https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_darwin_amd64.tar.gz', + arm64: + 'https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_darwin_arm64.tar.gz', }, linux: { - x64: "https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_linux_amd64.tar.gz", - arm64: "https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_linux_arm64.tar.gz", + x64: 'https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_linux_amd64.tar.gz', + arm64: + 'https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_linux_arm64.tar.gz', }, win32: { - x64: "https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_windows_amd64.tar.gz", - arm64: "https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_windows_arm64.tar.gz" - } -} + x64: 'https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_windows_amd64.tar.gz', + arm64: + 'https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_windows_arm64.tar.gz', + }, +}; function getBinPath(command) { return spawnSync('/usr/bin/which', [command], { env: Env }) @@ -133,7 +136,7 @@ async function downloadFile(url, dest) { const response = await axios({ url, method: 'GET', - responseType: 'stream' + responseType: 'stream', }); response.data.pipe(writer); return new Promise((resolve, reject) => { @@ -141,28 +144,29 @@ async function downloadFile(url, dest) { writer.on('error', reject); }); } catch (err) { - fs.unlink(dest, () => { }); // Delete the file if there is an error + fs.unlink(dest, () => {}); // Delete the file if there is an error console.error('Error downloading the file:', err.message); } } async function installTendermintUnix() { - const cwd = process.cwd() - process.chdir(TempDir) + const cwd = process.cwd(); + process.chdir(TempDir); - console.log(appendLog(`Installing tendermint for ${os.platform()}-${process.arch}`)) - const url = TendermintUrls[os.platform()][process.arch] + console.log( + appendLog(`Installing tendermint for ${os.platform()}-${process.arch}`), + ); + const url = TendermintUrls[os.platform()][process.arch]; - console.log(appendLog(`Downloading ${url}, might take a while...`)) - await downloadFile(url, `${TempDir}/tendermint.tar.gz`) + console.log(appendLog(`Downloading ${url}, might take a while...`)); + await downloadFile(url, `${TempDir}/tendermint.tar.gz`); - console.log(appendLog(`Installing tendermint binary`)) - await runCmdUnix("tar", ["-xvf", "tendermint.tar.gz"]) - await runSudoUnix("install", "tendermint /usr/local/bin") - process.chdir(cwd) + console.log(appendLog(`Installing tendermint binary`)); + await runCmdUnix('tar', ['-xvf', 'tendermint.tar.gz']); + await runSudoUnix('install', 'tendermint /usr/local/bin'); + process.chdir(cwd); } - function isDockerInstalledDarwin() { return Boolean(getBinPath('docker')); } @@ -310,7 +314,7 @@ async function setupDarwin(ipcChannel) { if (!isTendermintInstalledUnix()) { ipcChannel.send('response', 'Installing Pearl Daemon'); console.log(appendLog('Installing tendermint')); - await installTendermintUnix() + await installTendermintUnix(); } if (!fs.existsSync(VenvDir)) { @@ -364,7 +368,7 @@ async function setupUbuntu(ipcChannel) { if (!isTendermintInstalledUnix()) { ipcChannel.send('response', 'Installing Pearl Daemon'); console.log(appendLog('Installing tendermint')); - await installTendermintUnix() + await installTendermintUnix(); } if (!fs.existsSync(VenvDir)) { diff --git a/electron/main.js b/electron/main.js index faf83888..0dc81a8c 100644 --- a/electron/main.js +++ b/electron/main.js @@ -1,4 +1,4 @@ -const dotenv = require('dotenv'); +const dotenv = require("dotenv"); const { app, @@ -9,15 +9,15 @@ const { ipcMain, dialog, shell, -} = require('electron'); -const { spawn } = require('child_process'); -const path = require('path'); -const fs = require('fs'); -const os = require('os'); -const next = require('next'); -const http = require('http'); -const AdmZip = require('adm-zip'); -const { TRAY_ICONS, TRAY_ICONS_PATHS } = require('./icons'); +} = require("electron"); +const { spawn } = require("child_process"); +const path = require("path"); +const fs = require("fs"); +const os = require("os"); +const next = require("next"); +const http = require("http"); +const AdmZip = require("adm-zip"); +const { TRAY_ICONS, TRAY_ICONS_PATHS } = require("./icons"); const { setupDarwin, @@ -26,12 +26,12 @@ const { OperateDirectory, Env, dirs, -} = require('./install'); -const { killProcesses } = require('./processes'); -const { isPortAvailable, findAvailablePort } = require('./ports'); -const { PORT_RANGE, isWindows, isMac } = require('./constants'); -const { macUpdater } = require('./update'); -const { setupStoreIpc } = require('./store'); +} = require("./install"); +const { killProcesses } = require("./processes"); +const { isPortAvailable, findAvailablePort } = require("./ports"); +const { PORT_RANGE, isWindows, isMac } = require("./constants"); +const { macUpdater } = require("./update"); +const { setupStoreIpc } = require("./store"); // Configure environment variables dotenv.config(); @@ -40,8 +40,11 @@ dotenv.config(); const singleInstanceLock = app.requestSingleInstanceLock(); if (!singleInstanceLock) app.quit(); +// Attach mac updater +const macUpdater = setupMacUpdater(app); + const platform = os.platform(); -const isDev = process.env.NODE_ENV === 'development'; +const isDev = process.env.NODE_ENV === "development"; let appConfig = { ports: { @@ -104,54 +107,54 @@ const getUpdatedTrayIcon = (iconPath) => { */ const createTray = () => { const trayPath = getUpdatedTrayIcon( - isWindows || isMac ? TRAY_ICONS.LOGGED_OUT : TRAY_ICONS_PATHS.LOGGED_OUT, + isWindows || isMac ? TRAY_ICONS.LOGGED_OUT : TRAY_ICONS_PATHS.LOGGED_OUT ); const tray = new Tray(trayPath); const contextMenu = Menu.buildFromTemplate([ { - label: 'Show app', + label: "Show app", click: function () { mainWindow.show(); }, }, { - label: 'Hide app', + label: "Hide app", click: function () { mainWindow.hide(); }, }, { - label: 'Quit', + label: "Quit", click: async function () { await beforeQuit(); app.quit(); }, }, ]); - tray.setToolTip('Pearl'); + tray.setToolTip("Pearl"); tray.setContextMenu(contextMenu); - ipcMain.on('tray', (_event, status) => { + ipcMain.on("tray", (_event, status) => { switch (status) { - case 'low-gas': { + case "low-gas": { const icon = getUpdatedTrayIcon( - isWindows || isMac ? TRAY_ICONS.LOW_GAS : TRAY_ICONS_PATHS.LOW_GAS, + isWindows || isMac ? TRAY_ICONS.LOW_GAS : TRAY_ICONS_PATHS.LOW_GAS ); tray.setImage(icon); break; } - case 'running': { + case "running": { const icon = getUpdatedTrayIcon( - isWindows || isMac ? TRAY_ICONS.RUNNING : TRAY_ICONS_PATHS.RUNNING, + isWindows || isMac ? TRAY_ICONS.RUNNING : TRAY_ICONS_PATHS.RUNNING ); tray.setImage(icon); break; } - case 'paused': { + case "paused": { const icon = getUpdatedTrayIcon( - isWindows || isMac ? TRAY_ICONS.PAUSED : TRAY_ICONS_PATHS.PAUSED, + isWindows || isMac ? TRAY_ICONS.PAUSED : TRAY_ICONS_PATHS.PAUSED ); tray.setImage(icon); break; @@ -171,14 +174,14 @@ const createSplashWindow = () => { height: APP_WIDTH, resizable: false, show: true, - title: 'Pearl', + title: "Pearl", frame: false, webPreferences: { nodeIntegration: true, contextIsolation: false, }, }); - splashWindow.loadURL('file://' + __dirname + '/loading/index.html'); + splashWindow.loadURL("file://" + __dirname + "/loading/index.html"); if (isDev) { splashWindow.webContents.openDevTools(); @@ -192,7 +195,7 @@ const HEIGHT = 700; const createMainWindow = () => { const width = isDev ? 840 : APP_WIDTH; mainWindow = new BrowserWindow({ - title: 'Pearl', + title: "Pearl", resizable: false, draggable: true, frame: false, @@ -204,7 +207,7 @@ const createMainWindow = () => { webPreferences: { nodeIntegration: false, contextIsolation: true, - preload: path.join(__dirname, 'preload.js'), + preload: path.join(__dirname, "preload.js"), }, }); @@ -216,15 +219,15 @@ const createMainWindow = () => { mainWindow.loadURL(`http://localhost:${appConfig.ports.prod.next}`); } - ipcMain.on('close-app', () => { + ipcMain.on("close-app", () => { mainWindow.close(); }); - ipcMain.on('minimize-app', () => { + ipcMain.on("minimize-app", () => { mainWindow.minimize(); }); - app.on('activate', () => { + app.on("activate", () => { if (mainWindow.isMinimized()) { mainWindow.restore(); } else { @@ -232,29 +235,29 @@ const createMainWindow = () => { } }); - ipcMain.on('set-height', (_event, height) => { + ipcMain.on("set-height", (_event, height) => { mainWindow.setSize(width, height); }); - ipcMain.on('show-notification', (_event, title, description) => { + ipcMain.on("show-notification", (_event, title, description) => { showNotification(title, description || undefined); }); - mainWindow.webContents.on('did-fail-load', () => { + mainWindow.webContents.on("did-fail-load", () => { mainWindow.webContents.reloadIgnoringCache(); }); - mainWindow.webContents.on('ready-to-show', () => { + mainWindow.webContents.on("ready-to-show", () => { mainWindow.show(); }); mainWindow.webContents.setWindowOpenHandler(({ url }) => { // open url in a browser and prevent default - require('electron').shell.openExternal(url); - return { action: 'deny' }; + require("electron").shell.openExternal(url); + return { action: "deny" }; }); - mainWindow.on('close', function (event) { + mainWindow.on("close", function (event) { event.preventDefault(); mainWindow.hide(); }); @@ -268,8 +271,8 @@ const createMainWindow = () => { async function launchDaemon() { function appendLog(data) { - fs.appendFileSync(`${OperateDirectory}/logs.txt`, data.trim() + '\n', { - encoding: 'utf-8', + fs.appendFileSync(`${OperateDirectory}/logs.txt`, data.trim() + "\n", { + encoding: "utf-8", }); return data; } @@ -277,7 +280,7 @@ async function launchDaemon() { // Free up backend port if already occupied try { await fetch(`http://localhost:${appConfig.ports.prod.operate}/api`); - console.log('Killing backend server!'); + console.log("Killing backend server!"); let endpoint = fs .readFileSync(`${OperateDirectory}/operate.kill`) .toString() @@ -285,40 +288,40 @@ async function launchDaemon() { .trimRight(); await fetch(`http://localhost:${appConfig.ports.prod.operate}/${endpoint}`); } catch (err) { - console.log('Backend not running!'); + console.log("Backend not running!"); } const check = new Promise(function (resolve, _reject) { operateDaemon = spawn( OperateCmd, [ - 'daemon', + "daemon", `--port=${appConfig.ports.prod.operate}`, `--home=${OperateDirectory}`, ], - { env: Env }, + { env: Env } ); operateDaemonPid = operateDaemon.pid; fs.appendFileSync( `${OperateDirectory}/operate.pip`, `${operateDaemon.pid}`, { - encoding: 'utf-8', - }, + encoding: "utf-8", + } ); - operateDaemon.stderr.on('data', (data) => { - if (data.toString().includes('Uvicorn running on')) { + operateDaemon.stderr.on("data", (data) => { + if (data.toString().includes("Uvicorn running on")) { resolve({ running: true, error: null }); } if ( - data.toString().includes('error while attempting to bind on address') + data.toString().includes("error while attempting to bind on address") ) { - resolve({ running: false, error: 'Port already in use' }); + resolve({ running: false, error: "Port already in use" }); } console.log(appendLog(data.toString().trim())); }); - operateDaemon.stdout.on('data', (data) => { + operateDaemon.stdout.on("data", (data) => { console.log(appendLog(data.toString().trim())); }); }); @@ -327,26 +330,26 @@ async function launchDaemon() { async function launchDaemonDev() { const check = new Promise(function (resolve, _reject) { - operateDaemon = spawn('poetry', [ - 'run', - 'operate', - 'daemon', + operateDaemon = spawn("poetry", [ + "run", + "operate", + "daemon", `--port=${appConfig.ports.dev.operate}`, - '--home=.operate', + "--home=.operate", ]); operateDaemonPid = operateDaemon.pid; - operateDaemon.stderr.on('data', (data) => { - if (data.toString().includes('Uvicorn running on')) { + operateDaemon.stderr.on("data", (data) => { + if (data.toString().includes("Uvicorn running on")) { resolve({ running: true, error: null }); } if ( - data.toString().includes('error while attempting to bind on address') + data.toString().includes("error while attempting to bind on address") ) { - resolve({ running: false, error: 'Port already in use' }); + resolve({ running: false, error: "Port already in use" }); } console.log(data.toString().trim()); }); - operateDaemon.stdout.on('data', (data) => { + operateDaemon.stdout.on("data", (data) => { console.log(data.toString().trim()); }); }); @@ -360,11 +363,11 @@ async function launchNextApp() { port: appConfig.ports.prod.next, env: { GNOSIS_RPC: - process.env.NODE_ENV === 'production' + process.env.NODE_ENV === "production" ? process.env.FORK_URL : process.env.DEV_RPC, NEXT_PUBLIC_BACKEND_PORT: - process.env.NODE_ENV === 'production' + process.env.NODE_ENV === "production" ? appConfig.ports.prod.operate : appConfig.ports.dev.operate, }, @@ -378,7 +381,7 @@ async function launchNextApp() { server.listen(appConfig.ports.prod.next, (err) => { if (err) throw err; console.log( - `> Next server running on http://localhost:${appConfig.ports.prod.next}`, + `> Next server running on http://localhost:${appConfig.ports.prod.next}` ); }); } @@ -387,24 +390,24 @@ async function launchNextAppDev() { await new Promise(function (resolve, _reject) { process.env.NEXT_PUBLIC_BACKEND_PORT = appConfig.ports.dev.operate; // must set next env var to connect to backend nextAppProcess = spawn( - 'yarn', - ['dev:frontend', '--port', appConfig.ports.dev.next], + "yarn", + ["dev:frontend", "--port", appConfig.ports.dev.next], { env: { ...process.env, NEXT_PUBLIC_BACKEND_PORT: appConfig.ports.dev.operate, }, - }, + } ); nextAppProcessPid = nextAppProcess.pid; - nextAppProcess.stdout.on('data', (data) => { + nextAppProcess.stdout.on("data", (data) => { console.log(data.toString().trim()); resolve(); }); }); } -ipcMain.on('check', async function (event, _argument) { +ipcMain.on("check", async function (event, _argument) { // Update try { macUpdater.checkForUpdates().then((res) => { @@ -412,14 +415,14 @@ ipcMain.on('check', async function (event, _argument) { if (!res.downloadPromise) return; new Notification({ - title: 'Update Available', - body: 'Downloading update...', + title: "Update Available", + body: "Downloading update...", }).show(); res.downloadPromise.then(() => { new Notification({ - title: 'Update Downloaded', - body: 'Restarting application...', + title: "Update Downloaded", + body: "Restarting application...", }).show(); macUpdater.quitAndInstall(); }); @@ -430,11 +433,11 @@ ipcMain.on('check', async function (event, _argument) { // Setup try { - event.sender.send('response', 'Checking installation'); + event.sender.send("response", "Checking installation"); if (!isDev) { - if (platform === 'darwin') { + if (platform === "darwin") { await setupDarwin(event.sender); - } else if (platform === 'win32') { + } else if (platform === "win32") { // TODO } else { await setupUbuntu(event.sender); @@ -443,12 +446,12 @@ ipcMain.on('check', async function (event, _argument) { if (isDev) { event.sender.send( - 'response', - 'Starting Pearl Daemon In Development Mode', + "response", + "Starting Pearl Daemon In Development Mode" ); const daemonDevPortAvailable = await isPortAvailable( - appConfig.ports.dev.operate, + appConfig.ports.dev.operate ); if (!daemonDevPortAvailable) { @@ -458,12 +461,12 @@ ipcMain.on('check', async function (event, _argument) { } await launchDaemonDev(); event.sender.send( - 'response', - 'Starting Frontend Server In Development Mode', + "response", + "Starting Frontend Server In Development Mode" ); const frontendDevPortAvailable = await isPortAvailable( - appConfig.ports.dev.next, + appConfig.ports.dev.next ); if (!frontendDevPortAvailable) { @@ -474,12 +477,12 @@ ipcMain.on('check', async function (event, _argument) { } await launchNextAppDev(); } else { - event.sender.send('response', 'Starting Pearl Daemon'); + event.sender.send("response", "Starting Pearl Daemon"); await launchDaemon(); - event.sender.send('response', 'Starting Frontend Server'); + event.sender.send("response", "Starting Frontend Server"); const frontendPortAvailable = await isPortAvailable( - appConfig.ports.prod.next, + appConfig.ports.prod.next ); if (!frontendPortAvailable) { appConfig.ports.prod.next = await findAvailablePort({ @@ -490,54 +493,54 @@ ipcMain.on('check', async function (event, _argument) { await launchNextApp(); } - event.sender.send('response', 'Launching App'); + event.sender.send("response", "Launching App"); createMainWindow(); createTray(); splashWindow.destroy(); } catch (e) { console.log(e); new Notification({ - title: 'Error', + title: "Error", body: e, }).show(); - event.sender.send('response', e); + event.sender.send("response", e); // app.quit(); } }); // APP-SPECIFIC EVENTS -app.on('ready', async () => { - if (platform === 'darwin') { +app.on("ready", async () => { + if (platform === "darwin") { app.dock?.setIcon( - path.join(__dirname, 'assets/icons/splash-robot-head-dock.png'), + path.join(__dirname, "assets/icons/splash-robot-head-dock.png") ); } createSplashWindow(); }); -app.on('window-all-closed', () => { +app.on("window-all-closed", () => { app.quit(); }); -app.on('before-quit', async () => { +app.on("before-quit", async () => { await beforeQuit(); }); // UPDATER EVENTS -macUpdater.on('update-downloaded', () => { +macUpdater.on("update-downloaded", () => { macUpdater.quitAndInstall(); }); // PROCESS SPECIFIC EVENTS (HANDLES NON-GRACEFUL TERMINATION) -process.on('uncaughtException', (error) => { - console.error('Uncaught Exception:', error); +process.on("uncaughtException", (error) => { + console.error("Uncaught Exception:", error); // Clean up your child processes here beforeQuit().then(() => { process.exit(1); // Exit with a failure code }); }); -['SIGINT', 'SIGTERM'].forEach((signal) => { +["SIGINT", "SIGTERM"].forEach((signal) => { process.on(signal, () => { console.log(`Received ${signal}. Cleaning up...`); beforeQuit().then(() => { @@ -547,16 +550,16 @@ process.on('uncaughtException', (error) => { }); // OPEN PATH -ipcMain.on('open-path', (_, filePath) => { +ipcMain.on("open-path", (_, filePath) => { shell.openPath(filePath); }); function getSanitizedLogs({ name, filePath, data }) { - const logs = filePath ? fs.readFileSync(filePath, 'utf-8') : data; + const logs = filePath ? fs.readFileSync(filePath, "utf-8") : data; const tempDir = os.tmpdir(); const usernameRegex = /\/Users\/([^/]+)/g; - const sanitizedData = logs.replace(usernameRegex, '/Users/*****'); + const sanitizedData = logs.replace(usernameRegex, "/Users/*****"); const sanitizedLogsFilePath = path.join(tempDir, name); fs.writeFileSync(sanitizedLogsFilePath, sanitizedData); @@ -565,14 +568,14 @@ function getSanitizedLogs({ name, filePath, data }) { } // EXPORT LOGS -ipcMain.handle('save-logs', async (_, data) => { +ipcMain.handle("save-logs", async (_, data) => { // version.txt const versionFile = dirs.VersionFile; // logs.txt - const logFile = getSanitizedLogs({ name: 'log.txt', filePath: dirs.LogFile }); + const logFile = getSanitizedLogs({ name: "log.txt", filePath: dirs.LogFile }); // operate.log const installationLog = getSanitizedLogs({ - name: 'installation_log.txt', + name: "installation_log.txt", filePath: dirs.OperateInstallationLog, }); @@ -587,13 +590,13 @@ ipcMain.handle('save-logs', async (_, data) => { Total Memory: ${os.totalmem()} Free Memory: ${os.freemem()} `; - const osInfoFilePath = path.join(tempDir, 'os_info.txt'); + const osInfoFilePath = path.join(tempDir, "os_info.txt"); fs.writeFileSync(osInfoFilePath, osInfo); // Persistent store let storeFilePath; if (data.store) { - storeFilePath = path.join(tempDir, 'store.txt'); + storeFilePath = path.join(tempDir, "store.txt"); fs.writeFileSync(storeFilePath, JSON.stringify(data.store, null, 2)); } @@ -601,7 +604,7 @@ ipcMain.handle('save-logs', async (_, data) => { let debugDataFilePath; if (data.debugData) { debugDataFilePath = getSanitizedLogs({ - name: 'debug_data.txt', + name: "debug_data.txt", data: JSON.stringify(data.debugData, null, 2), }); } @@ -617,9 +620,9 @@ ipcMain.handle('save-logs', async (_, data) => { // Show save dialog const { filePath } = await dialog.showSaveDialog({ - title: 'Save Logs', - defaultPath: path.join(os.homedir(), 'pearl_logs.zip'), - filters: [{ name: 'Zip Files', extensions: ['zip'] }], + title: "Save Logs", + defaultPath: path.join(os.homedir(), "pearl_logs.zip"), + filters: [{ name: "Zip Files", extensions: ["zip"] }], }); let result; diff --git a/electron/update.js b/electron/update.js index d31153f2..cc72aee0 100644 --- a/electron/update.js +++ b/electron/update.js @@ -1,20 +1,41 @@ -const { publishOptions } = require('./constants/publishOptions'); -const electronUpdater = require('electron-updater'); -const electronLogger = require('electron-log'); +// const { publishOptions } = require('./constants/publishOptions'); +// const electronUpdater = require('electron-updater'); +// const electronLogger = require('electron-log'); -const macUpdater = new electronUpdater.MacUpdater({ - ...publishOptions, - private: false, -}); +// const macUpdater = new electronUpdater.MacUpdater({ +// ...publishOptions, +// }); -macUpdater.logger = electronLogger; +// macUpdater.logger = electronLogger; + +// macUpdater.setFeedURL({ +// ...publishOptions, +// }); + +// macUpdater.autoDownload = true; +// macUpdater.autoInstallOnAppQuit = true; +// macUpdater.logger = electronLogger; -macUpdater.setFeedURL({ - ...publishOptions, -}); +const { publishOptions } = require("../constants/publishOptions"); +const electronUpdater = require("electron-updater"); +const electronLogger = require("electron-log"); -macUpdater.autoDownload = true; -macUpdater.autoInstallOnAppQuit = true; macUpdater.logger = electronLogger; +export const setupMacUpdater = (app) => { + /** @type import type { MacUpdater } from "electron-updater" */ + const macUpdater = new electronUpdater.MacUpdater( + { + ...publishOptions, + }, + app + ); + + macUpdater.logger = electronLogger; + + return { + macUpdater, + }; +}; + module.exports = { macUpdater }; diff --git a/package.json b/package.json index d866e908..3cd9e83a 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "dotenv": "^16.4.5", "electron-log": "^5.1.4", "electron-store": "^9.0.0", - "electron-updater": "^6.1.8", + "electron-updater": "^6.3.0-alpha.4", "ethers": "5.7.2", "ethers-multicall": "^0.2.3", "lodash": "^4.17.21", @@ -34,6 +34,7 @@ "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-unused-imports": "^4.0.0", "hardhat": "==2.17.1", "net": "^1.0.2", "prettier": "^3.2.5" diff --git a/yarn.lock b/yarn.lock index 9d982560..9dc0da62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1753,14 +1753,6 @@ buildcheck@~0.0.6: resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.6.tgz#89aa6e417cfd1e2196e3f8fe915eb709d2fe4238" integrity sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A== -builder-util-runtime@9.2.3: - version "9.2.3" - resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.3.tgz#0a82c7aca8eadef46d67b353c638f052c206b83c" - integrity sha512-FGhkqXdFFZ5dNC4C+yuQB9ak311rpGAw+/ASz8ZdxwODCv1GGMWgLDeofRkdi0F3VCHQEWy/aXcJQozx2nOPiw== - dependencies: - debug "^4.3.4" - sax "^1.2.4" - builder-util-runtime@9.2.4: version "9.2.4" resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz#13cd1763da621e53458739a1e63f7fcba673c42a" @@ -1769,6 +1761,14 @@ builder-util-runtime@9.2.4: debug "^4.3.4" sax "^1.2.4" +builder-util-runtime@9.2.5-alpha.2: + version "9.2.5-alpha.2" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.5-alpha.2.tgz#b0a1737996717d7ae0b71e5efdf0bfbd1dd2c21e" + integrity sha512-/Ln2ddejGj2HNMJ+X66mKHRcOvmRzUO/dSi8t4hSV64J7IA+DE+mqDb+zogIE2gin7p7YwcGiOkKny4nwPPPXg== + dependencies: + debug "^4.3.4" + sax "^1.2.4" + builder-util@24.13.1: version "24.13.1" resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-24.13.1.tgz#4a4c4f9466b016b85c6990a0ea15aa14edec6816" @@ -2426,12 +2426,12 @@ electron-store@^9.0.0: conf "^12.0.0" type-fest "^4.18.1" -electron-updater@^6.1.8: - version "6.1.8" - resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.1.8.tgz#17637bca165322f4e526b13c99165f43e6f697d8" - integrity sha512-hhOTfaFAd6wRHAfUaBhnAOYc+ymSGCWJLtFkw4xJqOvtpHmIdNHnXDV9m1MHC+A6q08Abx4Ykgyz/R5DGKNAMQ== +electron-updater@^6.3.0-alpha.4: + version "6.3.0-alpha.4" + resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.3.0-alpha.4.tgz#7c5a9594bc00a6ee6c6fc9f092444a1d7d2e8ede" + integrity sha512-01Pmb4K23cIos6zuvX3e0MF3KxScHFaHivCs+6LUcnUZTuGuRfwGrQU7ov2iChbV0U5o+hnVecrO/HI6UoRT1Q== dependencies: - builder-util-runtime "9.2.3" + builder-util-runtime "9.2.5-alpha.2" fs-extra "^10.1.0" js-yaml "^4.1.0" lazy-val "^1.0.5" @@ -2560,6 +2560,18 @@ eslint-plugin-prettier@^5.1.3: prettier-linter-helpers "^1.0.0" synckit "^0.8.6" +eslint-plugin-unused-imports@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.0.0.tgz#93f3a7ee6088221e4a1d7127866e05d5917a9f65" + integrity sha512-mzM+y2B7XYpQryVa1usT+Y/BdNAtAZiXzwpSyDCboFoJN/LZRN67TNvQxKtuTK/Aplya3sLNQforiubzPPaIcQ== + dependencies: + eslint-rule-composer "^0.3.0" + +eslint-rule-composer@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" + integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== + eslint-scope@^7.2.2: version "7.2.2" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" @@ -5032,7 +5044,16 @@ string-convert@^0.2.0: resolved "https://registry.yarnpkg.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97" integrity sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5057,7 +5078,14 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -5429,7 +5457,16 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==