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