@boost/args
Advanced tools
Comparing version 2.3.0 to 2.3.1
@@ -6,2 +6,14 @@ # Change Log | ||
### 2.3.1 - 2021-02-08 | ||
#### 🛠 Internals | ||
- Sort type hints and aliases. ([1c49e33](https://github.com/milesj/boost/commit/1c49e33)) | ||
**Note:** Version bump only for package @boost/args | ||
## 2.3.0 - 2021-01-16 | ||
@@ -8,0 +20,0 @@ |
@@ -14,3 +14,3 @@ import { ArgsErrorCode } from './ArgsError'; | ||
checkNoInlineValue(inlineValue?: string): void; | ||
checkUnknownOption(option: ShortOptionName | LongOptionName): void; | ||
checkUnknownOption(option: LongOptionName | ShortOptionName): void; | ||
validateArityIsMet(option: LongOptionName, config: OptionConfig, value: ValueType): void; | ||
@@ -17,0 +17,0 @@ validateDefaultValue(option: LongOptionName, value: unknown, config: OptionConfig): void; |
@@ -7,3 +7,3 @@ import { CommandChecker } from '../types'; | ||
*/ | ||
export default function isCommand(arg: string, commandCheck: string[] | CommandChecker): boolean; | ||
export default function isCommand(arg: string, commandCheck: CommandChecker | string[]): boolean; | ||
//# sourceMappingURL=isCommand.d.ts.map |
@@ -7,3 +7,3 @@ import { LongOptionName, OptionConfig, ValueType } from './types'; | ||
unknown: boolean; | ||
value?: string | string[]; | ||
value?: string[] | string; | ||
constructor(name: LongOptionName, config?: OptionConfig); | ||
@@ -10,0 +10,0 @@ get flag(): boolean; |
@@ -5,4 +5,4 @@ export declare type Argv = string[]; | ||
export declare type ScalarType = number | string; | ||
export declare type PrimitiveType = boolean | ScalarType; | ||
export declare type ValueType = PrimitiveType | ListType; | ||
export declare type PrimitiveType = ScalarType | boolean; | ||
export declare type ValueType = ListType | PrimitiveType; | ||
export interface OptionMap { | ||
@@ -58,3 +58,3 @@ [option: string]: ValueType; | ||
export interface ParserOptions<O extends object, P extends PrimitiveType[] = ArgList> extends ParserSettings { | ||
commands?: string[] | CommandChecker; | ||
commands?: CommandChecker | string[]; | ||
options: MapOptionConfig<O>; | ||
@@ -70,5 +70,5 @@ params?: MapParamConfig<P>; | ||
category?: string; | ||
usage?: string | string[]; | ||
usage?: string[] | string; | ||
} | ||
export declare type InferArgType<T> = T extends boolean ? 'boolean' : T extends number | number[] ? 'number' : 'string'; | ||
export declare type InferArgType<T> = T extends boolean ? 'boolean' : T extends number[] | number ? 'number' : 'string'; | ||
export interface Arg<T> extends Config { | ||
@@ -118,3 +118,3 @@ default?: T; | ||
export declare type LongOptionName = string; | ||
export declare type ShortOptionName = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'; | ||
export declare type ShortOptionName = 'A' | 'a' | 'B' | 'b' | 'C' | 'c' | 'D' | 'd' | 'E' | 'e' | 'F' | 'f' | 'G' | 'g' | 'H' | 'h' | 'I' | 'i' | 'J' | 'j' | 'K' | 'k' | 'L' | 'l' | 'M' | 'm' | 'N' | 'n' | 'O' | 'o' | 'P' | 'p' | 'Q' | 'q' | 'R' | 'r' | 'S' | 's' | 'T' | 't' | 'U' | 'u' | 'V' | 'v' | 'W' | 'w' | 'X' | 'x' | 'Y' | 'y' | 'Z' | 'z'; | ||
//# sourceMappingURL=types.d.ts.map |
168
lib/index.js
@@ -0,1 +1,3 @@ | ||
// Generated with Packemon: https://packemon.dev | ||
// Platform: node, Support: stable, Format: lib | ||
'use strict'; | ||
@@ -17,3 +19,3 @@ | ||
var levenary__default = _interopDefaultLegacy(levenary); | ||
var levenary__default = /*#__PURE__*/_interopDefaultLegacy(levenary); | ||
@@ -63,8 +65,9 @@ const errors = { | ||
}) { | ||
const args = []; | ||
const args = []; // Commands | ||
if (command.length > 0) { | ||
args.push(command.join(':')); | ||
} | ||
} // Options | ||
Object.entries(options).forEach(([name, value]) => { | ||
@@ -76,8 +79,9 @@ if (typeof value === 'boolean') { | ||
} | ||
}); | ||
}); // Params | ||
if (params.length > 0) { | ||
args.push(...mapToStringList(params)); | ||
} | ||
} // Rest | ||
if (rest.length > 0) { | ||
@@ -88,11 +92,23 @@ args.push('--', ...mapToStringList(rest)); | ||
return args; | ||
} | ||
} // Default values for option types. | ||
const DEFAULT_BOOLEAN_VALUE = false; | ||
const DEFAULT_NUMBER_VALUE = 0; | ||
const DEFAULT_STRING_VALUE = ''; | ||
const COMMAND_FORMAT = /^[a-z][-a-z0-9:]*[a-z]$/iu; | ||
const LONG_OPTION_FORMAT = /^--[a-z][-a-z0-9]+$/iu; | ||
const SHORT_OPTION_FORMAT = /^-[a-z]{1}$/iu; | ||
const SHORT_OPTION_GROUP_FORMAT = /^-[a-z]{2,}$/iu; | ||
const DEFAULT_STRING_VALUE = ''; // Supports letters, numbers, dashes, and camel case. | ||
// Minimum 2 characters. Must start and end with a letter. | ||
const COMMAND_FORMAT = /^[a-z][-a-z0-9:]*[a-z]$/iu; // Double dash followed by a long name. | ||
// Supports letters, numbers, dashes, and camel case. | ||
// Minimum 2 characters. Must start with a letter. | ||
const LONG_OPTION_FORMAT = /^--[a-z][-a-z0-9]+$/iu; // Single dash followed by a short name. | ||
// Exactly 1 character. | ||
const SHORT_OPTION_FORMAT = /^-[a-z]{1}$/iu; // Single dash followed by N short names. | ||
// Minimum 2 characters, otherwise its a single short option. | ||
const SHORT_OPTION_GROUP_FORMAT = /^-[a-z]{2,}$/iu; // Pattern to match all the above, with the addition | ||
// of an inline value check. | ||
const OPTION_LIKE = /^-{1,2}[a-z][-a-z0-9]*=?/iu; | ||
@@ -354,3 +370,3 @@ | ||
config | ||
} = this; | ||
} = this; // Update the scope with this new value | ||
@@ -361,4 +377,6 @@ if (config.multiple) { | ||
this.value = value; | ||
} | ||
} // Commit scope when a single value is set, | ||
// or when a multiple arity is met. | ||
if (!config.multiple || config.arity && Array.isArray(this.value) && this.value.length >= config.arity) { | ||
@@ -377,3 +395,3 @@ commit(); | ||
let name = optionName; | ||
let negated = false; | ||
let negated = false; // Check for negated types | ||
@@ -383,10 +401,13 @@ if (name.slice(0, 3) === 'no-') { | ||
name = name.slice(3); | ||
} | ||
} // Convert option to camel case | ||
if (name.includes('-')) { | ||
name = camelCase(name); | ||
} | ||
} // Create scope | ||
const scope = new Scope(name, optionConfigs[name]); | ||
scope.negated = negated; | ||
scope.negated = negated; // When capturing multiples, we need to persist the array | ||
// so we can append. Avoid using the default array though. | ||
@@ -399,3 +420,7 @@ if (scope.config.multiple) { | ||
} | ||
/** | ||
* Expand a short option name to a long option name. | ||
*/ | ||
function expandShortOption(short, map, loose) { | ||
@@ -430,3 +455,9 @@ if (!map[short]) { | ||
} | ||
/** | ||
* Check that an argument is a command by looping through a list of available | ||
* commands, or running a command checking function. If an exact match, | ||
* or looks like a sub-command ("cmd:sub") return true. | ||
*/ | ||
function isCommand(arg, commandCheck) { | ||
@@ -447,3 +478,8 @@ if (Array.isArray(commandCheck) && commandCheck.length > 0) { | ||
} | ||
/** | ||
* Check that an argument looks like a long option, short option, | ||
* or short option group. Do not return true for negative numbers. | ||
*/ | ||
function isOptionLike(arg) { | ||
@@ -484,14 +520,20 @@ return OPTION_LIKE.test(arg); | ||
} | ||
/* eslint-disable no-param-reassign */ | ||
/** | ||
* Expand a group of short option names to a list of long option names. | ||
*/ | ||
function processShortOptionGroup(group, configs, options, map, loose) { | ||
group.split('').forEach(short => { | ||
const name = expandShortOption(short, map, loose); | ||
const config = configs[name]; | ||
const config = configs[name]; // Loose mode, always be a flag | ||
if (loose && !config) { | ||
options[name] = true; | ||
options[name] = true; // Unknown option | ||
} else if (!config || config.type === 'string') { | ||
throw new ArgsError('GROUP_UNSUPPORTED_TYPE'); | ||
throw new ArgsError('GROUP_UNSUPPORTED_TYPE'); // Boolean option, flag | ||
} else if (config.type === 'boolean') { | ||
options[name] = true; | ||
options[name] = true; // Number option, counter | ||
} else if (config.type === 'number') { | ||
@@ -506,3 +548,24 @@ if (config.count) { | ||
} | ||
/* eslint-disable complexity, no-continue */ | ||
// TERMINOLOGY | ||
// command line - The entire line that encompasses the following parts. | ||
// arg - Each type of argument (or part) passed on the command line, separated by a space. | ||
// command - An optional "command" being ran that allows for branching functionality. | ||
// Sub-commands are separated with ":". | ||
// option - An optional argument that requires a value(s). Starts with "--" (long) or "-" (short). | ||
// flag - A specialized option that only supports booleans. Can be toggled on an off (default). | ||
// param - An optional or required argument, that is not an option or option value, | ||
// Supports any raw value, and enforces a defined order. | ||
// rest - All remaining arguments that appear after a stand alone "--". | ||
// Usually passed to subsequent scripts. | ||
// scope - Argument currently being parsed. | ||
// FEATURES | ||
// Short name - A short name (single character) for an existing option or flag: --verbose, -v | ||
// Option grouping - When multiple short options are passed under a single option: -abc | ||
// Inline values - Option values that are immediately set using an equals sign: --foo=bar | ||
// Group count - Increment a number each time a short option is found in a group: -vvv | ||
// Arity count - Required number of argument values to consume for multiples. | ||
// Choices - List of valid values to choose from. Errors otherwise. | ||
function parse(argv, parserOptions) { | ||
@@ -536,3 +599,3 @@ const { | ||
finalValue | ||
} = currentScope; | ||
} = currentScope; // Support loose mode | ||
@@ -544,7 +607,9 @@ if (looseMode) { | ||
options[name] = finalValue; | ||
} | ||
} // Set an unknown value | ||
} else if (currentScope.unknown) { | ||
if (allowUnknown) { | ||
unknown[name] = value === undefined ? DEFAULT_STRING_VALUE : String(finalValue); | ||
} | ||
} // Set and cast value if defined | ||
} else if (value !== undefined) { | ||
@@ -555,4 +620,5 @@ options[name] = finalValue; | ||
currentScope = null; | ||
} | ||
} // Run validations and map defaults | ||
checker.validateParamOrder(paramConfigs); | ||
@@ -583,3 +649,3 @@ mapParserOptions(parserOptions, options, params, { | ||
}); | ||
}); // Process each argument | ||
@@ -589,3 +655,3 @@ for (let i = 0; i < argv.length; i += 1) { | ||
checker.arg = arg; | ||
checker.argIndex = i; | ||
checker.argIndex = i; // Rest arguments found, extract remaining and exit | ||
@@ -598,30 +664,34 @@ if (arg === '--') { | ||
try { | ||
// Options | ||
if (isOptionLike(arg)) { | ||
let optionName = arg; | ||
let inlineValue; | ||
commitScope(); | ||
let inlineValue; // Commit previous scope | ||
commitScope(); // Extract option and inline value | ||
if (optionName.includes('=')) { | ||
[optionName, inlineValue] = optionName.split('=', 2); | ||
} | ||
} // Short option group "-frl" | ||
if (isShortOptionGroup(optionName)) { | ||
checker.checkNoInlineValue(inlineValue); | ||
processShortOptionGroup(optionName.slice(1), optionConfigs, options, mapping, looseMode); | ||
continue; | ||
continue; // Short option "-f" | ||
} else if (isShortOption(optionName)) { | ||
optionName = expandShortOption(optionName.slice(1), mapping, looseMode); | ||
optionName = expandShortOption(optionName.slice(1), mapping, looseMode); // Long option "--foo" | ||
} else if (isLongOption(optionName)) { | ||
optionName = optionName.slice(2); | ||
} | ||
} // Parse and create next scope | ||
const scope = createScope(optionName, optionConfigs, options); | ||
const scope = createScope(optionName, optionConfigs, options); // Unknown option found, handle accordingly | ||
if (scope.unknown && !allowUnknown && !looseMode) { | ||
checker.checkUnknownOption(arg); | ||
checker.checkUnknownOption(arg); // Flag found, so set value immediately and discard scope | ||
} else if (scope.flag) { | ||
options[scope.name] = !scope.negated; | ||
checker.checkNoInlineValue(inlineValue); | ||
checker.checkNoInlineValue(inlineValue); // Otherwise keep scope open, to capture next value | ||
} else { | ||
currentScope = scope; | ||
currentScope = scope; // Update scope value if an inline value exists | ||
@@ -631,5 +701,6 @@ if (inlineValue !== undefined) { | ||
} | ||
} | ||
} // Option values | ||
} else if (currentScope) { | ||
currentScope.captureValue(arg, commitScope); | ||
currentScope.captureValue(arg, commitScope); // Commands | ||
} else if (isCommand(arg, commandConfigs)) { | ||
@@ -640,3 +711,4 @@ checker.checkCommandOrder(arg, command, params.length); | ||
command = arg; | ||
} | ||
} // Params | ||
} else if (paramConfigs[params.length]) { | ||
@@ -655,6 +727,7 @@ const config = paramConfigs[params.length]; | ||
} | ||
} | ||
} // Commit final scope | ||
commitScope(); | ||
commitScope(); // Fill missing params | ||
for (let i = params.length; i < paramConfigs.length; i += 1) { | ||
@@ -668,4 +741,5 @@ const config = paramConfigs[i]; | ||
params.push(getDefaultValue(config)); | ||
} | ||
} // Run final checks | ||
mapParserOptions(parserOptions, options, params, { | ||
@@ -675,3 +749,4 @@ onOption(config, value, name) { | ||
checker.validateArityIsMet(name, config, value); | ||
checker.validateChoiceIsMet(name, config, value); | ||
checker.validateChoiceIsMet(name, config, value); // Since default values avoid scope, | ||
// they are not cast. Do it manually after parsing. | ||
@@ -699,7 +774,8 @@ if (value === getDefaultValue(config)) { | ||
function parseInContext(argv, context) { | ||
let options; | ||
let options; // Loop through each arg until we find a context | ||
argv.some(arg => { | ||
options = context(arg, argv); | ||
return !!options; | ||
}); | ||
}); // Fail if context not found | ||
@@ -706,0 +782,0 @@ if (!options) { |
{ | ||
"name": "@boost/args", | ||
"version": "2.3.0", | ||
"version": "2.3.1", | ||
"release": "1594765247526", | ||
@@ -33,3 +33,3 @@ "description": "A convention based argument parsing and formatting library, with strict validation checks.", | ||
"dependencies": { | ||
"@boost/internal": "^2.2.0", | ||
"@boost/internal": "^2.2.1", | ||
"levenary": "^1.1.1" | ||
@@ -40,3 +40,3 @@ }, | ||
}, | ||
"gitHead": "e2c452ee0c15aa7db91d1945e23ac6951028e672" | ||
"gitHead": "3aa9bda270786e931a90e927375c33dddffed14d" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
61044
903
0
Updated@boost/internal@^2.2.1