zen-gitsync 2.11.19 → 2.11.21
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/README.md +145 -24
- package/package.json +2 -2
- package/scripts/release.js +31 -8
- package/src/ui/public/assets/css.worker-Wv5dxAWO.js +89 -0
- package/src/ui/public/assets/editor.worker-Bd9IXS8d.js +26 -0
- package/src/ui/public/assets/html.worker-CQP8QQsS.js +502 -0
- package/src/ui/public/assets/index-DI8xah2P.css +1 -0
- package/src/ui/public/assets/index-I2BT9uSF.js +92 -0
- package/src/ui/public/assets/json.worker-DzV-CpCQ.js +58 -0
- package/src/ui/public/assets/rolldown-runtime-BM3Ffeng.js +1 -0
- package/src/ui/public/assets/{ts.worker--OkPaiLD.js → ts.worker-Dth06zuC.js} +253 -250
- package/src/ui/public/assets/vendor-CjiV6IT4.css +1 -0
- package/src/ui/public/assets/vendor-CsS_wI9o.js +1323 -0
- package/src/ui/public/index.html +5 -4
- package/src/ui/server/routes/fs.js +117 -0
- package/src/ui/public/assets/css.worker-DJHgoStD.js +0 -93
- package/src/ui/public/assets/editor.worker-1JAmoQSB.js +0 -26
- package/src/ui/public/assets/html.worker-BSNtyp_I.js +0 -470
- package/src/ui/public/assets/index-DGWy-waR.css +0 -1
- package/src/ui/public/assets/index-JZlboou5.js +0 -109
- package/src/ui/public/assets/json.worker--DwPKSpO.js +0 -58
- package/src/ui/public/assets/vendor-CKZkoBDj.css +0 -1
- package/src/ui/public/assets/vendor-Ih5RdUJO.js +0 -1341
package/src/ui/public/index.html
CHANGED
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
11
11
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
12
12
|
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,400&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
13
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
15
|
-
<link rel="
|
|
16
|
-
<link rel="stylesheet" crossorigin href="/assets/
|
|
13
|
+
<script type="module" crossorigin src="/assets/index-I2BT9uSF.js"></script>
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-BM3Ffeng.js">
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/vendor-CsS_wI9o.js">
|
|
16
|
+
<link rel="stylesheet" crossorigin href="/assets/vendor-CjiV6IT4.css">
|
|
17
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DI8xah2P.css">
|
|
17
18
|
</head>
|
|
18
19
|
<body>
|
|
19
20
|
<div id="app"></div>
|
|
@@ -516,6 +516,35 @@ export function registerFsRoutes({
|
|
|
516
516
|
}
|
|
517
517
|
});
|
|
518
518
|
|
|
519
|
+
// ── 编辑器:读取原始文件(用于图片等二进制文件预览)────────────────────
|
|
520
|
+
app.get('/api/editor/raw', async (req, res) => {
|
|
521
|
+
try {
|
|
522
|
+
const filePath = req.query.path;
|
|
523
|
+
if (!filePath) return res.status(400).end();
|
|
524
|
+
const cwd = getCurrentProjectPath() || process.cwd();
|
|
525
|
+
const resolved = path.resolve(filePath);
|
|
526
|
+
if (!resolved.startsWith(path.resolve(cwd))) {
|
|
527
|
+
return res.status(403).end();
|
|
528
|
+
}
|
|
529
|
+
const stat = await fs.stat(resolved);
|
|
530
|
+
if (!stat.isFile()) return res.status(400).end();
|
|
531
|
+
if (stat.size > 20 * 1024 * 1024) return res.status(413).end();
|
|
532
|
+
const ext = path.extname(resolved).toLowerCase().slice(1);
|
|
533
|
+
const mimeMap = {
|
|
534
|
+
png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg',
|
|
535
|
+
gif: 'image/gif', webp: 'image/webp', ico: 'image/x-icon',
|
|
536
|
+
svg: 'image/svg+xml', bmp: 'image/bmp', tiff: 'image/tiff',
|
|
537
|
+
};
|
|
538
|
+
const mime = mimeMap[ext] || 'application/octet-stream';
|
|
539
|
+
const content = await fs.readFile(resolved);
|
|
540
|
+
res.setHeader('Content-Type', mime);
|
|
541
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
542
|
+
res.send(content);
|
|
543
|
+
} catch (error) {
|
|
544
|
+
res.status(500).end();
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
|
|
519
548
|
// ── 编辑器:写入文件内容 ────────────────────────────────────────
|
|
520
549
|
app.put('/api/editor/file', express.json(), async (req, res) => {
|
|
521
550
|
try {
|
|
@@ -534,5 +563,93 @@ export function registerFsRoutes({
|
|
|
534
563
|
res.status(500).json({ success: false, error: error.message });
|
|
535
564
|
}
|
|
536
565
|
});
|
|
566
|
+
|
|
567
|
+
// ── 编辑器:新建文件 ───────────────────────────────────────────
|
|
568
|
+
app.post('/api/editor/file', express.json(), async (req, res) => {
|
|
569
|
+
try {
|
|
570
|
+
const { path: filePath } = req.body;
|
|
571
|
+
if (!filePath) return res.status(400).json({ success: false, error: '缺少 path 参数' });
|
|
572
|
+
const cwd = getCurrentProjectPath() || process.cwd();
|
|
573
|
+
const resolved = path.resolve(filePath);
|
|
574
|
+
if (!resolved.startsWith(path.resolve(cwd))) {
|
|
575
|
+
return res.status(403).json({ success: false, error: '禁止在工作目录以外创建文件' });
|
|
576
|
+
}
|
|
577
|
+
// 如果已存在则拒绝
|
|
578
|
+
try {
|
|
579
|
+
await fs.access(resolved);
|
|
580
|
+
return res.status(409).json({ success: false, error: '文件已存在' });
|
|
581
|
+
} catch { /* 不存在,继续 */ }
|
|
582
|
+
await fs.mkdir(path.dirname(resolved), { recursive: true });
|
|
583
|
+
await fs.writeFile(resolved, '', 'utf-8');
|
|
584
|
+
res.json({ success: true });
|
|
585
|
+
} catch (error) {
|
|
586
|
+
res.status(500).json({ success: false, error: error.message });
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
// ── 编辑器:新建文件夹 ─────────────────────────────────────────
|
|
591
|
+
app.post('/api/editor/directory', express.json(), async (req, res) => {
|
|
592
|
+
try {
|
|
593
|
+
const { path: dirPath } = req.body;
|
|
594
|
+
if (!dirPath) return res.status(400).json({ success: false, error: '缺少 path 参数' });
|
|
595
|
+
const cwd = getCurrentProjectPath() || process.cwd();
|
|
596
|
+
const resolved = path.resolve(dirPath);
|
|
597
|
+
if (!resolved.startsWith(path.resolve(cwd))) {
|
|
598
|
+
return res.status(403).json({ success: false, error: '禁止在工作目录以外创建目录' });
|
|
599
|
+
}
|
|
600
|
+
try {
|
|
601
|
+
await fs.access(resolved);
|
|
602
|
+
return res.status(409).json({ success: false, error: '目录已存在' });
|
|
603
|
+
} catch { /* 不存在,继续 */ }
|
|
604
|
+
await fs.mkdir(resolved, { recursive: true });
|
|
605
|
+
res.json({ success: true });
|
|
606
|
+
} catch (error) {
|
|
607
|
+
res.status(500).json({ success: false, error: error.message });
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
// ── 编辑器:删除文件或文件夹 ───────────────────────────────────
|
|
612
|
+
app.delete('/api/editor/entry', express.json(), async (req, res) => {
|
|
613
|
+
try {
|
|
614
|
+
const filePath = req.query.path;
|
|
615
|
+
if (!filePath) return res.status(400).json({ success: false, error: '缺少 path 参数' });
|
|
616
|
+
const cwd = getCurrentProjectPath() || process.cwd();
|
|
617
|
+
const resolved = path.resolve(filePath);
|
|
618
|
+
if (!resolved.startsWith(path.resolve(cwd))) {
|
|
619
|
+
return res.status(403).json({ success: false, error: '禁止删除工作目录以外的内容' });
|
|
620
|
+
}
|
|
621
|
+
const stat = await fs.stat(resolved);
|
|
622
|
+
if (stat.isDirectory()) {
|
|
623
|
+
await fs.rm(resolved, { recursive: true, force: true });
|
|
624
|
+
} else {
|
|
625
|
+
await fs.unlink(resolved);
|
|
626
|
+
}
|
|
627
|
+
res.json({ success: true });
|
|
628
|
+
} catch (error) {
|
|
629
|
+
res.status(500).json({ success: false, error: error.message });
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
// ── 编辑器:重命名文件或文件夹 ────────────────────────────────
|
|
634
|
+
app.put('/api/editor/rename', express.json(), async (req, res) => {
|
|
635
|
+
try {
|
|
636
|
+
const { oldPath, newPath } = req.body;
|
|
637
|
+
if (!oldPath || !newPath) return res.status(400).json({ success: false, error: '缺少参数' });
|
|
638
|
+
const cwd = getCurrentProjectPath() || process.cwd();
|
|
639
|
+
const resolvedOld = path.resolve(oldPath);
|
|
640
|
+
const resolvedNew = path.resolve(newPath);
|
|
641
|
+
if (!resolvedOld.startsWith(path.resolve(cwd)) || !resolvedNew.startsWith(path.resolve(cwd))) {
|
|
642
|
+
return res.status(403).json({ success: false, error: '禁止操作工作目录以外的内容' });
|
|
643
|
+
}
|
|
644
|
+
try {
|
|
645
|
+
await fs.access(resolvedNew);
|
|
646
|
+
return res.status(409).json({ success: false, error: '目标名称已存在' });
|
|
647
|
+
} catch { /* 不存在,继续 */ }
|
|
648
|
+
await fs.rename(resolvedOld, resolvedNew);
|
|
649
|
+
res.json({ success: true });
|
|
650
|
+
} catch (error) {
|
|
651
|
+
res.status(500).json({ success: false, error: error.message });
|
|
652
|
+
}
|
|
653
|
+
});
|
|
537
654
|
}
|
|
538
655
|
|