Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. 'use strict';
  2. var _ = require('lodash');
  3. var { defer, empty, from, of } = require('rxjs');
  4. var { concatMap, filter, publish, reduce } = require('rxjs/operators');
  5. var runAsync = require('run-async');
  6. var utils = require('../utils/utils');
  7. var Base = require('./baseUI');
  8. /**
  9. * Base interface class other can inherits from
  10. */
  11. class PromptUI extends Base {
  12. constructor(prompts, opt) {
  13. super(opt);
  14. this.prompts = prompts;
  15. }
  16. run(questions) {
  17. // Keep global reference to the answers
  18. this.answers = {};
  19. // Make sure questions is an array.
  20. if (_.isPlainObject(questions)) {
  21. questions = [questions];
  22. }
  23. // Create an observable, unless we received one as parameter.
  24. // Note: As this is a public interface, we cannot do an instanceof check as we won't
  25. // be using the exact same object in memory.
  26. var obs = _.isArray(questions) ? from(questions) : questions;
  27. this.process = obs.pipe(
  28. concatMap(this.processQuestion.bind(this)),
  29. publish() // Creates a hot Observable. It prevents duplicating prompts.
  30. );
  31. this.process.connect();
  32. return this.process
  33. .pipe(
  34. reduce((answers, answer) => {
  35. _.set(this.answers, answer.name, answer.answer);
  36. return this.answers;
  37. }, {})
  38. )
  39. .toPromise(Promise)
  40. .then(this.onCompletion.bind(this));
  41. }
  42. /**
  43. * Once all prompt are over
  44. */
  45. onCompletion() {
  46. this.close();
  47. return this.answers;
  48. }
  49. processQuestion(question) {
  50. question = _.clone(question);
  51. return defer(() => {
  52. var obs = of(question);
  53. return obs.pipe(
  54. concatMap(this.setDefaultType.bind(this)),
  55. concatMap(this.filterIfRunnable.bind(this)),
  56. concatMap(() =>
  57. utils.fetchAsyncQuestionProperty(question, 'message', this.answers)
  58. ),
  59. concatMap(() =>
  60. utils.fetchAsyncQuestionProperty(question, 'default', this.answers)
  61. ),
  62. concatMap(() =>
  63. utils.fetchAsyncQuestionProperty(question, 'choices', this.answers)
  64. ),
  65. concatMap(this.fetchAnswer.bind(this))
  66. );
  67. });
  68. }
  69. fetchAnswer(question) {
  70. var Prompt = this.prompts[question.type];
  71. this.activePrompt = new Prompt(question, this.rl, this.answers);
  72. return defer(() =>
  73. from(
  74. this.activePrompt.run().then(answer => ({ name: question.name, answer: answer }))
  75. )
  76. );
  77. }
  78. setDefaultType(question) {
  79. // Default type to input
  80. if (!this.prompts[question.type]) {
  81. question.type = 'input';
  82. }
  83. return defer(() => of(question));
  84. }
  85. filterIfRunnable(question) {
  86. if (question.when === false) {
  87. return empty();
  88. }
  89. if (!_.isFunction(question.when)) {
  90. return of(question);
  91. }
  92. var answers = this.answers;
  93. return defer(() =>
  94. from(
  95. runAsync(question.when)(answers).then(shouldRun => {
  96. if (shouldRun) {
  97. return question;
  98. }
  99. })
  100. ).pipe(filter(val => val != null))
  101. );
  102. }
  103. }
  104. module.exports = PromptUI;