I have some asynchronous JavaScript code, which I'd like to run using vm2 / NodeVM.
The code tests two functions: a user-submitted function evenAndOdd and a pre-defined function solution using Node's built-in assert library.
My question is, how can I get the my resolved Promise out of vm.run()?
The Aynchronous Code
This is the test code I want to turn into a string and run using vm2:
const assert = require('assert');
function evenAndOdd(arr) {
return [arr.filter(el => el % 2 === 0).sort(), arr.filter(el => el % 2 === 1).sort()];
};
function solution(arr) {
return [arr.filter(el => el % 2 === 0).sort(), arr.filter(el => el % 2 === 1).sort()];
};
const runTest = async () => {
return new Promise((resolve, reject) => {
const map = new Map();
const tests = 10;
for (let i = 0; i < tests; i++) {
let randLength = parseInt(Math.random() * 19 + 1);
let randArray = [...Array(randLength)].map(e => ~~(Math.random() * randLength));
const test = async () => {
return assert.deepEqual(evenAndOdd(randArray), solution(randArray));
}
const description = "TEST CASE: evenAndOdd([" + randArray + "}]) EXPECT: [[" + solution(randArray)[0] + "], [" + solution(randArray)[1] + "]] GOT: [[" + evenAndOdd(randArray)[0] + "], [" + evenAndOdd(randArray)[1] + "]]";
test()
.then(() => {
map.set(description, true);
if (map.size === tests) {
resolve(map);
};
})
.catch(() => {
map.set(description, false);
if (map.size === tests) {
resolve(map);
};
})
}
})
}
If I append the following code, I get exactly what I want logged to the console:
runTest().then((result) => {
console.log(result)
});
The vm Code
My question is, how do I get the resolved promise from vm.run()?
const { NodeVM } = require('vm2');
const vm = new NodeVM({
console: 'inherit',
sandbox: {},
require: {
external: true,
builtin: ['assert'],
import: ['assert'],
root: "./",
},
});
const result = vm.run(stringifiedJavaScript, 'vm.js');
Right now, the result variable above is undefined.
NodeVM.run()executes the code and returns the module created by the execution, which can then be accessed by the host code. In order to access the result of the computation in the processed code, you should assign it tomodule.exports.Consider the following example:
The variable
vmExportsholds the module exported by theruncall, and the fieldvmExports.prholds the promise produced by the sandboxed script. The exported promise is thenable or can be awaited to access the resolved values.