diff --git a/documentation/INSTALLATION.md b/documentation/INSTALLATION.md index 3cd0d2cc..c33a48b3 100644 --- a/documentation/INSTALLATION.md +++ b/documentation/INSTALLATION.md @@ -31,6 +31,8 @@ The following video shows the steps in action: [![How to install PersonalAnalytics on macOS](https://markdown-videos-api.jorgenkh.no/youtube/ovfRzp3Ksgk)](https://youtu.be/ovfRzp3Ksgk) +> If you want to completely remove or reinstall PersonalAnalytics on macOS, please visit the [Troubleshooting](TROUBLESHOOTING.md#macos-reinstalling-personalanalytics-from-scratch) page. + ## Using PersonalAnalytics For the majority of the time, PersonalAnalytics is running nonintrusively in the background. @@ -52,5 +54,6 @@ The researchers might ask you to share the collected data with them for data ana image + ### Questions In case of questions, contact the researchers who asked you to install PersonalAnalytics. You find their email in the study description or by clicking "Get Help" in the context menu. diff --git a/documentation/TROUBLESHOOTING.md b/documentation/TROUBLESHOOTING.md new file mode 100644 index 00000000..a7f48e38 --- /dev/null +++ b/documentation/TROUBLESHOOTING.md @@ -0,0 +1,41 @@ +# Troubleshooting PersonalAnalytics + +### macOS: Reinstalling PersonalAnalytics from Scratch +> If you are experiencing issues with PersonalAnalytics on macOS and want to reinstall the app, please follow the steps below: + +1. Quit PA and check that it is not running with: +``` +ps aux | grep -i personal +``` + +2. Remove permissions for PA in System Settings: +``` +open "x-apple.systempreferences:com.apple.preference.security” +``` + +Check for entries in “Accessibility” and “Screen & System Audio Recording”, and delete these entries using the “-“ symbol at the bottom of the list. + +> Note: Checking for these permissions needs to be done *BEFORE* deleting the PA app, as permissions for deleted apps are kept, but not shown in this list if the app is deleted. + +3. Delete PA and its settings + +- Copy the database if you want to keep it +``` +open ~/Library/Application\ Support/personal-analytics +``` +- Delete PA +``` +rm -rf /Applications/PersonalAnalytics.app +``` +- Delete Settings +``` +rm -rf ~/Library/Application\ Support/personal-analytics +``` + +4. Make sure PA and settings are deleted +``` +ls -lah /Applications | grep -i personal +ls -lah ~/Library/Application\ Support | grep -i personal +``` + +5. Done - you can freshly install PersonalAnalytics now! diff --git a/src/electron/electron/config/Logger.ts b/src/electron/electron/config/Logger.ts new file mode 100644 index 00000000..175c0419 --- /dev/null +++ b/src/electron/electron/config/Logger.ts @@ -0,0 +1,13 @@ +import logger from 'electron-log/main'; +import { LogFunctions } from 'electron-log'; +import { LOG_FILE_NAME, LOG_LEVEL } from './logger.config'; + +export const getMainLogger = (loggerName: string): LogFunctions => { + logger.transports.file.fileName = `${LOG_FILE_NAME.BACKGROUND}.log`; + logger.transports.file.maxSize = 15 * 1024 * 1024; + logger.transports.file.level = LOG_LEVEL.FILE; + logger.transports.console.level = LOG_LEVEL.CONSOLE; + return logger.scope(loggerName); +}; + +export default getMainLogger; diff --git a/src/electron/electron/ipc/IpcHandler.ts b/src/electron/electron/ipc/IpcHandler.ts index 549d5b6b..6d32f219 100644 --- a/src/electron/electron/ipc/IpcHandler.ts +++ b/src/electron/electron/ipc/IpcHandler.ts @@ -1,7 +1,7 @@ import { ExperienceSamplingService } from '../main/services/ExperienceSamplingService'; import { app, ipcMain, IpcMainInvokeEvent, shell, systemPreferences } from 'electron'; import { WindowService } from '../main/services/WindowService'; -import { getLogger } from '../shared/Logger'; +import { getMainLogger } from '../config/Logger'; import { TypedIpcMain } from '../../src/utils/TypedIpcMain'; import Commands from '../../src/utils/Commands'; import Events from '../../src/utils/Events'; @@ -18,7 +18,7 @@ import WindowActivityDto from '../../shared/dto/WindowActivityDto'; import ExperienceSamplingDto from '../../shared/dto/ExperienceSamplingDto'; import { is } from '../main/services/utils/helpers'; -const LOG = getLogger('IpcHandler'); +const LOG = getMainLogger('IpcHandler'); export class IpcHandler { private readonly actions: any; diff --git a/src/electron/electron/main/index.ts b/src/electron/electron/main/index.ts index f09c0645..9cc189ae 100644 --- a/src/electron/electron/main/index.ts +++ b/src/electron/electron/main/index.ts @@ -4,7 +4,7 @@ import { release } from 'node:os'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import log from 'electron-log/main'; -import { getLogger } from '../shared/Logger'; +import { getMainLogger } from '../config/Logger'; import { DatabaseService } from './services/DatabaseService'; import { SettingsService } from './services/SettingsService'; import { TrackerType } from '../enums/TrackerType.enum'; @@ -59,7 +59,7 @@ if (is.macOS) { // Optional, initialize the logger for any renderer process log.initialize(); -const LOG = getLogger('Main'); +const LOG = getMainLogger('Main'); app.whenReady().then(async () => { app.setAppUserModelId('ch.ifi.hasel.personal-analytics'); diff --git a/src/electron/electron/main/services/AppUpdaterService.ts b/src/electron/electron/main/services/AppUpdaterService.ts index f9f28118..f3537208 100644 --- a/src/electron/electron/main/services/AppUpdaterService.ts +++ b/src/electron/electron/main/services/AppUpdaterService.ts @@ -1,4 +1,4 @@ -import { getLogger } from '../../shared/Logger'; +import getMainLogger from '../../config/Logger'; import { dialog, net } from 'electron'; import { EventEmitter } from 'events'; import updater from 'electron-updater'; @@ -6,7 +6,7 @@ import studyConfig from '../../../shared/study.config'; const { autoUpdater } = updater; -const LOG = getLogger('AutoUpdater'); +const LOG = getMainLogger('AutoUpdater'); export default class AppUpdaterService extends EventEmitter { private checkForUpdatesInterval: NodeJS.Timeout | undefined; diff --git a/src/electron/electron/main/services/DataExportService.ts b/src/electron/electron/main/services/DataExportService.ts index 9fb3140a..9f84dcd3 100644 --- a/src/electron/electron/main/services/DataExportService.ts +++ b/src/electron/electron/main/services/DataExportService.ts @@ -1,5 +1,5 @@ import { DataExportType } from '../../../shared/DataExportType.enum'; -import { getLogger } from '../../shared/Logger'; +import getMainLogger from '../../config/Logger'; import path from 'path'; import { app } from 'electron'; import { is } from './utils/helpers'; @@ -11,7 +11,7 @@ import { Settings } from '../entities/Settings'; import { UsageDataService } from './UsageDataService'; import { UsageDataEventType } from '../../enums/UsageDataEventType.enum'; -const LOG = getLogger('DataExportService'); +const LOG = getMainLogger('DataExportService'); export class DataExportService { private readonly windowActivityTrackerService: WindowActivityTrackerService = diff --git a/src/electron/electron/main/services/DatabaseService.ts b/src/electron/electron/main/services/DatabaseService.ts index ab93cd67..19811699 100644 --- a/src/electron/electron/main/services/DatabaseService.ts +++ b/src/electron/electron/main/services/DatabaseService.ts @@ -2,14 +2,14 @@ import { DataSource, DataSourceOptions } from 'typeorm'; import { app } from 'electron'; import path from 'path'; import { is } from './utils/helpers'; -import { getLogger } from '../../shared/Logger'; +import getMainLogger from '../../config/Logger'; import { WindowActivityEntity } from '../entities/WindowActivityEntity'; import { ExperienceSamplingResponseEntity } from '../entities/ExperienceSamplingResponseEntity'; import { UserInputEntity } from '../entities/UserInputEntity'; import { Settings } from '../entities/Settings'; import { UsageDataEntity } from '../entities/UsageDataEntity'; -const LOG = getLogger('DatabaseService'); +const LOG = getMainLogger('DatabaseService'); export class DatabaseService { public dataSource: DataSource; diff --git a/src/electron/electron/main/services/ExperienceSamplingService.ts b/src/electron/electron/main/services/ExperienceSamplingService.ts index e2e4b8f8..1d97b06d 100644 --- a/src/electron/electron/main/services/ExperienceSamplingService.ts +++ b/src/electron/electron/main/services/ExperienceSamplingService.ts @@ -1,8 +1,8 @@ import { ExperienceSamplingResponseEntity } from '../entities/ExperienceSamplingResponseEntity'; -import { getLogger } from '../../shared/Logger'; +import getMainLogger from '../../config/Logger'; import ExperienceSamplingDto from '../../../shared/dto/ExperienceSamplingDto'; -const LOG = getLogger('ExperienceSamplingService'); +const LOG = getMainLogger('ExperienceSamplingService'); export class ExperienceSamplingService { public async createExperienceSample( diff --git a/src/electron/electron/main/services/SettingsService.ts b/src/electron/electron/main/services/SettingsService.ts index 699b47a2..d42cd265 100644 --- a/src/electron/electron/main/services/SettingsService.ts +++ b/src/electron/electron/main/services/SettingsService.ts @@ -1,9 +1,9 @@ import { Settings } from '../entities/Settings'; import { generateAlphaNumericString } from './utils/helpers'; import studyConfig from '../../../shared/study.config'; -import { getLogger } from '../../shared/Logger'; +import getMainLogger from '../../config/Logger'; -const LOG = getLogger('SettingsService'); +const LOG = getMainLogger('SettingsService'); export class SettingsService { public async init(): Promise { diff --git a/src/electron/electron/main/services/UsageDataService.ts b/src/electron/electron/main/services/UsageDataService.ts index df96040f..0552fccd 100644 --- a/src/electron/electron/main/services/UsageDataService.ts +++ b/src/electron/electron/main/services/UsageDataService.ts @@ -1,8 +1,8 @@ -import { getLogger } from '../../shared/Logger'; +import getMainLogger from '../../config/Logger'; import { UsageDataEventType } from '../../enums/UsageDataEventType.enum'; import { UsageDataEntity } from '../entities/UsageDataEntity'; -const LOG = getLogger('UsageDataService'); +const LOG = getMainLogger('UsageDataService'); export class UsageDataService { public static async createNewUsageDataEvent( diff --git a/src/electron/electron/main/services/WindowService.ts b/src/electron/electron/main/services/WindowService.ts index dbeb2d85..07e3edd4 100644 --- a/src/electron/electron/main/services/WindowService.ts +++ b/src/electron/electron/main/services/WindowService.ts @@ -1,5 +1,5 @@ import { app, BrowserWindow, Menu, nativeImage, screen, shell, Tray } from 'electron'; -import { getLogger } from '../../shared/Logger'; +import getMainLogger from '../../config/Logger'; import AppUpdaterService from './AppUpdaterService'; import { is } from './utils/helpers'; import path from 'path'; @@ -7,11 +7,12 @@ import MenuItemConstructorOptions = Electron.MenuItemConstructorOptions; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import studyConfig from '../../../shared/study.config'; + import { Settings } from '../entities/Settings'; import { UsageDataService } from './UsageDataService'; import { UsageDataEventType } from '../../enums/UsageDataEventType.enum'; -const LOG = getLogger('WindowService'); +const LOG = getMainLogger('WindowService'); export class WindowService { private readonly appUpdaterService: AppUpdaterService; diff --git a/src/electron/electron/main/services/trackers/ExperienceSamplingTracker.ts b/src/electron/electron/main/services/trackers/ExperienceSamplingTracker.ts index d1b25ba8..3ea79a59 100644 --- a/src/electron/electron/main/services/trackers/ExperienceSamplingTracker.ts +++ b/src/electron/electron/main/services/trackers/ExperienceSamplingTracker.ts @@ -1,10 +1,11 @@ import * as schedule from 'node-schedule'; import { WindowService } from '../WindowService'; import { Tracker } from './Tracker'; -import { getLogger } from '../../../shared/Logger'; +import getMainLogger from '../../../config/Logger'; import { Settings } from '../../entities/Settings'; +import { powerMonitor } from 'electron'; -const LOG = getLogger('ExperienceSamplingTracker'); +const LOG = getMainLogger('ExperienceSamplingTracker'); export class ExperienceSamplingTracker implements Tracker { private checkIfExperienceSamplingIsDueJob: schedule.Job; @@ -41,15 +42,7 @@ export class ExperienceSamplingTracker implements Tracker { LOG.info( 'Next invocation is in the past, scheduling job to fire in 30 minutes + randomization' ); - const subtractOrAdd: 1 | -1 = Math.random() < 0.5 ? -1 : 1; - const randomization = - this.intervalInMs * this.samplingRandomization * Math.random() * subtractOrAdd; - const nextInvocation = new Date(Date.now() + 30 * 60 * 1000 + randomization); - - this.forcedExperienceSamplingJob = schedule.scheduleJob(nextInvocation, async () => { - await this.handleExperienceSamplingJob(nextInvocation); - }); - LOG.info(`Resume, scheduled to fire at ${nextInvocation}`); + await this.scheduleNextForcedExperienceSamplingJob(); } else { await this.startExperienceSamplingJob(); } @@ -83,6 +76,39 @@ export class ExperienceSamplingTracker implements Tracker { await settings.save(); } + private async scheduleNextForcedExperienceSamplingJob(): Promise { + const subtractOrAdd: 1 | -1 = Math.random() < 0.5 ? -1 : 1; + const scheduleAfterResumeInMs = 30 * 60 * 1000; + const randomization = + scheduleAfterResumeInMs * this.samplingRandomization * Math.random() * subtractOrAdd; + const nextInvocation = new Date(Date.now() + scheduleAfterResumeInMs + randomization); + + this.forcedExperienceSamplingJob = schedule.scheduleJob(nextInvocation, async () => { + const systemIdleState: 'active' | 'idle' | 'locked' | 'unknown' = + powerMonitor.getSystemIdleState(10 * 60); + LOG.debug( + `scheduleNextForcedExperienceSamplingJob(): System idle state: ${systemIdleState}, assuming idle after 10 minutes of inactivity` + ); + + const systemIdleTimeInSeconds: number = powerMonitor.getSystemIdleTime(); + LOG.debug( + `scheduleNextForcedExperienceSamplingJob(): System idle time: ${systemIdleTimeInSeconds}` + ); + if (systemIdleState !== 'active') { + LOG.info( + `scheduleNextForcedExperienceSamplingJob(): System idle time is greater than 30 minutes, not starting experience sampling job` + ); + await this.scheduleNextForcedExperienceSamplingJob(); + return; + } + await this.handleExperienceSamplingJob(nextInvocation); + }); + LOG.info(`scheduleNextForcedExperienceSamplingJob(): scheduled to fire at ${nextInvocation}`); + + await this.scheduleNextJob(); + await this.startExperienceSamplingJob(); + } + private getRandomNextInvocationDate(): Date { const subtractOrAdd: 1 | -1 = Math.random() < 0.5 ? -1 : 1; const randomization = diff --git a/src/electron/electron/main/services/trackers/TrackerService.ts b/src/electron/electron/main/services/trackers/TrackerService.ts index 6808f8cd..08487a72 100644 --- a/src/electron/electron/main/services/trackers/TrackerService.ts +++ b/src/electron/electron/main/services/trackers/TrackerService.ts @@ -2,14 +2,14 @@ import * as schedule from 'node-schedule'; import { Tracker } from './Tracker'; import { TrackerConfig } from '../../../types/StudyConfig'; import { TrackerType } from '../../../enums/TrackerType.enum'; -import { getLogger } from '../../../shared/Logger'; +import getMainLogger from '../../../config/Logger'; import { ExperienceSamplingTracker } from './ExperienceSamplingTracker'; import { WindowService } from '../WindowService'; import studyConfig from '../../../../shared/study.config'; import { UserInputEntity } from '../../entities/UserInputEntity'; import { MoreThanOrEqual } from 'typeorm'; -const LOG = getLogger('TrackerService'); +const LOG = getMainLogger('TrackerService'); export class TrackerService { private trackers: Tracker[] = []; diff --git a/src/electron/electron/main/services/trackers/WindowActivityTrackerService.ts b/src/electron/electron/main/services/trackers/WindowActivityTrackerService.ts index 252fd6e0..595f9d84 100644 --- a/src/electron/electron/main/services/trackers/WindowActivityTrackerService.ts +++ b/src/electron/electron/main/services/trackers/WindowActivityTrackerService.ts @@ -1,10 +1,10 @@ import ActiveWindow from 'windows-activity-tracker/dist/types/ActiveWindow'; import { WindowActivityEntity } from '../../entities/WindowActivityEntity'; import { In } from 'typeorm'; -import { getLogger } from '../../../shared/Logger'; +import getMainLogger from '../../../config/Logger'; import WindowActivityDto from '../../../../shared/dto/WindowActivityDto'; -const LOG = getLogger('WindowActivityTrackerService'); +const LOG = getMainLogger('WindowActivityTrackerService'); export class WindowActivityTrackerService { private randomStringMap: Map = new Map(); diff --git a/src/electron/electron/shared/Logger.ts b/src/electron/electron/shared/Logger.ts deleted file mode 100644 index 61cc329c..00000000 --- a/src/electron/electron/shared/Logger.ts +++ /dev/null @@ -1,17 +0,0 @@ -import logger from 'electron-log/main'; -import { LogFunctions } from 'electron-log'; -import { LOG_FILE_NAME, LOG_LEVEL } from '../config/logger.config'; - -const getLogger = (loggerName: string, background = true): LogFunctions => { - const currentDate: string = new Date().toISOString().split('T')[0]; - const processName: string = background ? LOG_FILE_NAME.BACKGROUND : LOG_FILE_NAME.RENDERER; - logger.transports.file.fileName = `${currentDate}-${processName}.log`; - logger.transports.file.level = LOG_LEVEL.FILE; - logger.transports.console.level = LOG_LEVEL.CONSOLE; - return logger.scope(loggerName); -}; - -const logFile: string = logger.transports.file.getFile().path; -const LOG_PATH: string = logFile.substring(0, logFile.lastIndexOf('/')); - -export { getLogger, LOG_PATH }; diff --git a/src/electron/package-lock.json b/src/electron/package-lock.json index aabd4b6f..920d6971 100644 --- a/src/electron/package-lock.json +++ b/src/electron/package-lock.json @@ -1,12 +1,12 @@ { "name": "personal-analytics", - "version": "0.0.18", + "version": "0.0.20", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "personal-analytics", - "version": "0.0.18", + "version": "0.0.20", "hasInstallScript": true, "dependencies": { "better-sqlite3": "^9.4.0", @@ -33,7 +33,7 @@ "autoprefixer": "^10.4.17", "daisyui": "^4.6.1", "electron": "^28.2.2", - "electron-builder": "^24.9.1", + "electron-builder": "^24.13.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", @@ -774,9 +774,9 @@ } }, "node_modules/@electron/asar": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.8.tgz", - "integrity": "sha512-cmskk5M06ewHMZAplSiF4AlME3IrnnZhKnWbtwKVLRkdJkKyUVjMLhDIiPIx/+6zQWVlKX/LtmK9xDme7540Sg==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.9.tgz", + "integrity": "sha512-Vu2P3X2gcZ3MY9W7yH72X9+AMXwUQZEJBrsPIbX0JsdllLtoh62/Q8Wg370/DawIEVKOyfD6KtTLo645ezqxUA==", "dev": true, "dependencies": { "commander": "^5.0.0", @@ -961,9 +961,9 @@ } }, "node_modules/@electron/universal": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.4.1.tgz", - "integrity": "sha512-lE/U3UNw1YHuowNbTmKNs9UlS3En3cPgwM5MI+agIgr/B1hSze9NdOP0qn7boZaI9Lph8IDv3/24g9IxnJP7aQ==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.5.1.tgz", + "integrity": "sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw==", "dev": true, "dependencies": { "@electron/asar": "^3.2.1", @@ -3032,9 +3032,9 @@ "dev": true }, "node_modules/@types/verror": { - "version": "1.10.9", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.9.tgz", - "integrity": "sha512-MLx9Z+9lGzwEuW16ubGeNkpBDE84RpB/NyGgg6z2BTpWzKkGU451cAY3UkUzZEp72RHF585oJ3V8JVNqIplcAQ==", + "version": "1.10.10", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.10.tgz", + "integrity": "sha512-l4MM0Jppn18hb9xmM6wwD1uTdShpf9Pn80aXTStnK1C94gtPvJcV2FrDmbOQUAQfJ1cKZHktkQUDwEqaAKXMMg==", "dev": true, "optional": true }, @@ -3699,26 +3699,25 @@ "dev": true }, "node_modules/app-builder-lib": { - "version": "24.9.1", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.9.1.tgz", - "integrity": "sha512-Q1nYxZcio4r+W72cnIRVYofEAyjBd3mG47o+zms8HlD51zWtA/YxJb01Jei5F+jkWhge/PTQK+uldsPh6d0/4g==", + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.13.3.tgz", + "integrity": "sha512-FAzX6IBit2POXYGnTCT8YHFO/lr5AapAII6zzhQO3Rw4cEDOgK+t1xhLc5tNcKlicTHlo9zxIwnYCX9X2DLkig==", "dev": true, "dependencies": { "@develar/schema-utils": "~2.6.5", - "@electron/notarize": "2.1.0", + "@electron/notarize": "2.2.1", "@electron/osx-sign": "1.0.5", - "@electron/universal": "1.4.1", + "@electron/universal": "1.5.1", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", - "7zip-bin": "~5.2.0", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "24.8.1", - "builder-util-runtime": "9.2.3", + "builder-util": "24.13.1", + "builder-util-runtime": "9.2.4", "chromium-pickle-js": "^0.2.0", "debug": "^4.3.4", "ejs": "^3.1.8", - "electron-publish": "24.8.1", + "electron-publish": "24.13.1", "form-data": "^4.0.0", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", @@ -3735,12 +3734,16 @@ }, "engines": { "node": ">=14.0.0" + }, + "peerDependencies": { + "dmg-builder": "24.13.3", + "electron-builder-squirrel-windows": "24.13.3" } }, "node_modules/app-builder-lib/node_modules/@electron/notarize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.1.0.tgz", - "integrity": "sha512-Q02xem1D0sg4v437xHgmBLxI2iz/fc0D4K7fiVWHa/AnW8o7D751xyKNXgziA6HrTOme9ul1JfWN5ark8WH1xA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.2.1.tgz", + "integrity": "sha512-aL+bFMIkpR0cmmj5Zgy0LMKEpgy43/hw5zadEArgmAMWWlKc5buwFvFT9G/o/YJkvXAJm5q3iuTuLaiaXW39sg==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -3766,6 +3769,19 @@ "node": ">=10" } }, + "node_modules/app-builder-lib/node_modules/builder-util-runtime": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", + "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/app-builder-lib/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -3827,6 +3843,80 @@ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "optional": true }, + "node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "dev": true, + "peer": true, + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "peer": true + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/are-we-there-yet": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", @@ -4268,16 +4358,16 @@ "dev": true }, "node_modules/builder-util": { - "version": "24.8.1", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.8.1.tgz", - "integrity": "sha512-ibmQ4BnnqCnJTNrdmdNlnhF48kfqhNzSeqFMXHLIl+o9/yhn6QfOaVrloZ9YUu3m0k3rexvlT5wcki6LWpjTZw==", + "version": "24.13.1", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.13.1.tgz", + "integrity": "sha512-NhbCSIntruNDTOVI9fdXz0dihaqX2YuE1D6zZMrwiErzH4ELZHE6mdiB40wEgZNprDia+FghRFgKoAqMZRRjSA==", "dev": true, "dependencies": { "@types/debug": "^4.1.6", "7zip-bin": "~5.2.0", "app-builder-bin": "4.0.0", "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.2.3", + "builder-util-runtime": "9.2.4", "chalk": "^4.1.2", "cross-spawn": "^7.0.3", "debug": "^4.3.4", @@ -4303,6 +4393,19 @@ "node": ">=12.0.0" } }, + "node_modules/builder-util/node_modules/builder-util-runtime": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", + "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/builder-util/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -4759,6 +4862,22 @@ "node": ">=0.10.0" } }, + "node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "dev": true, + "peer": true, + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/computeds": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", @@ -4840,8 +4959,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "optional": true + "dev": true }, "node_modules/crc": { "version": "3.8.0", @@ -4853,6 +4971,33 @@ "buffer": "^5.1.0" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "peer": true, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "dev": true, + "peer": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -6031,14 +6176,14 @@ "dev": true }, "node_modules/dmg-builder": { - "version": "24.9.1", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.9.1.tgz", - "integrity": "sha512-huC+O6hvHd24Ubj3cy2GMiGLe2xGFKN3klqVMLAdcbB6SWMd1yPSdZvV8W1O01ICzCCRlZDHiv4VrNUgnPUfbQ==", + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.13.3.tgz", + "integrity": "sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ==", "dev": true, "dependencies": { - "app-builder-lib": "24.9.1", - "builder-util": "24.8.1", - "builder-util-runtime": "9.2.3", + "app-builder-lib": "24.13.3", + "builder-util": "24.13.1", + "builder-util-runtime": "9.2.4", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" @@ -6047,6 +6192,19 @@ "dmg-license": "^1.0.11" } }, + "node_modules/dmg-builder/node_modules/builder-util-runtime": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", + "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/dmg-builder/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -6196,16 +6354,16 @@ } }, "node_modules/electron-builder": { - "version": "24.9.1", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.9.1.tgz", - "integrity": "sha512-v7BuakDuY6sKMUYM8mfQGrwyjBpZ/ObaqnenU0H+igEL10nc6ht049rsCw2HghRBdEwJxGIBuzs3jbEhNaMDmg==", + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.13.3.tgz", + "integrity": "sha512-yZSgVHft5dNVlo31qmJAe4BVKQfFdwpRw7sFp1iQglDRCDD6r22zfRJuZlhtB5gp9FHUxCMEoWGq10SkCnMAIg==", "dev": true, "dependencies": { - "app-builder-lib": "24.9.1", - "builder-util": "24.8.1", - "builder-util-runtime": "9.2.3", + "app-builder-lib": "24.13.3", + "builder-util": "24.13.1", + "builder-util-runtime": "9.2.4", "chalk": "^4.1.2", - "dmg-builder": "24.9.1", + "dmg-builder": "24.13.3", "fs-extra": "^10.1.0", "is-ci": "^3.0.0", "lazy-val": "^1.0.5", @@ -6221,6 +6379,70 @@ "node": ">=14.0.0" } }, + "node_modules/electron-builder-squirrel-windows": { + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-24.13.3.tgz", + "integrity": "sha512-oHkV0iogWfyK+ah9ZIvMDpei1m9ZRpdXcvde1wTpra2U8AFDNNpqJdnin5z+PM1GbQ5BoaKCWas2HSjtR0HwMg==", + "dev": true, + "peer": true, + "dependencies": { + "app-builder-lib": "24.13.3", + "archiver": "^5.3.1", + "builder-util": "24.13.1", + "fs-extra": "^10.1.0" + } + }, + "node_modules/electron-builder-squirrel-windows/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-builder-squirrel-windows/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-builder-squirrel-windows/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-builder/node_modules/builder-util-runtime": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", + "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/electron-builder/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -6265,20 +6487,33 @@ } }, "node_modules/electron-publish": { - "version": "24.8.1", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.8.1.tgz", - "integrity": "sha512-IFNXkdxMVzUdweoLJNXSupXkqnvgbrn3J4vognuOY06LaS/m0xvfFYIf+o1CM8if6DuWYWoQFKPcWZt/FUjZPw==", + "version": "24.13.1", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.13.1.tgz", + "integrity": "sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A==", "dev": true, "dependencies": { "@types/fs-extra": "^9.0.11", - "builder-util": "24.8.1", - "builder-util-runtime": "9.2.3", + "builder-util": "24.13.1", + "builder-util-runtime": "9.2.4", "chalk": "^4.1.2", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "mime": "^2.5.2" } }, + "node_modules/electron-publish/node_modules/builder-util-runtime": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", + "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/electron-publish/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -7939,6 +8174,13 @@ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", "dev": true }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "peer": true + }, "node_modules/isbinaryfile": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", @@ -8962,6 +9204,52 @@ "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==" }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "peer": true + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/less": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", @@ -9099,11 +9387,32 @@ "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", "dev": true }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true, + "peer": true + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", + "dev": true, + "peer": true + }, "node_modules/lodash.escaperegexp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true, + "peer": true + }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -9127,6 +9436,13 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", + "dev": true, + "peer": true + }, "node_modules/long-timeout": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", @@ -10493,6 +10809,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "peer": true + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -10686,6 +11009,29 @@ "node": ">= 6" } }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "peer": true, + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -11706,15 +12052,12 @@ "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==" }, "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, "engines": { - "node": ">=8.17.0" + "node": ">=14.14" } }, "node_modules/tmp-promise": { @@ -12677,6 +13020,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "dev": true, + "peer": true, + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, "PA.UserInputTracker/typescript": { "name": "user-input-tracker", "version": "1.0.0", diff --git a/src/electron/package.json b/src/electron/package.json index d47ed6c7..4c3a8a64 100644 --- a/src/electron/package.json +++ b/src/electron/package.json @@ -1,6 +1,6 @@ { "name": "personal-analytics", - "version": "0.0.19", + "version": "0.0.20", "main": "dist-electron/main/index.js", "type": "module", "author": { @@ -36,7 +36,7 @@ "autoprefixer": "^10.4.17", "daisyui": "^4.6.1", "electron": "^28.2.2", - "electron-builder": "^24.9.1", + "electron-builder": "^24.13.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", diff --git a/src/electron/src/utils/Logger.ts b/src/electron/src/utils/Logger.ts new file mode 100644 index 00000000..4b3e08a2 --- /dev/null +++ b/src/electron/src/utils/Logger.ts @@ -0,0 +1,7 @@ +import { LogFunctions } from 'electron-log'; +import rendererLogger from 'electron-log/renderer'; + +const getRendererLogger = (loggerName: string): LogFunctions => { + return rendererLogger.scope(`Renderer/${loggerName}`); +}; +export default getRendererLogger; diff --git a/src/electron/src/views/DataExportView.vue b/src/electron/src/views/DataExportView.vue index 49b07c1f..3a29912a 100644 --- a/src/electron/src/views/DataExportView.vue +++ b/src/electron/src/views/DataExportView.vue @@ -11,6 +11,9 @@ import WindowActivityDto from '../../shared/dto/WindowActivityDto'; import UserInputDto from '../../shared/dto/UserInputDto'; import DataExportExperienceSamplingTracker from '../components/DataExportExperienceSamplingTracker.vue'; import ExperienceSamplingDto from '../../shared/dto/ExperienceSamplingDto'; +import getRendererLogger from '../utils/Logger'; + +const LOG = getRendererLogger('DataExportView'); const currentStep = ref(0); const transitionName = ref('slide-lef-right'); @@ -169,7 +172,7 @@ async function handleNextStep() { // Also update the DataExportService if you change the file name here fileName.value = `PA_${studyInfo.value?.subjectId}_${nowStr}.sqlite`; } catch (e) { - console.error(e); + LOG.error(e); hasExportError.value = true; } isExporting.value = false;