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