From 63754de65947ab52e9e1e08336b253788a2a91aa Mon Sep 17 00:00:00 2001 From: Jack Kavanagh Date: Thu, 15 Jun 2023 14:18:37 +0200 Subject: [PATCH] electron app auto update performs a backup after download (#6005) * nix * export all on update download complete * fix missing websockets inclusions * tidy up export function --- packages/insomnia/src/common/export.tsx | 2 +- packages/insomnia/src/main/export.ts | 26 +++++++++++++++++++++++++ packages/insomnia/src/main/ipc/main.ts | 5 +++++ packages/insomnia/src/main/updates.ts | 5 ++++- packages/insomnia/src/models/stats.ts | 5 +++-- packages/insomnia/src/preload.ts | 1 + shell.nix | 3 ++- 7 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 packages/insomnia/src/main/export.ts diff --git a/packages/insomnia/src/common/export.tsx b/packages/insomnia/src/common/export.tsx index 70dc63df2..dcad8ae09 100644 --- a/packages/insomnia/src/common/export.tsx +++ b/packages/insomnia/src/common/export.tsx @@ -139,7 +139,7 @@ export async function exportWorkspacesData( ) { const promises = workspaces.map(getDocWithDescendants(includePrivateDocs)); const docs = (await Promise.all(promises)).flat(); - const requests = docs.filter(doc => isRequest(doc) || isGrpcRequest(doc)); + const requests = docs.filter(doc => isRequest(doc) || isGrpcRequest(doc) || isWebSocketRequest(doc)); return exportRequestsData(requests, includePrivateDocs, format); } diff --git a/packages/insomnia/src/main/export.ts b/packages/insomnia/src/main/export.ts new file mode 100644 index 000000000..76dff5bfa --- /dev/null +++ b/packages/insomnia/src/main/export.ts @@ -0,0 +1,26 @@ +import electron from 'electron'; +import fs, { mkdir } from 'node:fs/promises'; +import path from 'node:path'; + +import { version } from '../../package.json'; +import { database as db } from '../common/database'; +import { exportRequestsData } from '../common/export'; +import * as models from '../models'; +import { isGrpcRequest } from '../models/grpc-request'; +import { isRequest } from '../models/request'; +import { isWebSocketRequest } from '../models/websocket-request'; +export async function exportAllWorkspaces() { + const projects = await models.project.all(); + await Promise.all(projects.map(async project => { + const dataPath = process.env['INSOMNIA_DATA_PATH'] || electron.app.getPath('userData'); + const versionPath = path.join(dataPath, 'backups', version); + await mkdir(versionPath, { recursive: true }); + const fileName = path.join(versionPath, `${project.name}.insomnia.json`); + const workspaces = await models.workspace.findByParentId(project._id); + const docs = await Promise.all(workspaces.map(parentDoc => db.withDescendants(parentDoc))); + const requests = docs.flat().filter(doc => isRequest(doc) || isGrpcRequest(doc) || isWebSocketRequest(doc)); + const stringifiedExport = await exportRequestsData(requests, true, 'json'); + await fs.writeFile(fileName, stringifiedExport); + console.log('Exported project backup to:', fileName); + })); +} diff --git a/packages/insomnia/src/main/ipc/main.ts b/packages/insomnia/src/main/ipc/main.ts index 22ad58e34..70d66ab71 100644 --- a/packages/insomnia/src/main/ipc/main.ts +++ b/packages/insomnia/src/main/ipc/main.ts @@ -9,6 +9,7 @@ import fs from 'fs'; import { axiosRequest } from '../../network/axios-request'; import { authorizeUserInWindow } from '../../network/o-auth-2/misc'; +import { exportAllWorkspaces } from '../export'; import installPlugin from '../install-plugin'; import { cancelCurlRequest, curlRequest } from '../network/libcurl-promise'; import { WebSocketBridgeAPI } from '../network/websocket'; @@ -16,6 +17,7 @@ import { gRPCBridgeAPI } from './grpc'; export interface MainBridgeAPI { restart: () => void; + exportAllWorkspaces: () => Promise; spectralRun: (options: { contents: string; rulesetPath: string }) => Promise; authorizeUserInWindow: typeof authorizeUserInWindow; setMenuBarVisibility: (visible: boolean) => void; @@ -28,6 +30,9 @@ export interface MainBridgeAPI { grpc: gRPCBridgeAPI; } export function registerMainHandlers() { + ipcMain.handle('exportAllWorkspaces', async () => { + return exportAllWorkspaces(); + }); ipcMain.handle('authorizeUserInWindow', (_, options: Parameters[0]) => { const { url, urlSuccessRegex, urlFailureRegex, sessionId } = options; return authorizeUserInWindow({ url, urlSuccessRegex, urlFailureRegex, sessionId }); diff --git a/packages/insomnia/src/main/updates.ts b/packages/insomnia/src/main/updates.ts index d2df74e90..b07d92097 100644 --- a/packages/insomnia/src/main/updates.ts +++ b/packages/insomnia/src/main/updates.ts @@ -11,6 +11,7 @@ import { import { delay } from '../common/misc'; import * as models from '../models/index'; import { buildQueryStringFromParams, joinUrlAndQueryString } from '../utils/url/querystring'; +import { exportAllWorkspaces } from './export'; const { autoUpdater, BrowserWindow, ipcMain } = electron; async function getUpdateUrl(force: boolean): Promise { @@ -97,9 +98,11 @@ export async function init() { _sendUpdateStatus('Downloading...'); }); - autoUpdater.on('update-downloaded', (_error, _releaseNotes, releaseName) => { + autoUpdater.on('update-downloaded', async (_error, _releaseNotes, releaseName) => { console.log(`[updater] Downloaded ${releaseName}`); + await exportAllWorkspaces(); + _sendUpdateComplete(true, 'Updated (Restart Required)'); _showUpdateNotification(); diff --git a/packages/insomnia/src/models/stats.ts b/packages/insomnia/src/models/stats.ts index e4eec213d..5c58eb372 100644 --- a/packages/insomnia/src/models/stats.ts +++ b/packages/insomnia/src/models/stats.ts @@ -4,6 +4,7 @@ import type { BaseModel } from './index'; import { Project } from './project'; import { isRequest } from './request'; import type { RequestGroup } from './request-group'; +import { isWebSocketRequest } from './websocket-request'; import type { Workspace } from './workspace'; export const name = 'Stats'; @@ -112,7 +113,7 @@ export async function incrementExecutedRequests() { export async function incrementCreatedRequestsForDescendents(doc: Workspace | RequestGroup) { const docs = await db.withDescendants(doc); - const requests = docs.filter(doc => isRequest(doc) || isGrpcRequest(doc)); + const requests = docs.filter(doc => isRequest(doc) || isGrpcRequest(doc) || isWebSocketRequest(doc)); await incrementRequestStats({ createdRequests: requests.length, }); @@ -120,7 +121,7 @@ export async function incrementCreatedRequestsForDescendents(doc: Workspace | Re export async function incrementDeletedRequestsForDescendents(doc: Workspace | RequestGroup | Project) { const docs = await db.withDescendants(doc); - const requests = docs.filter(doc => isRequest(doc) || isGrpcRequest(doc)); + const requests = docs.filter(doc => isRequest(doc) || isGrpcRequest(doc) || isWebSocketRequest(doc)); await incrementRequestStats({ deletedRequests: requests.length, }); diff --git a/packages/insomnia/src/preload.ts b/packages/insomnia/src/preload.ts index 30d105b74..fdf53dbbd 100644 --- a/packages/insomnia/src/preload.ts +++ b/packages/insomnia/src/preload.ts @@ -26,6 +26,7 @@ const grpc: gRPCBridgeAPI = { }; const main: Window['main'] = { restart: () => ipcRenderer.send('restart'), + exportAllWorkspaces: () => ipcRenderer.invoke('exportAllWorkspaces'), authorizeUserInWindow: options => ipcRenderer.invoke('authorizeUserInWindow', options), spectralRun: options => ipcRenderer.invoke('spectralRun', options), setMenuBarVisibility: options => ipcRenderer.send('setMenuBarVisibility', options), diff --git a/shell.nix b/shell.nix index 944db6e21..a9dc58a00 100644 --- a/shell.nix +++ b/shell.nix @@ -4,7 +4,8 @@ mkShell { nativeBuildInputs = [ nodejs-16_x electron_22 + stdenv.cc.cc.lib ]; - + LD_LIBRARY_PATH = "${stdenv.cc.cc.lib}/lib64:$LD_LIBRARY_PATH"; ELECTRON_OVERRIDE_DIST_PATH = "${electron_22}/bin/"; }