Skip to content

Commit 0f9d340

Browse files
authored
refactor(main): Separate electron API Node.js api (#392)
* chore(main): Remove electronApi loader workaround * refactoring(main): Rename getName and getVersion to getAppName and getAppVersion * refactor(main): Separate electron and node.js api * fix(main): bind initialize method
1 parent f1844e0 commit 0f9d340

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+721
-625
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 5.1.0
4+
5+
- New entry point for NW.js / Node.js apps: `'electron-log/node'`
6+
37
## 5.0.0
48

59
### Core

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ only log functions like `info`, `warn` and so on.
5353
There are a few other ways how a logger can be initialized for a renderer
5454
process. [Read more](docs/initialize.md).
5555

56+
### Node.js and NW.js
57+
58+
```typescript
59+
import log from 'electron-log/node';
60+
log.info('Log from the nw.js or node.js');
61+
```
62+
5663
### electron-log v2.x, v3.x, v4.x
5764

5865
If you would like to upgrade to the latest version, read

node.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { NodeLogger } from './src';
2+
3+
declare const Logger: NodeLogger & {
4+
default: NodeLogger;
5+
};
6+
export = Logger;

node.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use strict';
2+
3+
const node = require('./src/node');
4+
5+
module.exports = node;

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "electron-log",
3-
"version": "5.0.5-beta.2",
3+
"version": "5.1.0-beta.1",
44
"description": "Just a simple logging module for your Electron application",
55
"main": "src/index.js",
66
"browser": "src/renderer/index.js",
@@ -24,6 +24,8 @@
2424
"src/*",
2525
"main.js",
2626
"main.d.ts",
27+
"node.js",
28+
"node.d.ts",
2729
"preload.js",
2830
"renderer.js",
2931
"renderer.d.ts"

src/core/Logger.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const scopeFactory = require('./scope');
1313
class Logger {
1414
static instances = {};
1515

16+
dependencies = {};
1617
errorHandler = null;
1718
eventLogger = null;
1819
functions = {};
@@ -26,6 +27,7 @@ class Logger {
2627

2728
constructor({
2829
allowUnknownLevel = false,
30+
dependencies = {},
2931
errorHandler,
3032
eventLogger,
3133
initializeFn,
@@ -37,10 +39,12 @@ class Logger {
3739
} = {}) {
3840
this.addLevel = this.addLevel.bind(this);
3941
this.create = this.create.bind(this);
42+
this.initialize = this.initialize.bind(this);
4043
this.logData = this.logData.bind(this);
4144
this.processMessage = this.processMessage.bind(this);
4245

4346
this.allowUnknownLevel = allowUnknownLevel;
47+
this.dependencies = dependencies;
4448
this.initializeFn = initializeFn;
4549
this.isDev = isDev;
4650
this.levels = levels;
@@ -55,13 +59,13 @@ class Logger {
5559
}
5660

5761
this.errorHandler = errorHandler;
58-
errorHandler?.setOptions({ logFn: this.error });
62+
errorHandler?.setOptions({ ...dependencies, logFn: this.error });
5963

6064
this.eventLogger = eventLogger;
61-
eventLogger?.setOptions({ logger: this });
65+
eventLogger?.setOptions({ ...dependencies, logger: this });
6266

6367
for (const [name, factory] of Object.entries(transportFactories)) {
64-
this.transports[name] = factory(this);
68+
this.transports[name] = factory(this, dependencies);
6569
}
6670

6771
Logger.instances[logId] = this;
@@ -97,12 +101,13 @@ class Logger {
97101
}
98102

99103
return new Logger({
100-
...options,
104+
dependencies: this.dependencies,
101105
errorHandler: this.errorHandler,
102106
initializeFn: this.initializeFn,
103107
isDev: this.isDev,
104108
transportFactories: this.transportFactories,
105109
variables: { ...this.variables },
110+
...options,
106111
});
107112
}
108113

@@ -117,7 +122,7 @@ class Logger {
117122
}
118123

119124
initialize(options = {}) {
120-
this.initializeFn({ logger: this, ...options });
125+
this.initializeFn({ logger: this, ...this.dependencies, ...options });
121126
}
122127

123128
logData(data, options = {}) {

src/index.d.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,13 @@ declare namespace Logger {
615615
): void;
616616
}
617617

618-
interface MainLogger extends Logger {
618+
interface NodeLogger extends Logger {
619+
errorHandler: ErrorHandler<MainErrorHandlerOptions>;
620+
eventLogger: EventLogger;
621+
transports: MainTransports;
622+
}
623+
624+
interface MainLogger extends NodeLogger {
619625
initialize(
620626
options?: {
621627
getSessions?: () => object[];
@@ -624,10 +630,6 @@ declare namespace Logger {
624630
spyRendererConsole?: boolean;
625631
},
626632
): void;
627-
628-
errorHandler: ErrorHandler<MainErrorHandlerOptions>;
629-
eventLogger: EventLogger;
630-
transports: MainTransports;
631633
}
632634

633635
interface RendererLogger extends Logger {

src/index.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
const isRenderer = typeof process === 'undefined'
66
|| (process.type === 'renderer' || process.type === 'worker');
77

8+
const isMain = typeof process === 'object' && process.type === 'browser';
9+
810
if (isRenderer) {
911
// Makes sense when contextIsolation/sandbox disabled
1012
require('./renderer/electron-log-preload');
1113
module.exports = require('./renderer');
12-
} else {
14+
} else if (isMain) {
1315
module.exports = require('./main');
16+
} else {
17+
module.exports = require('./node');
1418
}

src/main/ElectronExternalApi.js

+170
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
'use strict';
2+
3+
const electron = require('electron');
4+
const path = require('path');
5+
const NodeExternalApi = require('../node/NodeExternalApi');
6+
7+
class ElectronExternalApi extends NodeExternalApi {
8+
getAppName() {
9+
try {
10+
return electron.app?.name || electron.app?.getName();
11+
} catch {
12+
return super.getAppName();
13+
}
14+
}
15+
16+
getAppUserDataPath(appName) {
17+
return this.getPath('userData') || super.getAppUserDataPath(appName);
18+
}
19+
20+
getAppVersion() {
21+
try {
22+
return electron.app?.getVersion();
23+
} catch {
24+
return super.getAppVersion();
25+
}
26+
}
27+
28+
getElectronLogPath() {
29+
return this.getPath('logs') || super.getElectronLogPath();
30+
}
31+
32+
/**
33+
* @private
34+
* @param {any} name
35+
* @returns {string|undefined}
36+
*/
37+
getPath(name) {
38+
try {
39+
return electron.app?.getPath(name);
40+
} catch {
41+
return undefined;
42+
}
43+
}
44+
45+
getVersions() {
46+
return {
47+
app: `${this.getAppName()} ${this.getAppVersion()}`,
48+
electron: `Electron ${process.versions.electron}`,
49+
os: this.getOsVersion(),
50+
};
51+
}
52+
53+
getSystemPathAppData() {
54+
return this.getPath('appData') || super.getSystemPathAppData();
55+
}
56+
57+
isDev() {
58+
if (electron.app?.isPackaged !== undefined) {
59+
return !electron.app.isPackaged;
60+
}
61+
62+
if (typeof process.execPath === 'string') {
63+
const execFileName = path.basename(process.execPath).toLowerCase();
64+
return execFileName.startsWith('electron');
65+
}
66+
67+
return super.isDev();
68+
}
69+
70+
onAppEvent(eventName, handler) {
71+
electron.app?.on(eventName, handler);
72+
73+
return () => {
74+
electron.app?.off(eventName, handler);
75+
};
76+
}
77+
78+
onAppReady(handler) {
79+
if (electron.app?.isReady()) {
80+
handler();
81+
} else if (electron.app?.once) {
82+
electron.app?.once('ready', handler);
83+
} else {
84+
handler();
85+
}
86+
}
87+
88+
onEveryWebContentsEvent(eventName, handler) {
89+
electron.webContents?.getAllWebContents().forEach((webContents) => {
90+
webContents.on(eventName, handler);
91+
});
92+
93+
electron.app?.on('web-contents-created', onWebContentsCreated);
94+
95+
return () => {
96+
electron.webContents?.getAllWebContents().forEach((webContents) => {
97+
webContents.off(eventName, handler);
98+
});
99+
100+
electron.app?.off('web-contents-created', onWebContentsCreated);
101+
};
102+
103+
function onWebContentsCreated(_, webContents) {
104+
webContents.on(eventName, handler);
105+
}
106+
}
107+
108+
/**
109+
* Listen to async messages sent from opposite process
110+
* @param {string} channel
111+
* @param {function} listener
112+
*/
113+
onIpc(channel, listener) {
114+
electron.ipcMain?.on(channel, listener);
115+
}
116+
117+
onIpcInvoke(channel, listener) {
118+
electron.ipcMain?.handle?.(channel, listener);
119+
}
120+
121+
/**
122+
* @param {string} url
123+
* @param {Function} [logFunction]
124+
*/
125+
openUrl(url, logFunction = console.error) { // eslint-disable-line no-console
126+
electron.shell?.openExternal(url).catch(logFunction);
127+
}
128+
129+
setPreloadFileForSessions({
130+
filePath,
131+
includeFutureSession = true,
132+
getSessions = () => [electron.session?.defaultSession],
133+
}) {
134+
for (const session of getSessions().filter(Boolean)) {
135+
setPreload(session);
136+
}
137+
138+
if (includeFutureSession) {
139+
this.onAppEvent('session-created', (session) => {
140+
setPreload(session);
141+
});
142+
}
143+
144+
/**
145+
* @param {Session} session
146+
*/
147+
function setPreload(session) {
148+
session.setPreloads([...session.getPreloads(), filePath]);
149+
}
150+
}
151+
152+
/**
153+
* Sent a message to opposite process
154+
* @param {string} channel
155+
* @param {any} message
156+
*/
157+
sendIpc(channel, message) {
158+
electron.BrowserWindow?.getAllWindows().forEach((wnd) => {
159+
if (wnd.webContents?.isDestroyed() === false) {
160+
wnd.webContents.send(channel, message);
161+
}
162+
});
163+
}
164+
165+
showErrorBox(title, message) {
166+
electron.dialog?.showErrorBox(title, message);
167+
}
168+
}
169+
170+
module.exports = ElectronExternalApi;

src/main/__specs__/index.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const log = require('../index');
44

5-
describe('index', () => {
5+
describe('main/index', () => {
66
it('should contain all methods of Console API', () => {
77
const levels = [
88
'error',

0 commit comments

Comments
 (0)