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); } }