Comparing version 4.0.1 to 4.1.0
declare const flagSymbol: unique symbol; | ||
declare function arg<T extends arg.Spec>(spec: T, options?: {argv?: string[], permissive?: boolean}): arg.Result<T>; | ||
declare function arg<T extends arg.Spec>(spec: T, options?: arg.Options): arg.Result<T>; | ||
@@ -17,5 +17,3 @@ declare namespace arg { | ||
export type Result<T extends Spec> = { _: string[] } & { | ||
[K in keyof T]?: T[K] extends string | ||
? never | ||
: T[K] extends Handler | ||
[K in keyof T]?: T[K] extends Handler | ||
? ReturnType<T[K]> | ||
@@ -26,4 +24,10 @@ : T[K] extends [Handler] | ||
}; | ||
export interface Options { | ||
argv?: string[]; | ||
permissive?: boolean; | ||
stopAtPositional?: boolean; | ||
} | ||
} | ||
export = arg; |
61
index.js
const flagSymbol = Symbol('arg flag'); | ||
function arg(opts, {argv, permissive = false} = {}) { | ||
function arg(opts, {argv, permissive = false, stopAtPositional = false} = {}) { | ||
if (!opts) { | ||
@@ -16,2 +16,6 @@ throw new Error('Argument specification object is required'); | ||
for (const key of Object.keys(opts)) { | ||
if (!key) { | ||
throw new TypeError('Argument key cannot be an empty string'); | ||
} | ||
if (key[0] !== '-') { | ||
@@ -30,6 +34,16 @@ throw new TypeError(`Argument key must start with '-' but found: '${key}'`); | ||
const type = opts[key]; | ||
let type = opts[key]; | ||
let isFlag = false; | ||
if (!type || (typeof type !== 'function' && !(Array.isArray(type) && type.length === 1 && typeof type[0] === 'function'))) { | ||
throw new Error(`Type missing or not a function or valid array type: ${key}`); | ||
if (Array.isArray(type) && type.length === 1 && typeof type[0] === 'function') { | ||
const [fn] = type; | ||
type = (value, name, prev = []) => { | ||
prev.push(fn(value, name, prev[prev.length - 1])); | ||
return prev; | ||
}; | ||
isFlag = fn === Boolean || fn[flagSymbol] === true; | ||
} else if (typeof type === 'function') { | ||
isFlag = type === Boolean || type[flagSymbol] === true; | ||
} else { | ||
throw new TypeError(`Type missing or not a function or valid array type: ${key}`); | ||
} | ||
@@ -41,3 +55,3 @@ | ||
handlers[key] = type; | ||
handlers[key] = [type, isFlag]; | ||
} | ||
@@ -48,5 +62,5 @@ | ||
if (wholeArg.length < 2) { | ||
result._.push(wholeArg); | ||
continue; | ||
if (stopAtPositional && result._.length > 0) { | ||
result._ = result._.concat(argv.slice(i)); | ||
break; | ||
} | ||
@@ -59,3 +73,3 @@ | ||
if (wholeArg[0] === '-') { | ||
if (wholeArg.length > 1 && wholeArg[0] === '-') { | ||
/* eslint-disable operator-linebreak */ | ||
@@ -87,17 +101,10 @@ const separatedArguments = (wholeArg[1] === '-' || wholeArg.length === 2) | ||
/* eslint-disable operator-linebreak */ | ||
const [type, isArray] = Array.isArray(handlers[argName]) | ||
? [handlers[argName][0], true] | ||
: [handlers[argName], false]; | ||
/* eslint-enable operator-linebreak */ | ||
const [type, isFlag] = handlers[argName]; | ||
if (!(type === Boolean || type[flagSymbol]) && ((j + 1) < separatedArguments.length)) { | ||
if (!isFlag && ((j + 1) < separatedArguments.length)) { | ||
throw new TypeError(`Option requires argument (but was followed by another short argument): ${originalArgName}`); | ||
} | ||
let value; | ||
if (type === Boolean) { | ||
value = true; | ||
} else if (type[flagSymbol]) { | ||
value = type(true, argName, result[argName]); | ||
if (isFlag) { | ||
result[argName] = type(true, argName, result[argName]); | ||
} else if (argStr === undefined) { | ||
@@ -109,17 +116,7 @@ if (argv.length < i + 2 || (argv[i + 1].length > 1 && argv[i + 1][0] === '-')) { | ||
value = type(argv[i + 1], argName, result[argName]); | ||
result[argName] = type(argv[i + 1], argName, result[argName]); | ||
++i; | ||
} else { | ||
value = type(argStr, argName, result[argName]); | ||
result[argName] = type(argStr, argName, result[argName]); | ||
} | ||
if (isArray) { | ||
if (result[argName]) { | ||
result[argName].push(value); | ||
} else { | ||
result[argName] = [value]; | ||
} | ||
} else { | ||
result[argName] = value; | ||
} | ||
} | ||
@@ -126,0 +123,0 @@ } else { |
{ | ||
"name": "arg", | ||
"version": "4.0.1", | ||
"version": "4.1.0", | ||
"description": "Another simple argument parser", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -220,4 +220,36 @@ # Arg [![CircleCI](https://circleci.com/gh/zeit/arg.svg?style=svg)](https://circleci.com/gh/zeit/arg) | ||
#### Errors | ||
#### `stopAtPositional` | ||
When `stopAtPositional` is set to `true`, `arg` will halt parsing at the first | ||
positional argument. | ||
For example: | ||
```javascript | ||
const arg = require('arg'); | ||
const argv = ['--foo', 'hello', '--bar']; | ||
const args = arg( | ||
{ | ||
'--foo': Boolean, | ||
'--bar': Boolean | ||
}, { | ||
argv, | ||
stopAtPositional: true | ||
} | ||
); | ||
``` | ||
results in: | ||
```javascript | ||
const args = { | ||
_: ['hello', '--bar'], | ||
'--foo': true | ||
}; | ||
``` | ||
### Errors | ||
Some errors that `arg` throws provide a `.code` property in order to aid in recovering from user error, or to | ||
@@ -224,0 +256,0 @@ differentiate between user error and developer error (bug). |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
12592
281