Add options.noEchoBack.

This commit is contained in:
anseki 2014-07-12 07:37:25 +09:00
parent 526e11c7e2
commit 055e4b3060
5 changed files with 77 additions and 46 deletions

View file

@ -30,18 +30,20 @@ Sets the prompt, for example when you run `node` on the command line, you see `>
### prompt ### prompt
```js ```js
line = readlineSync.prompt() line = readlineSync.prompt([options])
``` ```
Readies readline for input from the user, putting the current `setPrompt` options on a new line, giving the user a new spot to write. Readies readline for input from the user, putting the current `setPrompt` options on a new line, giving the user a new spot to write.
If `{noEchoBack: true}` is specified to `options`, echo back is avoided. It is used to hide the password which is typed by user on screen. *See [Note](#note) for security.*
### question ### question
```js ```js
line = readlineSync.question(query) line = readlineSync.question(query[, options])
``` ```
Displays the `query` to the user, and then returns the user's response after it has been typed. Displays the `query` to the user, and then returns the user's response after it has been typed.
If `{noEchoBack: true}` is specified to `options`, echo back is avoided. It is used to hide the password which is typed by user on screen. *See [Note](#note) for security.*
### setEncoding ### setEncoding
@ -74,7 +76,7 @@ readlineSync.setPrint(function(display, encoding) {
console.log('Your account required.'.grey); console.log('Your account required.'.grey);
user = readlineSync.question('USER NAME'.white.inverse + ': '); user = readlineSync.question('USER NAME'.white.inverse + ': ');
pw = readlineSync.question('PASSWORD'.white.inverse + ': ', true); pw = readlineSync.question('PASSWORD'.white.inverse + ': ', {noEchoBack: true});
// Authorization ... // Authorization ...
console.log(('Welcome, ' + user + '!').green.bold); console.log(('Welcome, ' + user + '!').green.bold);
@ -82,8 +84,8 @@ readlineSync.setPrompt('> '.bold.red);
cmd = readlineSync.prompt(); cmd = readlineSync.prompt();
``` ```
## Note ## <a name ="note">Note</a>
The your Node and OS may not support interactively reading from stdin. The stdin interfaces are different by platforms. + The your Node and OS may not support interactively reading from stdin. The stdin interfaces are different by platforms.
If in those platforms, an error is thrown. If in those platforms, an error is thrown.
```js ```js
@ -95,8 +97,11 @@ try {
} }
``` ```
+ If `options.noEchoBack` is used, the text that input by user is saved to temporary file (e.g. `/tmp/readline-sync.stdout`). This file is removed immediately after reading is done, but you have to be careful about it because this text is *plain*. Removing the file might fail, or the file might be peeped before it is removed.
## Release History ## Release History
* 2014-07-12 v0.3.0 Add setPrint(). * 2014-07-12 v0.4.0 Add `options.noEchoBack`.
* 2014-07-12 v0.3.0 Add `setPrint()`.
* 2014-06-27 v0.2.3 Add alternative reading via shell on the environment which don't support interactively reading. * 2014-06-27 v0.2.3 Add alternative reading via shell on the environment which don't support interactively reading.
* 2013-12-18 v0.2.2 Error handle for the environment which don't support interactively reading from stdin. * 2013-12-18 v0.2.2 Error handle for the environment which don't support interactively reading from stdin.
* 2013-08-30 v0.2.0 Rewrite exporting methods. * 2013-08-30 v0.2.0 Rewrite exporting methods.

View file

@ -1,6 +1,11 @@
@echo off @echo off
setlocal setlocal
set /p LINE=<CON >CON if "%1"=="noechoback" (
set /p LINE=<CON >NUL
echo; >CON
) else (
set /p LINE=<CON >CON
)
set /p DUM="%LINE%"<NUL set /p DUM="%LINE%"<NUL
endlocal endlocal
exit /b 0 exit /b 0

View file

@ -1,3 +1,10 @@
read LINE </dev/tty if [ "$1" = "noechoback" ]; then
stty -F /dev/tty -echo echonl
read LINE </dev/tty
stty -F /dev/tty echo -echonl
# printf '\n' >/dev/tty
else
read LINE </dev/tty
fi
printf '%s' "$LINE" printf '%s' "$LINE"
exit 0 exit 0

View file

@ -17,7 +17,7 @@ var promptText = '> ',
buffer = new Buffer(BUF_SIZE), buffer = new Buffer(BUF_SIZE),
useShell = true, print, tempdir; useShell = true, print, tempdir;
function _readlineSync(display) { function _readlineSync(display, options) {
var input = '', rsize, err; var input = '', rsize, err;
if (display) { if (display) {
@ -25,6 +25,16 @@ function _readlineSync(display) {
stdout.write(display, encoding); stdout.write(display, encoding);
} }
if (options && options.noEchoBack) { // Try reading via shell
input = _readlineShell(true);
if (typeof input !== 'string') {
if (display) { stdout.write('\n', encoding); } // Return from prompt line.
throw new Error('Can\'t read via shell');
}
} else {
stdin.resume(); stdin.resume();
while (true) { while (true) {
rsize = 0; rsize = 0;
@ -57,24 +67,28 @@ function _readlineSync(display) {
} }
stdin.pause(); stdin.pause();
}
return input.trim(); return input.trim();
} }
function _readlineShell() { function _readlineShell(noEchoBack) {
// piping via files instead of execSync (node v0.12+) // piping via files instead of execSync (node v0.12+)
var shellPath, args, shellStdout, var shellPath, args, shellStdout,
pathStdout = getTempfile('readline-sync.stdout'), pathStdout = getTempfile('readline-sync.stdout'),
pathStatus = getTempfile('readline-sync.status'), pathStatus = getTempfile('readline-sync.status'),
pathDone = getTempfile('readline-sync.done'); pathDone = getTempfile('readline-sync.done'),
optEchoBack = noEchoBack ? ' noechoback' : '';
if (process.platform === 'win32') { if (process.platform === 'win32') {
// The quote (") is escaped by node before parsed by shell. Then use ENV{Q}. // The quote (") is escaped by node before parsed by shell. Then use ENV{Q}.
shellPath = 'cmd.exe'; shellPath = 'cmd.exe';
args = ['/V:ON', '/S', '/C', '%Q%' + __dirname + '\\read.bat%Q% >%Q%' + pathStdout + args = ['/V:ON', '/S', '/C',
'%Q%' + __dirname + '\\read.bat%Q%' + optEchoBack + ' >%Q%' + pathStdout +
'%Q% & (echo !ERRORLEVEL!)>%Q%' + pathStatus + '%Q% & (echo 1)>%Q%' + pathDone + '%Q%']; '%Q% & (echo !ERRORLEVEL!)>%Q%' + pathStatus + '%Q% & (echo 1)>%Q%' + pathDone + '%Q%'];
} else { } else {
shellPath = '/bin/sh'; shellPath = '/bin/sh';
args = ['-c', '(' + shellPath + ' "' + __dirname + '/read.sh") >"' + pathStdout + args = ['-c', '(' + shellPath + ' "' + __dirname + '/read.sh"' + optEchoBack + ') >"' + pathStdout +
'"; echo $? >"' + pathStatus + '"; echo 1 >"' + pathDone + '"']; '"; echo $? >"' + pathStatus + '"; echo 1 >"' + pathDone + '"'];
} }
@ -133,10 +147,10 @@ exports.setEncoding = function(newEncoding) {
} }
}; };
exports.prompt = function() { exports.prompt = function(options) {
return _readlineSync(promptText); return _readlineSync(promptText, options);
}; };
exports.question = function(query) { exports.question = function(query, options) {
return _readlineSync(typeof query === 'string' ? query : ''); return _readlineSync(typeof query === 'string' ? query : '', options);
}; };

View file

@ -1,7 +1,7 @@
{ {
"name": "readline-sync", "name": "readline-sync",
"description": "Synchronous Readline", "description": "Synchronous Readline",
"version": "0.3.0", "version": "0.4.0",
"homepage": "https://github.com/anseki/readline-sync", "homepage": "https://github.com/anseki/readline-sync",
"author": { "author": {
"name": "anseki" "name": "anseki"