password.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. 'use strict';
  2. /**
  3. * `password` type prompt
  4. */
  5. var chalk = require('chalk');
  6. var Base = require('./base');
  7. var observe = require('../utils/events');
  8. function mask(input, maskChar) {
  9. input = String(input);
  10. maskChar = typeof maskChar === 'string' ? maskChar : '*';
  11. if (input.length === 0) {
  12. return '';
  13. }
  14. return new Array(input.length + 1).join(maskChar);
  15. }
  16. class PasswordPrompt extends Base {
  17. /**
  18. * Start the Inquiry session
  19. * @param {Function} cb Callback when prompt is done
  20. * @return {this}
  21. */
  22. _run(cb) {
  23. this.done = cb;
  24. var events = observe(this.rl);
  25. // Once user confirm (enter key)
  26. var submit = events.line.map(this.filterInput.bind(this));
  27. var validation = this.handleSubmitEvents(submit);
  28. validation.success.forEach(this.onEnd.bind(this));
  29. validation.error.forEach(this.onError.bind(this));
  30. if (this.opt.mask) {
  31. events.keypress.takeUntil(validation.success).forEach(this.onKeypress.bind(this));
  32. }
  33. // Init
  34. this.render();
  35. return this;
  36. }
  37. /**
  38. * Render the prompt to screen
  39. * @return {PasswordPrompt} self
  40. */
  41. render(error) {
  42. var message = this.getQuestion();
  43. var bottomContent = '';
  44. if (this.status === 'answered') {
  45. message += this.opt.mask
  46. ? chalk.cyan(mask(this.answer, this.opt.mask))
  47. : chalk.italic.dim('[hidden]');
  48. } else if (this.opt.mask) {
  49. message += mask(this.rl.line || '', this.opt.mask);
  50. } else {
  51. message += chalk.italic.dim('[input is hidden] ');
  52. }
  53. if (error) {
  54. bottomContent = '\n' + chalk.red('>> ') + error;
  55. }
  56. this.screen.render(message, bottomContent);
  57. }
  58. /**
  59. * When user press `enter` key
  60. */
  61. filterInput(input) {
  62. if (!input) {
  63. return this.opt.default == null ? '' : this.opt.default;
  64. }
  65. return input;
  66. }
  67. onEnd(state) {
  68. this.status = 'answered';
  69. this.answer = state.value;
  70. // Re-render prompt
  71. this.render();
  72. this.screen.done();
  73. this.done(state.value);
  74. }
  75. onError(state) {
  76. this.render(state.isValid);
  77. }
  78. onKeypress() {
  79. this.render();
  80. }
  81. }
  82. module.exports = PasswordPrompt;