input.js 2.0 KB

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