forked from patriksimek/vm2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.d.ts
311 lines (290 loc) · 11.4 KB
/
index.d.ts
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
import { EventEmitter } from 'events';
import fs from 'fs';
import pa from 'path';
/**
* Interface for nodes fs module
*/
export interface VMFS {
/** Implements fs.statSync */
statSync: typeof fs.statSync;
/** Implements fs.readFileSync */
readFileSync: typeof fs.readFileSync;
}
/**
* Interface for nodes path module
*/
export interface VMPath {
/** Implements path.resolve */
resolve: typeof pa.resolve;
/** Implements path.isAbsolute */
isAbsolute: typeof pa.isAbsolute;
/** Implements path.join */
join: typeof pa.join;
/** Implements path.basename */
basename: typeof pa.basename;
/** Implements path.dirname */
dirname: typeof pa.dirname;
}
/**
* Custom file system which abstracts functions from node's fs and path modules.
*/
export interface VMFileSystemInterface extends VMFS, VMPath {
/** Implements (sep) => sep === path.sep */
isSeparator(char: string): boolean;
}
/**
* Implementation of a default file system.
*/
export class VMFileSystem implements VMFileSystemInterface {
constructor(options?: { fs?: VMFS, path?: VMPath });
/** Implements fs.statSync */
statSync: typeof fs.statSync;
/** Implements fs.readFileSync */
readFileSync: typeof fs.readFileSync;
/** Implements path.resolve */
resolve: typeof pa.resolve;
/** Implements path.isAbsolute */
isAbsolute: typeof pa.isAbsolute;
/** Implements path.join */
join: typeof pa.join;
/** Implements path.basename */
basename: typeof pa.basename;
/** Implements path.dirname */
dirname: typeof pa.dirname;
/** Implements (sep) => sep === path.sep */
isSeparator(char: string): boolean;
}
/**
* Function that will be called to load a built-in into a vm.
*/
export type BuiltinLoad = (vm: NodeVM) => any;
/**
* Either a function that will be called to load a built-in into a vm or an object with a init method and a load method to load the built-in.
*/
export type Builtin = BuiltinLoad | {init: (vm: NodeVM)=>void, load: BuiltinLoad};
/**
* Require method
*/
export type HostRequire = (id: string) => any;
/**
* This callback will be called to specify the context to use "per" module. Defaults to 'sandbox' if no return value provided.
*/
export type PathContextCallback = (modulePath: string, extensionType: string) => 'host' | 'sandbox';
/**
* Require options for a VM
*/
export interface VMRequire {
/**
* Array of allowed built-in modules, accepts ["*"] for all. Using "*" increases the attack surface and potential
* new modules allow to escape the sandbox. (default: none)
*/
builtin?: readonly string[];
/*
* `host` (default) to require modules in host and proxy them to sandbox. `sandbox` to load, compile and
* require modules in sandbox or a callback which chooses the context based on the filename.
* Built-in modules except `events` always required in host and proxied to sandbox
*/
context?: "host" | "sandbox" | PathContextCallback;
/** `true`, an array of allowed external modules or an object with external options (default: `false`) */
external?: boolean | readonly string[] | { modules: readonly string[], transitive: boolean };
/** Array of modules to be loaded into NodeVM on start. */
import?: readonly string[];
/** Restricted path(s) where local modules can be required (default: every path). */
root?: string | readonly string[];
/** Collection of mock modules (both external or built-in). */
mock?: any;
/* An additional lookup function in case a module wasn't found in one of the traditional node lookup paths. */
resolve?: (moduleName: string, parentDirname: string) => string | { path: string, module?: string } | undefined;
/** Custom require to require host and built-in modules. */
customRequire?: HostRequire;
/** Load modules in strict mode. (default: true) */
strict?: boolean;
/** FileSystem to load files from */
fs?: VMFileSystemInterface;
}
/**
* A custom compiler function for all of the JS that comes
* into the VM
*/
export type CompilerFunction = (code: string, filename: string) => string;
export abstract class Resolver {
private constructor(fs: VMFileSystemInterface, globalPaths: readonly string[], builtins: Map<string, Builtin>);
}
/**
* Create a resolver as normal `NodeVM` does given `VMRequire` options.
*
* @param options The options that would have been given to `NodeVM`.
* @param override Custom overrides for built-ins.
* @param compiler Compiler to be used for loaded modules.
*/
export function makeResolverFromLegacyOptions(options: VMRequire, override?: {[key: string]: Builtin}, compiler?: CompilerFunction): Resolver;
/**
* Options for creating a VM
*/
export interface VMOptions {
/**
* `javascript` (default) or `coffeescript` or custom compiler function (which receives the code, and it's file path).
* The library expects you to have coffee-script pre-installed if the compiler is set to `coffeescript`.
*/
compiler?: "javascript" | "coffeescript" | CompilerFunction;
/** VM's global object. */
sandbox?: any;
/**
* Script timeout in milliseconds. Timeout is only effective on code you run through `run`.
* Timeout is NOT effective on any method returned by VM.
*/
timeout?: number;
/**
* If set to `false` any calls to eval or function constructors (`Function`, `GeneratorFunction`, etc.) will throw an
* `EvalError` (default: `true`).
*/
eval?: boolean;
/**
* If set to `false` any attempt to compile a WebAssembly module will throw a `WebAssembly.CompileError` (default: `true`).
*/
wasm?: boolean;
/**
* If set to `true` any attempt to run code using async will throw a `VMError` (default: `false`).
* @deprecated Use `allowAsync` instead.
*/
fixAsync?: boolean;
/**
* If set to `false` any attempt to run code using async will throw a `VMError` (default: `true`).
*/
allowAsync?: boolean;
}
/**
* Options for creating a NodeVM
*/
export interface NodeVMOptions extends VMOptions {
/** `inherit` to enable console, `redirect` to redirect to events, `off` to disable console (default: `inherit`). */
console?: "inherit" | "redirect" | "off";
/** `true` or an object to enable `require` options (default: `false`). */
require?: boolean | VMRequire | Resolver;
/**
* **WARNING**: This should be disabled. It allows to create a NodeVM form within the sandbox which could return any host module.
* `true` to enable VMs nesting (default: `false`).
*/
nesting?: boolean;
/** `commonjs` (default) to wrap script into CommonJS wrapper, `none` to retrieve value returned by the script. */
wrapper?: "commonjs" | "none";
/** File extensions that the internal module resolver should accept. */
sourceExtensions?: readonly string[];
/**
* Array of arguments passed to `process.argv`.
* This object will not be copied and the script can change this object.
*/
argv?: string[];
/**
* Environment map passed to `process.env`.
* This object will not be copied and the script can change this object.
*/
env?: any;
/** Run modules in strict mode. Required modules are always strict. */
strict?: boolean;
}
/**
* VM is a simple sandbox, without `require` feature, to synchronously run an untrusted code.
* Only JavaScript built-in objects + Buffer are available. Scheduling functions
* (`setInterval`, `setTimeout` and `setImmediate`) are not available by default.
*/
export class VM {
constructor(options?: VMOptions);
/** Direct access to the global sandbox object */
readonly sandbox: any;
/** Timeout to use for the run methods */
timeout?: number;
/** Runs the code */
run(script: string | VMScript, options?: string | { filename?: string }): any;
/** Runs the code in the specific file */
runFile(filename: string): any;
/** Loads all the values into the global object with the same names */
setGlobals(values: any): this;
/** Make a object visible as a global with a specific name */
setGlobal(name: string, value: any): this;
/** Get the global object with the specific name */
getGlobal(name: string): any;
/** Freezes the object inside VM making it read-only. Not available for primitive values. */
freeze(object: any, name?: string): any;
/** Freezes the object inside VM making it read-only. Not available for primitive values. */
readonly(object: any): any;
/** Protects the object inside VM making impossible to set functions as it's properties. Not available for primitive values */
protect(object: any, name?: string): any;
}
/**
* A VM with behavior more similar to running inside Node.
*/
export class NodeVM extends EventEmitter implements VM {
constructor(options?: NodeVMOptions);
/** Require a module in VM and return it's exports. */
require(module: string): any;
/**
* Create NodeVM and run code inside it.
*
* @param {string} script JavaScript code.
* @param {string} [filename] File name (used in stack traces only).
* @param {Object} [options] VM options.
*/
static code(script: string, filename?: string, options?: NodeVMOptions): any;
/**
* Create NodeVM and run script from file inside it.
*
* @param {string} [filename] File name (used in stack traces only).
* @param {Object} [options] VM options.
*/
static file(filename: string, options?: NodeVMOptions): any;
/** Direct access to the global sandbox object */
readonly sandbox: any;
/** Only here because of implements VM. Does nothing. */
timeout?: number;
/** The resolver used to resolve modules */
readonly resolver: Resolver;
/** Runs the code */
run(js: string | VMScript, options?: string | { filename?: string, wrapper?: "commonjs" | "none", strict?: boolean }): any;
/** Runs the code in the specific file */
runFile(filename: string): any;
/** Loads all the values into the global object with the same names */
setGlobals(values: any): this;
/** Make a object visible as a global with a specific name */
setGlobal(name: string, value: any): this;
/** Get the global object with the specific name */
getGlobal(name: string): any;
/** Freezes the object inside VM making it read-only. Not available for primitive values. */
freeze(object: any, name?: string): any;
/** Freezes the object inside VM making it read-only. Not available for primitive values. */
readonly(object: any): any;
/** Protects the object inside VM making impossible to set functions as it's properties. Not available for primitive values */
protect(object: any, name?: string): any;
}
/**
* You can increase performance by using pre-compiled scripts.
* The pre-compiled VMScript can be run later multiple times. It is important to note that the code is not bound
* to any VM (context); rather, it is bound before each run, just for that run.
*/
export class VMScript {
constructor(code: string, path: string, options?: {
lineOffset?: number;
columnOffset?: number;
compiler?: "javascript" | "coffeescript" | CompilerFunction;
});
constructor(code: string, options?: {
filename?: string,
lineOffset?: number;
columnOffset?: number;
compiler?: "javascript" | "coffeescript" | CompilerFunction;
});
readonly code: string;
readonly filename: string;
readonly lineOffset: number;
readonly columnOffset: number;
readonly compiler: "javascript" | "coffeescript" | CompilerFunction;
/**
* Wraps the code
* @deprecated
*/
wrap(prefix: string, postfix: string): this;
/** Compiles the code. If called multiple times, the code is only compiled once. */
compile(): this;
}
/** Custom Error class */
export class VMError extends Error { }