Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input validation #14

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,12 @@ The query to be displayed by the prompt.

The name of the attribute under which the prompt result will be saved, inside the returned object.

#### `validate`

- Type: `Array`

Contains a list of validators to run when user input is available. Specifying this is **optional**. For the sturucture of a validator please refer to [validation](#Input-Validation).

#### qoa.`input({ type, query, handle })`

- Type: `Function`
Expand Down Expand Up @@ -515,6 +521,12 @@ The query to be displayed by the prompt.

The name of the attribute under which the prompt result will be saved, inside the returned object.

#### `validate`

- Type: `Array`

Contains a list of validators to run when user input is available. Specifying this is **optional**. For the sturucture of a validator please refer to [validation](#Input-Validation).

#### qoa.`interactive({ type, query, handle, symbol, menu })`

- Type: `Function`
Expand Down Expand Up @@ -669,6 +681,12 @@ The query to be displayed by the prompt.

The name of the attribute under which the prompt result will be saved, inside the returned object.

#### `validate`

- Type: `Array`

Contains a list of validators to run when user input is available. Specifying this is **optional**. For the sturucture of a validator please refer to [validation](#Input-Validation).

#### qoa.`config({ prefix, underlineQuery })`

- Type: `Function`
Expand Down Expand Up @@ -723,6 +741,56 @@ Underline the query of each prompt.

Move the cursor to the top-left corner of the console and clear everything below it.

## Input validation

3 of the available prompts support input validation: `input`, `hidden` and `secure`.
A validator object consists of the following:

##### `name`

- Type: `String`

The name of the validator.

##### `validate`

- Type: `Function`

A function to validate the input. The first argument given to the function is the user input. The function should return either `true` or `false` to indicate the success/fail of the validation.

##### `warning`

- Type: `String`

The warning message to print, when the validation fails. This setting is **optional**.

#### Example
```js
const qoa = require('qoa');

const {log} = console;

const ps = [
{
type: 'input',
query: 'Type your username:',
handle: 'username',
validate: [
{
name: 'min_length_8',
validate: (answer) => answer.length >= 8,
warning: 'The input is less than 8 characters long',
}
]
},
];

qoa.prompt(ps).then(log);
//=> { username: 'user', username_validators: {min_length_8: false} }
```
As you can see, the validators appear in the result prefixed with the handle you specified. In this case `username_validators`.
This object contains every validator result, that was tested on the current answer, where the **key** is the name of the validator and the **value** is the result of the `validate` function.

## Development

For more info on how to contribute to the project, please read the [contributing guidelines](https://github.com/klaussinani/qoa/blob/master/contributing.md).
Expand Down
4 changes: 4 additions & 0 deletions src/hidden.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ class Hidden extends Text {
result[this._handle] = secret;
this._input.removeListener('keypress', onkeypress);
prompt.close();
if (this._validators.length > 0) {
result[this._handle + '_validators'] = this._validateInput(secret);
}

resolve(result);
});
});
Expand Down
4 changes: 4 additions & 0 deletions src/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ class Input extends Text {
prompt.question(this._formatQuery(), answer => {
result[this._handle] = answer;
prompt.close();
if (this._validators.length > 0) {
result[this._handle + '_validators'] = this._validateInput(answer);
}

resolve(result);
});
});
Expand Down
4 changes: 4 additions & 0 deletions src/secure.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ class Secure extends Text {
result[this._handle] = secret;
this._input.removeListener('keypress', onkeypress);
prompt.close();
if (this._validators.length > 0) {
result[this._handle + '_validators'] = this._validateInput(secret);
}

resolve(result);
});
});
Expand Down
15 changes: 15 additions & 0 deletions src/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class Text extends Prompt {
super(opts);
this._historySize = 0;
this._promptSymbol = '';
this._validators = opts.validate || [];
}

get _promptOpts() {
Expand All @@ -30,6 +31,20 @@ class Text extends Prompt {
_removeLastChar(x) {
return x.slice(0, x.length - 1);
}

_validateInput(answer) {
const result = {};
this._validators.forEach(validator => {
const validationResult = validator.validate(answer);
if (!validationResult && validator.warning) {
console.log(validator.warning);
}

result[validator.name] = validationResult;
});

return result;
}
}

module.exports = Text;