@itwin/core-electron 3.5.0-dev.7 → 3.6.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,68 @@
1
1
  # Change Log - @itwin/core-electron
2
2
 
3
- This log was last generated on Thu, 01 Sep 2022 14:37:22 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 30 Nov 2022 14:28:19 GMT and should not be manually modified.
4
+
5
+ ## 3.4.7
6
+ Wed, 30 Nov 2022 14:28:19 GMT
7
+
8
+ _Version update only_
9
+
10
+ ## 3.4.6
11
+ Tue, 22 Nov 2022 14:24:19 GMT
12
+
13
+ _Version update only_
14
+
15
+ ## 3.4.5
16
+ Thu, 17 Nov 2022 21:32:50 GMT
17
+
18
+ _Version update only_
19
+
20
+ ## 3.4.4
21
+ Thu, 10 Nov 2022 19:32:17 GMT
22
+
23
+ _Version update only_
24
+
25
+ ## 3.4.3
26
+ Fri, 28 Oct 2022 13:34:57 GMT
27
+
28
+ _Version update only_
29
+
30
+ ## 3.4.2
31
+ Mon, 24 Oct 2022 13:23:45 GMT
32
+
33
+ _Version update only_
34
+
35
+ ## 3.4.1
36
+ Mon, 17 Oct 2022 20:06:51 GMT
37
+
38
+ _Version update only_
39
+
40
+ ## 3.4.0
41
+ Thu, 13 Oct 2022 20:24:47 GMT
42
+
43
+ ### Updates
44
+
45
+ - Add support for Electron versions 15, 16, and 17.
46
+ - Fix ElectronApp.shutdown not terminating RPC interfaces.
47
+ - Fix window setting not being set after opening new main window.
48
+ - Set supportFetchAPI to true for iTwin.js's custom Electron scheme
49
+ - Updated Node types declaration to support latest v16
50
+ - Setup electron backend code tests.
51
+
52
+ ## 3.3.5
53
+ Tue, 27 Sep 2022 11:50:59 GMT
54
+
55
+ _Version update only_
56
+
57
+ ## 3.3.4
58
+ Thu, 08 Sep 2022 19:00:04 GMT
59
+
60
+ _Version update only_
61
+
62
+ ## 3.3.3
63
+ Tue, 06 Sep 2022 20:54:19 GMT
64
+
65
+ _Version update only_
4
66
 
5
67
  ## 3.3.2
6
68
  Thu, 01 Sep 2022 14:37:22 GMT
@@ -1,7 +1,7 @@
1
1
  import type { BrowserWindow, BrowserWindowConstructorOptions } from "electron";
2
+ import type * as ElectronModule from "electron";
2
3
  import { IpcHandler, NativeHostOpts } from "@itwin/core-backend";
3
4
  import { RpcConfiguration, RpcInterfaceDefinition } from "@itwin/core-common";
4
- import * as ElectronModuleExports from "electron";
5
5
  /**
6
6
  * Options for [[ElectronHost.startup]]
7
7
  * @beta
@@ -57,7 +57,7 @@ export declare class ElectronHost {
57
57
  static rpcConfig: RpcConfiguration;
58
58
  static get ipcMain(): Electron.IpcMain;
59
59
  static get app(): Electron.App;
60
- static get electron(): typeof ElectronModuleExports;
60
+ static get electron(): typeof ElectronModule;
61
61
  private constructor();
62
62
  /**
63
63
  * Converts an "electron://frontend/" URL to an absolute file path.
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronHost.d.ts","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,+BAA+B,EAAE,MAAM,UAAU,CAAC;AAI/E,OAAO,EAAE,UAAU,EAAuB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAA8D,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAM1I,OAAO,KAAK,qBAAqB,MAAM,UAAU,CAAC;AAuBlD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2IAA2I;IAC3I,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,aAAa,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACzC,wDAAwD;IACxD,WAAW,CAAC,EAAE,CAAC,OAAO,UAAU,CAAC,EAAE,CAAC;CACrC;AAED,YAAY;AACZ,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED,YAAY;AACZ,MAAM,WAAW,yBAA0B,SAAQ,+BAA+B;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,CAAC,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,sBAAsB,CAAC,CAAC;CACjF;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAc;IACjC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAU;IAC3C,OAAO,CAAC,MAAM,CAAC,SAAS,CAA+B;IACvD,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAA0B;IAC1D,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAgB;IAC3C,OAAc,gBAAgB,EAAE,MAAM,CAAC;IACvC,OAAc,WAAW,EAAE,MAAM,CAAC;IAClC,OAAc,WAAW,EAAE,MAAM,CAAC;IAClC,OAAc,SAAS,EAAE,gBAAgB,CAAC;IAC1C,WAAkB,OAAO,qBAAsC;IAC/D,WAAkB,GAAG,iBAAkC;IACvD,WAAkB,QAAQ,iCAA6B;IAEvD,OAAO;IAEP;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAmB/B,OAAO,CAAC,MAAM,CAAC,WAAW;IAuD1B,qDAAqD;IACrD,WAAkB,UAAU,8BAA+B;IAE3D,0FAA0F;WAC5E,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAK9F,wFAAwF;WAC1E,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAIhF;;;OAGG;WACiB,cAAc,CAAC,aAAa,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC5F,WAAkB,OAAO,YAAsC;IAE/D;;;;;;OAMG;WACiB,OAAO,CAAC,IAAI,CAAC,EAAE,gBAAgB;CAmCpD"}
1
+ {"version":3,"file":"ElectronHost.d.ts","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,+BAA+B,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,KAAK,KAAK,cAAc,MAAM,UAAU,CAAC;AAKhD,OAAO,EAAE,UAAU,EAAuB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAA8D,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAyB1I;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2IAA2I;IAC3I,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,aAAa,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACzC,wDAAwD;IACxD,WAAW,CAAC,EAAE,CAAC,OAAO,UAAU,CAAC,EAAE,CAAC;CACrC;AAED,YAAY;AACZ,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED,YAAY;AACZ,MAAM,WAAW,yBAA0B,SAAQ,+BAA+B;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,CAAC,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,sBAAsB,CAAC,CAAC;CACjF;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAc;IACjC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAU;IAC3C,OAAO,CAAC,MAAM,CAAC,SAAS,CAAwB;IAChD,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAA0B;IAC1D,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAgB;IAC3C,OAAc,gBAAgB,EAAE,MAAM,CAAC;IACvC,OAAc,WAAW,EAAE,MAAM,CAAC;IAClC,OAAc,WAAW,EAAE,MAAM,CAAC;IAClC,OAAc,SAAS,EAAE,gBAAgB,CAAC;IAC1C,WAAkB,OAAO,qBAAsC;IAC/D,WAAkB,GAAG,iBAAkC;IACvD,WAAkB,QAAQ,0BAA6B;IAEvD,OAAO;IAEP;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAmB/B,OAAO,CAAC,MAAM,CAAC,WAAW;IAuD1B,qDAAqD;IACrD,WAAkB,UAAU,8BAA+B;IAE3D,0FAA0F;WAC5E,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAK9F,wFAAwF;WAC1E,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAIhF;;;OAGG;WACiB,cAAc,CAAC,aAAa,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC5F,WAAkB,OAAO,YAAsC;IAE/D;;;;;;OAMG;WACiB,OAAO,CAAC,IAAI,CAAC,EAAE,gBAAgB;CAmCpD"}
@@ -11,6 +11,7 @@ const core_bentley_1 = require("@itwin/core-bentley");
11
11
  const core_backend_1 = require("@itwin/core-backend");
12
12
  const core_common_1 = require("@itwin/core-common");
13
13
  const ElectronRpcManager_1 = require("../common/ElectronRpcManager");
14
+ const ElectronIpcInterface_1 = require("../common/ElectronIpcInterface");
14
15
  // cSpell:ignore signin devserver webcontents copyfile unmaximize eopt
15
16
  class ElectronIpc {
16
17
  addListener(channel, listener) {
@@ -49,7 +50,7 @@ class ElectronHost {
49
50
  */
50
51
  static parseElectronUrl(requestedUrl) {
51
52
  // Note that the "frontend/" path is arbitrary - this is just so we can handle *some* relative URLs...
52
- let assetPath = requestedUrl.substr(this._electronFrontend.length);
53
+ let assetPath = requestedUrl.substring(this._electronFrontend.length);
53
54
  if (assetPath.length === 0)
54
55
  assetPath = "index.html";
55
56
  assetPath = path.normalize(`${this.webResourcesPath}/${assetPath}`);
@@ -200,29 +201,21 @@ class ElectronHost {
200
201
  opts.ipcHost.socket = this._ipc;
201
202
  await core_backend_1.NativeHost.startup(opts);
202
203
  if (core_backend_1.IpcHost.isValid) {
203
- ElectronAppHandler.register();
204
+ ElectronDialogHandler.register();
204
205
  (_j = (_h = opts.electronHost) === null || _h === void 0 ? void 0 : _h.ipcHandlers) === null || _j === void 0 ? void 0 : _j.forEach((ipc) => ipc.register());
205
206
  }
206
207
  }
207
208
  }
208
209
  exports.ElectronHost = ElectronHost;
209
210
  ElectronHost._electronFrontend = "electron://frontend/";
210
- class ElectronAppHandler extends core_backend_1.IpcHandler {
211
- get channelName() { return "electron-safe"; }
212
- async callElectron(member, method, ...args) {
213
- let allowedMethods = [];
214
- if (member === "dialog") {
215
- const methods = ["showMessageBox", "showOpenDialog", "showSaveDialog"];
216
- allowedMethods = methods;
217
- }
218
- if (allowedMethods.indexOf(method) >= 0) {
219
- const electronMember = ElectronHost.electron[member];
220
- const func = electronMember[method];
221
- if (typeof func === "function") {
222
- return func.call(electronMember, ...args);
223
- }
224
- }
225
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.FunctionNotFound, `Method ${method} not found electron.${member}`);
211
+ class ElectronDialogHandler extends core_backend_1.IpcHandler {
212
+ get channelName() { return ElectronIpcInterface_1.dialogChannel; }
213
+ async callDialog(method, ...args) {
214
+ const dialog = ElectronHost.electron.dialog;
215
+ const dialogMethod = dialog[method];
216
+ if (typeof dialogMethod !== "function")
217
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.FunctionNotFound, `illegal electron dialog method`);
218
+ return dialogMethod.call(dialog, ...args);
226
219
  }
227
220
  }
228
221
  //# sourceMappingURL=ElectronHost.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronHost.js","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n// Note: only import types! Does not create a `require(\"electron\")` in JavaScript after transpiling. That's important so this file can\r\n// be imported by apps that sometimes use Electron and sometimes not. Call to `ElectronBackend.initialize`\r\n// will do the necessary `require(\"electron\")`\r\n// IMPORTANT: Do not call or construct any of these imports. Otherwise, a require(\"electron\") call will be emitted at top level.\r\n// Instead, use `ElectronHost.electron.<type>`\r\n\r\nimport type { BrowserWindow, BrowserWindowConstructorOptions } from \"electron\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { BeDuration, IModelStatus, ProcessDetector } from \"@itwin/core-bentley\";\r\nimport { IpcHandler, IpcHost, NativeHost, NativeHostOpts } from \"@itwin/core-backend\";\r\nimport { IModelError, IpcListener, IpcSocketBackend, RemoveFunction, RpcConfiguration, RpcInterfaceDefinition } from \"@itwin/core-common\";\r\nimport { ElectronRpcConfiguration, ElectronRpcManager } from \"../common/ElectronRpcManager\";\r\nimport { DialogModuleMethod } from \"../common/ElectronIpcInterface\";\r\n\r\n// This will not be transpiled into JavaScript files as long as it isn't used for more than it's type definition.\r\n// See: https://www.typescriptlang.org/docs/handbook/modules.html#optional-module-loading-and-other-advanced-loading-scenarios\r\nimport * as ElectronModuleExports from \"electron\";\r\n\r\n// cSpell:ignore signin devserver webcontents copyfile unmaximize eopt\r\n\r\nclass ElectronIpc implements IpcSocketBackend {\r\n public addListener(channel: string, listener: IpcListener): RemoveFunction {\r\n ElectronHost.ipcMain.addListener(channel, listener);\r\n return () => ElectronHost.ipcMain.removeListener(channel, listener);\r\n }\r\n public removeListener(channel: string, listener: IpcListener) {\r\n ElectronHost.ipcMain.removeListener(channel, listener);\r\n }\r\n public send(channel: string, ...args: any[]): void {\r\n const window = ElectronHost.mainWindow ?? ElectronHost.electron.BrowserWindow.getAllWindows()[0];\r\n window?.webContents.send(channel, ...args);\r\n }\r\n public handle(channel: string, listener: (evt: any, ...args: any[]) => Promise<any>): RemoveFunction {\r\n ElectronHost.ipcMain.removeHandler(channel); // make sure there's not already a handler registered\r\n ElectronHost.ipcMain.handle(channel, listener);\r\n return () => ElectronHost.ipcMain.removeHandler(channel);\r\n }\r\n}\r\n\r\n/**\r\n * Options for [[ElectronHost.startup]]\r\n * @beta\r\n */\r\nexport interface ElectronHostOptions {\r\n /** the path to find web resources */\r\n webResourcesPath?: string;\r\n /** filename for the app's icon, relative to [[webResourcesPath]] */\r\n iconName?: string;\r\n /** name of frontend url to open. */\r\n frontendURL?: string;\r\n /** use a development server rather than the \"electron\" protocol for loading frontend (see https://www.electronjs.org/docs/api/protocol) */\r\n developmentServer?: boolean;\r\n /** port number for development server. Default is 3000 */\r\n frontendPort?: number;\r\n /** list of RPC interface definitions to register */\r\n rpcInterfaces?: RpcInterfaceDefinition[];\r\n /** list of [IpcHandler]($common) classes to register */\r\n ipcHandlers?: (typeof IpcHandler)[];\r\n}\r\n\r\n/** @beta */\r\nexport interface ElectronHostOpts extends NativeHostOpts {\r\n electronHost?: ElectronHostOptions;\r\n}\r\n\r\n/** @beta */\r\nexport interface ElectronHostWindowOptions extends BrowserWindowConstructorOptions {\r\n storeWindowName?: string;\r\n /** The style of window title bar. Default is `default`. */\r\n titleBarStyle?: (\"default\" | \"hidden\" | \"hiddenInset\" | \"customButtonsOnHover\");\r\n}\r\n\r\n/** the size and position of a window as stored in the settings file.\r\n * @beta\r\n */\r\nexport interface WindowSizeAndPositionProps {\r\n width: number;\r\n height: number;\r\n x: number;\r\n y: number;\r\n}\r\n\r\n/**\r\n * The backend for Electron-based desktop applications\r\n * @beta\r\n */\r\nexport class ElectronHost {\r\n private static _ipc: ElectronIpc;\r\n private static _developmentServer: boolean;\r\n private static _electron: typeof ElectronModuleExports;\r\n private static _electronFrontend = \"electron://frontend/\";\r\n private static _mainWindow?: BrowserWindow;\r\n public static webResourcesPath: string;\r\n public static appIconPath: string;\r\n public static frontendURL: string;\r\n public static rpcConfig: RpcConfiguration;\r\n public static get ipcMain() { return this._electron?.ipcMain; }\r\n public static get app() { return this._electron?.app; }\r\n public static get electron() { return this._electron; }\r\n\r\n private constructor() { }\r\n\r\n /**\r\n * Converts an \"electron://frontend/\" URL to an absolute file path.\r\n *\r\n * We use this protocol in production builds because our frontend must be built with absolute URLs,\r\n * however, since we're loading everything directly from the install directory, we cannot know the\r\n * absolute path at build time.\r\n */\r\n private static parseElectronUrl(requestedUrl: string): string {\r\n // Note that the \"frontend/\" path is arbitrary - this is just so we can handle *some* relative URLs...\r\n let assetPath = requestedUrl.substr(this._electronFrontend.length);\r\n if (assetPath.length === 0)\r\n assetPath = \"index.html\";\r\n assetPath = path.normalize(`${this.webResourcesPath}/${assetPath}`);\r\n // File protocols don't follow symlinks, so we need to resolve this to a real path.\r\n // However, if the file doesn't exist, it's fine to return an invalid path here - the request will just fail with net::ERR_FILE_NOT_FOUND\r\n try {\r\n assetPath = fs.realpathSync(assetPath);\r\n } catch (error) {\r\n // eslint-disable-next-line no-console\r\n // console.warn(`WARNING: Frontend requested \"${requestedUrl}\", but ${assetPath} does not exist`);\r\n }\r\n if (!assetPath.startsWith(this.webResourcesPath))\r\n throw new Error(`Access to files outside installation directory (${this.webResourcesPath}) is prohibited`);\r\n return assetPath;\r\n }\r\n\r\n private static _openWindow(options?: ElectronHostWindowOptions) {\r\n const opts: BrowserWindowConstructorOptions = {\r\n ...options,\r\n autoHideMenuBar: true,\r\n icon: this.appIconPath,\r\n webPreferences: {\r\n ...options?.webPreferences,\r\n\r\n // These web preference variables should not be overriden by the ElectronHostWindowOptions\r\n preload: require.resolve(/* webpack: copyfile */\"./ElectronPreload.js\"),\r\n experimentalFeatures: false,\r\n nodeIntegration: false,\r\n contextIsolation: true,\r\n sandbox: true,\r\n nativeWindowOpen: true,\r\n nodeIntegrationInWorker: false,\r\n nodeIntegrationInSubFrames: false,\r\n },\r\n };\r\n\r\n this._mainWindow = new (this.electron.BrowserWindow)(opts);\r\n ElectronRpcConfiguration.targetWindowId = this._mainWindow.id;\r\n this._mainWindow.on(\"closed\", () => this._mainWindow = undefined);\r\n this._mainWindow.loadURL(this.frontendURL); // eslint-disable-line @typescript-eslint/no-floating-promises\r\n\r\n /** Monitors and saves main window size, position and maximized state */\r\n if (options?.storeWindowName) {\r\n const mainWindow = this._mainWindow;\r\n const name = options.storeWindowName;\r\n const saveWindowPosition = () => {\r\n const resolution = mainWindow.getSize();\r\n const position = mainWindow.getPosition();\r\n const pos: WindowSizeAndPositionProps = {\r\n width: resolution[0],\r\n height: resolution[1],\r\n x: position[0],\r\n y: position[1],\r\n };\r\n NativeHost.settingsStore.setData(`windowPos-${name}`, JSON.stringify(pos));\r\n };\r\n const saveMaximized = (maximized: boolean) => {\r\n if (!maximized)\r\n saveWindowPosition();\r\n NativeHost.settingsStore.setData(`windowMaximized-${name}`, maximized);\r\n };\r\n\r\n mainWindow.on(\"resized\", () => saveWindowPosition());\r\n mainWindow.on(\"moved\", () => saveWindowPosition());\r\n mainWindow.on(\"maximize\", () => saveMaximized(true));\r\n mainWindow.on(\"unmaximize\", () => saveMaximized(false));\r\n\r\n saveMaximized(mainWindow.isMaximized());\r\n }\r\n }\r\n\r\n /** The \"main\" BrowserWindow for this application. */\r\n public static get mainWindow() { return this._mainWindow; }\r\n\r\n /** Gets window size and position for a window, by name, from settings file, if present */\r\n public static getWindowSizeSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`windowPos-${windowName}`);\r\n return saved ? JSON.parse(saved) as WindowSizeAndPositionProps : undefined;\r\n }\r\n\r\n /** Gets \"window maximized\" flag for a window, by name, from settings file if present */\r\n public static getWindowMaximizedSetting(windowName: string): boolean | undefined {\r\n return NativeHost.settingsStore.getBoolean(`windowMaximized-${windowName}`);\r\n }\r\n\r\n /**\r\n * Open the main Window when the app is ready.\r\n * @param windowOptions Options for constructing the main BrowserWindow. See: https://electronjs.org/docs/api/browser-window#new-browserwindowoptions\r\n */\r\n public static async openMainWindow(windowOptions?: ElectronHostWindowOptions): Promise<void> {\r\n const app = this.app;\r\n // quit the application when all windows are closed (unless we're running on MacOS)\r\n app.on(\"window-all-closed\", () => {\r\n if (process.platform !== \"darwin\")\r\n app.quit();\r\n });\r\n\r\n // re-open the main window if it was closed and the app is re-activated (this is the normal MacOS behavior)\r\n app.on(\"activate\", () => {\r\n if (!this._mainWindow)\r\n this._openWindow(windowOptions);\r\n });\r\n\r\n if (this._developmentServer) {\r\n // Occasionally, the electron backend may start before the webpack devserver has even started.\r\n // If this happens, we'll just retry and keep reloading the page.\r\n app.on(\"web-contents-created\", (_e, webcontents) => {\r\n webcontents.on(\"did-fail-load\", async (_event, errorCode, _errorDescription, _validatedURL, isMainFrame) => {\r\n // errorCode -102 is CONNECTION_REFUSED - see https://cs.chromium.org/chromium/src/net/base/net_error_list.h\r\n if (isMainFrame && errorCode === -102) {\r\n await BeDuration.wait(100);\r\n webcontents.reload();\r\n }\r\n });\r\n });\r\n }\r\n\r\n await app.whenReady();\r\n\r\n if (!this._developmentServer) {\r\n // handle any \"electron://\" requests and redirect them to \"file://\" URLs\r\n this.electron.protocol.registerFileProtocol(\"electron\", (request, callback) => callback(this.parseElectronUrl(request.url))); // eslint-disable-line @typescript-eslint/no-var-requires\r\n }\r\n\r\n this._openWindow(windowOptions);\r\n }\r\n\r\n public static get isValid() { return this._ipc !== undefined; }\r\n\r\n /**\r\n * Initialize the backend of an Electron app.\r\n * This method configures the backend for all of the inter-process communication (RPC and IPC) for an\r\n * Electron app. It should be called from your Electron main function.\r\n * @param opts Options that control aspects of your backend.\r\n * @note This method must only be called from the backend of an Electron app (i.e. when [ProcessDetector.isElectronAppBackend]($bentley) is `true`).\r\n */\r\n public static async startup(opts?: ElectronHostOpts) {\r\n if (!ProcessDetector.isElectronAppBackend)\r\n throw new Error(\"Not running under Electron\");\r\n\r\n if (!this.isValid) {\r\n this._electron = require(\"electron\");\r\n this._ipc = new ElectronIpc();\r\n const app = this.app;\r\n if (!app.isReady())\r\n this.electron.protocol.registerSchemesAsPrivileged([{\r\n scheme: \"electron\",\r\n privileges: {\r\n standard: true,\r\n secure: true,\r\n supportFetchAPI: true,\r\n },\r\n }]);\r\n const eopt = opts?.electronHost;\r\n this._developmentServer = eopt?.developmentServer ?? false;\r\n const frontendPort = eopt?.frontendPort ?? 3000;\r\n this.webResourcesPath = eopt?.webResourcesPath ?? \"\";\r\n this.frontendURL = eopt?.frontendURL ?? (this._developmentServer ? `http://localhost:${frontendPort}` : `${this._electronFrontend}index.html`);\r\n this.appIconPath = path.join(this.webResourcesPath, eopt?.iconName ?? \"appicon.ico\");\r\n this.rpcConfig = ElectronRpcManager.initializeBackend(this._ipc, eopt?.rpcInterfaces);\r\n }\r\n\r\n opts = opts ?? {};\r\n opts.ipcHost = opts.ipcHost ?? {};\r\n opts.ipcHost.socket = this._ipc;\r\n await NativeHost.startup(opts);\r\n if (IpcHost.isValid) {\r\n ElectronAppHandler.register();\r\n opts.electronHost?.ipcHandlers?.forEach((ipc) => ipc.register());\r\n }\r\n }\r\n}\r\n\r\nclass ElectronAppHandler extends IpcHandler {\r\n public get channelName() { return \"electron-safe\"; }\r\n public async callElectron(member: string, method: string, ...args: any) {\r\n let allowedMethods: readonly string[] = [];\r\n if (member === \"dialog\") {\r\n const methods: DialogModuleMethod[] = [\"showMessageBox\", \"showOpenDialog\", \"showSaveDialog\"];\r\n allowedMethods = methods;\r\n }\r\n\r\n if (allowedMethods.indexOf(method) >= 0) {\r\n const electronMember = (ElectronHost.electron as any)[member];\r\n const func = electronMember[method];\r\n if (typeof func === \"function\") {\r\n return func.call(electronMember, ...args);\r\n }\r\n }\r\n\r\n throw new IModelError(IModelStatus.FunctionNotFound, `Method ${method} not found electron.${member}`);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ElectronHost.js","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n// Note: only import *types* from electron so this file can be imported by apps that sometimes use Electron and sometimes not.\r\nimport type { BrowserWindow, BrowserWindowConstructorOptions } from \"electron\";\r\nimport type * as ElectronModule from \"electron\";\r\n\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { BeDuration, IModelStatus, ProcessDetector } from \"@itwin/core-bentley\";\r\nimport { IpcHandler, IpcHost, NativeHost, NativeHostOpts } from \"@itwin/core-backend\";\r\nimport { IModelError, IpcListener, IpcSocketBackend, RemoveFunction, RpcConfiguration, RpcInterfaceDefinition } from \"@itwin/core-common\";\r\nimport { ElectronRpcConfiguration, ElectronRpcManager } from \"../common/ElectronRpcManager\";\r\nimport { dialogChannel, DialogModuleMethod } from \"../common/ElectronIpcInterface\";\r\n\r\n// cSpell:ignore signin devserver webcontents copyfile unmaximize eopt\r\n\r\nclass ElectronIpc implements IpcSocketBackend {\r\n public addListener(channel: string, listener: IpcListener): RemoveFunction {\r\n ElectronHost.ipcMain.addListener(channel, listener);\r\n return () => ElectronHost.ipcMain.removeListener(channel, listener);\r\n }\r\n public removeListener(channel: string, listener: IpcListener) {\r\n ElectronHost.ipcMain.removeListener(channel, listener);\r\n }\r\n public send(channel: string, ...args: any[]): void {\r\n const window = ElectronHost.mainWindow ?? ElectronHost.electron.BrowserWindow.getAllWindows()[0];\r\n window?.webContents.send(channel, ...args);\r\n }\r\n public handle(channel: string, listener: (evt: any, ...args: any[]) => Promise<any>): RemoveFunction {\r\n ElectronHost.ipcMain.removeHandler(channel); // make sure there's not already a handler registered\r\n ElectronHost.ipcMain.handle(channel, listener);\r\n return () => ElectronHost.ipcMain.removeHandler(channel);\r\n }\r\n}\r\n\r\n/**\r\n * Options for [[ElectronHost.startup]]\r\n * @beta\r\n */\r\nexport interface ElectronHostOptions {\r\n /** the path to find web resources */\r\n webResourcesPath?: string;\r\n /** filename for the app's icon, relative to [[webResourcesPath]] */\r\n iconName?: string;\r\n /** name of frontend url to open. */\r\n frontendURL?: string;\r\n /** use a development server rather than the \"electron\" protocol for loading frontend (see https://www.electronjs.org/docs/api/protocol) */\r\n developmentServer?: boolean;\r\n /** port number for development server. Default is 3000 */\r\n frontendPort?: number;\r\n /** list of RPC interface definitions to register */\r\n rpcInterfaces?: RpcInterfaceDefinition[];\r\n /** list of [IpcHandler]($common) classes to register */\r\n ipcHandlers?: (typeof IpcHandler)[];\r\n}\r\n\r\n/** @beta */\r\nexport interface ElectronHostOpts extends NativeHostOpts {\r\n electronHost?: ElectronHostOptions;\r\n}\r\n\r\n/** @beta */\r\nexport interface ElectronHostWindowOptions extends BrowserWindowConstructorOptions {\r\n storeWindowName?: string;\r\n /** The style of window title bar. Default is `default`. */\r\n titleBarStyle?: (\"default\" | \"hidden\" | \"hiddenInset\" | \"customButtonsOnHover\");\r\n}\r\n\r\n/** the size and position of a window as stored in the settings file.\r\n * @beta\r\n */\r\nexport interface WindowSizeAndPositionProps {\r\n width: number;\r\n height: number;\r\n x: number;\r\n y: number;\r\n}\r\n\r\n/**\r\n * The backend for Electron-based desktop applications\r\n * @beta\r\n */\r\nexport class ElectronHost {\r\n private static _ipc: ElectronIpc;\r\n private static _developmentServer: boolean;\r\n private static _electron: typeof ElectronModule;\r\n private static _electronFrontend = \"electron://frontend/\";\r\n private static _mainWindow?: BrowserWindow;\r\n public static webResourcesPath: string;\r\n public static appIconPath: string;\r\n public static frontendURL: string;\r\n public static rpcConfig: RpcConfiguration;\r\n public static get ipcMain() { return this._electron?.ipcMain; }\r\n public static get app() { return this._electron?.app; }\r\n public static get electron() { return this._electron; }\r\n\r\n private constructor() { }\r\n\r\n /**\r\n * Converts an \"electron://frontend/\" URL to an absolute file path.\r\n *\r\n * We use this protocol in production builds because our frontend must be built with absolute URLs,\r\n * however, since we're loading everything directly from the install directory, we cannot know the\r\n * absolute path at build time.\r\n */\r\n private static parseElectronUrl(requestedUrl: string): string {\r\n // Note that the \"frontend/\" path is arbitrary - this is just so we can handle *some* relative URLs...\r\n let assetPath = requestedUrl.substring(this._electronFrontend.length);\r\n if (assetPath.length === 0)\r\n assetPath = \"index.html\";\r\n assetPath = path.normalize(`${this.webResourcesPath}/${assetPath}`);\r\n // File protocols don't follow symlinks, so we need to resolve this to a real path.\r\n // However, if the file doesn't exist, it's fine to return an invalid path here - the request will just fail with net::ERR_FILE_NOT_FOUND\r\n try {\r\n assetPath = fs.realpathSync(assetPath);\r\n } catch (error) {\r\n // eslint-disable-next-line no-console\r\n // console.warn(`WARNING: Frontend requested \"${requestedUrl}\", but ${assetPath} does not exist`);\r\n }\r\n if (!assetPath.startsWith(this.webResourcesPath))\r\n throw new Error(`Access to files outside installation directory (${this.webResourcesPath}) is prohibited`);\r\n return assetPath;\r\n }\r\n\r\n private static _openWindow(options?: ElectronHostWindowOptions) {\r\n const opts: BrowserWindowConstructorOptions = {\r\n ...options,\r\n autoHideMenuBar: true,\r\n icon: this.appIconPath,\r\n webPreferences: {\r\n ...options?.webPreferences,\r\n\r\n // These web preference variables should not be overriden by the ElectronHostWindowOptions\r\n preload: require.resolve(/* webpack: copyfile */\"./ElectronPreload.js\"),\r\n experimentalFeatures: false,\r\n nodeIntegration: false,\r\n contextIsolation: true,\r\n sandbox: true,\r\n nativeWindowOpen: true,\r\n nodeIntegrationInWorker: false,\r\n nodeIntegrationInSubFrames: false,\r\n },\r\n };\r\n\r\n this._mainWindow = new (this.electron.BrowserWindow)(opts);\r\n ElectronRpcConfiguration.targetWindowId = this._mainWindow.id;\r\n this._mainWindow.on(\"closed\", () => this._mainWindow = undefined);\r\n this._mainWindow.loadURL(this.frontendURL); // eslint-disable-line @typescript-eslint/no-floating-promises\r\n\r\n /** Monitors and saves main window size, position and maximized state */\r\n if (options?.storeWindowName) {\r\n const mainWindow = this._mainWindow;\r\n const name = options.storeWindowName;\r\n const saveWindowPosition = () => {\r\n const resolution = mainWindow.getSize();\r\n const position = mainWindow.getPosition();\r\n const pos: WindowSizeAndPositionProps = {\r\n width: resolution[0],\r\n height: resolution[1],\r\n x: position[0],\r\n y: position[1],\r\n };\r\n NativeHost.settingsStore.setData(`windowPos-${name}`, JSON.stringify(pos));\r\n };\r\n const saveMaximized = (maximized: boolean) => {\r\n if (!maximized)\r\n saveWindowPosition();\r\n NativeHost.settingsStore.setData(`windowMaximized-${name}`, maximized);\r\n };\r\n\r\n mainWindow.on(\"resized\", () => saveWindowPosition());\r\n mainWindow.on(\"moved\", () => saveWindowPosition());\r\n mainWindow.on(\"maximize\", () => saveMaximized(true));\r\n mainWindow.on(\"unmaximize\", () => saveMaximized(false));\r\n\r\n saveMaximized(mainWindow.isMaximized());\r\n }\r\n }\r\n\r\n /** The \"main\" BrowserWindow for this application. */\r\n public static get mainWindow() { return this._mainWindow; }\r\n\r\n /** Gets window size and position for a window, by name, from settings file, if present */\r\n public static getWindowSizeSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`windowPos-${windowName}`);\r\n return saved ? JSON.parse(saved) as WindowSizeAndPositionProps : undefined;\r\n }\r\n\r\n /** Gets \"window maximized\" flag for a window, by name, from settings file if present */\r\n public static getWindowMaximizedSetting(windowName: string): boolean | undefined {\r\n return NativeHost.settingsStore.getBoolean(`windowMaximized-${windowName}`);\r\n }\r\n\r\n /**\r\n * Open the main Window when the app is ready.\r\n * @param windowOptions Options for constructing the main BrowserWindow. See: https://electronjs.org/docs/api/browser-window#new-browserwindowoptions\r\n */\r\n public static async openMainWindow(windowOptions?: ElectronHostWindowOptions): Promise<void> {\r\n const app = this.app;\r\n // quit the application when all windows are closed (unless we're running on MacOS)\r\n app.on(\"window-all-closed\", () => {\r\n if (process.platform !== \"darwin\")\r\n app.quit();\r\n });\r\n\r\n // re-open the main window if it was closed and the app is re-activated (this is the normal MacOS behavior)\r\n app.on(\"activate\", () => {\r\n if (!this._mainWindow)\r\n this._openWindow(windowOptions);\r\n });\r\n\r\n if (this._developmentServer) {\r\n // Occasionally, the electron backend may start before the webpack devserver has even started.\r\n // If this happens, we'll just retry and keep reloading the page.\r\n app.on(\"web-contents-created\", (_e, webcontents) => {\r\n webcontents.on(\"did-fail-load\", async (_event, errorCode, _errorDescription, _validatedURL, isMainFrame) => {\r\n // errorCode -102 is CONNECTION_REFUSED - see https://cs.chromium.org/chromium/src/net/base/net_error_list.h\r\n if (isMainFrame && errorCode === -102) {\r\n await BeDuration.wait(100);\r\n webcontents.reload();\r\n }\r\n });\r\n });\r\n }\r\n\r\n await app.whenReady();\r\n\r\n if (!this._developmentServer) {\r\n // handle any \"electron://\" requests and redirect them to \"file://\" URLs\r\n this.electron.protocol.registerFileProtocol(\"electron\", (request, callback) => callback(this.parseElectronUrl(request.url))); // eslint-disable-line @typescript-eslint/no-var-requires\r\n }\r\n\r\n this._openWindow(windowOptions);\r\n }\r\n\r\n public static get isValid() { return this._ipc !== undefined; }\r\n\r\n /**\r\n * Initialize the backend of an Electron app.\r\n * This method configures the backend for all of the inter-process communication (RPC and IPC) for an\r\n * Electron app. It should be called from your Electron main function.\r\n * @param opts Options that control aspects of your backend.\r\n * @note This method must only be called from the backend of an Electron app (i.e. when [ProcessDetector.isElectronAppBackend]($bentley) is `true`).\r\n */\r\n public static async startup(opts?: ElectronHostOpts) {\r\n if (!ProcessDetector.isElectronAppBackend)\r\n throw new Error(\"Not running under Electron\");\r\n\r\n if (!this.isValid) {\r\n this._electron = require(\"electron\");\r\n this._ipc = new ElectronIpc();\r\n const app = this.app;\r\n if (!app.isReady())\r\n this.electron.protocol.registerSchemesAsPrivileged([{\r\n scheme: \"electron\",\r\n privileges: {\r\n standard: true,\r\n secure: true,\r\n supportFetchAPI: true,\r\n },\r\n }]);\r\n const eopt = opts?.electronHost;\r\n this._developmentServer = eopt?.developmentServer ?? false;\r\n const frontendPort = eopt?.frontendPort ?? 3000;\r\n this.webResourcesPath = eopt?.webResourcesPath ?? \"\";\r\n this.frontendURL = eopt?.frontendURL ?? (this._developmentServer ? `http://localhost:${frontendPort}` : `${this._electronFrontend}index.html`);\r\n this.appIconPath = path.join(this.webResourcesPath, eopt?.iconName ?? \"appicon.ico\");\r\n this.rpcConfig = ElectronRpcManager.initializeBackend(this._ipc, eopt?.rpcInterfaces);\r\n }\r\n\r\n opts = opts ?? {};\r\n opts.ipcHost = opts.ipcHost ?? {};\r\n opts.ipcHost.socket = this._ipc;\r\n await NativeHost.startup(opts);\r\n if (IpcHost.isValid) {\r\n ElectronDialogHandler.register();\r\n opts.electronHost?.ipcHandlers?.forEach((ipc) => ipc.register());\r\n }\r\n }\r\n}\r\n\r\nclass ElectronDialogHandler extends IpcHandler {\r\n public get channelName() { return dialogChannel; }\r\n public async callDialog(method: DialogModuleMethod, ...args: any) {\r\n const dialog = ElectronHost.electron.dialog;\r\n const dialogMethod = dialog[method] as Function;\r\n if (typeof dialogMethod !== \"function\")\r\n throw new IModelError(IModelStatus.FunctionNotFound, `illegal electron dialog method`);\r\n\r\n return dialogMethod.call(dialog, ...args);\r\n }\r\n}\r\n"]}
@@ -1,6 +1,8 @@
1
- import { AsyncMethodsOf, ExtractLiterals } from "@itwin/core-bentley";
2
- /** Exposed main process methods of dialog module in an Electron app.
1
+ import { AsyncMethodsOf } from "@itwin/core-bentley";
2
+ /** @internal */
3
+ export declare const dialogChannel = "electron-dialog";
4
+ /** Asynchronous methods of dialog module in an Electron app.
3
5
  * @beta
4
6
  */
5
- export declare type DialogModuleMethod = ExtractLiterals<AsyncMethodsOf<Electron.Dialog>, "showMessageBox" | "showOpenDialog" | "showSaveDialog">;
7
+ export declare type DialogModuleMethod = AsyncMethodsOf<Electron.Dialog>;
6
8
  //# sourceMappingURL=ElectronIpcInterface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronIpcInterface.d.ts","sourceRoot":"","sources":["../../../src/common/ElectronIpcInterface.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtE;;GAEG;AACH,oBAAY,kBAAkB,GAAG,eAAe,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"ElectronIpcInterface.d.ts","sourceRoot":"","sources":["../../../src/common/ElectronIpcInterface.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,gBAAgB;AAChB,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAE/C;;GAEG;AACH,oBAAY,kBAAkB,GAAG,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC"}
@@ -1,3 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dialogChannel = void 0;
4
+ /** @internal */
5
+ exports.dialogChannel = "electron-dialog";
3
6
  //# sourceMappingURL=ElectronIpcInterface.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronIpcInterface.js","sourceRoot":"","sources":["../../../src/common/ElectronIpcInterface.ts"],"names":[],"mappings":"","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { AsyncMethodsOf, ExtractLiterals } from \"@itwin/core-bentley\";\r\n\r\n/** Exposed main process methods of dialog module in an Electron app.\r\n * @beta\r\n */\r\nexport type DialogModuleMethod = ExtractLiterals<AsyncMethodsOf<Electron.Dialog>, \"showMessageBox\" | \"showOpenDialog\" | \"showSaveDialog\">;\r\n"]}
1
+ {"version":3,"file":"ElectronIpcInterface.js","sourceRoot":"","sources":["../../../src/common/ElectronIpcInterface.ts"],"names":[],"mappings":";;;AAMA,gBAAgB;AACH,QAAA,aAAa,GAAG,iBAAiB,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { AsyncMethodsOf } from \"@itwin/core-bentley\";\r\n\r\n/** @internal */\r\nexport const dialogChannel = \"electron-dialog\";\r\n\r\n/** Asynchronous methods of dialog module in an Electron app.\r\n * @beta\r\n */\r\nexport type DialogModuleMethod = AsyncMethodsOf<Electron.Dialog>;\r\n"]}
@@ -2,14 +2,10 @@
2
2
  * @module Logging
3
3
  */
4
4
  /** Logger categories used by this package
5
- * @note All logger categories in this package start with the `core-backend` prefix.
5
+ * @note All logger categories in this package start with the `core-electron` prefix.
6
6
  * @see [Logger]($bentley)
7
7
  * @public
8
8
  */
9
9
  export declare enum ElectronManagerLoggerCategory {
10
- /** The logger category used by the following classes:
11
- * - [[KeyChainStore]]
12
- */
13
- Authorization = "core-electron.Authorization"
14
10
  }
15
11
  //# sourceMappingURL=ElectronManagerLoggerCategory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronManagerLoggerCategory.d.ts","sourceRoot":"","sources":["../../../src/common/ElectronManagerLoggerCategory.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH;;;;GAIG;AACH,oBAAY,6BAA6B;IACvC;;OAEG;IACH,aAAa,gCAAgC;CAC9C"}
1
+ {"version":3,"file":"ElectronManagerLoggerCategory.d.ts","sourceRoot":"","sources":["../../../src/common/ElectronManagerLoggerCategory.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH;;;;GAIG;AACH,oBAAY,6BAA6B;CAAI"}
@@ -9,15 +9,11 @@
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.ElectronManagerLoggerCategory = void 0;
11
11
  /** Logger categories used by this package
12
- * @note All logger categories in this package start with the `core-backend` prefix.
12
+ * @note All logger categories in this package start with the `core-electron` prefix.
13
13
  * @see [Logger]($bentley)
14
14
  * @public
15
15
  */
16
16
  var ElectronManagerLoggerCategory;
17
17
  (function (ElectronManagerLoggerCategory) {
18
- /** The logger category used by the following classes:
19
- * - [[KeyChainStore]]
20
- */
21
- ElectronManagerLoggerCategory["Authorization"] = "core-electron.Authorization";
22
18
  })(ElectronManagerLoggerCategory = exports.ElectronManagerLoggerCategory || (exports.ElectronManagerLoggerCategory = {}));
23
19
  //# sourceMappingURL=ElectronManagerLoggerCategory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronManagerLoggerCategory.js","sourceRoot":"","sources":["../../../src/common/ElectronManagerLoggerCategory.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH;;;;GAIG;AACH,IAAY,6BAKX;AALD,WAAY,6BAA6B;IACvC;;OAEG;IACH,8EAA6C,CAAA;AAC/C,CAAC,EALW,6BAA6B,GAA7B,qCAA6B,KAA7B,qCAA6B,QAKxC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Logging\r\n */\r\n\r\n/** Logger categories used by this package\r\n * @note All logger categories in this package start with the `core-backend` prefix.\r\n * @see [Logger]($bentley)\r\n * @public\r\n */\r\nexport enum ElectronManagerLoggerCategory {\r\n /** The logger category used by the following classes:\r\n * - [[KeyChainStore]]\r\n */\r\n Authorization = \"core-electron.Authorization\",\r\n}\r\n"]}
1
+ {"version":3,"file":"ElectronManagerLoggerCategory.js","sourceRoot":"","sources":["../../../src/common/ElectronManagerLoggerCategory.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH;;;;GAIG;AACH,IAAY,6BAAiC;AAA7C,WAAY,6BAA6B;AAAG,CAAC,EAAjC,6BAA6B,GAA7B,qCAA6B,KAA7B,qCAA6B,QAAI","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Logging\r\n */\r\n\r\n/** Logger categories used by this package\r\n * @note All logger categories in this package start with the `core-electron` prefix.\r\n * @see [Logger]($bentley)\r\n * @public\r\n */\r\nexport enum ElectronManagerLoggerCategory { }\r\n"]}
@@ -27,7 +27,10 @@ export declare class ElectronApp {
27
27
  * Call an asynchronous method in the [Electron.Dialog](https://www.electronjs.org/docs/api/dialog) interface from a previously initialized ElectronFrontend.
28
28
  * @param methodName the name of the method to call
29
29
  * @param args arguments to method
30
+ * @deprecated use [[dialogIpc]]
30
31
  */
31
32
  static callDialog<T extends DialogModuleMethod>(methodName: T, ...args: Parameters<Electron.Dialog[T]>): Promise<PromiseReturnType<Electron.Dialog[T]>>;
33
+ /** Proxy object for calling methods of `Electron.Dialog` */
34
+ static dialogIpc: import("@itwin/core-bentley").PickAsyncMethods<Electron.Dialog>;
32
35
  }
33
36
  //# sourceMappingURL=ElectronApp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronApp.d.ts","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEzE,OAAO,EAAqB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,OAAO,EAAE,gBAAgB,CAAC;KAC3B;CACF;AA4BD,YAAY;AACZ,oBAAY,eAAe,GAAG,aAAa,CAAC;AAE5C;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAc;IAClC,WAAkB,OAAO,IAAI,OAAO,CAAoC;IAExE;;;;OAIG;WACiB,OAAO,CAAC,IAAI,CAAC,EAAE,eAAe;WAU9B,QAAQ;IAM5B;;;;OAIG;WACiB,UAAU,CAAC,CAAC,SAAS,kBAAkB,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CAGpH"}
1
+ {"version":3,"file":"ElectronApp.d.ts","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEzE,OAAO,EAAqB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAiB,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEnF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,OAAO,EAAE,gBAAgB,CAAC;KAC3B;CACF;AA4BD,YAAY;AACZ,oBAAY,eAAe,GAAG,aAAa,CAAC;AAE5C;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAc;IAClC,WAAkB,OAAO,IAAI,OAAO,CAAoC;IAExE;;;;OAIG;WACiB,OAAO,CAAC,IAAI,CAAC,EAAE,eAAe;WAU9B,QAAQ;IAM5B;;;;;OAKG;WACiB,UAAU,CAAC,CAAC,SAAS,kBAAkB,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAInH,4DAA4D;IAC5D,OAAc,SAAS,kEAA6E;CACrG"}
@@ -7,6 +7,7 @@ exports.ElectronApp = void 0;
7
7
  *--------------------------------------------------------------------------------------------*/
8
8
  const core_bentley_1 = require("@itwin/core-bentley");
9
9
  const core_frontend_1 = require("@itwin/core-frontend");
10
+ const ElectronIpcInterface_1 = require("../common/ElectronIpcInterface");
10
11
  const ElectronRpcManager_1 = require("../common/ElectronRpcManager");
11
12
  /**
12
13
  * Frontend Ipc support for Electron apps.
@@ -63,10 +64,13 @@ class ElectronApp {
63
64
  * Call an asynchronous method in the [Electron.Dialog](https://www.electronjs.org/docs/api/dialog) interface from a previously initialized ElectronFrontend.
64
65
  * @param methodName the name of the method to call
65
66
  * @param args arguments to method
67
+ * @deprecated use [[dialogIpc]]
66
68
  */
67
69
  static async callDialog(methodName, ...args) {
68
- return core_frontend_1.IpcApp.callIpcChannel("electron-safe", "callElectron", "dialog", methodName, ...args);
70
+ return core_frontend_1.IpcApp.callIpcChannel(ElectronIpcInterface_1.dialogChannel, "callDialog", methodName, ...args);
69
71
  }
70
72
  }
71
73
  exports.ElectronApp = ElectronApp;
74
+ /** Proxy object for calling methods of `Electron.Dialog` */
75
+ ElectronApp.dialogIpc = core_frontend_1.IpcApp.makeIpcFunctionProxy(ElectronIpcInterface_1.dialogChannel, "callDialog");
72
76
  //# sourceMappingURL=ElectronApp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronApp.js","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":";;;AAAA;;;+FAG+F;AAC/F,sDAAyE;AAEzE,wDAAwE;AAGxE,qEAAkE;AASlE;;GAEG;AACH,MAAM,WAAW;IAef;;QACE,sJAAsJ;QACtJ,iGAAiG;QACjG,8DAA8D;QAC9D,IAAI,CAAC,IAAI,GAAG,MAAA,MAAM,CAAC,OAAO,mCAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC;IAChE,CAAC;IAlBM,WAAW,CAAC,WAAmB,EAAE,QAAqB;QAC3D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC7C,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC;IACM,cAAc,CAAC,WAAmB,EAAE,QAAqB;QAC9D,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IACM,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QACzC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACnC,CAAC;IACM,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,GAAG,IAAW;QACjD,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;CAOF;AAKD;;;GAGG;AACH,MAAa,WAAW;IAEf,MAAM,KAAK,OAAO,KAAc,OAAO,SAAS,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAExE;;;;OAIG;IACI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAsB;;QAChD,IAAI,CAAC,8BAAe,CAAC,qBAAqB;YACxC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,IAAI,CAAC,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,uCAAkB,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS,0CAAE,aAAa,CAAC,CAAC;SAClF;QACD,MAAM,yBAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAK,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,QAAQ;QAC1B,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,MAAM,yBAAS,CAAC,QAAQ,EAAE,CAAC;QAC3B,uCAAkB,CAAC,iBAAiB,EAAE,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,KAAK,CAAC,UAAU,CAA+B,UAAa,EAAE,GAAG,IAAoC;QACjH,OAAO,sBAAM,CAAC,cAAc,CAAC,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAA0C,CAAC;IACxI,CAAC;CACF;AAjCD,kCAiCC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { ProcessDetector, PromiseReturnType } from \"@itwin/core-bentley\";\r\nimport { IpcListener, IpcSocketFrontend } from \"@itwin/core-common\";\r\nimport { IpcApp, NativeApp, NativeAppOpts } from \"@itwin/core-frontend\";\r\nimport type { IpcRenderer } from \"electron\";\r\nimport { DialogModuleMethod } from \"../common/ElectronIpcInterface\";\r\nimport { ElectronRpcManager } from \"../common/ElectronRpcManager\";\r\nimport type { ITwinElectronApi } from \"../common/ITwinElectronApi\";\r\n\r\ndeclare global {\r\n interface Window {\r\n itwinjs: ITwinElectronApi;\r\n }\r\n}\r\n\r\n/**\r\n * Frontend Ipc support for Electron apps.\r\n */\r\nclass ElectronIpc implements IpcSocketFrontend {\r\n private _api: ITwinElectronApi | IpcRenderer;\r\n public addListener(channelName: string, listener: IpcListener) {\r\n this._api.addListener(channelName, listener);\r\n return () => this._api.removeListener(channelName, listener);\r\n }\r\n public removeListener(channelName: string, listener: IpcListener) {\r\n this._api.removeListener(channelName, listener);\r\n }\r\n public send(channel: string, ...data: any[]) {\r\n this._api.send(channel, ...data);\r\n }\r\n public async invoke(channel: string, ...args: any[]) {\r\n return this._api.invoke(channel, ...args);\r\n }\r\n constructor() {\r\n // use the methods on window.itwinjs exposed by ElectronPreload.ts, or ipcRenderer directly if running with nodeIntegration=true (**only** for tests).\r\n // Note that `require(\"electron\")` doesn't work with nodeIntegration=false - that's what it stops\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n this._api = window.itwinjs ?? require(\"electron\").ipcRenderer;\r\n }\r\n}\r\n\r\n/** @beta */\r\nexport type ElectronAppOpts = NativeAppOpts;\r\n\r\n/**\r\n * Frontend of an Electron App.\r\n * @beta\r\n */\r\nexport class ElectronApp {\r\n private static _ipc?: ElectronIpc;\r\n public static get isValid(): boolean { return undefined !== this._ipc; }\r\n\r\n /**\r\n * Start the frontend of an Electron application.\r\n * @param opts Options for your ElectronApp\r\n * @note This method must only be called from the frontend of an Electron app (i.e. when [ProcessDetector.isElectronAppFrontend]($bentley) is `true`).\r\n */\r\n public static async startup(opts?: ElectronAppOpts) {\r\n if (!ProcessDetector.isElectronAppFrontend)\r\n throw new Error(\"Not running under Electron\");\r\n if (!this.isValid) {\r\n this._ipc = new ElectronIpc();\r\n ElectronRpcManager.initializeFrontend(this._ipc, opts?.iModelApp?.rpcInterfaces);\r\n }\r\n await NativeApp.startup(this._ipc!, opts);\r\n }\r\n\r\n public static async shutdown() {\r\n this._ipc = undefined;\r\n await NativeApp.shutdown();\r\n ElectronRpcManager.terminateFrontend();\r\n }\r\n\r\n /**\r\n * Call an asynchronous method in the [Electron.Dialog](https://www.electronjs.org/docs/api/dialog) interface from a previously initialized ElectronFrontend.\r\n * @param methodName the name of the method to call\r\n * @param args arguments to method\r\n */\r\n public static async callDialog<T extends DialogModuleMethod>(methodName: T, ...args: Parameters<Electron.Dialog[T]>) {\r\n return IpcApp.callIpcChannel(\"electron-safe\", \"callElectron\", \"dialog\", methodName, ...args) as PromiseReturnType<Electron.Dialog[T]>;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ElectronApp.js","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":";;;AAAA;;;+FAG+F;AAC/F,sDAAyE;AAEzE,wDAAwE;AAExE,yEAAmF;AACnF,qEAAkE;AASlE;;GAEG;AACH,MAAM,WAAW;IAef;;QACE,sJAAsJ;QACtJ,iGAAiG;QACjG,8DAA8D;QAC9D,IAAI,CAAC,IAAI,GAAG,MAAA,MAAM,CAAC,OAAO,mCAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC;IAChE,CAAC;IAlBM,WAAW,CAAC,WAAmB,EAAE,QAAqB;QAC3D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC7C,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC;IACM,cAAc,CAAC,WAAmB,EAAE,QAAqB;QAC9D,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IACM,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QACzC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACnC,CAAC;IACM,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,GAAG,IAAW;QACjD,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;CAOF;AAKD;;;GAGG;AACH,MAAa,WAAW;IAEf,MAAM,KAAK,OAAO,KAAc,OAAO,SAAS,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAExE;;;;OAIG;IACI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAsB;;QAChD,IAAI,CAAC,8BAAe,CAAC,qBAAqB;YACxC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,IAAI,CAAC,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,uCAAkB,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS,0CAAE,aAAa,CAAC,CAAC;SAClF;QACD,MAAM,yBAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAK,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,QAAQ;QAC1B,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,MAAM,yBAAS,CAAC,QAAQ,EAAE,CAAC;QAC3B,uCAAkB,CAAC,iBAAiB,EAAE,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,UAAU,CAA+B,UAAa,EAAE,GAAG,IAAoC;QACjH,OAAO,sBAAM,CAAC,cAAc,CAAC,oCAAa,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,CAA0C,CAAC;IAC1H,CAAC;;AAjCH,kCAqCC;AAFC,4DAA4D;AAC9C,qBAAS,GAAG,sBAAM,CAAC,oBAAoB,CAAkB,oCAAa,EAAE,YAAY,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { ProcessDetector, PromiseReturnType } from \"@itwin/core-bentley\";\r\nimport { IpcListener, IpcSocketFrontend } from \"@itwin/core-common\";\r\nimport { IpcApp, NativeApp, NativeAppOpts } from \"@itwin/core-frontend\";\r\nimport type { IpcRenderer } from \"electron\";\r\nimport { dialogChannel, DialogModuleMethod } from \"../common/ElectronIpcInterface\";\r\nimport { ElectronRpcManager } from \"../common/ElectronRpcManager\";\r\nimport type { ITwinElectronApi } from \"../common/ITwinElectronApi\";\r\n\r\ndeclare global {\r\n interface Window {\r\n itwinjs: ITwinElectronApi;\r\n }\r\n}\r\n\r\n/**\r\n * Frontend Ipc support for Electron apps.\r\n */\r\nclass ElectronIpc implements IpcSocketFrontend {\r\n private _api: ITwinElectronApi | IpcRenderer;\r\n public addListener(channelName: string, listener: IpcListener) {\r\n this._api.addListener(channelName, listener);\r\n return () => this._api.removeListener(channelName, listener);\r\n }\r\n public removeListener(channelName: string, listener: IpcListener) {\r\n this._api.removeListener(channelName, listener);\r\n }\r\n public send(channel: string, ...data: any[]) {\r\n this._api.send(channel, ...data);\r\n }\r\n public async invoke(channel: string, ...args: any[]) {\r\n return this._api.invoke(channel, ...args);\r\n }\r\n constructor() {\r\n // use the methods on window.itwinjs exposed by ElectronPreload.ts, or ipcRenderer directly if running with nodeIntegration=true (**only** for tests).\r\n // Note that `require(\"electron\")` doesn't work with nodeIntegration=false - that's what it stops\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n this._api = window.itwinjs ?? require(\"electron\").ipcRenderer;\r\n }\r\n}\r\n\r\n/** @beta */\r\nexport type ElectronAppOpts = NativeAppOpts;\r\n\r\n/**\r\n * Frontend of an Electron App.\r\n * @beta\r\n */\r\nexport class ElectronApp {\r\n private static _ipc?: ElectronIpc;\r\n public static get isValid(): boolean { return undefined !== this._ipc; }\r\n\r\n /**\r\n * Start the frontend of an Electron application.\r\n * @param opts Options for your ElectronApp\r\n * @note This method must only be called from the frontend of an Electron app (i.e. when [ProcessDetector.isElectronAppFrontend]($bentley) is `true`).\r\n */\r\n public static async startup(opts?: ElectronAppOpts) {\r\n if (!ProcessDetector.isElectronAppFrontend)\r\n throw new Error(\"Not running under Electron\");\r\n if (!this.isValid) {\r\n this._ipc = new ElectronIpc();\r\n ElectronRpcManager.initializeFrontend(this._ipc, opts?.iModelApp?.rpcInterfaces);\r\n }\r\n await NativeApp.startup(this._ipc!, opts);\r\n }\r\n\r\n public static async shutdown() {\r\n this._ipc = undefined;\r\n await NativeApp.shutdown();\r\n ElectronRpcManager.terminateFrontend();\r\n }\r\n\r\n /**\r\n * Call an asynchronous method in the [Electron.Dialog](https://www.electronjs.org/docs/api/dialog) interface from a previously initialized ElectronFrontend.\r\n * @param methodName the name of the method to call\r\n * @param args arguments to method\r\n * @deprecated use [[dialogIpc]]\r\n */\r\n public static async callDialog<T extends DialogModuleMethod>(methodName: T, ...args: Parameters<Electron.Dialog[T]>) {\r\n return IpcApp.callIpcChannel(dialogChannel, \"callDialog\", methodName, ...args) as PromiseReturnType<Electron.Dialog[T]>;\r\n }\r\n\r\n /** Proxy object for calling methods of `Electron.Dialog` */\r\n public static dialogIpc = IpcApp.makeIpcFunctionProxy<Electron.Dialog>(dialogChannel, \"callDialog\");\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@itwin/core-electron",
3
- "version": "3.5.0-dev.7",
3
+ "version": "3.6.0-dev.1",
4
4
  "description": "iTwin.js ElectronHost and ElectronApp",
5
5
  "license": "MIT",
6
6
  "engines": {
7
- "node": ">=12.22.0 < 14.0 || >=14.17.0 <17.0"
7
+ "node": ">=12.22.0 < 14.0 || >=14.17.0 < 19.0"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
@@ -20,30 +20,33 @@
20
20
  "url": "http://www.bentley.com"
21
21
  },
22
22
  "peerDependencies": {
23
- "@itwin/core-backend": "^3.5.0-dev.7",
24
- "@itwin/core-bentley": "^3.5.0-dev.7",
25
- "@itwin/core-common": "^3.5.0-dev.7",
26
- "@itwin/core-frontend": "^3.5.0-dev.7",
27
- "@itwin/presentation-common": "^3.5.0-dev.7",
23
+ "@itwin/core-backend": "^3.6.0-dev.1",
24
+ "@itwin/core-bentley": "^3.6.0-dev.1",
25
+ "@itwin/core-common": "^3.6.0-dev.1",
26
+ "@itwin/core-frontend": "^3.6.0-dev.1",
27
+ "@itwin/presentation-common": "^3.6.0-dev.1",
28
28
  "electron": ">=14.0.0 <18.0.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@itwin/build-tools": "3.5.0-dev.7",
32
- "@itwin/core-backend": "3.5.0-dev.7",
33
- "@itwin/core-bentley": "3.5.0-dev.7",
34
- "@itwin/core-common": "3.5.0-dev.7",
35
- "@itwin/core-frontend": "3.5.0-dev.7",
36
- "@itwin/eslint-plugin": "3.5.0-dev.7",
37
- "@itwin/presentation-common": "3.5.0-dev.7",
31
+ "@itwin/build-tools": "3.6.0-dev.1",
32
+ "@itwin/certa": "3.6.0-dev.1",
33
+ "@itwin/core-backend": "3.6.0-dev.1",
34
+ "@itwin/core-bentley": "3.6.0-dev.1",
35
+ "@itwin/core-common": "3.6.0-dev.1",
36
+ "@itwin/core-frontend": "3.6.0-dev.1",
37
+ "@itwin/eslint-plugin": "3.6.0-dev.1",
38
+ "@itwin/presentation-common": "3.6.0-dev.1",
38
39
  "@types/chai": "4.3.1",
39
40
  "@types/mocha": "^8.2.2",
40
- "@types/node": "16.11.59",
41
+ "@types/node": "18.11.5",
41
42
  "chai": "^4.1.2",
42
43
  "electron": "^17.0.0",
43
44
  "eslint": "^7.11.0",
44
45
  "mocha": "^10.0.0",
45
46
  "rimraf": "^3.0.2",
46
- "typescript": "~4.4.0"
47
+ "source-map-loader": "^4.0.0",
48
+ "typescript": "~4.4.0",
49
+ "webpack": "^5.64.4"
47
50
  },
48
51
  "dependencies": {
49
52
  "@openid/appauth": "^1.2.6",
@@ -65,7 +68,11 @@
65
68
  "extract-api": "betools extract-api --entry=__DOC_ONLY__",
66
69
  "lint": "eslint -f visualstudio \"./src/**/*.ts\" 1>&2",
67
70
  "test": "",
68
- "test:integration": "mocha lib/cjs/test/backend/RunElectronBackendTests.js",
71
+ "test:integration": "npm run test:integration:backend && npm run test:integration:frontend:ci",
72
+ "test:integration:backend": "mocha --config src/test/backend/.mocharc.json",
73
+ "test:integration:frontend:ci": "npm run -s webpack:frontend-test && npm run test:integration:frontend",
74
+ "test:integration:frontend": "certa -r electron --config src/test/frontend/utils/certa.json",
75
+ "webpack:frontend-test": "webpack --config ./src/test/frontend/utils/webpack.config.js 1>&2",
69
76
  "cover": ""
70
77
  },
71
78
  "readme": "# @itwin/core-electron\r\n\r\nCopyright © Bentley Systems, Incorporated. All rights reserved. See LICENSE.md for license terms and full copyright notice.\r\n\r\n## Description\r\n\r\nThe __@itwin/core-electron__ package contains the electron utilities to write an iTwin.js application based on Electron.\r\n\r\n## Documentation\r\n\r\nSee the [iTwin.js](https://www.itwinjs.org) documentation for more information.\r\n"