Skip to content

Instantly share code, notes, and snippets.

@hungtcs
Last active October 25, 2023 03:13
Show Gist options
  • Save hungtcs/e79ac3069897d6e2c15f855d3253720d to your computer and use it in GitHub Desktop.
Save hungtcs/e79ac3069897d6e2c15f855d3253720d to your computer and use it in GitHub Desktop.
Simple JavaScript Sandbox
const parser = Sandbox.compile('a + b');
const result = parser({ a: 1, b: 2 });
// ---
const parser = Sandbox.compile('a + b + alert', { throwOnUndefined: true });
const result = parser({ a: 1, b: 2 });
interface SandboxOptions {
throwOnUndefined?: boolean;
}
class Sandbox {
public static cache = new WeakMap();
private constructor() {
}
public static compile(expression: string, options: SandboxOptions = {}) {
return (context: any) => {
let _context = Sandbox.cache.get(context);
if (!_context) {
_context = new Proxy(
context,
{
get: (target, p) => {
if (p === Symbol.unscopables) {
return undefined;
}
const value = target[p];
if (options.throwOnUndefined && value === undefined) {
throw new ReferenceError(`${ p.toString() } is not defined`);
}
return value;
},
has: () => true,
},
);
Sandbox.cache.set(context, _context);
}
return (new Function('context', `with(context) { return (${ expression }) }`))(_context)
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment