Browse Source
- Create unified ElectronAPI interface in debug-electron.ts - Export SQLiteAPI, IPCRenderer, and ElectronEnv interfaces - Update Window.electron type declarations to use shared interface - Fix type conflicts between debug-electron.ts and ElectronPlatformService.ts This change improves type safety and maintainability by centralizing Electron API type definitions in a single location.sql-absurd-sql-further
8 changed files with 488 additions and 283 deletions
@ -1,123 +1,169 @@ |
|||
/** |
|||
* Debug utilities for Electron integration |
|||
* Helps verify the context bridge and SQLite functionality |
|||
* |
|||
* @author Matthew Raymer |
|||
*/ |
|||
|
|||
const debugLogger = { |
|||
log: (...args: unknown[]) => console.log('[Debug]', ...args), |
|||
error: (...args: unknown[]) => console.error('[Debug]', ...args), |
|||
info: (...args: unknown[]) => console.info('[Debug]', ...args), |
|||
warn: (...args: unknown[]) => console.warn('[Debug]', ...args), |
|||
debug: (...args: unknown[]) => console.debug('[Debug]', ...args) |
|||
}; |
|||
import { logger } from "./logger"; |
|||
|
|||
// Define the SQLite interface
|
|||
export interface SQLiteAPI { |
|||
isAvailable: () => Promise<boolean>; |
|||
echo: (value: string) => Promise<string>; |
|||
createConnection: (options: { |
|||
database: string; |
|||
version: number; |
|||
readOnly: boolean; |
|||
}) => Promise<void>; |
|||
closeConnection: (options: { database: string }) => Promise<void>; |
|||
query: (options: { statement: string }) => Promise<unknown>; |
|||
run: (options: { statement: string }) => Promise<unknown>; |
|||
execute: (options: { |
|||
statements: Array<{ statement: string }>; |
|||
}) => Promise<unknown>; |
|||
getPlatform: () => Promise<string>; |
|||
} |
|||
|
|||
// Define the IPC renderer interface
|
|||
export interface IPCRenderer { |
|||
on: (channel: string, func: (...args: unknown[]) => void) => void; |
|||
once: (channel: string, func: (...args: unknown[]) => void) => void; |
|||
send: (channel: string, ...args: unknown[]) => void; |
|||
invoke: (channel: string, ...args: unknown[]) => Promise<unknown>; |
|||
} |
|||
|
|||
// Define the environment interface
|
|||
export interface ElectronEnv { |
|||
platform: string; |
|||
isDev: boolean; |
|||
} |
|||
|
|||
// Define the complete electron interface
|
|||
export interface ElectronAPI { |
|||
sqlite: SQLiteAPI; |
|||
ipcRenderer: IPCRenderer; |
|||
env: ElectronEnv; |
|||
getPath: (pathType: string) => Promise<string>; |
|||
getBasePath: () => Promise<string>; |
|||
} |
|||
|
|||
// Define the window.electron interface
|
|||
declare global { |
|||
interface Window { |
|||
electron: ElectronAPI; |
|||
} |
|||
} |
|||
|
|||
export async function verifyElectronAPI(): Promise<void> { |
|||
debugLogger.info('Verifying Electron API exposure...'); |
|||
logger.info("[Debug] Verifying Electron API exposure..."); |
|||
|
|||
// Check if window.electron exists
|
|||
if (!window.electron) { |
|||
throw new Error('window.electron is not defined'); |
|||
throw new Error("window.electron is not defined"); |
|||
} |
|||
debugLogger.info('window.electron is available'); |
|||
logger.info("[Debug] window.electron is available"); |
|||
|
|||
// Verify IPC renderer
|
|||
if (!window.electron.ipcRenderer) { |
|||
throw new Error('IPC renderer is not available'); |
|||
throw new Error("IPC renderer is not available"); |
|||
} |
|||
debugLogger.info('IPC renderer is available with methods:', { |
|||
hasOn: typeof window.electron.ipcRenderer.on === 'function', |
|||
hasOnce: typeof window.electron.ipcRenderer.once === 'function', |
|||
hasSend: typeof window.electron.ipcRenderer.send === 'function', |
|||
hasInvoke: typeof window.electron.ipcRenderer.invoke === 'function' |
|||
logger.info("[Debug] IPC renderer is available with methods:", { |
|||
hasOn: typeof window.electron.ipcRenderer.on === "function", |
|||
hasOnce: typeof window.electron.ipcRenderer.once === "function", |
|||
hasSend: typeof window.electron.ipcRenderer.send === "function", |
|||
hasInvoke: typeof window.electron.ipcRenderer.invoke === "function", |
|||
}); |
|||
|
|||
// Verify SQLite API
|
|||
if (!window.electron.sqlite) { |
|||
throw new Error('SQLite API is not available'); |
|||
throw new Error("SQLite API is not available"); |
|||
} |
|||
debugLogger.info('SQLite API is available with methods:', { |
|||
hasIsAvailable: typeof window.electron.sqlite.isAvailable === 'function', |
|||
hasEcho: typeof window.electron.sqlite.echo === 'function', |
|||
hasCreateConnection: typeof window.electron.sqlite.createConnection === 'function', |
|||
hasCloseConnection: typeof window.electron.sqlite.closeConnection === 'function', |
|||
hasQuery: typeof window.electron.sqlite.query === 'function', |
|||
hasRun: typeof window.electron.sqlite.run === 'function', |
|||
hasExecute: typeof window.electron.sqlite.execute === 'function', |
|||
hasGetPlatform: typeof window.electron.sqlite.getPlatform === 'function' |
|||
logger.info("[Debug] SQLite API is available with methods:", { |
|||
hasIsAvailable: typeof window.electron.sqlite.isAvailable === "function", |
|||
hasEcho: typeof window.electron.sqlite.echo === "function", |
|||
hasCreateConnection: |
|||
typeof window.electron.sqlite.createConnection === "function", |
|||
hasCloseConnection: |
|||
typeof window.electron.sqlite.closeConnection === "function", |
|||
hasQuery: typeof window.electron.sqlite.query === "function", |
|||
hasRun: typeof window.electron.sqlite.run === "function", |
|||
hasExecute: typeof window.electron.sqlite.execute === "function", |
|||
hasGetPlatform: typeof window.electron.sqlite.getPlatform === "function", |
|||
}); |
|||
|
|||
// Test SQLite availability
|
|||
try { |
|||
const isAvailable = await window.electron.sqlite.isAvailable(); |
|||
debugLogger.info('SQLite availability check:', { isAvailable }); |
|||
logger.info("[Debug] SQLite availability check:", { isAvailable }); |
|||
} catch (error) { |
|||
debugLogger.error('SQLite availability check failed:', error); |
|||
logger.error("[Debug] SQLite availability check failed:", error); |
|||
} |
|||
|
|||
// Test echo functionality
|
|||
try { |
|||
const echoResult = await window.electron.sqlite.echo('test'); |
|||
debugLogger.info('SQLite echo test:', echoResult); |
|||
const echoResult = await window.electron.sqlite.echo("test"); |
|||
logger.info("[Debug] SQLite echo test:", echoResult); |
|||
} catch (error) { |
|||
debugLogger.error('SQLite echo test failed:', error); |
|||
logger.error("[Debug] SQLite echo test failed:", error); |
|||
} |
|||
|
|||
// Verify environment
|
|||
debugLogger.info('Environment:', { |
|||
logger.info("[Debug] Environment:", { |
|||
platform: window.electron.env.platform, |
|||
isDev: window.electron.env.isDev |
|||
isDev: window.electron.env.isDev, |
|||
}); |
|||
|
|||
debugLogger.info('Electron API verification complete'); |
|||
logger.info("[Debug] Electron API verification complete"); |
|||
} |
|||
|
|||
// Export a function to test SQLite operations
|
|||
export async function testSQLiteOperations(): Promise<void> { |
|||
debugLogger.info('Testing SQLite operations...'); |
|||
logger.info("[Debug] Testing SQLite operations..."); |
|||
|
|||
try { |
|||
// Test connection creation
|
|||
debugLogger.info('Creating test connection...'); |
|||
logger.info("[Debug] Creating test connection..."); |
|||
await window.electron.sqlite.createConnection({ |
|||
database: 'test', |
|||
database: "test", |
|||
version: 1, |
|||
readOnly: false |
|||
readOnly: false, |
|||
}); |
|||
debugLogger.info('Test connection created successfully'); |
|||
logger.info("[Debug] Test connection created successfully"); |
|||
|
|||
// Test query
|
|||
debugLogger.info('Testing query operation...'); |
|||
logger.info("[Debug] Testing query operation..."); |
|||
const queryResult = await window.electron.sqlite.query({ |
|||
statement: 'SELECT 1 as test' |
|||
statement: "SELECT 1 as test", |
|||
}); |
|||
debugLogger.info('Query test result:', queryResult); |
|||
logger.info("[Debug] Query test result:", queryResult); |
|||
|
|||
// Test run
|
|||
debugLogger.info('Testing run operation...'); |
|||
logger.info("[Debug] Testing run operation..."); |
|||
const runResult = await window.electron.sqlite.run({ |
|||
statement: 'CREATE TABLE IF NOT EXISTS test_table (id INTEGER PRIMARY KEY)' |
|||
statement: |
|||
"CREATE TABLE IF NOT EXISTS test_table (id INTEGER PRIMARY KEY)", |
|||
}); |
|||
debugLogger.info('Run test result:', runResult); |
|||
logger.info("[Debug] Run test result:", runResult); |
|||
|
|||
// Test execute
|
|||
debugLogger.info('Testing execute operation...'); |
|||
logger.info("[Debug] Testing execute operation..."); |
|||
const executeResult = await window.electron.sqlite.execute({ |
|||
statements: [ |
|||
{ statement: 'INSERT INTO test_table (id) VALUES (1)' }, |
|||
{ statement: 'SELECT * FROM test_table' } |
|||
] |
|||
{ statement: "INSERT INTO test_table (id) VALUES (1)" }, |
|||
{ statement: "SELECT * FROM test_table" }, |
|||
], |
|||
}); |
|||
debugLogger.info('Execute test result:', executeResult); |
|||
logger.info("[Debug] Execute test result:", executeResult); |
|||
|
|||
// Clean up
|
|||
debugLogger.info('Closing test connection...'); |
|||
await window.electron.sqlite.closeConnection({ database: 'test' }); |
|||
debugLogger.info('Test connection closed'); |
|||
|
|||
logger.info("[Debug] Closing test connection..."); |
|||
await window.electron.sqlite.closeConnection({ database: "test" }); |
|||
logger.info("[Debug] Test connection closed"); |
|||
} catch (error) { |
|||
debugLogger.error('SQLite operation test failed:', error); |
|||
logger.error("[Debug] SQLite operation test failed:", error); |
|||
throw error; |
|||
} |
|||
|
|||
debugLogger.info('SQLite operations test complete'); |
|||
} |
|||
logger.info("[Debug] SQLite operations test complete"); |
|||
} |
|||
|
Loading…
Reference in new issue