import { contextBridge, ipcRenderer } from 'electron'; import compressing from 'compressing'; import os from 'os'; import fse from 'fs-extra'; import path from 'path'; import childProcess from 'child_process'; import { useLoading } from './loading'; import { domReady } from './utils'; import { ContextBridgeApi } from './types'; const { appendLoading, removeLoading } = useLoading(); (async () => { await domReady(); // appendLoading(); })(); // --------- Expose some API to the Renderer process. --------- const networkInterfaces = os.networkInterfaces(); const networkInterface = networkInterfaces.en0 ? networkInterfaces.en0[0] : (networkInterfaces as any).WLAN[0]; const env = Object.assign({}, process.env); const contextBridgeApi: ContextBridgeApi = { __dirname, userId: networkInterface.mac, userName: env.USER || '', fse, path, compressing, childProcess, buffer: Buffer, ipcRenderer: withPrototype(ipcRenderer) as import('electron').IpcRenderer, removeLoading, }; contextBridge.exposeInMainWorld('bridge', contextBridgeApi); // `exposeInMainWorld` can't detect attributes and methods of `prototype`, manually patching it. function withPrototype(obj: Record) { const protos = Object.getPrototypeOf(obj); for (const [key, value] of Object.entries(protos)) { if (Object.prototype.hasOwnProperty.call(obj, key)) continue; if (typeof value === 'function') { // Some native APIs, like `NodeJS.EventEmitter['on']`, don't work in the Renderer process. Wrapping them into a function. obj[key] = function (...args: any) { return value.call(obj, ...args); }; } else { obj[key] = value; } } return obj; }