blob: 0ec8a5062a2afec7229ff1f3b3da9408c71bd370 [file] [log] [blame]
import vm from 'vm';
import createBuiltInError from './createBuiltInError';
import sum from './sum';
// Inside of 'vm' for Node, we need a way to translate a pseudo-error
// back into a real error once it's out of the VM.
function createBuiltInErrorInVm(name) {
return {
builtInError: true,
name: name
};
}
function convertToTrueError(err) {
return createBuiltInError(err.name);
}
function isBuiltInError(obj) {
return obj && obj.builtInError;
}
// All of this vm hullaballoo is to be able to run arbitrary code in a sandbox
// for security reasons.
function evalFunctionInVm(func, emit) {
return function (arg1, arg2, arg3) {
var code = '(function() {"use strict";' +
'var createBuiltInError = ' + createBuiltInErrorInVm.toString() + ';' +
'var sum = ' + sum.toString() + ';' +
'var log = function () {};' +
'var isArray = Array.isArray;' +
'var toJSON = JSON.parse;' +
'var __emitteds__ = [];' +
'var emit = function (key, value) {__emitteds__.push([key, value]);};' +
'var __result__ = (' +
func.replace(/;\s*$/, '') + ')' + '(' +
JSON.stringify(arg1) + ',' +
JSON.stringify(arg2) + ',' +
JSON.stringify(arg3) + ');' +
'return {result: __result__, emitteds: __emitteds__};' +
'})()';
var output = vm.runInNewContext(code);
output.emitteds.forEach(function (emitted) {
emit(emitted[0], emitted[1]);
});
if (isBuiltInError(output.result)) {
output.result = convertToTrueError(output.result);
}
return output.result;
};
}
export default evalFunctionInVm;