choices.js 2.9 KB

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