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.
@@ -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-GE6lIBHK.js"></script>
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-CzUoE1WP.css">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-CQo5GCtA.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="app"></div>
@@ -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
+ }