Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

command-line-args

Package Overview
Dependencies
Maintainers
1
Versions
75
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

command-line-args - npm Package Compare versions

Comparing version 4.0.3 to 4.0.4

lib/value-arg.js

2

example/mocha.js

@@ -27,3 +27,2 @@ 'use strict'

Array

@@ -33,5 +32,4 @@ #indexOf()

1 passing (7ms)
*/

@@ -36,3 +36,3 @@ 'use strict'

this.forEach(arg => {
const matches = arg.match(optEquals.re)
const matches = arg.match(optEquals)
if (matches) {

@@ -57,3 +57,3 @@ expandedArgs.push(matches[1], option.VALUE_MARKER + matches[2])

if (hasGetopt) {
findReplace(this, combinedArg.re, arg => {
findReplace(this, combinedArg, arg => {
arg = arg.slice(1)

@@ -60,0 +60,0 @@ return arg.split('').map(letter => '-' + letter)

@@ -31,7 +31,3 @@ 'use strict'

const Definitions = require('./definitions')
const option = require('./option')
const Argv = require('./argv')
const Output = require('./output')
const GroupedOutput = require('./grouped-output')
const definitions = new Definitions()

@@ -45,14 +41,20 @@ definitions.load(optionDefinitions)

const output = definitions.isGrouped() ? new GroupedOutput(definitions, options) : new Output(definitions, options)
const OutputClass = definitions.isGrouped() ? require('./grouped-output') : require('./output')
const output = new OutputClass(definitions, options)
let optionName
argv.forEach(arg => {
const option = require('./option')
for (const arg of argv) {
if (option.isOption(arg)) {
optionName = output.set(arg) ? undefined : arg
optionName = output.setFlag(arg) ? undefined : arg
} else {
optionName = output.set(optionName, arg) ? undefined : optionName
if (optionName) {
optionName = output.setOptionValue(optionName, arg) ? undefined : optionName
} else {
optionName = output.setValue(arg) ? undefined : optionName
}
}
})
}
return output.toObject()
}

@@ -232,7 +232,3 @@ 'use strict'

isBoolean (value) {
if (this.type) {
return this.type === Boolean || (t.isFunction(this.type) && this.type.name === 'Boolean')
} else {
return false
}
return this.type === Boolean || (t.isFunction(this.type) && this.type.name === 'Boolean')
}

@@ -239,0 +235,0 @@ }

@@ -17,2 +17,3 @@ 'use strict'

load (definitions) {
this.clear()
arrayify(definitions).forEach(def => this.push(new Definition(def)))

@@ -22,2 +23,6 @@ this.validate()

clear () {
this.length = 0
}
/**

@@ -128,3 +133,2 @@ * validate option definitions

}
}

@@ -131,0 +135,0 @@

'use strict'
const t = require('typical')
const arrayify = require('array-back')

@@ -8,4 +7,6 @@ const Output = require('./output')

toObject () {
const superOutput = super.toObject()
delete superOutput._unknown
const grouped = {
_all: this.output
_all: superOutput
}

@@ -15,14 +16,16 @@ if (this.unknown.length) grouped._unknown = this.unknown

this.definitions.whereGrouped().forEach(def => {
arrayify(def.group).forEach(groupName => {
const outputValue = this.output[def.name]
for (const groupName of arrayify(def.group)) {
grouped[groupName] = grouped[groupName] || {}
if (t.isDefined(this.output[def.name])) {
grouped[groupName][def.name] = this.output[def.name]
if (outputValue && outputValue.isDefined()) {
grouped[groupName][def.name] = outputValue.value
}
})
}
})
this.definitions.whereNotGrouped().forEach(def => {
if (t.isDefined(this.output[def.name])) {
const outputValue = this.output[def.name]
if (outputValue && outputValue.isDefined()) {
if (!grouped._none) grouped._none = {}
grouped._none[def.name] = this.output[def.name]
grouped._none[def.name] = outputValue.value
}

@@ -29,0 +32,0 @@ })

'use strict'
/**
* A module for testing for and extracting names from options (e.g. `--one`, `-o`)
*
* @module option
* @private
*/
class Arg {
constructor (re) {
this.re = re
}
class ArgRegExp extends RegExp {
name (arg) {
return arg.match(this.re)[1]
return arg.match(this)[1]
}
test (arg) {
return this.re.test(arg)
}
}
const option = {
short: new Arg(/^-([^\d-])$/),
long: new Arg(/^--(\S+)/),
combined: new Arg(/^-([^\d-]{2,})$/),
isOption (arg) { return this.short.test(arg) || this.long.test(arg) },
optEquals: new Arg(/^(--\S+?)=(.*)/),
VALUE_MARKER: '552f3a31-14cd-4ced-bd67-656a659e9efb' // must be unique
}
module.exports = option
exports.short = new ArgRegExp('^-([^\\d-])$')
exports.long = new ArgRegExp('^--(\\S+)')
exports.combined = new ArgRegExp('^-([^\\d-]{2,})$')
exports.isOption = arg => exports.short.test(arg) || exports.long.test(arg)
exports.optEquals = new ArgRegExp('^(--\\S+?)=(.*)')
exports.VALUE_MARKER = '552f3a31-14cd-4ced-bd67-656a659e9efb' // must be unique

@@ -5,11 +5,20 @@ 'use strict'

class OutputValue {
constructor (value) {
this.value = value
this.hasDefaultArrayValue = false
this.valueSource = 'unknown'
}
isDefined () {
return t.isDefined(this.value)
}
}
class Output {
constructor (defs, options) {
constructor (definitions, options) {
this.options = options || {}
this.output = {}
this.hasDefaultArrayValue = {}
this.unknown = []
const Definitions = require('./definitions')
this.definitions = new Definitions()
this.definitions.load(defs)
this.definitions = definitions
this._assignDefaultValues()

@@ -21,6 +30,12 @@ }

if (t.isDefined(def.defaultValue)) {
this.output[def.name] = def.multiple ? arrayify(def.defaultValue) : def.defaultValue
if (def.multiple) {
this.hasDefaultArrayValue[def.name] = true
this.output[def.name] = new OutputValue(arrayify(def.defaultValue))
this.output[def.name].hasDefaultArrayValue = true
} else {
this.output[def.name] = new OutputValue(def.defaultValue)
}
this.output[def.name].valueSource = 'default'
} else {
/* guarantees a `multiple` returns an array, even without a defaultValue */
if (def.multiple) this.output[def.name] = new OutputValue([])
}

@@ -30,76 +45,89 @@ })

/**
* Return `true` when an option value was set and is not a multiple. Return `false` if option was a multiple or if a value was not yet set.
*/
set (optionArg, value) {
/* if the value marker is present at the beginning, strip it */
const option = require('./option')
const reBeginsWithValueMarker = new RegExp('^' + option.VALUE_MARKER)
const isOptionValueNotationValue = reBeginsWithValueMarker.test(value)
value = isOptionValueNotationValue
? value.replace(reBeginsWithValueMarker, '')
: value
setFlag (optionArg) {
const def = this.definitions.get(optionArg)
/* lookup the definition.. if no optionArg (--option) was supplied, use the defaultOption */
let def
if (t.isDefined(optionArg)) {
def = this.definitions.get(optionArg)
} else {
def = this.definitions.getDefault()
if (def) {
/* if it's not a `multiple` and the defaultOption has already been set, move on */
if (!def.multiple && t.isDefined(this.output[def.name]) && this.output[def.name] !== def.defaultValue) {
if (t.isDefined(value)) this.unknown.push(value)
return true
/* in the case we're setting an --option=value value on a multiple defaultOption, tag the value onto the previous unknown */
} else if (def.multiple && isOptionValueNotationValue && t.isDefined(this.output[def.name])) {
if (t.isDefined(value) && this.unknown.length) {
this.unknown[this.unknown.length - 1] += `=${value}`
return true
}
}
}
}
if (def) {
this.output[def.name] = this.output[def.name] || new OutputValue()
const outputValue = this.output[def.name]
/* if there's no definition or defaultOption, do nothing and continue */
if (!def) {
if (t.isDefined(optionArg)) this.unknown.push(optionArg)
if (t.isDefined(value)) {
if (isOptionValueNotationValue) {
this.unknown[this.unknown.length - 1] += `=${value}`
/* for boolean types, set value to `true`. For all other types run value through setter function. */
if (def.isBoolean()) {
if (Array.isArray(outputValue.value)) {
outputValue.value.push(true)
} else {
this.unknown.push(value)
outputValue.value = true
}
return true
} else {
if (!Array.isArray(outputValue.value) && outputValue.valueSource === 'unknown') outputValue.value = null
return false
}
} else {
this.unknown.push(optionArg)
return true
}
}
const name = def.name
setOptionValue (optionArg, value) {
const ValueArg = require('./value-arg')
const valueArg = new ValueArg(value)
/* if not already initialised, set a `multiple` value to a new array. */
if (def.multiple && !t.isDefined(this.output[name])) this.output[name] = []
const def = this.definitions.get(optionArg)
/* for boolean types, set value to `true`. For all other types run value through setter function. */
if (def.isBoolean()) {
value = true
} else if (t.isDefined(value)) {
value = def.type ? def.type(value) : value
this.output[def.name] = this.output[def.name] || new OutputValue()
const outputValue = this.output[def.name]
/* run value through setter function. */
valueArg.value = def.type(valueArg.value)
outputValue.valueSource = 'argv'
if (Array.isArray(outputValue.value)) {
if (outputValue.hasDefaultArrayValue) {
outputValue.value = [ valueArg.value ]
outputValue.hasDefaultArrayValue = false
} else {
outputValue.value.push(valueArg.value)
}
return false
} else {
outputValue.value = valueArg.value
return true
}
}
if (t.isDefined(value)) {
if (Array.isArray(this.output[name])) {
if (this.hasDefaultArrayValue[name]) {
this.output[name] = [ value ]
delete this.hasDefaultArrayValue[name]
/**
* Return `true` when an option value was set and is not a multiple. Return `false` if option was a multiple or if a value was not yet set.
*/
setValue (value) {
const ValueArg = require('./value-arg')
const valueArg = new ValueArg(value)
/* use the defaultOption */
const def = this.definitions.getDefault()
/* handle unknown values in the case a value was already set on a defaultOption */
if (def) {
const currentValue = this.output[def.name]
if (valueArg.isDefined() && currentValue && t.isDefined(currentValue.value)) {
if (def.multiple) {
/* in the case we're setting an --option=value value on a multiple defaultOption, tag the value onto the previous unknown */
if (valueArg.isOptionValueNotationValue && this.unknown.length) {
this.unknown[this.unknown.length - 1] += `=${valueArg.value}`
return true
}
} else {
this.output[name].push(value)
/* currentValue has already been set by argv,log this value as unknown and move on */
if (currentValue.valueSource === 'argv') {
this.unknown.push(valueArg.value)
return true
}
}
return false
}
return this.setOptionValue(`--${def.name}`, value)
} else {
if (valueArg.isOptionValueNotationValue) {
this.unknown[this.unknown.length - 1] += `=${valueArg.value}`
} else {
this.output[name] = value
return true
this.unknown.push(valueArg.value)
}
} else {
if (!Array.isArray(this.output[name])) this.output[name] = null
return false
return true
}

@@ -109,13 +137,15 @@ }

get (name) {
return this.output[name]
return this.output[name] && this.output[name].value
}
toObject () {
let output
let output = Object.assign({}, this.output)
if (this.options.partial && this.unknown.length) {
output = Object.assign({}, this.output)
output._unknown = this.unknown
} else {
output = this.output
}
for (const prop in output) {
if (prop !== '_unknown') {
output[prop] = output[prop].value
}
}
return output

@@ -122,0 +152,0 @@ }

{
"name": "command-line-args",
"version": "4.0.3",
"version": "4.0.4",
"description": "A mature, feature-complete library to parse command-line options.",

@@ -5,0 +5,0 @@ "repository": "https://github.com/75lb/command-line-args.git",

@@ -31,1 +31,19 @@ 'use strict'

})
runner.test('bad-input: empty string', function () {
const definitions = [
{ name: 'one', type: String },
{ name: 'two', type: Number },
{ name: 'three', type: Number, multiple: true },
{ name: 'four', type: String },
{ name: 'five', type: Boolean }
]
const argv = [ '--one', '', '', '--two', '0', '--three=', '', '--four=', '--five=' ]
a.deepStrictEqual(commandLineArgs(definitions, { argv }), {
one: '',
two: 0,
three: [ 0, 0 ],
four: '',
five: true
})
})

@@ -5,41 +5,95 @@ 'use strict'

const Output = require('../lib/output')
const Definitions = require('../lib/definitions')
const runner = new TestRunner()
runner.test('output.set(name): initial value', function () {
let definitions = [
runner.test('output.setFlag(name): initial value', function () {
let definitions = new Definitions()
definitions.load([
{ name: 'one', type: Number }
]
])
let output = new Output(definitions)
a.strictEqual(output.get('one'), undefined)
output.set('--one')
output.setFlag('--one')
a.strictEqual(output.get('one'), null)
definitions = [
definitions.load([
{ name: 'one', type: Boolean }
]
])
output = new Output(definitions)
a.strictEqual(output.get('one'), undefined)
output.set('--one')
output.setFlag('--one')
a.strictEqual(output.get('one'), true)
})
runner.test('output.set(name, value)', function () {
const definitions = [
runner.test('output.setOptionValue(name, value)', function () {
const definitions = new Definitions()
definitions.load([
{ name: 'one', type: Number, defaultValue: 1 }
]
])
const output = new Output(definitions)
a.strictEqual(output.get('one'), 1)
output.set('--one', '2')
output.setOptionValue('--one', '2')
a.strictEqual(output.get('one'), 2)
})
runner.test('output.set(name, value): multiple', function () {
const definitions = [
runner.test('output.setOptionValue(name, value): multiple, defaultValue', function () {
const definitions = new Definitions()
definitions.load([
{ name: 'one', type: Number, multiple: true, defaultValue: [ 1 ] }
]
])
const output = new Output(definitions)
a.deepStrictEqual(output.get('one'), [ 1 ])
output.set('--one', '2')
output.setOptionValue('--one', '2')
a.deepStrictEqual(output.get('one'), [ 2 ])
})
runner.test('output.setOptionValue(name, value): multiple 2', function () {
const definitions = new Definitions()
definitions.load([
{ name: 'one', type: Number, multiple: true }
])
const output = new Output(definitions)
a.deepStrictEqual(output.get('one'), [ ])
output.setOptionValue('--one', '2')
a.deepStrictEqual(output.get('one'), [ 2 ])
output.setOptionValue('--one', '3')
a.deepStrictEqual(output.get('one'), [ 2, 3 ])
})
runner.test('output.setValue(value): no defaultOption', function () {
const definitions = new Definitions()
definitions.load([
{ name: 'one', type: Number }
])
const output = new Output(definitions)
a.deepStrictEqual(output.get('one'), undefined)
output.setValue('2')
a.deepStrictEqual(output.get('one'), undefined)
a.deepStrictEqual(output.unknown, [ '2' ])
})
runner.test('output.setValue(value): with defaultOption', function () {
const definitions = new Definitions()
definitions.load([
{ name: 'one', type: Number, defaultOption: true }
])
const output = new Output(definitions)
a.deepStrictEqual(output.get('one'), undefined)
output.setValue('2')
a.deepStrictEqual(output.get('one'), 2)
a.deepStrictEqual(output.unknown, [])
})
runner.test('output.setValue(value): multiple', function () {
const definitions = new Definitions()
definitions.load([
{ name: 'one', multiple: true, defaultOption: true }
])
const output = new Output(definitions)
a.deepStrictEqual(output.get('one'), [])
output.setValue('1')
a.deepStrictEqual(output.get('one'), [ '1' ])
output.setValue('2')
a.deepStrictEqual(output.get('one'), [ '1', '2' ])
})

@@ -76,3 +76,3 @@ 'use strict'

const defs = [
{ name: 'path', defaultOption: true, defaultValue: './' },
{ name: 'path', defaultOption: true, defaultValue: './' }
]

@@ -93,1 +93,55 @@

})
runner.test('default value: combined with multiple and defaultOption', function () {
const defs = [
{ name: 'path', multiple: true, defaultOption: true, defaultValue: './' }
]
let argv = [ '--path', 'test1', 'test2' ]
a.deepStrictEqual(commandLineArgs(defs, { argv }), {
path: [ 'test1', 'test2' ]
})
argv = [ '--path', 'test' ]
a.deepStrictEqual(commandLineArgs(defs, { argv }), {
path: [ 'test' ]
})
argv = [ 'test1', 'test2' ]
a.deepStrictEqual(commandLineArgs(defs, { argv }), {
path: [ 'test1', 'test2' ]
})
argv = [ 'test' ]
a.deepStrictEqual(commandLineArgs(defs, { argv }), {
path: [ 'test' ]
})
argv = [ ]
a.deepStrictEqual(commandLineArgs(defs, { argv }), {
path: [ './' ]
})
})
runner.test('default value: array default combined with multiple and defaultOption', function () {
const defs = [
{ name: 'path', multiple: true, defaultOption: true, defaultValue: [ './' ] }
]
let argv = [ '--path', 'test1', 'test2' ]
a.deepStrictEqual(commandLineArgs(defs, { argv }), {
path: [ 'test1', 'test2' ]
})
argv = [ '--path', 'test' ]
a.deepStrictEqual(commandLineArgs(defs, { argv }), {
path: [ 'test' ]
})
argv = [ 'test1', 'test2' ]
a.deepStrictEqual(commandLineArgs(defs, { argv }), {
path: [ 'test1', 'test2' ]
})
argv = [ 'test' ]
a.deepStrictEqual(commandLineArgs(defs, { argv }), {
path: [ 'test' ]
})
argv = [ ]
a.deepStrictEqual(commandLineArgs(defs, { argv }), {
path: [ './' ]
})
})

@@ -175,1 +175,3 @@ 'use strict'

})
runner.test('err-invalid-defaultOption: defaultOption on a Boolean type')

@@ -6,12 +6,13 @@ 'use strict'

const definitions = [
{ name: 'one', group: 'a' },
{ name: 'two', group: 'a' },
{ name: 'three', group: 'b' }
]
const runner = new TestRunner()
runner.test('groups', function () {
a.deepStrictEqual(commandLineArgs(definitions, { argv: [ '--one', '1', '--two', '2', '--three', '3' ] }), {
const definitions = [
{ name: 'one', group: 'a' },
{ name: 'two', group: 'a' },
{ name: 'three', group: 'b' }
]
const argv = [ '--one', '1', '--two', '2', '--three', '3' ]
const output = commandLineArgs(definitions, { argv })
a.deepStrictEqual(output, {
a: {

@@ -60,1 +61,62 @@ one: '1',

})
runner.test('groups: nothing set', function () {
const definitions = [
{ name: 'one', group: 'a' },
{ name: 'two', group: 'a' },
{ name: 'three', group: 'b' }
]
const argv = [ ]
const output = commandLineArgs(definitions, { argv })
a.deepStrictEqual(output, {
a: {},
b: {},
_all: {}
})
})
runner.test('groups: nothing set with one ungrouped', function () {
const definitions = [
{ name: 'one', group: 'a' },
{ name: 'two', group: 'a' },
{ name: 'three' }
]
const argv = [ ]
const output = commandLineArgs(definitions, { argv })
a.deepStrictEqual(output, {
a: {},
_all: {}
})
})
runner.test('groups: two ungrouped, one set', function () {
const definitions = [
{ name: 'one', group: 'a' },
{ name: 'two', group: 'a' },
{ name: 'three' },
{ name: 'four' }
]
const argv = [ '--three', '3' ]
const output = commandLineArgs(definitions, { argv })
a.deepStrictEqual(output, {
a: {},
_all: { three: '3' },
_none: { three: '3' }
})
})
runner.test('groups: two ungrouped, both set', function () {
const definitions = [
{ name: 'one', group: 'a' },
{ name: 'two', group: 'a' },
{ name: 'three' },
{ name: 'four' }
]
const argv = [ '--three', '3', '--four', '4' ]
const output = commandLineArgs(definitions, { argv })
a.deepStrictEqual(output, {
a: {},
_all: { three: '3', four: '4' },
_none: { three: '3', four: '4' }
})
})

@@ -48,2 +48,26 @@ 'use strict'

runner.test('partial: defaultOption with value equal to defaultValue', function () {
const definitions = [
{ name: 'file', type: String, defaultOption: true, defaultValue: 'file1' }
]
const argv = [ 'file1', '--two=3', '--four', '5' ]
const options = commandLineArgs(definitions, { argv, partial: true })
a.deepStrictEqual(options, {
file: 'file1',
_unknown: [ '--two', '3', '--four', '5' ]
})
})
runner.test('partial: defaultOption with value equal to defaultValue 2', function () {
const definitions = [
{ name: 'file', type: String, defaultOption: true, defaultValue: 'file1' }
]
const argv = [ '--file', '--file=file1', '--two=3', '--four', '5' ]
const options = commandLineArgs(definitions, { argv, partial: true })
a.deepStrictEqual(options, {
file: 'file1',
_unknown: [ '--two', '3', '--four', '5' ]
})
})
runner.test('partial: multiple', function () {

@@ -50,0 +74,0 @@ const definitions = [

@@ -60,1 +60,12 @@ 'use strict'

})
runner.test('type-boolean-multiple: 1', function () {
const definitions = [
{ name: 'array', type: Boolean, multiple: true }
]
const argv = [ '--array', '--array', '--array' ]
const result = commandLineArgs(definitions, { argv })
a.deepStrictEqual(result, {
array: [ true, true, true ]
})
})

@@ -6,9 +6,8 @@ 'use strict'

const optionDefinitions = [
{ name: 'one', type: Number }
]
const runner = new TestRunner()
runner.test('type-number: different values', function () {
const optionDefinitions = [
{ name: 'one', type: Number }
]
a.deepStrictEqual(

@@ -29,1 +28,29 @@ commandLineArgs(optionDefinitions, { argv: [ '--one', '1' ] }),

})
runner.test('number multiple: 1', function () {
const optionDefinitions = [
{ name: 'array', type: Number, multiple: true }
]
const argv = [ '--array', '1', '2', '3' ]
const result = commandLineArgs(optionDefinitions, { argv })
a.deepStrictEqual(result, {
array: [ 1, 2, 3 ]
})
a.notDeepStrictEqual(result, {
array: [ '1', '2', '3' ]
})
})
runner.test('number multiple: 2', function () {
const optionDefinitions = [
{ name: 'array', type: Number, multiple: true }
]
const argv = [ '--array', '1', '--array', '2', '--array', '3' ]
const result = commandLineArgs(optionDefinitions, { argv })
a.deepStrictEqual(result, {
array: [ 1, 2, 3 ]
})
a.notDeepStrictEqual(result, {
array: [ '1', '2', '3' ]
})
})

@@ -41,1 +41,26 @@ 'use strict'

})
runner.test('type-other-multiple: different values', function () {
const definitions = [
{
name: 'file',
multiple: true,
type: function (file) {
return file
}
}
]
a.deepStrictEqual(
commandLineArgs(definitions, { argv: [ '--file', 'one.js' ] }),
{ file: [ 'one.js' ] }
)
a.deepStrictEqual(
commandLineArgs(definitions, { argv: [ '--file', 'one.js', 'two.js' ] }),
{ file: [ 'one.js', 'two.js' ] }
)
a.deepStrictEqual(
commandLineArgs(definitions, { argv: [ '--file' ] }),
{ file: [] }
)
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc