choices.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. 'use strict';
  2. var assert = require('assert');
  3. var _ = {
  4. isNumber: require('lodash/isNumber'),
  5. filter: require('lodash/filter'),
  6. map: require('lodash/map'),
  7. find: require('lodash/find'),
  8. };
  9. var Separator = require('./separator');
  10. var Choice = require('./choice');
  11. /**
  12. * Choices collection
  13. * Collection of multiple `choice` object
  14. * @constructor
  15. * @param {Array} choices All `choice` to keep in the collection
  16. */
  17. module.exports = class Choices {
  18. constructor(choices, answers) {
  19. this.choices = choices.map((val) => {
  20. if (val.type === 'separator') {
  21. if (!(val instanceof Separator)) {
  22. val = new Separator(val.line);
  23. }
  24. return val;
  25. }
  26. return new Choice(val, answers);
  27. });
  28. this.realChoices = this.choices
  29. .filter(Separator.exclude)
  30. .filter((item) => !item.disabled);
  31. Object.defineProperty(this, 'length', {
  32. get() {
  33. return this.choices.length;
  34. },
  35. set(val) {
  36. this.choices.length = val;
  37. },
  38. });
  39. Object.defineProperty(this, 'realLength', {
  40. get() {
  41. return this.realChoices.length;
  42. },
  43. set() {
  44. throw new Error('Cannot set `realLength` of a Choices collection');
  45. },
  46. });
  47. }
  48. /**
  49. * Get a valid choice from the collection
  50. * @param {Number} selector The selected choice index
  51. * @return {Choice|Undefined} Return the matched choice or undefined
  52. */
  53. getChoice(selector) {
  54. assert(_.isNumber(selector));
  55. return this.realChoices[selector];
  56. }
  57. /**
  58. * Get a raw element from the collection
  59. * @param {Number} selector The selected index value
  60. * @return {Choice|Undefined} Return the matched choice or undefined
  61. */
  62. get(selector) {
  63. assert(_.isNumber(selector));
  64. return this.choices[selector];
  65. }
  66. /**
  67. * Match the valid choices against a where clause
  68. * @param {Object} whereClause Lodash `where` clause
  69. * @return {Array} Matching choices or empty array
  70. */
  71. where(whereClause) {
  72. return _.filter(this.realChoices, whereClause);
  73. }
  74. /**
  75. * Pluck a particular key from the choices
  76. * @param {String} propertyName Property name to select
  77. * @return {Array} Selected properties
  78. */
  79. pluck(propertyName) {
  80. return _.map(this.realChoices, propertyName);
  81. }
  82. // Expose usual Array methods
  83. indexOf() {
  84. return this.choices.indexOf.apply(this.choices, arguments);
  85. }
  86. forEach() {
  87. return this.choices.forEach.apply(this.choices, arguments);
  88. }
  89. filter() {
  90. return this.choices.filter.apply(this.choices, arguments);
  91. }
  92. reduce() {
  93. return this.choices.reduce.apply(this.choices, arguments);
  94. }
  95. find(func) {
  96. return _.find(this.choices, func);
  97. }
  98. push() {
  99. var objs = _.map(arguments, (val) => new Choice(val));
  100. this.choices.push.apply(this.choices, objs);
  101. this.realChoices = this.choices
  102. .filter(Separator.exclude)
  103. .filter((item) => !item.disabled);
  104. return this.choices;
  105. }
  106. };