@novolobos/nodevm 3.10.5

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/lib/script.js ADDED
@@ -0,0 +1,394 @@
1
+ 'use strict';
2
+
3
+ const {Script} = require('vm');
4
+ const {
5
+ lookupCompiler,
6
+ removeShebang
7
+ } = require('./compiler');
8
+ const {
9
+ transformer
10
+ } = require('./transformer');
11
+
12
+ const objectDefineProperties = Object.defineProperties;
13
+
14
+ const MODULE_PREFIX = '(function (exports, require, module, __filename, __dirname) { ';
15
+ const STRICT_MODULE_PREFIX = MODULE_PREFIX + '"use strict"; ';
16
+ const MODULE_SUFFIX = '\n});';
17
+
18
+ /**
19
+ * Class Script
20
+ *
21
+ * @public
22
+ */
23
+ class VMScript {
24
+
25
+ /**
26
+ * The script code with wrapping. If set will invalidate the cache.<br>
27
+ * Writable only for backwards compatibility.
28
+ *
29
+ * @public
30
+ * @readonly
31
+ * @member {string} code
32
+ * @memberOf VMScript#
33
+ */
34
+
35
+ /**
36
+ * The filename used for this script.
37
+ *
38
+ * @public
39
+ * @readonly
40
+ * @since v3.9.0
41
+ * @member {string} filename
42
+ * @memberOf VMScript#
43
+ */
44
+
45
+ /**
46
+ * The line offset use for stack traces.
47
+ *
48
+ * @public
49
+ * @readonly
50
+ * @since v3.9.0
51
+ * @member {number} lineOffset
52
+ * @memberOf VMScript#
53
+ */
54
+
55
+ /**
56
+ * The column offset use for stack traces.
57
+ *
58
+ * @public
59
+ * @readonly
60
+ * @since v3.9.0
61
+ * @member {number} columnOffset
62
+ * @memberOf VMScript#
63
+ */
64
+
65
+ /**
66
+ * The compiler to use to get the JavaScript code.
67
+ *
68
+ * @public
69
+ * @readonly
70
+ * @since v3.9.0
71
+ * @member {(string|compileCallback)} compiler
72
+ * @memberOf VMScript#
73
+ */
74
+
75
+ /**
76
+ * The prefix for the script.
77
+ *
78
+ * @private
79
+ * @member {string} _prefix
80
+ * @memberOf VMScript#
81
+ */
82
+
83
+ /**
84
+ * The suffix for the script.
85
+ *
86
+ * @private
87
+ * @member {string} _suffix
88
+ * @memberOf VMScript#
89
+ */
90
+
91
+ /**
92
+ * The compiled vm.Script for the VM or if not compiled <code>null</code>.
93
+ *
94
+ * @private
95
+ * @member {?vm.Script} _compiledVM
96
+ * @memberOf VMScript#
97
+ */
98
+
99
+ /**
100
+ * The compiled vm.Script for the NodeVM or if not compiled <code>null</code>.
101
+ *
102
+ * @private
103
+ * @member {?vm.Script} _compiledNodeVM
104
+ * @memberOf VMScript#
105
+ */
106
+
107
+ /**
108
+ * The compiled vm.Script for the NodeVM in strict mode or if not compiled <code>null</code>.
109
+ *
110
+ * @private
111
+ * @member {?vm.Script} _compiledNodeVMStrict
112
+ * @memberOf VMScript#
113
+ */
114
+
115
+ /**
116
+ * The resolved compiler to use to get the JavaScript code.
117
+ *
118
+ * @private
119
+ * @readonly
120
+ * @member {compileCallback} _compiler
121
+ * @memberOf VMScript#
122
+ */
123
+
124
+ /**
125
+ * The script to run without wrapping.
126
+ *
127
+ * @private
128
+ * @member {string} _code
129
+ * @memberOf VMScript#
130
+ */
131
+
132
+ /**
133
+ * Whether or not the script contains async functions.
134
+ *
135
+ * @private
136
+ * @member {boolean} _hasAsync
137
+ * @memberOf VMScript#
138
+ */
139
+
140
+ /**
141
+ * Create VMScript instance.
142
+ *
143
+ * @public
144
+ * @param {string} code - Code to run.
145
+ * @param {(string|Object)} [options] - Options map or filename.
146
+ * @param {string} [options.filename="vm.js"] - Filename that shows up in any stack traces produced from this script.
147
+ * @param {number} [options.lineOffset=0] - Passed to vm.Script options.
148
+ * @param {number} [options.columnOffset=0] - Passed to vm.Script options.
149
+ * @param {(string|compileCallback)} [options.compiler="javascript"] - The compiler to use.
150
+ * @throws {VMError} If the compiler is unknown or if coffee-script was requested but the module not found.
151
+ */
152
+ constructor(code, options) {
153
+ const sCode = `${code}`;
154
+ let useFileName;
155
+ let useOptions;
156
+ if (arguments.length === 2) {
157
+ if (typeof options === 'object') {
158
+ useOptions = options || {__proto__: null};
159
+ useFileName = useOptions.filename;
160
+ } else {
161
+ useOptions = {__proto__: null};
162
+ useFileName = options;
163
+ }
164
+ } else if (arguments.length > 2) {
165
+ // We do it this way so that there are no more arguments in the function.
166
+ // eslint-disable-next-line prefer-rest-params
167
+ useOptions = arguments[2] || {__proto__: null};
168
+ useFileName = options || useOptions.filename;
169
+ } else {
170
+ useOptions = {__proto__: null};
171
+ }
172
+
173
+ const {
174
+ compiler = 'javascript',
175
+ compilerOptions,
176
+ lineOffset = 0,
177
+ columnOffset = 0
178
+ } = useOptions;
179
+
180
+ // Throw if the compiler is unknown.
181
+ const resolvedCompiler = lookupCompiler(compiler, compilerOptions);
182
+
183
+ objectDefineProperties(this, {
184
+ __proto__: null,
185
+ code: {
186
+ __proto__: null,
187
+ // Put this here so that it is enumerable, and looks like a property.
188
+ get() {
189
+ return this._prefix + this._code + this._suffix;
190
+ },
191
+ set(value) {
192
+ const strNewCode = String(value);
193
+ if (strNewCode === this._code && this._prefix === '' && this._suffix === '') return;
194
+ this._code = strNewCode;
195
+ this._prefix = '';
196
+ this._suffix = '';
197
+ this._compiledVM = null;
198
+ this._compiledNodeVM = null;
199
+ this._compiledCode = null;
200
+ },
201
+ enumerable: true
202
+ },
203
+ filename: {
204
+ __proto__: null,
205
+ value: useFileName || 'vm.js',
206
+ enumerable: true
207
+ },
208
+ lineOffset: {
209
+ __proto__: null,
210
+ value: lineOffset,
211
+ enumerable: true
212
+ },
213
+ columnOffset: {
214
+ __proto__: null,
215
+ value: columnOffset,
216
+ enumerable: true
217
+ },
218
+ compiler: {
219
+ __proto__: null,
220
+ value: compiler,
221
+ enumerable: true
222
+ },
223
+ compilerOptions: {
224
+ __proto__: null,
225
+ value: compilerOptions,
226
+ enumerable: true
227
+ },
228
+ _code: {
229
+ __proto__: null,
230
+ value: sCode,
231
+ writable: true
232
+ },
233
+ _prefix: {
234
+ __proto__: null,
235
+ value: '',
236
+ writable: true
237
+ },
238
+ _suffix: {
239
+ __proto__: null,
240
+ value: '',
241
+ writable: true
242
+ },
243
+ _compiledVM: {
244
+ __proto__: null,
245
+ value: null,
246
+ writable: true
247
+ },
248
+ _compiledNodeVM: {
249
+ __proto__: null,
250
+ value: null,
251
+ writable: true
252
+ },
253
+ _compiledNodeVMStrict: {
254
+ __proto__: null,
255
+ value: null,
256
+ writable: true
257
+ },
258
+ _compiledCode: {
259
+ __proto__: null,
260
+ value: null,
261
+ writable: true
262
+ },
263
+ _hasAsync: {
264
+ __proto__: null,
265
+ value: false,
266
+ writable: true
267
+ },
268
+ _compiler: {__proto__: null, value: resolvedCompiler}
269
+ });
270
+ }
271
+
272
+ /**
273
+ * Wraps the code.<br>
274
+ * This will replace the old wrapping.<br>
275
+ * Will invalidate the code cache.
276
+ *
277
+ * @public
278
+ * @deprecated Since v3.9.0. Wrap your code before passing it into the VMScript object.
279
+ * @param {string} prefix - String that will be appended before the script code.
280
+ * @param {script} suffix - String that will be appended behind the script code.
281
+ * @return {this} This for chaining.
282
+ * @throws {TypeError} If prefix or suffix is a Symbol.
283
+ */
284
+ wrap(prefix, suffix) {
285
+ const strPrefix = `${prefix}`;
286
+ const strSuffix = `${suffix}`;
287
+ if (this._prefix === strPrefix && this._suffix === strSuffix) return this;
288
+ this._prefix = strPrefix;
289
+ this._suffix = strSuffix;
290
+ this._compiledVM = null;
291
+ this._compiledNodeVM = null;
292
+ this._compiledNodeVMStrict = null;
293
+ return this;
294
+ }
295
+
296
+ /**
297
+ * Compile this script. <br>
298
+ * This is useful to detect syntax errors in the script.
299
+ *
300
+ * @public
301
+ * @return {this} This for chaining.
302
+ * @throws {SyntaxError} If there is a syntax error in the script.
303
+ */
304
+ compile() {
305
+ this._compileVM();
306
+ return this;
307
+ }
308
+
309
+ /**
310
+ * Get the compiled code.
311
+ *
312
+ * @private
313
+ * @return {string} The code.
314
+ */
315
+ getCompiledCode() {
316
+ if (!this._compiledCode) {
317
+ const comp = this._compiler(this._prefix + removeShebang(this._code) + this._suffix, this.filename);
318
+ const res = transformer(null, comp, false, false, this.filename);
319
+ this._compiledCode = res.code;
320
+ this._hasAsync = res.hasAsync;
321
+ }
322
+ return this._compiledCode;
323
+ }
324
+
325
+ /**
326
+ * Compiles this script to a vm.Script.
327
+ *
328
+ * @private
329
+ * @param {string} prefix - JavaScript code that will be used as prefix.
330
+ * @param {string} suffix - JavaScript code that will be used as suffix.
331
+ * @return {vm.Script} The compiled vm.Script.
332
+ * @throws {SyntaxError} If there is a syntax error in the script.
333
+ */
334
+ _compile(prefix, suffix) {
335
+ return new Script(prefix + this.getCompiledCode() + suffix, {
336
+ __proto__: null,
337
+ filename: this.filename,
338
+ displayErrors: false,
339
+ lineOffset: this.lineOffset,
340
+ columnOffset: this.columnOffset
341
+ });
342
+ }
343
+
344
+ /**
345
+ * Will return the cached version of the script intended for VM or compile it.
346
+ *
347
+ * @private
348
+ * @return {vm.Script} The compiled script
349
+ * @throws {SyntaxError} If there is a syntax error in the script.
350
+ */
351
+ _compileVM() {
352
+ let script = this._compiledVM;
353
+ if (!script) {
354
+ this._compiledVM = script = this._compile('', '');
355
+ }
356
+ return script;
357
+ }
358
+
359
+ /**
360
+ * Will return the cached version of the script intended for NodeVM or compile it.
361
+ *
362
+ * @private
363
+ * @return {vm.Script} The compiled script
364
+ * @throws {SyntaxError} If there is a syntax error in the script.
365
+ */
366
+ _compileNodeVM() {
367
+ let script = this._compiledNodeVM;
368
+ if (!script) {
369
+ this._compiledNodeVM = script = this._compile(MODULE_PREFIX, MODULE_SUFFIX);
370
+ }
371
+ return script;
372
+ }
373
+
374
+ /**
375
+ * Will return the cached version of the script intended for NodeVM in strict mode or compile it.
376
+ *
377
+ * @private
378
+ * @return {vm.Script} The compiled script
379
+ * @throws {SyntaxError} If there is a syntax error in the script.
380
+ */
381
+ _compileNodeVMStrict() {
382
+ let script = this._compiledNodeVMStrict;
383
+ if (!script) {
384
+ this._compiledNodeVMStrict = script = this._compile(STRICT_MODULE_PREFIX, MODULE_SUFFIX);
385
+ }
386
+ return script;
387
+ }
388
+
389
+ }
390
+
391
+ exports.MODULE_PREFIX = MODULE_PREFIX;
392
+ exports.STRICT_MODULE_PREFIX = STRICT_MODULE_PREFIX;
393
+ exports.MODULE_SUFFIX = MODULE_SUFFIX;
394
+ exports.VMScript = VMScript;