@itwin/core-electron 4.0.0-dev.4 → 4.0.0-dev.41
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 +22 -7
- package/lib/cjs/backend/ElectronHost.d.ts.map +1 -1
- package/lib/cjs/backend/ElectronHost.js +16 -19
- package/lib/cjs/backend/ElectronHost.js.map +1 -1
- package/lib/cjs/common/ElectronRpcManager.js +1 -1
- package/lib/cjs/common/ElectronRpcManager.js.map +1 -1
- package/lib/cjs/frontend/ElectronApp.js +2 -4
- package/lib/cjs/frontend/ElectronApp.js.map +1 -1
- package/package.json +21 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
# Change Log - @itwin/core-electron
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Wed, 08 Feb 2023 14:58:39 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 3.6.0
|
|
6
|
+
Wed, 08 Feb 2023 14:58:39 GMT
|
|
7
|
+
|
|
8
|
+
### Updates
|
|
9
|
+
|
|
10
|
+
- Added ElectronHost.getWindowSizeAndPositionSetting to replace now deprecated ElectronHost.getWindowSizeSetting
|
|
11
|
+
- Add support for Electron 22.
|
|
12
|
+
- Use EmptyLocalization for localization in tests to increase test performance
|
|
13
|
+
- React to RPC deprecations.
|
|
14
|
+
|
|
15
|
+
## 3.5.6
|
|
16
|
+
Fri, 24 Feb 2023 16:02:47 GMT
|
|
17
|
+
|
|
18
|
+
_Version update only_
|
|
4
19
|
|
|
5
20
|
## 3.5.5
|
|
6
21
|
Thu, 26 Jan 2023 22:53:27 GMT
|
|
@@ -497,7 +512,7 @@ Fri, 30 Apr 2021 12:36:58 GMT
|
|
|
497
512
|
### Updates
|
|
498
513
|
|
|
499
514
|
- allow authConfig to be supplied from backend
|
|
500
|
-
- Fixes to desktop and iOS apps.
|
|
515
|
+
- Fixes to desktop and iOS apps.
|
|
501
516
|
- Saving & restoring Electron main window size, position & maximized state
|
|
502
517
|
|
|
503
518
|
## 2.14.4
|
|
@@ -704,7 +719,7 @@ Fri, 02 Oct 2020 18:03:32 GMT
|
|
|
704
719
|
|
|
705
720
|
### Updates
|
|
706
721
|
|
|
707
|
-
- Fixed desktop authorization after recent changes.
|
|
722
|
+
- Fixed desktop authorization after recent changes.
|
|
708
723
|
|
|
709
724
|
## 2.6.5
|
|
710
725
|
Sat, 26 Sep 2020 16:06:34 GMT
|
|
@@ -828,9 +843,9 @@ Wed, 06 May 2020 13:17:49 GMT
|
|
|
828
843
|
|
|
829
844
|
- Update to Electron 8
|
|
830
845
|
- react to changes in imodeljs-clients
|
|
831
|
-
- FrontendAuthorizationClient does not extend IDisposable.
|
|
846
|
+
- FrontendAuthorizationClient does not extend IDisposable.
|
|
832
847
|
- Update minimum Node version to 10.16.0
|
|
833
|
-
- Renamed OIDC constructs for consistency; Removed SAML support.
|
|
848
|
+
- Renamed OIDC constructs for consistency; Removed SAML support.
|
|
834
849
|
- order imports.
|
|
835
850
|
- Upgrade to Rush 5.23.2
|
|
836
851
|
- Update electron version to ^8.2.1
|
|
@@ -856,7 +871,7 @@ Wed, 12 Feb 2020 17:45:50 GMT
|
|
|
856
871
|
|
|
857
872
|
### Updates
|
|
858
873
|
|
|
859
|
-
- Setup oidc client for backend use in electron applications.
|
|
874
|
+
- Setup oidc client for backend use in electron applications.
|
|
860
875
|
|
|
861
876
|
## 1.11.0
|
|
862
877
|
Wed, 22 Jan 2020 19:24:12 GMT
|
|
@@ -938,7 +953,7 @@ Mon, 13 May 2019 15:52:05 GMT
|
|
|
938
953
|
|
|
939
954
|
- Adds parameter for api-extractor to validate missing release tags
|
|
940
955
|
- Fix broken links
|
|
941
|
-
- Setup a generic context for tracking client requests, and made various related enhancements to logging, usage tracking and authorization.
|
|
956
|
+
- Setup a generic context for tracking client requests, and made various related enhancements to logging, usage tracking and authorization.
|
|
942
957
|
- Upgrade TypeDoc dependency to 0.14.2
|
|
943
958
|
|
|
944
959
|
## 0.190.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronHost.d.ts","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,+BAA+B,EAAkB,MAAM,UAAU,CAAC;AAC/F,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,QAAQ,CAAC,6BAA6B,CAAe;IACpE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAEjE,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;
|
|
1
|
+
{"version":3,"file":"ElectronHost.d.ts","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,+BAA+B,EAAkB,MAAM,UAAU,CAAC;AAC/F,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,QAAQ,CAAC,6BAA6B,CAAe;IACpE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAEjE,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;IAsD1B,qDAAqD;IACrD,WAAkB,UAAU,8BAA+B;IAE3D;;;;;;;OAOG;WACW,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAK9F;;OAEG;WACW,+BAA+B,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAKzG,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"}
|
|
@@ -22,9 +22,8 @@ class ElectronIpc {
|
|
|
22
22
|
ElectronHost.ipcMain.removeListener(channel, listener);
|
|
23
23
|
}
|
|
24
24
|
send(channel, ...args) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
window === null || window === void 0 ? void 0 : window.webContents.send(channel, ...args);
|
|
25
|
+
const window = ElectronHost.mainWindow ?? ElectronHost.electron.BrowserWindow.getAllWindows()[0];
|
|
26
|
+
window?.webContents.send(channel, ...args);
|
|
28
27
|
}
|
|
29
28
|
handle(channel, listener) {
|
|
30
29
|
ElectronHost.ipcMain.removeHandler(channel); // make sure there's not already a handler registered
|
|
@@ -38,8 +37,8 @@ class ElectronIpc {
|
|
|
38
37
|
*/
|
|
39
38
|
class ElectronHost {
|
|
40
39
|
constructor() { }
|
|
41
|
-
static get ipcMain() {
|
|
42
|
-
static get app() {
|
|
40
|
+
static get ipcMain() { return this._electron?.ipcMain; }
|
|
41
|
+
static get app() { return this._electron?.app; }
|
|
43
42
|
static get electron() { return this._electron; }
|
|
44
43
|
/**
|
|
45
44
|
* Converts an "electron://frontend/" URL to an absolute file path.
|
|
@@ -69,14 +68,13 @@ class ElectronHost {
|
|
|
69
68
|
}
|
|
70
69
|
static _openWindow(options) {
|
|
71
70
|
const webPreferences = {
|
|
72
|
-
...options
|
|
71
|
+
...options?.webPreferences,
|
|
73
72
|
// These web preference variables should not be overriden by the ElectronHostWindowOptions
|
|
74
73
|
preload: require.resolve(/* webpack: copyfile */ "./ElectronPreload.js"),
|
|
75
74
|
experimentalFeatures: false,
|
|
76
75
|
nodeIntegration: false,
|
|
77
76
|
contextIsolation: true,
|
|
78
77
|
sandbox: true,
|
|
79
|
-
nativeWindowOpen: true,
|
|
80
78
|
nodeIntegrationInWorker: false,
|
|
81
79
|
nodeIntegrationInSubFrames: false,
|
|
82
80
|
};
|
|
@@ -91,7 +89,7 @@ class ElectronHost {
|
|
|
91
89
|
this._mainWindow.on("closed", () => this._mainWindow = undefined);
|
|
92
90
|
this._mainWindow.loadURL(this.frontendURL); // eslint-disable-line @typescript-eslint/no-floating-promises
|
|
93
91
|
/** Monitors and saves main window size, position and maximized state */
|
|
94
|
-
if (options
|
|
92
|
+
if (options?.storeWindowName) {
|
|
95
93
|
const mainWindow = this._mainWindow;
|
|
96
94
|
const name = options.storeWindowName;
|
|
97
95
|
const saveWindowPosition = (key) => {
|
|
@@ -184,7 +182,6 @@ class ElectronHost {
|
|
|
184
182
|
* @note This method must only be called from the backend of an Electron app (i.e. when [ProcessDetector.isElectronAppBackend]($bentley) is `true`).
|
|
185
183
|
*/
|
|
186
184
|
static async startup(opts) {
|
|
187
|
-
var _a, _b, _c, _d, _f, _g, _h, _j;
|
|
188
185
|
if (!core_bentley_1.ProcessDetector.isElectronAppBackend)
|
|
189
186
|
throw new Error("Not running under Electron");
|
|
190
187
|
if (!this.isValid) {
|
|
@@ -200,21 +197,21 @@ class ElectronHost {
|
|
|
200
197
|
supportFetchAPI: true,
|
|
201
198
|
},
|
|
202
199
|
}]);
|
|
203
|
-
const eopt = opts
|
|
204
|
-
this._developmentServer =
|
|
205
|
-
const frontendPort =
|
|
206
|
-
this.webResourcesPath =
|
|
207
|
-
this.frontendURL =
|
|
208
|
-
this.appIconPath = path.join(this.webResourcesPath,
|
|
209
|
-
this.rpcConfig = ElectronRpcManager_1.ElectronRpcManager.initializeBackend(this._ipc, eopt
|
|
200
|
+
const eopt = opts?.electronHost;
|
|
201
|
+
this._developmentServer = eopt?.developmentServer ?? false;
|
|
202
|
+
const frontendPort = eopt?.frontendPort ?? 3000;
|
|
203
|
+
this.webResourcesPath = eopt?.webResourcesPath ?? "";
|
|
204
|
+
this.frontendURL = eopt?.frontendURL ?? (this._developmentServer ? `http://localhost:${frontendPort}` : `${this._electronFrontend}index.html`);
|
|
205
|
+
this.appIconPath = path.join(this.webResourcesPath, eopt?.iconName ?? "appicon.ico");
|
|
206
|
+
this.rpcConfig = ElectronRpcManager_1.ElectronRpcManager.initializeBackend(this._ipc, eopt?.rpcInterfaces);
|
|
210
207
|
}
|
|
211
|
-
opts = opts
|
|
212
|
-
opts.ipcHost =
|
|
208
|
+
opts = opts ?? {};
|
|
209
|
+
opts.ipcHost = opts.ipcHost ?? {};
|
|
213
210
|
opts.ipcHost.socket = this._ipc;
|
|
214
211
|
await core_backend_1.NativeHost.startup(opts);
|
|
215
212
|
if (core_backend_1.IpcHost.isValid) {
|
|
216
213
|
ElectronDialogHandler.register();
|
|
217
|
-
|
|
214
|
+
opts.electronHost?.ipcHandlers?.forEach((ipc) => ipc.register());
|
|
218
215
|
}
|
|
219
216
|
}
|
|
220
217
|
}
|
|
@@ -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* from electron so this file can be imported by apps that sometimes use Electron and sometimes not.\r\nimport type { BrowserWindow, BrowserWindowConstructorOptions, WebPreferences } 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 readonly _deprecatedSizeAndPosStoreKey = \"windowPos\";\r\n private static readonly _sizeAndPosStoreKey = \"windowSizeAndPos\";\r\n\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 webPreferences: WebPreferences & { nativeWindowOpen: true } = { // nativeWindowOpen was removed starting Electron 18\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 const opts: BrowserWindowConstructorOptions = {\r\n ...options,\r\n autoHideMenuBar: true,\r\n icon: this.appIconPath,\r\n webPreferences,\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 = (key: string) => {\r\n const bounds: WindowSizeAndPositionProps = mainWindow.getBounds();\r\n NativeHost.settingsStore.setData(`${key}-${name}`, JSON.stringify(bounds));\r\n };\r\n const saveMaximized = (maximized: boolean) => {\r\n if (!maximized)\r\n saveWindowPosition(this._deprecatedSizeAndPosStoreKey);\r\n NativeHost.settingsStore.setData(`windowMaximized-${name}`, maximized);\r\n };\r\n\r\n mainWindow.on(\"maximize\", () => saveMaximized(true));\r\n mainWindow.on(\"unmaximize\", () => saveMaximized(false));\r\n saveMaximized(mainWindow.isMaximized());\r\n\r\n mainWindow.on(\"resized\", () => saveWindowPosition(this._deprecatedSizeAndPosStoreKey));\r\n mainWindow.on(\"moved\", () => saveWindowPosition(this._deprecatedSizeAndPosStoreKey));\r\n\r\n const debouncedSaveWindowSizeAndPos = debounce(() => saveWindowPosition(this._sizeAndPosStoreKey));\r\n mainWindow.on(\"resize\", () => debouncedSaveWindowSizeAndPos());\r\n mainWindow.on(\"move\", () => debouncedSaveWindowSizeAndPos());\r\n saveWindowPosition(this._sizeAndPosStoreKey);\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 /**\r\n * Gets window size and position for a window, by name, from settings file, if present.\r\n * @note Size and position values in the settings file will be updated differently depending on platform.\r\n * On Linux values are only updated on window \"unmaximize\".\r\n * On Windows and MacOS values are also updated on window manual resize or move.\r\n * To get consistent behavior across different platforms, use [[ElectronHost.getWindowSizeAndPositionSetting]].\r\n * @deprecated in 3.6. Use [[ElectronHost.getWindowSizeAndPositionSetting]].\r\n */\r\n public static getWindowSizeSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`${this._deprecatedSizeAndPosStoreKey}-${windowName}`);\r\n return saved ? JSON.parse(saved) as WindowSizeAndPositionProps : undefined;\r\n }\r\n\r\n /**\r\n * Gets window size and position for a window, by name, from settings file, if present.\r\n */\r\n public static getWindowSizeAndPositionSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`${this._sizeAndPosStoreKey}-${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\r\nfunction debounce(func: Function, ms: number = 200) {\r\n let timeout: NodeJS.Timeout;\r\n return function (this: any, ...args: any[]) {\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => {\r\n func.apply(this, args);\r\n }, ms);\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, WebPreferences } 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 readonly _deprecatedSizeAndPosStoreKey = \"windowPos\";\r\n private static readonly _sizeAndPosStoreKey = \"windowSizeAndPos\";\r\n\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 webPreferences: 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 nodeIntegrationInWorker: false,\r\n nodeIntegrationInSubFrames: false,\r\n };\r\n\r\n const opts: BrowserWindowConstructorOptions = {\r\n ...options,\r\n autoHideMenuBar: true,\r\n icon: this.appIconPath,\r\n webPreferences,\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 = (key: string) => {\r\n const bounds: WindowSizeAndPositionProps = mainWindow.getBounds();\r\n NativeHost.settingsStore.setData(`${key}-${name}`, JSON.stringify(bounds));\r\n };\r\n const saveMaximized = (maximized: boolean) => {\r\n if (!maximized)\r\n saveWindowPosition(this._deprecatedSizeAndPosStoreKey);\r\n NativeHost.settingsStore.setData(`windowMaximized-${name}`, maximized);\r\n };\r\n\r\n mainWindow.on(\"maximize\", () => saveMaximized(true));\r\n mainWindow.on(\"unmaximize\", () => saveMaximized(false));\r\n saveMaximized(mainWindow.isMaximized());\r\n\r\n mainWindow.on(\"resized\", () => saveWindowPosition(this._deprecatedSizeAndPosStoreKey));\r\n mainWindow.on(\"moved\", () => saveWindowPosition(this._deprecatedSizeAndPosStoreKey));\r\n\r\n const debouncedSaveWindowSizeAndPos = debounce(() => saveWindowPosition(this._sizeAndPosStoreKey));\r\n mainWindow.on(\"resize\", () => debouncedSaveWindowSizeAndPos());\r\n mainWindow.on(\"move\", () => debouncedSaveWindowSizeAndPos());\r\n saveWindowPosition(this._sizeAndPosStoreKey);\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 /**\r\n * Gets window size and position for a window, by name, from settings file, if present.\r\n * @note Size and position values in the settings file will be updated differently depending on platform.\r\n * On Linux values are only updated on window \"unmaximize\".\r\n * On Windows and MacOS values are also updated on window manual resize or move.\r\n * To get consistent behavior across different platforms, use [[ElectronHost.getWindowSizeAndPositionSetting]].\r\n * @deprecated in 3.6. Use [[ElectronHost.getWindowSizeAndPositionSetting]].\r\n */\r\n public static getWindowSizeSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`${this._deprecatedSizeAndPosStoreKey}-${windowName}`);\r\n return saved ? JSON.parse(saved) as WindowSizeAndPositionProps : undefined;\r\n }\r\n\r\n /**\r\n * Gets window size and position for a window, by name, from settings file, if present.\r\n */\r\n public static getWindowSizeAndPositionSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`${this._sizeAndPosStoreKey}-${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\r\nfunction debounce(func: Function, ms: number = 200) {\r\n let timeout: NodeJS.Timeout;\r\n return function (this: any, ...args: any[]) {\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => {\r\n func.apply(this, args);\r\n }, ms);\r\n };\r\n}\r\n"]}
|
|
@@ -31,7 +31,7 @@ class ElectronRpcManager extends core_common_1.RpcManager {
|
|
|
31
31
|
return ElectronRpcManager.performInitialization(ipcBackend, interfaces);
|
|
32
32
|
}
|
|
33
33
|
static performInitialization(ipcSocket, rpcs) {
|
|
34
|
-
const interfaces = rpcs
|
|
34
|
+
const interfaces = rpcs ?? [
|
|
35
35
|
core_common_1.IModelReadRpcInterface,
|
|
36
36
|
core_common_1.IModelTileRpcInterface,
|
|
37
37
|
core_common_1.SnapshotIModelRpcInterface,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronRpcManager.js","sourceRoot":"","sources":["../../../src/common/ElectronRpcManager.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,oDAAmO;AACnO,oEAAsE;AACtE,+DAA4D;AAE5D,4CAA4C;AAE5C;;GAEG;AACH,MAAsB,wBAAyB,SAAQ,8BAAgB;CAMtE;AAND,4DAMC;AAED;;GAEG;AACH,MAAa,kBAAmB,SAAQ,wBAAU;IAChD,yEAAyE;IAClE,MAAM,CAAC,kBAAkB,CAAC,WAA8B,EAAE,UAAqC;QACpG,OAAO,kBAAkB,CAAC,qBAAqB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC3E,CAAC;IAED,wEAAwE;IACjE,MAAM,CAAC,iBAAiB,CAAC,UAA4B,EAAE,UAAqC;QACjG,OAAO,kBAAkB,CAAC,qBAAqB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC1E,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,SAAoB,EAAE,IAA+B;QACxF,MAAM,UAAU,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"ElectronRpcManager.js","sourceRoot":"","sources":["../../../src/common/ElectronRpcManager.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,oDAAmO;AACnO,oEAAsE;AACtE,+DAA4D;AAE5D,4CAA4C;AAE5C;;GAEG;AACH,MAAsB,wBAAyB,SAAQ,8BAAgB;CAMtE;AAND,4DAMC;AAED;;GAEG;AACH,MAAa,kBAAmB,SAAQ,wBAAU;IAChD,yEAAyE;IAClE,MAAM,CAAC,kBAAkB,CAAC,WAA8B,EAAE,UAAqC;QACpG,OAAO,kBAAkB,CAAC,qBAAqB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC3E,CAAC;IAED,wEAAwE;IACjE,MAAM,CAAC,iBAAiB,CAAC,UAA4B,EAAE,UAAqC;QACjG,OAAO,kBAAkB,CAAC,qBAAqB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC1E,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,SAAoB,EAAE,IAA+B;QACxF,MAAM,UAAU,GAAG,IAAI,IAAI;YACzB,oCAAsB;YACtB,oCAAsB;YACtB,wCAA0B;YAC1B,8CAAwB;SACzB,CAAC;QACF,MAAM,MAAM,GAAG,KAAM,SAAQ,wBAAwB;YAAtC;;gBACN,eAAU,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC;gBAC9B,aAAQ,GAAwB,IAAI,yCAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAClF,CAAC;SAAA,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE;YAC5B,8BAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;SAC5C;QAED,MAAM,QAAQ,GAAG,8BAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACjD,8BAAgB,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAEhD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,wEAAwE;IACjE,MAAM,CAAC,iBAAiB;QAC7B,OAAO,kBAAkB,CAAC,kBAAkB,EAAE,CAAC;IACjD,CAAC;IAEO,MAAM,CAAC,kBAAkB;QAC/B,MAAM,WAAW,GAAG,yBAAW,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAE3D,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,IAAI,WAAW,EAAE;YAC1C,wBAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;SAC7C;IACH,CAAC;CACF;AA7CD,gDA6CC","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 RpcInterface\r\n */\r\n\r\nimport { IModelReadRpcInterface, IModelTileRpcInterface, IpcSocket, IpcSocketBackend, IpcSocketFrontend, RpcConfiguration, RpcInterfaceDefinition, RpcManager, RpcRegistry, SnapshotIModelRpcInterface } from \"@itwin/core-common\";\r\nimport { PresentationRpcInterface } from \"@itwin/presentation-common\";\r\nimport { ElectronRpcProtocol } from \"./ElectronRpcProtocol\";\r\n\r\n/* eslint-disable deprecation/deprecation */\r\n\r\n/** RPC interface configuration for an Electron-based application.\r\n * @internal\r\n */\r\nexport abstract class ElectronRpcConfiguration extends RpcConfiguration {\r\n\r\n public static targetWindowId?: number;\r\n\r\n /** The protocol of the configuration. */\r\n public abstract override protocol: ElectronRpcProtocol;\r\n}\r\n\r\n/** Coordinates usage of RPC interfaces for an Electron-based application.\r\n * @internal\r\n */\r\nexport class ElectronRpcManager extends RpcManager {\r\n /** Initializes ElectronRpcManager for the frontend of an application. */\r\n public static initializeFrontend(ipcFrontend: IpcSocketFrontend, interfaces?: RpcInterfaceDefinition[]): ElectronRpcConfiguration {\r\n return ElectronRpcManager.performInitialization(ipcFrontend, interfaces);\r\n }\r\n\r\n /** Initializes ElectronRpcManager for the backend of an application. */\r\n public static initializeBackend(ipcBackend: IpcSocketBackend, interfaces?: RpcInterfaceDefinition[]): ElectronRpcConfiguration {\r\n return ElectronRpcManager.performInitialization(ipcBackend, interfaces);\r\n }\r\n\r\n private static performInitialization(ipcSocket: IpcSocket, rpcs?: RpcInterfaceDefinition[]): ElectronRpcConfiguration {\r\n const interfaces = rpcs ?? [\r\n IModelReadRpcInterface,\r\n IModelTileRpcInterface,\r\n SnapshotIModelRpcInterface,\r\n PresentationRpcInterface,\r\n ];\r\n const config = class extends ElectronRpcConfiguration {\r\n public interfaces = () => interfaces;\r\n public protocol: ElectronRpcProtocol = new ElectronRpcProtocol(this, ipcSocket);\r\n };\r\n\r\n for (const def of interfaces) {\r\n RpcConfiguration.assign(def, () => config);\r\n }\r\n\r\n const instance = RpcConfiguration.obtain(config);\r\n RpcConfiguration.initializeInterfaces(instance);\r\n\r\n return instance;\r\n }\r\n\r\n /** Terminates ElectronRpcManager for the frontend of an application. */\r\n public static terminateFrontend() {\r\n return ElectronRpcManager.performTermination();\r\n }\r\n\r\n private static performTermination() {\r\n const definitions = RpcRegistry.instance.definitionClasses;\r\n\r\n for (const [, interfaceDef] of definitions) {\r\n RpcManager.terminateInterface(interfaceDef);\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -14,11 +14,10 @@ const ElectronRpcManager_1 = require("../common/ElectronRpcManager");
|
|
|
14
14
|
*/
|
|
15
15
|
class ElectronIpc {
|
|
16
16
|
constructor() {
|
|
17
|
-
var _a;
|
|
18
17
|
// use the methods on window.itwinjs exposed by ElectronPreload.ts, or ipcRenderer directly if running with nodeIntegration=true (**only** for tests).
|
|
19
18
|
// Note that `require("electron")` doesn't work with nodeIntegration=false - that's what it stops
|
|
20
19
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
21
|
-
this._api =
|
|
20
|
+
this._api = window.itwinjs ?? require("electron").ipcRenderer;
|
|
22
21
|
}
|
|
23
22
|
addListener(channelName, listener) {
|
|
24
23
|
this._api.addListener(channelName, listener);
|
|
@@ -46,12 +45,11 @@ class ElectronApp {
|
|
|
46
45
|
* @note This method must only be called from the frontend of an Electron app (i.e. when [ProcessDetector.isElectronAppFrontend]($bentley) is `true`).
|
|
47
46
|
*/
|
|
48
47
|
static async startup(opts) {
|
|
49
|
-
var _a;
|
|
50
48
|
if (!core_bentley_1.ProcessDetector.isElectronAppFrontend)
|
|
51
49
|
throw new Error("Not running under Electron");
|
|
52
50
|
if (!this.isValid) {
|
|
53
51
|
this._ipc = new ElectronIpc();
|
|
54
|
-
ElectronRpcManager_1.ElectronRpcManager.initializeFrontend(this._ipc,
|
|
52
|
+
ElectronRpcManager_1.ElectronRpcManager.initializeFrontend(this._ipc, opts?.iModelApp?.rpcInterfaces);
|
|
55
53
|
}
|
|
56
54
|
await core_frontend_1.NativeApp.startup(this._ipc, opts);
|
|
57
55
|
}
|
|
@@ -1 +1 @@
|
|
|
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
|
|
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,MAAM,CAAC,OAAO,IAAI,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,IAAI,EAAE,SAAS,EAAE,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 in 3.x. 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": "4.0.0-dev.
|
|
3
|
+
"version": "4.0.0-dev.41",
|
|
4
4
|
"description": "iTwin.js ElectronHost and ElectronApp",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": "
|
|
7
|
+
"node": "^18.0.0"
|
|
8
8
|
},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -20,27 +20,27 @@
|
|
|
20
20
|
"url": "http://www.bentley.com"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"@itwin/core-backend": "^4.0.0-dev.
|
|
24
|
-
"@itwin/core-bentley": "^4.0.0-dev.
|
|
25
|
-
"@itwin/core-common": "^4.0.0-dev.
|
|
26
|
-
"@itwin/core-frontend": "^4.0.0-dev.
|
|
27
|
-
"@itwin/presentation-common": "^4.0.0-dev.
|
|
28
|
-
"electron": "
|
|
23
|
+
"@itwin/core-backend": "^4.0.0-dev.41",
|
|
24
|
+
"@itwin/core-bentley": "^4.0.0-dev.41",
|
|
25
|
+
"@itwin/core-common": "^4.0.0-dev.41",
|
|
26
|
+
"@itwin/core-frontend": "^4.0.0-dev.41",
|
|
27
|
+
"@itwin/presentation-common": "^4.0.0-dev.41",
|
|
28
|
+
"electron": "^23.0.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@itwin/build-tools": "4.0.0-dev.
|
|
32
|
-
"@itwin/certa": "4.0.0-dev.
|
|
33
|
-
"@itwin/core-backend": "4.0.0-dev.
|
|
34
|
-
"@itwin/core-bentley": "4.0.0-dev.
|
|
35
|
-
"@itwin/core-common": "4.0.0-dev.
|
|
36
|
-
"@itwin/core-frontend": "4.0.0-dev.
|
|
37
|
-
"@itwin/eslint-plugin": "4.0.0-dev.
|
|
38
|
-
"@itwin/presentation-common": "4.0.0-dev.
|
|
31
|
+
"@itwin/build-tools": "4.0.0-dev.41",
|
|
32
|
+
"@itwin/certa": "4.0.0-dev.41",
|
|
33
|
+
"@itwin/core-backend": "4.0.0-dev.41",
|
|
34
|
+
"@itwin/core-bentley": "4.0.0-dev.41",
|
|
35
|
+
"@itwin/core-common": "4.0.0-dev.41",
|
|
36
|
+
"@itwin/core-frontend": "4.0.0-dev.41",
|
|
37
|
+
"@itwin/eslint-plugin": "4.0.0-dev.31",
|
|
38
|
+
"@itwin/presentation-common": "4.0.0-dev.41",
|
|
39
39
|
"@types/chai": "4.3.1",
|
|
40
40
|
"@types/mocha": "^8.2.2",
|
|
41
|
-
"@types/node": "18.11.5",
|
|
41
|
+
"@types/node": "^18.11.5",
|
|
42
42
|
"chai": "^4.1.2",
|
|
43
|
-
"electron": "^
|
|
43
|
+
"electron": "^23.0.0",
|
|
44
44
|
"eslint": "^7.11.0",
|
|
45
45
|
"mocha": "^10.0.0",
|
|
46
46
|
"rimraf": "^3.0.2",
|
|
@@ -61,18 +61,17 @@
|
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"build": "npm run -s build:cjs",
|
|
64
|
-
"build:ci": "npm run -s build",
|
|
64
|
+
"build:ci": "npm run -s build && npm run -s webpack:test",
|
|
65
65
|
"build:cjs": "tsc 1>&2 --outDir lib/cjs",
|
|
66
66
|
"clean": "rimraf lib .rush/temp/package-deps*.json",
|
|
67
67
|
"docs": "betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-electron/file.json --tsIndexFile=./__DOC_ONLY__.ts --onlyJson",
|
|
68
68
|
"extract-api": "betools extract-api --entry=__DOC_ONLY__",
|
|
69
69
|
"lint": "eslint -f visualstudio \"./src/**/*.ts\" 1>&2",
|
|
70
70
|
"test": "",
|
|
71
|
-
"test:integration": "npm run test:integration:backend && npm run test:integration:frontend
|
|
71
|
+
"test:integration": "npm run test:integration:backend && npm run test:integration:frontend",
|
|
72
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
73
|
"test:integration:frontend": "certa -r electron --config src/test/frontend/utils/certa.json",
|
|
75
|
-
"webpack:
|
|
74
|
+
"webpack:test": "webpack --config ./src/test/frontend/utils/webpack.config.js 1>&2",
|
|
76
75
|
"cover": ""
|
|
77
76
|
},
|
|
78
77
|
"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"
|