@squiz/render-runtime-lib 1.2.1-alpha.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/lib/component-runner/component-runner.spec.d.ts +1 -0
- package/lib/component-runner/index.d.ts +22 -0
- package/lib/component-runner/worker/WorkerPool.d.ts +50 -0
- package/lib/component-runner/worker/getRuntimeModules.d.ts +1 -0
- package/lib/component-runner/worker/worker-root.d.ts +1 -0
- package/lib/index.d.ts +25 -0
- package/lib/index.js +112791 -0
- package/lib/index.js.map +7 -0
- package/lib/migrations/20220704054051_initial.sql +19 -0
- package/lib/migrations/20220718172237_adding_component_sets.sql +23 -0
- package/lib/migrations/20220728113941_add_env_vars_field.sql +1 -0
- package/lib/migrations/20220817113300_removing_null_props_from_jsonb.sql +41 -0
- package/lib/render-runtime-lib.spec.d.ts +1 -0
- package/lib/test/helpers/fixtures.d.ts +20 -0
- package/lib/test/helpers/stack.d.ts +6 -0
- package/lib/test/index.d.ts +2 -0
- package/lib/utils/convertFunctionStaticFilesToFqdn.d.ts +1 -0
- package/lib/utils/convertFunctionStaticFilesToFqdn.spec.d.ts +1 -0
- package/lib/utils/getFunctionDefinitionFromManifest.d.ts +2 -0
- package/lib/utils/getManifestPath.d.ts +1 -0
- package/lib/utils/getManifestPath.spec.d.ts +1 -0
- package/lib/utils/getPreviewFilePath.d.ts +1 -0
- package/lib/utils/getPreviewFilePath.spec.d.ts +1 -0
- package/lib/utils/isInProductionMode.d.ts +1 -0
- package/lib/utils/isInProductionMode.spec.d.ts +1 -0
- package/lib/utils/resolvePreviewOutput.d.ts +2 -0
- package/lib/utils/resolvePreviewOutput.spec.d.ts +1 -0
- package/lib/webserver/app.d.ts +4 -0
- package/lib/webserver/controllers/core.d.ts +3 -0
- package/lib/webserver/controllers/core.spec.d.ts +1 -0
- package/lib/webserver/controllers/definition.d.ts +3 -0
- package/lib/webserver/controllers/definition.spec.d.ts +1 -0
- package/lib/webserver/controllers/index.d.ts +4 -0
- package/lib/webserver/controllers/render.d.ts +3 -0
- package/lib/webserver/controllers/render.spec.d.ts +1 -0
- package/lib/webserver/controllers/static.d.ts +3 -0
- package/lib/webserver/controllers/static.spec.d.ts +1 -0
- package/lib/webserver/controllers/test/definition-route-tests.d.ts +1 -0
- package/lib/webserver/controllers/test/render-route-tests.d.ts +1 -0
- package/lib/webserver/controllers/test/static-route-tests.d.ts +1 -0
- package/lib/webserver/index.d.ts +22 -0
- package/lib/worker/bridge.js +1010 -0
- package/lib/worker/compiler.js +87 -0
- package/lib/worker/events.js +977 -0
- package/lib/worker/nodevm.js +503 -0
- package/lib/worker/resolver-compat.js +342 -0
- package/lib/worker/resolver.js +882 -0
- package/lib/worker/script.js +388 -0
- package/lib/worker/setup-node-sandbox.js +469 -0
- package/lib/worker/setup-sandbox.js +456 -0
- package/lib/worker/transformer.js +180 -0
- package/lib/worker/vm.js +539 -0
- package/lib/worker/worker-root.js +41743 -0
- package/lib/worker/worker-root.js.map +7 -0
- package/package.json +60 -0
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This callback will be called to resolve a module if it couldn't be found.
|
|
5
|
+
*
|
|
6
|
+
* @callback resolveCallback
|
|
7
|
+
* @param {string} moduleName - Name of the module used to resolve.
|
|
8
|
+
* @param {string} dirname - Name of the current directory.
|
|
9
|
+
* @return {(string|undefined)} The file or directory to use to load the requested module.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This callback will be called to require a module instead of node's require.
|
|
14
|
+
*
|
|
15
|
+
* @callback customRequire
|
|
16
|
+
* @param {string} moduleName - Name of the module requested.
|
|
17
|
+
* @return {*} The required module object.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const fs = require('fs');
|
|
21
|
+
const pa = require('path');
|
|
22
|
+
const {
|
|
23
|
+
Script
|
|
24
|
+
} = require('vm');
|
|
25
|
+
const {
|
|
26
|
+
VMError
|
|
27
|
+
} = require('./bridge');
|
|
28
|
+
const {
|
|
29
|
+
VMScript,
|
|
30
|
+
MODULE_PREFIX,
|
|
31
|
+
STRICT_MODULE_PREFIX,
|
|
32
|
+
MODULE_SUFFIX
|
|
33
|
+
} = require('./script');
|
|
34
|
+
const {
|
|
35
|
+
transformer
|
|
36
|
+
} = require('./transformer');
|
|
37
|
+
const {
|
|
38
|
+
VM
|
|
39
|
+
} = require('./vm');
|
|
40
|
+
const {
|
|
41
|
+
resolverFromOptions
|
|
42
|
+
} = require('./resolver-compat');
|
|
43
|
+
|
|
44
|
+
const objectDefineProperty = Object.defineProperty;
|
|
45
|
+
const objectDefineProperties = Object.defineProperties;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Host objects
|
|
49
|
+
*
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
const HOST = Object.freeze({
|
|
53
|
+
__proto__: null,
|
|
54
|
+
version: parseInt(process.versions.node.split('.')[0]),
|
|
55
|
+
process,
|
|
56
|
+
console,
|
|
57
|
+
setTimeout,
|
|
58
|
+
setInterval,
|
|
59
|
+
setImmediate,
|
|
60
|
+
clearTimeout,
|
|
61
|
+
clearInterval,
|
|
62
|
+
clearImmediate
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Compile a script.
|
|
67
|
+
*
|
|
68
|
+
* @private
|
|
69
|
+
* @param {string} filename - Filename of the script.
|
|
70
|
+
* @param {string} script - Script.
|
|
71
|
+
* @return {vm.Script} The compiled script.
|
|
72
|
+
*/
|
|
73
|
+
function compileScript(filename, script) {
|
|
74
|
+
return new Script(script, {
|
|
75
|
+
__proto__: null,
|
|
76
|
+
filename,
|
|
77
|
+
displayErrors: false
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let cacheSandboxScript = null;
|
|
82
|
+
let cacheMakeNestingScript = null;
|
|
83
|
+
|
|
84
|
+
const NESTING_OVERRIDE = Object.freeze({
|
|
85
|
+
__proto__: null,
|
|
86
|
+
vm2: vm2NestingLoader
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Event caused by a <code>console.debug</code> call if <code>options.console="redirect"</code> is specified.
|
|
91
|
+
*
|
|
92
|
+
* @public
|
|
93
|
+
* @event NodeVM."console.debug"
|
|
94
|
+
* @type {...*}
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Event caused by a <code>console.log</code> call if <code>options.console="redirect"</code> is specified.
|
|
99
|
+
*
|
|
100
|
+
* @public
|
|
101
|
+
* @event NodeVM."console.log"
|
|
102
|
+
* @type {...*}
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Event caused by a <code>console.info</code> call if <code>options.console="redirect"</code> is specified.
|
|
107
|
+
*
|
|
108
|
+
* @public
|
|
109
|
+
* @event NodeVM."console.info"
|
|
110
|
+
* @type {...*}
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Event caused by a <code>console.warn</code> call if <code>options.console="redirect"</code> is specified.
|
|
115
|
+
*
|
|
116
|
+
* @public
|
|
117
|
+
* @event NodeVM."console.warn"
|
|
118
|
+
* @type {...*}
|
|
119
|
+
*/
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Event caused by a <code>console.error</code> call if <code>options.console="redirect"</code> is specified.
|
|
123
|
+
*
|
|
124
|
+
* @public
|
|
125
|
+
* @event NodeVM."console.error"
|
|
126
|
+
* @type {...*}
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Event caused by a <code>console.dir</code> call if <code>options.console="redirect"</code> is specified.
|
|
131
|
+
*
|
|
132
|
+
* @public
|
|
133
|
+
* @event NodeVM."console.dir"
|
|
134
|
+
* @type {...*}
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Event caused by a <code>console.trace</code> call if <code>options.console="redirect"</code> is specified.
|
|
139
|
+
*
|
|
140
|
+
* @public
|
|
141
|
+
* @event NodeVM."console.trace"
|
|
142
|
+
* @type {...*}
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Class NodeVM.
|
|
147
|
+
*
|
|
148
|
+
* @public
|
|
149
|
+
* @extends {VM}
|
|
150
|
+
* @extends {EventEmitter}
|
|
151
|
+
*/
|
|
152
|
+
class NodeVM extends VM {
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Create a new NodeVM instance.<br>
|
|
156
|
+
*
|
|
157
|
+
* Unlike VM, NodeVM lets you use require same way like in regular node.<br>
|
|
158
|
+
*
|
|
159
|
+
* However, it does not use the timeout.
|
|
160
|
+
*
|
|
161
|
+
* @public
|
|
162
|
+
* @param {Object} [options] - VM options.
|
|
163
|
+
* @param {Object} [options.sandbox] - Objects that will be copied into the global object of the sandbox.
|
|
164
|
+
* @param {(string|compileCallback)} [options.compiler="javascript"] - The compiler to use.
|
|
165
|
+
* @param {boolean} [options.eval=true] - Allow the dynamic evaluation of code via eval(code) or Function(code)().<br>
|
|
166
|
+
* Only available for node v10+.
|
|
167
|
+
* @param {boolean} [options.wasm=true] - Allow to run wasm code.<br>
|
|
168
|
+
* Only available for node v10+.
|
|
169
|
+
* @param {("inherit"|"redirect"|"off")} [options.console="inherit"] - Sets the behavior of the console in the sandbox.
|
|
170
|
+
* <code>inherit</code> to enable console, <code>redirect</code> to redirect to events, <code>off</code> to disable console.
|
|
171
|
+
* @param {Object|boolean} [options.require=false] - Allow require inside the sandbox.
|
|
172
|
+
* @param {(boolean|string[]|Object)} [options.require.external=false] - <b>WARNING: When allowing require the option <code>options.require.root</code>
|
|
173
|
+
* should be set to restrict the script from requiring any module. Values can be true, an array of allowed external modules or an object.
|
|
174
|
+
* @param {(string[])} [options.require.external.modules] - Array of allowed external modules. Also supports wildcards, so specifying ['@scope/*-ver-??],
|
|
175
|
+
* for instance, will allow using all modules having a name of the form @scope/something-ver-aa, @scope/other-ver-11, etc.
|
|
176
|
+
* @param {boolean} [options.require.external.transitive=false] - Boolean which indicates if transitive dependencies of external modules are allowed.
|
|
177
|
+
* @param {string[]} [options.require.builtin=[]] - Array of allowed built-in modules, accepts ["*"] for all.
|
|
178
|
+
* @param {(string|string[])} [options.require.root] - Restricted path(s) where local modules can be required. If omitted every path is allowed.
|
|
179
|
+
* @param {Object} [options.require.mock] - Collection of mock modules (both external or built-in).
|
|
180
|
+
* @param {("host"|"sandbox")} [options.require.context="host"] - <code>host</code> to require modules in host and proxy them to sandbox.
|
|
181
|
+
* <code>sandbox</code> to load, compile and require modules in sandbox.
|
|
182
|
+
* Builtin modules except <code>events</code> always required in host and proxied to sandbox.
|
|
183
|
+
* @param {string[]} [options.require.import] - Array of modules to be loaded into NodeVM on start.
|
|
184
|
+
* @param {resolveCallback} [options.require.resolve] - An additional lookup function in case a module wasn't
|
|
185
|
+
* found in one of the traditional node lookup paths.
|
|
186
|
+
* @param {customRequire} [options.require.customRequire=require] - Custom require to require host and built-in modules.
|
|
187
|
+
* @param {boolean} [options.nesting=false] -
|
|
188
|
+
* <b>WARNING: Allowing this is a security risk as scripts can create a NodeVM which can require any host module.</b>
|
|
189
|
+
* Allow nesting of VMs.
|
|
190
|
+
* @param {("commonjs"|"none")} [options.wrapper="commonjs"] - <code>commonjs</code> to wrap script into CommonJS wrapper,
|
|
191
|
+
* <code>none</code> to retrieve value returned by the script.
|
|
192
|
+
* @param {string[]} [options.sourceExtensions=["js"]] - Array of file extensions to treat as source code.
|
|
193
|
+
* @param {string[]} [options.argv=[]] - Array of arguments passed to <code>process.argv</code>.
|
|
194
|
+
* This object will not be copied and the script can change this object.
|
|
195
|
+
* @param {Object} [options.env={}] - Environment map passed to <code>process.env</code>.
|
|
196
|
+
* This object will not be copied and the script can change this object.
|
|
197
|
+
* @param {boolean} [options.strict=false] - If modules should be loaded in strict mode.
|
|
198
|
+
* @throws {VMError} If the compiler is unknown.
|
|
199
|
+
*/
|
|
200
|
+
constructor(options = {}) {
|
|
201
|
+
const {
|
|
202
|
+
compiler,
|
|
203
|
+
eval: allowEval,
|
|
204
|
+
wasm,
|
|
205
|
+
console: consoleType = 'inherit',
|
|
206
|
+
require: requireOpts = false,
|
|
207
|
+
nesting = false,
|
|
208
|
+
wrapper = 'commonjs',
|
|
209
|
+
sourceExtensions = ['js'],
|
|
210
|
+
argv,
|
|
211
|
+
env,
|
|
212
|
+
strict = false,
|
|
213
|
+
sandbox
|
|
214
|
+
} = options;
|
|
215
|
+
|
|
216
|
+
// Throw this early
|
|
217
|
+
if (sandbox && 'object' !== typeof sandbox) {
|
|
218
|
+
throw new VMError('Sandbox must be an object.');
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
super({__proto__: null, compiler: compiler, eval: allowEval, wasm});
|
|
222
|
+
|
|
223
|
+
// This is only here for backwards compatibility.
|
|
224
|
+
objectDefineProperty(this, 'options', {__proto__: null, value: {
|
|
225
|
+
console: consoleType,
|
|
226
|
+
require: requireOpts,
|
|
227
|
+
nesting,
|
|
228
|
+
wrapper,
|
|
229
|
+
sourceExtensions,
|
|
230
|
+
strict
|
|
231
|
+
}});
|
|
232
|
+
|
|
233
|
+
const resolver = resolverFromOptions(this, requireOpts, nesting && NESTING_OVERRIDE, this._compiler);
|
|
234
|
+
|
|
235
|
+
objectDefineProperty(this, '_resolver', {__proto__: null, value: resolver});
|
|
236
|
+
|
|
237
|
+
if (!cacheSandboxScript) {
|
|
238
|
+
cacheSandboxScript = compileScript(`${__dirname}/setup-node-sandbox.js`,
|
|
239
|
+
`(function (host, data) { ${fs.readFileSync(`${__dirname}/setup-node-sandbox.js`, 'utf8')}\n})`);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const closure = this._runScript(cacheSandboxScript);
|
|
243
|
+
|
|
244
|
+
const extensions = {
|
|
245
|
+
__proto__: null
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const loadJS = (mod, filename) => resolver.loadJS(this, mod, filename);
|
|
249
|
+
|
|
250
|
+
for (let i = 0; i < sourceExtensions.length; i++) {
|
|
251
|
+
extensions['.' + sourceExtensions[i]] = loadJS;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (!extensions['.json']) extensions['.json'] = (mod, filename) => resolver.loadJSON(this, mod, filename);
|
|
255
|
+
if (!extensions['.node']) extensions['.node'] = (mod, filename) => resolver.loadNode(this, mod, filename);
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
this.readonly(HOST);
|
|
259
|
+
this.readonly(resolver);
|
|
260
|
+
this.readonly(this);
|
|
261
|
+
|
|
262
|
+
const {
|
|
263
|
+
Module,
|
|
264
|
+
jsonParse,
|
|
265
|
+
createRequireForModule,
|
|
266
|
+
requireImpl
|
|
267
|
+
} = closure(HOST, {
|
|
268
|
+
__proto__: null,
|
|
269
|
+
argv,
|
|
270
|
+
env,
|
|
271
|
+
console: consoleType,
|
|
272
|
+
vm: this,
|
|
273
|
+
resolver,
|
|
274
|
+
extensions
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
objectDefineProperties(this, {
|
|
278
|
+
__proto__: null,
|
|
279
|
+
_Module: {__proto__: null, value: Module},
|
|
280
|
+
_jsonParse: {__proto__: null, value: jsonParse},
|
|
281
|
+
_createRequireForModule: {__proto__: null, value: createRequireForModule},
|
|
282
|
+
_requireImpl: {__proto__: null, value: requireImpl},
|
|
283
|
+
_cacheRequireModule: {__proto__: null, value: null, writable: true}
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
resolver.init(this);
|
|
288
|
+
|
|
289
|
+
// prepare global sandbox
|
|
290
|
+
if (sandbox) {
|
|
291
|
+
this.setGlobals(sandbox);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (requireOpts && requireOpts.import) {
|
|
295
|
+
if (Array.isArray(requireOpts.import)) {
|
|
296
|
+
for (let i = 0, l = requireOpts.import.length; i < l; i++) {
|
|
297
|
+
this.require(requireOpts.import[i]);
|
|
298
|
+
}
|
|
299
|
+
} else {
|
|
300
|
+
this.require(requireOpts.import);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* @ignore
|
|
307
|
+
* @deprecated Just call the method yourself like <code>method(args);</code>
|
|
308
|
+
* @param {function} method - Function to invoke.
|
|
309
|
+
* @param {...*} args - Arguments to pass to the function.
|
|
310
|
+
* @return {*} Return value of the function.
|
|
311
|
+
* @todo Can we remove this function? It even had a bug that would use args as this parameter.
|
|
312
|
+
* @throws {*} Rethrows anything the method throws.
|
|
313
|
+
* @throws {VMError} If method is not a function.
|
|
314
|
+
* @throws {Error} If method is a class.
|
|
315
|
+
*/
|
|
316
|
+
call(method, ...args) {
|
|
317
|
+
if ('function' === typeof method) {
|
|
318
|
+
return method(...args);
|
|
319
|
+
} else {
|
|
320
|
+
throw new VMError('Unrecognized method type.');
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Require a module in VM and return it's exports.
|
|
326
|
+
*
|
|
327
|
+
* @public
|
|
328
|
+
* @param {string} module - Module name.
|
|
329
|
+
* @return {*} Exported module.
|
|
330
|
+
* @throws {*} If the module couldn't be found or loading it threw an error.
|
|
331
|
+
*/
|
|
332
|
+
require(module) {
|
|
333
|
+
const path = this._resolver.pathResolve('.');
|
|
334
|
+
let mod = this._cacheRequireModule;
|
|
335
|
+
if (!mod || mod.path !== path) {
|
|
336
|
+
const filename = this._resolver.pathConcat(path, '/vm.js');
|
|
337
|
+
mod = new (this._Module)(filename, path);
|
|
338
|
+
this._resolver.registerModule(mod, filename, path, null, false);
|
|
339
|
+
this._cacheRequireModule = mod;
|
|
340
|
+
}
|
|
341
|
+
return this._requireImpl(mod, module, true);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Run the code in NodeVM.
|
|
346
|
+
*
|
|
347
|
+
* First time you run this method, code is executed same way like in node's regular `require` - it's executed with
|
|
348
|
+
* `module`, `require`, `exports`, `__dirname`, `__filename` variables and expect result in `module.exports'.
|
|
349
|
+
*
|
|
350
|
+
* @param {(string|VMScript)} code - Code to run.
|
|
351
|
+
* @param {(string|Object)} [options] - Options map or filename.
|
|
352
|
+
* @param {string} [options.filename="vm.js"] - Filename that shows up in any stack traces produced from this script.<br>
|
|
353
|
+
* This is only used if code is a String.
|
|
354
|
+
* @param {boolean} [options.strict] - If modules should be loaded in strict mode. Defaults to NodeVM options.
|
|
355
|
+
* @param {("commonjs"|"none")} [options.wrapper] - <code>commonjs</code> to wrap script into CommonJS wrapper,
|
|
356
|
+
* <code>none</code> to retrieve value returned by the script. Defaults to NodeVM options.
|
|
357
|
+
* @return {*} Result of executed code.
|
|
358
|
+
* @throws {SyntaxError} If there is a syntax error in the script.
|
|
359
|
+
* @throws {*} If the script execution terminated with an exception it is propagated.
|
|
360
|
+
* @fires NodeVM."console.debug"
|
|
361
|
+
* @fires NodeVM."console.log"
|
|
362
|
+
* @fires NodeVM."console.info"
|
|
363
|
+
* @fires NodeVM."console.warn"
|
|
364
|
+
* @fires NodeVM."console.error"
|
|
365
|
+
* @fires NodeVM."console.dir"
|
|
366
|
+
* @fires NodeVM."console.trace"
|
|
367
|
+
*/
|
|
368
|
+
run(code, options) {
|
|
369
|
+
let script;
|
|
370
|
+
let filename;
|
|
371
|
+
|
|
372
|
+
if (typeof options === 'object') {
|
|
373
|
+
filename = options.filename;
|
|
374
|
+
} else {
|
|
375
|
+
filename = options;
|
|
376
|
+
options = {__proto__: null};
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const {
|
|
380
|
+
strict = this.options.strict,
|
|
381
|
+
wrapper = this.options.wrapper,
|
|
382
|
+
module: customModule,
|
|
383
|
+
require: customRequire,
|
|
384
|
+
dirname: customDirname = null
|
|
385
|
+
} = options;
|
|
386
|
+
|
|
387
|
+
let sandboxModule = customModule;
|
|
388
|
+
let dirname = customDirname;
|
|
389
|
+
|
|
390
|
+
if (code instanceof VMScript) {
|
|
391
|
+
script = strict ? code._compileNodeVMStrict() : code._compileNodeVM();
|
|
392
|
+
if (!sandboxModule) {
|
|
393
|
+
const resolvedFilename = this._resolver.pathResolve(code.filename);
|
|
394
|
+
dirname = this._resolver.pathDirname(resolvedFilename);
|
|
395
|
+
sandboxModule = new (this._Module)(resolvedFilename, dirname);
|
|
396
|
+
this._resolver.registerModule(sandboxModule, resolvedFilename, dirname, null, false);
|
|
397
|
+
}
|
|
398
|
+
} else {
|
|
399
|
+
const unresolvedFilename = filename || 'vm.js';
|
|
400
|
+
if (!sandboxModule) {
|
|
401
|
+
if (filename) {
|
|
402
|
+
const resolvedFilename = this._resolver.pathResolve(filename);
|
|
403
|
+
dirname = this._resolver.pathDirname(resolvedFilename);
|
|
404
|
+
sandboxModule = new (this._Module)(resolvedFilename, dirname);
|
|
405
|
+
this._resolver.registerModule(sandboxModule, resolvedFilename, dirname, null, false);
|
|
406
|
+
} else {
|
|
407
|
+
sandboxModule = new (this._Module)(null, null);
|
|
408
|
+
sandboxModule.id = unresolvedFilename;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
const prefix = strict ? STRICT_MODULE_PREFIX : MODULE_PREFIX;
|
|
412
|
+
let scriptCode = this._compiler(code, unresolvedFilename);
|
|
413
|
+
scriptCode = transformer(null, scriptCode, false, false, unresolvedFilename).code;
|
|
414
|
+
script = new Script(prefix + scriptCode + MODULE_SUFFIX, {
|
|
415
|
+
__proto__: null,
|
|
416
|
+
filename: unresolvedFilename,
|
|
417
|
+
displayErrors: false
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const closure = this._runScript(script);
|
|
422
|
+
|
|
423
|
+
const usedRequire = customRequire || this._createRequireForModule(sandboxModule);
|
|
424
|
+
|
|
425
|
+
const ret = Reflect.apply(closure, this.sandbox, [sandboxModule.exports, usedRequire, sandboxModule, filename, dirname]);
|
|
426
|
+
return wrapper === 'commonjs' ? sandboxModule.exports : ret;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Create NodeVM and run code inside it.
|
|
431
|
+
*
|
|
432
|
+
* @public
|
|
433
|
+
* @static
|
|
434
|
+
* @param {string} script - Code to execute.
|
|
435
|
+
* @param {string} [filename] - File name (used in stack traces only).
|
|
436
|
+
* @param {Object} [options] - VM options.
|
|
437
|
+
* @param {string} [options.filename] - File name (used in stack traces only). Used if <code>filename</code> is omitted.
|
|
438
|
+
* @return {*} Result of executed code.
|
|
439
|
+
* @see {@link NodeVM} for the options.
|
|
440
|
+
* @throws {SyntaxError} If there is a syntax error in the script.
|
|
441
|
+
* @throws {*} If the script execution terminated with an exception it is propagated.
|
|
442
|
+
*/
|
|
443
|
+
static code(script, filename, options) {
|
|
444
|
+
let unresolvedFilename;
|
|
445
|
+
if (filename != null) {
|
|
446
|
+
if ('object' === typeof filename) {
|
|
447
|
+
options = filename;
|
|
448
|
+
unresolvedFilename = options.filename;
|
|
449
|
+
} else if ('string' === typeof filename) {
|
|
450
|
+
unresolvedFilename = filename;
|
|
451
|
+
} else {
|
|
452
|
+
throw new VMError('Invalid arguments.');
|
|
453
|
+
}
|
|
454
|
+
} else if ('object' === typeof options) {
|
|
455
|
+
unresolvedFilename = options.filename;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (arguments.length > 3) {
|
|
459
|
+
throw new VMError('Invalid number of arguments.');
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const resolvedFilename = typeof unresolvedFilename === 'string' ? pa.resolve(unresolvedFilename) : undefined;
|
|
463
|
+
|
|
464
|
+
return new NodeVM(options).run(script, resolvedFilename);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Create NodeVM and run script from file inside it.
|
|
469
|
+
*
|
|
470
|
+
* @public
|
|
471
|
+
* @static
|
|
472
|
+
* @param {string} filename - Filename of file to load and execute in a NodeVM.
|
|
473
|
+
* @param {Object} [options] - NodeVM options.
|
|
474
|
+
* @return {*} Result of executed code.
|
|
475
|
+
* @see {@link NodeVM} for the options.
|
|
476
|
+
* @throws {Error} If filename is not a valid filename.
|
|
477
|
+
* @throws {SyntaxError} If there is a syntax error in the script.
|
|
478
|
+
* @throws {*} If the script execution terminated with an exception it is propagated.
|
|
479
|
+
*/
|
|
480
|
+
static file(filename, options) {
|
|
481
|
+
const resolvedFilename = pa.resolve(filename);
|
|
482
|
+
|
|
483
|
+
if (!fs.existsSync(resolvedFilename)) {
|
|
484
|
+
throw new VMError(`Script '${filename}' not found.`);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (fs.statSync(resolvedFilename).isDirectory()) {
|
|
488
|
+
throw new VMError('Script must be file, got directory.');
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
return new NodeVM(options).run(fs.readFileSync(resolvedFilename, 'utf8'), resolvedFilename);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
function vm2NestingLoader(resolver, vm, id) {
|
|
496
|
+
if (!cacheMakeNestingScript) {
|
|
497
|
+
cacheMakeNestingScript = compileScript('nesting.js', '(vm, nodevm) => ({VM: vm, NodeVM: nodevm})');
|
|
498
|
+
}
|
|
499
|
+
const makeNesting = vm._runScript(cacheMakeNestingScript);
|
|
500
|
+
return makeNesting(vm.readonly(VM), vm.readonly(NodeVM));
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
exports.NodeVM = NodeVM;
|