Repository navigation
Expand file tree
/
Copy pathsandbox.js
More file actions
106 lines (90 loc) · 3.2 KB
/
Copy pathsandbox.js
File metadata and controls
106 lines (90 loc) · 3.2 KB
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
var path = require('path');
var process = require('process');
var fs = require('fs');
var vm = require('vm');
var morgan = require('morgan');
var attachLiquidTemplateEngine = require('./attach-liquid-template-engine');
var bodyParser = require('body-parser');
var dirname = require('path').dirname;
var timers = require('timers');
var app;
var Sandbox = {};
var warnedAboutMethods = {};
Sandbox.define = function define() {
var url, verb, handler;
if (arguments.length === 2) {
url = arguments[0];
verb = 'get';
handler = arguments[1];
} else if (arguments.length === 3) {
url = arguments[0];
verb = arguments[1];
handler = arguments[2];
}
verb = verb.toLowerCase();
url = url.replace(/{(.+?)}/g, ":$1");
url = encodeURI(url);
if (typeof app[verb] === 'function') {
app[verb](url, handler);
} else {
if (!warnedAboutMethods[verb]) {
console.warn("Ignoring registration of '" + verb.toUpperCase() + "' http method, because it's not implemented in Express.js.");
warnedAboutMethods[verb] = true;
}
}
};
var loadSandbox = function loadSandbox(expressApp, sandboxMainPath, options) {
if (!path.isAbsolute(sandboxMainPath)) {
throw new Error('sandbox main path must be absolute path');
}
options = options || {};
app = expressApp;
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
var sandboxDir = path.dirname(sandboxMainPath);
attachLiquidTemplateEngine(app, sandboxDir);
var sandbox = {};
// this require function is only for relative files, it passes the sandbox content (3rd party libs etc. to the required modules)
sandbox.require = (file, requiringFile) => {
if (!file.match(/\.js$/)) file += '.js';
var pathToSource = path.resolve(dirname(requiringFile || sandboxMainPath), file);
var script = new vm.Script(fs.readFileSync(pathToSource).toString().replace(/require\(([^\)]+)/g, 'require($1, \'' + pathToSource + '\''), { filename: file });
var requireContext = {
...sandbox,
exports: {}
};
script.runInNewContext(requireContext);
return requireContext.exports;
};
sandbox.Sandbox = Sandbox;
sandbox.state = {};
sandbox.moment = require('moment-timezone');
sandbox._ = require('lodash');
sandbox.faker = require('faker');
sandbox.amanda = require('amanda');
sandbox.validator = require('validator');
sandbox.console = console;
if (options.persistState === true) {
const statefile = dirname(sandboxMainPath) + '/state.json';
// on init restore the state from statefile if it exists
if (fs.existsSync(statefile)) {
try {
sandbox.state = JSON.parse(fs.readFileSync(statefile, 'utf8'));
console.info('Restored state from ' + statefile);
} catch(e) {
sandbox.state = {};
console.warn('Could not restore state ' + e);
}
}
// periodically save state
timers.setInterval(() => {
fs.writeFileSync(statefile, JSON.stringify(sandbox.state));
}, 1000);
}
var script = new vm.Script(fs.readFileSync(sandboxMainPath).toString(), { filename: sandboxMainPath });
script.runInNewContext(sandbox);
};
module.exports = {
loadSandbox: loadSandbox
};