| 'use strict'; |
| /** |
| * `input` type prompt |
| */ |
| |
| var chalk = require('chalk'); |
| var { map, takeUntil } = require('rxjs/operators'); |
| var Base = require('./base'); |
| var observe = require('../utils/events'); |
| |
| class InputPrompt extends Base { |
| /** |
| * Start the Inquiry session |
| * @param {Function} cb Callback when prompt is done |
| * @return {this} |
| */ |
| |
| _run(cb) { |
| this.done = cb; |
| |
| // Once user confirm (enter key) |
| var events = observe(this.rl); |
| var submit = events.line.pipe(map(this.filterInput.bind(this))); |
| |
| var validation = this.handleSubmitEvents(submit); |
| validation.success.forEach(this.onEnd.bind(this)); |
| validation.error.forEach(this.onError.bind(this)); |
| |
| events.keypress |
| .pipe(takeUntil(validation.success)) |
| .forEach(this.onKeypress.bind(this)); |
| |
| // Init |
| this.render(); |
| |
| return this; |
| } |
| |
| /** |
| * Render the prompt to screen |
| * @return {InputPrompt} self |
| */ |
| |
| render(error) { |
| var bottomContent = ''; |
| var appendContent = ''; |
| var message = this.getQuestion(); |
| var transformer = this.opt.transformer; |
| var isFinal = this.status === 'answered'; |
| |
| if (isFinal) { |
| appendContent = this.answer; |
| } else { |
| appendContent = this.rl.line; |
| } |
| |
| if (transformer) { |
| message += transformer(appendContent, this.answers, { isFinal }); |
| } else { |
| message += isFinal ? chalk.cyan(appendContent) : appendContent; |
| } |
| |
| if (error) { |
| bottomContent = chalk.red('>> ') + error; |
| } |
| |
| this.screen.render(message, bottomContent); |
| } |
| |
| /** |
| * When user press `enter` key |
| */ |
| |
| filterInput(input) { |
| if (!input) { |
| return this.opt.default == null ? '' : this.opt.default; |
| } |
| |
| return input; |
| } |
| |
| onEnd(state) { |
| this.answer = state.value; |
| this.status = 'answered'; |
| |
| // Re-render prompt |
| this.render(); |
| |
| this.screen.done(); |
| this.done(state.value); |
| } |
| |
| onError(state) { |
| this.rl.line += state.value; |
| this.rl.cursor += state.value.length; |
| this.render(state.isValid); |
| } |
| |
| /** |
| * When user press a key |
| */ |
| |
| onKeypress() { |
| // If user press a key, just clear the default value |
| if (this.opt.default) { |
| this.opt.default = undefined; |
| } |
| |
| this.render(); |
| } |
| } |
| |
| module.exports = InputPrompt; |