question-cache
Advanced tools
+10
-13
@@ -16,3 +16,2 @@ 'use strict'; | ||
| var sessionAnswers = {}; | ||
| var forced = {}; | ||
@@ -55,2 +54,3 @@ /** | ||
| this.project = opts.project || utils.project(process.cwd()); | ||
| this.Question = opts.Question || Question; | ||
| this.data = opts.data || {}; | ||
@@ -129,3 +129,4 @@ this.cache = {}; | ||
| var question = new Question(name, val, options); | ||
| options = utils.merge({}, this.options, options); | ||
| var question = new this.Question(name, val, options); | ||
| debug('questions#set "%s"', name); | ||
@@ -417,5 +418,6 @@ | ||
| var questions = this.buildQueue(queue); | ||
| var answers = this.answers; | ||
| var self = this; | ||
| utils.async.reduce(questions, this.answers, function(answers, key, next) { | ||
| utils.eachSeries(questions, function(key, next) { | ||
| debug('asking question "%s"', key); | ||
@@ -429,4 +431,3 @@ | ||
| var options = question._options = question.opts(opts); | ||
| var val = question.answer(answers, data, self); | ||
| debug('using answer %j', val); | ||
| var val = question.getAnswer(answers, data, self); | ||
@@ -437,3 +438,4 @@ // emit question before building options | ||
| // get val again after emitting `ask` | ||
| val = question.answer(answers, data, self); | ||
| val = question.getAnswer(answers, data, self); | ||
| debug('using answer %j', val); | ||
@@ -447,2 +449,3 @@ // re-build options object after emitting ask, to allow | ||
| debug('skipping question "%s", using answer "%j"', key, val); | ||
| self.emit('answer', val, key, question, answers); | ||
| question.next(val, self, answers, next); | ||
@@ -454,8 +457,2 @@ return; | ||
| var isForced = force === true || utils.matchesKey(force, key); | ||
| if (!forced.hasOwnProperty(key)) { | ||
| forced[key] = true; | ||
| } else { | ||
| isForced = false; | ||
| } | ||
| if (!isForced && utils.isAnswer(val)) { | ||
@@ -501,3 +498,3 @@ debug('question "%s", using answer "%j"', key, val); | ||
| } | ||
| }, function(err, answers) { | ||
| }, function(err) { | ||
| if (err) return cb(err); | ||
@@ -504,0 +501,0 @@ self.emit('answers', answers); |
+15
-6
@@ -64,3 +64,5 @@ /*! | ||
| if (typeof question.options.next === 'function') { | ||
| question.next = question.options.next.bind(question); | ||
| question.next = function() { | ||
| question.options.next.apply(question, arguments); | ||
| }; | ||
| return; | ||
@@ -140,2 +142,7 @@ } | ||
| Question.prototype.setAnswer = function(val) { | ||
| this.answer = val; | ||
| return this; | ||
| }; | ||
| /** | ||
@@ -157,3 +164,3 @@ * Resolve the answer for the question from the given data sources, then | ||
| Question.prototype.answer = function(answers, data, app) { | ||
| Question.prototype.getAnswer = function(answers, data, app) { | ||
| debug('looking for answer for: "%s"', this.name); | ||
@@ -176,3 +183,3 @@ | ||
| // app.store, if one exists | ||
| if (app.store && typeof answer === 'undefined') { | ||
| if (typeof answer === 'undefined' && app.store) { | ||
| answer = app.store.get(this.name); | ||
@@ -182,3 +189,3 @@ debug('answer:store.get %j', util.inspect(answer)); | ||
| // app.globals store, if one exists | ||
| if (app.globals && typeof answer === 'undefined' && this.options.global === true) { | ||
| if (typeof answer === 'undefined' && this.options.global === true && app.globals) { | ||
| answer = app.globals.get(this.name); | ||
@@ -188,4 +195,5 @@ debug('answer:globals.get %j', util.inspect(answer)); | ||
| // if `type` is checkbox, return now. we don't want to set hints for checkboxes | ||
| if (this.type === 'checkbox') { | ||
| if (this.type === 'checkbox' || this.options.hints === false) { | ||
| debug('returning answer: %j', answer); | ||
| this.setAnswer(answer); | ||
| return answer; | ||
@@ -198,3 +206,3 @@ } | ||
| // app.hints store, if one exists | ||
| if (app.hints && typeof this.default === 'undefined') { | ||
| if (typeof this.default === 'undefined' && app.hints) { | ||
| this.default = app.hints.get(this.name); | ||
@@ -205,2 +213,3 @@ debug('default:hint %j', util.inspect(this.default)); | ||
| debug('returning answer: %j', answer); | ||
| this.setAnswer(answer); | ||
| return answer; | ||
@@ -207,0 +216,0 @@ }; |
+1
-1
@@ -13,3 +13,3 @@ 'use strict'; | ||
| require('arr-union', 'union'); | ||
| require('async'); | ||
| require('async-each-series', 'eachSeries'); | ||
| require('define-property', 'define'); | ||
@@ -16,0 +16,0 @@ require('get-value', 'get'); |
+35
-16
| { | ||
| "name": "question-cache", | ||
| "description": "A wrapper around inquirer that makes it easy to create and selectively reuse questions.", | ||
| "version": "0.4.0", | ||
| "version": "0.5.0", | ||
| "homepage": "https://github.com/jonschlinkert/question-cache", | ||
@@ -13,4 +13,7 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
| "files": [ | ||
| "LICENSE", | ||
| "README.md", | ||
| "index.js", | ||
| "lib" | ||
| "lib", | ||
| "utils.js" | ||
| ], | ||
@@ -24,19 +27,19 @@ "main": "index.js", | ||
| "arr-union": "^3.1.0", | ||
| "async": "1.5.2", | ||
| "async-each-series": "^1.1.0", | ||
| "debug": "^2.2.0", | ||
| "define-property": "^0.2.5", | ||
| "get-value": "^2.0.5", | ||
| "get-value": "^2.0.6", | ||
| "has-value": "^0.3.1", | ||
| "inquirer2": "^0.1.1", | ||
| "is-answer": "^0.1.0", | ||
| "isobject": "^2.0.0", | ||
| "lazy-cache": "^1.0.3", | ||
| "isobject": "^2.1.0", | ||
| "lazy-cache": "^2.0.1", | ||
| "mixin-deep": "^1.1.3", | ||
| "omit-empty": "^0.3.6", | ||
| "option-cache": "^3.3.5", | ||
| "omit-empty": "^0.4.1", | ||
| "option-cache": "^3.4.0", | ||
| "os-homedir": "^1.0.1", | ||
| "project-name": "^0.2.4", | ||
| "project-name": "^0.2.5", | ||
| "set-value": "^0.3.3", | ||
| "to-choices": "^0.2.0", | ||
| "use": "^1.1.2" | ||
| "use": "^2.0.0" | ||
| }, | ||
@@ -46,10 +49,10 @@ "devDependencies": { | ||
| "ansi-red": "^0.1.1", | ||
| "gulp": "^3.9.0", | ||
| "gulp-eslint": "^1.0.0", | ||
| "gulp-format-md": "^0.1.7", | ||
| "gulp-istanbul": "^0.10.2", | ||
| "gulp-mocha": "^2.1.3", | ||
| "gulp": "^3.9.1", | ||
| "gulp-eslint": "^3.0.1", | ||
| "gulp-format-md": "^0.1.9", | ||
| "gulp-istanbul": "^1.0.0", | ||
| "gulp-mocha": "^2.2.0", | ||
| "gulp-unused": "^0.1.2", | ||
| "helper-example": "^0.1.0", | ||
| "mocha": "^2.4.5" | ||
| "mocha": "^2.5.3" | ||
| }, | ||
@@ -59,9 +62,24 @@ "keywords": [ | ||
| "ask", | ||
| "cache", | ||
| "cli", | ||
| "command", | ||
| "command-line", | ||
| "console", | ||
| "create", | ||
| "generate", | ||
| "generator", | ||
| "generators", | ||
| "init", | ||
| "inquirer", | ||
| "menu", | ||
| "project", | ||
| "prompt", | ||
| "prompts", | ||
| "question", | ||
| "questions", | ||
| "scaffold", | ||
| "stdin", | ||
| "store", | ||
| "terminal", | ||
| "tty", | ||
| "util", | ||
@@ -92,2 +110,3 @@ "yeoman" | ||
| "verb", | ||
| "verb-generate-readme", | ||
| "yeoman" | ||
@@ -94,0 +113,0 @@ ], |
-547
| # question-cache [](https://www.npmjs.com/package/question-cache) [](https://npmjs.org/package/question-cache) [](https://travis-ci.org/jonschlinkert/question-cache) | ||
| > A wrapper around inquirer that makes it easy to create and selectively reuse questions. | ||
| ## Install | ||
| Install with [npm](https://www.npmjs.com/): | ||
| ```sh | ||
| $ npm install question-cache --save | ||
| ``` | ||
| ## Example | ||
| ```js | ||
| var questions = require('question-cache'); | ||
| questions() | ||
| .set('first', 'What is your first name?') | ||
| .set('last', 'What is your last name?') | ||
| .ask(function(err, answers) { | ||
| console.log(answers); | ||
| }); | ||
| ``` | ||
| **Screen capture** | ||
| <img width="669" alt="screen shot 2015-07-13 at 8 05 20 am" src="https://cloud.githubusercontent.com/assets/383994/8649221/00ecc908-2936-11e5-88d2-b1ab75a53ba0.png"> | ||
| See the [working examples](./examples). | ||
| ## Basic Usage | ||
| See the [working examples](./examples). | ||
| ```js | ||
| var questions = require('question-cache')(); | ||
| // question type "input" is used by default | ||
| questions | ||
| .set('name', 'What is your name?') | ||
| .ask('name', function (err, answers) { | ||
| console.log(answers); | ||
| }); | ||
| ``` | ||
| **[inquirer2](https://github.com/jonschlinkert/inquirer2)** | ||
| You may optionally pass your own instance of inquirer to the constructor: | ||
| ```js | ||
| // on the options | ||
| var questions = require('question-cache'); | ||
| var questions = new Questions({ | ||
| inquirer: require('inquirer2') | ||
| }); | ||
| // or if inquirer is the only thing passed | ||
| var questions = new Questions(require('inquirer2')); | ||
| ``` | ||
| ## Getting started | ||
| question-cache is a wrapper around [inquirer2](https://github.com/jonschlinkert/inquirer2). If you have any issues related to the interface (like scrolling, colors, styling, etc), then please create an issue on the [inquirer2](https://github.com/jonschlinkert/inquirer2) project. | ||
| **Asking questions** | ||
| The simplest way to ask a question is by passing a string and a callback: | ||
| ```js | ||
| questions.ask('name', function (err, answers) { | ||
| console.log(answers); | ||
| }); | ||
| ``` | ||
| **Ask all cached questions** | ||
| ```js | ||
| questions.ask(function (err, answers) { | ||
| console.log(answers); | ||
| }); | ||
| ``` | ||
| ## API | ||
| ### [Questions](index.js#L28) | ||
| Create an instance of `Questions` with the given `options`. | ||
| **Params** | ||
| * `options` **{Object}**: question cache options | ||
| **Example** | ||
| ```js | ||
| var Questions = new Questions(options); | ||
| ``` | ||
| ### [.set](index.js#L90) | ||
| Calls [addQuestion](#addQuestion), with the only difference being that `.set` returns the `questions` instance and `.addQuestion` returns the question object. So use `.set` if you want to chain questions, or `.addQuestion` if you need the created question object. | ||
| **Params** | ||
| * `name` **{Object|String}**: Question name, message (string), or question/options object. | ||
| * `value` **{Object|String}**: Question message (string), or question/options object. | ||
| * `options` **{Object|String}**: Question/options object. | ||
| **Example** | ||
| ```js | ||
| questions | ||
| .set('drink', 'What is your favorite beverage?') | ||
| .set('color', 'What is your favorite color?') | ||
| .set('season', 'What is your favorite season?'); | ||
| // or | ||
| questions.set('drink', { | ||
| type: 'input', | ||
| message: 'What is your favorite beverage?' | ||
| }); | ||
| // or | ||
| questions.set({ | ||
| name: 'drink' | ||
| type: 'input', | ||
| message: 'What is your favorite beverage?' | ||
| }); | ||
| ``` | ||
| ### [.addQuestion](index.js#L122) | ||
| Add a question to be asked at a later point. Creates an instance of [Question](#question), so any `Question` options or settings may be used. Also, the default `type` is `input` if not defined by the user. | ||
| **Params** | ||
| * `name` **{Object|String}**: Question name, message (string), or question/options object. | ||
| * `value` **{Object|String}**: Question message (string), or question/options object. | ||
| * `options` **{Object|String}**: Question/options object. | ||
| **Example** | ||
| ```js | ||
| questions.addQuestion('drink', 'What is your favorite beverage?'); | ||
| // or | ||
| questions.addQuestion('drink', { | ||
| type: 'input', | ||
| message: 'What is your favorite beverage?' | ||
| }); | ||
| // or | ||
| questions.addQuestion({ | ||
| name: 'drink' | ||
| type: 'input', | ||
| message: 'What is your favorite beverage?' | ||
| }); | ||
| ``` | ||
| ### [.choices](index.js#L158) | ||
| Create a "choices" question from an array of values. | ||
| **Params** | ||
| * `key` **{String}**: Question key | ||
| * `msg` **{String}**: Question message | ||
| * `items` **{Array}**: Choice items | ||
| * `options` **{Object|Function}**: Question options or callback function | ||
| * `callback` **{Function}**: callback function | ||
| **Example** | ||
| ```js | ||
| questions.choices('foo', ['a', 'b', 'c']); | ||
| // or | ||
| questions.choices('foo', { | ||
| message: 'Favorite letter?', | ||
| choices: ['a', 'b', 'c'] | ||
| }); | ||
| ``` | ||
| ### [.list](index.js#L189) | ||
| Create a "list" question from an array of values. | ||
| **Params** | ||
| * `key` **{String}**: Question key | ||
| * `msg` **{String}**: Question message | ||
| * `list` **{Array}**: List items | ||
| * `queue` **{String|Array}**: Name or array of question names. | ||
| * `options` **{Object|Function}**: Question options or callback function | ||
| * `callback` **{Function}**: callback function | ||
| **Example** | ||
| ```js | ||
| questions.list('foo', ['a', 'b', 'c']); | ||
| // or | ||
| questions.list('foo', { | ||
| message: 'Favorite letter?', | ||
| choices: ['a', 'b', 'c'] | ||
| }); | ||
| ``` | ||
| ### [.rawlist](index.js#L220) | ||
| Create a "rawlist" question from an array of values. | ||
| **Params** | ||
| * `key` **{String}**: Question key | ||
| * `msg` **{String}**: Question message | ||
| * `list` **{Array}**: List items | ||
| * `queue` **{String|Array}**: Name or array of question names. | ||
| * `options` **{Object|Function}**: Question options or callback function | ||
| * `callback` **{Function}**: callback function | ||
| **Example** | ||
| ```js | ||
| questions.rawlist('foo', ['a', 'b', 'c']); | ||
| // or | ||
| questions.rawlist('foo', { | ||
| message: 'Favorite letter?', | ||
| choices: ['a', 'b', 'c'] | ||
| }); | ||
| ``` | ||
| ### [.expand](index.js#L251) | ||
| Create an "expand" question from an array of values. | ||
| **Params** | ||
| * `key` **{String}**: Question key | ||
| * `msg` **{String}**: Question message | ||
| * `list` **{Array}**: List items | ||
| * `queue` **{String|Array}**: Name or array of question names. | ||
| * `options` **{Object|Function}**: Question options or callback function | ||
| * `callback` **{Function}**: callback function | ||
| **Example** | ||
| ```js | ||
| questions.expand('foo', ['a', 'b', 'c']); | ||
| // or | ||
| questions.expand('foo', { | ||
| message: 'Favorite letter?', | ||
| choices: ['a', 'b', 'c'] | ||
| }); | ||
| ``` | ||
| ### [.confirm](index.js#L278) | ||
| Create a "choices" question from an array of values. | ||
| **Params** | ||
| * `queue` **{String|Array}**: Name or array of question names. | ||
| * `options` **{Object|Function}**: Question options or callback function | ||
| * `callback` **{Function}**: callback function | ||
| **Example** | ||
| ```js | ||
| questions.choices('foo', ['a', 'b', 'c']); | ||
| // or | ||
| questions.choices('foo', { | ||
| message: 'Favorite letter?', | ||
| choices: ['a', 'b', 'c'] | ||
| }); | ||
| ``` | ||
| ### [.get](index.js#L297) | ||
| Get question `name`, or group `name` if question is not found. You can also do a direct lookup using `quesions.cache['foo']`. | ||
| **Params** | ||
| * `name` **{String}** | ||
| * `returns` **{Object}**: Returns the question object. | ||
| **Example** | ||
| ```js | ||
| var name = questions.get('name'); | ||
| //=> question object | ||
| ``` | ||
| ### [.has](index.js#L313) | ||
| Returns true if `questions.cache` or `questions.groups` has question `name`. | ||
| * `returns` **{String}**: The name of the question to check | ||
| **Example** | ||
| ```js | ||
| var name = questions.has('name'); | ||
| //=> true | ||
| ``` | ||
| ### [.del](index.js#L338) | ||
| Delete the given question or any questions that have the given namespace using dot-notation. | ||
| * `returns` **{String}**: The name of the question to delete | ||
| **Example** | ||
| ```js | ||
| questions.del('name'); | ||
| questions.get('name'); | ||
| //=> undefined | ||
| // using dot-notation | ||
| questions.del('author'); | ||
| questions.get('author.name'); | ||
| //=> undefined | ||
| ``` | ||
| ### [.clearAnswers](index.js#L356) | ||
| Clear all cached answers. | ||
| **Example** | ||
| ```js | ||
| questions.clearAnswers(); | ||
| ``` | ||
| ### [.clearQuestions](index.js#L371) | ||
| Clear all questions from the cache. | ||
| **Example** | ||
| ```js | ||
| questions.clearQuestions(); | ||
| ``` | ||
| ### [.clear](index.js#L386) | ||
| Clear all cached questions and answers. | ||
| **Example** | ||
| ```js | ||
| questions.clear(); | ||
| ``` | ||
| ### [.ask](index.js#L405) | ||
| Ask one or more questions, with the given `options` and callback. | ||
| **Params** | ||
| * `queue` **{String|Array}**: Name or array of question names. | ||
| * `options` **{Object|Function}**: Question options or callback function | ||
| * `callback` **{Function}**: callback function | ||
| **Example** | ||
| ```js | ||
| questions.ask(['name', 'description'], function(err, answers) { | ||
| console.log(answers); | ||
| }); | ||
| ``` | ||
| ### [.normalize](index.js#L531) | ||
| Normalize the given value to return an array of question keys. | ||
| **Params** | ||
| * **{[type]}**: key | ||
| * `returns` **{[type]}** | ||
| ## Dot notation | ||
| See the [working examples](./examples). | ||
| Qestions may be cached using object-path notatation (e.g. `a.b.c`). | ||
| **Example** | ||
| All of the following will be cached on the `name` object: | ||
| ```js | ||
| questions | ||
| .set('name.first', 'What is your first name?') | ||
| .set('name.middle', 'What is your middle name?') | ||
| .set('name.last', 'What is your last name?') | ||
| ``` | ||
| **Dot notation usage** | ||
| When cached using dot-notation, there are a few different ways questions that may be asked. | ||
| ### Dot notation usage | ||
| #### ask one | ||
| Ask a single `name` question: | ||
| ```js | ||
| questions.ask('name.first', function (err, answers) { | ||
| console.log(answers); | ||
| }); | ||
| ``` | ||
| #### ask all "name" questions | ||
| Ask all `name` questions, `first`, `middle` and `last`: | ||
| ```js | ||
| questions.ask('name', function (err, answers) { | ||
| console.log(answers); | ||
| }); | ||
| ``` | ||
| #### array of questions | ||
| Ask specific questions on `name`: | ||
| ```js | ||
| questions.ask(['name.first', 'name.last'], function (err, answers) { | ||
| console.log(answers); | ||
| }); | ||
| ``` | ||
| #### ask all questions | ||
| Ask specific questions on `name`: | ||
| ```js | ||
| questions | ||
| .set('name.first', { | ||
| message: 'What is your first name?', | ||
| }) | ||
| .set('name.last', { | ||
| message: 'What is your last name?', | ||
| }) | ||
| .set('foo', { | ||
| message: 'Any thoughts about foo?', | ||
| }) | ||
| questions.ask(['name', 'foo'], function (err, answers) { | ||
| console.log(answers); | ||
| }); | ||
| ``` | ||
| #### nested questions | ||
| Ask one question at a time, based on feedback: | ||
| ```js | ||
| questions.ask('name.first', function (err, answers) { | ||
| console.log(answers); | ||
| //=> {name: { first: 'Brian' }} | ||
| questions.ask('name.last', function (err, answers) { | ||
| console.log(answers); | ||
| //=> {name: { last: 'Woodward' }} | ||
| }); | ||
| }); | ||
| ``` | ||
| ## More examples | ||
| ### Mixture of dot notation and non-dot-notation | ||
| Given you have the following questions: | ||
| ```js | ||
| questions | ||
| .set('name.first', 'What is your first name?') | ||
| .set('name.last', 'What is your last name?') | ||
| .set('foo', 'Any thoughts about foo?') | ||
| .set('bar', 'Any thoughts about bar?') | ||
| ``` | ||
| The following will ask questions: `name.first`, `name.last` and `foo` | ||
| ```js | ||
| questions.ask(['name', 'foo'], function (err, answers) { | ||
| console.log(answers); | ||
| }); | ||
| ``` | ||
| ## Related projects | ||
| You might also be interested in these projects: | ||
| * [ask-for-github-auth](https://www.npmjs.com/package/ask-for-github-auth): Prompt a user for their github authentication credentials and save the results. | [homepage](https://github.com/doowb/ask-for-github-auth) | ||
| * [ask-once](https://www.npmjs.com/package/ask-once): Only ask a question one time and store the answer. | [homepage](https://github.com/doowb/ask-once) | ||
| * [generate](https://www.npmjs.com/package/generate): Fast, composable, highly extendable project generator with a user-friendly and expressive API. | [homepage](https://github.com/generate/generate) | ||
| * [question-helper](https://www.npmjs.com/package/question-helper): Template helper that asks a question in the command line and resolves the template with… [more](https://www.npmjs.com/package/question-helper) | [homepage](https://github.com/doowb/question-helper) | ||
| ## Contributing | ||
| Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/question-cache/issues/new). | ||
| ## Building docs | ||
| Generate readme and API documentation with [verb](https://github.com/verbose/verb): | ||
| ```sh | ||
| $ npm install verb && npm run docs | ||
| ``` | ||
| Or, if [verb](https://github.com/verbose/verb) is installed globally: | ||
| ```sh | ||
| $ verb | ||
| ``` | ||
| ## Running tests | ||
| Install dev dependencies: | ||
| ```sh | ||
| $ npm install -d && npm test | ||
| ``` | ||
| ## Author | ||
| **Jon Schlinkert** | ||
| * [github/jonschlinkert](https://github.com/jonschlinkert) | ||
| * [twitter/jonschlinkert](http://twitter.com/jonschlinkert) | ||
| ## License | ||
| Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). | ||
| Released under the [MIT license](https://github.com/jonschlinkert/question-cache/blob/master/LICENSE). | ||
| *** | ||
| _This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on April 13, 2016._ |
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
786
0.77%0
-100%25221
-32.41%5
-16.67%1
Infinity%0
-100%+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated
Updated
Updated