diff --git a/package-lock.json b/package-lock.json index c67eff7..d52f85d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,32 +1,32 @@ { "name": "shargs-repl", - "version": "0.3.0", + "version": "0.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.3.tgz", + "integrity": "sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg==", "dev": true, "requires": { - "@babel/highlight": "^7.10.1" + "@babel/highlight": "^7.10.3" } }, "@babel/core": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", - "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.3.tgz", + "integrity": "sha512-5YqWxYE3pyhIi84L84YcwjeEgS+fa7ZjK6IBVGTjDVfm64njkR2lfDhVR5OudLk8x2GK59YoSyVv+L/03k1q9w==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.2", + "@babel/code-frame": "^7.10.3", + "@babel/generator": "^7.10.3", "@babel/helper-module-transforms": "^7.10.1", "@babel/helpers": "^7.10.1", - "@babel/parser": "^7.10.2", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.2", + "@babel/parser": "^7.10.3", + "@babel/template": "^7.10.3", + "@babel/traverse": "^7.10.3", + "@babel/types": "^7.10.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -52,12 +52,12 @@ } }, "@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.3.tgz", + "integrity": "sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA==", "dev": true, "requires": { - "@babel/types": "^7.10.2", + "@babel/types": "^7.10.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -72,41 +72,41 @@ } }, "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz", + "integrity": "sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/helper-get-function-arity": "^7.10.3", + "@babel/template": "^7.10.3", + "@babel/types": "^7.10.3" } }, "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz", + "integrity": "sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.3" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", - "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.3.tgz", + "integrity": "sha512-q7+37c4EPLSjNb2NmWOjNwj0+BOyYlssuQ58kHEWk1Z78K5i8vTUsteq78HMieRPQSl/NtpQyJfdjt3qZ5V2vw==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.3" } }, "@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz", + "integrity": "sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.3" } }, "@babel/helper-module-transforms": { @@ -125,18 +125,18 @@ } }, "@babel/helper-optimise-call-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", - "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.3.tgz", + "integrity": "sha512-kT2R3VBH/cnSz+yChKpaKRJQJWxdGoc6SjioRId2wkeV3bK0wLLioFpJROrX0U4xr/NmxSSAWT/9Ih5snwIIzg==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.3" } }, "@babel/helper-plugin-utils": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", - "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.3.tgz", + "integrity": "sha512-j/+j8NAWUTxOtx4LKHybpSClxHoq6I91DQ/mKgAXn5oNUPIUiGppjPIX3TDtJWPrdfP9Kfl7e4fgVMiQR9VE/g==", "dev": true }, "@babel/helper-replace-supers": { @@ -171,9 +171,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz", + "integrity": "sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw==", "dev": true }, "@babel/helpers": { @@ -188,12 +188,12 @@ } }, "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.3.tgz", + "integrity": "sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.1", + "@babel/helper-validator-identifier": "^7.10.3", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -251,9 +251,9 @@ } }, "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.3.tgz", + "integrity": "sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -356,40 +356,40 @@ } }, "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.3.tgz", + "integrity": "sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/code-frame": "^7.10.3", + "@babel/parser": "^7.10.3", + "@babel/types": "^7.10.3" } }, "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.3.tgz", + "integrity": "sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", + "@babel/code-frame": "^7.10.3", + "@babel/generator": "^7.10.3", + "@babel/helper-function-name": "^7.10.3", "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", + "@babel/parser": "^7.10.3", + "@babel/types": "^7.10.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "version": "7.10.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.3.tgz", + "integrity": "sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.1", + "@babel/helper-validator-identifier": "^7.10.3", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -628,9 +628,9 @@ } }, "@types/babel__core": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz", - "integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==", + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -1522,9 +1522,9 @@ "dev": true }, "escodegen": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.2.tgz", - "integrity": "sha512-InuOIiKk8wwuOFg6x9BQXbzjrQhtyXh46K9bqVTPzSo2FnyMBaYGBMC6PhQy7yxxil9vIedFBweQBMK74/7o8A==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, "requires": { "esprima": "^4.0.1", diff --git a/package.json b/package.json index 85248aa..ff4ffdc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "shargs-repl", - "version": "0.3.0", + "version": "0.4.0", "description": "A REPL using shargs commands", "keywords": [ "shargs", diff --git a/src/index.js b/src/index.js index 2585a88..40b7f3b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,7 @@ -const {repl} = require('./repl') +const {repl, replF, replSync} = require('./repl') module.exports = { - repl + repl, + replF, + replSync } \ No newline at end of file diff --git a/src/repl/Async.js b/src/repl/Async.js new file mode 100644 index 0000000..6e28b9c --- /dev/null +++ b/src/repl/Async.js @@ -0,0 +1,31 @@ +const Async = { + resolve, + reject, + all, + then, + catch: _catch +} + +module.exports = { + Async +} + +function resolve (value) { + return Promise.resolve(value) +} + +function reject (reason) { + return Promise.reject(reason) +} + +function all (promises) { + return Promise.all(promises) +} + +function then (onFulfilled, onRejected) { + return promise => promise.then(onFulfilled, onRejected) +} + +function _catch (onRejected) { + return promise => promise.catch(onRejected) +} \ No newline at end of file diff --git a/src/repl/Sync.js b/src/repl/Sync.js new file mode 100644 index 0000000..4ac7c29 --- /dev/null +++ b/src/repl/Sync.js @@ -0,0 +1,80 @@ +const Sync = { + resolve, + reject, + all, + then, + catch: _catch +} + +module.exports = { + Sync +} + +function resolve (value) { + if (typeof value === 'object' && typeof value.err === 'object' && typeof value.val !== 'undefined') { + return value + } else { + return {err: null, val: value} + } +} + +function reject (reason) { + if (typeof reason === 'object' && typeof reason.err === 'object' && typeof reason.val !== 'undefined') { + return {...reason, err: reason} + } else { + return {err: reason, val: null} + } +} + +function all (array) { + try { + let err = null + const val = [] + + for (let i = 0; i < array.length; i++) { + const elem = array[i] + + if (typeof elem === 'object') { + if (elem.err === null) { + if (typeof elem.val === 'undefined') { + val.push(elem) + } else { + val.push(elem.val) + } + } else { + err = elem.err + val.push(null) + } + } else { + val.push(elem) + } + } + + return {err, val} + } catch (err) { + return {err, val: null} + } +} + +function then (onFulfilled, onRejected) { + return ({err, val}) => { + try { + return { + err: typeof onRejected === 'function' ? onRejected(err) : err, + val: typeof onFulfilled === 'function' ? onFulfilled(val) : val + } + } catch (err) { + return {err, val: null} + } + } +} + +function _catch (onRejected) { + return ({err, val}) => { + try { + return {err: onRejected(err), val} + } catch (err) { + return {err, val: null} + } + } +} \ No newline at end of file diff --git a/src/repl/index.js b/src/repl/index.js index 56bf914..aae0520 100644 --- a/src/repl/index.js +++ b/src/repl/index.js @@ -1,18 +1,22 @@ +const {Async} = require('./Async') const nodeRepl = require('repl') -const {replEval} = require('./replEval') +const {replEvalF} = require('./replEval') const {completer} = require('./completer') +const {Sync} = require('./Sync') -const repl = (lexer, parser, commands, {only = false} = {only: false}) => { +const replF = mode => (lexer, parser, commands, {only = false} = {only: false}) => { console.log(commands.desc ? commands.desc + '\n' : '') nodeRepl.start({ prompt: `${commands.key}~$ `, ignoreUndefined: true, - eval: replEval(parser, commands), + eval: replEvalF(mode)(parser, commands), completer: completer(lexer, commands, {only}) }) } module.exports = { - repl + repl: replF(Async), + replF, + replSync: replF(Sync) } \ No newline at end of file diff --git a/src/repl/pipe.js b/src/repl/pipe.js new file mode 100644 index 0000000..58711b7 --- /dev/null +++ b/src/repl/pipe.js @@ -0,0 +1,9 @@ +const pipe = (...fs) => a => { + let res = a + for (let i = 0; i < fs.length; i++) res = fs[i](res) + return res +} + +module.exports = { + pipe +} \ No newline at end of file diff --git a/src/repl/replEval.js b/src/repl/replEval.js index 5de4bc2..1cab88c 100644 --- a/src/repl/replEval.js +++ b/src/repl/replEval.js @@ -1,20 +1,26 @@ -const replEval = (parser, commands) => { +const {pipe} = require('./pipe') + +const replEvalF = mode => (parser, commands) => { const parse = parser(commands) return (cmd, context, filename, callback) => { - const { errs, args } = parse(cmd) + const {errs, args} = parse(cmd) - Object.entries(args).forEach(([key, value]) => { - const cmd = commands.opts.find(_ => _.args.includes(key)) || { action: _ => undefined } - const action = cmd.action || (_ => undefined) + const results = Object.entries(args).map(([key, value]) => { + const cmd = commands.opts.find(_ => _.args.includes(key)) || { action: _ => 42 } + const action = cmd.action || (_ => 42) - action(value, errs) + return typeof action === 'undefined' ? mode.resolve() : mode.resolve(action(value, errs)) }) - callback(null, undefined); + return pipe( + mode.all, + mode.then(() => callback(null, undefined)), + mode.catch(err => callback(null, err === null ? undefined : err)) + )(results) } } module.exports = { - replEval + replEvalF } \ No newline at end of file