Comparing version 0.0.0 to 0.0.1
59
index.js
'use strict'; | ||
var readline = require('readline'); | ||
var read = require('read'); | ||
var promptly = module.exports; | ||
@@ -19,13 +19,18 @@ | ||
// Instantiate node's readline | ||
var rl = opts.rl; | ||
if (!rl) { | ||
rl = opts.rl = readline.createInterface({ | ||
input: opts.input || process.stdin, | ||
output: opts.output || process.stdout | ||
}); | ||
} | ||
// Setup read's options | ||
var readOpts = { | ||
prompt: message, | ||
stdin: opts.input || process.stdin, | ||
stdout: opts.output || process.stdout, | ||
silent: opts.silent | ||
}; | ||
// Use readline question | ||
rl.question(message, function (response) { | ||
read(readOpts, function (err, response) { | ||
// Ignore the error attribute | ||
// It is set on SIGINT or if timeout reached (we are not using timeout) | ||
if (err) { | ||
return; | ||
} | ||
// Trim? | ||
@@ -61,4 +66,2 @@ if (opts.trim) { | ||
rl.close(); | ||
delete opts.rl; | ||
e.retry = promptly.prompt.bind(promptly, message, opts, fn); | ||
@@ -72,3 +75,2 @@ | ||
// Everything ok | ||
rl.close(); | ||
fn(null, response); | ||
@@ -78,4 +80,21 @@ }); | ||
promptly.password = function () { | ||
// TODO: | ||
promptly.password = function (message, opts, fn) { | ||
// Arguments parsing | ||
if (typeof opts === 'function') { | ||
fn = opts; | ||
opts = {}; | ||
} else { | ||
opts = opts || {}; | ||
} | ||
// Set default options | ||
if (opts.silent === undefined) { | ||
opts.silent = true; | ||
} | ||
if (opts.trim === undefined) { | ||
opts.trim = false; | ||
} | ||
// Use prompt() | ||
promptly.prompt(message, opts, fn); | ||
}; | ||
@@ -120,3 +139,3 @@ | ||
// Use choose with true, false | ||
// Use choose() with true, false | ||
promptly.choose(message, [true, false], opts, fn); | ||
@@ -134,5 +153,2 @@ }; | ||
if (opts.retry === undefined) { | ||
opts.retry = true; | ||
} | ||
opts.validator = opts.validator || []; | ||
@@ -143,2 +159,7 @@ if (!Array.isArray(opts.validator)) { | ||
// Set the default options | ||
if (opts.retry === undefined) { | ||
opts.retry = true; | ||
} | ||
// Push the choice validator | ||
@@ -145,0 +166,0 @@ var validator = function (value) { |
{ | ||
"name": "promptly", | ||
"version": "0.0.0", | ||
"version": "0.0.1", | ||
"description": "Simple command line prompting utility", | ||
@@ -18,2 +18,5 @@ "main": "index.js", | ||
}, | ||
"bugs": { | ||
"url": "http://github.com/IndigoUnited/node-promptly/issues" | ||
}, | ||
"keywords": [ | ||
@@ -28,3 +31,6 @@ "prompt", | ||
"author": "IndigoUnited <hello@indigounited.com> (http://indigounited.com)", | ||
"license": "MIT" | ||
"license": "MIT", | ||
"dependencies": { | ||
"read": "~1.0.4" | ||
} | ||
} |
# promptly # | ||
--- | ||
Simple command line prompting utilify. | ||
Simple command line prompting utility. | ||
## Installation ## | ||
`$ npm install promptly` | ||
## API ## | ||
@@ -16,3 +19,3 @@ | ||
Prompts for a value, printing the `message` and waiting for the input. | ||
When done, calls `fn` with an `error` and `value`. | ||
When done, calls `fn` with `error` and `value`. | ||
@@ -28,4 +31,9 @@ Default options: | ||
'validator': null, | ||
// Automatically retry on error | ||
'retry': false | ||
// Automatically retry if a validator fails | ||
'retry': false, | ||
// Do not print what the user types | ||
'silent': false, | ||
// Input and output streams to read and write to | ||
'input': process.stdin, | ||
'output': process.stdout | ||
} | ||
@@ -47,14 +55,8 @@ ``` | ||
Example usages: | ||
Example usages | ||
Ask for a name. | ||
Ask for a name: | ||
```js | ||
promptly.prompt('name: ', function (err, value) { | ||
if (err) { | ||
console.log('invalid name'); | ||
// Manually call retry | ||
// The passed errors have a retry method to easily prompt again. | ||
return err.retry(); | ||
} | ||
promptly.prompt('Name: ', function (err, value) { | ||
// err is always null in this case, because no validators are set | ||
console.log(value); | ||
@@ -64,10 +66,26 @@ }); | ||
Ask for a name until it validates (non-empty value). | ||
Ask for a name with a constraint (non-empty value and length > 2): | ||
```js | ||
promptly.prompt('name: ', { retry: true }, function (err, value) { | ||
console.log(value); | ||
var validator = function (value) { | ||
if (value.length < 2) { | ||
throw new Error('Min length of 2'); | ||
} | ||
return value; | ||
}; | ||
promptly.prompt('Name: ', { validator: validator }, function (err, value) { | ||
if (err) { | ||
console.error('Invalid name'); | ||
// Manually call retry | ||
// The passed error have a retry method to easily prompt again. | ||
err.retry(); | ||
} | ||
console.log('Name is: ', value); | ||
}); | ||
``` | ||
Ask for a name until it validates (non-empty value and length > 2). | ||
Same as above but retry automatically: | ||
```js | ||
@@ -80,6 +98,7 @@ var validator = function (value) { | ||
return value; | ||
} | ||
}; | ||
promptly.prompt('name: ', { retry: true, validator: validator }, function (err, value) { | ||
console.log(value); | ||
promptly.prompt('Name: ', { validator: validator , retry: true}, function (err, value) { | ||
// err is always null because promptly will be prompting for a name until it validates | ||
console.log('Name is: ', value); | ||
}); | ||
@@ -89,11 +108,10 @@ ``` | ||
### .confirm(message, opts, fn) ### | ||
Ask the user to confirm something. | ||
Calls `fn` with an `error` and `value` (true or false). | ||
Calls `fn` with `error` and `value` (true or false). | ||
The available options are the same, except that `retry` defauls to `true`. | ||
Truthy values are: `y`, `yes`, `1` and `true`. | ||
Falsy values are `n`, `no`, `0` and `false`. | ||
The available options are the same, except that `retry` defaults to `true`. | ||
Truthy values are: `y`, `yes` and `1`. | ||
Falsy values are `n`, `no`, and `0`. | ||
Comparison is made in case insensitive way. | ||
@@ -104,3 +122,3 @@ | ||
```js | ||
promply.confirm('Are you sure? ', function (err, value) { | ||
promptly.confirm('Are you sure? ', function (err, value) { | ||
console.log('Answer: ', value); | ||
@@ -114,9 +132,10 @@ }); | ||
Ask the user to choose between multiple `choices` (array of choices). | ||
Calls `fn` with an `error` and `value` (true or false). | ||
Calls `fn` with `error` and `value` (true or false). | ||
The available options are the same, except that `retry` defauls to `true`. | ||
The available options are the same, except that `retry` defaults to `true`. | ||
Example usage: | ||
```js | ||
promply.choose('Do you want an apple or an orange? ', ['apple', 'orange'], function (err, value) { | ||
promptly.choose('Do you want an apple or an orange? ', ['apple', 'orange'], function (err, value) { | ||
console.log('Answer: ', value); | ||
@@ -130,10 +149,11 @@ }); | ||
Prompts for a password, printing the `message` and waiting for the input. | ||
When available, calls `fn` with an `error` and `value`. | ||
When available, calls `fn` with `error` and `value`. | ||
The available options are the same, except that `trim` defauls to `false`. | ||
The available options are the same, except that `trim` and `silent` defaults to `false`. | ||
Example usage: | ||
```js | ||
promply.password('password: ', function (err, value) { | ||
console.log('password is ' + value); | ||
promptly.password('Type a password: ', function (err, value) { | ||
console.log('Password is', value); | ||
}); | ||
@@ -140,0 +160,0 @@ ``` |
@@ -28,3 +28,3 @@ 'use strict'; | ||
it('should keep asking if no value is passed and not default was defined', function (next) { | ||
it('should keep asking if no value is passed and no default was defined', function (next) { | ||
stdout = ''; | ||
@@ -47,5 +47,5 @@ | ||
promptly.prompt('something: ', { 'default': 'yeaa' }, function (err, value) { | ||
promptly.prompt('something: ', { 'default': '' }, function (err, value) { | ||
expect(err).to.be(null); | ||
expect(value).to.be('yeaa'); | ||
expect(value).to.be(''); | ||
expect(stdout).to.contain('something: '); | ||
@@ -134,3 +134,3 @@ next(); | ||
promptly.prompt('something: ', { trim: true, validator: validator }, function (err, value) { | ||
promptly.prompt('something: ', { validator: validator }, function (err, value) { | ||
times++; | ||
@@ -145,2 +145,4 @@ | ||
expect(value).to.equal('yeaa'); | ||
expect(stdout).to.contain('something: '); | ||
expect(stdout.indexOf('something')).to.not.be(stdout.lastIndexOf('something')); | ||
next(); | ||
@@ -151,2 +153,24 @@ }); | ||
}); | ||
it('should automatically retry if a validator fails and retry is enabled', function (next) { | ||
stdout = ''; | ||
var validator = function (value) { | ||
if (value !== 'yeaa') { | ||
throw new Error('bla'); | ||
} | ||
return value; | ||
}; | ||
promptly.prompt('something: ', { validator: validator, retry: true }, function (err, value) { | ||
expect(stdout).to.contain('something: '); | ||
expect(stdout.indexOf('something')).to.not.be(stdout.lastIndexOf('something')); | ||
expect(value).to.equal('yeaa'); | ||
next(); | ||
}); | ||
process.stdin.emit('data', 'wtf\n'); | ||
process.stdin.emit('data', 'yeaa\n'); | ||
}); | ||
}); | ||
@@ -251,2 +275,32 @@ | ||
}); | ||
}); | ||
describe('password()', function () { | ||
it('should prompt the user silently', function (next) { | ||
stdout = ''; | ||
promptly.password('something: ', function (err, value) { | ||
expect(value).to.be('yeaa'); | ||
expect(stdout).to.contain('something: '); | ||
expect(stdout).to.not.contain('yeaa'); | ||
next(); | ||
}); | ||
process.stdin.emit('data', 'yeaa\n'); | ||
}); | ||
it('should not trim by default', function (next) { | ||
stdout = ''; | ||
promptly.password('something: ', function (err, value) { | ||
expect(value).to.be(' yeaa '); | ||
expect(stdout).to.contain('something: '); | ||
expect(stdout).to.not.contain(' yeaa '); | ||
next(); | ||
}); | ||
process.stdin.emit('data', ' yeaa \n'); | ||
}); | ||
}); |
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
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
20413
374
0
157
1
+ Addedread@~1.0.4
+ Addedmute-stream@0.0.8(transitive)
+ Addedread@1.0.7(transitive)