Skip to content

Instantly share code, notes, and snippets.

@devotox
Last active October 18, 2022 07:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save devotox/e6ba8463884e956043040e8e374c9e94 to your computer and use it in GitHub Desktop.
Save devotox/e6ba8463884e956043040e8e374c9e94 to your computer and use it in GitHub Desktop.
Create A Javascript sandbox to execute custom code without giving access to things like window and outer contextThey still have a `this` object they can use across multiple executions to persist data
import Service from '@ember/service';
const has = () => true;
const { console, WeakMap, Proxy, Symbol } = window;
const get = (target, key) => key === Symbol.unscopables ? undefined : target[key];
export default Service.extend({
sandboxes: new WeakMap(),
globals: { console, Object },
getSandboxKey(context) {
return context;
// return JSON.stringify(Object.keys(context));
},
createSandbox(/* globals */) {
return this.get('globals');
// return Object.assign({}, globals, defaultGlobals);
},
compileCode(src) {
src = `with (context) { ${src} }`;
let sandboxes = this.get('sandboxes');
let code = new Function('context', src);
return (context) => {
let sandboxKey = this.getSandboxKey(context);
if (!sandboxes.has(sandboxKey)) {
let global = Object.create(null);
let proxy = new Proxy(context, { has, get });
sandboxes.set(sandboxKey, { proxy, global });
}
let { proxy, global } = sandboxes.get(sandboxKey);
return code.call(global, proxy);
};
},
runCode(src, globals) {
let sandbox = this.createSandbox(globals);
let code = this.compileCode(src);
return code(sandbox);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment