| 'use strict'; |
| var assert = require('assert'); |
| var _ = require('lodash'); |
| var Separator = require('./separator'); |
| var Choice = require('./choice'); |
| |
| /** |
| * Choices collection |
| * Collection of multiple `choice` object |
| * @constructor |
| * @param {Array} choices All `choice` to keep in the collection |
| */ |
| |
| var Choices = module.exports = function (choices, answers) { |
| this.choices = choices.map(function (val) { |
| if (val.type === 'separator') { |
| if (!(val instanceof Separator)) { |
| val = new Separator(val.line); |
| } |
| return val; |
| } |
| return new Choice(val, answers); |
| }); |
| |
| this.realChoices = this.choices |
| .filter(Separator.exclude) |
| .filter(function (item) { |
| return !item.disabled; |
| }); |
| |
| Object.defineProperty(this, 'length', { |
| get: function () { |
| return this.choices.length; |
| }, |
| set: function (val) { |
| this.choices.length = val; |
| } |
| }); |
| |
| Object.defineProperty(this, 'realLength', { |
| get: function () { |
| return this.realChoices.length; |
| }, |
| set: function () { |
| throw new Error('Cannot set `realLength` of a Choices collection'); |
| } |
| }); |
| }; |
| |
| /** |
| * Get a valid choice from the collection |
| * @param {Number} selector The selected choice index |
| * @return {Choice|Undefined} Return the matched choice or undefined |
| */ |
| |
| Choices.prototype.getChoice = function (selector) { |
| assert(_.isNumber(selector)); |
| return this.realChoices[selector]; |
| }; |
| |
| /** |
| * Get a raw element from the collection |
| * @param {Number} selector The selected index value |
| * @return {Choice|Undefined} Return the matched choice or undefined |
| */ |
| |
| Choices.prototype.get = function (selector) { |
| assert(_.isNumber(selector)); |
| return this.choices[selector]; |
| }; |
| |
| /** |
| * Match the valid choices against a where clause |
| * @param {Object} whereClause Lodash `where` clause |
| * @return {Array} Matching choices or empty array |
| */ |
| |
| Choices.prototype.where = function (whereClause) { |
| return _.filter(this.realChoices, whereClause); |
| }; |
| |
| /** |
| * Pluck a particular key from the choices |
| * @param {String} propertyName Property name to select |
| * @return {Array} Selected properties |
| */ |
| |
| Choices.prototype.pluck = function (propertyName) { |
| return _.map(this.realChoices, propertyName); |
| }; |
| |
| // Expose usual Array methods |
| Choices.prototype.indexOf = function () { |
| return this.choices.indexOf.apply(this.choices, arguments); |
| }; |
| Choices.prototype.forEach = function () { |
| return this.choices.forEach.apply(this.choices, arguments); |
| }; |
| Choices.prototype.filter = function () { |
| return this.choices.filter.apply(this.choices, arguments); |
| }; |
| Choices.prototype.find = function (func) { |
| return _.find(this.choices, func); |
| }; |
| Choices.prototype.push = function () { |
| var objs = _.map(arguments, function (val) { |
| return new Choice(val); |
| }); |
| this.choices.push.apply(this.choices, objs); |
| this.realChoices = this.choices.filter(Separator.exclude); |
| return this.choices; |
| }; |