Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ CommonJS format
```js
const metavm = require('metavm');

const ms = await metavm.readScript('./examples/cjssimple.js', {
const ms = await metavm.readScript('./examples/cjs/simple.js', {
type: metavm.MODULE_TYPE.COMMONJS,
});
console.log(ms.exports);
// { field: 'value', add: [Function: add], sub:[Function: sub] }
// { field: 'value', add: [Function: add], sub: [Function: sub] }
```

## License & Contributors
Expand Down
2 changes: 2 additions & 0 deletions metavm.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Context, Script, ScriptOptions } from 'node:vm';

export const EMPTY_CONTEXT: Context;
export const EMPTY_CJS: Context;
export const COMMON_CONTEXT: Context;
export const NODE_CONTEXT: Context;

Expand All @@ -12,6 +13,7 @@ export function createContext(
): Context;

export enum MODULE_TYPE {
AUTO = 0,
METARHIA = 1,
COMMONJS = 2,
ECMA = 3,
Expand Down
24 changes: 17 additions & 7 deletions metavm.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const CONTEXT_OPTIONS = {
};

const MODULE_TYPE = {
AUTO: 0,
METARHIA: 1,
COMMONJS: 2,
ECMA: 3,
Expand Down Expand Up @@ -63,6 +64,8 @@ const NODE = { global, console, process };
const EMPTY_CONTEXT = vm.createContext(Object.freeze({}), CONTEXT_OPTIONS);
const COMMON_CONTEXT = vm.createContext(Object.freeze({ ...DEFAULT }));
const NODE_CONTEXT = vm.createContext(Object.freeze({ ...DEFAULT, ...NODE }));
const CONTEXT_CJS = Object.freeze({ module: {} });
const EMPTY_CJS = vm.createContext(CONTEXT_CJS, CONTEXT_OPTIONS);

class MetavmError extends Error {}

Expand All @@ -72,12 +75,10 @@ const createContext = (context, preventEscape = false) => {
return vm.createContext(context, { ...CONTEXT_OPTIONS, ...options });
};

const SRC_BEFORE = '((exports, require, module, __filename, __dirname) => { ';
const SRC_AFTER = '\n});';
const wrapSource = (src) => SRC_BEFORE + src + SRC_AFTER;
const wrapSource = (source) =>
`((exports, require, module, __filename, __dirname) => { ${source}\n});`;

const USE_STRICT = `'use strict';\n`;
const useStrict = (src) => (src.startsWith(USE_STRICT) ? '' : USE_STRICT);

const addExt = (name) => {
if (name.toLocaleLowerCase().endsWith('.js')) return name;
Expand All @@ -94,15 +95,23 @@ class MetaScript {
this.name = name;
this.dirname = options.dirname || process.cwd();
this.relative = options.relative || '.';
this.type = options.type || MODULE_TYPE.METARHIA;
this.type = options.type || MODULE_TYPE.AUTO;
this.access = options.access || {};
if (this.type === MODULE_TYPE.AUTO) {
if (src.includes('module.exports')) this.type = MODULE_TYPE.COMMONJS;
else this.type = MODULE_TYPE.METARHIA;
}
const common = this.type === MODULE_TYPE.COMMONJS;
const strict = useStrict(src);
const strict = src.startsWith(USE_STRICT) ? '' : USE_STRICT;
const code = common ? wrapSource(src) : `{\n${src}\n}`;
const lineOffset = strict === '' ? -1 : -2;
const scriptOptions = { filename: name, ...options, lineOffset };
this.script = new vm.Script(strict + code, scriptOptions);
this.context = options.context || createContext();

if (options.context) this.context = options.context;
else if (this.type === MODULE_TYPE.COMMONJS) this.context = EMPTY_CJS;
else this.context = EMPTY_CONTEXT;

const runOptions = { ...RUN_OPTIONS, ...options };
const exports = this.script.runInContext(this.context, runOptions);
this.exports = common ? this.commonExports(exports) : exports;
Expand Down Expand Up @@ -183,6 +192,7 @@ module.exports = {
MetavmError,
createScript,
EMPTY_CONTEXT,
EMPTY_CJS,
COMMON_CONTEXT,
NODE_CONTEXT,
MODULE_TYPE,
Expand Down
3 changes: 2 additions & 1 deletion test/metarhia.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ test('Metarhia line number and position in reference error', async () => {
test('Metarhia line number and position with use strict', async () => {
const filePath = path.join(examples, 'useStrict.js');
try {
const script = await metavm.readScript(filePath);
const options = { type: metavm.MODULE_TYPE.METARHIA };
const script = await metavm.readScript(filePath, options);
await script.exports();
assert.fail();
} catch (error) {
Expand Down