Integrate local database management and IPC handlers into Electron

- Add comprehensive IPC handlers for database operations like books, chapters, characters, and conversations.
- Implement local database initialization and user data encryption.
- Update preload script paths for consistent environment handling.
- Modify `page.tsx` to initialize local database within Electron environment.
- Add new dependencies including `node-sqlite3-wasm` and `electron-rebuild`.
This commit is contained in:
natreex
2025-11-17 07:46:20 -05:00
parent b4eafca3bc
commit 71067c6fa8
10 changed files with 820 additions and 13 deletions

View File

@@ -31,6 +31,8 @@ import enMessages from '@/lib/locales/en.json';
import {NextIntlClientProvider, useTranslations} from "next-intl"; import {NextIntlClientProvider, useTranslations} from "next-intl";
import {LangContext} from "@/context/LangContext"; import {LangContext} from "@/context/LangContext";
import {AIUsageContext} from "@/context/AIUsageContext"; import {AIUsageContext} from "@/context/AIUsageContext";
import OfflineProvider from "@/context/OfflineProvider";
import OfflineContext from "@/context/OfflineContext";
const messagesMap = { const messagesMap = {
fr: frMessages, fr: frMessages,
@@ -41,6 +43,7 @@ function ScribeContent() {
const t = useTranslations(); const t = useTranslations();
const {lang: locale} = useContext(LangContext); const {lang: locale} = useContext(LangContext);
const {errorMessage} = useContext(AlertContext); const {errorMessage} = useContext(AlertContext);
const {initializeDatabase} = useContext(OfflineContext);
const editor: Editor | null = useEditor({ const editor: Editor | null = useEditor({
extensions: [ extensions: [
StarterKit, StarterKit,
@@ -216,6 +219,19 @@ function ScribeContent() {
}); });
setCurrentCredits(user.creditsBalance) setCurrentCredits(user.creditsBalance)
setAmountSpent(user.aiUsage) setAmountSpent(user.aiUsage)
// Initialiser la DB locale en Electron
if (window.electron && user.id) {
try {
const dbInitialized = await initializeDatabase(user.id);
if (dbInitialized) {
console.log('Database initialized successfully');
// TODO: Sync initial des données du serveur vers la DB locale
}
} catch (error) {
console.error('Failed to initialize database:', error);
}
}
} catch (e: unknown) { } catch (e: unknown) {
if (e instanceof Error) { if (e instanceof Error) {
errorMessage(e.message); errorMessage(e.message);
@@ -359,9 +375,11 @@ export default function Scribe() {
return ( return (
<LangContext.Provider value={{lang: locale, setLang: setLocale}}> <LangContext.Provider value={{lang: locale, setLang: setLocale}}>
<NextIntlClientProvider locale={locale} messages={messages}> <NextIntlClientProvider locale={locale} messages={messages}>
<AlertProvider> <OfflineProvider>
<ScribeContent/> <AlertProvider>
</AlertProvider> <ScribeContent/>
</AlertProvider>
</OfflineProvider>
</NextIntlClientProvider> </NextIntlClientProvider>
</LangContext.Provider> </LangContext.Provider>
); );

View File

@@ -2,6 +2,7 @@
import {useContext} from "react"; import {useContext} from "react";
import {BookContext, BookContextProps} from "@/context/BookContext"; import {BookContext, BookContextProps} from "@/context/BookContext";
import {useTranslations} from "next-intl"; import {useTranslations} from "next-intl";
import OfflineToggle from "@/components/offline/OfflineToggle";
export default function ScribeTopBar() { export default function ScribeTopBar() {
const book: BookContextProps = useContext(BookContext); const book: BookContextProps = useContext(BookContext);
@@ -33,6 +34,7 @@ export default function ScribeTopBar() {
</div> </div>
)} )}
<div className="flex items-center space-x-2 min-w-[120px] justify-end"> <div className="flex items-center space-x-2 min-w-[120px] justify-end">
<OfflineToggle />
</div> </div>
</div> </div>
) )

View File

@@ -244,8 +244,8 @@ export default function BookList() {
<div <div
className="flex justify-between items-center w-full max-w-5xl mx-auto mb-6 px-6"> className="flex justify-between items-center w-full max-w-5xl mx-auto mb-6 px-6">
<h2 className="text-3xl text-text-primary capitalize font-['ADLaM_Display'] flex items-center gap-3"> <h2 className="text-3xl text-text-primary capitalize font-['ADLaM_Display'] flex items-center gap-3">
<span className="w-1 h-8 bg-primary rounded-full"></span> <span key="icon" className="w-1 h-8 bg-primary rounded-full"></span>
{category} <span key="title">{category}</span>
</h2> </h2>
<span <span
className="text-muted text-lg font-medium bg-secondary/30 px-4 py-1.5 rounded-full">{books.length} {t("bookList.works")}</span> className="text-muted text-lg font-medium bg-secondary/30 px-4 py-1.5 rounded-full">{books.length} {t("bookList.works")}</span>

17
electron.d.ts vendored
View File

@@ -5,6 +5,23 @@ export interface IElectronAPI {
removeToken: () => Promise<boolean>; removeToken: () => Promise<boolean>;
loginSuccess: (token: string) => void; loginSuccess: (token: string) => void;
logout: () => void; logout: () => void;
// Database operations
generateEncryptionKey: (userId: string) => Promise<{ success: boolean; key?: string; error?: string }>;
getUserEncryptionKey: (userId: string) => Promise<string | null>;
setUserEncryptionKey: (userId: string, encryptionKey: string) => Promise<boolean>;
dbInitialize: (userId: string, encryptionKey: string) => Promise<{ success: boolean; error?: string }>;
dbGetBooks: () => Promise<{ success: boolean; data?: any[]; error?: string }>;
dbGetBook: (bookId: string) => Promise<{ success: boolean; data?: any; error?: string }>;
dbSaveBook: (book: any, authorId?: string) => Promise<{ success: boolean; error?: string }>;
dbDeleteBook: (bookId: string) => Promise<{ success: boolean; error?: string }>;
dbSaveChapter: (chapter: any, bookId: string, contentId?: string) => Promise<{ success: boolean; error?: string }>;
dbGetCharacters: (bookId: string) => Promise<{ success: boolean; data?: any[]; error?: string }>;
dbSaveCharacter: (character: any, bookId: string) => Promise<{ success: boolean; error?: string }>;
dbGetConversations: (bookId: string) => Promise<{ success: boolean; data?: any[]; error?: string }>;
dbSaveConversation: (conversation: any, bookId: string) => Promise<{ success: boolean; error?: string }>;
dbGetSyncStatus: () => Promise<{ success: boolean; data?: any[]; error?: string }>;
dbGetPendingChanges: (limit?: number) => Promise<{ success: boolean; data?: any[]; error?: string }>;
} }
declare global { declare global {

View File

@@ -4,6 +4,7 @@ import * as url from 'url';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import Store from 'electron-store'; import Store from 'electron-store';
import * as fs from 'fs'; import * as fs from 'fs';
import { getDatabaseService } from './database/database.service.js';
// Fix pour __dirname en ES modules // Fix pour __dirname en ES modules
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
@@ -29,10 +30,8 @@ if (!isDev) {
// Définir le nom de l'application // Définir le nom de l'application
app.setName('ERitors Scribe'); app.setName('ERitors Scribe');
// En dev, __dirname pointe vers electron/, en prod vers dist/electron/ // En dev et prod, __dirname pointe vers dist/electron/
const preloadPath = isDev const preloadPath = path.join(__dirname, 'preload.js');
? path.join(__dirname, '../dist/electron/preload.js')
: path.join(__dirname, 'preload.js');
// Icône de l'application // Icône de l'application
const iconPath = isDev const iconPath = isDev
@@ -143,6 +142,10 @@ ipcMain.on('login-success', (_event, token: string) => {
ipcMain.on('logout', () => { ipcMain.on('logout', () => {
store.delete('authToken'); store.delete('authToken');
// Close database connection
const db = getDatabaseService();
db.close();
if (mainWindow) { if (mainWindow) {
mainWindow.close(); mainWindow.close();
} }
@@ -150,6 +153,246 @@ ipcMain.on('logout', () => {
createLoginWindow(); createLoginWindow();
}); });
// ========== DATABASE IPC HANDLERS ==========
/**
* Generate user encryption key
*/
ipcMain.handle('generate-encryption-key', async (_event, userId: string) => {
try {
// Import encryption module dynamically
const { generateUserEncryptionKey } = await import('./database/encryption.js');
const key = generateUserEncryptionKey(userId);
return { success: true, key };
} catch (error) {
console.error('Failed to generate encryption key:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Get or generate user encryption key
*/
ipcMain.handle('get-user-encryption-key', (_event, userId: string) => {
const key = store.get(`encryptionKey-${userId}`, null);
return key;
});
/**
* Store user encryption key
*/
ipcMain.handle('set-user-encryption-key', (_event, userId: string, encryptionKey: string) => {
store.set(`encryptionKey-${userId}`, encryptionKey);
return true;
});
/**
* Initialize database for user
*/
ipcMain.handle('db-initialize', (_event, userId: string, encryptionKey: string) => {
try {
const db = getDatabaseService();
db.initialize(userId, encryptionKey);
return { success: true };
} catch (error) {
console.error('Failed to initialize database:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Get all books
*/
ipcMain.handle('db-get-books', () => {
try {
const db = getDatabaseService();
const books = db.getBooks();
return { success: true, data: books };
} catch (error) {
console.error('Failed to get books:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Get single book with all data
*/
ipcMain.handle('db-get-book', (_event, bookId: string) => {
try {
const db = getDatabaseService();
const book = db.getBook(bookId);
return { success: true, data: book };
} catch (error) {
console.error('Failed to get book:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Save book
*/
ipcMain.handle('db-save-book', (_event, book: any, authorId?: string) => {
try {
const db = getDatabaseService();
db.saveBook(book, authorId);
return { success: true };
} catch (error) {
console.error('Failed to save book:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Delete book
*/
ipcMain.handle('db-delete-book', (_event, bookId: string) => {
try {
const db = getDatabaseService();
db.deleteBook(bookId);
return { success: true };
} catch (error) {
console.error('Failed to delete book:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Save chapter
*/
ipcMain.handle('db-save-chapter', (_event, chapter: any, bookId: string, contentId?: string) => {
try {
const db = getDatabaseService();
db.saveChapter(chapter, bookId, contentId);
return { success: true };
} catch (error) {
console.error('Failed to save chapter:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Get characters for a book
*/
ipcMain.handle('db-get-characters', (_event, bookId: string) => {
try {
const db = getDatabaseService();
const characters = db.getCharacters(bookId);
return { success: true, data: characters };
} catch (error) {
console.error('Failed to get characters:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Save character
*/
ipcMain.handle('db-save-character', (_event, character: any, bookId: string) => {
try {
const db = getDatabaseService();
db.saveCharacter(character, bookId);
return { success: true };
} catch (error) {
console.error('Failed to save character:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Get AI conversations for a book
*/
ipcMain.handle('db-get-conversations', (_event, bookId: string) => {
try {
const db = getDatabaseService();
const conversations = db.getConversations(bookId);
return { success: true, data: conversations };
} catch (error) {
console.error('Failed to get conversations:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Save AI conversation
*/
ipcMain.handle('db-save-conversation', (_event, conversation: any, bookId: string) => {
try {
const db = getDatabaseService();
db.saveConversation(conversation, bookId);
return { success: true };
} catch (error) {
console.error('Failed to save conversation:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Get sync status
*/
ipcMain.handle('db-get-sync-status', () => {
try {
const db = getDatabaseService();
const status = db.getSyncStatus();
return { success: true, data: status };
} catch (error) {
console.error('Failed to get sync status:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
/**
* Get pending changes
*/
ipcMain.handle('db-get-pending-changes', (_event, limit: number = 100) => {
try {
const db = getDatabaseService();
const changes = db.getPendingChanges(limit);
return { success: true, data: changes };
} catch (error) {
console.error('Failed to get pending changes:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});
app.whenReady().then(() => { app.whenReady().then(() => {
console.log('App ready, isDev:', isDev); console.log('App ready, isDev:', isDev);
console.log('resourcesPath:', process.resourcesPath); console.log('resourcesPath:', process.resourcesPath);

View File

@@ -12,4 +12,21 @@ contextBridge.exposeInMainWorld('electron', {
// Auth events // Auth events
loginSuccess: (token: string) => ipcRenderer.send('login-success', token), loginSuccess: (token: string) => ipcRenderer.send('login-success', token),
logout: () => ipcRenderer.send('logout'), logout: () => ipcRenderer.send('logout'),
// Database operations
generateEncryptionKey: (userId: string) => ipcRenderer.invoke('generate-encryption-key', userId),
getUserEncryptionKey: (userId: string) => ipcRenderer.invoke('get-user-encryption-key', userId),
setUserEncryptionKey: (userId: string, encryptionKey: string) => ipcRenderer.invoke('set-user-encryption-key', userId, encryptionKey),
dbInitialize: (userId: string, encryptionKey: string) => ipcRenderer.invoke('db-initialize', userId, encryptionKey),
dbGetBooks: () => ipcRenderer.invoke('db-get-books'),
dbGetBook: (bookId: string) => ipcRenderer.invoke('db-get-book', bookId),
dbSaveBook: (book: any, authorId?: string) => ipcRenderer.invoke('db-save-book', book, authorId),
dbDeleteBook: (bookId: string) => ipcRenderer.invoke('db-delete-book', bookId),
dbSaveChapter: (chapter: any, bookId: string, contentId?: string) => ipcRenderer.invoke('db-save-chapter', chapter, bookId, contentId),
dbGetCharacters: (bookId: string) => ipcRenderer.invoke('db-get-characters', bookId),
dbSaveCharacter: (character: any, bookId: string) => ipcRenderer.invoke('db-save-character', character, bookId),
dbGetConversations: (bookId: string) => ipcRenderer.invoke('db-get-conversations', bookId),
dbSaveConversation: (conversation: any, bookId: string) => ipcRenderer.invoke('db-save-conversation', conversation, bookId),
dbGetSyncStatus: () => ipcRenderer.invoke('db-get-sync-status'),
dbGetPendingChanges: (limit?: number) => ipcRenderer.invoke('db-get-pending-changes', limit),
}); });

493
package-lock.json generated
View File

@@ -32,6 +32,7 @@
"next": "^16.0.3", "next": "^16.0.3",
"next-export-i18n": "^2.4.3", "next-export-i18n": "^2.4.3",
"next-intl": "^4.5.3", "next-intl": "^4.5.3",
"node-sqlite3-wasm": "^0.8.51",
"postcss": "^8.5.6", "postcss": "^8.5.6",
"react": "^19.2.0", "react": "^19.2.0",
"react-dom": "^19.2.0", "react-dom": "^19.2.0",
@@ -51,6 +52,8 @@
"concurrently": "^9.2.1", "concurrently": "^9.2.1",
"electron": "^39.2.1", "electron": "^39.2.1",
"electron-builder": "^26.0.12", "electron-builder": "^26.0.12",
"electron-rebuild": "^3.2.9",
"electronmon": "^2.0.4",
"tsx": "^4.20.6", "tsx": "^4.20.6",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"vite": "^7.2.2", "vite": "^7.2.2",
@@ -4760,6 +4763,28 @@
"node": ">= 10.0.0" "node": ">= 10.0.0"
} }
}, },
"node_modules/aproba": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz",
"integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==",
"dev": true,
"license": "ISC"
},
"node_modules/are-we-there-yet": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
"integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
"deprecated": "This package is no longer supported.",
"dev": true,
"license": "ISC",
"dependencies": {
"delegates": "^1.0.0",
"readable-stream": "^3.6.0"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/argparse": { "node_modules/argparse": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -4963,6 +4988,19 @@
"concat-map": "0.0.1" "concat-map": "0.0.1"
} }
}, },
"node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.28.0", "version": "4.28.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz",
@@ -5445,6 +5483,16 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"dev": true,
"license": "ISC",
"bin": {
"color-support": "bin.js"
}
},
"node_modules/combined-stream": { "node_modules/combined-stream": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -5668,6 +5716,13 @@
"node": ">=16 || 14 >=14.17" "node": ">=16 || 14 >=14.17"
} }
}, },
"node_modules/console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
"dev": true,
"license": "ISC"
},
"node_modules/convert-source-map": { "node_modules/convert-source-map": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
@@ -5915,6 +5970,13 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
"dev": true,
"license": "MIT"
},
"node_modules/detect-libc": { "node_modules/detect-libc": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -6286,6 +6348,97 @@
"node": ">= 10.0.0" "node": ">= 10.0.0"
} }
}, },
"node_modules/electron-rebuild": {
"version": "3.2.9",
"resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-3.2.9.tgz",
"integrity": "sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw==",
"deprecated": "Please use @electron/rebuild moving forward. There is no API change, just a package name change",
"dev": true,
"license": "MIT",
"dependencies": {
"@malept/cross-spawn-promise": "^2.0.0",
"chalk": "^4.0.0",
"debug": "^4.1.1",
"detect-libc": "^2.0.1",
"fs-extra": "^10.0.0",
"got": "^11.7.0",
"lzma-native": "^8.0.5",
"node-abi": "^3.0.0",
"node-api-version": "^0.1.4",
"node-gyp": "^9.0.0",
"ora": "^5.1.0",
"semver": "^7.3.5",
"tar": "^6.0.5",
"yargs": "^17.0.1"
},
"bin": {
"electron-rebuild": "lib/src/cli.js"
},
"engines": {
"node": ">=12.13.0"
}
},
"node_modules/electron-rebuild/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,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/electron-rebuild/node_modules/jsonfile": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
"dev": true,
"license": "MIT",
"dependencies": {
"universalify": "^2.0.0"
},
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/electron-rebuild/node_modules/node-api-version": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz",
"integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==",
"dev": true,
"license": "MIT",
"dependencies": {
"semver": "^7.3.5"
}
},
"node_modules/electron-rebuild/node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/electron-rebuild/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,
"license": "MIT",
"engines": {
"node": ">= 10.0.0"
}
},
"node_modules/electron-store": { "node_modules/electron-store": {
"version": "11.0.2", "version": "11.0.2",
"resolved": "https://registry.npmjs.org/electron-store/-/electron-store-11.0.2.tgz", "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-11.0.2.tgz",
@@ -6378,6 +6531,39 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/electronmon": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/electronmon/-/electronmon-2.0.4.tgz",
"integrity": "sha512-u6eDrvUbqa+wsnMrhG2vHmo5neL1owLg2e5i1avGWcOb4rHsUf9lSfbs0FvfPsBNpLxxlPO98nrMhAGV+zw/fQ==",
"dev": true,
"license": "ISC",
"dependencies": {
"chalk": "^3.0.0",
"import-from": "^3.0.0",
"runtime-required": "^1.1.0",
"watchboy": "^0.4.3"
},
"bin": {
"electronmon": "bin/cli.js"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/electronmon/node_modules/chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -6702,6 +6888,19 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/find-root": { "node_modules/find-root": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
@@ -6846,6 +7045,27 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/gauge": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
"integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
"deprecated": "This package is no longer supported.",
"dev": true,
"license": "ISC",
"dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.3",
"console-control-strings": "^1.1.0",
"has-unicode": "^2.0.1",
"signal-exit": "^3.0.7",
"string-width": "^4.2.3",
"strip-ansi": "^6.0.1",
"wide-align": "^1.1.5"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/gensync": { "node_modules/gensync": {
"version": "1.0.0-beta.2", "version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -7113,6 +7333,13 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
"dev": true,
"license": "ISC"
},
"node_modules/hasown": { "node_modules/hasown": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@@ -7305,6 +7532,29 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/import-from": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz",
"integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"resolve-from": "^5.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/import-from/node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/imurmurhash": { "node_modules/imurmurhash": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@@ -7434,6 +7684,16 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/is-unicode-supported": { "node_modules/is-unicode-supported": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
@@ -7935,6 +8195,13 @@
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"license": "MIT" "license": "MIT"
}, },
"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,
"license": "MIT"
},
"node_modules/log-symbols": { "node_modules/log-symbols": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
@@ -7975,6 +8242,32 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/lzma-native": {
"version": "8.0.6",
"resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz",
"integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"node-addon-api": "^3.1.0",
"node-gyp-build": "^4.2.1",
"readable-stream": "^3.6.0"
},
"bin": {
"lzmajs": "bin/lzmajs"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/lzma-native/node_modules/node-addon-api": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
"dev": true,
"license": "MIT"
},
"node_modules/magic-string": { "node_modules/magic-string": {
"version": "0.30.21", "version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -8110,6 +8403,33 @@
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=8.6"
}
},
"node_modules/micromatch/node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/mime": { "node_modules/mime": {
"version": "2.6.0", "version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
@@ -8592,12 +8912,69 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/node-gyp": {
"version": "9.4.1",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz",
"integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"env-paths": "^2.2.0",
"exponential-backoff": "^3.1.1",
"glob": "^7.1.4",
"graceful-fs": "^4.2.6",
"make-fetch-happen": "^10.0.3",
"nopt": "^6.0.0",
"npmlog": "^6.0.0",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"tar": "^6.1.2",
"which": "^2.0.2"
},
"bin": {
"node-gyp": "bin/node-gyp.js"
},
"engines": {
"node": "^12.13 || ^14.13 || >=16"
}
},
"node_modules/node-gyp-build": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
"integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
"dev": true,
"license": "MIT",
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
"node-gyp-build-test": "build-test.js"
}
},
"node_modules/node-gyp/node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.27", "version": "2.0.27",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
"integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/node-sqlite3-wasm": {
"version": "0.8.51",
"resolved": "https://registry.npmjs.org/node-sqlite3-wasm/-/node-sqlite3-wasm-0.8.51.tgz",
"integrity": "sha512-tbUWEZLrGJwfi6eE6Xw+6GYRIQne4/C7uyh76hDI1tD88JfnLQCqPED8IvW0FVfrMNYuhYkO5a10XjI1du1kLg==",
"license": "MIT"
},
"node_modules/nopt": { "node_modules/nopt": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
@@ -8614,6 +8991,19 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0" "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
} }
}, },
"node_modules/normalize-path": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
"integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"remove-trailing-separator": "^1.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/normalize-range": { "node_modules/normalize-range": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
@@ -8636,6 +9026,23 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/npmlog": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
"integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
"deprecated": "This package is no longer supported.",
"dev": true,
"license": "ISC",
"dependencies": {
"are-we-there-yet": "^3.0.0",
"console-control-strings": "^1.1.0",
"gauge": "^4.0.3",
"set-blocking": "^2.0.0"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/object-keys": { "node_modules/object-keys": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
@@ -8892,6 +9299,16 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/plist": { "node_modules/plist": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
@@ -10008,6 +10425,13 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
"integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
"dev": true,
"license": "ISC"
},
"node_modules/require-directory": { "node_modules/require-directory": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -10218,6 +10642,16 @@
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/runtime-required": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/runtime-required/-/runtime-required-1.1.0.tgz",
"integrity": "sha512-yX97f5E0WfNpcQnfVjap6vzQcvErkYYCx6eTK4siqGEdC8lglwypUFgZVTX7ShvIlgfkC4XGFl9O1KTYcff0pw==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/rxjs": { "node_modules/rxjs": {
"version": "7.8.2", "version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
@@ -10323,6 +10757,13 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"dev": true,
"license": "ISC"
},
"node_modules/set-cookie-parser": { "node_modules/set-cookie-parser": {
"version": "2.7.2", "version": "2.7.2",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
@@ -10961,6 +11402,19 @@
"tmp": "^0.2.0" "tmp": "^0.2.0"
} }
}, },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/toggle-selection": { "node_modules/toggle-selection": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
@@ -11102,6 +11556,19 @@
"node": ">= 4.0.0" "node": ">= 4.0.0"
} }
}, },
"node_modules/unixify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz",
"integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==",
"dev": true,
"license": "MIT",
"dependencies": {
"normalize-path": "^2.1.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/update-browserslist-db": { "node_modules/update-browserslist-db": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
@@ -11312,6 +11779,22 @@
"node": ">=20.0.0" "node": ">=20.0.0"
} }
}, },
"node_modules/watchboy": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/watchboy/-/watchboy-0.4.3.tgz",
"integrity": "sha512-GHs1HxwvxSMBsqd/WfTOZhj5gBdMqf5HQpfgtKxDfZRxrlYPDdVLRB61LCeRzJaWANmvSIMlfmRVDwVmJFgAKA==",
"dev": true,
"license": "ISC",
"dependencies": {
"lodash.difference": "^4.5.0",
"micromatch": "^4.0.2",
"pify": "^4.0.1",
"unixify": "^1.0.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/wcwidth": { "node_modules/wcwidth": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
@@ -11344,6 +11827,16 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/wide-align": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
"dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
"node_modules/wrap-ansi": { "node_modules/wrap-ansi": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",

View File

@@ -5,7 +5,7 @@
"type": "module", "type": "module",
"main": "dist/electron/main.js", "main": "dist/electron/main.js",
"scripts": { "scripts": {
"dev": "concurrently \"next dev -p 4000\" \"wait-on http://localhost:4000 && electron -r tsx/cjs electron/main.ts\"", "dev": "tsc -p tsconfig.electron.json && tsc -p tsconfig.preload.json && concurrently \"tsc -p tsconfig.electron.json -w\" \"tsc -p tsconfig.preload.json -w\" \"next dev -p 4000\" \"wait-on http://localhost:4000 && wait-on dist/electron/main.js && electron dist/electron/main.js\"",
"build:mac": "next build && tsc --project tsconfig.electron.json && tsc --project tsconfig.preload.json && electron-builder build --mac", "build:mac": "next build && tsc --project tsconfig.electron.json && tsc --project tsconfig.preload.json && electron-builder build --mac",
"build:win": "next build && tsc --project tsconfig.electron.json && tsc --project tsconfig.preload.json && electron-builder build --win", "build:win": "next build && tsc --project tsconfig.electron.json && tsc --project tsconfig.preload.json && electron-builder build --win",
"build:linux": "next build && tsc --project tsconfig.electron.json && tsc --project tsconfig.preload.json && electron-builder build --linux", "build:linux": "next build && tsc --project tsconfig.electron.json && tsc --project tsconfig.preload.json && electron-builder build --linux",
@@ -26,6 +26,8 @@
"concurrently": "^9.2.1", "concurrently": "^9.2.1",
"electron": "^39.2.1", "electron": "^39.2.1",
"electron-builder": "^26.0.12", "electron-builder": "^26.0.12",
"electron-rebuild": "^3.2.9",
"electronmon": "^2.0.4",
"tsx": "^4.20.6", "tsx": "^4.20.6",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"vite": "^7.2.2", "vite": "^7.2.2",
@@ -56,6 +58,7 @@
"next": "^16.0.3", "next": "^16.0.3",
"next-export-i18n": "^2.4.3", "next-export-i18n": "^2.4.3",
"next-intl": "^4.5.3", "next-intl": "^4.5.3",
"node-sqlite3-wasm": "^0.8.51",
"postcss": "^8.5.6", "postcss": "^8.5.6",
"react": "^19.2.0", "react": "^19.2.0",
"react-dom": "^19.2.0", "react-dom": "^19.2.0",

View File

@@ -20,6 +20,11 @@
"dist", "dist",
"src", "src",
".next", ".next",
"out" "out",
"lib",
"components",
"app",
"context",
"electron/preload.ts"
] ]
} }

View File

@@ -1,11 +1,20 @@
{ {
"extends": "./tsconfig.electron.json",
"compilerOptions": { "compilerOptions": {
"module": "CommonJS", "module": "CommonJS",
"moduleResolution": "node", "moduleResolution": "node",
"outDir": "dist/electron" "target": "ES2022",
"outDir": "dist/electron",
"lib": ["ES2022"],
"esModuleInterop": true,
"skipLibCheck": true,
"strict": true,
"resolveJsonModule": true,
"noEmit": false
}, },
"include": [ "include": [
"electron/preload.ts" "electron/preload.ts"
],
"exclude": [
"node_modules"
] ]
} }