11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ArrayPrototypeForEach, 51cb0ef41Sopenharmony_ci ArrayPrototypeIncludes, 61cb0ef41Sopenharmony_ci ArrayPrototypeMap, 71cb0ef41Sopenharmony_ci ArrayPrototypePush, 81cb0ef41Sopenharmony_ci ArrayPrototypePushApply, 91cb0ef41Sopenharmony_ci ArrayPrototypeShift, 101cb0ef41Sopenharmony_ci ArrayPrototypeSlice, 111cb0ef41Sopenharmony_ci ArrayPrototypeUnshiftApply, 121cb0ef41Sopenharmony_ci ObjectEntries, 131cb0ef41Sopenharmony_ci ObjectPrototypeHasOwnProperty: ObjectHasOwn, 141cb0ef41Sopenharmony_ci StringPrototypeCharAt, 151cb0ef41Sopenharmony_ci StringPrototypeIndexOf, 161cb0ef41Sopenharmony_ci StringPrototypeSlice, 171cb0ef41Sopenharmony_ci StringPrototypeStartsWith, 181cb0ef41Sopenharmony_ci} = primordials; 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ciconst { 211cb0ef41Sopenharmony_ci validateArray, 221cb0ef41Sopenharmony_ci validateBoolean, 231cb0ef41Sopenharmony_ci validateBooleanArray, 241cb0ef41Sopenharmony_ci validateObject, 251cb0ef41Sopenharmony_ci validateString, 261cb0ef41Sopenharmony_ci validateStringArray, 271cb0ef41Sopenharmony_ci validateUnion, 281cb0ef41Sopenharmony_ci} = require('internal/validators'); 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciconst { 311cb0ef41Sopenharmony_ci findLongOptionForShort, 321cb0ef41Sopenharmony_ci isLoneLongOption, 331cb0ef41Sopenharmony_ci isLoneShortOption, 341cb0ef41Sopenharmony_ci isLongOptionAndValue, 351cb0ef41Sopenharmony_ci isOptionValue, 361cb0ef41Sopenharmony_ci isOptionLikeValue, 371cb0ef41Sopenharmony_ci isShortOptionAndValue, 381cb0ef41Sopenharmony_ci isShortOptionGroup, 391cb0ef41Sopenharmony_ci useDefaultValueOption, 401cb0ef41Sopenharmony_ci objectGetOwn, 411cb0ef41Sopenharmony_ci optionsGetOwn, 421cb0ef41Sopenharmony_ci} = require('internal/util/parse_args/utils'); 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ciconst { 451cb0ef41Sopenharmony_ci codes: { 461cb0ef41Sopenharmony_ci ERR_INVALID_ARG_VALUE, 471cb0ef41Sopenharmony_ci ERR_PARSE_ARGS_INVALID_OPTION_VALUE, 481cb0ef41Sopenharmony_ci ERR_PARSE_ARGS_UNKNOWN_OPTION, 491cb0ef41Sopenharmony_ci ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL, 501cb0ef41Sopenharmony_ci }, 511cb0ef41Sopenharmony_ci} = require('internal/errors'); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ciconst { 541cb0ef41Sopenharmony_ci kEmptyObject, 551cb0ef41Sopenharmony_ci} = require('internal/util'); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_cifunction getMainArgs() { 591cb0ef41Sopenharmony_ci // Work out where to slice process.argv for user supplied arguments. 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci // Check node options for scenarios where user CLI args follow executable. 621cb0ef41Sopenharmony_ci const execArgv = process.execArgv; 631cb0ef41Sopenharmony_ci if (ArrayPrototypeIncludes(execArgv, '-e') || 641cb0ef41Sopenharmony_ci ArrayPrototypeIncludes(execArgv, '--eval') || 651cb0ef41Sopenharmony_ci ArrayPrototypeIncludes(execArgv, '-p') || 661cb0ef41Sopenharmony_ci ArrayPrototypeIncludes(execArgv, '--print')) { 671cb0ef41Sopenharmony_ci return ArrayPrototypeSlice(process.argv, 1); 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci // Normally first two arguments are executable and script, then CLI arguments 711cb0ef41Sopenharmony_ci return ArrayPrototypeSlice(process.argv, 2); 721cb0ef41Sopenharmony_ci} 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci/** 751cb0ef41Sopenharmony_ci * In strict mode, throw for possible usage errors like --foo --bar 761cb0ef41Sopenharmony_ci * @param {object} token - from tokens as available from parseArgs 771cb0ef41Sopenharmony_ci */ 781cb0ef41Sopenharmony_cifunction checkOptionLikeValue(token) { 791cb0ef41Sopenharmony_ci if (!token.inlineValue && isOptionLikeValue(token.value)) { 801cb0ef41Sopenharmony_ci // Only show short example if user used short option. 811cb0ef41Sopenharmony_ci const example = StringPrototypeStartsWith(token.rawName, '--') ? 821cb0ef41Sopenharmony_ci `'${token.rawName}=-XYZ'` : 831cb0ef41Sopenharmony_ci `'--${token.name}=-XYZ' or '${token.rawName}-XYZ'`; 841cb0ef41Sopenharmony_ci const errorMessage = `Option '${token.rawName}' argument is ambiguous. 851cb0ef41Sopenharmony_ciDid you forget to specify the option argument for '${token.rawName}'? 861cb0ef41Sopenharmony_ciTo specify an option argument starting with a dash use ${example}.`; 871cb0ef41Sopenharmony_ci throw new ERR_PARSE_ARGS_INVALID_OPTION_VALUE(errorMessage); 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci} 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci/** 921cb0ef41Sopenharmony_ci * In strict mode, throw for usage errors. 931cb0ef41Sopenharmony_ci * @param {object} config - from config passed to parseArgs 941cb0ef41Sopenharmony_ci * @param {object} token - from tokens as available from parseArgs 951cb0ef41Sopenharmony_ci */ 961cb0ef41Sopenharmony_cifunction checkOptionUsage(config, token) { 971cb0ef41Sopenharmony_ci if (!ObjectHasOwn(config.options, token.name)) { 981cb0ef41Sopenharmony_ci throw new ERR_PARSE_ARGS_UNKNOWN_OPTION( 991cb0ef41Sopenharmony_ci token.rawName, config.allowPositionals); 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci const short = optionsGetOwn(config.options, token.name, 'short'); 1031cb0ef41Sopenharmony_ci const shortAndLong = `${short ? `-${short}, ` : ''}--${token.name}`; 1041cb0ef41Sopenharmony_ci const type = optionsGetOwn(config.options, token.name, 'type'); 1051cb0ef41Sopenharmony_ci if (type === 'string' && typeof token.value !== 'string') { 1061cb0ef41Sopenharmony_ci throw new ERR_PARSE_ARGS_INVALID_OPTION_VALUE(`Option '${shortAndLong} <value>' argument missing`); 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci // (Idiomatic test for undefined||null, expecting undefined.) 1091cb0ef41Sopenharmony_ci if (type === 'boolean' && token.value != null) { 1101cb0ef41Sopenharmony_ci throw new ERR_PARSE_ARGS_INVALID_OPTION_VALUE(`Option '${shortAndLong}' does not take an argument`); 1111cb0ef41Sopenharmony_ci } 1121cb0ef41Sopenharmony_ci} 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci/** 1161cb0ef41Sopenharmony_ci * Store the option value in `values`. 1171cb0ef41Sopenharmony_ci * @param {string} longOption - long option name e.g. 'foo' 1181cb0ef41Sopenharmony_ci * @param {string|undefined} optionValue - value from user args 1191cb0ef41Sopenharmony_ci * @param {object} options - option configs, from parseArgs({ options }) 1201cb0ef41Sopenharmony_ci * @param {object} values - option values returned in `values` by parseArgs 1211cb0ef41Sopenharmony_ci */ 1221cb0ef41Sopenharmony_cifunction storeOption(longOption, optionValue, options, values) { 1231cb0ef41Sopenharmony_ci if (longOption === '__proto__') { 1241cb0ef41Sopenharmony_ci return; // No. Just no. 1251cb0ef41Sopenharmony_ci } 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci // We store based on the option value rather than option type, 1281cb0ef41Sopenharmony_ci // preserving the users intent for author to deal with. 1291cb0ef41Sopenharmony_ci const newValue = optionValue ?? true; 1301cb0ef41Sopenharmony_ci if (optionsGetOwn(options, longOption, 'multiple')) { 1311cb0ef41Sopenharmony_ci // Always store value in array, including for boolean. 1321cb0ef41Sopenharmony_ci // values[longOption] starts out not present, 1331cb0ef41Sopenharmony_ci // first value is added as new array [newValue], 1341cb0ef41Sopenharmony_ci // subsequent values are pushed to existing array. 1351cb0ef41Sopenharmony_ci // (note: values has null prototype, so simpler usage) 1361cb0ef41Sopenharmony_ci if (values[longOption]) { 1371cb0ef41Sopenharmony_ci ArrayPrototypePush(values[longOption], newValue); 1381cb0ef41Sopenharmony_ci } else { 1391cb0ef41Sopenharmony_ci values[longOption] = [newValue]; 1401cb0ef41Sopenharmony_ci } 1411cb0ef41Sopenharmony_ci } else { 1421cb0ef41Sopenharmony_ci values[longOption] = newValue; 1431cb0ef41Sopenharmony_ci } 1441cb0ef41Sopenharmony_ci} 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci/** 1471cb0ef41Sopenharmony_ci * Store the default option value in `values`. 1481cb0ef41Sopenharmony_ci * @param {string} longOption - long option name e.g. 'foo' 1491cb0ef41Sopenharmony_ci * @param {string 1501cb0ef41Sopenharmony_ci * | boolean 1511cb0ef41Sopenharmony_ci * | string[] 1521cb0ef41Sopenharmony_ci * | boolean[]} optionValue - default value from option config 1531cb0ef41Sopenharmony_ci * @param {object} values - option values returned in `values` by parseArgs 1541cb0ef41Sopenharmony_ci */ 1551cb0ef41Sopenharmony_cifunction storeDefaultOption(longOption, optionValue, values) { 1561cb0ef41Sopenharmony_ci if (longOption === '__proto__') { 1571cb0ef41Sopenharmony_ci return; // No. Just no. 1581cb0ef41Sopenharmony_ci } 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci values[longOption] = optionValue; 1611cb0ef41Sopenharmony_ci} 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci/** 1641cb0ef41Sopenharmony_ci * Process args and turn into identified tokens: 1651cb0ef41Sopenharmony_ci * - option (along with value, if any) 1661cb0ef41Sopenharmony_ci * - positional 1671cb0ef41Sopenharmony_ci * - option-terminator 1681cb0ef41Sopenharmony_ci * @param {string[]} args - from parseArgs({ args }) or mainArgs 1691cb0ef41Sopenharmony_ci * @param {object} options - option configs, from parseArgs({ options }) 1701cb0ef41Sopenharmony_ci */ 1711cb0ef41Sopenharmony_cifunction argsToTokens(args, options) { 1721cb0ef41Sopenharmony_ci const tokens = []; 1731cb0ef41Sopenharmony_ci let index = -1; 1741cb0ef41Sopenharmony_ci let groupCount = 0; 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci const remainingArgs = ArrayPrototypeSlice(args); 1771cb0ef41Sopenharmony_ci while (remainingArgs.length > 0) { 1781cb0ef41Sopenharmony_ci const arg = ArrayPrototypeShift(remainingArgs); 1791cb0ef41Sopenharmony_ci const nextArg = remainingArgs[0]; 1801cb0ef41Sopenharmony_ci if (groupCount > 0) 1811cb0ef41Sopenharmony_ci groupCount--; 1821cb0ef41Sopenharmony_ci else 1831cb0ef41Sopenharmony_ci index++; 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci // Check if `arg` is an options terminator. 1861cb0ef41Sopenharmony_ci // Guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html 1871cb0ef41Sopenharmony_ci if (arg === '--') { 1881cb0ef41Sopenharmony_ci // Everything after a bare '--' is considered a positional argument. 1891cb0ef41Sopenharmony_ci ArrayPrototypePush(tokens, { kind: 'option-terminator', index }); 1901cb0ef41Sopenharmony_ci ArrayPrototypePushApply( 1911cb0ef41Sopenharmony_ci tokens, ArrayPrototypeMap(remainingArgs, (arg) => { 1921cb0ef41Sopenharmony_ci return { kind: 'positional', index: ++index, value: arg }; 1931cb0ef41Sopenharmony_ci }), 1941cb0ef41Sopenharmony_ci ); 1951cb0ef41Sopenharmony_ci break; // Finished processing args, leave while loop. 1961cb0ef41Sopenharmony_ci } 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci if (isLoneShortOption(arg)) { 1991cb0ef41Sopenharmony_ci // e.g. '-f' 2001cb0ef41Sopenharmony_ci const shortOption = StringPrototypeCharAt(arg, 1); 2011cb0ef41Sopenharmony_ci const longOption = findLongOptionForShort(shortOption, options); 2021cb0ef41Sopenharmony_ci let value; 2031cb0ef41Sopenharmony_ci let inlineValue; 2041cb0ef41Sopenharmony_ci if (optionsGetOwn(options, longOption, 'type') === 'string' && 2051cb0ef41Sopenharmony_ci isOptionValue(nextArg)) { 2061cb0ef41Sopenharmony_ci // e.g. '-f', 'bar' 2071cb0ef41Sopenharmony_ci value = ArrayPrototypeShift(remainingArgs); 2081cb0ef41Sopenharmony_ci inlineValue = false; 2091cb0ef41Sopenharmony_ci } 2101cb0ef41Sopenharmony_ci ArrayPrototypePush( 2111cb0ef41Sopenharmony_ci tokens, 2121cb0ef41Sopenharmony_ci { kind: 'option', name: longOption, rawName: arg, 2131cb0ef41Sopenharmony_ci index, value, inlineValue }); 2141cb0ef41Sopenharmony_ci if (value != null) ++index; 2151cb0ef41Sopenharmony_ci continue; 2161cb0ef41Sopenharmony_ci } 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci if (isShortOptionGroup(arg, options)) { 2191cb0ef41Sopenharmony_ci // Expand -fXzy to -f -X -z -y 2201cb0ef41Sopenharmony_ci const expanded = []; 2211cb0ef41Sopenharmony_ci for (let index = 1; index < arg.length; index++) { 2221cb0ef41Sopenharmony_ci const shortOption = StringPrototypeCharAt(arg, index); 2231cb0ef41Sopenharmony_ci const longOption = findLongOptionForShort(shortOption, options); 2241cb0ef41Sopenharmony_ci if (optionsGetOwn(options, longOption, 'type') !== 'string' || 2251cb0ef41Sopenharmony_ci index === arg.length - 1) { 2261cb0ef41Sopenharmony_ci // Boolean option, or last short in group. Well formed. 2271cb0ef41Sopenharmony_ci ArrayPrototypePush(expanded, `-${shortOption}`); 2281cb0ef41Sopenharmony_ci } else { 2291cb0ef41Sopenharmony_ci // String option in middle. Yuck. 2301cb0ef41Sopenharmony_ci // Expand -abfFILE to -a -b -fFILE 2311cb0ef41Sopenharmony_ci ArrayPrototypePush(expanded, `-${StringPrototypeSlice(arg, index)}`); 2321cb0ef41Sopenharmony_ci break; // finished short group 2331cb0ef41Sopenharmony_ci } 2341cb0ef41Sopenharmony_ci } 2351cb0ef41Sopenharmony_ci ArrayPrototypeUnshiftApply(remainingArgs, expanded); 2361cb0ef41Sopenharmony_ci groupCount = expanded.length; 2371cb0ef41Sopenharmony_ci continue; 2381cb0ef41Sopenharmony_ci } 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ci if (isShortOptionAndValue(arg, options)) { 2411cb0ef41Sopenharmony_ci // e.g. -fFILE 2421cb0ef41Sopenharmony_ci const shortOption = StringPrototypeCharAt(arg, 1); 2431cb0ef41Sopenharmony_ci const longOption = findLongOptionForShort(shortOption, options); 2441cb0ef41Sopenharmony_ci const value = StringPrototypeSlice(arg, 2); 2451cb0ef41Sopenharmony_ci ArrayPrototypePush( 2461cb0ef41Sopenharmony_ci tokens, 2471cb0ef41Sopenharmony_ci { kind: 'option', name: longOption, rawName: `-${shortOption}`, 2481cb0ef41Sopenharmony_ci index, value, inlineValue: true }); 2491cb0ef41Sopenharmony_ci continue; 2501cb0ef41Sopenharmony_ci } 2511cb0ef41Sopenharmony_ci 2521cb0ef41Sopenharmony_ci if (isLoneLongOption(arg)) { 2531cb0ef41Sopenharmony_ci // e.g. '--foo' 2541cb0ef41Sopenharmony_ci const longOption = StringPrototypeSlice(arg, 2); 2551cb0ef41Sopenharmony_ci let value; 2561cb0ef41Sopenharmony_ci let inlineValue; 2571cb0ef41Sopenharmony_ci if (optionsGetOwn(options, longOption, 'type') === 'string' && 2581cb0ef41Sopenharmony_ci isOptionValue(nextArg)) { 2591cb0ef41Sopenharmony_ci // e.g. '--foo', 'bar' 2601cb0ef41Sopenharmony_ci value = ArrayPrototypeShift(remainingArgs); 2611cb0ef41Sopenharmony_ci inlineValue = false; 2621cb0ef41Sopenharmony_ci } 2631cb0ef41Sopenharmony_ci ArrayPrototypePush( 2641cb0ef41Sopenharmony_ci tokens, 2651cb0ef41Sopenharmony_ci { kind: 'option', name: longOption, rawName: arg, 2661cb0ef41Sopenharmony_ci index, value, inlineValue }); 2671cb0ef41Sopenharmony_ci if (value != null) ++index; 2681cb0ef41Sopenharmony_ci continue; 2691cb0ef41Sopenharmony_ci } 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ci if (isLongOptionAndValue(arg)) { 2721cb0ef41Sopenharmony_ci // e.g. --foo=bar 2731cb0ef41Sopenharmony_ci const equalIndex = StringPrototypeIndexOf(arg, '='); 2741cb0ef41Sopenharmony_ci const longOption = StringPrototypeSlice(arg, 2, equalIndex); 2751cb0ef41Sopenharmony_ci const value = StringPrototypeSlice(arg, equalIndex + 1); 2761cb0ef41Sopenharmony_ci ArrayPrototypePush( 2771cb0ef41Sopenharmony_ci tokens, 2781cb0ef41Sopenharmony_ci { kind: 'option', name: longOption, rawName: `--${longOption}`, 2791cb0ef41Sopenharmony_ci index, value, inlineValue: true }); 2801cb0ef41Sopenharmony_ci continue; 2811cb0ef41Sopenharmony_ci } 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci ArrayPrototypePush(tokens, { kind: 'positional', index, value: arg }); 2841cb0ef41Sopenharmony_ci } 2851cb0ef41Sopenharmony_ci return tokens; 2861cb0ef41Sopenharmony_ci} 2871cb0ef41Sopenharmony_ci 2881cb0ef41Sopenharmony_ciconst parseArgs = (config = kEmptyObject) => { 2891cb0ef41Sopenharmony_ci const args = objectGetOwn(config, 'args') ?? getMainArgs(); 2901cb0ef41Sopenharmony_ci const strict = objectGetOwn(config, 'strict') ?? true; 2911cb0ef41Sopenharmony_ci const allowPositionals = objectGetOwn(config, 'allowPositionals') ?? !strict; 2921cb0ef41Sopenharmony_ci const returnTokens = objectGetOwn(config, 'tokens') ?? false; 2931cb0ef41Sopenharmony_ci const options = objectGetOwn(config, 'options') ?? { __proto__: null }; 2941cb0ef41Sopenharmony_ci // Bundle these up for passing to strict-mode checks. 2951cb0ef41Sopenharmony_ci const parseConfig = { args, strict, options, allowPositionals }; 2961cb0ef41Sopenharmony_ci 2971cb0ef41Sopenharmony_ci // Validate input configuration. 2981cb0ef41Sopenharmony_ci validateArray(args, 'args'); 2991cb0ef41Sopenharmony_ci validateBoolean(strict, 'strict'); 3001cb0ef41Sopenharmony_ci validateBoolean(allowPositionals, 'allowPositionals'); 3011cb0ef41Sopenharmony_ci validateBoolean(returnTokens, 'tokens'); 3021cb0ef41Sopenharmony_ci validateObject(options, 'options'); 3031cb0ef41Sopenharmony_ci ArrayPrototypeForEach( 3041cb0ef41Sopenharmony_ci ObjectEntries(options), 3051cb0ef41Sopenharmony_ci ({ 0: longOption, 1: optionConfig }) => { 3061cb0ef41Sopenharmony_ci validateObject(optionConfig, `options.${longOption}`); 3071cb0ef41Sopenharmony_ci 3081cb0ef41Sopenharmony_ci // type is required 3091cb0ef41Sopenharmony_ci const optionType = objectGetOwn(optionConfig, 'type'); 3101cb0ef41Sopenharmony_ci validateUnion(optionType, `options.${longOption}.type`, ['string', 'boolean']); 3111cb0ef41Sopenharmony_ci 3121cb0ef41Sopenharmony_ci if (ObjectHasOwn(optionConfig, 'short')) { 3131cb0ef41Sopenharmony_ci const shortOption = optionConfig.short; 3141cb0ef41Sopenharmony_ci validateString(shortOption, `options.${longOption}.short`); 3151cb0ef41Sopenharmony_ci if (shortOption.length !== 1) { 3161cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE( 3171cb0ef41Sopenharmony_ci `options.${longOption}.short`, 3181cb0ef41Sopenharmony_ci shortOption, 3191cb0ef41Sopenharmony_ci 'must be a single character', 3201cb0ef41Sopenharmony_ci ); 3211cb0ef41Sopenharmony_ci } 3221cb0ef41Sopenharmony_ci } 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_ci const multipleOption = objectGetOwn(optionConfig, 'multiple'); 3251cb0ef41Sopenharmony_ci if (ObjectHasOwn(optionConfig, 'multiple')) { 3261cb0ef41Sopenharmony_ci validateBoolean(multipleOption, `options.${longOption}.multiple`); 3271cb0ef41Sopenharmony_ci } 3281cb0ef41Sopenharmony_ci 3291cb0ef41Sopenharmony_ci const defaultValue = objectGetOwn(optionConfig, 'default'); 3301cb0ef41Sopenharmony_ci if (defaultValue !== undefined) { 3311cb0ef41Sopenharmony_ci let validator; 3321cb0ef41Sopenharmony_ci switch (optionType) { 3331cb0ef41Sopenharmony_ci case 'string': 3341cb0ef41Sopenharmony_ci validator = multipleOption ? validateStringArray : validateString; 3351cb0ef41Sopenharmony_ci break; 3361cb0ef41Sopenharmony_ci 3371cb0ef41Sopenharmony_ci case 'boolean': 3381cb0ef41Sopenharmony_ci validator = multipleOption ? validateBooleanArray : validateBoolean; 3391cb0ef41Sopenharmony_ci break; 3401cb0ef41Sopenharmony_ci } 3411cb0ef41Sopenharmony_ci validator(defaultValue, `options.${longOption}.default`); 3421cb0ef41Sopenharmony_ci } 3431cb0ef41Sopenharmony_ci }, 3441cb0ef41Sopenharmony_ci ); 3451cb0ef41Sopenharmony_ci 3461cb0ef41Sopenharmony_ci // Phase 1: identify tokens 3471cb0ef41Sopenharmony_ci const tokens = argsToTokens(args, options); 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_ci // Phase 2: process tokens into parsed option values and positionals 3501cb0ef41Sopenharmony_ci const result = { 3511cb0ef41Sopenharmony_ci values: { __proto__: null }, 3521cb0ef41Sopenharmony_ci positionals: [], 3531cb0ef41Sopenharmony_ci }; 3541cb0ef41Sopenharmony_ci if (returnTokens) { 3551cb0ef41Sopenharmony_ci result.tokens = tokens; 3561cb0ef41Sopenharmony_ci } 3571cb0ef41Sopenharmony_ci ArrayPrototypeForEach(tokens, (token) => { 3581cb0ef41Sopenharmony_ci if (token.kind === 'option') { 3591cb0ef41Sopenharmony_ci if (strict) { 3601cb0ef41Sopenharmony_ci checkOptionUsage(parseConfig, token); 3611cb0ef41Sopenharmony_ci checkOptionLikeValue(token); 3621cb0ef41Sopenharmony_ci } 3631cb0ef41Sopenharmony_ci storeOption(token.name, token.value, options, result.values); 3641cb0ef41Sopenharmony_ci } else if (token.kind === 'positional') { 3651cb0ef41Sopenharmony_ci if (!allowPositionals) { 3661cb0ef41Sopenharmony_ci throw new ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL(token.value); 3671cb0ef41Sopenharmony_ci } 3681cb0ef41Sopenharmony_ci ArrayPrototypePush(result.positionals, token.value); 3691cb0ef41Sopenharmony_ci } 3701cb0ef41Sopenharmony_ci }); 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_ci // Phase 3: fill in default values for missing args 3731cb0ef41Sopenharmony_ci ArrayPrototypeForEach(ObjectEntries(options), ({ 0: longOption, 3741cb0ef41Sopenharmony_ci 1: optionConfig }) => { 3751cb0ef41Sopenharmony_ci const mustSetDefault = useDefaultValueOption(longOption, 3761cb0ef41Sopenharmony_ci optionConfig, 3771cb0ef41Sopenharmony_ci result.values); 3781cb0ef41Sopenharmony_ci if (mustSetDefault) { 3791cb0ef41Sopenharmony_ci storeDefaultOption(longOption, 3801cb0ef41Sopenharmony_ci objectGetOwn(optionConfig, 'default'), 3811cb0ef41Sopenharmony_ci result.values); 3821cb0ef41Sopenharmony_ci } 3831cb0ef41Sopenharmony_ci }); 3841cb0ef41Sopenharmony_ci 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_ci return result; 3871cb0ef41Sopenharmony_ci}; 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_cimodule.exports = { 3901cb0ef41Sopenharmony_ci parseArgs, 3911cb0ef41Sopenharmony_ci}; 392