diff --git a/lib/command/flag-to-prompt.js b/lib/command/flag-to-prompt.js index df4a8b9..cc5bf4b 100644 --- a/lib/command/flag-to-prompt.js +++ b/lib/command/flag-to-prompt.js @@ -15,5 +15,6 @@ function flagToPrompt(name, opt) { , 'when': opt.when , 'validate': opt.validate , 'filter': opt.filter + , 'transformer': opt.transformer } } diff --git a/lib/command/index.js b/lib/command/index.js index 3a7de77..c7f5fb0 100644 --- a/lib/command/index.js +++ b/lib/command/index.js @@ -2,7 +2,7 @@ /** * Base command class for creating interactive cli programs - * @module module:lib/command + * @module module:seeli/lib/command * @author Eric Satterwhite * @requires options * @requires events @@ -31,6 +31,7 @@ const ora = require('ora') const toArray = require('mout/lang/toArray') const isFunction = require('mout/lang/isFunction') const hasOwn = require('mout/object/hasOwn') +const typecast = require('mout/string/typecast') const toPrompt = require('./flag-to-prompt') const Registry = require('../registry') const conf = require('../conf') @@ -346,7 +347,7 @@ class Command extends Registry { const current = this.options.flags[flag] if (current.interactive === false) continue if (Array.isArray(current.type)) { - answers[flag] = await ask(flag, cmd, current, this[kPrompt]) + answers[flag] = await ask(flag, current, this[kPrompt]) continue } const arg = toQuestion(flag, current, answers) @@ -357,7 +358,13 @@ class Command extends Registry { this.parsed = {...this.parsed, ...answers} for (const [flag, answer] of Object.entries(answers)) { - args.push(`--${flag}=${answer}`) + if (Array.isArray(answer)) { + for (const value of answer) { + args.push(`--${flag}=${value}`) + } + } else { + args.push(`--${flag}=${answer}`) + } object.set(this.parsed, flag, answer) } @@ -507,10 +514,22 @@ class Command extends Registry { return this.register(...args) } + /** + * @typedef {Object} Prompt + * @property {String} type + * @property {String} name + * @property {String} message + * @property {?String[]} choices + * @property {?String|Number|Boolean} default + * @property {?Function} when + * @property {?Function} validate + * @property {?Function} filter + **/ + /** * Convert all registered flags to inquierer compatible prompt objects * @method module:seeli/lib/command#toPrompt - * @returns {Object[]} array of inquirer prompt objects + * @returns {Prompt[]} array of inquirer prompt objects **/ toPrompt() { const prompts = [] @@ -538,12 +557,19 @@ async function ask(name, opts, inquirer) { const question = toQuestion(name, opts) while (true) { const answer = await inquirer(question) - if (answer[name] === '') break - results.push(answer[name]) + const value = typecast(answer[name]) + if (value === '') break + if (question.type === 'number' && isNaN(value)) break + results.push(value) } return results } +function transform(input, answers, status) { + if (!status.isFinal) return input + if (this.type === 'number' && isNaN(input)) return '' + return chalk.cyan(input) +} function toQuestion(flag, opts, answers) { const arg = toPrompt(flag, opts) @@ -553,6 +579,7 @@ function toQuestion(flag, opts, answers) { arg.when = opts.when ? opts.when.bind(null, answers) : undefined arg.validate = opts.validate ? opts.validate.bind(null, answers) : undefined arg.filter = opts.filter ? opts.filter.bind(null, answers) : undefined + arg.transformer = opts.transformer ? opts.transformer : transform.bind(arg) return arg } diff --git a/lib/seeli.js b/lib/seeli.js index 1d0cdc4..7764888 100644 --- a/lib/seeli.js +++ b/lib/seeli.js @@ -1,5 +1,11 @@ 'use strict' - +/** + * @module module:seeli/lib/seeli + * @requires mout/lang/toArray + * @requires mout/lang/kindOf + * @requires seeli/lib/command + * @requires seeli/lib/conf + **/ const chalk = require('chalk') const toArray = require('mout/lang/toArray') const kindOf = require('mout/lang/kindOf') @@ -7,6 +13,12 @@ const Command = require('./command') const config = require('./conf.js') const {PluginException} = require('./exceptions.js') +/** + * Seeli Entrypoint used for registring and managing commands + * @constructor + * @alias module:seeli/lib/seeli + * @extends module:seeli/lib/command + **/ class Seeli extends Command { constructor(...args) { super({ diff --git a/test/flag-to-prompt.js b/test/flag-to-prompt.js index 3382235..f5641c2 100644 --- a/test/flag-to-prompt.js +++ b/test/flag-to-prompt.js @@ -17,6 +17,7 @@ test('flagToPrompt', async (t) => { , when: undefined , validate: undefined , filter: undefined + , transformer: undefined }) }) @@ -29,6 +30,7 @@ test('flagToPrompt', async (t) => { , when: () => {} , validate: () => {} , filter: () => {} + , transformer: () => {} }) t.match(out, { @@ -39,6 +41,7 @@ test('flagToPrompt', async (t) => { , when: Function , validate: Function , filter: Function + , transformer: Function }) }) }).catch(threw)