choices.js 2.7 KB

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