diff --git a/lib/index.js b/lib/index.js index 0c6b358..b32f513 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,7 +1,7 @@ const path = require('path') const chalk = require('chalk') const mm = require('micromatch') -const requireFromString = require('require-from-string') +const runJavaScript = require('./runJavaScript') const logger = require('./logger') const readMaidFile = require('./readMaidFile') const MaidError = require('./MaidError') @@ -63,24 +63,26 @@ class Maid { throw new MaidError(`Task '${task.name}' failed.\n${err.stack}`) } if (checkTypes(task, ['sh', 'bash'])) { - return runCLICommand({ task, resolve, reject }) + runCLICommand({ task, resolve, reject }) + return } if (checkTypes(task, ['py', 'python'])) { - return runCLICommand({ type: 'python', task, resolve, reject }) + runCLICommand({ type: 'python', task, resolve, reject }) + return } if (checkTypes(task, ['js', 'javascript'])) { - let res - try { - res = requireFromString(task.script, this.maidfile.filepath) - } catch (err) { - return handleError(err) - } - res = res.default || res - return resolve( - typeof res === 'function' - ? Promise.resolve(res()).catch(handleError) - : res - ) + runJavaScript(task.script, this.maidfile.filepath) + .then(result => { + result = (result && result.default) || result + + // if code fence module.exports a function (even async one) + // we call it and passing it with `task` object - it may be useful + return typeof result === 'function' ? result(task) : result + }) + .then(resolve) + .catch(handleError) + + return } return resolve() diff --git a/lib/runJavaScript.js b/lib/runJavaScript.js new file mode 100644 index 0000000..edbdcf6 --- /dev/null +++ b/lib/runJavaScript.js @@ -0,0 +1,45 @@ +const vm = require('vm') + +/** + * Example + * + * ```js + * runJavaScript(`var bar = 123; if (bar) console.log(bar + 5)`) + * .then(() => { + * console.log('done') + * }) + * .catch(console.error) + * ``` + */ + +const runJavaScript = (content, filepath) => { + const run = vm.runInNewContext( + `(() => new Promise((____resolve) => { + ____resolve(${content}); +}))`, + { + global: global, + process: process, + require: require, + console: console, + exports: exports, + module: module + }, + filepath + ) + + return run() +} + +// Example +// +// runJavaScript( +// `module.exports = async () => process.env.NODE_ENV`, +// 'lib/loadFile.js' +// ) +// .then(fn => { +// console.log('done', fn()) +// }) +// .catch(console.error) + +module.exports = runJavaScript diff --git a/package.json b/package.json index db03732..0352092 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "joycon": "^1.0.4", "markdown-it": "^8.4.1", "micromatch": "^3.1.10", - "require-from-string": "^2.0.2", "rexrex": "^1.2.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index c61f5c4..3bce8bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3496,10 +3496,6 @@ replace-ext@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - require-precompiled@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa"