Socket
Socket
Sign inDemoInstall

prompt-choices

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prompt-choices - npm Package Compare versions

Comparing version 2.0.0 to 3.0.0

416

index.js

@@ -6,6 +6,7 @@ 'use strict';

var define = require('define-property');
var extend = require('extend-shallow');
var visit = require('collection-visit');
var Actions = require('./lib/actions');
var Choice = require('./lib/choice');
var utils = require('./lib/utils');
var log = require('log-utils');

@@ -28,59 +29,55 @@ /**

}
this.options = options || {};
define(this, 'isChoices', true);
define(this, 'answers', this.options.answers || {});
this.original = utils.clone(choices);
this.options = extend({}, options);
this.answers = this.options.answers || {};
this.paginator = new Paginator(this.options);
this.position = 0;
this.choices = [];
this.items = [];
this.keymap = {};
this.keys = [];
this.keymap = {};
this.addChoices(choices);
this.original = [];
this.position = 0;
if (choices) {
this.original = utils.clone(choices);
this.addChoices(choices);
}
}
/**
* Render the current choices.
* Create a new `Choice` object.
*
* @param {Number} `position` Cursor position
* @param {Object} `options`
* @return {String}
* ```js
* choices.choice('blue');
* ```
* @param {String|Object} `choice`
* @return {Object} Returns a choice object.
* @api public
*/
Choices.prototype.render = function(position, options) {
var opts = utils.extend({}, this.options, options);
var len = this.choices.length;
var idx = -1;
var buf = '';
this.position = position || 0;
while (++idx < len) {
buf += this.choices[idx].render(this.position, opts);
}
var str = '\n' + buf.replace(/\s+$/, '');
return this.paginator.paginate(str, this.position, opts.limit);
Choices.prototype.choice = function(choice) {
return new Choice(choice, this.options);
};
/**
* Add an array of normalized `choice` objects to the `choices` array. This
* method is called in the constructor, but it can also be used to add
* choices after instantiation.
* Returns a normalized `choice` object.
*
* ```js
* choices.addChoices(['a', 'b', 'c']);
* choices.toChoice('foo');
* choices.toChoice({name: 'foo'});
* ```
* @param {Array|Object} `choices` One or more choices to add.
* @param {Object|String} `choice`
* @return {Object}
* @api public
*/
Choices.prototype.addChoices = function(choices) {
choices = utils.arrayify(choices);
var len = choices.length;
var idx = -1;
while (++idx < len) {
this.addChoice(choices[idx]);
Choices.prototype.toChoice = function(choice) {
if (choice.type === 'separator') {
if (!choice.isSeparator) {
choice = this.separator(choice.line, this.options);
}
return choice;
}
return this.choice(choice);
};

@@ -92,3 +89,3 @@

* ```js
* choices.addChoice(['a', 'b', 'c']);
* choices.addChoice(['foo', 'bar', 'baz']);
* ```

@@ -100,12 +97,4 @@ * @param {string|Object} `choice` One or more choices to add.

Choices.prototype.addChoice = function(choice) {
if (choice.type === 'separator') {
if (!choice.isSeparator) {
choice = this.separator(choice.line);
}
} else if (choice.disabled) {
choice = this.choice(choice);
} else {
choice = this.choice(choice);
choice = this.toChoice(choice);
if (!choice.disabled && choice.type !== 'separator') {
choice.index = this.items.length;

@@ -116,23 +105,120 @@ this.keymap[choice.key] = choice;

}
// push normalized "choice" object onto array
this.choices.push(choice);
return this;
};
/**
* Create a new `Choice` object.
* Add an array of normalized `choice` objects to the `choices` array. This
* method is called in the constructor, but it can also be used to add
* choices after instantiation.
*
* ```js
* choices.choice('blue');
* choices.addChoices(['foo', 'bar', 'baz']);
* ```
* @param {String|Object} `choice`
* @return {Object} Returns a choice object.
* @param {Array|Object} `choices` One or more choices to add.
* @api public
*/
Choices.prototype.choice = function(choice) {
return new Choice(choice, this.options);
Choices.prototype.addChoices = function(choices) {
if (this.options.radio === true && Array.isArray(choices) && choices.length > 2) {
choices = { all: choices };
}
if (utils.isObject(choices)) {
choices = this.toGroups(choices);
}
if (!Array.isArray(choices)) {
return;
}
for (var i = 0; i < choices.length; i++) {
this.addChoice(choices[i]);
}
};
/**
* Create choice "groups" from the given choices object.
* ![choice groups](docs/prompt-groups.gif).
*
* ```js
* choices.toGroups({
* foo: ['a', 'b', 'c'],
* bar: ['d', 'e', 'f']
* });
* ```
* @param {Object} `choices` (required) The value of each object must be an array of choices (strings or objects).
* @return {Array} Returns an array of normalized choice objects.
* @api public
*/
Choices.prototype.toGroups = function(choices) {
if (!utils.isObject(choices)) {
throw new TypeError('expected choices to be an object');
}
var blank = this.separator('');
var line = this.separator(this.options);
var keys = Object.keys(choices);
var head = [];
var tail = [line];
var items = [];
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var val = choices[key];
var arr = (utils.isObject(val) && val.choices) ? val.choices : val;
if (!Array.isArray(arr)) {
throw new TypeError('expected group choices to be an array');
}
var select = this.choice({
name: key,
type: 'group',
choices: [],
keys: []
});
if (key !== 'all') {
tail.push(select);
}
var len = arr.length;
var idx = -1;
for (var j = 0; j < arr.length; j++) {
var choice = this.choice(arr[j]);
choice.type = 'option',
choice.group = select;
choice.groupName = key;
select.choices.push(choice);
select.keys.push(choice.name);
tail.push(choice);
items.push(choice);
}
}
var none = {name: 'none', type: 'radio', choices: items};
var all = {name: 'all', type: 'radio', choices: items};
if (keys.length === 1 && arr.length <= 2) {
return tail.filter(function(choice) {
var isOption = choice.type === 'option';
delete choice.type;
return isOption;
});
}
if (this.options.radio === true) {
head.unshift(none);
head.unshift(all);
} else if (keys.length === 1 && keys[0] === 'all') {
head.push(none);
}
head.unshift(blank);
return head.concat(tail);
};
/**
* Create a new `Separator` object. See [choices-separator][]

@@ -166,27 +252,6 @@ * for more details.

Choices.prototype.hasChoice = function(val) {
return this.getIndex(val) !== -1;
return typeof this.get(val) !== 'undefined';
};
/**
* Get the choice or separator object at the specified index.
*
* ```js
* var choice = choices.get(1);
* ```
* @param {Number|String} `key` The name or index of the object to get
* @return {Object} Returns the specified choice
* @api public
*/
Choices.prototype.get = function(key) {
if (typeof key === 'string') {
key = this.getIndex(key);
}
if (!utils.isNumber(key)) {
throw new TypeError('expected index to be a number or string');
}
return this.getChoice(key);
};
/**
* Get a non-separator choice from the collection.

@@ -233,18 +298,20 @@ *

/**
* Call the given `method` on `choices.actions`
* Get the choice or separator object at the specified index.
*
* ```js
* choices.action('up', 1);
* var choice = choices.get(1);
* ```
* @param {String} `method`
* @param {Number} `pos`
* @param {Number|String} `key` The name or index of the object to get
* @return {Object} Returns the specified choice
* @api public
*/
Choices.prototype.action = function(method, pos) {
var action = this.actions[method];
if (typeof action !== 'function') {
throw new Error('choices.action "' + method + '" does not exist');
Choices.prototype.get = function(key) {
if (typeof key === 'string') {
key = this.getIndex(key);
}
return action.call(this.actions, pos);
if (!utils.isNumber(key)) {
throw new TypeError('expected index to be a number or string');
}
return this.getChoice(key);
};

@@ -303,2 +370,25 @@

/**
* Returns true if a choice is checked.
*
* ```js
* var choices = new Choices(['foo', 'bar', 'baz']);
* console.log(choices.isChecked('foo'));
* //=> false
* choices.check('foo');
* console.log(choices.isChecked('foo'));
* //=> true
* ```
* @param {String|Number} `name` Name or index of the choice.
* @return {Boolean}
* @api public
*/
Choices.prototype.isChecked = function(name) {
var choice = this.get(name);
if (choice) {
return choice.checked === true;
}
};
/**
* Toggle the choice at the given `idx`.

@@ -319,2 +409,3 @@ *

}
if (Array.isArray(val)) {

@@ -324,10 +415,19 @@ visit(this, 'toggle', val, radio);

}
if (typeof val === 'string') {
val = this.getIndex(val);
}
if (radio) {
utils.toggle(this.items, 'checked', val);
} else {
this.getChoice(val).toggle();
this.update();
return this;
}
var choice = this.get(val);
if (choice) {
choice.toggle();
}
this.update();
return this;

@@ -337,2 +437,79 @@ };

/**
* When user press `enter` key
*/
Choices.prototype.radio = function() {
var choice = this.get(this.position);
if (!choice) return;
if (choice.type === 'group') {
choice.toggle();
this.toggle(choice.keys);
this.update();
return;
}
if (this.length > 1) {
if (choice.name === 'all') {
this[choice.checked ? 'uncheck' : 'check']();
this.toggle('none');
this.update();
return;
}
if (choice.name === 'none') {
this.uncheck();
this.check(this.position);
this.update();
return;
}
}
choice.toggle();
this.update();
};
Choices.prototype.update = function() {
if (this.all) {
this.check('all');
this.uncheck('none');
return;
}
if (this.none) {
this.uncheck('all');
this.check('none');
return;
}
if (this.checked.length) {
this.uncheck(['all', 'none']);
}
};
/**
* Render the current choice "line".
*
* @param {Number} `position` Cursor position
* @param {Object} `options`
* @return {String}
* @api public
*/
Choices.prototype.render = function(position, options) {
var opts = utils.extend({limit: 7}, this.options, options);
var buf = '';
if (opts.radio === true) {
opts.limit += 2;
}
this.position = position || 0;
for (var i = 0; i < this.choices.length; i++) {
buf += this.choices[i].render(this.position, opts);
}
var str = '\n' + buf.replace(/\s+$/, '');
return this.paginator.paginate(str, this.position, opts.limit);
};
/**
* Return choice values for choices that return truthy based

@@ -386,2 +563,19 @@ * on the given `val`.

/**
* Returns true if the given `choice` is a valid choice item, and
* not a "group" or "radio" choice.
*
* @param {String} `key` Property name to use for plucking objects.
* @return {Array} Plucked objects
* @api public
*/
Choices.prototype.isItem = function(choice) {
return choice.type !== 'separator'
&& choice.type !== 'group'
&& choice.type !== 'radio'
&& choice.name !== 'none'
&& choice.name !== 'all';
};
/**
* Returns true if the given `index` is a valid choice index.

@@ -437,2 +631,6 @@ * @param {String} `key` Property name to use for plucking objects.

Choices.prototype.some = function() {
return this.items.some.apply(this.items, arguments);
};
/**

@@ -449,15 +647,33 @@ * Getter for getting the checked choices from the collection.

get: function() {
var opts = this.options;
return this.items.reduce(function(acc, choice) {
if (opts.radio && choice.name === 'all' || choice.name === 'none') {
if (this.options.radio === true && !this.isItem(choice)) {
return acc;
}
if (choice.checked === true) {
acc.push((opts.radio || opts.choiceObject) ? choice : choice.value);
acc.push(choice.value);
}
return acc;
}, []);
}.bind(this), []);
}
});
Object.defineProperty(Choices.prototype, 'all', {
set: function() {
throw new Error('.all is a getter and cannot be defined');
},
get: function() {
var items = this.filter(this.isItem);
return items.length === this.checked.length;
}
});
Object.defineProperty(Choices.prototype, 'none', {
set: function() {
throw new Error('.none is a getter and cannot be defined');
},
get: function() {
return this.checked.length === 0;
}
});
/**

@@ -479,18 +695,2 @@ * Getter for getting the length of the collection.

/**
* Getter for instantiating the `Actions` utility class
*/
Object.defineProperty(Choices.prototype, 'actions', {
set: function(actions) {
utils.define(this, '_actions', actions);
},
get: function() {
if (!this._actions) {
utils.define(this, '_actions', new Actions(this, this.options));
}
return this._actions;
}
});
/**
* Create a new `Separator` object. See [choices-separator][] for more details.

@@ -497,0 +697,0 @@ *

@@ -6,2 +6,3 @@ 'use strict';

var define = require('define-property');
var pointer = require('prompt-pointer');
var radio = require('radio-symbol');

@@ -59,3 +60,3 @@ var strip = require('strip-color');

this.pointer = utils.pointer(this.options);
this.pointer = pointer(this.options);
if (!this.options.pointer) {

@@ -73,2 +74,5 @@ this.pointer = log.cyan(this.pointer);

}
if (typeof options.checkbox === 'string') {
this.symbol = options.checkbox;
}
if (this.type === 'separator') {

@@ -127,7 +131,15 @@ return this.value;

get: function() {
var symbol = this.options.checkbox || radio;
return (this.options.checkbox || radio)[this.state];
}
});
Object.defineProperty(Choice.prototype, 'state', {
set: function() {
throw new Error('.state is a getter and cannot be defined');
},
get: function() {
if (this.disabled) {
return symbol.disabled;
return 'disabled';
}
return this.checked ? symbol.on : symbol.off;
return this.checked ? 'on' : 'off';
}

@@ -149,2 +161,6 @@ });

var line = this.value;
if (line.trim() === 'all' || line.trim() === 'none') {
line = log.bold(line);
}
if (typeof this.disabled === 'string') {

@@ -157,3 +173,9 @@ this.pointer = this.prefix;

}
return this.pointer + this.symbol + ' '
var symbol = this.symbol;
if(this.type === 'option') {
symbol = ' ' + radio.check[this.state];
}
return this.pointer + symbol + ' '
+ this.format(line).replace(/\s+$/, '')

@@ -160,0 +182,0 @@ + '\n';

@@ -22,21 +22,2 @@ 'use strict';

// todo: see if there is a better option for linux
utils.pointer = function(options) {
if (options && typeof options.pointer === 'string') {
return options.pointer.trim();
}
var small = options && options.small;
switch(process.platform) {
case 'cygwin':
case 'msys':
case 'win32':
return small ? '»' : '>';
case 'linux':
return small ? '‣' : '‣';
default: {
return small ? '›' : '❯';
}
}
};
/**

@@ -43,0 +24,0 @@ * Returns true if `val` is a number (also ensures that val

{
"name": "prompt-choices",
"description": "Create an array of multiple choice objects for use in prompts.",
"version": "2.0.0",
"version": "3.0.0",
"homepage": "https://github.com/enquirer/prompt-choices",

@@ -25,14 +25,15 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)",

"arr-flatten": "^1.0.3",
"choices-separator": "^1.1.0",
"clone-deep": "^0.2.4",
"choices-separator": "^2.0.0",
"clone-deep": "^0.3.0",
"collection-visit": "^1.0.0",
"debug": "^2.6.6",
"debug": "^2.6.8",
"define-property": "^1.0.0",
"extend-shallow": "^2.0.1",
"is-number": "^3.0.0",
"kind-of": "^3.2.0",
"kind-of": "^4.0.0",
"lazy-cache": "^2.0.2",
"log-utils": "^0.2.1",
"radio-symbol": "^1.0.3",
"set-value": "^0.4.3",
"prompt-pointer": "^1.0.0",
"radio-symbol": "^2.0.0",
"set-value": "^1.0.0",
"strip-color": "^0.1.0",

@@ -47,6 +48,7 @@ "terminal-paginator": "^1.1.0",

"gulp-istanbul": "^1.1.1",
"gulp-mocha": "^3.0.0",
"gulp-mocha": "^3.0.1",
"gulp-unused": "^0.2.1",
"is-windows": "^1.0.1",
"mocha": "^3.3.0"
"mocha": "^3.4.1",
"prompt-actions": "^1.1.1"
},

@@ -101,4 +103,7 @@ "keywords": [

]
}
},
"reflinks": [
"choices-separator"
]
}
}

@@ -22,3 +22,3 @@ # prompt-choices [![NPM version](https://img.shields.io/npm/v/prompt-choices.svg?style=flat)](https://www.npmjs.com/package/prompt-choices) [![NPM monthly downloads](https://img.shields.io/npm/dm/prompt-choices.svg?style=flat)](https://npmjs.org/package/prompt-choices) [![NPM total downloads](https://img.shields.io/npm/dt/prompt-choices.svg?style=flat)](https://npmjs.org/package/prompt-choices) [![Linux Build Status](https://img.shields.io/travis/enquirer/prompt-choices.svg?style=flat&label=Travis)](https://travis-ci.org/enquirer/prompt-choices)

### [Choices](index.js#L22)
### [Choices](index.js#L23)

@@ -38,19 +38,25 @@ Create a new `Choices` collection.

### [.render](index.js#L49)
### [.choice](index.js#L57)
Render the current choices.
Create a new `Choice` object.
**Params**
* `position` **{Number}**: Cursor position
* `options` **{Object}**
* `returns` **{String}**
* `choice` **{String|Object}**
* `returns` **{Object}**: Returns a choice object.
### [.addChoices](index.js#L76)
**Example**
Add an array of normalized `choice` objects to the `choices` array. This method is called in the constructor, but it can also be used to add choices after instantiation.
```js
choices.choice('blue');
```
### [.toChoice](index.js#L73)
Returns a normalized `choice` object.
**Params**
* `choices` **{Array|Object}**: One or more choices to add.
* `choice` **{Object|String}**
* `returns` **{Object}**

@@ -60,6 +66,7 @@ **Example**

```js
choices.addChoices(['a', 'b', 'c']);
choices.toChoice('foo');
choices.toChoice({name: 'foo'});
```
### [.addChoice](index.js#L96)
### [.addChoice](index.js#L93)

@@ -75,13 +82,12 @@ Add a normalized `choice` object to the `choices` array.

```js
choices.addChoice(['a', 'b', 'c']);
choices.addChoice(['foo', 'bar', 'baz']);
```
### [.choice](index.js#L128)
### [.addChoices](index.js#L117)
Create a new `Choice` object.
Add an array of normalized `choice` objects to the `choices` array. This method is called in the constructor, but it can also be used to add choices after instantiation.
**Params**
* `choice` **{String|Object}**
* `returns` **{Object}**: Returns a choice object.
* `choices` **{Array|Object}**: One or more choices to add.

@@ -91,13 +97,13 @@ **Example**

```js
choices.choice('blue');
choices.addChoices(['foo', 'bar', 'baz']);
```
### [.separator](index.js#L144)
### [.toGroups](index.js#L150)
Create a new `Separator` object. See [choices-separator](https://github.com/enquirer/choices-separator) for more details.
Create choice "groups" from the given choices object. ![choice groups](docs/prompt-groups.gif).
**Params**
* `separator` **{String}**: Optionally pass a string to use as the separator.
* `returns` **{Object}**: Returns a separator object.
* `choices` **{Object}**: (required) The value of each object must be an array of choices (strings or objects).
* `returns` **{Array}**: Returns an array of normalized choice objects.

@@ -107,13 +113,16 @@ **Example**

```js
choices.separator();
choices.toGroups({
foo: ['a', 'b', 'c'],
bar: ['d', 'e', 'f']
});
```
### [.hasChoice](index.js#L160)
### [.separator](index.js#L230)
Returns true if a choice exists.
Create a new `Separator` object. See [choices-separator](https://github.com/enquirer/choices-separator) for more details.
**Params**
* `val` **{Number}**: The index or key of the choice to check for.
* `returns` **{Boolean}**
* `separator` **{String}**: Optionally pass a string to use as the separator.
* `returns` **{Object}**: Returns a separator object.

@@ -123,14 +132,13 @@ **Example**

```js
choices.hasChoice(1);
choices.hasChoice('foo');
choices.separator();
```
### [.get](index.js#L175)
### [.hasChoice](index.js#L246)
Get the choice or separator object at the specified index.
Returns true if a choice exists.
**Params**
* `key` **{Number|String}**: The name or index of the object to get
* `returns` **{Object}**: Returns the specified choice
* `val` **{Number}**: The index or key of the choice to check for.
* `returns` **{Boolean}**

@@ -140,6 +148,7 @@ **Example**

```js
var choice = choices.get(1);
choices.hasChoice(1);
choices.hasChoice('foo');
```
### [.getChoice](index.js#L197)
### [.getChoice](index.js#L262)

@@ -160,3 +169,3 @@ Get a non-separator choice from the collection.

### [.getIndex](index.js#L219)
### [.getIndex](index.js#L284)

@@ -180,10 +189,10 @@ Get the index of a non-separator choice from the collection.

### [.action](index.js#L237)
### [.get](index.js#L302)
Call the given `method` on `choices.actions`
Get the choice or separator object at the specified index.
**Params**
* `method` **{String}**
* `pos` **{Number}**
* `key` **{Number|String}**: The name or index of the object to get
* `returns` **{Object}**: Returns the specified choice

@@ -193,6 +202,6 @@ **Example**

```js
choices.action('up', 1);
var choice = choices.get(1);
```
### [.check](index.js#L255)
### [.check](index.js#L322)

@@ -211,3 +220,3 @@ Check the choice at the given `idx`.

### [.uncheck](index.js#L280)
### [.uncheck](index.js#L347)

@@ -226,4 +235,24 @@ Disable the choice at the given `idx`.

### [.toggle](index.js#L307)
### [.isChecked](index.js#L378)
Returns true if a choice is checked.
**Params**
* `name` **{String|Number}**: Name or index of the choice.
* `returns` **{Boolean}**
**Example**
```js
var choices = new Choices(['foo', 'bar', 'baz']);
console.log(choices.isChecked('foo'));
//=> false
choices.check('foo');
console.log(choices.isChecked('foo'));
//=> true
```
### [.toggle](index.js#L397)
Toggle the choice at the given `idx`.

@@ -243,4 +272,14 @@

### [.where](index.js#L335)
### [.render](index.js#L486)
Render the current choice "line".
**Params**
* `position` **{Number}**: Cursor position
* `options` **{Object}**
* `returns` **{String}**
### [.where](index.js#L512)
Return choice values for choices that return truthy based

@@ -254,4 +293,14 @@ on the given `val`.

### [.isValidIndex](index.js#L381)
### [.isItem](index.js#L560)
Returns true if the given `choice` is a valid choice item, and
not a "group" or "radio" choice.
**Params**
* `key` **{String}**: Property name to use for plucking objects.
* `returns` **{Array}**: Plucked objects
### [.isValidIndex](index.js#L575)
Returns true if the given `index` is a valid choice index.

@@ -264,3 +313,3 @@

### [.key](index.js#L392)
### [.key](index.js#L586)

@@ -274,3 +323,3 @@ Return the `.key` property from the choice at the given index.

### [.pluck](index.js#L403)
### [.pluck](index.js#L597)

@@ -284,11 +333,11 @@ Pluck an object with the specified key from the choices collection.

### [.checked](index.js#L431)
### [.checked](index.js#L629)
Getter for getting the checked choices from the collection.
### [.length](index.js#L455)
### [.length](index.js#L671)
Getter for getting the length of the collection.
### [.Separator](index.js#L491)
### [.Separator](index.js#L691)

@@ -308,3 +357,3 @@ Create a new `Separator` object. See [choices-separator](https://github.com/enquirer/choices-separator) for more details.

### [.isChoices](index.js#L507)
### [.isChoices](index.js#L707)

@@ -327,3 +376,3 @@ Create a new `Separator` object. See [choices-separator](https://github.com/enquirer/choices-separator) for more details.

### [.isChoice](index.js#L526)
### [.isChoice](index.js#L726)

@@ -417,2 +466,2 @@ Create a new `Separator` object. See [choices-separator](https://github.com/enquirer/choices-separator) for more details.

_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on May 10, 2017._
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on May 21, 2017._
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc