diff --git a/.eslintrc.json b/.eslintrc.json index 9b7834a..1e19c82 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,6 +3,9 @@ "extends": "../../../_common/eslintrc.json", "env": {"node": true}, "rules": { + "no-var": "off", + "prefer-arrow-callback": "off", + "object-shorthand": "off", "no-underscore-dangle": [2, {"allow": ["_DBG_useExt", "_DBG_checkOptions", "_DBG_checkMethod", "_readlineSync", "_execFileSync", "_handle", "_flattenArray", "_getPhContent", "_DBG_set_useExt", "_DBG_set_checkOptions", "_DBG_set_checkMethod", "_DBG_clearHistory", "_questionNum", "_keyInYN", "_setOption"]}], "camelcase": 0 } diff --git a/lib/readline-sync.js b/lib/readline-sync.js index 3429eef..f34579d 100644 --- a/lib/readline-sync.js +++ b/lib/readline-sync.js @@ -42,10 +42,15 @@ var /* eslint-enable key-spacing */ }, - fdR = 'none', fdW, ttyR, isRawMode = false, - extHostPath, extHostArgs, tempdir, salt = 0, - lastInput = '', inputHistory = [], rawInput, - _DBG_useExt = false, _DBG_checkOptions = false, _DBG_checkMethod = false; + fdR = 'none', + isRawMode = false, + salt = 0, + lastInput = '', + inputHistory = [], + _DBG_useExt = false, + _DBG_checkOptions = false, + _DBG_checkMethod = false, + fdW, ttyR, extHostPath, extHostArgs, tempdir, rawInput; function getHostArgs(options) { // Send any text to crazy Windows shell safely. @@ -84,7 +89,8 @@ function getHostArgs(options) { function _execFileSync(options, execOptions) { function getTempfile(name) { - var filepath, suffix = '', fd; + var suffix = '', + filepath, fd; tempdir = tempdir || require('os').tmpdir(); while (true) { @@ -105,12 +111,13 @@ function _execFileSync(options, execOptions) { return filepath; } - var hostArgs, shellPath, shellArgs, res = {}, exitCode, extMessage, + var res = {}, pathStdout = getTempfile('readline-sync.stdout'), pathStderr = getTempfile('readline-sync.stderr'), pathExit = getTempfile('readline-sync.exit'), pathDone = getTempfile('readline-sync.done'), - crypto = require('crypto'), shasum, decipher, password; + crypto = require('crypto'), + hostArgs, shellPath, shellArgs, exitCode, extMessage, shasum, decipher, password; shasum = crypto.createHash(ALGORITHM_HASH); shasum.update('' + process.pid + (salt++) + Math.random()); @@ -179,15 +186,17 @@ function _execFileSync(options, execOptions) { } function readlineExt(options) { - var hostArgs, res = {}, extMessage, - execOptions = {env: process.env, encoding: options.encoding}; + var res = {}, + execOptions = {env: process.env, encoding: options.encoding}, + hostArgs, extMessage; if (!extHostPath) { if (IS_WIN) { if (process.env.PSModulePath) { // Windows PowerShell extHostPath = 'powershell.exe'; - extHostArgs = ['-ExecutionPolicy', 'Bypass', '-File', __dirname + '\\read.ps1']; // eslint-disable-line no-path-concat - } else { // Windows Script Host + extHostArgs = ['-ExecutionPolicy', 'Bypass', + '-File', __dirname + '\\read.ps1']; // eslint-disable-line no-path-concat + } else { // Windows Script Host extHostPath = 'cscript.exe'; extHostArgs = ['//nologo', __dirname + '\\read.cs.js']; // eslint-disable-line no-path-concat } @@ -241,9 +250,9 @@ function readlineExt(options) { encoding, bufferSize, print */ function _readlineSync(options) { - var input = '', displaySave = options.display, - silent = !options.display && - options.keyIn && options.hideEchoBack && !options.mask; + var input = '', + displaySave = options.display, + silent = !options.display && options.keyIn && options.hideEchoBack && !options.mask; function tryExt() { var res = readlineExt(options); @@ -334,9 +343,8 @@ function _readlineSync(options) { })(); (function() { // try read - var atEol, limit, - isCooked = !options.hideEchoBack && !options.keyIn, - buffer, reqSize, readSize, chunk, line; + var isCooked = !options.hideEchoBack && !options.keyIn, + atEol, limit, buffer, reqSize, readSize, chunk, line; rawInput = ''; // Node.js v0.10- returns an error if same mode is set. @@ -422,9 +430,12 @@ function _readlineSync(options) { })(); if (options.print && !silent) { - options.print(displaySave + (options.displayOnly ? '' : - (options.hideEchoBack ? (new Array(input.length + 1)).join(options.mask) - : input) + '\n'), // must at least write '\n' + options.print( + displaySave + ( + options.displayOnly ? '' : ( + options.hideEchoBack ? (new Array(input.length + 1)).join(options.mask) : input + ) + '\n' // must at least write '\n' + ), options.encoding); } @@ -435,9 +446,8 @@ function _readlineSync(options) { function flattenArray(array, validator) { var flatArray = []; function _flattenArray(array) { - if (array == null) { - return; - } else if (Array.isArray(array)) { + if (array == null) { return; } + if (Array.isArray(array)) { array.forEach(_flattenArray); } else if (!validator || validator(array)) { flatArray.push(array); @@ -488,8 +498,9 @@ function margeOptions() { var value; if (!optionsPart.hasOwnProperty(optionName)) { return; } value = optionsPart[optionName]; + /* eslint-disable no-multi-spaces */ switch (optionName) { - // _readlineSync <- * * -> defaultOptions + // _readlineSync <- * * -> defaultOptions // ================ string case 'mask': // * * case 'limitMessage': // * @@ -540,6 +551,7 @@ function margeOptions() { break; // no default } + /* eslint-enable no-multi-spaces */ }); return options; }, {}); @@ -548,8 +560,8 @@ function margeOptions() { function isMatched(res, comps, caseSensitive) { return comps.some(function(comp) { var type = typeof comp; - return type === 'string' ? - (caseSensitive ? res === comp : res.toLowerCase() === comp.toLowerCase()) : + return type === 'string' + ? (caseSensitive ? res === comp : res.toLowerCase() === comp.toLowerCase()) : type === 'number' ? parseFloat(res) === comp : type === 'function' ? comp(res) : comp instanceof RegExp ? comp.test(res) : false; @@ -559,7 +571,7 @@ function isMatched(res, comps, caseSensitive) { function replaceHomePath(path, expand) { var homePath = pathUtil.normalize( IS_WIN ? (process.env.HOMEDRIVE || '') + (process.env.HOMEPATH || '') : - process.env.HOME || '').replace(/[\/\\]+$/, ''); + process.env.HOME || '').replace(/[/\\]+$/, ''); path = pathUtil.normalize(path); return expand ? path.replace(/^~(?=\/|\\|$)/, homePath) : path.replace(new RegExp('^' + escapePattern(homePath) + @@ -582,7 +594,11 @@ function replacePlaceholder(text, generator) { } function array2charlist(array, caseSensitive, collectSymbols) { - var values, group = [], groupClass = -1, charCode = 0, symbols = '', suppressed; + var group = [], + groupClass = -1, + charCode = 0, + symbols = '', + values, suppressed; function addGroup(groups, group) { if (group.length > 3) { // ellipsis groups.push(group[0] + '...' + group[group.length - 1]); @@ -593,29 +609,29 @@ function array2charlist(array, caseSensitive, collectSymbols) { return groups; } - values = array.reduce( - function(chars, value) { return chars.concat((value + '').split('')); }, []) - .reduce(function(groups, curChar) { - var curGroupClass, curCharCode; - if (!caseSensitive) { curChar = curChar.toLowerCase(); } - curGroupClass = /^\d$/.test(curChar) ? 1 : - /^[A-Z]$/.test(curChar) ? 2 : /^[a-z]$/.test(curChar) ? 3 : 0; - if (collectSymbols && curGroupClass === 0) { - symbols += curChar; + values = array.reduce(function(chars, value) { + return chars.concat((value + '').split('')); + }, []).reduce(function(groups, curChar) { + var curGroupClass, curCharCode; + if (!caseSensitive) { curChar = curChar.toLowerCase(); } + curGroupClass = /^\d$/.test(curChar) ? 1 : + /^[A-Z]$/.test(curChar) ? 2 : /^[a-z]$/.test(curChar) ? 3 : 0; + if (collectSymbols && curGroupClass === 0) { + symbols += curChar; + } else { + curCharCode = curChar.charCodeAt(0); + if (curGroupClass && curGroupClass === groupClass && + curCharCode === charCode + 1) { + group.push(curChar); } else { - curCharCode = curChar.charCodeAt(0); - if (curGroupClass && curGroupClass === groupClass && - curCharCode === charCode + 1) { - group.push(curChar); - } else { - groups = addGroup(groups, group); - group = [curChar]; - groupClass = curGroupClass; - } - charCode = curCharCode; + groups = addGroup(groups, group); + group = [curChar]; + groupClass = curGroupClass; } - return groups; - }, []); + charCode = curCharCode; + } + return groups; + }, []); values = addGroup(values, group); // last group if (symbols) { values.push(symbols); suppressed = true; } return {values: values, suppressed: suppressed}; @@ -626,7 +642,8 @@ function joinChunks(chunks, suppressed) { } function getPhContent(param, options) { - var text, values, resCharlist = {}, arg; + var resCharlist = {}, + text, values, arg; if (options.phContent) { text = options.phContent(param, options); } @@ -667,8 +684,7 @@ function getPhContent(param, options) { break; case 'limitCount': case 'limitCountNotZero': - text = options[options.hasOwnProperty('limitSrc') ? - 'limitSrc' : 'limit'].length; + text = options[options.hasOwnProperty('limitSrc') ? 'limitSrc' : 'limit'].length; text = text || param !== 'limitCountNotZero' ? text + '' : ''; break; case 'lastInput': @@ -702,7 +718,9 @@ function getPhContent(param, options) { } function getPhCharlist(param) { - var matches = /^(.)-(.)$/.exec(param), text = '', from, to, code, step; + var matches = /^(.)-(.)$/.exec(param), + text = '', + from, to, code, step; if (!matches) { return null; } from = matches[1].charCodeAt(0); to = matches[2].charCodeAt(0); @@ -713,8 +731,10 @@ function getPhCharlist(param) { // cmd "arg" " a r g " "" 'a"r"g' "a""rg" "arg function parseCl(cl) { - var reToken = new RegExp(/(\s*)(?:("|')(.*?)(?:\2|$)|(\S+))/g), matches, - taken = '', args = [], part; + var reToken = new RegExp(/(\s*)(?:("|')(.*?)(?:\2|$)|(\S+))/g), + taken = '', + args = [], + matches, part; cl = cl.trim(); while ((matches = reToken.exec(cl))) { part = matches[3] || matches[4] || ''; @@ -756,7 +776,7 @@ function getValidLine(options) { if (options.defaultInput && !res) { res = options.defaultInput; } if (options.history) { - if ((matches = /^\s*\!(?:\!|-1)(:p)?\s*$/.exec(res))) { // `!!` `!-1` +`:p` + if ((matches = /^\s*!(?:!|-1)(:p)?\s*$/.exec(res))) { // `!!` `!-1` +`:p` histInput = inputHistory[0] || ''; if (matches[1]) { // only display forceNext = true; @@ -856,8 +876,9 @@ exports.keyIn = function(query, options) { readOptions.limitSrc = readOptions.limit.filter(function(value) { var type = typeof value; return type === 'string' || type === 'number'; - }) - .map(function(text) { return replacePlaceholder(text + '', getPhCharlist); }); + }).map(function(text) { + return replacePlaceholder(text + '', getPhCharlist); + }); // pattern readOptions.limit = escapePattern(readOptions.limitSrc.join('')); @@ -886,7 +907,7 @@ exports.questionEMail = function(query, options) { // -------- default hideEchoBack: false, // http://www.w3.org/TR/html5/forms.html#valid-e-mail-address - limit: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/, + limit: /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/, limitMessage: 'Input valid e-mail address, please.', trueValue: null, falseValue: null @@ -985,7 +1006,8 @@ exports.questionFloat = function(query, options) { exports.questionPath = function(query, options) { /* eslint-disable key-spacing */ - var validPath, error = '', + var error = '', + validPath, // before readOptions readOptions = margeOptions({ // -------- default hideEchoBack: false, @@ -1078,7 +1100,8 @@ exports.questionPath = function(query, options) { // props: preCheck, args, hRes, limit function getClHandler(commandHandler, options) { - var clHandler = {}, hIndex = {}; + var clHandler = {}, + hIndex = {}; if (typeof commandHandler === 'object') { Object.keys(commandHandler).forEach(function(cmd) { if (typeof commandHandler[cmd] === 'function') { @@ -1091,9 +1114,9 @@ function getClHandler(commandHandler, options) { cmdKey = clHandler.args[0] || ''; if (!options.caseSensitive) { cmdKey = cmdKey.toLowerCase(); } clHandler.hRes = - cmdKey !== '_' && hIndex.hasOwnProperty(cmdKey) ? - hIndex[cmdKey].apply(res, clHandler.args.slice(1)) : - hIndex.hasOwnProperty('_') ? hIndex._.apply(res, clHandler.args) : null; + cmdKey !== '_' && hIndex.hasOwnProperty(cmdKey) + ? hIndex[cmdKey].apply(res, clHandler.args.slice(1)) : + hIndex.hasOwnProperty('_') ? hIndex._.apply(res, clHandler.args) : null; return {res: res, forceNext: false}; }; if (!hIndex.hasOwnProperty('_')) { @@ -1106,8 +1129,8 @@ function getClHandler(commandHandler, options) { } else { clHandler.preCheck = function(res) { clHandler.args = parseCl(res); - clHandler.hRes = typeof commandHandler === 'function' ? - commandHandler.apply(res, clHandler.args) : true; // true for break loop + clHandler.hRes = typeof commandHandler === 'function' + ? commandHandler.apply(res, clHandler.args) : true; // true for break loop return {res: res, forceNext: false}; }; } @@ -1123,9 +1146,9 @@ exports.promptCL = function(commandHandler, options) { caseSensitive: false, history: true }, options), - // -------- forced - // trueValue, falseValue, keepWhitespace don't work. - // preCheck, limit (by clHandler) + // -------- forced + // trueValue, falseValue, keepWhitespace don't work. + // preCheck, limit (by clHandler) clHandler = getClHandler(commandHandler, readOptions); /* eslint-enable key-spacing */ readOptions.limit = clHandler.limit; @@ -1146,7 +1169,7 @@ exports.promptLoop = function(inputHandler, options) { }, options); /* eslint-enable key-spacing */ while (true) { if (inputHandler(exports.prompt(readOptions))) { break; } } - return; + // return; // nothing is returned }; exports.promptCLLoop = function(commandHandler, options) { @@ -1158,9 +1181,9 @@ exports.promptCLLoop = function(commandHandler, options) { caseSensitive: false, history: true }, options), - // -------- forced - // trueValue, falseValue, keepWhitespace don't work. - // preCheck, limit (by clHandler) + // -------- forced + // trueValue, falseValue, keepWhitespace don't work. + // preCheck, limit (by clHandler) clHandler = getClHandler(commandHandler, readOptions); /* eslint-enable key-spacing */ readOptions.limit = clHandler.limit; @@ -1169,7 +1192,7 @@ exports.promptCLLoop = function(commandHandler, options) { exports.prompt(readOptions); if (clHandler.hRes) { break; } } - return; + // return; // nothing is returned }; exports.promptSimShell = function(options) { @@ -1181,12 +1204,10 @@ exports.promptSimShell = function(options) { }, options, { // -------- forced prompt: (function() { - return IS_WIN ? - '$>' : + return IS_WIN ? '$>' : // 'user@host:cwd$ ' (process.env.USER || '') + - (process.env.HOSTNAME ? - '@' + process.env.HOSTNAME.replace(/\..*$/, '') : '') + + (process.env.HOSTNAME ? '@' + process.env.HOSTNAME.replace(/\..*$/, '') : '') + ':$$ '; })() })); @@ -1232,7 +1253,7 @@ exports.keyInPause = function(query, options) { })); // added: guide /* eslint-enable key-spacing */ - return; + // return; // nothing is returned }; exports.keyInSelect = function(items, query, options) { @@ -1253,7 +1274,10 @@ exports.keyInSelect = function(items, query, options) { } }), // added: guide, cancel - keylist = '', key2i = {}, charCode = 49 /* '1' */, display = '\n'; + keylist = '', + key2i = {}, + charCode = 49 /* '1' */, + display = '\n'; /* eslint-enable key-spacing */ if (!Array.isArray(items) || !items.length || items.length > 35) { throw '`items` must be Array (max length: 35).'; @@ -1270,8 +1294,8 @@ exports.keyInSelect = function(items, query, options) { keylist += '0'; key2i['0'] = -1; display += '[0] ' + - (options && options.cancel != null && typeof options.cancel !== 'boolean' ? - (options.cancel + '').trim() : 'CANCEL') + '\n'; + (options && options.cancel != null && typeof options.cancel !== 'boolean' + ? (options.cancel + '').trim() : 'CANCEL') + '\n'; } readOptions.limit = keylist; display += '\n';