node / sandBox.ts
YYou3
add initial
5e9feb1
import * as path from "path";
import { v4 as uuidv4 } from 'uuid';
import * as fs from 'node:fs';
import * as child_process from 'node:child_process';
export async function sandBox(req:any,res:any,next:any){
let timeout = req.query.timeout || 60000;
const code = req.body;
let name = uuidv4();
let file = path.join(__dirname,`./${name}.js`);
console.log(`writing file ${file}`);
fs.writeFileSync(
file,
`
console.log('entering ${name}');
const done = async (result)=>{
let data = await result
console.log('done ${name}');
let fs = require('fs');
let path = require('path');
fs.writeFileSync(path.join(__dirname,'./${name}.child.json'),JSON.stringify({data},null,4));
process.exit(0);
}
${code}
`,
"utf-8"
);
let child_logs: any = {
start: new Date().toString(),
timestamp: new Date().toString(),
end: null,
success: null,
value: null,
stdout: [],
stderr: [],
close: null,
err: null
};
let childProc = child_process.exec(`node ${file}`, {
cwd: __dirname,
});
childProc.stdout?.on("data", function (data) {
child_logs.stdout.push(data);
});
childProc.stderr?.on("data", function (data) {
child_logs.stderr.push(data);
});
childProc.on("close", function (code) {
child_logs.success = code == 0;
child_logs.close = `exit code : ${code}`;
});
childProc.on("error", function (err) {
child_logs.err = err;
});
let checkHandle:any;
let timeoutHandle:any;
let task = Promise.race([
new Promise((resolve) => {
timeoutHandle = setTimeout(() => {
clearInterval(checkHandle);
childProc.kill();
child_logs.end = new Date().toString();
child_logs.success = false;
child_logs.value = "timeout";
fs.writeFileSync(
path.join(__dirname,`./${name}.json`),
JSON.stringify(child_logs, null, 4)
);
resolve("timeout");
}, timeout);
}),
new Promise((resolve) => {
checkHandle = setInterval(() => {
child_logs.timestamp = new Date().toString();
fs.writeFileSync(
path.join(__dirname,`./${name}.json`),
JSON.stringify(child_logs, null, 4)
);
if (child_logs.close) {
clearTimeout(timeoutHandle);
child_logs.end = new Date().toString();
try{
child_logs.value = require(path.join(__dirname,`./${name}.child.json`)).data;
}catch(e: any){
child_logs.value = e.message;
}
fs.writeFileSync(
path.join(__dirname,`./${name}.json`),
JSON.stringify(child_logs, null, 4)
);
resolve("done");
}
}, 1000);
}),
]);
let waitHandle = await task;
if (waitHandle == "done") {
res.status(200).send(child_logs);
} else {
res.status(500).send(child_logs);
}
}