diff --git a/apps/desktop/.npmrc b/apps/desktop/.npmrc deleted file mode 100644 index 17633b5..0000000 --- a/apps/desktop/.npmrc +++ /dev/null @@ -1 +0,0 @@ -node-linker = hoisted diff --git a/apps/desktop/forge.config.ts b/apps/desktop/forge.config.ts index 9475d60..d2762e1 100644 --- a/apps/desktop/forge.config.ts +++ b/apps/desktop/forge.config.ts @@ -1,26 +1,270 @@ import type { ForgeConfig } from '@electron-forge/shared-types'; import { MakerSquirrel } from '@electron-forge/maker-squirrel'; -import { MakerZIP } from '@electron-forge/maker-zip'; +import { MakerDMG } from '@electron-forge/maker-dmg'; import { MakerDeb } from '@electron-forge/maker-deb'; import { MakerRpm } from '@electron-forge/maker-rpm'; import { VitePlugin } from '@electron-forge/plugin-vite'; import { FusesPlugin } from '@electron-forge/plugin-fuses'; import { FuseV1Options, FuseVersion } from '@electron/fuses'; +import { readdirSync, rmdirSync, statSync, existsSync, mkdirSync, cpSync } from 'node:fs'; +import { join, normalize } from 'node:path'; +// Use flora-colossus for finding all dependencies of EXTERNAL_DEPENDENCIES +// flora-colossus is maintained by MarshallOfSound (a top electron-forge contributor) +// already included as a dependency of electron-packager/galactus (so we do NOT have to add it to package.json) +// grabs nested dependencies from tree +import { Walker, DepType, type Module } from 'flora-colossus'; + +let nativeModuleDependenciesToPackage: string[] = []; + +export const EXTERNAL_DEPENDENCIES = [ + 'electron-squirrel-startup', + 'smart-whisper', + '@libsql/client', + '@libsql/darwin-arm64', + '@libsql/darwin-x64', + '@libsql/linux-x64-gnu', + '@libsql/linux-x64-musl', + '@libsql/win32-x64-msvc', + 'libsql', + // Add any other native modules you need here +]; const config: ForgeConfig = { + hooks: { + prePackage: async () => { + console.error('prePackage'); + const projectRoot = normalize(__dirname); + // In a monorepo, node_modules are typically at the root level + const monorepoRoot = join(projectRoot, '../../'); // Go up to monorepo root + + const getExternalNestedDependencies = async ( + nodeModuleNames: string[], + includeNestedDeps = true + ) => { + const foundModules = new Set(nodeModuleNames); + if (includeNestedDeps) { + for (const external of nodeModuleNames) { + type MyPublicClass = { + [P in keyof T]: T[P]; + }; + type MyPublicWalker = MyPublicClass & { + modules: Module[]; + walkDependenciesForModule: ( + moduleRoot: string, + depType: DepType + ) => Promise; + }; + const moduleRoot = join(monorepoRoot, 'node_modules', external); + console.log('moduleRoot', moduleRoot); + // Initialize Walker with monorepo root as base path + const walker = new Walker(monorepoRoot) as unknown as MyPublicWalker; + walker.modules = []; + await walker.walkDependenciesForModule(moduleRoot, DepType.PROD); + walker.modules + .filter((dep) => (dep.nativeModuleType as number) === DepType.PROD) + // Remove the problematic name splitting that breaks scoped packages + .map((dep) => dep.name) + .forEach((name) => foundModules.add(name)); + } + } + return foundModules; + }; + + const nativeModuleDependencies = await getExternalNestedDependencies(EXTERNAL_DEPENDENCIES); + nativeModuleDependenciesToPackage = Array.from(nativeModuleDependencies); + + // Copy external dependencies to local node_modules + console.error('Copying external dependencies to local node_modules'); + const localNodeModules = join(projectRoot, 'node_modules'); + const rootNodeModules = join(monorepoRoot, 'node_modules'); + + // Ensure local node_modules directory exists + if (!existsSync(localNodeModules)) { + mkdirSync(localNodeModules, { recursive: true }); + } + + console.log(`Found ${nativeModuleDependenciesToPackage.length} dependencies to copy`); + + // Copy all required dependencies + for (const dep of nativeModuleDependenciesToPackage) { + const rootDepPath = join(rootNodeModules, dep); + const localDepPath = join(localNodeModules, dep); + + try { + // Skip if source doesn't exist + if (!existsSync(rootDepPath)) { + console.log(`Skipping ${dep}: not found in root node_modules`); + continue; + } + + // Skip if target already exists (don't override) + if (existsSync(localDepPath)) { + console.log(`Skipping ${dep}: already exists locally`); + continue; + } + + // Copy the package + console.log(`Copying ${dep}...`); + cpSync(rootDepPath, localDepPath, { recursive: true }); + console.log(`✓ Successfully copied ${dep}`); + + } catch (error) { + console.error(`Failed to copy ${dep}:`, error); + } + } + }, + packageAfterPrune: async (_forgeConfig, buildPath) => { + try { + function getItemsFromFolder( + path: string, + totalCollection: { + path: string; + type: 'directory' | 'file'; + empty: boolean; + }[] = [] + ) { + try { + const normalizedPath = normalize(path); + const childItems = readdirSync(normalizedPath); + const getItemStats = statSync(normalizedPath); + if (getItemStats.isDirectory()) { + totalCollection.push({ + path: normalizedPath, + type: 'directory', + empty: childItems.length === 0, + }); + } + childItems.forEach((childItem) => { + const childItemNormalizedPath = join(normalizedPath, childItem); + const childItemStats = statSync(childItemNormalizedPath); + if (childItemStats.isDirectory()) { + getItemsFromFolder(childItemNormalizedPath, totalCollection); + } else { + totalCollection.push({ + path: childItemNormalizedPath, + type: 'file', + empty: false, + }); + } + }); + } catch { + return; + } + return totalCollection; + } + const getItems = getItemsFromFolder(buildPath) ?? []; + for (const item of getItems) { + const DELETE_EMPTY_DIRECTORIES = true; + if (item.empty === true) { + if (DELETE_EMPTY_DIRECTORIES) { + const pathToDelete = normalize(item.path); + // one last check to make sure it is a directory and is empty + const stats = statSync(pathToDelete); + if (!stats.isDirectory()) { + // SKIPPING DELETION: pathToDelete is not a directory + return; + } + const childItems = readdirSync(pathToDelete); + if (childItems.length !== 0) { + // SKIPPING DELETION: pathToDelete is not empty + return; + } + rmdirSync(pathToDelete); + } + } + } + } catch (error) { + console.error('Error in packageAfterPrune:', error); + throw error; + } + }, + }, packagerConfig: { asar: true, name: 'Amical', executableName: 'Amical', icon: './assets/logo', // Path to your icon file (without extension) - extraResource: ['../../packages/native-helpers/swift-helper/bin'], + extraResource: [ + '../../packages/native-helpers/swift-helper/bin', + './src/db/migrations', + ], extendInfo: { NSMicrophoneUsageDescription: 'This app needs access to your microphone to record audio for transcription.', }, + //! issues with monorepo setup and module resolutions + //! when forge walks paths via flora-colossus + prune: false, + ignore: (file: string) => { + try { + + const filePath = file.toLowerCase(); + const KEEP_FILE = { + keep: false, + log: true, + }; + // NOTE: must return false for empty string or nothing will be packaged + if (filePath === '') KEEP_FILE.keep = true; + if (!KEEP_FILE.keep && filePath === '/package.json') KEEP_FILE.keep = true; + if (!KEEP_FILE.keep && filePath === '/node_modules') KEEP_FILE.keep = true; + if (!KEEP_FILE.keep && filePath === '/.vite') KEEP_FILE.keep = true; + if (!KEEP_FILE.keep && filePath.startsWith('/.vite/')) KEEP_FILE.keep = true; + if (!KEEP_FILE.keep && filePath.startsWith('/node_modules/')) { + // check if matches any of the external dependencies + for (const dep of nativeModuleDependenciesToPackage) { + if ( + filePath === `/node_modules/${dep}/` || + filePath === `/node_modules/${dep}` + ) { + KEEP_FILE.keep = true; + break; + } + if (filePath === `/node_modules/${dep}/package.json`) { + KEEP_FILE.keep = true; + break; + } + if (filePath.startsWith(`/node_modules/${dep}/`)) { + KEEP_FILE.keep = true; + KEEP_FILE.log = false; + break; + } + + // Handle scoped packages: if dep is @scope/package, also keep @scope/ directory + if (dep.includes('/') && dep.startsWith('@')) { + const scopeDir = dep.split('/')[0]; // @libsql/client -> @libsql + if ( + filePath === `/node_modules/${scopeDir}/` || + filePath === `/node_modules/${scopeDir}` || + filePath.startsWith(`/node_modules/${scopeDir}/`) + ) { + KEEP_FILE.keep = true; + KEEP_FILE.log = filePath === `/node_modules/${scopeDir}/` || filePath === `/node_modules/${scopeDir}`; + break; + } + } + } + } + if (KEEP_FILE.keep) { + if (KEEP_FILE.log) console.log('Keeping:', file); + return false; + } + return true; + } catch (error) { + console.error('Error in ignore:', error); + throw error; + } + }, }, rebuildConfig: {}, - makers: [new MakerSquirrel({}), new MakerZIP({}, ['darwin']), new MakerRpm({}), new MakerDeb({})], + makers: [ + new MakerSquirrel({}), + new MakerDMG({ + name: 'Amical', + icon: './assets/logo.svg' + }, ['darwin']), + new MakerRpm({}), + new MakerDeb({}) + ], plugins: [ new VitePlugin({ // `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc. diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 7a83f5e..a94bac7 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -8,6 +8,7 @@ "start": "pnpm build:swift-helper && electron-forge start", "package": "pnpm build:swift-helper && electron-forge package", "make": "pnpm build:swift-helper && electron-forge make", + "make:dmg": "pnpm build:swift-helper && electron-forge make --targets=@electron-forge/maker-dmg --platform=darwin --arch=arm64", "publish": "electron-forge publish", "lint": "eslint --ext .ts,.tsx .", "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"", @@ -23,6 +24,7 @@ "devDependencies": { "@electron-forge/cli": "^7.8.1", "@electron-forge/maker-deb": "^7.8.1", + "@electron-forge/maker-dmg": "^7.8.1", "@electron-forge/maker-rpm": "^7.8.1", "@electron-forge/maker-squirrel": "^7.8.1", "@electron-forge/maker-zip": "^7.8.1", @@ -39,6 +41,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.31.0", "eslint-plugin-prettier": "^5.4.0", + "flora-colossus": "^2.0.0", "prettier": "^3.5.3", "tailwindcss": "^4.1.6", "tsx": "^4.19.4", diff --git a/apps/desktop/src/db/config.ts b/apps/desktop/src/db/config.ts index d950421..acbaaf2 100644 --- a/apps/desktop/src/db/config.ts +++ b/apps/desktop/src/db/config.ts @@ -31,15 +31,8 @@ export async function initializeDatabase() { // Development: use source path relative to the app's working directory migrationsPath = path.join(process.cwd(), 'src', 'db', 'migrations'); } else { - // Production: migrations should be in app resources - migrationsPath = path.join( - process.resourcesPath, - 'app.asar.unpacked', - 'dist', - 'main', - 'db', - 'migrations' - ); + // Production: migrations are copied to resources via extraResource + migrationsPath = path.join(process.resourcesPath, 'migrations'); } console.log('Attempting to run migrations from:', migrationsPath); diff --git a/apps/desktop/src/main/main.ts b/apps/desktop/src/main/main.ts index e3a5a72..e04a520 100644 --- a/apps/desktop/src/main/main.ts +++ b/apps/desktop/src/main/main.ts @@ -37,8 +37,7 @@ if (started) { declare const MAIN_WINDOW_VITE_DEV_SERVER_URL: string; declare const MAIN_WINDOW_VITE_NAME: string; - -const WIDGET_WINDOW_VITE_NAME = 'widget_window'; +declare const WIDGET_WINDOW_VITE_NAME: string; let mainWindow: BrowserWindow | null = null; let floatingButtonWindow: BrowserWindow | null = null; @@ -158,7 +157,7 @@ const createFloatingButtonWindow = () => { floatingButtonWindow.loadURL(devUrl.toString()); } else { floatingButtonWindow.loadFile( - path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/fab.html`) + path.join(__dirname, `../renderer/${WIDGET_WINDOW_VITE_NAME}/fab.html`) ); } diff --git a/apps/desktop/vite.main.config.mts b/apps/desktop/vite.main.config.mts index 67939ba..2a5a4f4 100644 --- a/apps/desktop/vite.main.config.mts +++ b/apps/desktop/vite.main.config.mts @@ -6,7 +6,6 @@ export default defineConfig({ build: { rollupOptions: { external: [ - 'better-sqlite3', 'smart-whisper', '@libsql/client', '@libsql/darwin-arm64', diff --git a/package.json b/package.json index 6dc75f3..b078219 100644 --- a/package.json +++ b/package.json @@ -28,15 +28,16 @@ "protobufjs", "sharp", "smart-whisper", - "drizzle-orm/libsql", - "@libsql" + "drizzle-orm/libsql" ], "onlyBuiltDependencies": [ "electron", "electron-winstaller", "smart-whisper", "drizzle-orm/libsql", - "@libsql" + "@libsql", + "macos-alias", + "fs-xattr" ] } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7201fd7..604b3e3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -264,6 +264,9 @@ importers: '@electron-forge/maker-deb': specifier: ^7.8.1 version: 7.8.1 + '@electron-forge/maker-dmg': + specifier: ^7.8.1 + version: 7.8.1 '@electron-forge/maker-rpm': specifier: ^7.8.1 version: 7.8.1 @@ -312,6 +315,9 @@ importers: eslint-plugin-prettier: specifier: ^5.4.0 version: 5.4.0(eslint-config-prettier@9.1.0(eslint@9.27.0(jiti@2.4.2)))(eslint@9.27.0(jiti@2.4.2))(prettier@3.5.3) + flora-colossus: + specifier: ^2.0.0 + version: 2.0.0 prettier: specifier: ^3.5.3 version: 3.5.3 @@ -859,6 +865,10 @@ packages: resolution: {integrity: sha512-tjjeesQtCP5Xht1X7gl4+K9bwoETPmQfBkOVAY/FZIxPj40uQh/hOUtLX2tYENNGNVZ1ryDYRs8TuPi+I41Vfw==} engines: {node: '>= 16.4.0'} + '@electron-forge/maker-dmg@7.8.1': + resolution: {integrity: sha512-l449QvY2Teu+J9rHnjkTHEm/wOJ1LRfmrQ2QkGtFoTRcqvFWdUAEN8nK2/08w3j2h6tvOY3QSUjRzXrhJZRNRA==} + engines: {node: '>= 16.4.0'} + '@electron-forge/maker-rpm@7.8.1': resolution: {integrity: sha512-TF6wylft3BHkw9zdHcxmjEPBZYgTIc0jE31skFnMEQ/aExbNRiNaCZvsXy+7ptTWZxhxUKRc9KHhLFRMCmOK8g==} engines: {node: '>= 16.4.0'} @@ -3151,6 +3161,9 @@ packages: resolution: {integrity: sha512-Kqo+gKJleFB+GkKiSHCCb4RB46VDBTWRKdp08RQ4rtL60+SU89M6F7gpTGG/4nL2eYD98mOKp3Lyzfk/Auht7A==} hasBin: true + '@types/appdmg@0.5.5': + resolution: {integrity: sha512-G+n6DgZTZFOteITE30LnWj+HRVIGr7wMlAiLWOO02uJFWVEitaPU9JVXm9wJokkgshBawb2O1OykdcsmkkZfgg==} + '@types/better-sqlite3@7.6.13': resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} @@ -3455,6 +3468,12 @@ packages: app-module-path@2.2.0: resolution: {integrity: sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==} + appdmg@0.6.6: + resolution: {integrity: sha512-GRmFKlCG+PWbcYF4LUNonTYmy0GjguDy6Jh9WP8mpd0T6j80XIJyXBiWlD0U+MLNhqV9Nhx49Gl9GpVToulpLg==} + engines: {node: '>=8.5'} + os: [darwin] + hasBin: true + aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} @@ -3547,6 +3566,9 @@ packages: async-mutex@0.5.0: resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + async@1.5.2: + resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -3572,6 +3594,9 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base32-encode@1.2.0: + resolution: {integrity: sha512-cHFU8XeRyx0GgmoWi5qHMCVRiqU6J3MHWxVgun7jggCBUpVzm1Ir7M9dYr2whjSNc3tFeXfQ/oZjQu/4u55h9A==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -3612,6 +3637,9 @@ packages: bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + bplist-creator@0.0.8: + resolution: {integrity: sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -3806,6 +3834,9 @@ packages: collection-utils@1.0.1: resolution: {integrity: sha512-LA2YTIlR7biSpXkKYwwuzGjwL5rjWEZVOSnvdUc7gObvWe4WkjxOpfrdhoP7Hs09YWDVfg0Mal9BpAqLfVEzQg==} + color-convert@0.5.3: + resolution: {integrity: sha512-RwBeO/B/vZR3dfKL1ye/vx8MHZ40ugzpyfeVG5GsiuGnrlMWe2o8wxBbLCpw9CsxV+wHuzYlCiWnybrIA0ling==} + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -4306,6 +4337,9 @@ packages: sqlite3: optional: true + ds-store@0.1.6: + resolution: {integrity: sha512-kY21M6Lz+76OS3bnCzjdsJSF7LBpLYGCVfavW8TgQD2XkcqIZ86W0y9qUDZu6fp7SIZzqosMDW2zi7zVFfv4hw==} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -4326,6 +4360,11 @@ packages: os: [darwin, linux] hasBin: true + electron-installer-dmg@5.0.1: + resolution: {integrity: sha512-qOa1aAQdX57C+vzhDk3549dd/PRlNL4F8y736MTD1a43qptD+PvHY97Bo9gSf+OZ8iUWE7BrYSpk/FgLUe40EA==} + engines: {node: '>= 16'} + hasBin: true + electron-installer-redhat@3.4.0: resolution: {integrity: sha512-gEISr3U32Sgtj+fjxUAlSDo3wyGGq6OBx7rF5UdpIgbnpUvMN4W5uYb0ThpnAZ42VEJh/3aODQXHbFS4f5J3Iw==} engines: {node: '>= 10.0.0'} @@ -4374,6 +4413,9 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -4820,6 +4862,9 @@ packages: resolution: {integrity: sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA==} engines: {node: '>= 12'} + fmix@0.1.0: + resolution: {integrity: sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==} + for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -4898,6 +4943,14 @@ packages: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} + fs-temp@1.2.1: + resolution: {integrity: sha512-okTwLB7/Qsq82G6iN5zZJFsOfZtx2/pqrA7Hk/9fvy+c+eJS9CvgGXT2uNxwnI14BDY9L/jQPkaBgSvlKfSW9w==} + + fs-xattr@0.3.1: + resolution: {integrity: sha512-UVqkrEW0GfDabw4C3HOrFlxKfx0eeigfRne69FxSBdHIP8Qt5Sq6Pu3RM9KmMlkygtC4pPKkj5CiPO5USnj2GA==} + engines: {node: '>=8.6.0'} + os: ['!win32'] + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -4971,6 +5024,12 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} deprecated: This package is no longer supported. + generate-function@2.3.1: + resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} + + generate-object-property@1.2.0: + resolution: {integrity: sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -5246,6 +5305,11 @@ packages: resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==} engines: {node: '>= 4'} + image-size@0.7.5: + resolution: {integrity: sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==} + engines: {node: '>=6.9.0'} + hasBin: true + image-size@2.0.2: resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==} engines: {node: '>=16.x'} @@ -5255,6 +5319,10 @@ packages: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} + imul@1.0.1: + resolution: {integrity: sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==} + engines: {node: '>=0.10.0'} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -5419,6 +5487,12 @@ packages: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} + is-my-ip-valid@1.0.1: + resolution: {integrity: sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==} + + is-my-json-valid@2.20.6: + resolution: {integrity: sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==} + is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -5442,6 +5516,9 @@ packages: is-promise@2.2.2: resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + is-property@1.0.2: + resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} + is-reference@1.2.1: resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} @@ -5578,6 +5655,10 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + jstransformer@1.0.0: resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} @@ -5760,6 +5841,10 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + macos-alias@0.2.12: + resolution: {integrity: sha512-yiLHa7cfJcGRFq4FrR4tMlpNHb4Vy4mWnpajlSSIFM5k4Lv8/7BbbDLzCAVogWNl0LlLhizRp1drXv0hK9h0Yw==} + os: [darwin] + magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} @@ -6104,6 +6189,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + murmur-32@0.2.0: + resolution: {integrity: sha512-ZkcWZudylwF+ir3Ld1n7gL6bI2mQAzXvSobPwVtu8aYi2sbXeipeSkdcanRLzIofLcM5F53lGaKm2dk7orBi7Q==} + mustache@4.2.0: resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true @@ -6114,6 +6202,9 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nan@2.22.2: + resolution: {integrity: sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -6413,6 +6504,9 @@ packages: resolution: {integrity: sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==} engines: {node: '>=0.10.0'} + parse-color@1.0.0: + resolution: {integrity: sha512-fuDHYgFHJGbpGMgw9skY/bj3HL/Jrn4l/5rSspy00DoT4RyLnDcRvPxdZ+r6OFwIsgAuhDh4I09tAId4mI12bw==} + parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} @@ -6686,6 +6780,9 @@ packages: resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==} engines: {node: '>= 0.8'} + random-path@0.1.2: + resolution: {integrity: sha512-4jY0yoEaQ5v9StCl5kZbNIQlg1QheIDBrdkDn53EynpPb9FgO6//p3X/tgMnrC45XN6QZCzU1Xz/+pSSsJBpRw==} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -6886,6 +6983,10 @@ packages: remark@15.0.1: resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -7265,6 +7366,10 @@ packages: resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} engines: {node: '>=4', npm: '>=6'} + stream-buffers@2.2.0: + resolution: {integrity: sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==} + engines: {node: '>= 0.10.0'} + stream-chain@2.2.5: resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} @@ -7484,6 +7589,13 @@ packages: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} + tn1150@0.1.0: + resolution: {integrity: sha512-DbplOfQFkqG5IHcDyyrs/lkvSr3mPUVsFf/RbDppOshs22yTPnSJWEe6FkYd1txAwU/zcnR905ar2fi4kwF29w==} + engines: {node: '>=0.12'} + + to-data-view@1.1.0: + resolution: {integrity: sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -7737,6 +7849,10 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unorm@1.6.0: + resolution: {integrity: sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==} + engines: {node: '>= 0.4.0'} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -8000,6 +8116,10 @@ packages: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} engines: {node: '>=8.0'} + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + xterm-addon-fit@0.5.0: resolution: {integrity: sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==} deprecated: This package is now deprecated. Move to @xterm/addon-fit instead. @@ -8762,6 +8882,17 @@ snapshots: - bluebird - supports-color + '@electron-forge/maker-dmg@7.8.1': + dependencies: + '@electron-forge/maker-base': 7.8.1 + '@electron-forge/shared-types': 7.8.1 + fs-extra: 10.1.0 + optionalDependencies: + electron-installer-dmg: 5.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + '@electron-forge/maker-rpm@7.8.1': dependencies: '@electron-forge/maker-base': 7.8.1 @@ -11099,6 +11230,11 @@ snapshots: semver: 7.6.2 update-check: 1.5.4 + '@types/appdmg@0.5.5': + dependencies: + '@types/node': 22.15.12 + optional: true + '@types/better-sqlite3@7.6.13': dependencies: '@types/node': 22.15.12 @@ -11426,6 +11562,21 @@ snapshots: app-module-path@2.2.0: {} + appdmg@0.6.6: + dependencies: + async: 1.5.2 + ds-store: 0.1.6 + execa: 1.0.0 + fs-temp: 1.2.1 + fs-xattr: 0.3.1 + image-size: 0.7.5 + is-my-json-valid: 2.20.6 + minimist: 1.2.8 + parse-color: 1.0.0 + path-exists: 4.0.0 + repeat-string: 1.6.1 + optional: true + aproba@2.0.0: {} are-we-there-yet@4.0.2: {} @@ -11535,6 +11686,9 @@ snapshots: dependencies: tslib: 2.8.1 + async@1.5.2: + optional: true + asynckit@0.4.0: {} at-least-node@1.0.0: {} @@ -11553,6 +11707,11 @@ snapshots: balanced-match@1.0.2: {} + base32-encode@1.2.0: + dependencies: + to-data-view: 1.1.0 + optional: true + base64-js@1.5.1: {} base64id@2.0.0: {} @@ -11604,6 +11763,11 @@ snapshots: bowser@2.11.0: {} + bplist-creator@0.0.8: + dependencies: + stream-buffers: 2.2.0 + optional: true + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -11835,6 +11999,9 @@ snapshots: collection-utils@1.0.1: {} + color-convert@0.5.3: + optional: true + color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -12217,6 +12384,13 @@ snapshots: '@types/better-sqlite3': 7.6.13 better-sqlite3: 11.10.0 + ds-store@0.1.6: + dependencies: + bplist-creator: 0.0.8 + macos-alias: 0.2.12 + tn1150: 0.1.0 + optional: true + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -12258,6 +12432,17 @@ snapshots: - supports-color optional: true + electron-installer-dmg@5.0.1: + dependencies: + '@types/appdmg': 0.5.5 + debug: 4.4.1 + minimist: 1.2.8 + optionalDependencies: + appdmg: 0.6.6 + transitivePeerDependencies: + - supports-color + optional: true + electron-installer-redhat@3.4.0: dependencies: '@malept/cross-spawn-promise': 1.1.1 @@ -12327,6 +12512,9 @@ snapshots: emoji-regex@9.2.2: {} + encode-utf8@1.0.3: + optional: true + encodeurl@1.0.2: {} encodeurl@2.0.0: {} @@ -13025,6 +13213,11 @@ snapshots: transitivePeerDependencies: - supports-color + fmix@0.1.0: + dependencies: + imul: 1.0.1 + optional: true + for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -13112,6 +13305,14 @@ snapshots: dependencies: minipass: 3.3.6 + fs-temp@1.2.1: + dependencies: + random-path: 0.1.2 + optional: true + + fs-xattr@0.3.1: + optional: true + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -13232,6 +13433,16 @@ snapshots: strip-ansi: 6.0.1 wide-align: 1.1.5 + generate-function@2.3.1: + dependencies: + is-property: 1.0.2 + optional: true + + generate-object-property@1.2.0: + dependencies: + is-property: 1.0.2 + optional: true + get-caller-file@2.0.5: {} get-folder-size@2.0.1: @@ -13626,6 +13837,9 @@ snapshots: ignore@7.0.4: {} + image-size@0.7.5: + optional: true + image-size@2.0.2: {} import-fresh@3.3.1: @@ -13633,6 +13847,9 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 + imul@1.0.1: + optional: true + imurmurhash@0.1.4: {} indent-string@4.0.0: {} @@ -13817,6 +14034,18 @@ snapshots: is-map@2.0.3: {} + is-my-ip-valid@1.0.1: + optional: true + + is-my-json-valid@2.20.6: + dependencies: + generate-function: 2.3.1 + generate-object-property: 1.2.0 + is-my-ip-valid: 1.0.1 + jsonpointer: 5.0.1 + xtend: 4.0.2 + optional: true + is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -13832,6 +14061,9 @@ snapshots: is-promise@2.2.2: {} + is-property@1.0.2: + optional: true + is-reference@1.2.1: dependencies: '@types/estree': 1.0.7 @@ -13960,6 +14192,9 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonpointer@5.0.1: + optional: true + jstransformer@1.0.0: dependencies: is-promise: 2.2.2 @@ -14136,6 +14371,11 @@ snapshots: dependencies: react: 19.1.0 + macos-alias@0.2.12: + dependencies: + nan: 2.22.2 + optional: true + magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -14755,6 +14995,13 @@ snapshots: ms@2.1.3: {} + murmur-32@0.2.0: + dependencies: + encode-utf8: 1.0.3 + fmix: 0.1.0 + imul: 1.0.1 + optional: true + mustache@4.2.0: {} mute-stream@0.0.8: {} @@ -14765,6 +15012,9 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + nan@2.22.2: + optional: true + nanoid@3.3.11: {} napi-build-utils@2.0.0: {} @@ -15098,6 +15348,11 @@ snapshots: dependencies: author-regex: 1.0.0 + parse-color@1.0.0: + dependencies: + color-convert: 0.5.3 + optional: true + parse-entities@4.0.2: dependencies: '@types/unist': 2.0.11 @@ -15439,6 +15694,12 @@ snapshots: random-bytes@1.0.0: {} + random-path@0.1.2: + dependencies: + base32-encode: 1.2.0 + murmur-32: 0.2.0 + optional: true + range-parser@1.2.1: {} raw-body@2.5.2: @@ -15724,6 +15985,9 @@ snapshots: transitivePeerDependencies: - supports-color + repeat-string@1.6.1: + optional: true + require-directory@2.1.1: {} resedit@2.0.3: @@ -16256,6 +16520,9 @@ snapshots: stoppable@1.1.0: {} + stream-buffers@2.2.0: + optional: true + stream-chain@2.2.5: {} stream-json@1.8.0: @@ -16504,6 +16771,14 @@ snapshots: tmp@0.2.3: optional: true + tn1150@0.1.0: + dependencies: + unorm: 1.6.0 + optional: true + + to-data-view@1.1.0: + optional: true + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -16781,6 +17056,9 @@ snapshots: universalify@2.0.1: {} + unorm@1.6.0: + optional: true + unpipe@1.0.0: {} update-check@1.5.4: @@ -17032,6 +17310,9 @@ snapshots: xmlbuilder@15.1.1: {} + xtend@4.0.2: + optional: true + xterm-addon-fit@0.5.0(xterm@4.19.0): dependencies: xterm: 4.19.0