38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
import { Validator } from "./validator";
|
|
|
|
export class Evaluator<Context extends object> {
|
|
context?: Context;
|
|
validator: Validator;
|
|
|
|
constructor({
|
|
context,
|
|
predicate = Validator.defaultPredicate,
|
|
}: { context?: Context; predicate?: (identifier: string) => boolean } = {}) {
|
|
let actualPredicate = predicate;
|
|
if (context) {
|
|
this.context = new Proxy(context, {
|
|
has: () => true,
|
|
get: (t, k) => (k === Symbol.unscopables ? undefined : t[k as keyof typeof t]),
|
|
});
|
|
actualPredicate = (identifier: string) =>
|
|
predicate(identifier) || Object.getOwnPropertyNames(Math).includes(identifier);
|
|
}
|
|
this.validator = new Validator(actualPredicate);
|
|
}
|
|
|
|
evaluate(expression: string): unknown {
|
|
this.validator.validate(expression);
|
|
|
|
const body = `with (sandbox) { return ${expression}; }`;
|
|
const evaluate = new Function("sandbox", body);
|
|
return evaluate(this.context ?? {});
|
|
}
|
|
}
|
|
|
|
export const defaultEvaluator = new Evaluator();
|
|
|
|
export const mathEvaluator = new Evaluator({ context: Math });
|