| 'use strict'; | |
| /** | |
| * `password` type prompt | |
| */ | |
| var chalk = require('chalk'); | |
| var { map, takeUntil } = require('rxjs/operators'); | |
| var Base = require('./base'); | |
| var observe = require('../utils/events'); | |
| function mask(input, maskChar) { | |
| input = String(input); | |
| maskChar = typeof maskChar === 'string' ? maskChar : '*'; | |
| if (input.length === 0) { | |
| return ''; | |
| } | |
| return new Array(input.length + 1).join(maskChar); | |
| } | |
| class PasswordPrompt extends Base { | |
| /** | |
| * Start the Inquiry session | |
| * @param {Function} cb Callback when prompt is done | |
| * @return {this} | |
| */ | |
| _run(cb) { | |
| this.done = cb; | |
| var events = observe(this.rl); | |
| // Once user confirm (enter key) | |
| 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 {PasswordPrompt} self | |
| */ | |
| render(error) { | |
| var message = this.getQuestion(); | |
| var bottomContent = ''; | |
| if (this.status === 'answered') { | |
| message += this.opt.mask | |
| ? chalk.cyan(mask(this.answer, this.opt.mask)) | |
| : chalk.italic.dim('[hidden]'); | |
| } else if (this.opt.mask) { | |
| message += mask(this.rl.line || '', this.opt.mask); | |
| } else { | |
| message += chalk.italic.dim('[input is hidden] '); | |
| } | |
| if (error) { | |
| bottomContent = '\n' + 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.status = 'answered'; | |
| this.answer = state.value; | |
| // Re-render prompt | |
| this.render(); | |
| this.screen.done(); | |
| this.done(state.value); | |
| } | |
| onError(state) { | |
| this.render(state.isValid); | |
| } | |
| onKeypress() { | |
| // If user press a key, just clear the default value | |
| if (this.opt.default) { | |
| this.opt.default = undefined; | |
| } | |
| this.render(); | |
| } | |
| } | |
| module.exports = PasswordPrompt; |