@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 CHANGED
@@ -1,3 +1,2 @@
1
- import { TApi, TExposedApi } from './utils';
2
- export declare function eraseApi(api: any, prefix?: string): TExposedApi;
1
+ import { TApi } from './utils';
3
2
  export declare function exposeApiToRenderer<T extends TApi>(api: T): void;
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
- throw new Error('Ipc only supports stringified data');
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
- throw new Error(result.error);
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
- throw new Error(result.error);
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
- if (key === 'constructor')
19
- continue;
20
- const keyString = String(key);
21
- if (keyString.startsWith('_') || keyString.startsWith('#'))
22
- continue;
23
- if (typeof object[key] === 'function') {
24
- try {
25
- // Get the number of parameters of the function to call it with empty objects
26
- const params = Array.from({ length: object[key].length }, () => ({}));
27
- const funcResponse = object[key].call(object, ...params);
28
- if (funcResponse instanceof Promise) {
29
- funcResponse.catch(() => { }).then(() => { });
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
- syncMethods.add(keyString);
34
- }
35
- catch (_a) {
36
- syncMethods.add(keyString);
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 {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cityofzion/bs-electron",
3
- "version": "0.1.57",
3
+ "version": "0.1.59",
4
4
  "repository": "https://github.com/CityOfZion/blockchain-services",
5
5
  "author": "Coz",
6
6
  "license": "GPL-3.0-only",