Skip to content

Commit

Permalink
feat(core): compiler and context arguments for plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
Igmat committed Jan 29, 2018
1 parent 0dec754 commit b2e4a67
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/baset-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@
"typescript": "^2.6.2"
},
"dependencies": {
"json-beautify": "^1.0.1"
"vm2": "^3.5.2"
}
}
46 changes: 43 additions & 3 deletions packages/baset-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,54 @@
import * as fs from 'fs';
import * as path from 'path';
import { isPrimitive, promisify } from 'util';
import { NodeVM } from 'vm2';

const writeFile = promisify(fs.writeFile);
const readFile = promisify(fs.readFile);
const isExists = promisify(fs.exists);
const unlink = promisify(fs.unlink);

function defaultJsCompiler(code: string, filename: string) {
return code;
}

export interface IPluginConstructor {
// tslint:disable-next-line:no-any
new(compilers: { [index: string]: (code: string, filename: string) => string }, context: NodeVM, pluginsOptions: any): IPlugin;
}
export interface IPlugin {
read(filePath: string, result: string | Promise<string>): Promise<string> | string;
}

export interface IDictionary<T> {
[index: string]: T;
}

export class Tester {
private readers: {
pattern: RegExp;
read(filePath: string): Promise<string>;
read(filePath: string): Promise<string> | string;
}[];
private compilers: {
[index: string]: (code: string, filename: string) => string;
} = {
'.js': defaultJsCompiler,
'.json': defaultJsCompiler,
'.node': defaultJsCompiler,
};
private context: NodeVM;

// tslint:disable-next-line:no-any
constructor(readers: IDictionary<string[]>, pluginsOptions: IDictionary<any>) {
this.readers = this.initPlugins(readers, pluginsOptions);
this.context = new NodeVM({
require: {
builtin: ['*'],
external: true,
context: 'sandbox',
},
compiler: this.compile,
});
}

test(specs: string[], baselines: string[]) {
Expand Down Expand Up @@ -60,11 +89,22 @@ export class Tester {
// tslint:disable-next-line:no-any
private initPlugins = (plugins: IDictionary<string[]>, pluginsOptions: IDictionary<any>) =>
Object.keys(plugins).map(key => {
const chain = plugins[key].map(plugin => new (require(path.resolve(plugin)).default)(pluginsOptions[plugin]));
const chain = plugins[key].map(plugin => {
const Plugin: IPluginConstructor = require(path.resolve(plugin)).default;

return new Plugin(this.compilers, this.context, pluginsOptions[plugin]);
});

return {
pattern: new RegExp(key),
read: (filePath: string) => chain.reduce((result, plugin) => plugin.read(filePath, result), ''),
read: (filePath: string) => chain.reduce<string | Promise<string>>((result, plugin) => plugin.read(filePath, result), ''),
};
})

private compile = (code: string, filePath: string) => {
const compiler = this.compilers[path.extname(filePath)];
if (!compiler) throw new Error(`There is no compiler for "${path.extname(filePath)}" filetype`);

return compiler(code, filePath);
}
}

0 comments on commit b2e4a67

Please sign in to comment.