/ cloudformation-templates / node_modules / aws-cdk / node_modules / yargs-parser / build / index.cjs
index.cjs
1 'use strict'; 2 3 var util = require('util'); 4 var fs = require('fs'); 5 var path = require('path'); 6 7 function camelCase(str) { 8 const isCamelCase = str !== str.toLowerCase() && str !== str.toUpperCase(); 9 if (!isCamelCase) { 10 str = str.toLowerCase(); 11 } 12 if (str.indexOf('-') === -1 && str.indexOf('_') === -1) { 13 return str; 14 } 15 else { 16 let camelcase = ''; 17 let nextChrUpper = false; 18 const leadingHyphens = str.match(/^-+/); 19 for (let i = leadingHyphens ? leadingHyphens[0].length : 0; i < str.length; i++) { 20 let chr = str.charAt(i); 21 if (nextChrUpper) { 22 nextChrUpper = false; 23 chr = chr.toUpperCase(); 24 } 25 if (i !== 0 && (chr === '-' || chr === '_')) { 26 nextChrUpper = true; 27 } 28 else if (chr !== '-' && chr !== '_') { 29 camelcase += chr; 30 } 31 } 32 return camelcase; 33 } 34 } 35 function decamelize(str, joinString) { 36 const lowercase = str.toLowerCase(); 37 joinString = joinString || '-'; 38 let notCamelcase = ''; 39 for (let i = 0; i < str.length; i++) { 40 const chrLower = lowercase.charAt(i); 41 const chrString = str.charAt(i); 42 if (chrLower !== chrString && i > 0) { 43 notCamelcase += `${joinString}${lowercase.charAt(i)}`; 44 } 45 else { 46 notCamelcase += chrString; 47 } 48 } 49 return notCamelcase; 50 } 51 function looksLikeNumber(x) { 52 if (x === null || x === undefined) 53 return false; 54 if (typeof x === 'number') 55 return true; 56 if (/^0x[0-9a-f]+$/i.test(x)) 57 return true; 58 if (/^0[^.]/.test(x)) 59 return false; 60 return /^[-]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); 61 } 62 63 function tokenizeArgString(argString) { 64 if (Array.isArray(argString)) { 65 return argString.map(e => typeof e !== 'string' ? e + '' : e); 66 } 67 argString = argString.trim(); 68 let i = 0; 69 let prevC = null; 70 let c = null; 71 let opening = null; 72 const args = []; 73 for (let ii = 0; ii < argString.length; ii++) { 74 prevC = c; 75 c = argString.charAt(ii); 76 if (c === ' ' && !opening) { 77 if (!(prevC === ' ')) { 78 i++; 79 } 80 continue; 81 } 82 if (c === opening) { 83 opening = null; 84 } 85 else if ((c === "'" || c === '"') && !opening) { 86 opening = c; 87 } 88 if (!args[i]) 89 args[i] = ''; 90 args[i] += c; 91 } 92 return args; 93 } 94 95 var DefaultValuesForTypeKey; 96 (function (DefaultValuesForTypeKey) { 97 DefaultValuesForTypeKey["BOOLEAN"] = "boolean"; 98 DefaultValuesForTypeKey["STRING"] = "string"; 99 DefaultValuesForTypeKey["NUMBER"] = "number"; 100 DefaultValuesForTypeKey["ARRAY"] = "array"; 101 })(DefaultValuesForTypeKey || (DefaultValuesForTypeKey = {})); 102 103 let mixin; 104 class YargsParser { 105 constructor(_mixin) { 106 mixin = _mixin; 107 } 108 parse(argsInput, options) { 109 const opts = Object.assign({ 110 alias: undefined, 111 array: undefined, 112 boolean: undefined, 113 config: undefined, 114 configObjects: undefined, 115 configuration: undefined, 116 coerce: undefined, 117 count: undefined, 118 default: undefined, 119 envPrefix: undefined, 120 narg: undefined, 121 normalize: undefined, 122 string: undefined, 123 number: undefined, 124 __: undefined, 125 key: undefined 126 }, options); 127 const args = tokenizeArgString(argsInput); 128 const aliases = combineAliases(Object.assign(Object.create(null), opts.alias)); 129 const configuration = Object.assign({ 130 'boolean-negation': true, 131 'camel-case-expansion': true, 132 'combine-arrays': false, 133 'dot-notation': true, 134 'duplicate-arguments-array': true, 135 'flatten-duplicate-arrays': true, 136 'greedy-arrays': true, 137 'halt-at-non-option': false, 138 'nargs-eats-options': false, 139 'negation-prefix': 'no-', 140 'parse-numbers': true, 141 'parse-positional-numbers': true, 142 'populate--': false, 143 'set-placeholder-key': false, 144 'short-option-groups': true, 145 'strip-aliased': false, 146 'strip-dashed': false, 147 'unknown-options-as-args': false 148 }, opts.configuration); 149 const defaults = Object.assign(Object.create(null), opts.default); 150 const configObjects = opts.configObjects || []; 151 const envPrefix = opts.envPrefix; 152 const notFlagsOption = configuration['populate--']; 153 const notFlagsArgv = notFlagsOption ? '--' : '_'; 154 const newAliases = Object.create(null); 155 const defaulted = Object.create(null); 156 const __ = opts.__ || mixin.format; 157 const flags = { 158 aliases: Object.create(null), 159 arrays: Object.create(null), 160 bools: Object.create(null), 161 strings: Object.create(null), 162 numbers: Object.create(null), 163 counts: Object.create(null), 164 normalize: Object.create(null), 165 configs: Object.create(null), 166 nargs: Object.create(null), 167 coercions: Object.create(null), 168 keys: [] 169 }; 170 const negative = /^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/; 171 const negatedBoolean = new RegExp('^--' + configuration['negation-prefix'] + '(.+)'); 172 [].concat(opts.array || []).filter(Boolean).forEach(function (opt) { 173 const key = typeof opt === 'object' ? opt.key : opt; 174 const assignment = Object.keys(opt).map(function (key) { 175 const arrayFlagKeys = { 176 boolean: 'bools', 177 string: 'strings', 178 number: 'numbers' 179 }; 180 return arrayFlagKeys[key]; 181 }).filter(Boolean).pop(); 182 if (assignment) { 183 flags[assignment][key] = true; 184 } 185 flags.arrays[key] = true; 186 flags.keys.push(key); 187 }); 188 [].concat(opts.boolean || []).filter(Boolean).forEach(function (key) { 189 flags.bools[key] = true; 190 flags.keys.push(key); 191 }); 192 [].concat(opts.string || []).filter(Boolean).forEach(function (key) { 193 flags.strings[key] = true; 194 flags.keys.push(key); 195 }); 196 [].concat(opts.number || []).filter(Boolean).forEach(function (key) { 197 flags.numbers[key] = true; 198 flags.keys.push(key); 199 }); 200 [].concat(opts.count || []).filter(Boolean).forEach(function (key) { 201 flags.counts[key] = true; 202 flags.keys.push(key); 203 }); 204 [].concat(opts.normalize || []).filter(Boolean).forEach(function (key) { 205 flags.normalize[key] = true; 206 flags.keys.push(key); 207 }); 208 if (typeof opts.narg === 'object') { 209 Object.entries(opts.narg).forEach(([key, value]) => { 210 if (typeof value === 'number') { 211 flags.nargs[key] = value; 212 flags.keys.push(key); 213 } 214 }); 215 } 216 if (typeof opts.coerce === 'object') { 217 Object.entries(opts.coerce).forEach(([key, value]) => { 218 if (typeof value === 'function') { 219 flags.coercions[key] = value; 220 flags.keys.push(key); 221 } 222 }); 223 } 224 if (typeof opts.config !== 'undefined') { 225 if (Array.isArray(opts.config) || typeof opts.config === 'string') { 226 [].concat(opts.config).filter(Boolean).forEach(function (key) { 227 flags.configs[key] = true; 228 }); 229 } 230 else if (typeof opts.config === 'object') { 231 Object.entries(opts.config).forEach(([key, value]) => { 232 if (typeof value === 'boolean' || typeof value === 'function') { 233 flags.configs[key] = value; 234 } 235 }); 236 } 237 } 238 extendAliases(opts.key, aliases, opts.default, flags.arrays); 239 Object.keys(defaults).forEach(function (key) { 240 (flags.aliases[key] || []).forEach(function (alias) { 241 defaults[alias] = defaults[key]; 242 }); 243 }); 244 let error = null; 245 checkConfiguration(); 246 let notFlags = []; 247 const argv = Object.assign(Object.create(null), { _: [] }); 248 const argvReturn = {}; 249 for (let i = 0; i < args.length; i++) { 250 const arg = args[i]; 251 const truncatedArg = arg.replace(/^-{3,}/, '---'); 252 let broken; 253 let key; 254 let letters; 255 let m; 256 let next; 257 let value; 258 if (arg !== '--' && isUnknownOptionAsArg(arg)) { 259 pushPositional(arg); 260 } 261 else if (truncatedArg.match(/---+(=|$)/)) { 262 pushPositional(arg); 263 continue; 264 } 265 else if (arg.match(/^--.+=/) || (!configuration['short-option-groups'] && arg.match(/^-.+=/))) { 266 m = arg.match(/^--?([^=]+)=([\s\S]*)$/); 267 if (m !== null && Array.isArray(m) && m.length >= 3) { 268 if (checkAllAliases(m[1], flags.arrays)) { 269 i = eatArray(i, m[1], args, m[2]); 270 } 271 else if (checkAllAliases(m[1], flags.nargs) !== false) { 272 i = eatNargs(i, m[1], args, m[2]); 273 } 274 else { 275 setArg(m[1], m[2]); 276 } 277 } 278 } 279 else if (arg.match(negatedBoolean) && configuration['boolean-negation']) { 280 m = arg.match(negatedBoolean); 281 if (m !== null && Array.isArray(m) && m.length >= 2) { 282 key = m[1]; 283 setArg(key, checkAllAliases(key, flags.arrays) ? [false] : false); 284 } 285 } 286 else if (arg.match(/^--.+/) || (!configuration['short-option-groups'] && arg.match(/^-[^-]+/))) { 287 m = arg.match(/^--?(.+)/); 288 if (m !== null && Array.isArray(m) && m.length >= 2) { 289 key = m[1]; 290 if (checkAllAliases(key, flags.arrays)) { 291 i = eatArray(i, key, args); 292 } 293 else if (checkAllAliases(key, flags.nargs) !== false) { 294 i = eatNargs(i, key, args); 295 } 296 else { 297 next = args[i + 1]; 298 if (next !== undefined && (!next.match(/^-/) || 299 next.match(negative)) && 300 !checkAllAliases(key, flags.bools) && 301 !checkAllAliases(key, flags.counts)) { 302 setArg(key, next); 303 i++; 304 } 305 else if (/^(true|false)$/.test(next)) { 306 setArg(key, next); 307 i++; 308 } 309 else { 310 setArg(key, defaultValue(key)); 311 } 312 } 313 } 314 } 315 else if (arg.match(/^-.\..+=/)) { 316 m = arg.match(/^-([^=]+)=([\s\S]*)$/); 317 if (m !== null && Array.isArray(m) && m.length >= 3) { 318 setArg(m[1], m[2]); 319 } 320 } 321 else if (arg.match(/^-.\..+/) && !arg.match(negative)) { 322 next = args[i + 1]; 323 m = arg.match(/^-(.\..+)/); 324 if (m !== null && Array.isArray(m) && m.length >= 2) { 325 key = m[1]; 326 if (next !== undefined && !next.match(/^-/) && 327 !checkAllAliases(key, flags.bools) && 328 !checkAllAliases(key, flags.counts)) { 329 setArg(key, next); 330 i++; 331 } 332 else { 333 setArg(key, defaultValue(key)); 334 } 335 } 336 } 337 else if (arg.match(/^-[^-]+/) && !arg.match(negative)) { 338 letters = arg.slice(1, -1).split(''); 339 broken = false; 340 for (let j = 0; j < letters.length; j++) { 341 next = arg.slice(j + 2); 342 if (letters[j + 1] && letters[j + 1] === '=') { 343 value = arg.slice(j + 3); 344 key = letters[j]; 345 if (checkAllAliases(key, flags.arrays)) { 346 i = eatArray(i, key, args, value); 347 } 348 else if (checkAllAliases(key, flags.nargs) !== false) { 349 i = eatNargs(i, key, args, value); 350 } 351 else { 352 setArg(key, value); 353 } 354 broken = true; 355 break; 356 } 357 if (next === '-') { 358 setArg(letters[j], next); 359 continue; 360 } 361 if (/[A-Za-z]/.test(letters[j]) && 362 /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next) && 363 checkAllAliases(next, flags.bools) === false) { 364 setArg(letters[j], next); 365 broken = true; 366 break; 367 } 368 if (letters[j + 1] && letters[j + 1].match(/\W/)) { 369 setArg(letters[j], next); 370 broken = true; 371 break; 372 } 373 else { 374 setArg(letters[j], defaultValue(letters[j])); 375 } 376 } 377 key = arg.slice(-1)[0]; 378 if (!broken && key !== '-') { 379 if (checkAllAliases(key, flags.arrays)) { 380 i = eatArray(i, key, args); 381 } 382 else if (checkAllAliases(key, flags.nargs) !== false) { 383 i = eatNargs(i, key, args); 384 } 385 else { 386 next = args[i + 1]; 387 if (next !== undefined && (!/^(-|--)[^-]/.test(next) || 388 next.match(negative)) && 389 !checkAllAliases(key, flags.bools) && 390 !checkAllAliases(key, flags.counts)) { 391 setArg(key, next); 392 i++; 393 } 394 else if (/^(true|false)$/.test(next)) { 395 setArg(key, next); 396 i++; 397 } 398 else { 399 setArg(key, defaultValue(key)); 400 } 401 } 402 } 403 } 404 else if (arg.match(/^-[0-9]$/) && 405 arg.match(negative) && 406 checkAllAliases(arg.slice(1), flags.bools)) { 407 key = arg.slice(1); 408 setArg(key, defaultValue(key)); 409 } 410 else if (arg === '--') { 411 notFlags = args.slice(i + 1); 412 break; 413 } 414 else if (configuration['halt-at-non-option']) { 415 notFlags = args.slice(i); 416 break; 417 } 418 else { 419 pushPositional(arg); 420 } 421 } 422 applyEnvVars(argv, true); 423 applyEnvVars(argv, false); 424 setConfig(argv); 425 setConfigObjects(); 426 applyDefaultsAndAliases(argv, flags.aliases, defaults, true); 427 applyCoercions(argv); 428 if (configuration['set-placeholder-key']) 429 setPlaceholderKeys(argv); 430 Object.keys(flags.counts).forEach(function (key) { 431 if (!hasKey(argv, key.split('.'))) 432 setArg(key, 0); 433 }); 434 if (notFlagsOption && notFlags.length) 435 argv[notFlagsArgv] = []; 436 notFlags.forEach(function (key) { 437 argv[notFlagsArgv].push(key); 438 }); 439 if (configuration['camel-case-expansion'] && configuration['strip-dashed']) { 440 Object.keys(argv).filter(key => key !== '--' && key.includes('-')).forEach(key => { 441 delete argv[key]; 442 }); 443 } 444 if (configuration['strip-aliased']) { 445 [].concat(...Object.keys(aliases).map(k => aliases[k])).forEach(alias => { 446 if (configuration['camel-case-expansion'] && alias.includes('-')) { 447 delete argv[alias.split('.').map(prop => camelCase(prop)).join('.')]; 448 } 449 delete argv[alias]; 450 }); 451 } 452 function pushPositional(arg) { 453 const maybeCoercedNumber = maybeCoerceNumber('_', arg); 454 if (typeof maybeCoercedNumber === 'string' || typeof maybeCoercedNumber === 'number') { 455 argv._.push(maybeCoercedNumber); 456 } 457 } 458 function eatNargs(i, key, args, argAfterEqualSign) { 459 let ii; 460 let toEat = checkAllAliases(key, flags.nargs); 461 toEat = typeof toEat !== 'number' || isNaN(toEat) ? 1 : toEat; 462 if (toEat === 0) { 463 if (!isUndefined(argAfterEqualSign)) { 464 error = Error(__('Argument unexpected for: %s', key)); 465 } 466 setArg(key, defaultValue(key)); 467 return i; 468 } 469 let available = isUndefined(argAfterEqualSign) ? 0 : 1; 470 if (configuration['nargs-eats-options']) { 471 if (args.length - (i + 1) + available < toEat) { 472 error = Error(__('Not enough arguments following: %s', key)); 473 } 474 available = toEat; 475 } 476 else { 477 for (ii = i + 1; ii < args.length; ii++) { 478 if (!args[ii].match(/^-[^0-9]/) || args[ii].match(negative) || isUnknownOptionAsArg(args[ii])) 479 available++; 480 else 481 break; 482 } 483 if (available < toEat) 484 error = Error(__('Not enough arguments following: %s', key)); 485 } 486 let consumed = Math.min(available, toEat); 487 if (!isUndefined(argAfterEqualSign) && consumed > 0) { 488 setArg(key, argAfterEqualSign); 489 consumed--; 490 } 491 for (ii = i + 1; ii < (consumed + i + 1); ii++) { 492 setArg(key, args[ii]); 493 } 494 return (i + consumed); 495 } 496 function eatArray(i, key, args, argAfterEqualSign) { 497 let argsToSet = []; 498 let next = argAfterEqualSign || args[i + 1]; 499 const nargsCount = checkAllAliases(key, flags.nargs); 500 if (checkAllAliases(key, flags.bools) && !(/^(true|false)$/.test(next))) { 501 argsToSet.push(true); 502 } 503 else if (isUndefined(next) || 504 (isUndefined(argAfterEqualSign) && /^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next))) { 505 if (defaults[key] !== undefined) { 506 const defVal = defaults[key]; 507 argsToSet = Array.isArray(defVal) ? defVal : [defVal]; 508 } 509 } 510 else { 511 if (!isUndefined(argAfterEqualSign)) { 512 argsToSet.push(processValue(key, argAfterEqualSign)); 513 } 514 for (let ii = i + 1; ii < args.length; ii++) { 515 if ((!configuration['greedy-arrays'] && argsToSet.length > 0) || 516 (nargsCount && typeof nargsCount === 'number' && argsToSet.length >= nargsCount)) 517 break; 518 next = args[ii]; 519 if (/^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next)) 520 break; 521 i = ii; 522 argsToSet.push(processValue(key, next)); 523 } 524 } 525 if (typeof nargsCount === 'number' && ((nargsCount && argsToSet.length < nargsCount) || 526 (isNaN(nargsCount) && argsToSet.length === 0))) { 527 error = Error(__('Not enough arguments following: %s', key)); 528 } 529 setArg(key, argsToSet); 530 return i; 531 } 532 function setArg(key, val) { 533 if (/-/.test(key) && configuration['camel-case-expansion']) { 534 const alias = key.split('.').map(function (prop) { 535 return camelCase(prop); 536 }).join('.'); 537 addNewAlias(key, alias); 538 } 539 const value = processValue(key, val); 540 const splitKey = key.split('.'); 541 setKey(argv, splitKey, value); 542 if (flags.aliases[key]) { 543 flags.aliases[key].forEach(function (x) { 544 const keyProperties = x.split('.'); 545 setKey(argv, keyProperties, value); 546 }); 547 } 548 if (splitKey.length > 1 && configuration['dot-notation']) { 549 (flags.aliases[splitKey[0]] || []).forEach(function (x) { 550 let keyProperties = x.split('.'); 551 const a = [].concat(splitKey); 552 a.shift(); 553 keyProperties = keyProperties.concat(a); 554 if (!(flags.aliases[key] || []).includes(keyProperties.join('.'))) { 555 setKey(argv, keyProperties, value); 556 } 557 }); 558 } 559 if (checkAllAliases(key, flags.normalize) && !checkAllAliases(key, flags.arrays)) { 560 const keys = [key].concat(flags.aliases[key] || []); 561 keys.forEach(function (key) { 562 Object.defineProperty(argvReturn, key, { 563 enumerable: true, 564 get() { 565 return val; 566 }, 567 set(value) { 568 val = typeof value === 'string' ? mixin.normalize(value) : value; 569 } 570 }); 571 }); 572 } 573 } 574 function addNewAlias(key, alias) { 575 if (!(flags.aliases[key] && flags.aliases[key].length)) { 576 flags.aliases[key] = [alias]; 577 newAliases[alias] = true; 578 } 579 if (!(flags.aliases[alias] && flags.aliases[alias].length)) { 580 addNewAlias(alias, key); 581 } 582 } 583 function processValue(key, val) { 584 if (typeof val === 'string' && 585 (val[0] === "'" || val[0] === '"') && 586 val[val.length - 1] === val[0]) { 587 val = val.substring(1, val.length - 1); 588 } 589 if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) { 590 if (typeof val === 'string') 591 val = val === 'true'; 592 } 593 let value = Array.isArray(val) 594 ? val.map(function (v) { return maybeCoerceNumber(key, v); }) 595 : maybeCoerceNumber(key, val); 596 if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === 'boolean')) { 597 value = increment(); 598 } 599 if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) { 600 if (Array.isArray(val)) 601 value = val.map((val) => { return mixin.normalize(val); }); 602 else 603 value = mixin.normalize(val); 604 } 605 return value; 606 } 607 function maybeCoerceNumber(key, value) { 608 if (!configuration['parse-positional-numbers'] && key === '_') 609 return value; 610 if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.bools) && !Array.isArray(value)) { 611 const shouldCoerceNumber = looksLikeNumber(value) && configuration['parse-numbers'] && (Number.isSafeInteger(Math.floor(parseFloat(`${value}`)))); 612 if (shouldCoerceNumber || (!isUndefined(value) && checkAllAliases(key, flags.numbers))) { 613 value = Number(value); 614 } 615 } 616 return value; 617 } 618 function setConfig(argv) { 619 const configLookup = Object.create(null); 620 applyDefaultsAndAliases(configLookup, flags.aliases, defaults); 621 Object.keys(flags.configs).forEach(function (configKey) { 622 const configPath = argv[configKey] || configLookup[configKey]; 623 if (configPath) { 624 try { 625 let config = null; 626 const resolvedConfigPath = mixin.resolve(mixin.cwd(), configPath); 627 const resolveConfig = flags.configs[configKey]; 628 if (typeof resolveConfig === 'function') { 629 try { 630 config = resolveConfig(resolvedConfigPath); 631 } 632 catch (e) { 633 config = e; 634 } 635 if (config instanceof Error) { 636 error = config; 637 return; 638 } 639 } 640 else { 641 config = mixin.require(resolvedConfigPath); 642 } 643 setConfigObject(config); 644 } 645 catch (ex) { 646 if (ex.name === 'PermissionDenied') 647 error = ex; 648 else if (argv[configKey]) 649 error = Error(__('Invalid JSON config file: %s', configPath)); 650 } 651 } 652 }); 653 } 654 function setConfigObject(config, prev) { 655 Object.keys(config).forEach(function (key) { 656 const value = config[key]; 657 const fullKey = prev ? prev + '.' + key : key; 658 if (typeof value === 'object' && value !== null && !Array.isArray(value) && configuration['dot-notation']) { 659 setConfigObject(value, fullKey); 660 } 661 else { 662 if (!hasKey(argv, fullKey.split('.')) || (checkAllAliases(fullKey, flags.arrays) && configuration['combine-arrays'])) { 663 setArg(fullKey, value); 664 } 665 } 666 }); 667 } 668 function setConfigObjects() { 669 if (typeof configObjects !== 'undefined') { 670 configObjects.forEach(function (configObject) { 671 setConfigObject(configObject); 672 }); 673 } 674 } 675 function applyEnvVars(argv, configOnly) { 676 if (typeof envPrefix === 'undefined') 677 return; 678 const prefix = typeof envPrefix === 'string' ? envPrefix : ''; 679 const env = mixin.env(); 680 Object.keys(env).forEach(function (envVar) { 681 if (prefix === '' || envVar.lastIndexOf(prefix, 0) === 0) { 682 const keys = envVar.split('__').map(function (key, i) { 683 if (i === 0) { 684 key = key.substring(prefix.length); 685 } 686 return camelCase(key); 687 }); 688 if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && !hasKey(argv, keys)) { 689 setArg(keys.join('.'), env[envVar]); 690 } 691 } 692 }); 693 } 694 function applyCoercions(argv) { 695 let coerce; 696 const applied = new Set(); 697 Object.keys(argv).forEach(function (key) { 698 if (!applied.has(key)) { 699 coerce = checkAllAliases(key, flags.coercions); 700 if (typeof coerce === 'function') { 701 try { 702 const value = maybeCoerceNumber(key, coerce(argv[key])); 703 ([].concat(flags.aliases[key] || [], key)).forEach(ali => { 704 applied.add(ali); 705 argv[ali] = value; 706 }); 707 } 708 catch (err) { 709 error = err; 710 } 711 } 712 } 713 }); 714 } 715 function setPlaceholderKeys(argv) { 716 flags.keys.forEach((key) => { 717 if (~key.indexOf('.')) 718 return; 719 if (typeof argv[key] === 'undefined') 720 argv[key] = undefined; 721 }); 722 return argv; 723 } 724 function applyDefaultsAndAliases(obj, aliases, defaults, canLog = false) { 725 Object.keys(defaults).forEach(function (key) { 726 if (!hasKey(obj, key.split('.'))) { 727 setKey(obj, key.split('.'), defaults[key]); 728 if (canLog) 729 defaulted[key] = true; 730 (aliases[key] || []).forEach(function (x) { 731 if (hasKey(obj, x.split('.'))) 732 return; 733 setKey(obj, x.split('.'), defaults[key]); 734 }); 735 } 736 }); 737 } 738 function hasKey(obj, keys) { 739 let o = obj; 740 if (!configuration['dot-notation']) 741 keys = [keys.join('.')]; 742 keys.slice(0, -1).forEach(function (key) { 743 o = (o[key] || {}); 744 }); 745 const key = keys[keys.length - 1]; 746 if (typeof o !== 'object') 747 return false; 748 else 749 return key in o; 750 } 751 function setKey(obj, keys, value) { 752 let o = obj; 753 if (!configuration['dot-notation']) 754 keys = [keys.join('.')]; 755 keys.slice(0, -1).forEach(function (key) { 756 key = sanitizeKey(key); 757 if (typeof o === 'object' && o[key] === undefined) { 758 o[key] = {}; 759 } 760 if (typeof o[key] !== 'object' || Array.isArray(o[key])) { 761 if (Array.isArray(o[key])) { 762 o[key].push({}); 763 } 764 else { 765 o[key] = [o[key], {}]; 766 } 767 o = o[key][o[key].length - 1]; 768 } 769 else { 770 o = o[key]; 771 } 772 }); 773 const key = sanitizeKey(keys[keys.length - 1]); 774 const isTypeArray = checkAllAliases(keys.join('.'), flags.arrays); 775 const isValueArray = Array.isArray(value); 776 let duplicate = configuration['duplicate-arguments-array']; 777 if (!duplicate && checkAllAliases(key, flags.nargs)) { 778 duplicate = true; 779 if ((!isUndefined(o[key]) && flags.nargs[key] === 1) || (Array.isArray(o[key]) && o[key].length === flags.nargs[key])) { 780 o[key] = undefined; 781 } 782 } 783 if (value === increment()) { 784 o[key] = increment(o[key]); 785 } 786 else if (Array.isArray(o[key])) { 787 if (duplicate && isTypeArray && isValueArray) { 788 o[key] = configuration['flatten-duplicate-arrays'] ? o[key].concat(value) : (Array.isArray(o[key][0]) ? o[key] : [o[key]]).concat([value]); 789 } 790 else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) { 791 o[key] = value; 792 } 793 else { 794 o[key] = o[key].concat([value]); 795 } 796 } 797 else if (o[key] === undefined && isTypeArray) { 798 o[key] = isValueArray ? value : [value]; 799 } 800 else if (duplicate && !(o[key] === undefined || 801 checkAllAliases(key, flags.counts) || 802 checkAllAliases(key, flags.bools))) { 803 o[key] = [o[key], value]; 804 } 805 else { 806 o[key] = value; 807 } 808 } 809 function extendAliases(...args) { 810 args.forEach(function (obj) { 811 Object.keys(obj || {}).forEach(function (key) { 812 if (flags.aliases[key]) 813 return; 814 flags.aliases[key] = [].concat(aliases[key] || []); 815 flags.aliases[key].concat(key).forEach(function (x) { 816 if (/-/.test(x) && configuration['camel-case-expansion']) { 817 const c = camelCase(x); 818 if (c !== key && flags.aliases[key].indexOf(c) === -1) { 819 flags.aliases[key].push(c); 820 newAliases[c] = true; 821 } 822 } 823 }); 824 flags.aliases[key].concat(key).forEach(function (x) { 825 if (x.length > 1 && /[A-Z]/.test(x) && configuration['camel-case-expansion']) { 826 const c = decamelize(x, '-'); 827 if (c !== key && flags.aliases[key].indexOf(c) === -1) { 828 flags.aliases[key].push(c); 829 newAliases[c] = true; 830 } 831 } 832 }); 833 flags.aliases[key].forEach(function (x) { 834 flags.aliases[x] = [key].concat(flags.aliases[key].filter(function (y) { 835 return x !== y; 836 })); 837 }); 838 }); 839 }); 840 } 841 function checkAllAliases(key, flag) { 842 const toCheck = [].concat(flags.aliases[key] || [], key); 843 const keys = Object.keys(flag); 844 const setAlias = toCheck.find(key => keys.includes(key)); 845 return setAlias ? flag[setAlias] : false; 846 } 847 function hasAnyFlag(key) { 848 const flagsKeys = Object.keys(flags); 849 const toCheck = [].concat(flagsKeys.map(k => flags[k])); 850 return toCheck.some(function (flag) { 851 return Array.isArray(flag) ? flag.includes(key) : flag[key]; 852 }); 853 } 854 function hasFlagsMatching(arg, ...patterns) { 855 const toCheck = [].concat(...patterns); 856 return toCheck.some(function (pattern) { 857 const match = arg.match(pattern); 858 return match && hasAnyFlag(match[1]); 859 }); 860 } 861 function hasAllShortFlags(arg) { 862 if (arg.match(negative) || !arg.match(/^-[^-]+/)) { 863 return false; 864 } 865 let hasAllFlags = true; 866 let next; 867 const letters = arg.slice(1).split(''); 868 for (let j = 0; j < letters.length; j++) { 869 next = arg.slice(j + 2); 870 if (!hasAnyFlag(letters[j])) { 871 hasAllFlags = false; 872 break; 873 } 874 if ((letters[j + 1] && letters[j + 1] === '=') || 875 next === '-' || 876 (/[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) || 877 (letters[j + 1] && letters[j + 1].match(/\W/))) { 878 break; 879 } 880 } 881 return hasAllFlags; 882 } 883 function isUnknownOptionAsArg(arg) { 884 return configuration['unknown-options-as-args'] && isUnknownOption(arg); 885 } 886 function isUnknownOption(arg) { 887 arg = arg.replace(/^-{3,}/, '--'); 888 if (arg.match(negative)) { 889 return false; 890 } 891 if (hasAllShortFlags(arg)) { 892 return false; 893 } 894 const flagWithEquals = /^-+([^=]+?)=[\s\S]*$/; 895 const normalFlag = /^-+([^=]+?)$/; 896 const flagEndingInHyphen = /^-+([^=]+?)-$/; 897 const flagEndingInDigits = /^-+([^=]+?\d+)$/; 898 const flagEndingInNonWordCharacters = /^-+([^=]+?)\W+.*$/; 899 return !hasFlagsMatching(arg, flagWithEquals, negatedBoolean, normalFlag, flagEndingInHyphen, flagEndingInDigits, flagEndingInNonWordCharacters); 900 } 901 function defaultValue(key) { 902 if (!checkAllAliases(key, flags.bools) && 903 !checkAllAliases(key, flags.counts) && 904 `${key}` in defaults) { 905 return defaults[key]; 906 } 907 else { 908 return defaultForType(guessType(key)); 909 } 910 } 911 function defaultForType(type) { 912 const def = { 913 [DefaultValuesForTypeKey.BOOLEAN]: true, 914 [DefaultValuesForTypeKey.STRING]: '', 915 [DefaultValuesForTypeKey.NUMBER]: undefined, 916 [DefaultValuesForTypeKey.ARRAY]: [] 917 }; 918 return def[type]; 919 } 920 function guessType(key) { 921 let type = DefaultValuesForTypeKey.BOOLEAN; 922 if (checkAllAliases(key, flags.strings)) 923 type = DefaultValuesForTypeKey.STRING; 924 else if (checkAllAliases(key, flags.numbers)) 925 type = DefaultValuesForTypeKey.NUMBER; 926 else if (checkAllAliases(key, flags.bools)) 927 type = DefaultValuesForTypeKey.BOOLEAN; 928 else if (checkAllAliases(key, flags.arrays)) 929 type = DefaultValuesForTypeKey.ARRAY; 930 return type; 931 } 932 function isUndefined(num) { 933 return num === undefined; 934 } 935 function checkConfiguration() { 936 Object.keys(flags.counts).find(key => { 937 if (checkAllAliases(key, flags.arrays)) { 938 error = Error(__('Invalid configuration: %s, opts.count excludes opts.array.', key)); 939 return true; 940 } 941 else if (checkAllAliases(key, flags.nargs)) { 942 error = Error(__('Invalid configuration: %s, opts.count excludes opts.narg.', key)); 943 return true; 944 } 945 return false; 946 }); 947 } 948 return { 949 aliases: Object.assign({}, flags.aliases), 950 argv: Object.assign(argvReturn, argv), 951 configuration: configuration, 952 defaulted: Object.assign({}, defaulted), 953 error: error, 954 newAliases: Object.assign({}, newAliases) 955 }; 956 } 957 } 958 function combineAliases(aliases) { 959 const aliasArrays = []; 960 const combined = Object.create(null); 961 let change = true; 962 Object.keys(aliases).forEach(function (key) { 963 aliasArrays.push([].concat(aliases[key], key)); 964 }); 965 while (change) { 966 change = false; 967 for (let i = 0; i < aliasArrays.length; i++) { 968 for (let ii = i + 1; ii < aliasArrays.length; ii++) { 969 const intersect = aliasArrays[i].filter(function (v) { 970 return aliasArrays[ii].indexOf(v) !== -1; 971 }); 972 if (intersect.length) { 973 aliasArrays[i] = aliasArrays[i].concat(aliasArrays[ii]); 974 aliasArrays.splice(ii, 1); 975 change = true; 976 break; 977 } 978 } 979 } 980 } 981 aliasArrays.forEach(function (aliasArray) { 982 aliasArray = aliasArray.filter(function (v, i, self) { 983 return self.indexOf(v) === i; 984 }); 985 const lastAlias = aliasArray.pop(); 986 if (lastAlias !== undefined && typeof lastAlias === 'string') { 987 combined[lastAlias] = aliasArray; 988 } 989 }); 990 return combined; 991 } 992 function increment(orig) { 993 return orig !== undefined ? orig + 1 : 1; 994 } 995 function sanitizeKey(key) { 996 if (key === '__proto__') 997 return '___proto___'; 998 return key; 999 } 1000 1001 const minNodeVersion = (process && process.env && process.env.YARGS_MIN_NODE_VERSION) 1002 ? Number(process.env.YARGS_MIN_NODE_VERSION) 1003 : 10; 1004 if (process && process.version) { 1005 const major = Number(process.version.match(/v([^.]+)/)[1]); 1006 if (major < minNodeVersion) { 1007 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`); 1008 } 1009 } 1010 const env = process ? process.env : {}; 1011 const parser = new YargsParser({ 1012 cwd: process.cwd, 1013 env: () => { 1014 return env; 1015 }, 1016 format: util.format, 1017 normalize: path.normalize, 1018 resolve: path.resolve, 1019 require: (path) => { 1020 if (typeof require !== 'undefined') { 1021 return require(path); 1022 } 1023 else if (path.match(/\.json$/)) { 1024 return fs.readFileSync(path, 'utf8'); 1025 } 1026 else { 1027 throw Error('only .json config files are supported in ESM'); 1028 } 1029 } 1030 }); 1031 const yargsParser = function Parser(args, opts) { 1032 const result = parser.parse(args.slice(), opts); 1033 return result.argv; 1034 }; 1035 yargsParser.detailed = function (args, opts) { 1036 return parser.parse(args.slice(), opts); 1037 }; 1038 yargsParser.camelCase = camelCase; 1039 yargsParser.decamelize = decamelize; 1040 yargsParser.looksLikeNumber = looksLikeNumber; 1041 1042 module.exports = yargsParser;