2023-10-03 11:14:36 +08:00
'use strict' ;
var util = require ( 'util' ) ;
var fs = require ( 'fs' ) ;
var path = require ( 'path' ) ;
function camelCase ( str ) {
const isCamelCase = str !== str . toLowerCase ( ) && str !== str . toUpperCase ( ) ;
if ( ! isCamelCase ) {
str = str . toLowerCase ( ) ;
}
if ( str . indexOf ( '-' ) === - 1 && str . indexOf ( '_' ) === - 1 ) {
return str ;
}
else {
let camelcase = '' ;
let nextChrUpper = false ;
const leadingHyphens = str . match ( /^-+/ ) ;
for ( let i = leadingHyphens ? leadingHyphens [ 0 ] . length : 0 ; i < str . length ; i ++ ) {
let chr = str . charAt ( i ) ;
if ( nextChrUpper ) {
nextChrUpper = false ;
chr = chr . toUpperCase ( ) ;
}
if ( i !== 0 && ( chr === '-' || chr === '_' ) ) {
nextChrUpper = true ;
}
else if ( chr !== '-' && chr !== '_' ) {
camelcase += chr ;
}
}
return camelcase ;
}
}
function decamelize ( str , joinString ) {
const lowercase = str . toLowerCase ( ) ;
joinString = joinString || '-' ;
let notCamelcase = '' ;
for ( let i = 0 ; i < str . length ; i ++ ) {
const chrLower = lowercase . charAt ( i ) ;
const chrString = str . charAt ( i ) ;
if ( chrLower !== chrString && i > 0 ) {
notCamelcase += ` ${ joinString } ${ lowercase . charAt ( i ) } ` ;
}
else {
notCamelcase += chrString ;
}
}
return notCamelcase ;
}
function looksLikeNumber ( x ) {
if ( x === null || x === undefined )
return false ;
if ( typeof x === 'number' )
return true ;
if ( /^0x[0-9a-f]+$/i . test ( x ) )
return true ;
if ( /^0[^.]/ . test ( x ) )
return false ;
return /^[-]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/ . test ( x ) ;
}
function tokenizeArgString ( argString ) {
if ( Array . isArray ( argString ) ) {
return argString . map ( e => typeof e !== 'string' ? e + '' : e ) ;
}
argString = argString . trim ( ) ;
let i = 0 ;
let prevC = null ;
let c = null ;
let opening = null ;
const args = [ ] ;
for ( let ii = 0 ; ii < argString . length ; ii ++ ) {
prevC = c ;
c = argString . charAt ( ii ) ;
if ( c === ' ' && ! opening ) {
if ( ! ( prevC === ' ' ) ) {
i ++ ;
}
continue ;
}
if ( c === opening ) {
opening = null ;
}
else if ( ( c === "'" || c === '"' ) && ! opening ) {
opening = c ;
}
if ( ! args [ i ] )
args [ i ] = '' ;
args [ i ] += c ;
}
return args ;
}
var DefaultValuesForTypeKey ;
( function ( DefaultValuesForTypeKey ) {
DefaultValuesForTypeKey [ "BOOLEAN" ] = "boolean" ;
DefaultValuesForTypeKey [ "STRING" ] = "string" ;
DefaultValuesForTypeKey [ "NUMBER" ] = "number" ;
DefaultValuesForTypeKey [ "ARRAY" ] = "array" ;
} ) ( DefaultValuesForTypeKey || ( DefaultValuesForTypeKey = { } ) ) ;
let mixin ;
class YargsParser {
constructor ( _mixin ) {
mixin = _mixin ;
}
parse ( argsInput , options ) {
const opts = Object . assign ( {
alias : undefined ,
array : undefined ,
boolean : undefined ,
config : undefined ,
configObjects : undefined ,
configuration : undefined ,
coerce : undefined ,
count : undefined ,
default : undefined ,
envPrefix : undefined ,
narg : undefined ,
normalize : undefined ,
string : undefined ,
number : undefined ,
_ _ : undefined ,
key : undefined
} , options ) ;
const args = tokenizeArgString ( argsInput ) ;
const aliases = combineAliases ( Object . assign ( Object . create ( null ) , opts . alias ) ) ;
const configuration = Object . assign ( {
'boolean-negation' : true ,
'camel-case-expansion' : true ,
'combine-arrays' : false ,
'dot-notation' : true ,
'duplicate-arguments-array' : true ,
'flatten-duplicate-arrays' : true ,
'greedy-arrays' : true ,
'halt-at-non-option' : false ,
'nargs-eats-options' : false ,
'negation-prefix' : 'no-' ,
'parse-numbers' : true ,
'parse-positional-numbers' : true ,
'populate--' : false ,
'set-placeholder-key' : false ,
'short-option-groups' : true ,
'strip-aliased' : false ,
'strip-dashed' : false ,
'unknown-options-as-args' : false
} , opts . configuration ) ;
const defaults = Object . assign ( Object . create ( null ) , opts . default ) ;
const configObjects = opts . configObjects || [ ] ;
const envPrefix = opts . envPrefix ;
const notFlagsOption = configuration [ 'populate--' ] ;
const notFlagsArgv = notFlagsOption ? '--' : '_' ;
const newAliases = Object . create ( null ) ;
const defaulted = Object . create ( null ) ;
const _ _ = opts . _ _ || mixin . format ;
const flags = {
aliases : Object . create ( null ) ,
arrays : Object . create ( null ) ,
bools : Object . create ( null ) ,
strings : Object . create ( null ) ,
numbers : Object . create ( null ) ,
counts : Object . create ( null ) ,
normalize : Object . create ( null ) ,
configs : Object . create ( null ) ,
nargs : Object . create ( null ) ,
coercions : Object . create ( null ) ,
keys : [ ]
} ;
const negative = /^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/ ;
const negatedBoolean = new RegExp ( '^--' + configuration [ 'negation-prefix' ] + '(.+)' ) ;
[ ] . concat ( opts . array || [ ] ) . filter ( Boolean ) . forEach ( function ( opt ) {
const key = typeof opt === 'object' ? opt . key : opt ;
const assignment = Object . keys ( opt ) . map ( function ( key ) {
const arrayFlagKeys = {
boolean : 'bools' ,
string : 'strings' ,
number : 'numbers'
} ;
return arrayFlagKeys [ key ] ;
} ) . filter ( Boolean ) . pop ( ) ;
if ( assignment ) {
flags [ assignment ] [ key ] = true ;
}
flags . arrays [ key ] = true ;
flags . keys . push ( key ) ;
} ) ;
[ ] . concat ( opts . boolean || [ ] ) . filter ( Boolean ) . forEach ( function ( key ) {
flags . bools [ key ] = true ;
flags . keys . push ( key ) ;
} ) ;
[ ] . concat ( opts . string || [ ] ) . filter ( Boolean ) . forEach ( function ( key ) {
flags . strings [ key ] = true ;
flags . keys . push ( key ) ;
} ) ;
[ ] . concat ( opts . number || [ ] ) . filter ( Boolean ) . forEach ( function ( key ) {
flags . numbers [ key ] = true ;
flags . keys . push ( key ) ;
} ) ;
[ ] . concat ( opts . count || [ ] ) . filter ( Boolean ) . forEach ( function ( key ) {
flags . counts [ key ] = true ;
flags . keys . push ( key ) ;
} ) ;
[ ] . concat ( opts . normalize || [ ] ) . filter ( Boolean ) . forEach ( function ( key ) {
flags . normalize [ key ] = true ;
flags . keys . push ( key ) ;
} ) ;
if ( typeof opts . narg === 'object' ) {
Object . entries ( opts . narg ) . forEach ( ( [ key , value ] ) => {
if ( typeof value === 'number' ) {
flags . nargs [ key ] = value ;
flags . keys . push ( key ) ;
}
} ) ;
}
if ( typeof opts . coerce === 'object' ) {
Object . entries ( opts . coerce ) . forEach ( ( [ key , value ] ) => {
if ( typeof value === 'function' ) {
flags . coercions [ key ] = value ;
flags . keys . push ( key ) ;
}
} ) ;
}
if ( typeof opts . config !== 'undefined' ) {
if ( Array . isArray ( opts . config ) || typeof opts . config === 'string' ) {
[ ] . concat ( opts . config ) . filter ( Boolean ) . forEach ( function ( key ) {
flags . configs [ key ] = true ;
} ) ;
}
else if ( typeof opts . config === 'object' ) {
Object . entries ( opts . config ) . forEach ( ( [ key , value ] ) => {
if ( typeof value === 'boolean' || typeof value === 'function' ) {
flags . configs [ key ] = value ;
}
} ) ;
}
}
extendAliases ( opts . key , aliases , opts . default , flags . arrays ) ;
Object . keys ( defaults ) . forEach ( function ( key ) {
( flags . aliases [ key ] || [ ] ) . forEach ( function ( alias ) {
defaults [ alias ] = defaults [ key ] ;
} ) ;
} ) ;
let error = null ;
checkConfiguration ( ) ;
let notFlags = [ ] ;
const argv = Object . assign ( Object . create ( null ) , { _ : [ ] } ) ;
const argvReturn = { } ;
for ( let i = 0 ; i < args . length ; i ++ ) {
const arg = args [ i ] ;
const truncatedArg = arg . replace ( /^-{3,}/ , '---' ) ;
let broken ;
let key ;
let letters ;
let m ;
let next ;
let value ;
if ( arg !== '--' && isUnknownOptionAsArg ( arg ) ) {
pushPositional ( arg ) ;
}
else if ( truncatedArg . match ( /---+(=|$)/ ) ) {
pushPositional ( arg ) ;
continue ;
}
else if ( arg . match ( /^--.+=/ ) || ( ! configuration [ 'short-option-groups' ] && arg . match ( /^-.+=/ ) ) ) {
m = arg . match ( /^--?([^=]+)=([\s\S]*)$/ ) ;
if ( m !== null && Array . isArray ( m ) && m . length >= 3 ) {
if ( checkAllAliases ( m [ 1 ] , flags . arrays ) ) {
i = eatArray ( i , m [ 1 ] , args , m [ 2 ] ) ;
}
else if ( checkAllAliases ( m [ 1 ] , flags . nargs ) !== false ) {
i = eatNargs ( i , m [ 1 ] , args , m [ 2 ] ) ;
}
else {
setArg ( m [ 1 ] , m [ 2 ] ) ;
}
}
}
else if ( arg . match ( negatedBoolean ) && configuration [ 'boolean-negation' ] ) {
m = arg . match ( negatedBoolean ) ;
if ( m !== null && Array . isArray ( m ) && m . length >= 2 ) {
key = m [ 1 ] ;
setArg ( key , checkAllAliases ( key , flags . arrays ) ? [ false ] : false ) ;
}
}
else if ( arg . match ( /^--.+/ ) || ( ! configuration [ 'short-option-groups' ] && arg . match ( /^-[^-]+/ ) ) ) {
m = arg . match ( /^--?(.+)/ ) ;
if ( m !== null && Array . isArray ( m ) && m . length >= 2 ) {
key = m [ 1 ] ;
if ( checkAllAliases ( key , flags . arrays ) ) {
i = eatArray ( i , key , args ) ;
}
else if ( checkAllAliases ( key , flags . nargs ) !== false ) {
i = eatNargs ( i , key , args ) ;
}
else {
next = args [ i + 1 ] ;
if ( next !== undefined && ( ! next . match ( /^-/ ) ||
next . match ( negative ) ) &&
! checkAllAliases ( key , flags . bools ) &&
! checkAllAliases ( key , flags . counts ) ) {
setArg ( key , next ) ;
i ++ ;
}
else if ( /^(true|false)$/ . test ( next ) ) {
setArg ( key , next ) ;
i ++ ;
}
else {
setArg ( key , defaultValue ( key ) ) ;
}
}
}
}
else if ( arg . match ( /^-.\..+=/ ) ) {
m = arg . match ( /^-([^=]+)=([\s\S]*)$/ ) ;
if ( m !== null && Array . isArray ( m ) && m . length >= 3 ) {
setArg ( m [ 1 ] , m [ 2 ] ) ;
}
}
else if ( arg . match ( /^-.\..+/ ) && ! arg . match ( negative ) ) {
next = args [ i + 1 ] ;
m = arg . match ( /^-(.\..+)/ ) ;
if ( m !== null && Array . isArray ( m ) && m . length >= 2 ) {
key = m [ 1 ] ;
if ( next !== undefined && ! next . match ( /^-/ ) &&
! checkAllAliases ( key , flags . bools ) &&
! checkAllAliases ( key , flags . counts ) ) {
setArg ( key , next ) ;
i ++ ;
}
else {
setArg ( key , defaultValue ( key ) ) ;
}
}
}
else if ( arg . match ( /^-[^-]+/ ) && ! arg . match ( negative ) ) {
letters = arg . slice ( 1 , - 1 ) . split ( '' ) ;
broken = false ;
for ( let j = 0 ; j < letters . length ; j ++ ) {
next = arg . slice ( j + 2 ) ;
if ( letters [ j + 1 ] && letters [ j + 1 ] === '=' ) {
value = arg . slice ( j + 3 ) ;
key = letters [ j ] ;
if ( checkAllAliases ( key , flags . arrays ) ) {
i = eatArray ( i , key , args , value ) ;
}
else if ( checkAllAliases ( key , flags . nargs ) !== false ) {
i = eatNargs ( i , key , args , value ) ;
}
else {
setArg ( key , value ) ;
}
broken = true ;
break ;
}
if ( next === '-' ) {
setArg ( letters [ j ] , next ) ;
continue ;
}
if ( /[A-Za-z]/ . test ( letters [ j ] ) &&
/^-?\d+(\.\d*)?(e-?\d+)?$/ . test ( next ) &&
checkAllAliases ( next , flags . bools ) === false ) {
setArg ( letters [ j ] , next ) ;
broken = true ;
break ;
}
if ( letters [ j + 1 ] && letters [ j + 1 ] . match ( /\W/ ) ) {
setArg ( letters [ j ] , next ) ;
broken = true ;
break ;
}
else {
setArg ( letters [ j ] , defaultValue ( letters [ j ] ) ) ;
}
}
key = arg . slice ( - 1 ) [ 0 ] ;
if ( ! broken && key !== '-' ) {
if ( checkAllAliases ( key , flags . arrays ) ) {
i = eatArray ( i , key , args ) ;
}
else if ( checkAllAliases ( key , flags . nargs ) !== false ) {
i = eatNargs ( i , key , args ) ;
}
else {
next = args [ i + 1 ] ;
if ( next !== undefined && ( ! /^(-|--)[^-]/ . test ( next ) ||
next . match ( negative ) ) &&
! checkAllAliases ( key , flags . bools ) &&
! checkAllAliases ( key , flags . counts ) ) {
setArg ( key , next ) ;
i ++ ;
}
else if ( /^(true|false)$/ . test ( next ) ) {
setArg ( key , next ) ;
i ++ ;
}
else {
setArg ( key , defaultValue ( key ) ) ;
}
}
}
}
else if ( arg . match ( /^-[0-9]$/ ) &&
arg . match ( negative ) &&
checkAllAliases ( arg . slice ( 1 ) , flags . bools ) ) {
key = arg . slice ( 1 ) ;
setArg ( key , defaultValue ( key ) ) ;
}
else if ( arg === '--' ) {
notFlags = args . slice ( i + 1 ) ;
break ;
}
else if ( configuration [ 'halt-at-non-option' ] ) {
notFlags = args . slice ( i ) ;
break ;
}
else {
pushPositional ( arg ) ;
}
}
applyEnvVars ( argv , true ) ;
applyEnvVars ( argv , false ) ;
setConfig ( argv ) ;
setConfigObjects ( ) ;
applyDefaultsAndAliases ( argv , flags . aliases , defaults , true ) ;
applyCoercions ( argv ) ;
if ( configuration [ 'set-placeholder-key' ] )
setPlaceholderKeys ( argv ) ;
Object . keys ( flags . counts ) . forEach ( function ( key ) {
if ( ! hasKey ( argv , key . split ( '.' ) ) )
setArg ( key , 0 ) ;
} ) ;
if ( notFlagsOption && notFlags . length )
argv [ notFlagsArgv ] = [ ] ;
notFlags . forEach ( function ( key ) {
argv [ notFlagsArgv ] . push ( key ) ;
} ) ;
if ( configuration [ 'camel-case-expansion' ] && configuration [ 'strip-dashed' ] ) {
Object . keys ( argv ) . filter ( key => key !== '--' && key . includes ( '-' ) ) . forEach ( key => {
delete argv [ key ] ;
} ) ;
}
if ( configuration [ 'strip-aliased' ] ) {
[ ] . concat ( ... Object . keys ( aliases ) . map ( k => aliases [ k ] ) ) . forEach ( alias => {
if ( configuration [ 'camel-case-expansion' ] && alias . includes ( '-' ) ) {
delete argv [ alias . split ( '.' ) . map ( prop => camelCase ( prop ) ) . join ( '.' ) ] ;
}
delete argv [ alias ] ;
} ) ;
}
function pushPositional ( arg ) {
const maybeCoercedNumber = maybeCoerceNumber ( '_' , arg ) ;
if ( typeof maybeCoercedNumber === 'string' || typeof maybeCoercedNumber === 'number' ) {
argv . _ . push ( maybeCoercedNumber ) ;
}
}
function eatNargs ( i , key , args , argAfterEqualSign ) {
let ii ;
let toEat = checkAllAliases ( key , flags . nargs ) ;
toEat = typeof toEat !== 'number' || isNaN ( toEat ) ? 1 : toEat ;
if ( toEat === 0 ) {
if ( ! isUndefined ( argAfterEqualSign ) ) {
error = Error ( _ _ ( 'Argument unexpected for: %s' , key ) ) ;
}
setArg ( key , defaultValue ( key ) ) ;
return i ;
}
let available = isUndefined ( argAfterEqualSign ) ? 0 : 1 ;
if ( configuration [ 'nargs-eats-options' ] ) {
if ( args . length - ( i + 1 ) + available < toEat ) {
error = Error ( _ _ ( 'Not enough arguments following: %s' , key ) ) ;
}
available = toEat ;
}
else {
for ( ii = i + 1 ; ii < args . length ; ii ++ ) {
if ( ! args [ ii ] . match ( /^-[^0-9]/ ) || args [ ii ] . match ( negative ) || isUnknownOptionAsArg ( args [ ii ] ) )
available ++ ;
else
break ;
}
if ( available < toEat )
error = Error ( _ _ ( 'Not enough arguments following: %s' , key ) ) ;
}
let consumed = Math . min ( available , toEat ) ;
if ( ! isUndefined ( argAfterEqualSign ) && consumed > 0 ) {
setArg ( key , argAfterEqualSign ) ;
consumed -- ;
}
for ( ii = i + 1 ; ii < ( consumed + i + 1 ) ; ii ++ ) {
setArg ( key , args [ ii ] ) ;
}
return ( i + consumed ) ;
}
function eatArray ( i , key , args , argAfterEqualSign ) {
let argsToSet = [ ] ;
let next = argAfterEqualSign || args [ i + 1 ] ;
const nargsCount = checkAllAliases ( key , flags . nargs ) ;
if ( checkAllAliases ( key , flags . bools ) && ! ( /^(true|false)$/ . test ( next ) ) ) {
argsToSet . push ( true ) ;
}
else if ( isUndefined ( next ) ||
( isUndefined ( argAfterEqualSign ) && /^-/ . test ( next ) && ! negative . test ( next ) && ! isUnknownOptionAsArg ( next ) ) ) {
if ( defaults [ key ] !== undefined ) {
const defVal = defaults [ key ] ;
argsToSet = Array . isArray ( defVal ) ? defVal : [ defVal ] ;
}
}
else {
if ( ! isUndefined ( argAfterEqualSign ) ) {
argsToSet . push ( processValue ( key , argAfterEqualSign ) ) ;
}
for ( let ii = i + 1 ; ii < args . length ; ii ++ ) {
if ( ( ! configuration [ 'greedy-arrays' ] && argsToSet . length > 0 ) ||
( nargsCount && typeof nargsCount === 'number' && argsToSet . length >= nargsCount ) )
break ;
next = args [ ii ] ;
if ( /^-/ . test ( next ) && ! negative . test ( next ) && ! isUnknownOptionAsArg ( next ) )
break ;
i = ii ;
argsToSet . push ( processValue ( key , next ) ) ;
}
}
if ( typeof nargsCount === 'number' && ( ( nargsCount && argsToSet . length < nargsCount ) ||
( isNaN ( nargsCount ) && argsToSet . length === 0 ) ) ) {
error = Error ( _ _ ( 'Not enough arguments following: %s' , key ) ) ;
}
setArg ( key , argsToSet ) ;
return i ;
}
function setArg ( key , val ) {
if ( /-/ . test ( key ) && configuration [ 'camel-case-expansion' ] ) {
const alias = key . split ( '.' ) . map ( function ( prop ) {
return camelCase ( prop ) ;
} ) . join ( '.' ) ;
addNewAlias ( key , alias ) ;
}
const value = processValue ( key , val ) ;
const splitKey = key . split ( '.' ) ;
setKey ( argv , splitKey , value ) ;
if ( flags . aliases [ key ] ) {
flags . aliases [ key ] . forEach ( function ( x ) {
const keyProperties = x . split ( '.' ) ;
setKey ( argv , keyProperties , value ) ;
} ) ;
}
if ( splitKey . length > 1 && configuration [ 'dot-notation' ] ) {
( flags . aliases [ splitKey [ 0 ] ] || [ ] ) . forEach ( function ( x ) {
let keyProperties = x . split ( '.' ) ;
const a = [ ] . concat ( splitKey ) ;
a . shift ( ) ;
keyProperties = keyProperties . concat ( a ) ;
if ( ! ( flags . aliases [ key ] || [ ] ) . includes ( keyProperties . join ( '.' ) ) ) {
setKey ( argv , keyProperties , value ) ;
}
} ) ;
}
if ( checkAllAliases ( key , flags . normalize ) && ! checkAllAliases ( key , flags . arrays ) ) {
const keys = [ key ] . concat ( flags . aliases [ key ] || [ ] ) ;
keys . forEach ( function ( key ) {
Object . defineProperty ( argvReturn , key , {
enumerable : true ,
get ( ) {
return val ;
} ,
set ( value ) {
val = typeof value === 'string' ? mixin . normalize ( value ) : value ;
}
} ) ;
} ) ;
}
}
function addNewAlias ( key , alias ) {
if ( ! ( flags . aliases [ key ] && flags . aliases [ key ] . length ) ) {
flags . aliases [ key ] = [ alias ] ;
newAliases [ alias ] = true ;
}
if ( ! ( flags . aliases [ alias ] && flags . aliases [ alias ] . length ) ) {
addNewAlias ( alias , key ) ;
}
}
function processValue ( key , val ) {
if ( typeof val === 'string' &&
( val [ 0 ] === "'" || val [ 0 ] === '"' ) &&
val [ val . length - 1 ] === val [ 0 ] ) {
val = val . substring ( 1 , val . length - 1 ) ;
}
if ( checkAllAliases ( key , flags . bools ) || checkAllAliases ( key , flags . counts ) ) {
if ( typeof val === 'string' )
val = val === 'true' ;
}
let value = Array . isArray ( val )
? val . map ( function ( v ) { return maybeCoerceNumber ( key , v ) ; } )
: maybeCoerceNumber ( key , val ) ;
if ( checkAllAliases ( key , flags . counts ) && ( isUndefined ( value ) || typeof value === 'boolean' ) ) {
value = increment ( ) ;
}
if ( checkAllAliases ( key , flags . normalize ) && checkAllAliases ( key , flags . arrays ) ) {
if ( Array . isArray ( val ) )
value = val . map ( ( val ) => { return mixin . normalize ( val ) ; } ) ;
else
value = mixin . normalize ( val ) ;
}
return value ;
}
function maybeCoerceNumber ( key , value ) {
if ( ! configuration [ 'parse-positional-numbers' ] && key === '_' )
return value ;
if ( ! checkAllAliases ( key , flags . strings ) && ! checkAllAliases ( key , flags . bools ) && ! Array . isArray ( value ) ) {
const shouldCoerceNumber = looksLikeNumber ( value ) && configuration [ 'parse-numbers' ] && ( Number . isSafeInteger ( Math . floor ( parseFloat ( ` ${ value } ` ) ) ) ) ;
if ( shouldCoerceNumber || ( ! isUndefined ( value ) && checkAllAliases ( key , flags . numbers ) ) ) {
value = Number ( value ) ;
}
}
return value ;
}
function setConfig ( argv ) {
const configLookup = Object . create ( null ) ;
applyDefaultsAndAliases ( configLookup , flags . aliases , defaults ) ;
Object . keys ( flags . configs ) . forEach ( function ( configKey ) {
const configPath = argv [ configKey ] || configLookup [ configKey ] ;
if ( configPath ) {
try {
let config = null ;
const resolvedConfigPath = mixin . resolve ( mixin . cwd ( ) , configPath ) ;
const resolveConfig = flags . configs [ configKey ] ;
if ( typeof resolveConfig === 'function' ) {
try {
config = resolveConfig ( resolvedConfigPath ) ;
}
catch ( e ) {
config = e ;
}
if ( config instanceof Error ) {
error = config ;
return ;
}
}
else {
config = mixin . require ( resolvedConfigPath ) ;
}
setConfigObject ( config ) ;
}
catch ( ex ) {
if ( ex . name === 'PermissionDenied' )
error = ex ;
else if ( argv [ configKey ] )
error = Error ( _ _ ( 'Invalid JSON config file: %s' , configPath ) ) ;
}
}
} ) ;
}
function setConfigObject ( config , prev ) {
Object . keys ( config ) . forEach ( function ( key ) {
const value = config [ key ] ;
const fullKey = prev ? prev + '.' + key : key ;
if ( typeof value === 'object' && value !== null && ! Array . isArray ( value ) && configuration [ 'dot-notation' ] ) {
setConfigObject ( value , fullKey ) ;
}
else {
if ( ! hasKey ( argv , fullKey . split ( '.' ) ) || ( checkAllAliases ( fullKey , flags . arrays ) && configuration [ 'combine-arrays' ] ) ) {
setArg ( fullKey , value ) ;
}
}
} ) ;
}
function setConfigObjects ( ) {
if ( typeof configObjects !== 'undefined' ) {
configObjects . forEach ( function ( configObject ) {
setConfigObject ( configObject ) ;
} ) ;
}
}
function applyEnvVars ( argv , configOnly ) {
if ( typeof envPrefix === 'undefined' )
return ;
const prefix = typeof envPrefix === 'string' ? envPrefix : '' ;
const env = mixin . env ( ) ;
Object . keys ( env ) . forEach ( function ( envVar ) {
if ( prefix === '' || envVar . lastIndexOf ( prefix , 0 ) === 0 ) {
const keys = envVar . split ( '__' ) . map ( function ( key , i ) {
if ( i === 0 ) {
key = key . substring ( prefix . length ) ;
}
return camelCase ( key ) ;
} ) ;
if ( ( ( configOnly && flags . configs [ keys . join ( '.' ) ] ) || ! configOnly ) && ! hasKey ( argv , keys ) ) {
setArg ( keys . join ( '.' ) , env [ envVar ] ) ;
}
}
} ) ;
}
function applyCoercions ( argv ) {
let coerce ;
const applied = new Set ( ) ;
Object . keys ( argv ) . forEach ( function ( key ) {
if ( ! applied . has ( key ) ) {
coerce = checkAllAliases ( key , flags . coercions ) ;
if ( typeof coerce === 'function' ) {
try {
const value = maybeCoerceNumber ( key , coerce ( argv [ key ] ) ) ;
( [ ] . concat ( flags . aliases [ key ] || [ ] , key ) ) . forEach ( ali => {
applied . add ( ali ) ;
argv [ ali ] = value ;
} ) ;
}
catch ( err ) {
error = err ;
}
}
}
} ) ;
}
function setPlaceholderKeys ( argv ) {
flags . keys . forEach ( ( key ) => {
if ( ~ key . indexOf ( '.' ) )
return ;
if ( typeof argv [ key ] === 'undefined' )
argv [ key ] = undefined ;
} ) ;
return argv ;
}
function applyDefaultsAndAliases ( obj , aliases , defaults , canLog = false ) {
Object . keys ( defaults ) . forEach ( function ( key ) {
if ( ! hasKey ( obj , key . split ( '.' ) ) ) {
setKey ( obj , key . split ( '.' ) , defaults [ key ] ) ;
if ( canLog )
defaulted [ key ] = true ;
( aliases [ key ] || [ ] ) . forEach ( function ( x ) {
if ( hasKey ( obj , x . split ( '.' ) ) )
return ;
setKey ( obj , x . split ( '.' ) , defaults [ key ] ) ;
} ) ;
}
} ) ;
}
function hasKey ( obj , keys ) {
let o = obj ;
if ( ! configuration [ 'dot-notation' ] )
keys = [ keys . join ( '.' ) ] ;
keys . slice ( 0 , - 1 ) . forEach ( function ( key ) {
o = ( o [ key ] || { } ) ;
} ) ;
const key = keys [ keys . length - 1 ] ;
if ( typeof o !== 'object' )
return false ;
else
return key in o ;
}
function setKey ( obj , keys , value ) {
let o = obj ;
if ( ! configuration [ 'dot-notation' ] )
keys = [ keys . join ( '.' ) ] ;
keys . slice ( 0 , - 1 ) . forEach ( function ( key ) {
key = sanitizeKey ( key ) ;
if ( typeof o === 'object' && o [ key ] === undefined ) {
o [ key ] = { } ;
}
if ( typeof o [ key ] !== 'object' || Array . isArray ( o [ key ] ) ) {
if ( Array . isArray ( o [ key ] ) ) {
o [ key ] . push ( { } ) ;
}
else {
o [ key ] = [ o [ key ] , { } ] ;
}
o = o [ key ] [ o [ key ] . length - 1 ] ;
}
else {
o = o [ key ] ;
}
} ) ;
const key = sanitizeKey ( keys [ keys . length - 1 ] ) ;
const isTypeArray = checkAllAliases ( keys . join ( '.' ) , flags . arrays ) ;
const isValueArray = Array . isArray ( value ) ;
let duplicate = configuration [ 'duplicate-arguments-array' ] ;
if ( ! duplicate && checkAllAliases ( key , flags . nargs ) ) {
duplicate = true ;
if ( ( ! isUndefined ( o [ key ] ) && flags . nargs [ key ] === 1 ) || ( Array . isArray ( o [ key ] ) && o [ key ] . length === flags . nargs [ key ] ) ) {
o [ key ] = undefined ;
}
}
if ( value === increment ( ) ) {
o [ key ] = increment ( o [ key ] ) ;
}
else if ( Array . isArray ( o [ key ] ) ) {
if ( duplicate && isTypeArray && isValueArray ) {
o [ key ] = configuration [ 'flatten-duplicate-arrays' ] ? o [ key ] . concat ( value ) : ( Array . isArray ( o [ key ] [ 0 ] ) ? o [ key ] : [ o [ key ] ] ) . concat ( [ value ] ) ;
}
else if ( ! duplicate && Boolean ( isTypeArray ) === Boolean ( isValueArray ) ) {
o [ key ] = value ;
}
else {
o [ key ] = o [ key ] . concat ( [ value ] ) ;
}
}
else if ( o [ key ] === undefined && isTypeArray ) {
o [ key ] = isValueArray ? value : [ value ] ;
}
else if ( duplicate && ! ( o [ key ] === undefined ||
checkAllAliases ( key , flags . counts ) ||
checkAllAliases ( key , flags . bools ) ) ) {
o [ key ] = [ o [ key ] , value ] ;
}
else {
o [ key ] = value ;
}
}
function extendAliases ( ... args ) {
args . forEach ( function ( obj ) {
Object . keys ( obj || { } ) . forEach ( function ( key ) {
if ( flags . aliases [ key ] )
return ;
flags . aliases [ key ] = [ ] . concat ( aliases [ key ] || [ ] ) ;
flags . aliases [ key ] . concat ( key ) . forEach ( function ( x ) {
if ( /-/ . test ( x ) && configuration [ 'camel-case-expansion' ] ) {
const c = camelCase ( x ) ;
if ( c !== key && flags . aliases [ key ] . indexOf ( c ) === - 1 ) {
flags . aliases [ key ] . push ( c ) ;
newAliases [ c ] = true ;
}
}
} ) ;
flags . aliases [ key ] . concat ( key ) . forEach ( function ( x ) {
if ( x . length > 1 && /[A-Z]/ . test ( x ) && configuration [ 'camel-case-expansion' ] ) {
const c = decamelize ( x , '-' ) ;
if ( c !== key && flags . aliases [ key ] . indexOf ( c ) === - 1 ) {
flags . aliases [ key ] . push ( c ) ;
newAliases [ c ] = true ;
}
}
} ) ;
flags . aliases [ key ] . forEach ( function ( x ) {
flags . aliases [ x ] = [ key ] . concat ( flags . aliases [ key ] . filter ( function ( y ) {
return x !== y ;
} ) ) ;
} ) ;
} ) ;
} ) ;
}
function checkAllAliases ( key , flag ) {
const toCheck = [ ] . concat ( flags . aliases [ key ] || [ ] , key ) ;
const keys = Object . keys ( flag ) ;
const setAlias = toCheck . find ( key => keys . includes ( key ) ) ;
return setAlias ? flag [ setAlias ] : false ;
}
function hasAnyFlag ( key ) {
const flagsKeys = Object . keys ( flags ) ;
const toCheck = [ ] . concat ( flagsKeys . map ( k => flags [ k ] ) ) ;
return toCheck . some ( function ( flag ) {
return Array . isArray ( flag ) ? flag . includes ( key ) : flag [ key ] ;
} ) ;
}
function hasFlagsMatching ( arg , ... patterns ) {
const toCheck = [ ] . concat ( ... patterns ) ;
return toCheck . some ( function ( pattern ) {
const match = arg . match ( pattern ) ;
return match && hasAnyFlag ( match [ 1 ] ) ;
} ) ;
}
function hasAllShortFlags ( arg ) {
if ( arg . match ( negative ) || ! arg . match ( /^-[^-]+/ ) ) {
return false ;
}
let hasAllFlags = true ;
let next ;
const letters = arg . slice ( 1 ) . split ( '' ) ;
for ( let j = 0 ; j < letters . length ; j ++ ) {
next = arg . slice ( j + 2 ) ;
if ( ! hasAnyFlag ( letters [ j ] ) ) {
hasAllFlags = false ;
break ;
}
if ( ( letters [ j + 1 ] && letters [ j + 1 ] === '=' ) ||
next === '-' ||
( /[A-Za-z]/ . test ( letters [ j ] ) && /^-?\d+(\.\d*)?(e-?\d+)?$/ . test ( next ) ) ||
( letters [ j + 1 ] && letters [ j + 1 ] . match ( /\W/ ) ) ) {
break ;
}
}
return hasAllFlags ;
}
function isUnknownOptionAsArg ( arg ) {
return configuration [ 'unknown-options-as-args' ] && isUnknownOption ( arg ) ;
}
function isUnknownOption ( arg ) {
arg = arg . replace ( /^-{3,}/ , '--' ) ;
if ( arg . match ( negative ) ) {
return false ;
}
if ( hasAllShortFlags ( arg ) ) {
return false ;
}
const flagWithEquals = /^-+([^=]+?)=[\s\S]*$/ ;
const normalFlag = /^-+([^=]+?)$/ ;
const flagEndingInHyphen = /^-+([^=]+?)-$/ ;
const flagEndingInDigits = /^-+([^=]+?\d+)$/ ;
const flagEndingInNonWordCharacters = /^-+([^=]+?)\W+.*$/ ;
return ! hasFlagsMatching ( arg , flagWithEquals , negatedBoolean , normalFlag , flagEndingInHyphen , flagEndingInDigits , flagEndingInNonWordCharacters ) ;
}
function defaultValue ( key ) {
if ( ! checkAllAliases ( key , flags . bools ) &&
! checkAllAliases ( key , flags . counts ) &&
` ${ key } ` in defaults ) {
return defaults [ key ] ;
}
else {
return defaultForType ( guessType ( key ) ) ;
}
}
function defaultForType ( type ) {
const def = {
[ DefaultValuesForTypeKey . BOOLEAN ] : true ,
[ DefaultValuesForTypeKey . STRING ] : '' ,
[ DefaultValuesForTypeKey . NUMBER ] : undefined ,
[ DefaultValuesForTypeKey . ARRAY ] : [ ]
} ;
return def [ type ] ;
}
function guessType ( key ) {
let type = DefaultValuesForTypeKey . BOOLEAN ;
if ( checkAllAliases ( key , flags . strings ) )
type = DefaultValuesForTypeKey . STRING ;
else if ( checkAllAliases ( key , flags . numbers ) )
type = DefaultValuesForTypeKey . NUMBER ;
else if ( checkAllAliases ( key , flags . bools ) )
type = DefaultValuesForTypeKey . BOOLEAN ;
else if ( checkAllAliases ( key , flags . arrays ) )
type = DefaultValuesForTypeKey . ARRAY ;
return type ;
}
function isUndefined ( num ) {
return num === undefined ;
}
function checkConfiguration ( ) {
Object . keys ( flags . counts ) . find ( key => {
if ( checkAllAliases ( key , flags . arrays ) ) {
error = Error ( _ _ ( 'Invalid configuration: %s, opts.count excludes opts.array.' , key ) ) ;
return true ;
}
else if ( checkAllAliases ( key , flags . nargs ) ) {
error = Error ( _ _ ( 'Invalid configuration: %s, opts.count excludes opts.narg.' , key ) ) ;
return true ;
}
return false ;
} ) ;
}
return {
aliases : Object . assign ( { } , flags . aliases ) ,
argv : Object . assign ( argvReturn , argv ) ,
configuration : configuration ,
defaulted : Object . assign ( { } , defaulted ) ,
error : error ,
newAliases : Object . assign ( { } , newAliases )
} ;
}
}
function combineAliases ( aliases ) {
const aliasArrays = [ ] ;
const combined = Object . create ( null ) ;
let change = true ;
Object . keys ( aliases ) . forEach ( function ( key ) {
aliasArrays . push ( [ ] . concat ( aliases [ key ] , key ) ) ;
} ) ;
while ( change ) {
change = false ;
for ( let i = 0 ; i < aliasArrays . length ; i ++ ) {
for ( let ii = i + 1 ; ii < aliasArrays . length ; ii ++ ) {
const intersect = aliasArrays [ i ] . filter ( function ( v ) {
return aliasArrays [ ii ] . indexOf ( v ) !== - 1 ;
} ) ;
if ( intersect . length ) {
aliasArrays [ i ] = aliasArrays [ i ] . concat ( aliasArrays [ ii ] ) ;
aliasArrays . splice ( ii , 1 ) ;
change = true ;
break ;
}
}
}
}
aliasArrays . forEach ( function ( aliasArray ) {
aliasArray = aliasArray . filter ( function ( v , i , self ) {
return self . indexOf ( v ) === i ;
} ) ;
const lastAlias = aliasArray . pop ( ) ;
if ( lastAlias !== undefined && typeof lastAlias === 'string' ) {
combined [ lastAlias ] = aliasArray ;
}
} ) ;
return combined ;
}
function increment ( orig ) {
return orig !== undefined ? orig + 1 : 1 ;
}
function sanitizeKey ( key ) {
if ( key === '__proto__' )
return '___proto___' ;
return key ;
}
const minNodeVersion = ( process && process . env && process . env . YARGS _MIN _NODE _VERSION )
? Number ( process . env . YARGS _MIN _NODE _VERSION )
: 10 ;
if ( process && process . version ) {
const major = Number ( process . version . match ( /v([^.]+)/ ) [ 1 ] ) ;
if ( major < minNodeVersion ) {
throw Error ( ` yargs parser supports a minimum Node.js version of ${ minNodeVersion } . Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions ` ) ;
}
}
const env = process ? process . env : { } ;
const parser = new YargsParser ( {
cwd : process . cwd ,
env : ( ) => {
return env ;
} ,
format : util . format ,
normalize : path . normalize ,
resolve : path . resolve ,
require : ( path ) => {
if ( typeof require !== 'undefined' ) {
return require ( path ) ;
}
else if ( path . match ( /\.json$/ ) ) {
return fs . readFileSync ( path , 'utf8' ) ;
}
else {
throw Error ( 'only .json config files are supported in ESM' ) ;
}
}
} ) ;
const yargsParser = function Parser ( args , opts ) {
const result = parser . parse ( args . slice ( ) , opts ) ;
return result . argv ;
} ;
yargsParser . detailed = function ( args , opts ) {
return parser . parse ( args . slice ( ) , opts ) ;
} ;
yargsParser . camelCase = camelCase ;
yargsParser . decamelize = decamelize ;
yargsParser . looksLikeNumber = looksLikeNumber ;
module . exports = yargsParser ;