UNPKG

json-processing

Version:

JSON Processing Tool

139 lines (138 loc) 4.98 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ScriptRunner = void 0; const vm2_1 = require("vm2"); const filter_1 = __importDefault(require("./lib/filter")); const lodash_1 = require("lodash"); const require_dir_1 = __importDefault(require("require-dir")); const fs_1 = require("fs"); const path_1 = require("path"); const lodash_2 = require("lodash"); const core_1 = require("@babel/core"); const plugin_proposal_pipeline_operator_1 = __importDefault(require("@babel/plugin-proposal-pipeline-operator")); class ScriptRunner { constructor(input) { this._input = input; this._global = {}; } _createSandbox() { let sandbox = lodash_1.merge({ requireDir: require_dir_1.default, __transpileCode: this._transpileCode, run: (command, input) => this._run(command, input), from: (path) => fs_1.createReadStream(path_1.resolve(process.cwd(), path)), select: (pathOrInput, input) => { let path; if (!input && !lodash_2.isString(pathOrInput)) { input = pathOrInput; path = '$'; } else if (typeof pathOrInput == 'string') { path = pathOrInput; } else { throw new Error("Invalid Parameters on select()"); } path = path[0] != '$' ? `$${path}` : path; return filter_1.default(input || this._input, path); } }, this._global); return sandbox; } _createVM() { return new vm2_1.NodeVM({ sandbox: this._createSandbox(), require: { external: true, context: 'sandbox', builtin: ['*'] }, compiler: this._transpileCode }); } _runScript(script, path) { const vm = this._createVM(); return vm.run(`'use strict';${script}`, path); } _transpileCode(code, filename) { const transpiled = core_1.transformSync(code, { plugins: [[ plugin_proposal_pipeline_operator_1.default, { proposal: 'minimal' } ]] }); if (!transpiled || !transpiled.code) { throw new Error('script transpilation failed'); } return transpiled.code; } addGlobal(object) { this._global = lodash_1.merge({}, this._global, object || {}); return this; } addGlobalFromPath(path) { return this.addGlobal(this._loadPath(path)); } setInlineScript(inline) { this._inlineScript = inline; return this; } setCommand(command) { this._command = command; return this; } setCommandArgs(args) { this._commandArgs = args; return this; } setCommandsPath(path) { this._commandsPath = path; return this; } setPluginsInfo(pluginsInfo) { return this.addGlobal(this._loadPlugins(pluginsInfo)); } run() { if (!lodash_2.isEmpty(this._command)) { const commandFile = resolveCommand(this._commandsPath, this._command); return this._runScript(` const command = require('${commandFile}'); module.exports = (argv) => command(argv)${this._inlineScript ? this._inlineScript : ''};`, commandFile)(this._commandArgs || {}); } const inlineScript = lodash_2.isEmpty(this._inlineScript) ? 'select()' : this._inlineScript; return this._runScript(`module.exports = () => ${inlineScript};`)(); } _loadPlugins(pluginsInfo) { const homeDir = path_1.dirname(pluginsInfo); return this._runScript(` module.exports = () => { const pluginsInfo = require("${pluginsInfo}"); const result = {}; Object.keys(pluginsInfo).forEach(name => { result["$" + name] = require(pluginsInfo[name])("${homeDir}"); }); return result; } `, pluginsInfo)(); } _loadPath(path) { return this._runScript(` module.exports = () => requireDir('${path}', { recurse: true })`, `${path}/index.js`)(); } _run(command, input) { const runner = new ScriptRunner(input); runner._global = this._global; runner._command = command; runner._commandsPath = this._commandsPath; return runner.run(); } } exports.ScriptRunner = ScriptRunner; function resolveCommand(commandsPath, command) { if (/^.+\.js$/.test(command)) return path_1.resolve(process.cwd(), command); return path_1.resolve(commandsPath, `${command}.js`); }