import { contextBridge, ipcRenderer } from 'electron' const channels = { invoke: [ 'dll:init', 'dll:printer-info', 'dll:printer-status', 'dll:printer-reset', 'dll:printer-reject', 'dll:printer-read-card', 'dll:printer-eject-card', 'dll:printer-error-str', 'dll:job-create', 'dll:job-cancel', 'dll:usb-copy', 'poll:job-start', 'poll:job-stop', 'poll:usb-start', 'poll:usb-stop', 'poll:card-position-start', 'poll:card-position-stop', 'dialog:open-directory', 'dialog:open-file', 'fs:path-exists', 'fs:dir-size', 'fs:parse-soon', 'fs:resolve-network-hosts', 'fs:write-job-csv', 'secrets:get', 'secrets:set', 'config:get', 'config:set', 'shell:open-path', 'design:open', 'dll:reject-available' ] as const, on: ['job:poll-tick', 'usb:poll-tick', 'card:position-tick', 'app:trace'] as const } const cardsoonApi = { invoke(channel: (typeof channels.invoke)[number], ...args: unknown[]) { if (!(channels.invoke as readonly string[]).includes(channel)) { throw new Error(`IPC channel not allowed: ${channel}`) } return ipcRenderer.invoke(channel, ...args) }, on(channel: (typeof channels.on)[number], listener: (...args: unknown[]) => void) { if (!(channels.on as readonly string[]).includes(channel)) { throw new Error(`IPC event not allowed: ${channel}`) } const subscription = (_event: unknown, payload: unknown) => listener(payload) ipcRenderer.on(channel, subscription) return () => ipcRenderer.removeListener(channel, subscription) } } contextBridge.exposeInMainWorld('cardsoonApi', cardsoonApi)