189 lines
5.5 KiB
JavaScript
Raw Permalink Normal View History

2025-04-28 12:25:20 +08:00
const express = require('express');
const router = express.Router();
const fs = require('fs').promises;
const path = require('path');
// 获取XNCore环境变量
const xnCorePath = process.env.XNCore || '';
// 默认IDL文件保存目录使用XNCore环境变量下的IDL子文件夹
const IDL_BASE_DIR = xnCorePath ? path.join(xnCorePath, 'IDL') : path.join(process.cwd(), 'idl_files');
// 确保IDL文件目录存在
async function ensureIdlDirExists() {
try {
await fs.mkdir(IDL_BASE_DIR, { recursive: true });
} catch (error) {
console.error('创建IDL目录失败:', error);
}
}
// 初始化确保目录存在
ensureIdlDirExists();
// 安全地获取文件路径,避免路径遍历攻击
function getSafePath(filePath) {
// 确保文件路径以.idl结尾
if (!filePath.toLowerCase().endsWith('.idl')) {
filePath += '.idl';
}
// 使用path.join确保路径在IDL_BASE_DIR下
const safePath = path.join(IDL_BASE_DIR, path.basename(filePath));
return safePath;
}
// 列出所有IDL文件
router.get('/list', async (req, res) => {
try {
// 确保目录存在
await ensureIdlDirExists();
// 读取目录
const files = await fs.readdir(IDL_BASE_DIR);
// 过滤出.idl文件
const idlFiles = files.filter(file => file.toLowerCase().endsWith('.idl'));
// 获取文件信息
const fileInfos = await Promise.all(idlFiles.map(async (file) => {
const filePath = path.join(IDL_BASE_DIR, file);
const stats = await fs.stat(filePath);
return {
name: file,
size: stats.size,
modified: stats.mtime
};
}));
res.json({ files: fileInfos });
} catch (error) {
console.error('列出IDL文件失败:', error);
res.status(500).json({ error: '列出IDL文件失败', message: error.message });
}
});
// 读取IDL文件内容
router.get('/read', async (req, res) => {
try {
const filename = req.query.filename;
if (!filename) {
return res.status(400).json({ error: '缺少文件名参数' });
}
const filePath = getSafePath(filename);
// 读取文件内容
const content = await fs.readFile(filePath, 'utf-8');
res.json({ content, filename: path.basename(filePath) });
} catch (error) {
console.error('读取IDL文件失败:', error);
if (error.code === 'ENOENT') {
return res.status(404).json({ error: '文件不存在' });
}
res.status(500).json({ error: '读取IDL文件失败', message: error.message });
}
});
// 保存IDL文件内容
router.post('/save', async (req, res) => {
try {
const { filename, content } = req.body;
if (!filename || content === undefined) {
return res.status(400).json({ error: '缺少必要参数' });
}
// 确保目录存在
await ensureIdlDirExists();
const filePath = getSafePath(filename);
// 写入文件内容
await fs.writeFile(filePath, content, 'utf-8');
res.json({ success: true, filename: path.basename(filePath) });
} catch (error) {
console.error('保存IDL文件失败:', error);
res.status(500).json({ error: '保存IDL文件失败', message: error.message });
}
});
// 新建IDL文件
router.post('/create', async (req, res) => {
try {
const { filename } = req.body;
if (!filename) {
return res.status(400).json({ error: '缺少文件名参数' });
}
// 确保目录存在
await ensureIdlDirExists();
const filePath = getSafePath(filename);
// 检查文件是否已存在
try {
await fs.access(filePath);
return res.status(409).json({ error: '文件已存在' });
} catch (accessError) {
// 文件不存在,可以创建
}
// 创建具有默认内容的IDL文件
const defaultContent = `module XNSim
{
struct YourStruct
{
// 在此添加字段
};
};`;
// 写入文件内容
await fs.writeFile(filePath, defaultContent, 'utf-8');
res.json({
success: true,
filename: path.basename(filePath),
content: defaultContent
});
} catch (error) {
console.error('创建IDL文件失败:', error);
res.status(500).json({ error: '创建IDL文件失败', message: error.message });
}
});
// 删除IDL文件
router.delete('/delete', async (req, res) => {
try {
const filename = req.query.filename;
if (!filename) {
return res.status(400).json({ error: '缺少文件名参数' });
}
const filePath = getSafePath(filename);
// 删除文件
await fs.unlink(filePath);
res.json({ success: true, filename: path.basename(filePath) });
} catch (error) {
console.error('删除IDL文件失败:', error);
if (error.code === 'ENOENT') {
return res.status(404).json({ error: '文件不存在' });
}
res.status(500).json({ error: '删除IDL文件失败', message: error.message });
}
});
module.exports = router;