build: generate desktop application release artifacts and update project configuration

This commit is contained in:
Firman Ramdhani
2026-04-05 22:33:08 +07:00
parent 9b7e027024
commit a13feb1c51
20 changed files with 3183 additions and 31 deletions
+81
View File
@@ -0,0 +1,81 @@
import { contextBridge, ipcRenderer } from 'electron';
// ─── Type definitions for the exposed API ───────────────────────
// These mirror the types in apps/web/src/types/electron.d.ts
export interface PrintResult {
success: boolean;
failureReason?: string;
}
export interface ProgressInfo {
total: number;
delta: number;
transferred: number;
percent: number;
bytesPerSecond: number;
}
export interface UpdateInfo {
version: string;
releaseDate: string;
releaseName?: string | null;
releaseNotes?: string | null;
}
// ─── Helper: create a one-way event listener with cleanup ───────
function createEventSubscription<T>(channel: string) {
return (callback: (data: T) => void): (() => void) => {
const handler = (_event: Electron.IpcRendererEvent, data: T) => callback(data);
ipcRenderer.on(channel, handler);
// Return an unsubscribe function
return () => {
ipcRenderer.removeListener(channel, handler);
};
};
}
// ─── Exposed API ────────────────────────────────────────────────
// SECURITY: Only expose specific methods. Never expose ipcRenderer directly.
const electronAPI = {
// ── Printing ────────────────────────────────────────────────
getPrinters: (): Promise<Electron.PrinterInfo[]> => {
return ipcRenderer.invoke('printer:get-list');
},
print: (options?: Electron.WebContentsPrintOptions): Promise<PrintResult> => {
return ipcRenderer.invoke('printer:print', options);
},
// ── Auto-Update: Commands ───────────────────────────────────
checkForUpdates: (): void => {
ipcRenderer.invoke('updater:check');
},
installUpdate: (): void => {
ipcRenderer.send('updater:install');
},
// ── Auto-Update: Event Subscriptions ────────────────────────
// Each returns an unsubscribe function for cleanup in useEffect.
onUpdateChecking: createEventSubscription<void>('updater:checking'),
onUpdateAvailable: createEventSubscription<UpdateInfo>('updater:available'),
onUpdateNotAvailable: createEventSubscription<UpdateInfo>('updater:not-available'),
onDownloadProgress: createEventSubscription<ProgressInfo>('updater:progress'),
onUpdateDownloaded: createEventSubscription<UpdateInfo>('updater:downloaded'),
onUpdateError: createEventSubscription<string>('updater:error'),
};
// ─── Expose to renderer via contextBridge ───────────────────────
contextBridge.exposeInMainWorld('electronAPI', electronAPI);
// Export the type for reference (used by electron.d.ts in apps/web)
export type ElectronAPI = typeof electronAPI;