diff --git a/lib/vm.js b/lib/vm.js index 4a2fcba..5795a97 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -26,9 +26,17 @@ const COMMON_CONTEXT = vm.createContext( }) ); +const contextifiedRequire = (context) => (module) => { + if (Reflect.has(context, module)) return Reflect.get(context, module); + return undefined; +}; + const createContext = (context, preventEscape = false) => { if (!context) return EMPTY_CONTEXT; - return vm.createContext(context, preventEscape ? CONTEXT_OPTIONS : {}); + return vm.createContext( + { ...context, require: contextifiedRequire(context) }, + preventEscape ? CONTEXT_OPTIONS : {} + ); }; class MetaScript { diff --git a/test/unit.js b/test/unit.js index 27e88d0..0ff9524 100644 --- a/test/unit.js +++ b/test/unit.js @@ -156,11 +156,22 @@ metatests.test('Create custom context', async (test) => { sandbox.global = sandbox; const context = metavm.createContext(sandbox); test.strictSame(context.field, 'value'); - test.strictSame(Object.keys(context), ['field', 'global']); + test.strictSame(Object.keys(context), ['field', 'global', 'require']); test.strictSame(context.global, sandbox); test.end(); }); +metatests.test('Require binded to custom context', async (test) => { + const sandbox = { field: 'value' }; + sandbox.global = sandbox; + const context = metavm.createContext(sandbox); + const src = `({ exist: require('field'), notExist: require('nothing') })`; + const ms = metavm.createScript('Example', src, { context }); + test.strictSame('value', ms.exports.exist); + test.strictSame(undefined, ms.exports.notExist); + test.end(); +}); + metatests.test('Call undefined as a function', async (test) => { const filePath = path.join(examples, 'undef.js'); const ms = await metavm.readScript(filePath);