zen-gitsync 2.9.10 → 2.9.11
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/package.json +2 -1
- package/src/ui/public/assets/index-CQo5GCtA.css +1 -0
- package/src/ui/public/assets/index-DT6eyL2d.js +108 -0
- package/src/ui/public/index.html +2 -2
- package/src/ui/server/index.js +5 -0
- package/src/ui/server/routes/code.js +96 -0
- package/src/ui/public/assets/index-CzUoE1WP.css +0 -1
- package/src/ui/public/assets/index-GE6lIBHK.js +0 -79
package/src/ui/public/index.html
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
7
7
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
8
8
|
<title>Zen GitSync</title>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-DT6eyL2d.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/vendor-PvZNfVU0.js">
|
|
11
11
|
<link rel="stylesheet" crossorigin href="/assets/vendor-BUGaay5Z.css">
|
|
12
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
12
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CQo5GCtA.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="app"></div>
|
package/src/ui/server/index.js
CHANGED
|
@@ -25,6 +25,7 @@ import { registerFsRoutes } from './routes/fs.js';
|
|
|
25
25
|
import { registerNpmRoutes } from './routes/npm.js';
|
|
26
26
|
import { registerFileOpenRoutes } from './routes/fileOpen.js';
|
|
27
27
|
import { registerGitOpsRoutes } from './routes/gitOps.js';
|
|
28
|
+
import { registerCodeRoutes } from './routes/code.js';
|
|
28
29
|
import { createSavePortToFile } from './utils/createSavePortToFile.js';
|
|
29
30
|
import { startServerOnAvailablePort } from './utils/startServerOnAvailablePort.js';
|
|
30
31
|
|
|
@@ -123,6 +124,10 @@ async function startUIServer(noOpen = false, savePort = false) {
|
|
|
123
124
|
runningProcesses
|
|
124
125
|
});
|
|
125
126
|
|
|
127
|
+
registerCodeRoutes({
|
|
128
|
+
app
|
|
129
|
+
});
|
|
130
|
+
|
|
126
131
|
registerTerminalRoutes({
|
|
127
132
|
app,
|
|
128
133
|
getCurrentProjectPath: () => currentProjectPath,
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as vm from 'node:vm';
|
|
2
|
+
|
|
3
|
+
function isPlainObject(value) {
|
|
4
|
+
return Object.prototype.toString.call(value) === '[object Object]';
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function normalizeOutputs(outputs) {
|
|
8
|
+
if (!isPlainObject(outputs)) return {};
|
|
9
|
+
|
|
10
|
+
const result = {};
|
|
11
|
+
const entries = Object.entries(outputs);
|
|
12
|
+
|
|
13
|
+
for (const [key, val] of entries) {
|
|
14
|
+
const safeKey = String(key || '').trim();
|
|
15
|
+
if (!safeKey) continue;
|
|
16
|
+
if (safeKey.length > 64) continue;
|
|
17
|
+
|
|
18
|
+
if (val === undefined || val === null) {
|
|
19
|
+
result[safeKey] = '';
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (typeof val === 'string') {
|
|
24
|
+
result[safeKey] = val;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (typeof val === 'number' || typeof val === 'boolean') {
|
|
29
|
+
result[safeKey] = String(val);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
result[safeKey] = JSON.stringify(val);
|
|
35
|
+
} catch {
|
|
36
|
+
result[safeKey] = String(val);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function registerCodeRoutes({ app }) {
|
|
44
|
+
app.post('/api/execute-code-node', async (req, res) => {
|
|
45
|
+
try {
|
|
46
|
+
const { script, input, param } = req.body || {};
|
|
47
|
+
|
|
48
|
+
if (!script || typeof script !== 'string' || !script.trim()) {
|
|
49
|
+
return res.status(400).json({ success: false, error: 'script 不能为空' });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const inputText = typeof input === 'string' ? input : (input === undefined || input === null ? '' : String(input));
|
|
53
|
+
|
|
54
|
+
const paramObj = (param && typeof param === 'object') ? param : undefined;
|
|
55
|
+
|
|
56
|
+
const wrapped = `"use strict";\n${script}\n`;
|
|
57
|
+
|
|
58
|
+
const sandbox = {
|
|
59
|
+
input: inputText,
|
|
60
|
+
param: paramObj,
|
|
61
|
+
main: undefined
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const context = vm.createContext(sandbox, {
|
|
65
|
+
name: 'code-node-sandbox'
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const vmScript = new vm.Script(wrapped, { filename: 'code-node.js' });
|
|
69
|
+
|
|
70
|
+
let result;
|
|
71
|
+
try {
|
|
72
|
+
result = vmScript.runInContext(context, { timeout: 800 });
|
|
73
|
+
} catch (e) {
|
|
74
|
+
return res.status(400).json({ success: false, error: e?.message || String(e) });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const mainFn = context.main || sandbox.main;
|
|
78
|
+
if (typeof mainFn !== 'function') {
|
|
79
|
+
return res.status(400).json({ success: false, error: '未找到 main(param) 函数' });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let finalResult = result;
|
|
83
|
+
try {
|
|
84
|
+
finalResult = mainFn(paramObj || {});
|
|
85
|
+
} catch (e) {
|
|
86
|
+
return res.status(400).json({ success: false, error: e?.message || String(e) });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const outputs = normalizeOutputs(finalResult);
|
|
90
|
+
|
|
91
|
+
return res.json({ success: true, outputs });
|
|
92
|
+
} catch (error) {
|
|
93
|
+
return res.status(500).json({ success: false, error: error?.message || String(error) });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|