Merge pull request #119 from Deepractice/feature/toolsandbox-unified-refactor
🔧 ToolSandbox统一重构:修复process API缺失和代码重复问题
This commit is contained in:
@ -207,9 +207,12 @@ class ToolSandbox {
|
|||||||
* 在基础沙箱中分析工具
|
* 在基础沙箱中分析工具
|
||||||
*/
|
*/
|
||||||
async analyzeToolInSandbox() {
|
async analyzeToolInSandbox() {
|
||||||
const basicSandbox = this.createBasicSandbox();
|
const sandbox = this.createSandbox({
|
||||||
|
supportDependencies: false,
|
||||||
|
sandboxPath: process.cwd()
|
||||||
|
});
|
||||||
const script = new vm.Script(this.toolContent, { filename: `${this.toolId}.js` });
|
const script = new vm.Script(this.toolContent, { filename: `${this.toolId}.js` });
|
||||||
const context = vm.createContext(basicSandbox);
|
const context = vm.createContext(sandbox);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
script.runInContext(context);
|
script.runInContext(context);
|
||||||
@ -442,7 +445,10 @@ class ToolSandbox {
|
|||||||
* 创建执行沙箱环境
|
* 创建执行沙箱环境
|
||||||
*/
|
*/
|
||||||
async createExecutionSandbox() {
|
async createExecutionSandbox() {
|
||||||
this.sandboxContext = this.createSmartSandbox();
|
this.sandboxContext = this.createSandbox({
|
||||||
|
supportDependencies: true,
|
||||||
|
sandboxPath: this.sandboxPath
|
||||||
|
});
|
||||||
|
|
||||||
// 在智能沙箱中重新加载工具
|
// 在智能沙箱中重新加载工具
|
||||||
const script = new vm.Script(this.toolContent, { filename: `${this.toolId}.js` });
|
const script = new vm.Script(this.toolContent, { filename: `${this.toolId}.js` });
|
||||||
@ -459,19 +465,27 @@ class ToolSandbox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建基础沙箱
|
* 创建统一沙箱环境
|
||||||
|
* @param {Object} options - 沙箱配置
|
||||||
|
* @param {boolean} options.supportDependencies - 是否支持依赖解析
|
||||||
|
* @param {string} options.sandboxPath - 沙箱工作目录
|
||||||
|
* @returns {Object} 沙箱环境对象
|
||||||
*/
|
*/
|
||||||
createBasicSandbox() {
|
createSandbox(options = {}) {
|
||||||
|
const {
|
||||||
|
supportDependencies = false,
|
||||||
|
sandboxPath = process.cwd()
|
||||||
|
} = options;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
require: require,
|
require: supportDependencies ?
|
||||||
|
this.createSmartRequire(sandboxPath) :
|
||||||
|
this.createAnalysisRequire(),
|
||||||
module: { exports: {} },
|
module: { exports: {} },
|
||||||
exports: {},
|
exports: {},
|
||||||
console: console,
|
console: console,
|
||||||
Buffer: Buffer,
|
Buffer: Buffer,
|
||||||
process: {
|
process: this.createProcessMock(sandboxPath),
|
||||||
env: process.env,
|
|
||||||
hrtime: process.hrtime
|
|
||||||
},
|
|
||||||
setTimeout: setTimeout,
|
setTimeout: setTimeout,
|
||||||
clearTimeout: clearTimeout,
|
clearTimeout: clearTimeout,
|
||||||
setInterval: setInterval,
|
setInterval: setInterval,
|
||||||
@ -491,48 +505,70 @@ class ToolSandbox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建智能沙箱(支持依赖)
|
* 创建完整的process对象mock
|
||||||
|
* @param {string} sandboxPath - 沙箱工作目录
|
||||||
|
* @returns {Object} mock的process对象
|
||||||
*/
|
*/
|
||||||
createSmartSandbox() {
|
createProcessMock(sandboxPath) {
|
||||||
return {
|
return {
|
||||||
require: (moduleName) => {
|
env: process.env,
|
||||||
|
version: process.version,
|
||||||
|
platform: process.platform,
|
||||||
|
arch: process.arch,
|
||||||
|
hrtime: process.hrtime,
|
||||||
|
cwd: () => sandboxPath,
|
||||||
|
pid: process.pid,
|
||||||
|
uptime: process.uptime
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建分析阶段的mock require
|
||||||
|
* 让所有require调用都成功,脚本能完整执行到module.exports
|
||||||
|
* @returns {Function} mock require函数
|
||||||
|
*/
|
||||||
|
createAnalysisRequire() {
|
||||||
|
return (moduleName) => {
|
||||||
|
// Node.js内置模块使用真实require
|
||||||
|
const builtinModules = ['path', 'fs', 'url', 'crypto', 'util', 'os', 'events', 'stream'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 检查是否是内置模块
|
||||||
|
if (builtinModules.includes(moduleName) || moduleName.startsWith('node:')) {
|
||||||
|
return require(moduleName);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// 内置模块加载失败,继续mock处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第三方模块返回通用mock对象
|
||||||
|
console.log(`[ToolSandbox] 分析阶段mock模块: ${moduleName}`);
|
||||||
|
return new Proxy({}, {
|
||||||
|
get: () => () => ({}), // 所有属性和方法都返回空函数/对象
|
||||||
|
apply: () => ({}), // 如果被当作函数调用
|
||||||
|
construct: () => ({}) // 如果被当作构造函数
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建支持依赖解析的require函数
|
||||||
|
* @param {string} sandboxPath - 沙箱路径
|
||||||
|
* @returns {Function} 智能require函数
|
||||||
|
*/
|
||||||
|
createSmartRequire(sandboxPath) {
|
||||||
|
return (moduleName) => {
|
||||||
try {
|
try {
|
||||||
// 优先从沙箱目录查找依赖
|
|
||||||
return require(require.resolve(moduleName, {
|
return require(require.resolve(moduleName, {
|
||||||
paths: [
|
paths: [
|
||||||
path.join(this.sandboxPath, 'node_modules'),
|
path.join(sandboxPath, 'node_modules'),
|
||||||
this.sandboxPath,
|
sandboxPath,
|
||||||
process.cwd() + '/node_modules'
|
process.cwd() + '/node_modules'
|
||||||
]
|
]
|
||||||
}));
|
}));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 回退到默认require
|
|
||||||
return require(moduleName);
|
return require(moduleName);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
module: { exports: {} },
|
|
||||||
exports: {},
|
|
||||||
console: console,
|
|
||||||
Buffer: Buffer,
|
|
||||||
process: {
|
|
||||||
env: process.env,
|
|
||||||
hrtime: process.hrtime
|
|
||||||
},
|
|
||||||
setTimeout: setTimeout,
|
|
||||||
clearTimeout: clearTimeout,
|
|
||||||
setInterval: setInterval,
|
|
||||||
clearInterval: clearInterval,
|
|
||||||
Object: Object,
|
|
||||||
Array: Array,
|
|
||||||
String: String,
|
|
||||||
Number: Number,
|
|
||||||
Boolean: Boolean,
|
|
||||||
Date: Date,
|
|
||||||
JSON: JSON,
|
|
||||||
Math: Math,
|
|
||||||
RegExp: RegExp,
|
|
||||||
Error: Error,
|
|
||||||
URL: URL
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user