@bolloon/bolloon-agent 0.3.36 → 0.3.37
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/electron/config.js +9 -14
- package/dist/electron/dialogs.js +16 -53
- package/dist/electron/first-run.js +24 -65
- package/dist/electron/ipc.js +10 -14
- package/dist/electron/logger.js +7 -44
- package/dist/electron/main.js +42 -45
- package/dist/electron/menu.js +13 -18
- package/dist/electron/paths.js +12 -54
- package/dist/electron/server.js +18 -57
- package/dist/electron/tray.js +15 -53
- package/dist/electron/window.js +22 -61
- package/dist/electron-build/electron/config.js +21 -0
- package/dist/electron-build/electron/config.js.map +1 -0
- package/dist/electron-build/electron/dialogs.js +108 -0
- package/dist/electron-build/electron/dialogs.js.map +1 -0
- package/dist/electron-build/electron/first-run.js +170 -0
- package/dist/electron-build/electron/first-run.js.map +1 -0
- package/dist/electron-build/electron/ipc.js +20 -0
- package/dist/electron-build/electron/ipc.js.map +1 -0
- package/dist/electron-build/electron/logger.js +114 -0
- package/dist/electron-build/electron/logger.js.map +1 -0
- package/dist/electron-build/electron/main.js +79 -0
- package/dist/electron-build/electron/main.js.map +1 -0
- package/dist/electron-build/electron/menu.js +145 -0
- package/dist/electron-build/electron/menu.js.map +1 -0
- package/dist/electron-build/electron/paths.js +75 -0
- package/dist/electron-build/electron/paths.js.map +1 -0
- package/dist/electron-build/electron/server.js +119 -0
- package/dist/electron-build/electron/server.js.map +1 -0
- package/dist/electron-build/electron/tray.js +111 -0
- package/dist/electron-build/electron/tray.js.map +1 -0
- package/dist/electron-build/electron/window.js +111 -0
- package/dist/electron-build/electron/window.js.map +1 -0
- package/dist/electron-build/electron-preload.js +32 -0
- package/dist/electron-build/electron-preload.js.map +1 -0
- package/dist/electron-build/electron.js +8 -0
- package/dist/electron-build/electron.js.map +1 -0
- package/dist/electron-build/utils/auto-update.js +598 -0
- package/dist/electron-build/utils/auto-update.js.map +1 -0
- package/dist/electron-preload.js +16 -19
- package/dist/electron.js +1 -4
- package/dist/utils/auto-update.js +12 -51
- package/package.json +5 -4
package/dist/electron/paths.js
CHANGED
|
@@ -1,44 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.dataDir = dataDir;
|
|
37
|
-
exports.userDataDir = userDataDir;
|
|
38
|
-
exports.logsDir = logsDir;
|
|
39
|
-
exports.mainLogPath = mainLogPath;
|
|
40
|
-
exports.firstRunFlagPath = firstRunFlagPath;
|
|
41
|
-
exports.buildResourcesDir = buildResourcesDir;
|
|
42
1
|
/**
|
|
43
2
|
* 路径常量 — 单一来源, 避免散落各处
|
|
44
3
|
*
|
|
@@ -47,29 +6,28 @@ exports.buildResourcesDir = buildResourcesDir;
|
|
|
47
6
|
* userDataDir: Electron 的 app.getPath('userData'), 用来放日志 / 临时 / 锁文件
|
|
48
7
|
* logsDir: userData 下的 logs/ 子目录
|
|
49
8
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
function dataDir() {
|
|
9
|
+
import { app } from 'electron';
|
|
10
|
+
import * as os from 'os';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
export function dataDir() {
|
|
54
13
|
return path.join(os.homedir(), '.bolloon');
|
|
55
14
|
}
|
|
56
|
-
function userDataDir() {
|
|
57
|
-
return
|
|
15
|
+
export function userDataDir() {
|
|
16
|
+
return app.getPath('userData');
|
|
58
17
|
}
|
|
59
|
-
function logsDir() {
|
|
18
|
+
export function logsDir() {
|
|
60
19
|
return path.join(userDataDir(), 'logs');
|
|
61
20
|
}
|
|
62
|
-
function mainLogPath() {
|
|
21
|
+
export function mainLogPath() {
|
|
63
22
|
return path.join(logsDir(), 'bolloon.log');
|
|
64
23
|
}
|
|
65
|
-
function firstRunFlagPath() {
|
|
24
|
+
export function firstRunFlagPath() {
|
|
66
25
|
return path.join(userDataDir(), '.bolloon-first-run-seen');
|
|
67
26
|
}
|
|
68
27
|
/** 资源目录: packaged 下是 process.resourcesPath/build, dev 下是 repo/build/ */
|
|
69
|
-
function buildResourcesDir() {
|
|
70
|
-
if (
|
|
28
|
+
export function buildResourcesDir() {
|
|
29
|
+
if (app.isPackaged) {
|
|
71
30
|
return path.join(process.resourcesPath, 'build');
|
|
72
31
|
}
|
|
73
|
-
return path.join(
|
|
32
|
+
return path.join(app.getAppPath(), 'build');
|
|
74
33
|
}
|
|
75
|
-
//# sourceMappingURL=paths.js.map
|
package/dist/electron/server.js
CHANGED
|
@@ -1,51 +1,13 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.getWebServerProcess = getWebServerProcess;
|
|
37
|
-
exports.killWebServer = killWebServer;
|
|
38
|
-
exports.startWebServer = startWebServer;
|
|
39
1
|
/**
|
|
40
2
|
* Spawns dist/web/server.js as a child Node process (via Electron's
|
|
41
3
|
* ELECTRON_RUN_AS_NODE=1) and parses BOLLOON_PORT=NNNN to learn the
|
|
42
4
|
* actually-bound port (which may have drifted from the preferred port
|
|
43
5
|
* due to EADDRINUSE auto-bump).
|
|
44
6
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
7
|
+
import { spawn } from 'child_process';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { log } from './logger';
|
|
10
|
+
import { WEB_SERVER_STARTUP_TIMEOUT_MS, DEFAULT_HOST } from './config';
|
|
49
11
|
// Resolve to the directory holding this file. See src/electron/window.ts for the rationale;
|
|
50
12
|
// this avoids the same `import.meta` / `__dirname` redeclaration conflicts that broke
|
|
51
13
|
// the electron tsconfig when esnext module mode was set.
|
|
@@ -53,30 +15,30 @@ const g = globalThis;
|
|
|
53
15
|
const __basedir = g.__dirname
|
|
54
16
|
?? (g.__filename ? path.dirname(g.__filename) : process.cwd());
|
|
55
17
|
let webServerProcess = null;
|
|
56
|
-
function getWebServerProcess() {
|
|
18
|
+
export function getWebServerProcess() {
|
|
57
19
|
return webServerProcess;
|
|
58
20
|
}
|
|
59
|
-
function killWebServer() {
|
|
21
|
+
export function killWebServer() {
|
|
60
22
|
if (webServerProcess && !webServerProcess.killed) {
|
|
61
|
-
|
|
23
|
+
log('终止 Web 服务器进程');
|
|
62
24
|
webServerProcess.kill();
|
|
63
25
|
}
|
|
64
26
|
webServerProcess = null;
|
|
65
27
|
}
|
|
66
|
-
function startWebServer(preferredPort) {
|
|
28
|
+
export function startWebServer(preferredPort) {
|
|
67
29
|
return new Promise((resolve, reject) => {
|
|
68
30
|
const serverScript = path.join(__basedir, '..', 'web', 'server.js');
|
|
69
|
-
|
|
31
|
+
log(`启动 Web 服务器进程: ${serverScript}`);
|
|
70
32
|
// ELECTRON_RUN_AS_NODE=1 — packaged 时 process.execPath 是 Electron 二进制,
|
|
71
33
|
// 没这行 require() 会失败. Dev 模式 (electron dist/electron.js) 同样情况.
|
|
72
|
-
webServerProcess =
|
|
34
|
+
webServerProcess = spawn(process.execPath, [serverScript], {
|
|
73
35
|
env: {
|
|
74
36
|
...process.env,
|
|
75
37
|
ELECTRON_RUN_AS_NODE: '1',
|
|
76
38
|
NODE_ENV: 'production',
|
|
77
39
|
PORT: String(preferredPort),
|
|
78
40
|
ELECTRON_PORT: String(preferredPort),
|
|
79
|
-
BOLLOON_HOST:
|
|
41
|
+
BOLLOON_HOST: DEFAULT_HOST,
|
|
80
42
|
},
|
|
81
43
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
82
44
|
});
|
|
@@ -88,32 +50,31 @@ function startWebServer(preferredPort) {
|
|
|
88
50
|
const m = stdoutBuf.match(/^BOLLOON_PORT=(\d+)/m);
|
|
89
51
|
if (m) {
|
|
90
52
|
const actualPort = parseInt(m[1], 10);
|
|
91
|
-
|
|
53
|
+
log(`Web 服务器就绪: 实际端口=${actualPort} (preferred=${preferredPort})`);
|
|
92
54
|
resolve({ port: actualPort });
|
|
93
55
|
}
|
|
94
56
|
});
|
|
95
57
|
webServerProcess.stderr?.on('data', (data) => {
|
|
96
58
|
stderrData += data.toString();
|
|
97
59
|
process.stderr.write(`[WebServer ERR] ${data}`);
|
|
98
|
-
|
|
60
|
+
log(`[WebServer stderr] ${data.toString().trim()}`, 'warn');
|
|
99
61
|
});
|
|
100
62
|
webServerProcess.on('error', (err) => {
|
|
101
|
-
|
|
63
|
+
log(`Web 服务器启动失败: ${err.message}`, 'error');
|
|
102
64
|
reject(err);
|
|
103
65
|
});
|
|
104
66
|
webServerProcess.on('exit', (code, signal) => {
|
|
105
|
-
|
|
67
|
+
log(`Web 服务器退出: code=${code} signal=${signal}`);
|
|
106
68
|
if (code !== 0 && code !== null) {
|
|
107
|
-
|
|
69
|
+
log(`Web 服务器 stderr: ${stderrData.slice(0, 500)}`, 'error');
|
|
108
70
|
}
|
|
109
71
|
webServerProcess = null;
|
|
110
72
|
});
|
|
111
73
|
setTimeout(() => {
|
|
112
74
|
if (webServerProcess && !webServerProcess.killed) {
|
|
113
|
-
|
|
75
|
+
log(`Web 服务器启动超时 (${WEB_SERVER_STARTUP_TIMEOUT_MS}ms)`, 'error');
|
|
114
76
|
reject(new Error('Web server startup timeout'));
|
|
115
77
|
}
|
|
116
|
-
},
|
|
78
|
+
}, WEB_SERVER_STARTUP_TIMEOUT_MS);
|
|
117
79
|
});
|
|
118
80
|
}
|
|
119
|
-
//# sourceMappingURL=server.js.map
|
package/dist/electron/tray.js
CHANGED
|
@@ -1,40 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.createTray = createTray;
|
|
37
|
-
exports.destroyTray = destroyTray;
|
|
38
1
|
/**
|
|
39
2
|
* 系统托盘 — Show / Hide / Quit
|
|
40
3
|
*
|
|
@@ -44,33 +7,33 @@ exports.destroyTray = destroyTray;
|
|
|
44
7
|
*
|
|
45
8
|
* 若 build 目录没有 tray 图标, 降级为不创建托盘 (主菜单和窗口关闭行为不变)
|
|
46
9
|
*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
10
|
+
import { Tray, Menu, nativeImage, app } from 'electron';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import { buildResourcesDir } from './paths';
|
|
14
|
+
import { log } from './logger';
|
|
52
15
|
let trayInstance = null;
|
|
53
16
|
function loadTrayIcon() {
|
|
54
17
|
const isMac = process.platform === 'darwin';
|
|
55
18
|
const file = isMac ? 'trayTemplate.png' : 'tray.png';
|
|
56
|
-
const iconPath = path.join(
|
|
19
|
+
const iconPath = path.join(buildResourcesDir(), file);
|
|
57
20
|
if (!fs.existsSync(iconPath)) {
|
|
58
|
-
|
|
21
|
+
log(`托盘图标缺失: ${iconPath} (跳过托盘创建)`, 'warn');
|
|
59
22
|
return null;
|
|
60
23
|
}
|
|
61
|
-
const img =
|
|
24
|
+
const img = nativeImage.createFromPath(iconPath);
|
|
62
25
|
if (isMac)
|
|
63
26
|
img.setTemplateImage(true);
|
|
64
27
|
return img;
|
|
65
28
|
}
|
|
66
|
-
function createTray(getMainWindow) {
|
|
29
|
+
export function createTray(getMainWindow) {
|
|
67
30
|
if (trayInstance)
|
|
68
31
|
return;
|
|
69
32
|
const icon = loadTrayIcon();
|
|
70
33
|
if (!icon)
|
|
71
34
|
return;
|
|
72
|
-
trayInstance = new
|
|
73
|
-
trayInstance.setToolTip(`Bolloon Agent v${
|
|
35
|
+
trayInstance = new Tray(icon);
|
|
36
|
+
trayInstance.setToolTip(`Bolloon Agent v${app.getVersion()}`);
|
|
74
37
|
const toggle = () => {
|
|
75
38
|
const w = getMainWindow();
|
|
76
39
|
if (!w)
|
|
@@ -85,14 +48,14 @@ function createTray(getMainWindow) {
|
|
|
85
48
|
w.focus();
|
|
86
49
|
}
|
|
87
50
|
};
|
|
88
|
-
const menu =
|
|
51
|
+
const menu = Menu.buildFromTemplate([
|
|
89
52
|
{ label: 'Show / Hide', click: () => toggle() },
|
|
90
53
|
{ type: 'separator' },
|
|
91
54
|
{
|
|
92
55
|
label: 'Quit',
|
|
93
56
|
click: () => {
|
|
94
|
-
|
|
95
|
-
|
|
57
|
+
log('托盘菜单 Quit');
|
|
58
|
+
app.quit();
|
|
96
59
|
},
|
|
97
60
|
},
|
|
98
61
|
]);
|
|
@@ -102,10 +65,9 @@ function createTray(getMainWindow) {
|
|
|
102
65
|
trayInstance.on('click', () => toggle());
|
|
103
66
|
}
|
|
104
67
|
}
|
|
105
|
-
function destroyTray() {
|
|
68
|
+
export function destroyTray() {
|
|
106
69
|
if (trayInstance) {
|
|
107
70
|
trayInstance.destroy();
|
|
108
71
|
trayInstance = null;
|
|
109
72
|
}
|
|
110
73
|
}
|
|
111
|
-
//# sourceMappingURL=tray.js.map
|
package/dist/electron/window.js
CHANGED
|
@@ -1,63 +1,25 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.getMainWindow = getMainWindow;
|
|
37
|
-
exports.createMainWindow = createMainWindow;
|
|
38
|
-
exports.focusMainWindow = focusMainWindow;
|
|
39
1
|
/**
|
|
40
2
|
* 主窗口工厂 — preload 路径解析 + dev/prod loadURL + 外部链接走系统浏览器
|
|
41
3
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
4
|
+
import { BrowserWindow, shell } from 'electron';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { log } from './logger';
|
|
7
|
+
import { isDev, MAIN_WINDOW_DEFAULT, MAIN_WINDOW_MIN, preferredPort } from './config';
|
|
8
|
+
import { startWebServer } from './server';
|
|
47
9
|
const g = globalThis;
|
|
48
10
|
const __basedir = g.__dirname
|
|
49
11
|
?? (g.__filename ? path.dirname(g.__filename) : process.cwd());
|
|
50
12
|
let mainWindow = null;
|
|
51
|
-
function getMainWindow() {
|
|
13
|
+
export function getMainWindow() {
|
|
52
14
|
return mainWindow;
|
|
53
15
|
}
|
|
54
|
-
async function createMainWindow() {
|
|
55
|
-
|
|
56
|
-
mainWindow = new
|
|
57
|
-
width:
|
|
58
|
-
height:
|
|
59
|
-
minWidth:
|
|
60
|
-
minHeight:
|
|
16
|
+
export async function createMainWindow() {
|
|
17
|
+
log('创建主窗口...');
|
|
18
|
+
mainWindow = new BrowserWindow({
|
|
19
|
+
width: MAIN_WINDOW_DEFAULT.width,
|
|
20
|
+
height: MAIN_WINDOW_DEFAULT.height,
|
|
21
|
+
minWidth: MAIN_WINDOW_MIN.width,
|
|
22
|
+
minHeight: MAIN_WINDOW_MIN.height,
|
|
61
23
|
title: 'Bolloon Agent',
|
|
62
24
|
webPreferences: {
|
|
63
25
|
nodeIntegration: false,
|
|
@@ -67,40 +29,40 @@ async function createMainWindow() {
|
|
|
67
29
|
},
|
|
68
30
|
show: false,
|
|
69
31
|
});
|
|
70
|
-
if (
|
|
32
|
+
if (isDev) {
|
|
71
33
|
// dev:web 用 tsx 起 server, 端口固定 preferredPort, 不会 EADDRINUSE 自增
|
|
72
|
-
const port =
|
|
34
|
+
const port = preferredPort();
|
|
73
35
|
mainWindow.loadURL(`http://localhost:${port}`);
|
|
74
36
|
mainWindow.webContents.openDevTools();
|
|
75
37
|
}
|
|
76
38
|
else {
|
|
77
39
|
try {
|
|
78
|
-
|
|
79
|
-
const { port: actualPort } = await
|
|
40
|
+
log('启动内置 Web 服务器...');
|
|
41
|
+
const { port: actualPort } = await startWebServer(preferredPort());
|
|
80
42
|
mainWindow.loadURL(`http://localhost:${actualPort}`);
|
|
81
43
|
}
|
|
82
44
|
catch (err) {
|
|
83
|
-
|
|
45
|
+
log(`启动服务器失败: ${err.message}`, 'error');
|
|
84
46
|
console.error('启动服务器失败:', err);
|
|
85
47
|
}
|
|
86
48
|
}
|
|
87
49
|
mainWindow.once('ready-to-show', () => {
|
|
88
50
|
mainWindow?.show();
|
|
89
|
-
|
|
51
|
+
log('窗口已显示');
|
|
90
52
|
});
|
|
91
53
|
// 外部链接走系统浏览器, 不在 app 内开新窗口
|
|
92
54
|
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
|
93
55
|
if (url.startsWith('http://') || url.startsWith('https://')) {
|
|
94
|
-
|
|
56
|
+
shell.openExternal(url);
|
|
95
57
|
}
|
|
96
58
|
return { action: 'deny' };
|
|
97
59
|
});
|
|
98
60
|
mainWindow.on('closed', () => {
|
|
99
61
|
mainWindow = null;
|
|
100
62
|
});
|
|
101
|
-
|
|
63
|
+
log('窗口创建完成');
|
|
102
64
|
}
|
|
103
|
-
function focusMainWindow() {
|
|
65
|
+
export function focusMainWindow() {
|
|
104
66
|
if (!mainWindow)
|
|
105
67
|
return;
|
|
106
68
|
if (mainWindow.isMinimized())
|
|
@@ -108,4 +70,3 @@ function focusMainWindow() {
|
|
|
108
70
|
mainWindow.show();
|
|
109
71
|
mainWindow.focus();
|
|
110
72
|
}
|
|
111
|
-
//# sourceMappingURL=window.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDev = exports.MAIN_WINDOW_MIN = exports.MAIN_WINDOW_DEFAULT = exports.WEB_SERVER_STARTUP_TIMEOUT_MS = exports.DEFAULT_HOST = exports.DEFAULT_PORT = void 0;
|
|
4
|
+
exports.preferredPort = preferredPort;
|
|
5
|
+
/**
|
|
6
|
+
* 常量配置 (env 解析在这里集中, 不散在 main 流程)
|
|
7
|
+
*/
|
|
8
|
+
const electron_1 = require("electron");
|
|
9
|
+
exports.DEFAULT_PORT = 54188;
|
|
10
|
+
/** Hard-pin to loopback; LAN exposure must be explicit. */
|
|
11
|
+
exports.DEFAULT_HOST = '127.0.0.1';
|
|
12
|
+
exports.WEB_SERVER_STARTUP_TIMEOUT_MS = 15_000;
|
|
13
|
+
exports.MAIN_WINDOW_DEFAULT = { width: 1200, height: 800 };
|
|
14
|
+
exports.MAIN_WINDOW_MIN = { width: 800, height: 600 };
|
|
15
|
+
function preferredPort() {
|
|
16
|
+
const raw = process.env.ELECTRON_PORT || process.env.PORT;
|
|
17
|
+
const n = parseInt(raw || '', 10);
|
|
18
|
+
return Number.isFinite(n) && n > 0 && n < 65536 ? n : exports.DEFAULT_PORT;
|
|
19
|
+
}
|
|
20
|
+
exports.isDev = process.env.NODE_ENV === 'development' || !electron_1.app.isPackaged;
|
|
21
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/electron/config.ts"],"names":[],"mappings":";;;AAcA,sCAIC;AAlBD;;GAEG;AACH,uCAA+B;AAElB,QAAA,YAAY,GAAG,KAAK,CAAC;AAClC,2DAA2D;AAC9C,QAAA,YAAY,GAAG,WAAW,CAAC;AAE3B,QAAA,6BAA6B,GAAG,MAAM,CAAC;AAEvC,QAAA,mBAAmB,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACnD,QAAA,eAAe,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAE3D,SAAgB,aAAa;IAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IAC1D,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAY,CAAC;AACrE,CAAC;AAEY,QAAA,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,CAAC,cAAG,CAAC,UAAU,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.registerDialogIpc = registerDialogIpc;
|
|
37
|
+
/**
|
|
38
|
+
* 文件 dialog 桥 (open / save / dir) + 安全的 fs 桥 (read / write / exists)
|
|
39
|
+
*
|
|
40
|
+
* 5MB read 上限保护 — 渲染进程直接 fs.readFile 没法做限制, 走主进程就有界
|
|
41
|
+
* 所有 handler 解析 event.sender 拿到 window, 让 dialog 模态在该窗口上
|
|
42
|
+
*/
|
|
43
|
+
const electron_1 = require("electron");
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const logger_1 = require("./logger");
|
|
47
|
+
const MAX_READ_BYTES = 5 * 1024 * 1024; // 5MB
|
|
48
|
+
function windowFor(event) {
|
|
49
|
+
return electron_1.BrowserWindow.fromWebContents(event.sender);
|
|
50
|
+
}
|
|
51
|
+
function resolveSafe(target) {
|
|
52
|
+
// 不去硬限制路径 — user 给 renderer 暴露 fs 已经信任了, 这里只 normalize
|
|
53
|
+
return path.resolve(target);
|
|
54
|
+
}
|
|
55
|
+
function registerDialogIpc() {
|
|
56
|
+
electron_1.ipcMain.handle('dialog:open-file', async (event, opts = {}) => {
|
|
57
|
+
const win = windowFor(event);
|
|
58
|
+
const result = await electron_1.dialog.showOpenDialog(win, {
|
|
59
|
+
title: opts.title,
|
|
60
|
+
defaultPath: opts.defaultPath,
|
|
61
|
+
filters: opts.filters,
|
|
62
|
+
properties: opts.properties ?? ['openFile'],
|
|
63
|
+
});
|
|
64
|
+
return { canceled: result.canceled, filePaths: result.filePaths };
|
|
65
|
+
});
|
|
66
|
+
electron_1.ipcMain.handle('dialog:save-file', async (event, opts = {}) => {
|
|
67
|
+
const win = windowFor(event);
|
|
68
|
+
const result = await electron_1.dialog.showSaveDialog(win, {
|
|
69
|
+
title: opts.title,
|
|
70
|
+
defaultPath: opts.defaultPath,
|
|
71
|
+
filters: opts.filters,
|
|
72
|
+
});
|
|
73
|
+
return { canceled: result.canceled, filePath: result.filePath };
|
|
74
|
+
});
|
|
75
|
+
electron_1.ipcMain.handle('dialog:open-directory', async (event, opts = {}) => {
|
|
76
|
+
const win = windowFor(event);
|
|
77
|
+
const result = await electron_1.dialog.showOpenDialog(win, {
|
|
78
|
+
title: opts.title,
|
|
79
|
+
defaultPath: opts.defaultPath,
|
|
80
|
+
properties: ['openDirectory', 'createDirectory'],
|
|
81
|
+
});
|
|
82
|
+
return { canceled: result.canceled, filePaths: result.filePaths };
|
|
83
|
+
});
|
|
84
|
+
electron_1.ipcMain.handle('fs:read-text-file', async (_event, opts) => {
|
|
85
|
+
const target = resolveSafe(opts.path);
|
|
86
|
+
const stat = fs.statSync(target);
|
|
87
|
+
if (stat.size > MAX_READ_BYTES) {
|
|
88
|
+
throw new Error(`文件过大: ${stat.size} > ${MAX_READ_BYTES} bytes`);
|
|
89
|
+
}
|
|
90
|
+
return fs.readFileSync(target, { encoding: opts.encoding ?? 'utf8' });
|
|
91
|
+
});
|
|
92
|
+
electron_1.ipcMain.handle('fs:write-text-file', async (_event, opts) => {
|
|
93
|
+
const target = resolveSafe(opts.path);
|
|
94
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
95
|
+
fs.writeFileSync(target, opts.content, { encoding: opts.encoding ?? 'utf8' });
|
|
96
|
+
});
|
|
97
|
+
electron_1.ipcMain.handle('fs:path-exists', async (_event, opts) => {
|
|
98
|
+
try {
|
|
99
|
+
fs.accessSync(resolveSafe(opts.path));
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
(0, logger_1.log)('dialog + fs IPC handlers registered');
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=dialogs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialogs.js","sourceRoot":"","sources":["../../../src/electron/dialogs.ts"],"names":[],"mappings":"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"}
|