-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
39 lines (31 loc) · 1.59 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
'use strict';
const acorn = require('acorn');
const { evalProgram, installImplClasses, installBuiltIns } = require('./lib/eval');
const { AbstractFunction, GenericFunction } = require('./lib/function');
const { builtIns, builtInsImpls } = require('./lib/function');
const { Context } = require('./lib/context');
const { CONTEXT_DEFAULT } = require('./lib/context/defaults');
installImplClasses({ AbstractFunction, GenericFunction });
installBuiltIns(builtIns, builtInsImpls);
const evalAst = (ast, vars, options, runState) => {
let context = options.context || CONTEXT_DEFAULT;
const userVars = Object.entries(vars);
if (userVars.length > 0) {
context = new Context(userVars.reduce((acc, varEntry) => {
acc[varEntry[0]] = { value: varEntry[1], isConst: false };
return acc;
}, {}), context);
}
const globalThis = context.asObject();
return evalProgram(ast, context, globalThis, options, runState);
};
const esEval = (code, vars, options) => {
options = Object.assign({ timeout: 100 }, options || {}); // @todo(refactor) unify default values
// @todo(refactor) check if this freeze can be removed
Object.freeze(options); // Even if this object is passed in the context, it cannot be altered. If that would be possible, a custom code could be able to increase the timeout, for example.
const ast = acorn.parse(`(${code})`, { ecmaVersion: 2022 });
const runState = { startTime: Date.now() };
return evalAst(ast, vars || {}, options, runState);
};
// Do not export other library functions to call them directly, that could break the security in the execution.
module.exports = esEval;