Comparing version 1.0.1 to 1.0.2
@@ -6,2 +6,3 @@ "use strict"; | ||
}); | ||
exports.c = c; | ||
exports.default = askQuestions; | ||
@@ -14,2 +15,9 @@ | ||
/** | ||
* Color foreground with grey | ||
* @param {string} t | ||
*/ | ||
function c(t) { | ||
return `\x1b[90m${t}\x1b[0m`; | ||
} | ||
/** | ||
* Ask a set of questions. | ||
@@ -22,2 +30,4 @@ * @param {object} questions An object with questions as values | ||
*/ | ||
async function askQuestions(questions, timeout) { | ||
@@ -51,19 +61,28 @@ if (typeof questions != 'object') { | ||
question.text = `${question.text}${question.text.endsWith('?') ? '' : ':'} `; | ||
let defaultValue; | ||
let gotDefaultValue; | ||
if (question.defaultValue) { | ||
question.text = `${question.text}[${question.defaultValue}] `; | ||
defaultValue = question.defaultValue; | ||
} | ||
let defaultValue; | ||
if (question.getDefault) { | ||
gotDefaultValue = await question.getDefault(); | ||
} | ||
if (typeof question.getDefault == 'function') { | ||
defaultValue = await question.getDefault(); | ||
question.text = `${question.text}[${defaultValue}] `; | ||
let dv = defaultValue || ''; | ||
if (defaultValue && gotDefaultValue && defaultValue != gotDefaultValue) { | ||
dv = c(defaultValue); | ||
} else if (defaultValue && defaultValue == gotDefaultValue) { | ||
dv = ''; | ||
} | ||
let gtd = gotDefaultValue || ''; | ||
const text = `${question.text}${dv ? `[${dv}] ` : ''}${gtd ? `[${gtd}] ` : ''}`; | ||
const { | ||
promise | ||
} = (0, _ask.default)(question.text, timeout); | ||
} = (0, _ask.default)(text, timeout); | ||
const a = await promise; | ||
let answer = a || defaultValue || question.defaultValue; | ||
let answer = a || gotDefaultValue || question.defaultValue; | ||
@@ -70,0 +89,0 @@ if (typeof question.validation == 'function') { |
@@ -1,8 +0,19 @@ | ||
## 1.0.1 (11 June 2018) | ||
## 26 June 2018 | ||
### 1.0.2 | ||
- [fix] Don't display same `defaultValue` to `getDefault` value, grey out `defaultValue` if `getDefault` takes precedence. | ||
- [doc] Start using `documentary`, split into files, document the `Question` type in a table. | ||
## 11 June 2018 | ||
### 1.0.1 | ||
- [build] build with source maps | ||
- [doc] document return type | ||
## 1.0.0 (9 June 2018) | ||
## 9 June 2018 | ||
### 1.0.0 | ||
- [ecma] update to modules | ||
@@ -13,9 +24,13 @@ - [api] change the api to allow to ask single questions. | ||
## 0.2.0 (31 May 2017) | ||
## 31 May 2017 | ||
### 0.2.0 | ||
- [feature] `askQuestions`: ask multiple questions. | ||
## 0.1.0 (23 May 2017) | ||
## 23 May 2017 | ||
### 0.1.0 | ||
- Create `reloquent`: reading from readline interface with a timeout | ||
- [repo]: `test`, `src`, `example`, `.eslintrc` |
{ | ||
"name": "reloquent", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "Ask user configurable questions via read-line.", | ||
@@ -10,3 +10,5 @@ "main": "build", | ||
"test-build": "BABEL_ENV=test-build zoroaster test/spec -b", | ||
"build": "babel src --out-dir build --source-maps", | ||
"b": "b --source-maps", | ||
"doc": "NODE_DEBUG=doc doc documentary -o README.md", | ||
"build": "yarn-s b doc", | ||
"e": "node example", | ||
@@ -16,3 +18,4 @@ "example/single.js": "yarn e example/single.js", | ||
"example/questions.js": "yarn e example/questions.js", | ||
"lint": "eslint ." | ||
"lint": "eslint .", | ||
"p": "git add documentary README.md; git commit -m t; git push;" | ||
}, | ||
@@ -41,11 +44,6 @@ "files": [ | ||
"devDependencies": { | ||
"@babel/cli": "7.0.0-beta.49", | ||
"@babel/core": "7.0.0-beta.49", | ||
"@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.49", | ||
"@babel/plugin-transform-modules-commonjs": "7.0.0-beta.49", | ||
"@babel/register": "7.0.0-beta.49", | ||
"babel-plugin-transform-rename-import": "2.2.0", | ||
"cross-env": "5.0.0", | ||
"eslint": "4.19.1", | ||
"documentary": "1.8.0", | ||
"eslint-config-artdeco": "1.0.0", | ||
"yarn-s": "1.1.0", | ||
"zoroaster": "2.1.0" | ||
@@ -52,0 +50,0 @@ }, |
181
README.md
# reloquent | ||
[![npm version](https://badge.fury.io/js/reloquent.svg)](https://badge.fury.io/js/reloquent) | ||
[![npm version](https://badge.fury.io/js/reloquent.svg)](https://npmjs.org/package/reloquent) | ||
`reloquent` allows to ask user a question, or a series of questions via the read-line interface. | ||
`reloquent` allows to ask users a question, or a series of questions via the read-line interface. | ||
@@ -11,2 +11,15 @@ ```sh | ||
- [API](#api) | ||
* [`Question` Type](#question-type) | ||
* [<strong><code>text</code></strong>](#text) | ||
* [<code>validation</code>](#validation) | ||
* [<code>postProcess</code>](#postprocess) | ||
* [<code>defaultValue</code>](#defaultvalue) | ||
* [<code>getDefault</code>](#getdefault) | ||
* [`async askSingle(question: string, timeout?: number): string`](#async-asksinglequestion-stringtimeout-number-string) | ||
* [`async askSingle(question: Question, timeout?: number): string`](#async-asksinglequestion-questiontimeout-number-string) | ||
* [`async ask(questions: <string, Question>, timeout?: number): object`](#async-askquestions-string-questiontimeout-number-object) | ||
- [Them Questions](#them-questions) | ||
## API | ||
@@ -16,27 +29,136 @@ | ||
- ask a single question as a string | ||
- ask a single question as an object | ||
- ask multiple questions | ||
- ask a single question as a string; | ||
- ask a single question as an object; | ||
- ask multiple questions. | ||
### Question | ||
Their respective methods can be required with the `import` statement: | ||
```js | ||
import ask, { askSingle } from 'reloquent' | ||
``` | ||
### `Question` Type | ||
When asking a question which is not a string, the `question` object should have the following structure: | ||
| Property | Type | Description | | ||
|--------------|----------------|-----------------------------------------------------------------------| | ||
| **text** | string | Display text. Required. | | ||
| validation | async function | A function which needs to throw an error if validation does not pass. | | ||
| postProcess | async function | A function to transform the answer. | | ||
| defaultValue | string | Default answer. | | ||
| getDefault | async function | A function to get default value. | | ||
<table> | ||
<tr> | ||
<th>Property</th> | ||
<th>Type</th> | ||
<th>Description</th> | ||
<th>Example</th> | ||
</tr> | ||
<tr> | ||
<td><a name="text"><strong><code>text</code></strong></a></td> | ||
<td><em>string</em></td> | ||
<td>Display text. Required.</td> | ||
<td> | ||
### `askSingle(question: string|Question, timeout?: number) => Promise.<string>` | ||
```js | ||
const q = { | ||
text: 'What is your name', | ||
} | ||
``` | ||
</td> | ||
</tr> | ||
Ask a question and wait for the answer. If a timeout is passed, the promise will expire after the specified number of milliseconds if answer was not given. | ||
<tr> | ||
<td><a name="validation"><code>validation</code></a></td> | ||
A question can be a simple string: | ||
<td><em>(async) function</em></td> | ||
<td>A function which needs to throw an error if validation does not pass.</td> | ||
<td> | ||
```js | ||
/* yarn example/string.js */ | ||
const q = { | ||
text: 'What is your name', | ||
validate(v) { | ||
if (!v.length) throw new Error('Name is required.') | ||
}, | ||
} | ||
``` | ||
</td> | ||
</tr> | ||
<tr> | ||
<td><a name="postprocess"><code>postProcess</code></a></td> | ||
<td><em>(async) function</em></td> | ||
<td>A function to transform the answer.</td> | ||
<td> | ||
```js | ||
const q = { | ||
text: 'What is your name', | ||
postProcess(v) { | ||
return `${v.toLowerCase()}` | ||
}, | ||
} | ||
``` | ||
</td> | ||
</tr> | ||
<tr> | ||
<td><a name="defaultvalue"><code>defaultValue</code></a></td> | ||
<td><em>string</em></td> | ||
<td> | ||
Default answer (shown to users in `[default]` brackets).</td> | ||
<td> | ||
```js | ||
const q = { | ||
text: 'What is your name', | ||
defaultValue: 'Visitor', | ||
} | ||
``` | ||
</td> | ||
</tr> | ||
<tr> | ||
<td><a name="getdefault"><code>getDefault</code></a></td> | ||
<td><em>(async) function</em></td> | ||
<td>A function to execute to obtain the default value.</td> | ||
<td> | ||
```js | ||
const q = { | ||
text: 'What is your name', | ||
async getDefault() { | ||
await git('config', 'user.name') | ||
}, | ||
} | ||
``` | ||
</td> | ||
</tr> | ||
</table> | ||
If both `defaultValue` and `getDefault` are provided, the result of the `getDefault` takes precedence: | ||
```js | ||
const q = { | ||
defaultValue: 'I desire it much', | ||
getDefault() { | ||
return 'I desire it much so' | ||
}, | ||
} | ||
``` | ||
![getDefault will get precedence](doc/precedence.gif) | ||
### `async askSingle(`<br/> `question: string,`<br/> `timeout?: number,`<br/>`): string` | ||
Ask a question as a string and wait for the answer. If a timeout is passed, the promise will expire after the specified number of milliseconds if answer was not given. | ||
```javascript | ||
import { askSingle } from 'reloquent' | ||
@@ -49,2 +171,3 @@ | ||
} catch (err) { | ||
console.log() | ||
console.log(err) | ||
@@ -61,9 +184,10 @@ console.log('Nevermind...') | ||
```fs | ||
I guess Art is the cause. | ||
You've answered: I guess Art is the cause. | ||
``` | ||
Or it can be an object: | ||
### `async askSingle(`<br/> `question: Question,`<br/> `timeout?: number,`<br/>`): string` | ||
```js | ||
/* yarn example/single.js */ | ||
Ask a question which is passed as an object of the [`Question`](#question-type) type, and return a string. | ||
```javascript | ||
import { askSingle } from 'reloquent' | ||
@@ -83,2 +207,5 @@ | ||
}, | ||
async getDefault() { | ||
return 'I desire it much so' | ||
}, | ||
}) | ||
@@ -97,8 +224,7 @@ console.log(answer) | ||
### `ask(questions: <string, Question>, timeout:number) => Promise.<object>` | ||
### `async ask(`<br/> `questions: <string, Question>,`<br/> `timeout?: number,`<br/>`): object` | ||
Ask a series of questions and transform them into answers. | ||
```js | ||
/* yarn example/questions.js */ | ||
```javascript | ||
import ask from 'reloquent' | ||
@@ -155,8 +281,7 @@ | ||
``` | ||
## Them Questions | ||
<!-- ## todo | ||
User interaction is important in the modern day applications. `reloquent` is an eloquent way to do this. | ||
* show timer on the right | ||
* accept other ios | ||
* reject when closed without answer --> | ||
[![Why you asking all them questions](http://img.youtube.com/vi/C1pkVrHKDik/0.jpg)](http://www.youtube.com/watch?v=C1pkVrHKDik) | ||
@@ -163,0 +288,0 @@ --- |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
22794
5
162
286