From e5f5067259ceeaf0b098d14bec910f87e58708c7 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 16 Oct 2022 13:40:18 -0700 Subject: [PATCH 01/10] [eslint] fix indentation and whitespace --- .eslintrc | 86 ++++------ README.md | 26 +-- index.js | 364 ++++++++++++++++++++--------------------- package.json | 144 ++++++++-------- test/all_bool.js | 48 +++--- test/bool.js | 192 +++++++++++----------- test/dash.js | 43 ++--- test/default_bool.js | 24 +-- test/dotted.js | 22 +-- test/long.js | 52 +++--- test/num.js | 56 +++---- test/parse.js | 313 ++++++++++++++++++----------------- test/parse_modified.js | 10 +- test/proto.js | 54 +++--- test/short.js | 110 ++++++------- test/whitespace.js | 8 +- 16 files changed, 764 insertions(+), 788 deletions(-) diff --git a/.eslintrc b/.eslintrc index 137f67b..7074004 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,54 +1,40 @@ { - "root": true, + "root": true, - "extends": "@ljharb/eslint-config/node/0.4", + "extends": "@ljharb/eslint-config/node/0.4", - "rules": { - "array-bracket-spacing": 0, - "array-element-newline": 0, - "brace-style": 1, - "camelcase": 1, - "comma-dangle": 1, - "comma-spacing": 1, - "complexity": 0, - "curly": 1, - "dot-notation": 1, - "eol-last": 1, - "func-style": 1, - "function-paren-newline": 1, - "indent": [1, 4], - "key-spacing": 1, - "max-lines-per-function": 0, - "max-nested-callbacks": 1, - "max-statements": 0, - "multiline-comment-style": 1, - "no-array-constructor": 1, - "no-continue": 1, - "no-div-regex": 1, - "no-extra-parens": 1, - "no-mixed-operators": 1, - "no-multi-spaces": 1, - "no-multiple-empty-lines": 1, - "no-param-reassign": 1, - "no-plusplus": 1, - "no-proto": 1, - "no-redeclare": 1, - "no-restricted-syntax": 1, - "no-shadow": 1, - "no-trailing-spaces": 1, - "no-unused-vars": 1, - "no-use-before-define": 1, - "object-curly-newline": 1, - "object-curly-spacing": 1, - "operator-linebreak": 1, - "quote-props": 1, - "quotes": 1, - "semi-style": 1, - "semi": 1, - "space-before-blocks": 1, - "space-before-function-paren": 1, - "space-infix-ops": 1, - "strict": 1, - "wrap-regex": 1, - }, + "rules": { + "array-element-newline": 0, + "camelcase": 1, + "comma-dangle": 1, + "complexity": 0, + "curly": 1, + "dot-notation": 1, + "func-style": 1, + "max-lines-per-function": 0, + "max-nested-callbacks": 1, + "max-statements": 0, + "multiline-comment-style": 0, + "no-array-constructor": 1, + "no-continue": 1, + "no-div-regex": 1, + "no-extra-parens": 1, + "no-mixed-operators": 1, + "no-param-reassign": 1, + "no-plusplus": 1, + "no-proto": 1, + "no-redeclare": 1, + "no-restricted-syntax": 1, + "no-shadow": 1, + "no-unused-vars": 1, + "no-use-before-define": 1, + "object-curly-newline": 1, + "operator-linebreak": 1, + "quote-props": 1, + "quotes": 1, + "semi-style": 1, + "semi": 1, + "strict": 1, + "wrap-regex": 1, + }, } diff --git a/README.md b/README.md index eaac70d..b62e8d9 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,16 @@ $ node example/parse.js -a beep -b boop ``` $ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz -{ _: [ 'foo', 'bar', 'baz' ], - x: 3, - y: 4, - n: 5, - a: true, - b: true, - c: true, - beep: 'boop' } +{ + _: ['foo', 'bar', 'baz'], + x: 3, + y: 4, + n: 5, + a: true, + b: true, + c: true, + beep: 'boop' +} ``` # methods @@ -71,10 +73,12 @@ argument names to use as aliases * `opts['--']` - when true, populate `argv._` with everything before the `--` and `argv['--']` with everything after the `--`. Here's an example: -``` +```sh > require('./')('one two three -- four five --six'.split(' '), { '--': true }) -{ _: [ 'one', 'two', 'three' ], - '--': [ 'four', 'five', '--six' ] } +{ + _: ['one', 'two', 'three'], + '--': ['four', 'five', '--six'], +} ``` Note that with `opts['--']` set, parsing for arguments still stops after the diff --git a/index.js b/index.js index 6e82175..5ce6216 100644 --- a/index.js +++ b/index.js @@ -1,209 +1,195 @@ module.exports = function (args, opts) { - if (!opts) opts = {}; - - var flags = { bools : {}, strings : {} }; - - if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { - flags.allBools = true; - } else { - [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { - flags.bools[key] = true; - }); - } - - var aliases = {}; - Object.keys(opts.alias || {}).forEach(function (key) { - aliases[key] = [].concat(opts.alias[key]); - aliases[key].forEach(function (x) { - aliases[x] = [key].concat(aliases[key].filter(function (y) { - return x !== y; - })); - }); - }); - - [].concat(opts.string).filter(Boolean).forEach(function (key) { - flags.strings[key] = true; - if (aliases[key]) { - flags.strings[aliases[key]] = true; - } - }); - - var defaults = opts['default'] || {}; - - var argv = { _ : [] }; - Object.keys(flags.bools).forEach(function (key) { - setArg(key, defaults[key] === undefined ? false : defaults[key]); - }); - - var notFlags = []; - - if (args.indexOf('--') !== -1) { - notFlags = args.slice(args.indexOf('--')+1); - args = args.slice(0, args.indexOf('--')); - } - - function setArg (key, val) { - var value = !flags.strings[key] && isNumber(val) - ? Number(val) : val + if (!opts) opts = {}; + + var flags = { bools: {}, strings: {} }; + + if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { + flags.allBools = true; + } else { + [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { + flags.bools[key] = true; + }); + } + + var aliases = {}; + Object.keys(opts.alias || {}).forEach(function (key) { + aliases[key] = [].concat(opts.alias[key]); + aliases[key].forEach(function (x) { + aliases[x] = [key].concat(aliases[key].filter(function (y) { + return x !== y; + })); + }); + }); + + [].concat(opts.string).filter(Boolean).forEach(function (key) { + flags.strings[key] = true; + if (aliases[key]) { + flags.strings[aliases[key]] = true; + } + }); + + var defaults = opts['default'] || {}; + + var argv = { _: [] }; + Object.keys(flags.bools).forEach(function (key) { + setArg(key, defaults[key] === undefined ? false : defaults[key]); + }); + + var notFlags = []; + + if (args.indexOf('--') !== -1) { + notFlags = args.slice(args.indexOf('--') + 1); + args = args.slice(0, args.indexOf('--')); + } + + function setArg(key, val) { + var value = !flags.strings[key] && isNumber(val) + ? Number(val) : val ; - setKey(argv, key.split('.'), value); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), value); - }); - } - - for (var i = 0; i < args.length; i++) { - var arg = args[i]; - - if (/^--.+=/.test(arg)) { - // Using [\s\S] instead of . because js doesn't support the - // 'dotall' regex modifier. See: - // http://stackoverflow.com/a/1068308/13216 - var m = arg.match(/^--([^=]+)=([\s\S]*)$/); - setArg(m[1], m[2]); - } - else if (/^--no-.+/.test(arg)) { - var key = arg.match(/^--no-(.+)/)[1]; - setArg(key, false); - } - else if (/^--.+/.test(arg)) { - var key = arg.match(/^--(.+)/)[1]; - var next = args[i + 1]; - if (next !== undefined && !/^-/.test(next) + setKey(argv, key.split('.'), value); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), value); + }); + } + + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + + if (/^--.+=/.test(arg)) { + // Using [\s\S] instead of . because js doesn't support the + // 'dotall' regex modifier. See: + // http://stackoverflow.com/a/1068308/13216 + var m = arg.match(/^--([^=]+)=([\s\S]*)$/); + setArg(m[1], m[2]); + } else if (/^--no-.+/.test(arg)) { + var key = arg.match(/^--no-(.+)/)[1]; + setArg(key, false); + } else if (/^--.+/.test(arg)) { + var key = arg.match(/^--(.+)/)[1]; + var next = args[i + 1]; + if (next !== undefined && !/^-/.test(next) && !flags.bools[key] && !flags.allBools && (aliases[key] ? !flags.bools[aliases[key]] : true)) { - setArg(key, next); - i++; - } - else if (/^(true|false)$/.test(next)) { - setArg(key, next === 'true'); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true); - } - } - else if (/^-[^-]+/.test(arg)) { - var letters = arg.slice(1,-1).split(''); - - var broken = false; - for (var j = 0; j < letters.length; j++) { - var next = arg.slice(j+2); - - if (next === '-') { - setArg(letters[j], next) - continue; - } - - if (/[A-Za-z]/.test(letters[j]) + setArg(key, next); + i++; + } else if (/^(true|false)$/.test(next)) { + setArg(key, next === 'true'); + i++; + } else { + setArg(key, flags.strings[key] ? '' : true); + } + } else if (/^-[^-]+/.test(arg)) { + var letters = arg.slice(1, -1).split(''); + + var broken = false; + for (var j = 0; j < letters.length; j++) { + var next = arg.slice(j + 2); + + if (next === '-') { + setArg(letters[j], next) + continue; + } + + if (/[A-Za-z]/.test(letters[j]) && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { - setArg(letters[j], next); - broken = true; - break; - } - - if (letters[j+1] && letters[j+1].match(/\W/)) { - setArg(letters[j], arg.slice(j+2)); - broken = true; - break; - } - else { - setArg(letters[j], flags.strings[letters[j]] ? '' : true); - } - } - - var key = arg.slice(-1)[0]; - if (!broken && key !== '-') { - if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) + setArg(letters[j], next); + broken = true; + break; + } + + if (letters[j + 1] && letters[j + 1].match(/\W/)) { + setArg(letters[j], arg.slice(j + 2)); + broken = true; + break; + } else { + setArg(letters[j], flags.strings[letters[j]] ? '' : true); + } + } + + var key = arg.slice(-1)[0]; + if (!broken && key !== '-') { + if (args[i + 1] && !/^(-|--)[^-]/.test(args[i + 1]) && !flags.bools[key] && (aliases[key] ? !flags.bools[aliases[key]] : true)) { - setArg(key, args[i+1]); - i++; - } - else if (args[i+1] && /true|false/.test(args[i+1])) { - setArg(key, args[i+1] === 'true'); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true); - } - } - } - else { - argv._.push( - flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) - ); - } - } - - Object.keys(defaults).forEach(function (key) { - if (!hasKey(argv, key.split('.'))) { - setKey(argv, key.split('.'), defaults[key]); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), defaults[key]); - }); - } - }); - - if (opts['--']) { - argv['--'] = new Array(); - notFlags.forEach(function(key) { - argv['--'].push(key); - }); - } - else { - notFlags.forEach(function(key) { - argv._.push(key); - }); - } - - return argv; + setArg(key, args[i + 1]); + i++; + } else if (args[i + 1] && /true|false/.test(args[i + 1])) { + setArg(key, args[i + 1] === 'true'); + i++; + } else { + setArg(key, flags.strings[key] ? '' : true); + } + } + } else { + argv._.push(flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)); + } + } + + Object.keys(defaults).forEach(function (key) { + if (!hasKey(argv, key.split('.'))) { + setKey(argv, key.split('.'), defaults[key]); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), defaults[key]); + }); + } + }); + + if (opts['--']) { + argv['--'] = new Array(); + notFlags.forEach(function (key) { + argv['--'].push(key); + }); + } else { + notFlags.forEach(function (key) { + argv._.push(key); + }); + } + + return argv; }; -function hasKey (obj, keys) { - var o = obj; - keys.slice(0,-1).forEach(function (key) { - o = (o[key] || {}); - }); +function hasKey(obj, keys) { + var o = obj; + keys.slice(0, -1).forEach(function (key) { + o = (o[key] || {}); + }); - var key = keys[keys.length - 1]; - return key in o; + var key = keys[keys.length - 1]; + return key in o; } -function setKey (obj, keys, value) { - var o = obj; - for (var i = 0; i < keys.length-1; i++) { - var key = keys[i]; - if (key === '__proto__') return; - if (o[key] === undefined) o[key] = {}; - if (o[key] === Object.prototype || o[key] === Number.prototype +function setKey(obj, keys, value) { + var o = obj; + for (var i = 0; i < keys.length - 1; i++) { + var key = keys[i]; + if (key === '__proto__') return; + if (o[key] === undefined) o[key] = {}; + if (o[key] === Object.prototype || o[key] === Number.prototype || o[key] === String.prototype) o[key] = {}; - if (o[key] === Array.prototype) o[key] = []; - o = o[key]; - } + if (o[key] === Array.prototype) o[key] = []; + o = o[key]; + } - var key = keys[keys.length - 1]; - if (key === '__proto__') return; - if (o === Object.prototype || o === Number.prototype + var key = keys[keys.length - 1]; + if (key === '__proto__') return; + if (o === Object.prototype || o === Number.prototype || o === String.prototype) o = {}; - if (o === Array.prototype) o = []; - if (o[key] === undefined || typeof o[key] === 'boolean') { - o[key] = value; - } - else if (Array.isArray(o[key])) { - o[key].push(value); - } - else { - o[key] = [ o[key], value ]; - } + if (o === Array.prototype) o = []; + if (o[key] === undefined || typeof o[key] === 'boolean') { + o[key] = value; + } else if (Array.isArray(o[key])) { + o[key].push(value); + } else { + o[key] = [o[key], value]; + } } -function isNumber (x) { - if (typeof x === 'number') return true; - if (/^0x[0-9a-f]+$/i.test(x)) return true; - return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); +function isNumber(x) { + if (typeof x === 'number') return true; + if (/^0x[0-9a-f]+$/i.test(x)) return true; + return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); } diff --git a/package.json b/package.json index e0e4989..a774107 100644 --- a/package.json +++ b/package.json @@ -1,74 +1,74 @@ { - "name": "minimist", - "version": "0.2.2", - "description": "parse argument options", - "main": "index.js", - "devDependencies": { - "@ljharb/eslint-config": "^21.0.0", - "aud": "^2.0.1", - "auto-changelog": "^2.4.0", - "eslint": "=8.8.0", - "in-publish": "^2.0.1", - "nyc": "^10.3.2", - "safe-publish-latest": "^2.0.0", - "tape": "^5.6.1" - }, - "scripts": { - "prepack": "npmignore --auto --commentLines=auto", - "prepublishOnly": "safe-publish-latest", - "prepublish": "not-in-publish || npm run prepublishOnly", - "lint": "eslint --ext=js,mjs .", - "pretest": "npm run lint", - "tests-only": "nyc tape test/*.js", - "test": "npm run tests-only", - "posttest": "aud --production", - "version": "auto-changelog && git add CHANGELOG.md", - "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" - }, - "testling": { - "files": "test/*.js", - "browsers": [ - "ie/6..latest", - "ff/5", - "firefox/latest", - "chrome/10", - "chrome/latest", - "safari/5.1", - "safari/latest", - "opera/12" - ] - }, - "repository": { - "type": "git", - "url": "git://github.com/minimistjs/minimist.git" - }, - "homepage": "https://github.com/minimistjs/minimist", - "keywords": [ - "argv", - "getopt", - "parser", - "optimist" - ], - "author": { - "name": "James Halliday", - "email": "mail@substack.net", - "url": "http://substack.net" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - }, - "license": "MIT", - "auto-changelog": { - "output": "CHANGELOG.md", - "template": "keepachangelog", - "unreleased": false, - "commitLimit": false, - "backfillLimit": false, - "hideCredit": true - }, - "publishConfig": { - "ignore": [ - ".github/workflows" - ] - } + "name": "minimist", + "version": "0.2.2", + "description": "parse argument options", + "main": "index.js", + "devDependencies": { + "@ljharb/eslint-config": "^21.0.0", + "aud": "^2.0.1", + "auto-changelog": "^2.4.0", + "eslint": "=8.8.0", + "in-publish": "^2.0.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.6.1" + }, + "scripts": { + "prepack": "npmignore --auto --commentLines=auto", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "lint": "eslint --ext=js,mjs .", + "pretest": "npm run lint", + "tests-only": "nyc tape test/*.js", + "test": "npm run tests-only", + "posttest": "aud --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/6..latest", + "ff/5", + "firefox/latest", + "chrome/10", + "chrome/latest", + "safari/5.1", + "safari/latest", + "opera/12" + ] + }, + "repository": { + "type": "git", + "url": "git://github.com/minimistjs/minimist.git" + }, + "homepage": "https://github.com/minimistjs/minimist", + "keywords": [ + "argv", + "getopt", + "parser", + "optimist" + ], + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "license": "MIT", + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + } } diff --git a/test/all_bool.js b/test/all_bool.js index 1191235..3df5709 100644 --- a/test/all_bool.js +++ b/test/all_bool.js @@ -2,31 +2,31 @@ var parse = require('../'); var test = require('tape'); test('flag boolean true (default all --args to boolean)', function (t) { - var argv = parse(['moo', '--honk', 'cow'], { - boolean: true - }); - - t.deepEqual(argv, { - honk: true, - _: ['moo', 'cow'] - }); - - t.deepEqual(typeof argv.honk, 'boolean'); - t.end(); + var argv = parse(['moo', '--honk', 'cow'], { + boolean: true + }); + + t.deepEqual(argv, { + honk: true, + _: ['moo', 'cow'] + }); + + t.deepEqual(typeof argv.honk, 'boolean'); + t.end(); }); test('flag boolean true only affects double hyphen arguments without equals signs', function (t) { - var argv = parse(['moo', '--honk', 'cow', '-p', '55', '--tacos=good'], { - boolean: true - }); - - t.deepEqual(argv, { - _: ['moo', 'cow'], - honk: true, - p: 55, - tacos: 'good' - }); - - t.deepEqual(typeof argv.honk, 'boolean'); - t.end(); + var argv = parse(['moo', '--honk', 'cow', '-p', '55', '--tacos=good'], { + boolean: true + }); + + t.deepEqual(argv, { + _: ['moo', 'cow'], + honk: true, + p: 55, + tacos: 'good' + }); + + t.deepEqual(typeof argv.honk, 'boolean'); + t.end(); }); diff --git a/test/bool.js b/test/bool.js index 749e083..c5f15e3 100644 --- a/test/bool.js +++ b/test/bool.js @@ -2,118 +2,118 @@ var parse = require('../'); var test = require('tape'); test('flag boolean default false', function (t) { - var argv = parse(['moo'], { - boolean: ['t', 'verbose'], - default: { verbose: false, t: false } - }); - - t.deepEqual(argv, { - verbose: false, - t: false, - _: ['moo'] - }); - - t.deepEqual(typeof argv.verbose, 'boolean'); - t.deepEqual(typeof argv.t, 'boolean'); - t.end(); + var argv = parse(['moo'], { + boolean: ['t', 'verbose'], + default: { verbose: false, t: false } + }); + + t.deepEqual(argv, { + verbose: false, + t: false, + _: ['moo'] + }); + + t.deepEqual(typeof argv.verbose, 'boolean'); + t.deepEqual(typeof argv.t, 'boolean'); + t.end(); }); test('boolean groups', function (t) { - var argv = parse([ '-x', '-z', 'one', 'two', 'three' ], { - boolean: ['x','y','z'] - }); - - t.deepEqual(argv, { - x : true, - y : false, - z : true, - _ : [ 'one', 'two', 'three' ] - }); - - t.deepEqual(typeof argv.x, 'boolean'); - t.deepEqual(typeof argv.y, 'boolean'); - t.deepEqual(typeof argv.z, 'boolean'); - t.end(); + var argv = parse(['-x', '-z', 'one', 'two', 'three'], { + boolean: ['x', 'y', 'z'] + }); + + t.deepEqual(argv, { + x: true, + y: false, + z: true, + _: ['one', 'two', 'three'] + }); + + t.deepEqual(typeof argv.x, 'boolean'); + t.deepEqual(typeof argv.y, 'boolean'); + t.deepEqual(typeof argv.z, 'boolean'); + t.end(); }); test('boolean and alias with chainable api', function (t) { - var aliased = [ '-h', 'derp' ]; - var regular = [ '--herp', 'derp' ]; - var opts = { - herp: { alias: 'h', boolean: true } - }; - var aliasedArgv = parse(aliased, { - boolean: 'herp', - alias: { h: 'herp' } - }); - var propertyArgv = parse(regular, { - boolean: 'herp', - alias: { h: 'herp' } - }); - var expected = { - herp: true, - h: true, - '_': [ 'derp' ] - }; - - t.same(aliasedArgv, expected); - t.same(propertyArgv, expected); - t.end(); + var aliased = ['-h', 'derp']; + var regular = ['--herp', 'derp']; + var opts = { + herp: { alias: 'h', boolean: true } + }; + var aliasedArgv = parse(aliased, { + boolean: 'herp', + alias: { h: 'herp' } + }); + var propertyArgv = parse(regular, { + boolean: 'herp', + alias: { h: 'herp' } + }); + var expected = { + herp: true, + h: true, + '_': ['derp'] + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); }); test('boolean and alias with options hash', function (t) { - var aliased = [ '-h', 'derp' ]; - var regular = [ '--herp', 'derp' ]; - var opts = { - alias: { 'h': 'herp' }, - boolean: 'herp' - }; - var aliasedArgv = parse(aliased, opts); - var propertyArgv = parse(regular, opts); - var expected = { - herp: true, - h: true, - '_': [ 'derp' ] - }; - t.same(aliasedArgv, expected); - t.same(propertyArgv, expected); - t.end(); + var aliased = ['-h', 'derp']; + var regular = ['--herp', 'derp']; + var opts = { + alias: { 'h': 'herp' }, + boolean: 'herp' + }; + var aliasedArgv = parse(aliased, opts); + var propertyArgv = parse(regular, opts); + var expected = { + herp: true, + h: true, + '_': ['derp'] + }; + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); }); test('boolean and alias using explicit true', function (t) { - var aliased = [ '-h', 'true' ]; - var regular = [ '--herp', 'true' ]; - var opts = { - alias: { h: 'herp' }, - boolean: 'h' - }; - var aliasedArgv = parse(aliased, opts); - var propertyArgv = parse(regular, opts); - var expected = { - herp: true, - h: true, - '_': [ ] - }; + var aliased = ['-h', 'true']; + var regular = ['--herp', 'true']; + var opts = { + alias: { h: 'herp' }, + boolean: 'h' + }; + var aliasedArgv = parse(aliased, opts); + var propertyArgv = parse(regular, opts); + var expected = { + herp: true, + h: true, + '_': [] + }; - t.same(aliasedArgv, expected); - t.same(propertyArgv, expected); - t.end(); + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); }); // regression, see https://github.com/substack/node-optimist/issues/71 -test('boolean and --x=true', function(t) { - var parsed = parse(['--boool', '--other=true'], { - boolean: 'boool' - }); +test('boolean and --x=true', function (t) { + var parsed = parse(['--boool', '--other=true'], { + boolean: 'boool' + }); + + t.same(parsed.boool, true); + t.same(parsed.other, 'true'); - t.same(parsed.boool, true); - t.same(parsed.other, 'true'); + parsed = parse(['--boool', '--other=false'], { + boolean: 'boool' + }); - parsed = parse(['--boool', '--other=false'], { - boolean: 'boool' - }); - - t.same(parsed.boool, true); - t.same(parsed.other, 'false'); - t.end(); + t.same(parsed.boool, true); + t.same(parsed.other, 'false'); + t.end(); }); diff --git a/test/dash.js b/test/dash.js index 5a4fa5b..e61a079 100644 --- a/test/dash.js +++ b/test/dash.js @@ -2,30 +2,31 @@ var parse = require('../'); var test = require('tape'); test('-', function (t) { - t.plan(5); - t.deepEqual(parse([ '-n', '-' ]), { n: '-', _: [] }); - t.deepEqual(parse([ '-' ]), { _: [ '-' ] }); - t.deepEqual(parse([ '-f-' ]), { f: '-', _: [] }); - t.deepEqual( - parse([ '-b', '-' ], { boolean: 'b' }), - { b: true, _: [ '-' ] } - ); - t.deepEqual( - parse([ '-s', '-' ], { string: 's' }), - { s: '-', _: [] } - ); + t.plan(5); + t.deepEqual(parse(['-n', '-']), { n: '-', _: [] }); + t.deepEqual(parse(['-']), { _: ['-'] }); + t.deepEqual(parse(['-f-']), { f: '-', _: [] }); + t.deepEqual( + parse(['-b', '-'], { boolean: 'b' }), + { b: true, _: ['-'] } + ); + t.deepEqual( + parse(['-s', '-'], { string: 's' }), + { s: '-', _: [] } + ); }); test('-a -- b', function (t) { - t.plan(3); - t.deepEqual(parse([ '-a', '--', 'b' ]), { a: true, _: [ 'b' ] }); - t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] }); - t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] }); + t.plan(3); + t.deepEqual(parse(['-a', '--', 'b']), { a: true, _: ['b'] }); + t.deepEqual(parse(['--a', '--', 'b']), { a: true, _: ['b'] }); + t.deepEqual(parse(['--a', '--', 'b']), { a: true, _: ['b'] }); }); -test('move arguments after the -- into their own `--` array', function(t) { - t.plan(1); - t.deepEqual( - parse([ '--name', 'John', 'before', '--', 'after' ], { '--': true }), - { name: 'John', _: [ 'before' ], '--': [ 'after' ] }); +test('move arguments after the -- into their own `--` array', function (t) { + t.plan(1); + t.deepEqual( + parse(['--name', 'John', 'before', '--', 'after'], { '--': true }), + { name: 'John', _: ['before'], '--': ['after'] } + ); }); diff --git a/test/default_bool.js b/test/default_bool.js index f0041ee..d25dae7 100644 --- a/test/default_bool.js +++ b/test/default_bool.js @@ -2,19 +2,19 @@ var test = require('tape'); var parse = require('../'); test('boolean default true', function (t) { - var argv = parse([], { - boolean: 'sometrue', - default: { sometrue: true } - }); - t.equal(argv.sometrue, true); - t.end(); + var argv = parse([], { + boolean: 'sometrue', + default: { sometrue: true } + }); + t.equal(argv.sometrue, true); + t.end(); }); test('boolean default false', function (t) { - var argv = parse([], { - boolean: 'somefalse', - default: { somefalse: false } - }); - t.equal(argv.somefalse, false); - t.end(); + var argv = parse([], { + boolean: 'somefalse', + default: { somefalse: false } + }); + t.equal(argv.somefalse, false); + t.end(); }); diff --git a/test/dotted.js b/test/dotted.js index d8b3e85..ed9e9d2 100644 --- a/test/dotted.js +++ b/test/dotted.js @@ -2,21 +2,21 @@ var parse = require('../'); var test = require('tape'); test('dotted alias', function (t) { - var argv = parse(['--a.b', '22'], {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}}); - t.equal(argv.a.b, 22); - t.equal(argv.aa.bb, 22); - t.end(); + var argv = parse(['--a.b', '22'], { default: { 'a.b': 11 }, alias: { 'a.b': 'aa.bb' } }); + t.equal(argv.a.b, 22); + t.equal(argv.aa.bb, 22); + t.end(); }); test('dotted default', function (t) { - var argv = parse('', {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}}); - t.equal(argv.a.b, 11); - t.equal(argv.aa.bb, 11); - t.end(); + var argv = parse('', { default: { 'a.b': 11 }, alias: { 'a.b': 'aa.bb' } }); + t.equal(argv.a.b, 11); + t.equal(argv.aa.bb, 11); + t.end(); }); test('dotted default with no alias', function (t) { - var argv = parse('', {default: {'a.b': 11}}); - t.equal(argv.a.b, 11); - t.end(); + var argv = parse('', { default: { 'a.b': 11 } }); + t.equal(argv.a.b, 11); + t.end(); }); diff --git a/test/long.js b/test/long.js index 5d3a1e0..99fe947 100644 --- a/test/long.js +++ b/test/long.js @@ -2,30 +2,30 @@ var test = require('tape'); var parse = require('../'); test('long opts', function (t) { - t.deepEqual( - parse([ '--bool' ]), - { bool : true, _ : [] }, - 'long boolean' - ); - t.deepEqual( - parse([ '--pow', 'xixxle' ]), - { pow : 'xixxle', _ : [] }, - 'long capture sp' - ); - t.deepEqual( - parse([ '--pow=xixxle' ]), - { pow : 'xixxle', _ : [] }, - 'long capture eq' - ); - t.deepEqual( - parse([ '--host', 'localhost', '--port', '555' ]), - { host : 'localhost', port : 555, _ : [] }, - 'long captures sp' - ); - t.deepEqual( - parse([ '--host=localhost', '--port=555' ]), - { host : 'localhost', port : 555, _ : [] }, - 'long captures eq' - ); - t.end(); + t.deepEqual( + parse(['--bool']), + { bool: true, _: [] }, + 'long boolean' + ); + t.deepEqual( + parse(['--pow', 'xixxle']), + { pow: 'xixxle', _: [] }, + 'long capture sp' + ); + t.deepEqual( + parse(['--pow=xixxle']), + { pow: 'xixxle', _: [] }, + 'long capture eq' + ); + t.deepEqual( + parse(['--host', 'localhost', '--port', '555']), + { host: 'localhost', port: 555, _: [] }, + 'long captures sp' + ); + t.deepEqual( + parse(['--host=localhost', '--port=555']), + { host: 'localhost', port: 555, _: [] }, + 'long captures eq' + ); + t.end(); }); diff --git a/test/num.js b/test/num.js index 2cc77f4..2075efe 100644 --- a/test/num.js +++ b/test/num.js @@ -2,35 +2,35 @@ var parse = require('../'); var test = require('tape'); test('nums', function (t) { - var argv = parse([ - '-x', '1234', - '-y', '5.67', - '-z', '1e7', - '-w', '10f', - '--hex', '0xdeadbeef', - '789' - ]); - t.deepEqual(argv, { - x : 1234, - y : 5.67, - z : 1e7, - w : '10f', - hex : 0xdeadbeef, - _ : [ 789 ] - }); - t.deepEqual(typeof argv.x, 'number'); - t.deepEqual(typeof argv.y, 'number'); - t.deepEqual(typeof argv.z, 'number'); - t.deepEqual(typeof argv.w, 'string'); - t.deepEqual(typeof argv.hex, 'number'); - t.deepEqual(typeof argv._[0], 'number'); - t.end(); + var argv = parse([ + '-x', '1234', + '-y', '5.67', + '-z', '1e7', + '-w', '10f', + '--hex', '0xdeadbeef', + '789' + ]); + t.deepEqual(argv, { + x: 1234, + y: 5.67, + z: 1e7, + w: '10f', + hex: 0xdeadbeef, + _: [789] + }); + t.deepEqual(typeof argv.x, 'number'); + t.deepEqual(typeof argv.y, 'number'); + t.deepEqual(typeof argv.z, 'number'); + t.deepEqual(typeof argv.w, 'string'); + t.deepEqual(typeof argv.hex, 'number'); + t.deepEqual(typeof argv._[0], 'number'); + t.end(); }); test('already a number', function (t) { - var argv = parse([ '-x', 1234, 789 ]); - t.deepEqual(argv, { x : 1234, _ : [ 789 ] }); - t.deepEqual(typeof argv.x, 'number'); - t.deepEqual(typeof argv._[0], 'number'); - t.end(); + var argv = parse(['-x', 1234, 789]); + t.deepEqual(argv, { x: 1234, _: [789] }); + t.deepEqual(typeof argv.x, 'number'); + t.deepEqual(typeof argv._[0], 'number'); + t.end(); }); diff --git a/test/parse.js b/test/parse.js index 7b4a2a1..3eee946 100644 --- a/test/parse.js +++ b/test/parse.js @@ -2,196 +2,195 @@ var parse = require('../'); var test = require('tape'); test('parse args', function (t) { - t.deepEqual( - parse([ '--no-moo' ]), - { moo : false, _ : [] }, - 'no' - ); - t.deepEqual( - parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]), - { v : ['a','b','c'], _ : [] }, - 'multi' - ); - t.end(); + t.deepEqual( + parse(['--no-moo']), + { moo: false, _: [] }, + 'no' + ); + t.deepEqual( + parse(['-v', 'a', '-v', 'b', '-v', 'c']), + { v: ['a', 'b', 'c'], _: [] }, + 'multi' + ); + t.end(); }); - + test('comprehensive', function (t) { - t.deepEqual( - parse([ - '--name=meowmers', 'bare', '-cats', 'woo', - '-h', 'awesome', '--multi=quux', - '--key', 'value', - '-b', '--bool', '--no-meep', '--multi=baz', - '--', '--not-a-flag', 'eek' - ]), - { - c : true, - a : true, - t : true, - s : 'woo', - h : 'awesome', - b : true, - bool : true, - key : 'value', - multi : [ 'quux', 'baz' ], - meep : false, - name : 'meowmers', - _ : [ 'bare', '--not-a-flag', 'eek' ] - } - ); - t.end(); + t.deepEqual( + parse([ + '--name=meowmers', 'bare', '-cats', 'woo', + '-h', 'awesome', '--multi=quux', + '--key', 'value', + '-b', '--bool', '--no-meep', '--multi=baz', + '--', '--not-a-flag', 'eek' + ]), + { + c: true, + a: true, + t: true, + s: 'woo', + h: 'awesome', + b: true, + bool: true, + key: 'value', + multi: ['quux', 'baz'], + meep: false, + name: 'meowmers', + _: ['bare', '--not-a-flag', 'eek'] + } + ); + t.end(); }); test('flag boolean', function (t) { - var argv = parse([ '-t', 'moo' ], { boolean: 't' }); - t.deepEqual(argv, { t : true, _ : [ 'moo' ] }); - t.deepEqual(typeof argv.t, 'boolean'); - t.end(); + var argv = parse(['-t', 'moo'], { boolean: 't' }); + t.deepEqual(argv, { t: true, _: ['moo'] }); + t.deepEqual(typeof argv.t, 'boolean'); + t.end(); }); test('flag boolean value', function (t) { - var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], { - boolean: [ 't', 'verbose' ], - default: { verbose: true } - }); - - t.deepEqual(argv, { - verbose: false, - t: true, - _: ['moo'] - }); - - t.deepEqual(typeof argv.verbose, 'boolean'); - t.deepEqual(typeof argv.t, 'boolean'); - t.end(); + var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], { + boolean: ['t', 'verbose'], + default: { verbose: true } + }); + + t.deepEqual(argv, { + verbose: false, + t: true, + _: ['moo'] + }); + + t.deepEqual(typeof argv.verbose, 'boolean'); + t.deepEqual(typeof argv.t, 'boolean'); + t.end(); }); -test('newlines in params' , function (t) { - var args = parse([ '-s', "X\nX" ]) - t.deepEqual(args, { _ : [], s : "X\nX" }); - - // reproduce in bash: - // VALUE="new - // line" - // node program.js --s="$VALUE" - args = parse([ "--s=X\nX" ]) - t.deepEqual(args, { _ : [], s : "X\nX" }); - t.end(); +test('newlines in params', function (t) { + var args = parse(['-s', "X\nX"]) + t.deepEqual(args, { _: [], s: "X\nX" }); + + // reproduce in bash: + // VALUE="new + // line" + // node program.js --s="$VALUE" + args = parse(["--s=X\nX"]) + t.deepEqual(args, { _: [], s: "X\nX" }); + t.end(); }); -test('strings' , function (t) { - var s = parse([ '-s', '0001234' ], { string: 's' }).s; - t.equal(s, '0001234'); - t.equal(typeof s, 'string'); - - var x = parse([ '-x', '56' ], { string: 'x' }).x; - t.equal(x, '56'); - t.equal(typeof x, 'string'); - t.end(); +test('strings', function (t) { + var s = parse(['-s', '0001234'], { string: 's' }).s; + t.equal(s, '0001234'); + t.equal(typeof s, 'string'); + + var x = parse(['-x', '56'], { string: 'x' }).x; + t.equal(x, '56'); + t.equal(typeof x, 'string'); + t.end(); }); test('stringArgs', function (t) { - var s = parse([ ' ', ' ' ], { string: '_' })._; - t.same(s.length, 2); - t.same(typeof s[0], 'string'); - t.same(s[0], ' '); - t.same(typeof s[1], 'string'); - t.same(s[1], ' '); - t.end(); + var s = parse([' ', ' '], { string: '_' })._; + t.same(s.length, 2); + t.same(typeof s[0], 'string'); + t.same(s[0], ' '); + t.same(typeof s[1], 'string'); + t.same(s[1], ' '); + t.end(); }); -test('empty strings', function(t) { - var s = parse([ '-s' ], { string: 's' }).s; - t.equal(s, ''); - t.equal(typeof s, 'string'); +test('empty strings', function (t) { + var s = parse(['-s'], { string: 's' }).s; + t.equal(s, ''); + t.equal(typeof s, 'string'); - var str = parse([ '--str' ], { string: 'str' }).str; - t.equal(str, ''); - t.equal(typeof str, 'string'); + var str = parse(['--str'], { string: 'str' }).str; + t.equal(str, ''); + t.equal(typeof str, 'string'); - var letters = parse([ '-art' ], { - string: [ 'a', 't' ] - }); + var letters = parse(['-art'], { + string: ['a', 't'] + }); - t.equal(letters.a, ''); - t.equal(letters.r, true); - t.equal(letters.t, ''); + t.equal(letters.a, ''); + t.equal(letters.r, true); + t.equal(letters.t, ''); - t.end(); + t.end(); }); - -test('string and alias', function(t) { - var x = parse([ '--str', '000123' ], { - string: 's', - alias: { s: 'str' } - }); - - t.equal(x.str, '000123'); - t.equal(typeof x.str, 'string'); - t.equal(x.s, '000123'); - t.equal(typeof x.s, 'string'); - - var y = parse([ '-s', '000123' ], { - string: 'str', - alias: { str: 's' } - }); - - t.equal(y.str, '000123'); - t.equal(typeof y.str, 'string'); - t.equal(y.s, '000123'); - t.equal(typeof y.s, 'string'); - t.end(); +test('string and alias', function (t) { + var x = parse(['--str', '000123'], { + string: 's', + alias: { s: 'str' } + }); + + t.equal(x.str, '000123'); + t.equal(typeof x.str, 'string'); + t.equal(x.s, '000123'); + t.equal(typeof x.s, 'string'); + + var y = parse(['-s', '000123'], { + string: 'str', + alias: { str: 's' } + }); + + t.equal(y.str, '000123'); + t.equal(typeof y.str, 'string'); + t.equal(y.s, '000123'); + t.equal(typeof y.s, 'string'); + t.end(); }); test('slashBreak', function (t) { - t.same( - parse([ '-I/foo/bar/baz' ]), - { I : '/foo/bar/baz', _ : [] } - ); - t.same( - parse([ '-xyz/foo/bar/baz' ]), - { x : true, y : true, z : '/foo/bar/baz', _ : [] } - ); - t.end(); + t.same( + parse(['-I/foo/bar/baz']), + { I: '/foo/bar/baz', _: [] } + ); + t.same( + parse(['-xyz/foo/bar/baz']), + { x: true, y: true, z: '/foo/bar/baz', _: [] } + ); + t.end(); }); test('alias', function (t) { - var argv = parse([ '-f', '11', '--zoom', '55' ], { - alias: { z: 'zoom' } - }); - t.equal(argv.zoom, 55); - t.equal(argv.z, argv.zoom); - t.equal(argv.f, 11); - t.end(); + var argv = parse(['-f', '11', '--zoom', '55'], { + alias: { z: 'zoom' } + }); + t.equal(argv.zoom, 55); + t.equal(argv.z, argv.zoom); + t.equal(argv.f, 11); + t.end(); }); test('multiAlias', function (t) { - var argv = parse([ '-f', '11', '--zoom', '55' ], { - alias: { z: [ 'zm', 'zoom' ] } - }); - t.equal(argv.zoom, 55); - t.equal(argv.z, argv.zoom); - t.equal(argv.z, argv.zm); - t.equal(argv.f, 11); - t.end(); + var argv = parse(['-f', '11', '--zoom', '55'], { + alias: { z: ['zm', 'zoom'] } + }); + t.equal(argv.zoom, 55); + t.equal(argv.z, argv.zoom); + t.equal(argv.z, argv.zm); + t.equal(argv.f, 11); + t.end(); }); test('nested dotted objects', function (t) { - var argv = parse([ - '--foo.bar', '3', '--foo.baz', '4', - '--foo.quux.quibble', '5', '--foo.quux.o_O', - '--beep.boop' - ]); - - t.same(argv.foo, { - bar : 3, - baz : 4, - quux : { - quibble : 5, - o_O : true - } - }); - t.same(argv.beep, { boop : true }); - t.end(); + var argv = parse([ + '--foo.bar', '3', '--foo.baz', '4', + '--foo.quux.quibble', '5', '--foo.quux.o_O', + '--beep.boop' + ]); + + t.same(argv.foo, { + bar: 3, + baz: 4, + quux: { + quibble: 5, + o_O: true + } + }); + t.same(argv.beep, { boop: true }); + t.end(); }); diff --git a/test/parse_modified.js b/test/parse_modified.js index d6b9caa..3bcad6a 100644 --- a/test/parse_modified.js +++ b/test/parse_modified.js @@ -1,9 +1,9 @@ var parse = require('../'); var test = require('tape'); -test('parse with modifier functions' , function (t) { - t.plan(1); - - var argv = parse([ '-b', '123' ], { boolean: 'b' }); - t.deepEqual(argv, { _: [123], b: true }); +test('parse with modifier functions', function (t) { + t.plan(1); + + var argv = parse(['-b', '123'], { boolean: 'b' }); + t.deepEqual(argv, { _: [123], b: true }); }); diff --git a/test/proto.js b/test/proto.js index 8649107..a97e133 100644 --- a/test/proto.js +++ b/test/proto.js @@ -2,43 +2,43 @@ var parse = require('../'); var test = require('tape'); test('proto pollution', function (t) { - var argv = parse(['--__proto__.x','123']); - t.equal({}.x, undefined); - t.equal(argv.__proto__.x, undefined); - t.equal(argv.x, undefined); - t.end(); + var argv = parse(['--__proto__.x', '123']); + t.equal({}.x, undefined); + t.equal(argv.__proto__.x, undefined); + t.equal(argv.x, undefined); + t.end(); }); test('proto pollution (array)', function (t) { - var argv = parse(['--x','4','--x','5','--x.__proto__.z','789']); - t.equal({}.z, undefined); - t.deepEqual(argv.x, [4,5]); - t.equal(argv.x.z, undefined); - t.equal(argv.x.__proto__.z, undefined); - t.end(); + var argv = parse(['--x', '4', '--x', '5', '--x.__proto__.z', '789']); + t.equal({}.z, undefined); + t.deepEqual(argv.x, [4, 5]); + t.equal(argv.x.z, undefined); + t.equal(argv.x.__proto__.z, undefined); + t.end(); }); test('proto pollution (number)', function (t) { - var argv = parse(['--x','5','--x.__proto__.z','100']); - t.equal({}.z, undefined); - t.equal((4).z, undefined); - t.equal(argv.x, 5); - t.equal(argv.x.z, undefined); - t.end(); + var argv = parse(['--x', '5', '--x.__proto__.z', '100']); + t.equal({}.z, undefined); + t.equal((4).z, undefined); + t.equal(argv.x, 5); + t.equal(argv.x.z, undefined); + t.end(); }); test('proto pollution (string)', function (t) { - var argv = parse(['--x','abc','--x.__proto__.z','def']); - t.equal({}.z, undefined); - t.equal('...'.z, undefined); - t.equal(argv.x, 'abc'); - t.equal(argv.x.z, undefined); - t.end(); + var argv = parse(['--x', 'abc', '--x.__proto__.z', 'def']); + t.equal({}.z, undefined); + t.equal('...'.z, undefined); + t.equal(argv.x, 'abc'); + t.equal(argv.x.z, undefined); + t.end(); }); test('proto pollution (constructor)', function (t) { - var argv = parse(['--constructor.prototype.y','123']); - t.equal({}.y, undefined); - t.equal(argv.y, undefined); - t.end(); + var argv = parse(['--constructor.prototype.y', '123']); + t.equal({}.y, undefined); + t.equal(argv.y, undefined); + t.end(); }); diff --git a/test/short.js b/test/short.js index d513a1c..d65dc08 100644 --- a/test/short.js +++ b/test/short.js @@ -2,66 +2,66 @@ var parse = require('../'); var test = require('tape'); test('numeric short args', function (t) { - t.plan(2); - t.deepEqual(parse([ '-n123' ]), { n: 123, _: [] }); - t.deepEqual( - parse([ '-123', '456' ]), - { 1: true, 2: true, 3: 456, _: [] } - ); + t.plan(2); + t.deepEqual(parse(['-n123']), { n: 123, _: [] }); + t.deepEqual( + parse(['-123', '456']), + { 1: true, 2: true, 3: 456, _: [] } + ); }); test('short', function (t) { - t.deepEqual( - parse([ '-b' ]), - { b : true, _ : [] }, - 'short boolean' - ); - t.deepEqual( - parse([ 'foo', 'bar', 'baz' ]), - { _ : [ 'foo', 'bar', 'baz' ] }, - 'bare' - ); - t.deepEqual( - parse([ '-cats' ]), - { c : true, a : true, t : true, s : true, _ : [] }, - 'group' - ); - t.deepEqual( - parse([ '-cats', 'meow' ]), - { c : true, a : true, t : true, s : 'meow', _ : [] }, - 'short group next' - ); - t.deepEqual( - parse([ '-h', 'localhost' ]), - { h : 'localhost', _ : [] }, - 'short capture' - ); - t.deepEqual( - parse([ '-h', 'localhost', '-p', '555' ]), - { h : 'localhost', p : 555, _ : [] }, - 'short captures' - ); - t.end(); + t.deepEqual( + parse(['-b']), + { b: true, _: [] }, + 'short boolean' + ); + t.deepEqual( + parse(['foo', 'bar', 'baz']), + { _: ['foo', 'bar', 'baz'] }, + 'bare' + ); + t.deepEqual( + parse(['-cats']), + { c: true, a: true, t: true, s: true, _: [] }, + 'group' + ); + t.deepEqual( + parse(['-cats', 'meow']), + { c: true, a: true, t: true, s: 'meow', _: [] }, + 'short group next' + ); + t.deepEqual( + parse(['-h', 'localhost']), + { h: 'localhost', _: [] }, + 'short capture' + ); + t.deepEqual( + parse(['-h', 'localhost', '-p', '555']), + { h: 'localhost', p: 555, _: [] }, + 'short captures' + ); + t.end(); }); - + test('mixed short bool and capture', function (t) { - t.same( - parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), - { - f : true, p : 555, h : 'localhost', - _ : [ 'script.js' ] - } - ); - t.end(); + t.same( + parse(['-h', 'localhost', '-fp', '555', 'script.js']), + { + f: true, p: 555, h: 'localhost', + _: ['script.js'] + } + ); + t.end(); }); - + test('short and long', function (t) { - t.deepEqual( - parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), - { - f : true, p : 555, h : 'localhost', - _ : [ 'script.js' ] - } - ); - t.end(); + t.deepEqual( + parse(['-h', 'localhost', '-fp', '555', 'script.js']), + { + f: true, p: 555, h: 'localhost', + _: ['script.js'] + } + ); + t.end(); }); diff --git a/test/whitespace.js b/test/whitespace.js index 8a52a58..e79c482 100644 --- a/test/whitespace.js +++ b/test/whitespace.js @@ -1,8 +1,8 @@ var parse = require('../'); var test = require('tape'); -test('whitespace should be whitespace' , function (t) { - t.plan(1); - var x = parse([ '-x', '\t' ]).x; - t.equal(x, '\t'); +test('whitespace should be whitespace', function (t) { + t.plan(1); + var x = parse(['-x', '\t']).x; + t.equal(x, '\t'); }); From 36ac5d0d95e4947d074e5737d94814034ca335d1 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 16 Oct 2022 13:44:03 -0700 Subject: [PATCH 02/10] [eslint] more cleanup --- .eslintrc | 35 +++----- example/parse.js | 2 + index.js | 192 ++++++++++++++++++++++------------------- test/all_bool.js | 10 ++- test/bool.js | 34 ++++---- test/dash.js | 2 + test/default_bool.js | 6 +- test/dotted.js | 2 + test/long.js | 2 + test/num.js | 6 +- test/parse.js | 34 ++++---- test/parse_modified.js | 2 + test/proto.js | 4 + test/short.js | 6 +- test/whitespace.js | 2 + 15 files changed, 183 insertions(+), 156 deletions(-) diff --git a/.eslintrc b/.eslintrc index 7074004..bd1a5e0 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,36 +5,25 @@ "rules": { "array-element-newline": 0, - "camelcase": 1, - "comma-dangle": 1, "complexity": 0, - "curly": 1, - "dot-notation": 1, - "func-style": 1, + "func-style": [2, "declaration"], "max-lines-per-function": 0, "max-nested-callbacks": 1, + "max-statements-per-line": 1, "max-statements": 0, "multiline-comment-style": 0, - "no-array-constructor": 1, "no-continue": 1, - "no-div-regex": 1, - "no-extra-parens": 1, - "no-mixed-operators": 1, "no-param-reassign": 1, - "no-plusplus": 1, - "no-proto": 1, - "no-redeclare": 1, "no-restricted-syntax": 1, - "no-shadow": 1, - "no-unused-vars": 1, - "no-use-before-define": 1, - "object-curly-newline": 1, - "operator-linebreak": 1, - "quote-props": 1, - "quotes": 1, - "semi-style": 1, - "semi": 1, - "strict": 1, - "wrap-regex": 1, + "object-curly-newline": 0, }, + + "overrides": [ + { + "files": "test/**", + "rules": { + "camelcase": 0, + }, + }, + ] } diff --git a/example/parse.js b/example/parse.js index abff3e8..9e982e1 100644 --- a/example/parse.js +++ b/example/parse.js @@ -1,2 +1,4 @@ +'use strict'; + var argv = require('../')(process.argv.slice(2)); console.dir(argv); diff --git a/index.js b/index.js index 5ce6216..75662ee 100644 --- a/index.js +++ b/index.js @@ -1,12 +1,67 @@ +'use strict'; + +function isNumber(x) { + if (typeof x === 'number') { return true; } + if ((/^0x[0-9a-f]+$/i).test(x)) { return true; } + return (/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x); +} + +function hasKey(obj, keys) { + var o = obj; + keys.slice(0, -1).forEach(function (key) { + o = o[key] || {}; + }); + + var key = keys[keys.length - 1]; + return key in o; +} + +function setKey(obj, keys, value) { + var o = obj; + var key; + for (var i = 0; i < keys.length - 1; i++) { + key = keys[i]; + if (key === '__proto__') { return; } + if (o[key] === undefined) { o[key] = {}; } + if ( + o[key] === Object.prototype + || o[key] === Number.prototype + || o[key] === String.prototype + ) { + o[key] = {}; + } + if (o[key] === Array.prototype) { o[key] = []; } + o = o[key]; + } + + key = keys[keys.length - 1]; + if (key === '__proto__') { return; } + if ( + o === Object.prototype + || o === Number.prototype + || o === String.prototype + ) { + o = {}; + } + if (o === Array.prototype) { o = []; } + if (o[key] === undefined || typeof o[key] === 'boolean') { + o[key] = value; + } else if (Array.isArray(o[key])) { + o[key].push(value); + } else { + o[key] = [o[key], value]; + } +} + module.exports = function (args, opts) { - if (!opts) opts = {}; + if (!opts) { opts = {}; } var flags = { bools: {}, strings: {} }; - if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { + if (typeof opts.boolean === 'boolean' && opts.boolean) { flags.allBools = true; } else { - [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { + [].concat(opts.boolean).filter(Boolean).forEach(function (key) { flags.bools[key] = true; }); } @@ -28,9 +83,21 @@ module.exports = function (args, opts) { } }); - var defaults = opts['default'] || {}; + var defaults = opts.default || {}; var argv = { _: [] }; + + function setArg(key, val) { + var value = !flags.strings[key] && isNumber(val) + ? Number(val) + : val; + setKey(argv, key.split('.'), value); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), value); + }); + } + Object.keys(flags.bools).forEach(function (key) { setArg(key, defaults[key] === undefined ? false : defaults[key]); }); @@ -42,58 +109,49 @@ module.exports = function (args, opts) { args = args.slice(0, args.indexOf('--')); } - function setArg(key, val) { - var value = !flags.strings[key] && isNumber(val) - ? Number(val) : val - ; - setKey(argv, key.split('.'), value); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), value); - }); - } - for (var i = 0; i < args.length; i++) { var arg = args[i]; + var key; + var next; - if (/^--.+=/.test(arg)) { + if ((/^--.+=/).test(arg)) { // Using [\s\S] instead of . because js doesn't support the // 'dotall' regex modifier. See: // http://stackoverflow.com/a/1068308/13216 var m = arg.match(/^--([^=]+)=([\s\S]*)$/); setArg(m[1], m[2]); - } else if (/^--no-.+/.test(arg)) { - var key = arg.match(/^--no-(.+)/)[1]; + } else if ((/^--no-.+/).test(arg)) { + key = arg.match(/^--no-(.+)/)[1]; setArg(key, false); - } else if (/^--.+/.test(arg)) { - var key = arg.match(/^--(.+)/)[1]; - var next = args[i + 1]; - if (next !== undefined && !/^-/.test(next) + } else if ((/^--.+/).test(arg)) { + key = arg.match(/^--(.+)/)[1]; + next = args[i + 1]; + if (next !== undefined && !(/^-/).test(next) && !flags.bools[key] && !flags.allBools && (aliases[key] ? !flags.bools[aliases[key]] : true)) { setArg(key, next); - i++; - } else if (/^(true|false)$/.test(next)) { + i += 1; + } else if ((/^(true|false)$/).test(next)) { setArg(key, next === 'true'); - i++; + i += 1; } else { setArg(key, flags.strings[key] ? '' : true); } - } else if (/^-[^-]+/.test(arg)) { + } else if ((/^-[^-]+/).test(arg)) { var letters = arg.slice(1, -1).split(''); var broken = false; for (var j = 0; j < letters.length; j++) { - var next = arg.slice(j + 2); + next = arg.slice(j + 2); if (next === '-') { - setArg(letters[j], next) + setArg(letters[j], next); continue; } - if (/[A-Za-z]/.test(letters[j]) - && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { + if ((/[A-Za-z]/).test(letters[j]) + && (/-?\d+(\.\d*)?(e-?\d+)?$/).test(next)) { setArg(letters[j], next); broken = true; break; @@ -108,88 +166,42 @@ module.exports = function (args, opts) { } } - var key = arg.slice(-1)[0]; + key = arg.slice(-1)[0]; if (!broken && key !== '-') { - if (args[i + 1] && !/^(-|--)[^-]/.test(args[i + 1]) + if (args[i + 1] && !(/^(-|--)[^-]/).test(args[i + 1]) && !flags.bools[key] && (aliases[key] ? !flags.bools[aliases[key]] : true)) { setArg(key, args[i + 1]); - i++; - } else if (args[i + 1] && /true|false/.test(args[i + 1])) { + i += 1; + } else if (args[i + 1] && (/true|false/).test(args[i + 1])) { setArg(key, args[i + 1] === 'true'); - i++; + i += 1; } else { setArg(key, flags.strings[key] ? '' : true); } } } else { - argv._.push(flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)); + argv._.push(flags.strings._ || !isNumber(arg) ? arg : Number(arg)); } } - Object.keys(defaults).forEach(function (key) { - if (!hasKey(argv, key.split('.'))) { - setKey(argv, key.split('.'), defaults[key]); + Object.keys(defaults).forEach(function (k) { + if (!hasKey(argv, k.split('.'))) { + setKey(argv, k.split('.'), defaults[k]); - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), defaults[key]); + (aliases[k] || []).forEach(function (x) { + setKey(argv, x.split('.'), defaults[k]); }); } }); if (opts['--']) { - argv['--'] = new Array(); - notFlags.forEach(function (key) { - argv['--'].push(key); - }); + argv['--'] = notFlags.slice(); } else { - notFlags.forEach(function (key) { - argv._.push(key); + notFlags.forEach(function (k) { + argv._.push(k); }); } return argv; }; - -function hasKey(obj, keys) { - var o = obj; - keys.slice(0, -1).forEach(function (key) { - o = (o[key] || {}); - }); - - var key = keys[keys.length - 1]; - return key in o; -} - -function setKey(obj, keys, value) { - var o = obj; - for (var i = 0; i < keys.length - 1; i++) { - var key = keys[i]; - if (key === '__proto__') return; - if (o[key] === undefined) o[key] = {}; - if (o[key] === Object.prototype || o[key] === Number.prototype - || o[key] === String.prototype) o[key] = {}; - if (o[key] === Array.prototype) o[key] = []; - o = o[key]; - } - - var key = keys[keys.length - 1]; - if (key === '__proto__') return; - if (o === Object.prototype || o === Number.prototype - || o === String.prototype) o = {}; - if (o === Array.prototype) o = []; - if (o[key] === undefined || typeof o[key] === 'boolean') { - o[key] = value; - } else if (Array.isArray(o[key])) { - o[key].push(value); - } else { - o[key] = [o[key], value]; - } -} - -function isNumber(x) { - if (typeof x === 'number') return true; - if (/^0x[0-9a-f]+$/i.test(x)) return true; - return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); -} - diff --git a/test/all_bool.js b/test/all_bool.js index 3df5709..bc47041 100644 --- a/test/all_bool.js +++ b/test/all_bool.js @@ -1,14 +1,16 @@ +'use strict'; + var parse = require('../'); var test = require('tape'); test('flag boolean true (default all --args to boolean)', function (t) { var argv = parse(['moo', '--honk', 'cow'], { - boolean: true + boolean: true, }); t.deepEqual(argv, { honk: true, - _: ['moo', 'cow'] + _: ['moo', 'cow'], }); t.deepEqual(typeof argv.honk, 'boolean'); @@ -17,14 +19,14 @@ test('flag boolean true (default all --args to boolean)', function (t) { test('flag boolean true only affects double hyphen arguments without equals signs', function (t) { var argv = parse(['moo', '--honk', 'cow', '-p', '55', '--tacos=good'], { - boolean: true + boolean: true, }); t.deepEqual(argv, { _: ['moo', 'cow'], honk: true, p: 55, - tacos: 'good' + tacos: 'good', }); t.deepEqual(typeof argv.honk, 'boolean'); diff --git a/test/bool.js b/test/bool.js index c5f15e3..42f4c2c 100644 --- a/test/bool.js +++ b/test/bool.js @@ -1,16 +1,18 @@ +'use strict'; + var parse = require('../'); var test = require('tape'); test('flag boolean default false', function (t) { var argv = parse(['moo'], { boolean: ['t', 'verbose'], - default: { verbose: false, t: false } + default: { verbose: false, t: false }, }); t.deepEqual(argv, { verbose: false, t: false, - _: ['moo'] + _: ['moo'], }); t.deepEqual(typeof argv.verbose, 'boolean'); @@ -21,14 +23,14 @@ test('flag boolean default false', function (t) { test('boolean groups', function (t) { var argv = parse(['-x', '-z', 'one', 'two', 'three'], { - boolean: ['x', 'y', 'z'] + boolean: ['x', 'y', 'z'], }); t.deepEqual(argv, { x: true, y: false, z: true, - _: ['one', 'two', 'three'] + _: ['one', 'two', 'three'], }); t.deepEqual(typeof argv.x, 'boolean'); @@ -39,21 +41,19 @@ test('boolean groups', function (t) { test('boolean and alias with chainable api', function (t) { var aliased = ['-h', 'derp']; var regular = ['--herp', 'derp']; - var opts = { - herp: { alias: 'h', boolean: true } - }; + var aliasedArgv = parse(aliased, { boolean: 'herp', - alias: { h: 'herp' } + alias: { h: 'herp' }, }); var propertyArgv = parse(regular, { boolean: 'herp', - alias: { h: 'herp' } + alias: { h: 'herp' }, }); var expected = { herp: true, h: true, - '_': ['derp'] + _: ['derp'], }; t.same(aliasedArgv, expected); @@ -65,15 +65,15 @@ test('boolean and alias with options hash', function (t) { var aliased = ['-h', 'derp']; var regular = ['--herp', 'derp']; var opts = { - alias: { 'h': 'herp' }, - boolean: 'herp' + alias: { h: 'herp' }, + boolean: 'herp', }; var aliasedArgv = parse(aliased, opts); var propertyArgv = parse(regular, opts); var expected = { herp: true, h: true, - '_': ['derp'] + _: ['derp'], }; t.same(aliasedArgv, expected); t.same(propertyArgv, expected); @@ -85,14 +85,14 @@ test('boolean and alias using explicit true', function (t) { var regular = ['--herp', 'true']; var opts = { alias: { h: 'herp' }, - boolean: 'h' + boolean: 'h', }; var aliasedArgv = parse(aliased, opts); var propertyArgv = parse(regular, opts); var expected = { herp: true, h: true, - '_': [] + _: [], }; t.same(aliasedArgv, expected); @@ -103,14 +103,14 @@ test('boolean and alias using explicit true', function (t) { // regression, see https://github.com/substack/node-optimist/issues/71 test('boolean and --x=true', function (t) { var parsed = parse(['--boool', '--other=true'], { - boolean: 'boool' + boolean: 'boool', }); t.same(parsed.boool, true); t.same(parsed.other, 'true'); parsed = parse(['--boool', '--other=false'], { - boolean: 'boool' + boolean: 'boool', }); t.same(parsed.boool, true); diff --git a/test/dash.js b/test/dash.js index e61a079..7c897d4 100644 --- a/test/dash.js +++ b/test/dash.js @@ -1,3 +1,5 @@ +'use strict'; + var parse = require('../'); var test = require('tape'); diff --git a/test/default_bool.js b/test/default_bool.js index d25dae7..ce93557 100644 --- a/test/default_bool.js +++ b/test/default_bool.js @@ -1,10 +1,12 @@ +'use strict'; + var test = require('tape'); var parse = require('../'); test('boolean default true', function (t) { var argv = parse([], { boolean: 'sometrue', - default: { sometrue: true } + default: { sometrue: true }, }); t.equal(argv.sometrue, true); t.end(); @@ -13,7 +15,7 @@ test('boolean default true', function (t) { test('boolean default false', function (t) { var argv = parse([], { boolean: 'somefalse', - default: { somefalse: false } + default: { somefalse: false }, }); t.equal(argv.somefalse, false); t.end(); diff --git a/test/dotted.js b/test/dotted.js index ed9e9d2..126ff03 100644 --- a/test/dotted.js +++ b/test/dotted.js @@ -1,3 +1,5 @@ +'use strict'; + var parse = require('../'); var test = require('tape'); diff --git a/test/long.js b/test/long.js index 99fe947..9fef51f 100644 --- a/test/long.js +++ b/test/long.js @@ -1,3 +1,5 @@ +'use strict'; + var test = require('tape'); var parse = require('../'); diff --git a/test/num.js b/test/num.js index 2075efe..074393e 100644 --- a/test/num.js +++ b/test/num.js @@ -1,3 +1,5 @@ +'use strict'; + var parse = require('../'); var test = require('tape'); @@ -8,7 +10,7 @@ test('nums', function (t) { '-z', '1e7', '-w', '10f', '--hex', '0xdeadbeef', - '789' + '789', ]); t.deepEqual(argv, { x: 1234, @@ -16,7 +18,7 @@ test('nums', function (t) { z: 1e7, w: '10f', hex: 0xdeadbeef, - _: [789] + _: [789], }); t.deepEqual(typeof argv.x, 'number'); t.deepEqual(typeof argv.y, 'number'); diff --git a/test/parse.js b/test/parse.js index 3eee946..f88c816 100644 --- a/test/parse.js +++ b/test/parse.js @@ -1,3 +1,5 @@ +'use strict'; + var parse = require('../'); var test = require('tape'); @@ -22,7 +24,7 @@ test('comprehensive', function (t) { '-h', 'awesome', '--multi=quux', '--key', 'value', '-b', '--bool', '--no-meep', '--multi=baz', - '--', '--not-a-flag', 'eek' + '--', '--not-a-flag', 'eek', ]), { c: true, @@ -36,7 +38,7 @@ test('comprehensive', function (t) { multi: ['quux', 'baz'], meep: false, name: 'meowmers', - _: ['bare', '--not-a-flag', 'eek'] + _: ['bare', '--not-a-flag', 'eek'], } ); t.end(); @@ -52,13 +54,13 @@ test('flag boolean', function (t) { test('flag boolean value', function (t) { var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], { boolean: ['t', 'verbose'], - default: { verbose: true } + default: { verbose: true }, }); t.deepEqual(argv, { verbose: false, t: true, - _: ['moo'] + _: ['moo'], }); t.deepEqual(typeof argv.verbose, 'boolean'); @@ -67,15 +69,15 @@ test('flag boolean value', function (t) { }); test('newlines in params', function (t) { - var args = parse(['-s', "X\nX"]) - t.deepEqual(args, { _: [], s: "X\nX" }); + var args = parse(['-s', 'X\nX']); + t.deepEqual(args, { _: [], s: 'X\nX' }); // reproduce in bash: // VALUE="new // line" // node program.js --s="$VALUE" - args = parse(["--s=X\nX"]) - t.deepEqual(args, { _: [], s: "X\nX" }); + args = parse(['--s=X\nX']); + t.deepEqual(args, { _: [], s: 'X\nX' }); t.end(); }); @@ -110,7 +112,7 @@ test('empty strings', function (t) { t.equal(typeof str, 'string'); var letters = parse(['-art'], { - string: ['a', 't'] + string: ['a', 't'], }); t.equal(letters.a, ''); @@ -123,7 +125,7 @@ test('empty strings', function (t) { test('string and alias', function (t) { var x = parse(['--str', '000123'], { string: 's', - alias: { s: 'str' } + alias: { s: 'str' }, }); t.equal(x.str, '000123'); @@ -133,7 +135,7 @@ test('string and alias', function (t) { var y = parse(['-s', '000123'], { string: 'str', - alias: { str: 's' } + alias: { str: 's' }, }); t.equal(y.str, '000123'); @@ -157,7 +159,7 @@ test('slashBreak', function (t) { test('alias', function (t) { var argv = parse(['-f', '11', '--zoom', '55'], { - alias: { z: 'zoom' } + alias: { z: 'zoom' }, }); t.equal(argv.zoom, 55); t.equal(argv.z, argv.zoom); @@ -167,7 +169,7 @@ test('alias', function (t) { test('multiAlias', function (t) { var argv = parse(['-f', '11', '--zoom', '55'], { - alias: { z: ['zm', 'zoom'] } + alias: { z: ['zm', 'zoom'] }, }); t.equal(argv.zoom, 55); t.equal(argv.z, argv.zoom); @@ -180,7 +182,7 @@ test('nested dotted objects', function (t) { var argv = parse([ '--foo.bar', '3', '--foo.baz', '4', '--foo.quux.quibble', '5', '--foo.quux.o_O', - '--beep.boop' + '--beep.boop', ]); t.same(argv.foo, { @@ -188,8 +190,8 @@ test('nested dotted objects', function (t) { baz: 4, quux: { quibble: 5, - o_O: true - } + o_O: true, + }, }); t.same(argv.beep, { boop: true }); t.end(); diff --git a/test/parse_modified.js b/test/parse_modified.js index 3bcad6a..9a3d298 100644 --- a/test/parse_modified.js +++ b/test/parse_modified.js @@ -1,3 +1,5 @@ +'use strict'; + var parse = require('../'); var test = require('tape'); diff --git a/test/proto.js b/test/proto.js index a97e133..589efd7 100644 --- a/test/proto.js +++ b/test/proto.js @@ -1,6 +1,10 @@ +'use strict'; + var parse = require('../'); var test = require('tape'); +/* eslint no-proto: 0 */ + test('proto pollution', function (t) { var argv = parse(['--__proto__.x', '123']); t.equal({}.x, undefined); diff --git a/test/short.js b/test/short.js index d65dc08..4a7b843 100644 --- a/test/short.js +++ b/test/short.js @@ -1,3 +1,5 @@ +'use strict'; + var parse = require('../'); var test = require('tape'); @@ -49,7 +51,7 @@ test('mixed short bool and capture', function (t) { parse(['-h', 'localhost', '-fp', '555', 'script.js']), { f: true, p: 555, h: 'localhost', - _: ['script.js'] + _: ['script.js'], } ); t.end(); @@ -60,7 +62,7 @@ test('short and long', function (t) { parse(['-h', 'localhost', '-fp', '555', 'script.js']), { f: true, p: 555, h: 'localhost', - _: ['script.js'] + _: ['script.js'], } ); t.end(); diff --git a/test/whitespace.js b/test/whitespace.js index e79c482..4fdaf1d 100644 --- a/test/whitespace.js +++ b/test/whitespace.js @@ -1,3 +1,5 @@ +'use strict'; + var parse = require('../'); var test = require('tape'); From ef9153fc52b6cea0744b2239921c5dcae4697f11 Mon Sep 17 00:00:00 2001 From: substack Date: Mon, 21 Mar 2022 16:45:18 -1000 Subject: [PATCH 03/10] isConstructorOrProto adapted from PR --- index.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 75662ee..e836daf 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,10 @@ function isNumber(x) { return (/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x); } +function isConstructorOrProto(obj, key) { + return key === 'constructor' && (typeof obj[key] === 'function' || key === '__proto__'); +} + function hasKey(obj, keys) { var o = obj; keys.slice(0, -1).forEach(function (key) { @@ -21,7 +25,9 @@ function setKey(obj, keys, value) { var key; for (var i = 0; i < keys.length - 1; i++) { key = keys[i]; - if (key === '__proto__') { return; } + if (key === '__proto__' || isConstructorOrProto(o, key)) { + return; + } if (o[key] === undefined) { o[key] = {}; } if ( o[key] === Object.prototype From 4f9bc3e1dcca33a3e5bc39e390e48dc82566fe10 Mon Sep 17 00:00:00 2001 From: nanohertz Date: Tue, 18 Oct 2022 08:21:22 +0300 Subject: [PATCH 04/10] [Fix] opt.string works with multiple aliases (#10) Fixes #9. --- index.js | 4 +++- package.json | 2 +- test/parse.js | 11 +++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index e836daf..93295f3 100644 --- a/index.js +++ b/index.js @@ -85,7 +85,9 @@ module.exports = function (args, opts) { [].concat(opts.string).filter(Boolean).forEach(function (key) { flags.strings[key] = true; if (aliases[key]) { - flags.strings[aliases[key]] = true; + [].concat(aliases[key]).forEach(function (k) { + flags.strings[k] = true; + }); } }); diff --git a/package.json b/package.json index a774107..12eb5aa 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "prepublish": "not-in-publish || npm run prepublishOnly", "lint": "eslint --ext=js,mjs .", "pretest": "npm run lint", - "tests-only": "nyc tape test/*.js", + "tests-only": "nyc tape 'test/**/*.js'", "test": "npm run tests-only", "posttest": "aud --production", "version": "auto-changelog && git add CHANGELOG.md", diff --git a/test/parse.js b/test/parse.js index f88c816..65d9d90 100644 --- a/test/parse.js +++ b/test/parse.js @@ -142,6 +142,17 @@ test('string and alias', function (t) { t.equal(typeof y.str, 'string'); t.equal(y.s, '000123'); t.equal(typeof y.s, 'string'); + + var z = parse(['-s123'], { + alias: { str: ['s', 'S'] }, + string: ['str'], + }); + + t.deepEqual( + z, + { _: [], s: '123', S: '123', str: '123' }, + 'opt.string works with multiple aliases' + ); t.end(); }); From 098873c213cdb7c92e55ae1ef5aa1af3a8192a79 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 5 Jan 2023 22:01:32 -0800 Subject: [PATCH 05/10] [Dev Deps] update `@ljharb/eslint-config`, `aud` --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 12eb5aa..6f74a64 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "description": "parse argument options", "main": "index.js", "devDependencies": { - "@ljharb/eslint-config": "^21.0.0", - "aud": "^2.0.1", + "@ljharb/eslint-config": "^21.0.1", + "aud": "^2.0.2", "auto-changelog": "^2.4.0", "eslint": "=8.8.0", "in-publish": "^2.0.1", From 3226afaf09e9d127ca369742437fe6e88f752d6b Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 5 Jan 2023 22:02:40 -0800 Subject: [PATCH 06/10] [Dev Deps] add missing `npmignore` dev dep --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 6f74a64..643985f 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "auto-changelog": "^2.4.0", "eslint": "=8.8.0", "in-publish": "^2.0.1", + "npmignore": "^0.3.0", "nyc": "^10.3.2", "safe-publish-latest": "^2.0.0", "tape": "^5.6.1" From 34b0f1ccaa45183c3c4f06a91f9b405180a6f982 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 5 Jan 2023 22:03:57 -0800 Subject: [PATCH 07/10] [eslint] fix indentation --- index.js | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index 93295f3..63fce17 100644 --- a/index.js +++ b/index.js @@ -32,7 +32,7 @@ function setKey(obj, keys, value) { if ( o[key] === Object.prototype || o[key] === Number.prototype - || o[key] === String.prototype + || o[key] === String.prototype ) { o[key] = {}; } @@ -45,7 +45,7 @@ function setKey(obj, keys, value) { if ( o === Object.prototype || o === Number.prototype - || o === String.prototype + || o === String.prototype ) { o = {}; } @@ -134,10 +134,13 @@ module.exports = function (args, opts) { } else if ((/^--.+/).test(arg)) { key = arg.match(/^--(.+)/)[1]; next = args[i + 1]; - if (next !== undefined && !(/^-/).test(next) - && !flags.bools[key] - && !flags.allBools - && (aliases[key] ? !flags.bools[aliases[key]] : true)) { + if ( + next !== undefined + && !(/^-/).test(next) + && !flags.bools[key] + && !flags.allBools + && (aliases[key] ? !flags.bools[aliases[key]] : true) + ) { setArg(key, next); i += 1; } else if ((/^(true|false)$/).test(next)) { @@ -158,8 +161,10 @@ module.exports = function (args, opts) { continue; } - if ((/[A-Za-z]/).test(letters[j]) - && (/-?\d+(\.\d*)?(e-?\d+)?$/).test(next)) { + if ( + (/[A-Za-z]/).test(letters[j]) + && (/-?\d+(\.\d*)?(e-?\d+)?$/).test(next) + ) { setArg(letters[j], next); broken = true; break; @@ -176,9 +181,12 @@ module.exports = function (args, opts) { key = arg.slice(-1)[0]; if (!broken && key !== '-') { - if (args[i + 1] && !(/^(-|--)[^-]/).test(args[i + 1]) - && !flags.bools[key] - && (aliases[key] ? !flags.bools[aliases[key]] : true)) { + if ( + args[i + 1] + && !(/^(-|--)[^-]/).test(args[i + 1]) + && !flags.bools[key] + && (aliases[key] ? !flags.bools[aliases[key]] : true) + ) { setArg(key, args[i + 1]); i += 1; } else if (args[i + 1] && (/true|false/).test(args[i + 1])) { From 72239e6f0ea77d8be0ad4f682b7ae7d142144395 Mon Sep 17 00:00:00 2001 From: Wes Carr Date: Wed, 26 Oct 2022 11:09:20 -0700 Subject: [PATCH 08/10] [Tests] Remove duplicate test (#12) Fixes #8 --- test/dash.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/dash.js b/test/dash.js index 7c897d4..66d9bbd 100644 --- a/test/dash.js +++ b/test/dash.js @@ -19,10 +19,9 @@ test('-', function (t) { }); test('-a -- b', function (t) { - t.plan(3); + t.plan(2); t.deepEqual(parse(['-a', '--', 'b']), { a: true, _: ['b'] }); t.deepEqual(parse(['--a', '--', 'b']), { a: true, _: ['b'] }); - t.deepEqual(parse(['--a', '--', 'b']), { a: true, _: ['b'] }); }); test('move arguments after the -- into their own `--` array', function (t) { From 63b8fee87b8e7a003216d5d77ba5d6decf3cfb0d Mon Sep 17 00:00:00 2001 From: John Gee Date: Fri, 6 Jan 2023 13:57:07 +1300 Subject: [PATCH 09/10] [Fix] Fix long option followed by single dash (#17) Fixes #15 --- index.js | 2 +- test/dash.js | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 63fce17..e6dba60 100644 --- a/index.js +++ b/index.js @@ -136,7 +136,7 @@ module.exports = function (args, opts) { next = args[i + 1]; if ( next !== undefined - && !(/^-/).test(next) + && !(/^(-|--)[^-]/).test(next) && !flags.bools[key] && !flags.allBools && (aliases[key] ? !flags.bools[aliases[key]] : true) diff --git a/test/dash.js b/test/dash.js index 66d9bbd..7078817 100644 --- a/test/dash.js +++ b/test/dash.js @@ -4,8 +4,9 @@ var parse = require('../'); var test = require('tape'); test('-', function (t) { - t.plan(5); + t.plan(6); t.deepEqual(parse(['-n', '-']), { n: '-', _: [] }); + t.deepEqual(parse(['--nnn', '-']), { nnn: '-', _: [] }); t.deepEqual(parse(['-']), { _: ['-'] }); t.deepEqual(parse(['-f-']), { f: '-', _: [] }); t.deepEqual( @@ -31,3 +32,12 @@ test('move arguments after the -- into their own `--` array', function (t) { { name: 'John', _: ['before'], '--': ['after'] } ); }); + +test('--- option value', function (t) { + // A multi-dash value is largely an edge case, but check the behaviour is as expected, + // and in particular the same for short option and long option (as made consistent in Jan 2023). + t.plan(2); + t.deepEqual(parse(['-n', '---']), { n: '---', _: [] }); + t.deepEqual(parse(['--nnn', '---']), { nnn: '---', _: [] }); +}); + From c0b26618322e94adea26c68e613ef0be482c6c63 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 9 Feb 2023 10:53:27 -0800 Subject: [PATCH 10/10] v0.2.3 --- CHANGELOG.md | 25 ++++++++++++++++++++++++- package.json | 2 +- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e92dc8c..291aa8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -109,13 +109,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - coverage script [`e5531ba`](https://github.com/minimistjs/minimist/commit/e5531ba0479da3b8138d3d8cac545d84ccb1c8df) - extra fn to get 100% coverage again [`a6972da`](https://github.com/minimistjs/minimist/commit/a6972da89e56bf77642f8ec05a13b6558db93498) -## [v1.0.0](https://github.com/minimistjs/minimist/compare/v0.2.2...v1.0.0) - 2014-08-10 +## [v1.0.0](https://github.com/minimistjs/minimist/compare/v0.2.3...v1.0.0) - 2014-08-10 ### Commits - added stopEarly option [`471c7e4`](https://github.com/minimistjs/minimist/commit/471c7e4a7e910fc7ad8f9df850a186daf32c64e9) - fix list [`fef6ae7`](https://github.com/minimistjs/minimist/commit/fef6ae79c38b9dc1c49569abb7cd04eb965eac5e) +## [v0.2.3](https://github.com/minimistjs/minimist/compare/v0.2.2...v0.2.3) - 2023-02-09 + +### Merged + +- [Fix] Fix long option followed by single dash [`#17`](https://github.com/minimistjs/minimist/pull/17) +- [Tests] Remove duplicate test [`#12`](https://github.com/minimistjs/minimist/pull/12) +- [Fix] opt.string works with multiple aliases [`#10`](https://github.com/minimistjs/minimist/pull/10) + +### Fixed + +- [Fix] Fix long option followed by single dash (#17) [`#15`](https://github.com/minimistjs/minimist/issues/15) +- [Tests] Remove duplicate test (#12) [`#8`](https://github.com/minimistjs/minimist/issues/8) +- [Fix] opt.string works with multiple aliases (#10) [`#9`](https://github.com/minimistjs/minimist/issues/9) + +### Commits + +- [eslint] fix indentation and whitespace [`e5f5067`](https://github.com/minimistjs/minimist/commit/e5f5067259ceeaf0b098d14bec910f87e58708c7) +- [eslint] more cleanup [`36ac5d0`](https://github.com/minimistjs/minimist/commit/36ac5d0d95e4947d074e5737d94814034ca335d1) +- [eslint] fix indentation [`34b0f1c`](https://github.com/minimistjs/minimist/commit/34b0f1ccaa45183c3c4f06a91f9b405180a6f982) +- isConstructorOrProto adapted from PR [`ef9153f`](https://github.com/minimistjs/minimist/commit/ef9153fc52b6cea0744b2239921c5dcae4697f11) +- [Dev Deps] update `@ljharb/eslint-config`, `aud` [`098873c`](https://github.com/minimistjs/minimist/commit/098873c213cdb7c92e55ae1ef5aa1af3a8192a79) +- [Dev Deps] add missing `npmignore` dev dep [`3226afa`](https://github.com/minimistjs/minimist/commit/3226afaf09e9d127ca369742437fe6e88f752d6b) + ## [v0.2.2](https://github.com/minimistjs/minimist/compare/v0.2.1...v0.2.2) - 2022-10-10 ### Commits diff --git a/package.json b/package.json index 643985f..f48df96 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minimist", - "version": "0.2.2", + "version": "0.2.3", "description": "parse argument options", "main": "index.js", "devDependencies": {