Skip to content

Commit

Permalink
Merge pull request patriksimek#92 from patriksimek/custom_files
Browse files Browse the repository at this point in the history
Add support for custom source file extensions
  • Loading branch information
orta authored May 8, 2018
2 parents fa39b68 + 468bc1e commit 8a1dcad
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 10 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ Unlike `VM`, `NodeVM` lets you require modules same way like in regular Node's c
* `console` - `inherit` to enable console, `redirect` to redirect to events, `off` to disable console (default: `inherit`).
* `sandbox` - VM's global object.
* `compiler` - `javascript` (default) or `coffeescript` or custom compiler function (which receives the code, and it's filepath). The library expects you to have coffee-script pre-installed if the compiler is set to `coffeescript`.
* `sourceExtensions` - Array of file extensions to treat as source code (default: `['js']`).
* `require` - `true` or object to enable `require` method (default: `false`).
* `require.external` - `true` or an array of allowed external modules (default: `false`).
* `require.builtin` - Array of allowed builtin modules, accepts ["*"] for all (default: none).
Expand Down
3 changes: 3 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ export interface VMOptions {
* Timeout is NOT effective on any method returned by VM.
*/
timeout?: number;

/** File extensions that the internal module resolver should accept. */
sourceExtensions?: string[]
}

/**
Expand Down
3 changes: 2 additions & 1 deletion lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ class NodeVM extends EventEmitter {
compiler: options.compiler || 'javascript',
require: options.require || false,
nesting: options.nesting || false,
wrapper: options.wrapper || 'commonjs'
wrapper: options.wrapper || 'commonjs',
sourceExtensions: options.sourceExtensions || ['js']
};

const host = {
Expand Down
25 changes: 18 additions & 7 deletions lib/sandbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,14 @@ return ((vm, host) => {
} catch (e) {
throw Contextify.value(e);
}
},
[".js"](module, filename, dirname) {
}
};


for (var i = 0; i < vm.options.sourceExtensions.length; i++) {
var ext = vm.options.sourceExtensions[i];

EXTENSIONS["." + ext] = (module, filename, dirname) => {
if (vm.options.require.context !== 'sandbox') {
try {
module.exports = Contextify.readonly(host.require(filename));
Expand Down Expand Up @@ -72,7 +78,7 @@ return ((vm, host) => {
closure(module.exports, module.require, module, filename, dirname);
}
}
};
}

/**
* Resolve filename.
Expand All @@ -88,8 +94,10 @@ return ((vm, host) => {
if (exists && !isdir) return path;

// load as file

if (fs.existsSync(`${path}.js`)) return `${path}.js`;
for (var i = 0; i < vm.options.sourceExtensions.length; i++) {
var ext = vm.options.sourceExtensions[i];
if (fs.existsSync(`${path}.${ext}`)) return `${path}.${ext}`;
}
if (fs.existsSync(`${path}.node`)) return `${path}.node`;
if (fs.existsSync(`${path}.json`)) return `${path}.json`;

Expand All @@ -106,7 +114,11 @@ return ((vm, host) => {
return _resolveFilename(`${path}/${pkg.main}`);
}

if (fs.existsSync(`${path}/index.js`)) return `${path}/index.js`;
for (var i = 0; i < vm.options.sourceExtensions.length; i++) {
var ext = vm.options.sourceExtensions[i];
if (fs.existsSync(`${path}/index.${ext}`)) return `${path}/index.${ext}`;
}

if (fs.existsSync(`${path}/index.node`)) return `${path}/index.node`;

return null;
Expand Down Expand Up @@ -253,7 +265,6 @@ return ((vm, host) => {
};

// lookup extensions

if (EXTENSIONS[extname]) {
EXTENSIONS[extname](module, filename, dirname);
return module.exports;
Expand Down
1 change: 1 addition & 0 deletions test/data/custom_extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1 + 1;
28 changes: 26 additions & 2 deletions test/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ describe('modules', () => {
let vm = new NodeVM({
require: {
external: true
}
},
})

vm.run("require('foobar')", __filename);
Expand All @@ -576,7 +576,7 @@ describe('modules', () => {
let vm = new NodeVM({
require: {
external: false
}
},
})

assert.throws(() => vm.run("require('mocha')", __filename), err => {
Expand Down Expand Up @@ -826,3 +826,27 @@ describe('freeze, protect', () => {
assert.strictEqual(vm.run('(i) => /x/.test(i.date)')(obj), false);
})
})

describe('source extensions', () => {
it('does not find a TS module with the default settings', () => {
let vm = new NodeVM({
require: {
external: true
}
})
assert.throws(() => {
vm.run("require('./data/custom_extension')", __filename);
})
})

it('finds a TS module with source extensions set', () => {
let vm = new NodeVM({
require: {
external: true
},
sourceExtensions: ["ts", "js"]
})

vm.run("require('./data/custom_extension')", __filename);
})
})

0 comments on commit 8a1dcad

Please sign in to comment.