@cityofzion/bs-electron 0.1.57 → 0.1.59
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/dist/main.d.ts +1 -2
- package/dist/main.js +4 -35
- package/dist/renderer.js +12 -3
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +89 -18
- package/package.json +1 -1
package/dist/main.d.ts
CHANGED
package/dist/main.js
CHANGED
|
@@ -12,7 +12,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.eraseApi = eraseApi;
|
|
16
15
|
exports.exposeApiToRenderer = exposeApiToRenderer;
|
|
17
16
|
const utils_1 = require("./utils");
|
|
18
17
|
const utils_2 = require("./utils");
|
|
@@ -20,36 +19,6 @@ const electron_1 = require("electron");
|
|
|
20
19
|
const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep"));
|
|
21
20
|
const exposedApis = new Map();
|
|
22
21
|
let initialized = false;
|
|
23
|
-
// Erase the api to expose all methods and properties to renderer. It also supports nested objects
|
|
24
|
-
function eraseApi(api, prefix) {
|
|
25
|
-
const { asyncMethods, syncMethods, properties } = (0, utils_1.getPropertiesAndMethods)(api);
|
|
26
|
-
// As it is a recursive function, we need to add the prefix to the methods and properties
|
|
27
|
-
const response = {
|
|
28
|
-
asyncMethods: asyncMethods.map(method => (prefix ? `${prefix}.${method}` : method)),
|
|
29
|
-
syncMethods: syncMethods.map(method => (prefix ? `${prefix}.${method}` : method)),
|
|
30
|
-
properties: properties.map(property => (prefix ? `${prefix}.${property}` : property)),
|
|
31
|
-
};
|
|
32
|
-
// Iterate for all properties to discover nested objects
|
|
33
|
-
properties.forEach(property => {
|
|
34
|
-
const propertyValue = api[property];
|
|
35
|
-
// If the property is not an object, we don't need to iterate over it. Array is also considered an object so we need to disconsider it
|
|
36
|
-
if (typeof propertyValue !== 'object' ||
|
|
37
|
-
Array.isArray(propertyValue) ||
|
|
38
|
-
propertyValue instanceof Map ||
|
|
39
|
-
propertyValue instanceof Set)
|
|
40
|
-
return;
|
|
41
|
-
const propertyWithPrefix = prefix ? `${prefix}.${property}` : property;
|
|
42
|
-
// Recursive call to discover nested properties and methods
|
|
43
|
-
const nestedPropertiesAndMethods = eraseApi(propertyValue, propertyWithPrefix);
|
|
44
|
-
// Add the nested properties and methods to the response
|
|
45
|
-
response.syncMethods.push(...nestedPropertiesAndMethods.syncMethods);
|
|
46
|
-
response.asyncMethods.push(...nestedPropertiesAndMethods.asyncMethods);
|
|
47
|
-
response.properties.push(...nestedPropertiesAndMethods.properties);
|
|
48
|
-
// Remove the actual property because it is a instance and can't be serialized by ipc
|
|
49
|
-
response.properties.splice(response.properties.indexOf(propertyWithPrefix), 1);
|
|
50
|
-
});
|
|
51
|
-
return response;
|
|
52
|
-
}
|
|
53
22
|
function exposeApiToRenderer(api) {
|
|
54
23
|
init();
|
|
55
24
|
// Class name
|
|
@@ -60,7 +29,7 @@ function exposeApiToRenderer(api) {
|
|
|
60
29
|
return;
|
|
61
30
|
}
|
|
62
31
|
const apiClone = (0, lodash_clonedeep_1.default)(api);
|
|
63
|
-
const { asyncMethods, properties, syncMethods } = eraseApi(apiClone);
|
|
32
|
+
const { asyncMethods, properties, syncMethods } = (0, utils_1.eraseApi)(apiClone);
|
|
64
33
|
// For each property, we need to create a listener so renderer can request the property value
|
|
65
34
|
properties.forEach(property => {
|
|
66
35
|
electron_1.ipcMain.on((0, utils_2.buildIpcChannelName)(apiName, property), event => {
|
|
@@ -69,7 +38,7 @@ function exposeApiToRenderer(api) {
|
|
|
69
38
|
event.returnValue = { data: value };
|
|
70
39
|
}
|
|
71
40
|
catch (error) {
|
|
72
|
-
event.returnValue = { error: error.message };
|
|
41
|
+
event.returnValue = { error: { message: error.message, stack: error.stack, name: error.name } };
|
|
73
42
|
}
|
|
74
43
|
});
|
|
75
44
|
});
|
|
@@ -82,7 +51,7 @@ function exposeApiToRenderer(api) {
|
|
|
82
51
|
event.returnValue = { data };
|
|
83
52
|
}
|
|
84
53
|
catch (error) {
|
|
85
|
-
event.returnValue = { error: error.message };
|
|
54
|
+
event.returnValue = { error: { message: error.message, stack: error.stack, name: error.name } };
|
|
86
55
|
}
|
|
87
56
|
});
|
|
88
57
|
});
|
|
@@ -95,7 +64,7 @@ function exposeApiToRenderer(api) {
|
|
|
95
64
|
return { data };
|
|
96
65
|
}
|
|
97
66
|
catch (error) {
|
|
98
|
-
return { error: error.message };
|
|
67
|
+
return { error: { message: error.message, stack: error.stack, name: error.name } };
|
|
99
68
|
}
|
|
100
69
|
}));
|
|
101
70
|
});
|
package/dist/renderer.js
CHANGED
|
@@ -29,7 +29,10 @@ function bindApiFromMain(apiName) {
|
|
|
29
29
|
get: () => {
|
|
30
30
|
const result = window.ipcBsElectron.sendSync((0, utils_1.buildIpcChannelName)(apiName, property));
|
|
31
31
|
if (result.error) {
|
|
32
|
-
|
|
32
|
+
const error = new Error(result.error.message);
|
|
33
|
+
error.name = result.error.name;
|
|
34
|
+
error.stack = result.error.stack;
|
|
35
|
+
throw error;
|
|
33
36
|
}
|
|
34
37
|
return result.data;
|
|
35
38
|
},
|
|
@@ -42,7 +45,10 @@ function bindApiFromMain(apiName) {
|
|
|
42
45
|
const plainArgs = (0, utils_1.toPlainObject)(args);
|
|
43
46
|
const result = window.ipcBsElectron.sendSync((0, utils_1.buildIpcChannelName)(apiName, method), ...plainArgs);
|
|
44
47
|
if (result.error) {
|
|
45
|
-
|
|
48
|
+
const error = new Error(result.error.message);
|
|
49
|
+
error.name = result.error.name;
|
|
50
|
+
error.stack = result.error.stack;
|
|
51
|
+
throw error;
|
|
46
52
|
}
|
|
47
53
|
return result.data;
|
|
48
54
|
},
|
|
@@ -55,7 +61,10 @@ function bindApiFromMain(apiName) {
|
|
|
55
61
|
const plainArgs = (0, utils_1.toPlainObject)(args);
|
|
56
62
|
const result = yield window.ipcBsElectron.invoke((0, utils_1.buildIpcChannelName)(apiName, method), ...plainArgs);
|
|
57
63
|
if (result.error) {
|
|
58
|
-
|
|
64
|
+
const error = new Error(result.error.message);
|
|
65
|
+
error.name = result.error.name;
|
|
66
|
+
error.stack = result.error.stack;
|
|
67
|
+
throw error;
|
|
59
68
|
}
|
|
60
69
|
return result.data;
|
|
61
70
|
}),
|
package/dist/utils.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export type TExposedApi = {
|
|
|
8
8
|
syncMethods: string[];
|
|
9
9
|
asyncMethods: string[];
|
|
10
10
|
};
|
|
11
|
+
export declare function fixSimpleObject(api: TExposedApi): string[];
|
|
12
|
+
export declare function eraseApi(api: any, prefix?: string): TExposedApi;
|
|
11
13
|
export declare function getPropertiesAndMethods(object: any): {
|
|
12
14
|
properties: string[];
|
|
13
15
|
syncMethods: string[];
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GET_EXPOSED_API_CHANNEL = exports.CHANNEL_PREFIX = void 0;
|
|
4
|
+
exports.fixSimpleObject = fixSimpleObject;
|
|
5
|
+
exports.eraseApi = eraseApi;
|
|
4
6
|
exports.getPropertiesAndMethods = getPropertiesAndMethods;
|
|
5
7
|
exports.getValueFromPath = getValueFromPath;
|
|
6
8
|
exports.populateObjectFromPath = populateObjectFromPath;
|
|
@@ -8,6 +10,68 @@ exports.buildIpcChannelName = buildIpcChannelName;
|
|
|
8
10
|
exports.toPlainObject = toPlainObject;
|
|
9
11
|
exports.CHANNEL_PREFIX = 'bsElectron';
|
|
10
12
|
exports.GET_EXPOSED_API_CHANNEL = `${exports.CHANNEL_PREFIX}:getExposedApi`;
|
|
13
|
+
function fixSimpleObject(api) {
|
|
14
|
+
const methods = [...api.asyncMethods, ...api.syncMethods];
|
|
15
|
+
const newProperties = new Set();
|
|
16
|
+
for (const property of api.properties) {
|
|
17
|
+
const pathSegments = property.split('.');
|
|
18
|
+
// Handle root level properties (no dots)
|
|
19
|
+
if (pathSegments.length === 1) {
|
|
20
|
+
newProperties.add(property);
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const pathWithoutLastSegment = pathSegments.slice(0, -1).join('.');
|
|
24
|
+
// Skip if we already processed this parent path
|
|
25
|
+
if (newProperties.has(pathWithoutLastSegment)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
// Check if this path or any of its sub-paths have methods
|
|
29
|
+
const hasMethod = methods.some(method => method.startsWith(pathWithoutLastSegment));
|
|
30
|
+
if (hasMethod) {
|
|
31
|
+
newProperties.add(property);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
// If no methods are found in this path, it means it's a simple object, so we add only the parent path
|
|
35
|
+
newProperties.add(pathWithoutLastSegment);
|
|
36
|
+
}
|
|
37
|
+
return Array.from(newProperties);
|
|
38
|
+
}
|
|
39
|
+
// Erase the api to expose all methods and properties to renderer. It also supports nested objects
|
|
40
|
+
function eraseApi(api, prefix) {
|
|
41
|
+
const { asyncMethods, syncMethods, properties } = getPropertiesAndMethods(api);
|
|
42
|
+
// As it is a recursive function, we need to add the prefix to the methods and properties
|
|
43
|
+
const response = {
|
|
44
|
+
asyncMethods: asyncMethods.map(method => (prefix ? `${prefix}.${method}` : method)),
|
|
45
|
+
syncMethods: syncMethods.map(method => (prefix ? `${prefix}.${method}` : method)),
|
|
46
|
+
properties: properties.map(property => (prefix ? `${prefix}.${property}` : property)),
|
|
47
|
+
};
|
|
48
|
+
// Iterate for all properties to discover nested objects
|
|
49
|
+
properties.forEach(property => {
|
|
50
|
+
const propertyValue = api[property];
|
|
51
|
+
// If the property is not an object, we don't need to iterate over it. Array is also considered an object so we need to disconsider it
|
|
52
|
+
if (typeof propertyValue !== 'object' ||
|
|
53
|
+
Array.isArray(propertyValue) ||
|
|
54
|
+
propertyValue instanceof Map ||
|
|
55
|
+
propertyValue instanceof Set) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const propertyWithPrefix = prefix ? `${prefix}.${property}` : property;
|
|
59
|
+
// Recursive call to discover nested properties and methods
|
|
60
|
+
const nestedResult = eraseApi(propertyValue, propertyWithPrefix);
|
|
61
|
+
// Add the nested properties and methods to the response
|
|
62
|
+
response.syncMethods.push(...nestedResult.syncMethods);
|
|
63
|
+
response.asyncMethods.push(...nestedResult.asyncMethods);
|
|
64
|
+
response.properties.push(...nestedResult.properties);
|
|
65
|
+
// Remove the actual property because it is a instance and can't be serialized by ipc
|
|
66
|
+
response.properties.splice(response.properties.indexOf(propertyWithPrefix), 1);
|
|
67
|
+
});
|
|
68
|
+
response.properties = fixSimpleObject({
|
|
69
|
+
asyncMethods: response.asyncMethods,
|
|
70
|
+
syncMethods: response.syncMethods,
|
|
71
|
+
properties: response.properties,
|
|
72
|
+
});
|
|
73
|
+
return response;
|
|
74
|
+
}
|
|
11
75
|
// It returns all properties and methods from an object and its prototype chain, that is, extended classes are also considered
|
|
12
76
|
function getPropertiesAndMethods(object) {
|
|
13
77
|
const syncMethods = new Set();
|
|
@@ -15,29 +79,36 @@ function getPropertiesAndMethods(object) {
|
|
|
15
79
|
const properties = new Set();
|
|
16
80
|
do {
|
|
17
81
|
for (const key of Reflect.ownKeys(object)) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
82
|
+
try {
|
|
83
|
+
if (key === 'constructor')
|
|
84
|
+
continue;
|
|
85
|
+
const keyString = String(key);
|
|
86
|
+
if (keyString.startsWith('_') || keyString.startsWith('#'))
|
|
87
|
+
continue;
|
|
88
|
+
if (typeof object[key] === 'function') {
|
|
89
|
+
const funcString = object[key].toString();
|
|
90
|
+
// Check for async patterns:
|
|
91
|
+
// 1. Native async: 'async function' or 'async ('
|
|
92
|
+
// 2. TypeScript compiled: '__awaiter' helper
|
|
93
|
+
// 3. Babel compiled: '_asyncToGenerator' helper
|
|
94
|
+
const isAsync = funcString.includes('__awaiter') ||
|
|
95
|
+
funcString.includes('_asyncToGenerator') ||
|
|
96
|
+
funcString.startsWith('async ') ||
|
|
97
|
+
funcString.startsWith('async(') ||
|
|
98
|
+
funcString.includes('async function');
|
|
99
|
+
if (isAsync) {
|
|
30
100
|
asyncMethods.add(keyString);
|
|
31
|
-
continue;
|
|
32
101
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
102
|
+
else {
|
|
103
|
+
syncMethods.add(keyString);
|
|
104
|
+
}
|
|
105
|
+
continue;
|
|
37
106
|
}
|
|
107
|
+
properties.add(keyString);
|
|
108
|
+
}
|
|
109
|
+
catch (_a) {
|
|
38
110
|
continue;
|
|
39
111
|
}
|
|
40
|
-
properties.add(keyString);
|
|
41
112
|
}
|
|
42
113
|
} while ((object = Reflect.getPrototypeOf(object)) && object !== Object.prototype);
|
|
43
114
|
return {
|