a bit of cleanup
This commit is contained in:
parent
9d44128914
commit
b88a022468
6 changed files with 90 additions and 38 deletions
|
@ -58,8 +58,8 @@ export function generateMenu(win: BrowserWindow): Menu {
|
|||
}
|
||||
perms.push(
|
||||
new MenuItem({
|
||||
label: "fs & path",
|
||||
id: "perm-fs",
|
||||
label: "fs + path",
|
||||
id: "perm-fs/path",
|
||||
type: "checkbox",
|
||||
checked: false,
|
||||
click: perm,
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
// runs arbitrary code in a sandbox
|
||||
|
||||
// TODO share context between vms
|
||||
import { NodeVM, VM } from "vm2";
|
||||
import { NodeVM, VM, NodeVMOptions, VMScript } from "vm2";
|
||||
let consol;
|
||||
const sandbox = {};
|
||||
const vmLibrary: Record<string, NodeVM> = {};
|
||||
const perms: Record<string, boolean> = {
|
||||
fs: false,
|
||||
path: false,
|
||||
zlib: false,
|
||||
http: false,
|
||||
https: false,
|
||||
os: false,
|
||||
};
|
||||
const vm = new VM({ sandbox, timeout: 3000 });
|
||||
|
||||
// TODO permissions
|
||||
|
||||
// resets the vm sandbox
|
||||
export function reset(): void {
|
||||
for (let i in sandbox) {
|
||||
|
@ -19,22 +22,32 @@ export function reset(): void {
|
|||
}
|
||||
}
|
||||
|
||||
interface VMResult {
|
||||
value: unknown;
|
||||
err: boolean;
|
||||
}
|
||||
|
||||
// run code as a nodejs vm
|
||||
export function run(code: string): unknown {
|
||||
export function run(code: string, fileName: string = "yourCode.js"): VMResult {
|
||||
try {
|
||||
// TODO make console.log work
|
||||
return getVm(permArray()).run(code);
|
||||
return {
|
||||
value: getVm(permArray()).run(new VMScript(code, fileName)),
|
||||
err: false,
|
||||
};
|
||||
} catch (err) {
|
||||
return err;
|
||||
return { value: err, err: true };
|
||||
}
|
||||
}
|
||||
|
||||
// run code in a less fancy vm, for the console
|
||||
export function runLess(code: string): unknown {
|
||||
export function runLess(code: string): VMResult {
|
||||
try {
|
||||
return vm.run(code);
|
||||
return {
|
||||
value: vm.run(code),
|
||||
err: false,
|
||||
};
|
||||
} catch (err) {
|
||||
return err;
|
||||
return { value: err, err: true };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +64,9 @@ export function setConsole(newConsole): void {
|
|||
|
||||
// sets a permission
|
||||
export function setPerm(name: string, toggle: boolean): void {
|
||||
if (perms.hasOwnProperty(name)) perms[name] = toggle;
|
||||
name.split("/").forEach((i) => {
|
||||
if (perms.hasOwnProperty(i)) perms[i] = toggle;
|
||||
});
|
||||
}
|
||||
|
||||
// convert permission object into an array
|
||||
|
@ -64,29 +79,36 @@ function permArray(): Array<string> {
|
|||
}
|
||||
|
||||
// because vm2
|
||||
function getVm(perms: Array<string>) {
|
||||
const name: string = perms.sort().join(",");
|
||||
if (vmLibrary.hasOwnProperty(name)) return vmLibrary[name];
|
||||
const nodevm = new NodeVM({
|
||||
sandbox,
|
||||
require: {
|
||||
external: false,
|
||||
builtin: perms,
|
||||
function getVm(perms: Array<string>, obj: object = {}) {
|
||||
const options = Object.assign(
|
||||
{
|
||||
sandbox,
|
||||
require: {
|
||||
external: false,
|
||||
builtin: perms,
|
||||
},
|
||||
wrapper: "none",
|
||||
console: "redirect",
|
||||
},
|
||||
wrapper: "none",
|
||||
console: "redirect",
|
||||
})
|
||||
.on("console.log", (msg) => {
|
||||
if (consol) consol.log(msg);
|
||||
obj
|
||||
) as NodeVMOptions;
|
||||
|
||||
// lazy way of getting a unique name
|
||||
const name: string = perms.sort().join(",") + JSON.stringify(obj);
|
||||
if (vmLibrary.hasOwnProperty(name)) return vmLibrary[name];
|
||||
|
||||
const nodevm = new NodeVM(options)
|
||||
.on("console.log", (...msg) => {
|
||||
if (consol) msg.forEach((i) => consol.log(i));
|
||||
})
|
||||
.on("console.info", (msg) => {
|
||||
if (consol) consol.log(msg);
|
||||
.on("console.info", (...msg) => {
|
||||
if (consol) msg.forEach((i) => consol.log(i));
|
||||
})
|
||||
.on("console.warn", (msg) => {
|
||||
if (consol) consol.warn(msg);
|
||||
.on("console.warn", (...msg) => {
|
||||
if (consol) msg.forEach((i) => consol.warn(i));
|
||||
})
|
||||
.on("console.error", (msg) => {
|
||||
if (consol) consol.error(msg);
|
||||
.on("console.error", (...msg) => {
|
||||
if (consol) msg.forEach((i) => consol.error(i));
|
||||
});
|
||||
vmLibrary[name] = nodevm;
|
||||
return nodevm;
|
||||
|
|
|
@ -7,6 +7,12 @@ import { Editor } from "./editor";
|
|||
import { Bar } from "./dragBar";
|
||||
import { Highlight } from "./highlight";
|
||||
|
||||
function gotoEnd(editor) {
|
||||
var row = editor.session.getLength() - 1;
|
||||
var column = Infinity;
|
||||
editor.selection.moveTo(row + 1, column);
|
||||
}
|
||||
|
||||
export class Console extends Element {
|
||||
content: HTMLElement;
|
||||
bar: Bar;
|
||||
|
@ -38,6 +44,9 @@ export class Console extends Element {
|
|||
showGutter: false,
|
||||
highlightActiveLine: false,
|
||||
});
|
||||
|
||||
const history: Array<string> = [];
|
||||
let histIndex: number = -1;
|
||||
this.input.listen("runCode", "enter", () => {
|
||||
// TODO console icons, see more below
|
||||
// need icon for console input, console
|
||||
|
@ -46,13 +55,32 @@ export class Console extends Element {
|
|||
const code = this.input.editor.session.getValue();
|
||||
new Highlight(content, code);
|
||||
if (this.run) this.run(code);
|
||||
history.unshift(code);
|
||||
histIndex = -1;
|
||||
this.input.editor.session.setValue("");
|
||||
});
|
||||
this.input.listen("prevHist", "up", () => {
|
||||
histIndex++;
|
||||
if (histIndex >= history.length) histIndex = history.length - 1;
|
||||
if (history.length > 0)
|
||||
this.input.editor.session.setValue(history[histIndex]);
|
||||
gotoEnd(this.input.editor);
|
||||
});
|
||||
this.input.listen("nextHist", "down", () => {
|
||||
histIndex--;
|
||||
if (histIndex < -1) histIndex = -1;
|
||||
if (histIndex >= 0 && history.length > 0) {
|
||||
this.input.editor.session.setValue(history[histIndex]);
|
||||
} else {
|
||||
this.input.editor.session.setValue("");
|
||||
}
|
||||
gotoEnd(this.input.editor);
|
||||
});
|
||||
|
||||
bar.dragged = function (e) {
|
||||
const barHeight = 3,
|
||||
minY = barHeight,
|
||||
maxY = window.innerHeight;
|
||||
maxY = window.innerHeight - 3;
|
||||
let newY = e.clientY;
|
||||
if (newY < minY) newY = minY;
|
||||
if (newY > maxY) newY = maxY;
|
||||
|
|
|
@ -37,11 +37,11 @@
|
|||
}
|
||||
|
||||
.display.warn {
|
||||
background: #ffff0033;
|
||||
background: #e6e15533;
|
||||
}
|
||||
|
||||
.display.error {
|
||||
background: #ff000033;
|
||||
background: #ed584533;
|
||||
}
|
||||
|
||||
.display div:not(.expand) {
|
||||
|
@ -99,5 +99,5 @@
|
|||
}
|
||||
|
||||
.display .error {
|
||||
color: #d43;
|
||||
color: #ff6225;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ vm.setConsole(consol);
|
|||
|
||||
consol.run = (code) => {
|
||||
const res = vm.runLess(code);
|
||||
consol.log(res);
|
||||
consol[res.err ? "error" : "log"](res.value);
|
||||
};
|
||||
|
||||
ipcRenderer.on("menu", (e, message) => {
|
||||
|
@ -105,7 +105,8 @@ ipcRenderer.on("menu", (e, message) => {
|
|||
format();
|
||||
break;
|
||||
case "run":
|
||||
consol.log(vm.run(edit.editor.session.getValue()));
|
||||
const res = vm.run(edit.editor.session.getValue());
|
||||
consol[res.err ? "error" : "log"](res.value);
|
||||
break;
|
||||
case "clear":
|
||||
consol.clear();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"outDir": "dist",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"target": "es6",
|
||||
"paths": {
|
||||
"*": ["node_modules/*"]
|
||||
}
|
||||
|
|
Reference in a new issue