password.js 2.1 KB

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