baseUI.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. 'use strict';
  2. var _ = require('lodash');
  3. var MuteStream = require('mute-stream');
  4. var readline = require('readline');
  5. /**
  6. * Base interface class other can inherits from
  7. */
  8. class UI {
  9. constructor(opt) {
  10. // Instantiate the Readline interface
  11. // @Note: Don't reassign if already present (allow test to override the Stream)
  12. if (!this.rl) {
  13. this.rl = readline.createInterface(setupReadlineOptions(opt));
  14. }
  15. this.rl.resume();
  16. this.onForceClose = this.onForceClose.bind(this);
  17. // Make sure new prompt start on a newline when closing
  18. process.on('exit', this.onForceClose);
  19. // Terminate process on SIGINT (which will call process.on('exit') in return)
  20. this.rl.on('SIGINT', this.onForceClose);
  21. }
  22. /**
  23. * Handle the ^C exit
  24. * @return {null}
  25. */
  26. onForceClose() {
  27. this.close();
  28. process.kill(process.pid, 'SIGINT');
  29. console.log('');
  30. }
  31. /**
  32. * Close the interface and cleanup listeners
  33. */
  34. close() {
  35. // Remove events listeners
  36. this.rl.removeListener('SIGINT', this.onForceClose);
  37. process.removeListener('exit', this.onForceClose);
  38. this.rl.output.unmute();
  39. if (this.activePrompt && typeof this.activePrompt.close === 'function') {
  40. this.activePrompt.close();
  41. }
  42. // Close the readline
  43. this.rl.output.end();
  44. this.rl.pause();
  45. // @see https://github.com/nodejs/node/issues/21771
  46. if (!/^win/i.test(process.platform)) {
  47. this.rl.close();
  48. }
  49. }
  50. }
  51. function setupReadlineOptions(opt) {
  52. opt = opt || {};
  53. // Default `input` to stdin
  54. var input = opt.input || process.stdin;
  55. // Add mute capabilities to the output
  56. var ms = new MuteStream();
  57. ms.pipe(opt.output || process.stdout);
  58. var output = ms;
  59. return _.extend(
  60. {
  61. terminal: true,
  62. input: input,
  63. output: output
  64. },
  65. _.omit(opt, ['input', 'output'])
  66. );
  67. }
  68. module.exports = UI;