yargs-factory.ts ×35

Frontier kind: Code frontier

unlabeled · c_273b23af2b21

787 tests · 1896 LOC · 18 files · introduces 0 tests · 577 LOC · 8 files

Introduces — evidence that enters the hierarchy at this concept

Code
93 ranges577 lines · 8 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
341 ranges1896 lines · 18 files · Browse complete extent
All tests (intent)
787 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

8 files ranked by introduced lines: 577 introduced LOC across 93 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

lib/yargs-factory.ts 324 introduced LOC · 35 ranges

Open complete file

65 export function YargsFactory(_shim: PlatformShim) {
66 return (
67 > processArgs: string | string[] = [], yargs-factory.ts
68 > cwd = _shim.process.cwd(),
69 > parentRequire?: RequireType
70 > ): YargsInstance => {
71 > const yargs = new YargsInstance(processArgs, cwd, parentRequire, _shim);
72 > // Legacy yargs.argv interface, it's recommended that you use .parse().
73 > Object.defineProperty(yargs, 'argv', {
74 > get: () => {
75 return yargs.parse();
77 > enumerable: true,
78 > });
79 > // an app should almost always have --version and --help,
80 > // if you *really* want to disable this use .help(false)/.version(false).
81 > yargs.help();
82 > yargs.version();
83 > return yargs;
84 };
85 }
211
212 constructor(
213 > processArgs: string | string[] = [], yargs-factory.ts
214 > cwd: string,
215 > parentRequire: RequireType | undefined,
216 > shim: PlatformShim
217 > ) {
218 > this.#shim = shim;
219 > this.#processArgs = processArgs;
220 > this.#cwd = cwd;
221 > this.#parentRequire = parentRequire;
222 > this.#globalMiddleware = new GlobalMiddleware(this);
223 > this.$0 = this[kGetDollarZero]();
224 > // #command, #validation, and #usage are initialized on first reset:
225 > this[kReset]();
226 > this.#command = this!.#command;
227 > this.#usage = this!.#usage;
228 > this.#validation = this!.#validation;
229 > this.#options = this!.#options;
230 > this.#options.showHiddenOpt = this.#defaultShowHiddenOpt;
231 > this.#logger = this[kCreateLogger]();
232 > // y18n is a singleton intentionally, to prevent locales
233 > // from being loaded multiple times off disk. We reset
234 > // the language code whenever a new YargsInstance
235 > // is created mainly for unit tests.
236 > this.#shim.y18n.setLocale(DEFAULT_LOCALE);
237 > }
238 addHelpOpt(opt?: string | false, msg?: string): YargsInstance {
239 > const defaultHelpOpt = 'help'; yargs-factory.ts
240 > argsert('[string|boolean] [string]', [opt, msg], arguments.length);
241 >
242 > // nuke the key previously configured
243 > // to return help.
244 > if (this.#helpOpt) {
245 this[kDeleteFromParserHintObject](this.#helpOpt);
246 this.#helpOpt = null;
247 }
249 > if (opt === false && msg === undefined) return this;
250 >
251 > // use arguments, fallback to defaults for opt and msg
252 > this.#helpOpt = typeof opt === 'string' ? opt : defaultHelpOpt;
253 > this.boolean(this.#helpOpt);
254 > this.describe(
255 > this.#helpOpt,
256 > msg || this.#usage.deferY18nLookup('Show help')
257 > );
258 > return this;
259 > }
260 help(opt?: string, msg?: string): YargsInstance {
261 > return this.addHelpOpt(opt, msg); yargs-factory.ts
262 > }
263
264 addShowHiddenOpt(opt?: string | false, msg?: string): YargsInstance {
303 }
304 boolean(keys: string | string[]): YargsInstance {
305 > argsert('<array|string>', [keys], arguments.length); yargs-factory.ts
306 > this[kPopulateParserHintArray]('boolean', keys);
307 > this[kTrackManuallySetKeys](keys);
308 > return this;
309 > }
310 check(
311 f: (argv: Arguments, options: Options) => any,
683 }
684 describe(
685 > keys: string | string[] | Dictionary<string>, yargs-factory.ts
686 > description?: string
687 > ): YargsInstance {
688 > argsert(
689 > '<object|string|array> [string]',
690 > [keys, description],
691 > arguments.length
692 > );
693 > this[kSetKey](keys, true);
694 > this.#usage.describe(keys, description);
695 > return this;
696 > }
697 detectLocale(detect: boolean): YargsInstance {
698 argsert('<boolean>', [detect], arguments.length);
1421 }
1422 version(opt?: string | false, msg?: string, ver?: string): YargsInstance {
1423 > const defaultVersionOpt = 'version'; yargs-factory.ts
1424 > argsert(
1425 > '[boolean|string] [string] [string]',
1426 > [opt, msg, ver],
1427 > arguments.length
1428 > );
1429 >
1430 > // nuke the key previously configured
1431 > // to return version #.
1432 > if (this.#versionOpt) {
1433 this[kDeleteFromParserHintObject](this.#versionOpt);
1434 this.#usage.version(undefined);
1435 this.#versionOpt = null;
1436 }
1438 > if (arguments.length === 0) {
1439 > ver = this[kGuessVersion]();
1440 > opt = defaultVersionOpt;
1441 > } else if (arguments.length === 1) {
1442 if (opt === false) {
1443 // disable default 'version' key.
1450 msg = undefined;
1451 }
1453 > this.#versionOpt = typeof opt === 'string' ? opt : defaultVersionOpt;
1454 > msg = msg || this.#usage.deferY18nLookup('Show version number');
1455 >
1456 > this.#usage.version(ver || undefined);
1457 > this.boolean(this.#versionOpt);
1458 > this.describe(this.#versionOpt, msg);
1459 > return this;
1460 > }
1461 wrap(cols: number | nil): YargsInstance {
1462 argsert('<number|null|undefined>', [cols], arguments.length);
1483 }
1484 [kCreateLogger](): LoggerInstance {
1485 > return { yargs-factory.ts
1486 > log: (...args: any[]) => {
1487 if (!this[kHasParseCallback]()) console.log(...args);
1488 this.#hasOutput = true;
1489 if (this.#output.length) this.#output += '\n';
1490 this.#output += args.join(' ');
1491 > }, yargs-factory.ts
1492 > error: (...args: any[]) => {
1493 if (!this[kHasParseCallback]()) console.error(...args);
1494 this.#hasOutput = true;
1495 if (this.#output.length) this.#output += '\n';
1496 this.#output += args.join(' ');
1497 > }, yargs-factory.ts
1498 > };
1499 > }
1500 [kDeleteFromParserHintObject](optionKey: string) {
1501 // delete from all parsing hints:
1549 }
1550 [kGetDollarZero](): string {
1551 > let $0 = ''; yargs-factory.ts
1552 > // ignore the node bin, specify this in your
1553 > // bin file with #!/usr/bin/env node
1554 > let default$0: string[];
1555 > if (
1556 > /\b(node|iojs|electron|bun)(\.exe)?$/.test(this.#shim.process.argv()[0])
1557 > ) {
1558 default$0 = this.#shim.process.argv().slice(1, 2);
1559 > } else { yargs-factory.ts
1560 default$0 = this.#shim.process.argv().slice(0, 1);
1561 }
1563 > $0 = default$0
1564 > .map(x => {
1565 > const b = this[kRebase](this.#cwd, x);
1566 > return x.match(/^(\/|([a-zA-Z]:)?\\)/) && b.length < x.length ? b : x;
1567 > })
1568 > .join(' ')
1569 > .trim();
1570 >
1571 > if (
1572 > this.#shim.getEnv('_') &&
1573 > this.#shim.getProcessArgvBin() === this.#shim.getEnv('_')
1574 > ) {
1575 $0 = this.#shim
1576 .getEnv('_')!
1580 );
1581 }
1582 > return $0; yargs-factory.ts
1583 > }
1584 [kGetParserConfiguration](): Configuration {
1585 return this.#parserConfig;
1599 }
1600 [kGuessVersion](): string {
1601 > const obj = this[kPkgUp](); yargs-factory.ts
1602 > return (obj.version as string) || 'unknown';
1603 > }
1604 // We wait to coerce numbers for positionals until after the initial parse.
1605 // This allows commands to configure number parsing on a positional by
1619 }
1620 [kPkgUp](rootPath?: string) {
1621 > const npath = rootPath || '*'; yargs-factory.ts
1622 > if (this.#pkgs[npath]) return this.#pkgs[npath];
1623 >
1624 > let obj = {};
1625 > try {
1626 > let startDir = rootPath || this.#shim.mainFilename;
1627 > // If a file path is provided for root, remove the file and keep path.
1628 > if (this.#shim.path.extname(startDir)) {
1629 startDir = this.#shim.path.dirname(startDir);
1630 }
1632 > const pkgJsonPath = this.#shim.findUp(
1633 > startDir,
1634 > (dir: string[], names: string[]) => {
1635 > if (names.includes('package.json')) {
1636 > return 'package.json';
1637 > } else {
1638 return undefined;
1639 }
1640 > } yargs-factory.ts
1641 > );
1642 > assertNotStrictEqual(pkgJsonPath, undefined, this.#shim);
1643 > obj = JSON.parse(this.#shim.readFileSync(pkgJsonPath, 'utf8'));
1644 > // eslint-disable-next-line no-empty
1645 > } catch (_noop) {}
1646 >
1647 > this.#pkgs[npath] = obj || {};
1648 > return this.#pkgs[npath];
1649 > }
1650 [kPopulateParserHintArray]<T extends KeyOf<Options, string[]>>(
1651 > type: T, yargs-factory.ts
1652 > keys: string | string[]
1653 > ) {
1654 > keys = ([] as string[]).concat(keys);
1655 > keys.forEach(key => {
1656 > key = this[kSanitizeKey](key);
1657 > this.#options[type].push(key);
1658 > });
1659 > }
1660 [kPopulateParserHintSingleValueDictionary]<
1661 > T extends yargs-factory.ts
1662 > | Exclude<DictionaryKeyof<Options>, DictionaryKeyof<Options, any[]>>
1663 > | 'default',
1664 > K extends keyof Options[T] & string = keyof Options[T] & string,
1665 > V extends ValueOf<Options[T]> = ValueOf<Options[T]>,
1666 > >(
1667 > builder: (key: K, value: V, ...otherArgs: any[]) => YargsInstance,
1668 > type: T,
1669 > key: K | K[] | {[key in K]: V | undefined},
1670 > value?: V
1671 > ) {
1672 > this[kPopulateParserHintDictionary]<T, K, V>(
1673 > builder,
1674 > type,
1675 > key,
1676 > value,
1677 > (type, key, value) => {
1678 > this.#options[type][key] = value as ValueOf<Options[T]>;
1679 > }
1680 > );
1681 > }
1682 [kPopulateParserHintArrayDictionary]<
1683 T extends DictionaryKeyof<Options, any[]>,
1704 }
1705 [kPopulateParserHintDictionary]<
1706 > T extends keyof Options, yargs-factory.ts
1707 > K extends keyof Options[T],
1708 > V,
1709 > >(
1710 > builder: (key: K, value: V, ...otherArgs: any[]) => YargsInstance,
1711 > type: T,
1712 > key: K | K[] | {[key in K]: V | undefined},
1713 > value: V | undefined,
1714 > singleKeyHandler: (type: T, key: K, value?: V) => void
1715 > ) {
1716 > if (Array.isArray(key)) {
1717 // an array of keys with one value ['x', 'y', 'z'], function parse () {}
1718 key.forEach(k => {
1719 builder(k, value!);
1720 });
1721 > } else if ( yargs-factory.ts
1722 > ((key): key is {[key in K]: V} => typeof key === 'object')(key)
1723 > ) {
1724 // an object of key value pairs: {'x': parse () {}, 'y': parse() {}}
1725 for (const k of objectKeys(key)) {
1726 builder(k, key[k]);
1727 }
1728 > } else { yargs-factory.ts
1729 > singleKeyHandler(type, this[kSanitizeKey](key), value);
1730 > }
1731 > }
1732 [kSanitizeKey](key: any) {
1733 > if (key === '__proto__') return '___proto___'; yargs-factory.ts
1734 > return key;
1735 > }
1736 [kSetKey](
1737 > key: string | string[] | Dictionary<string | boolean>, yargs-factory.ts
1738 > set?: boolean | string
1739 > ) {
1740 > this[kPopulateParserHintSingleValueDictionary](
1741 > this[kSetKey].bind(this),
1742 > 'key',
1743 > key,
1744 > set
1745 > );
1746 > return this;
1747 > }
1748 [kUnfreeze]() {
1749 const frozen = this.#frozens.pop();
1864 // commands in a breadth first manner:
1865 [kReset](aliases: Aliases = {}): YargsInstance {
1866 > this.#options = this.#options || ({} as Options); yargs-factory.ts
1867 > const tmpOptions = {} as Options;
1868 > tmpOptions.local = this.#options.local || [];
1869 > tmpOptions.configObjects = this.#options.configObjects || [];
1870 >
1871 > // if a key has been explicitly set as local,
1872 > // we should reset it before passing options to command.
1873 > const localLookup: Dictionary<boolean> = {};
1874 > tmpOptions.local.forEach(l => {
1875 localLookup[l] = true;
1876 (aliases[l] || []).forEach(a => {
1877 localLookup[a] = true;
1878 });
1879 > }); yargs-factory.ts
1880 >
1881 > // add all groups not set to local to preserved groups
1882 > Object.assign(
1883 > this.#preservedGroups,
1884 > Object.keys(this.#groups).reduce(
1885 > (acc, groupName) => {
1886 const keys = this.#groups[groupName].filter(
1887 key => !(key in localLookup)
1891 }
1892 return acc;
1893 > }, yargs-factory.ts
1894 > {} as Dictionary<string[]>
1895 > )
1896 > );
1897 > // groups can now be reset
1898 > this.#groups = {};
1899 >
1900 > const arrayOptions: KeyOf<Options, string[]>[] = [
1901 > 'array',
1902 > 'boolean',
1903 > 'string',
1904 > 'skipValidation',
1905 > 'count',
1906 > 'normalize',
1907 > 'number',
1908 > 'hiddenOptions',
1909 > ];
1910 >
1911 > const objectOptions: DictionaryKeyof<Options>[] = [
1912 > 'narg',
1913 > 'key',
1914 > 'alias',
1915 > 'default',
1916 > 'defaultDescription',
1917 > 'config',
1918 > 'choices',
1919 > 'demandedOptions',
1920 > 'demandedCommands',
1921 > 'deprecatedOptions',
1922 > ];
1923 >
1924 > arrayOptions.forEach(k => {
1925 > tmpOptions[k] = (this.#options[k] || []).filter(
1926 > (k: string) => !localLookup[k]
1927 > );
1928 > });
1929 >
1930 > objectOptions.forEach(<K extends DictionaryKeyof<Options>>(k: K) => {
1931 > tmpOptions[k] = objFilter(
1932 > this.#options[k],
1933 > k => !localLookup[k as string]
1934 > );
1935 > });
1936 >
1937 > tmpOptions.envPrefix = this.#options.envPrefix;
1938 > this.#options = tmpOptions;
1939 >
1940 > // if this is the first time being executed, create
1941 > // instances of all our helpers -- otherwise just reset.
1942 > this.#usage = this.#usage
1943 > ? this.#usage.reset(localLookup)
1944 > : Usage(this, this.#shim);
1945 > this.#validation = this.#validation
1946 > ? this.#validation.reset(localLookup)
1947 > : Validation(this, this.#usage, this.#shim);
1948 > this.#command = this.#command
1949 > ? this.#command.reset()
1950 > : Command(
1951 > this.#usage,
1952 > this.#validation,
1953 > this.#globalMiddleware,
1954 > this.#shim
1955 > );
1956 > if (!this.#completion)
1957 > this.#completion = Completion(
1958 > this,
1959 > this.#usage,
1960 > this.#command,
1961 > this.#shim
1962 > );
1963 > this.#globalMiddleware.reset();
1964 >
1965 > this.#completionCommand = null;
1966 > this.#output = '';
1967 > this.#exitError = null;
1968 > this.#hasOutput = false;
1969 > this.parsed = false;
1970 >
1971 > return this;
1972 > }
1973 [kRebase](base: string, dir: string): string {
1974 > return this.#shim.path.relative(base, dir); yargs-factory.ts
1975 > }
1976 [kRunYargsParserAndExecuteCommands](
1977 args: string | string[] | null,
2276 }
2277 [kTrackManuallySetKeys](keys: string | string[]) {
2278 > if (typeof keys === 'string') { yargs-factory.ts
2279 > this.#options.key[keys] = true;
2280 > } else {
2281 for (const k of keys) {
2282 this.#options.key[k] = true;
2283 }
2284 }
2285 > } yargs-factory.ts
2286 }
2287
lib/usage.ts 134 introduced LOC · 32 ranges

Open complete file

13
14 export function usage(yargs: YargsInstance, shim: PlatformShim) {
15 > const __ = shim.y18n.__; usage.ts
16 > const self = {} as UsageInstance;
17 >
18 > // methods for outputting/building failure message.
19 > const fails: (FailureFunction | boolean)[] = [];
20 > self.failFn = function failFn(f) {
21 fails.push(f);
22 > }; usage.ts
23 > let failMessage: string | nil = null;
24 > let globalFailMessage: string | nil = null;
25 > let showHelpOnFail = true;
26 > self.showHelpOnFail = function showHelpOnFailFn(
27 arg1: boolean | string = true,
28 arg2?: string
40 showHelpOnFail = enabled;
41 return self;
42 > }; usage.ts
43 >
44 > let failureOutput = false;
45 > self.fail = function fail(msg, err) {
46 const logger = yargs.getInternalMethods().getLoggerInstance();
47
83 }
84 }
85 > }; usage.ts
86 >
87 > // methods for outputting/building help (usage) message.
88 > let usages: [string, string][] = [];
89 > let usageDisabled = false;
90 > self.usage = (msg, description) => {
91 if (msg === null) {
92 usageDisabled = true;
97 usages.push([msg, description || '']);
98 return self;
99 > }; usage.ts
100 > self.getUsage = () => {
101 return usages;
102 > }; usage.ts
103 > self.getUsageDisabled = () => {
104 return usageDisabled;
105 > }; usage.ts
106 >
107 > self.getPositionalGroupName = () => {
108 return __('Positionals:');
109 > }; usage.ts
110 >
111 > let examples: [string, string][] = [];
112 > self.example = (cmd, description) => {
113 examples.push([cmd, description || '']);
114 > }; usage.ts
115 >
116 > let commands: [string, string, boolean, string[], boolean][] = [];
117 > self.command = function command(
118 cmd,
119 description,
130 }
131 commands.push([cmd, description || '', isDefault, aliases, deprecated]);
132 > }; usage.ts
133 > self.getCommands = () => commands;
134 >
135 > let descriptions: Dictionary<string | undefined> = {};
136 > self.describe = function describe(
137 > keyOrKeys: string | string[] | Dictionary<string>,
138 > desc?: string
139 > ) {
140 > if (Array.isArray(keyOrKeys)) {
141 keyOrKeys.forEach(k => {
142 self.describe(k, desc);
143 });
144 > } else if (typeof keyOrKeys === 'object') { usage.ts
145 Object.keys(keyOrKeys).forEach(k => {
146 self.describe(k, keyOrKeys[k]);
147 });
148 > } else { usage.ts
149 > descriptions[keyOrKeys] = desc;
150 > }
151 > };
152 > self.getDescriptions = () => descriptions;
153 >
154 > let epilogs: string[] = [];
155 > self.epilog = msg => {
156 epilogs.push(msg);
157 > }; usage.ts
158 >
159 > let wrapSet = false;
160 > let wrap: number | nil;
161 > self.wrap = cols => {
162 wrapSet = true;
163 wrap = cols;
164 > }; usage.ts
165 >
166 > self.getWrap = () => {
167 if (shim.getEnv('YARGS_DISABLE_WRAP')) {
168 return null;
174
175 return wrap;
176 > }; usage.ts
177 >
178 > const deferY18nLookupPrefix = '__yargsString__:';
179 > self.deferY18nLookup = str => deferY18nLookupPrefix + str;
180 >
181 > self.help = function help() {
182 if (cachedHelpMessage) return cachedHelpMessage;
183 normalizeAliases();
507 // Remove the trailing white spaces
508 return ui.toString().replace(/\s*$/, '');
509 > }; usage.ts
510 >
511 > // return the maximum width of a string
512 > // in the left-hand column of a table.
513 > function maxWidth(
514 table:
515 [string | IndentedText, ...any[]][] | Dictionary<string | IndentedText>,
543 return width;
544 }
545 > usage.ts
546 > // make sure any options set for aliases,
547 > // are copied to the keys being aliased.
548 > function normalizeAliases() {
549 // handle old demanded API
550 const demandedOptions = yargs.getDemandedOptions();
568 });
569 }
570 > usage.ts
571 > // if yargs is executing an async handler, we take a snapshot of the
572 > // help message to display on failure:
573 > let cachedHelpMessage: string | undefined;
574 > self.cacheHelpMessage = function () {
575 cachedHelpMessage = this.help();
576 > }; usage.ts
577 >
578 > // however this snapshot must be cleared afterwards
579 > // not to be be used by next calls to parse
580 > self.clearCachedHelpMessage = function () {
581 cachedHelpMessage = undefined;
582 > }; usage.ts
583 >
584 > self.hasCachedHelpMessage = function () {
585 return !!cachedHelpMessage;
586 > }; usage.ts
587 >
588 > // given a set of keys, place any keys that are
589 > // ungrouped under the 'Options:' grouping.
590 > function addUngroupedKeys(
591 keys: string[],
592 aliases: Dictionary<string[]>,
608 return groupedKeys;
609 }
610 > usage.ts
611 > function filterHiddenOptions(key: string) {
612 return (
613 yargs.getOptions().hiddenOptions.indexOf(key) < 0 ||
615 );
616 }
617 > usage.ts
618 > self.showHelp = (level: 'error' | 'log' | ((message: string) => void)) => {
619 const logger = yargs.getInternalMethods().getLoggerInstance();
620 if (!level) level = 'error';
621 const emit = typeof level === 'function' ? level : logger[level];
622 emit(self.help());
623 > }; usage.ts
624 >
625 > self.functionDescription = fn => {
626 const description = fn.name
627 ? shim.Parser.decamelize(fn.name, '-')
628 : __('generated-value');
629 return ['(', description, ')'].join('');
630 > }; usage.ts
631 >
632 > self.stringifiedValues = function stringifiedValues(values, separator) {
633 let string = '';
634 const sep = separator || ', ';
643
644 return string;
645 > }; usage.ts
646 >
647 > // format the default-value-string displayed in
648 > // the right-hand column.
649 > function defaultString(value: any, defaultDescription?: string) {
650 let string = `[${__('default:')} `;
651
669 return `${string}]`;
670 }
671 > usage.ts
672 > // guess the width of the console window, max-width 80.
673 > function windowWidth() {
674 const maxWidth = 80;
675 // CI is not a TTY
681 }
682 }
683 > usage.ts
684 > // logic for displaying application version.
685 > let version: any = null;
686 > self.version = ver => {
687 > version = ver;
688 > };
689 >
690 > self.showVersion = level => {
691 const logger = yargs.getInternalMethods().getLoggerInstance();
692 if (!level) level = 'error';
693 const emit = typeof level === 'function' ? level : logger[level];
694 emit(version);
695 > }; usage.ts
696 >
697 > self.reset = function reset(localLookup) {
698 // do not reset wrap here
699 // do not reset fails here
707 descriptions = objFilter(descriptions, k => !localLookup[k]);
708 return self;
709 > }; usage.ts
710 >
711 > const frozens = [] as FrozenUsageInstance[];
712 > self.freeze = function freeze() {
713 frozens.push({
714 failMessage,
721 descriptions,
722 });
723 > }; usage.ts
724 > self.unfreeze = function unfreeze(defaultCommand = false) {
725 const frozen = frozens.pop();
726 // In the case of running a defaultCommand, we reset
747 } = frozen);
748 }
749 > }; usage.ts
750 >
751 > return self;
752 > }
753
754 /** Instance of the usage module. */
lib/validation.ts 72 introduced LOC · 18 ranges

Open complete file

16 // bad implications:
17 export function validation(
18 > yargs: YargsInstance, validation.ts
19 > usage: UsageInstance,
20 > shim: PlatformShim
21 > ) {
22 > const __ = shim.y18n.__;
23 > const __n = shim.y18n.__n;
24 > const self = {} as ValidationInstance;
25 >
26 > // validate appropriate # of non-option
27 > // arguments were provided, i.e., '_'.
28 > self.nonOptionCount = function nonOptionCount(argv) {
29 const demandedCommands = yargs.getDemandedCommands();
30 // don't count currently executing commands
82 }
83 }
84 > }; validation.ts
85 >
86 > // validate the appropriate # of <required>
87 > // positional arguments were provided:
88 > self.positionalCount = function positionalCount(required, observed) {
89 if (observed < required) {
90 usage.fail(
98 );
99 }
100 > }; validation.ts
101 >
102 > // make sure all the required arguments are present.
103 > self.requiredArguments = function requiredArguments(
104 argv,
105 demandedOptions: Dictionary<string | undefined>
136 );
137 }
138 > }; validation.ts
139 >
140 > // check for unknown arguments (strict-mode).
141 > self.unknownArguments = function unknownArguments(
142 argv,
143 aliases,
210 );
211 }
212 > }; validation.ts
213 >
214 > self.unknownCommands = function unknownCommands(argv) {
215 const commandKeys = yargs
216 .getInternalMethods()
241 return false;
242 }
243 > }; validation.ts
244 >
245 > // check for a key that is not an alias, or for which every alias is new,
246 > // implying that it was invented by the parser, e.g., during camelization
247 > self.isValidAndSomeAliasIsNotNew = function isValidAndSomeAliasIsNotNew(
248 key,
249 aliases
257 !Object.prototype.hasOwnProperty.call(newAliases, a) || !newAliases[key]
258 );
259 > }; validation.ts
260 >
261 > // validate arguments limited to enumerated choices
262 > self.limitedChoices = function limitedChoices(argv) {
263 const options = yargs.getOptions();
264 const invalid: Dictionary<any[]> = {};
297 });
298 usage.fail(msg);
299 > }; validation.ts
300 >
301 > // check implications, argument foo implies => argument bar.
302 > let implied: Dictionary<KeyOrPos[]> = {};
303 > self.implies = function implies(key, value) {
304 argsert(
305 '<string|object> [array|number|string]',
324 }
325 }
326 > }; validation.ts
327 > self.getImplied = function getImplied() {
328 return implied;
329 > }; validation.ts
330 >
331 > function keyExists(argv: Arguments, val: any): any {
332 // convert string '1' to number 1
333 const num = Number(val);
347 return val;
348 }
350 > self.implications = function implications(argv) {
351 const implyFail: string[] = [];
352
374 usage.fail(msg);
375 }
376 > }; validation.ts
377 >
378 > let conflicting: Dictionary<(string | undefined)[]> = {};
379 > self.conflicts = function conflicts(key, value) {
380 argsert('<string|object> [array|string]', [key, value], arguments.length);
381
395 }
396 }
397 > }; validation.ts
398 > self.getConflicting = () => conflicting;
399 >
400 > self.conflicting = function conflictingFn(argv) {
401 Object.keys(argv).forEach(key => {
402 if (conflicting[key]) {
430 });
431 }
432 > }; validation.ts
433 >
434 > self.recommendCommands = function recommendCommands(cmd, potentialCommands) {
435 const threshold = 3; // if it takes more than three edits, let's move on.
436 potentialCommands = potentialCommands.sort((a, b) => b.length - a.length);
450 }
451 if (recommended) usage.fail(__('Did you mean %s?', recommended));
452 > }; validation.ts
453 >
454 > self.reset = function reset(localLookup) {
455 implied = objFilter(implied, k => !localLookup[k]);
456 conflicting = objFilter(conflicting, k => !localLookup[k]);
457 return self;
458 > }; validation.ts
459 >
460 > const frozens: FrozenValidationInstance[] = [];
461 > self.freeze = function freeze() {
462 frozens.push({
463 implied,
464 conflicting,
465 });
466 > }; validation.ts
467 > self.unfreeze = function unfreeze() {
468 const frozen = frozens.pop();
469 assertNotStrictEqual(frozen, undefined, shim);
470 ({implied, conflicting} = frozen);
471 > }; validation.ts
472 >
473 > return self;
474 > }
475
476 /** Instance of the validation module. */
lib/command.ts 17 introduced LOC · 2 ranges

Open complete file

44 frozens: FrozenCommandInstance[] = [];
45 constructor(
46 > usage: UsageInstance, command.ts
47 > validation: ValidationInstance,
48 > globalMiddleware: GlobalMiddleware,
49 > shim: PlatformShim
50 > ) {
51 > this.shim = shim;
52 > this.usage = usage;
53 > this.globalMiddleware = globalMiddleware;
54 > this.validation = validation;
55 > }
56 addDirectory(
57 dir: string,
784 // Adds support to yargs for lazy loading a hierarchy of commands:
785 export function command(
786 > usage: UsageInstance, command.ts
787 > validation: ValidationInstance,
788 > globalMiddleware: GlobalMiddleware,
789 > shim: PlatformShim
790 > ) {
791 > return new CommandInstance(usage, validation, globalMiddleware, shim);
792 > }
793
794 export interface CommandHandlerDefinition extends Partial<
lib/completion.ts 17 introduced LOC · 2 ranges

Open complete file

37
38 constructor(
39 > private readonly yargs: YargsInstance, completion.ts
40 > private readonly usage: UsageInstance,
41 > private readonly command: CommandInstance,
42 > private readonly shim: PlatformShim
43 > ) {
44 > this.zshShell =
45 > (this.shim.getEnv('SHELL')?.includes('zsh') ||
46 > this.shim.getEnv('ZSH_NAME')?.includes('zsh')) ??
47 > false;
48 > }
49
50 private defaultCompletion(
374 // For backwards compatibility
375 export function completion(
376 > yargs: YargsInstance, completion.ts
377 > usage: UsageInstance,
378 > command: CommandInstance,
379 > shim: PlatformShim
380 > ): CompletionInstance {
381 > return new Completion(yargs, usage, command, shim);
382 > }
383
384 export type CompletionFunction =
lib/typings/common-types.ts 7 introduced LOC · 1 range

Open complete file

41 */
42 export function assertNotStrictEqual<N, T>(
43 > actual: T | N, common-types.ts
44 > expected: N,
45 > shim: PlatformShim,
46 > message?: string | Error
47 > ): asserts actual is Exclude<T, N> {
48 > shim.assert.notStrictEqual(actual, expected, message);
49 > }
50
51 /**
lib/middleware.ts 4 introduced LOC · 2 ranges

Open complete file

8 frozens: Array<Middleware[]> = [];
9 constructor(yargs: YargsInstance) {
10 > this.yargs = yargs; middleware.ts
11 > }
12 addMiddleware(
13 callback: MiddlewareCallback | MiddlewareCallback[],
69 }
70 reset() {
71 > this.globalMiddleware = this.globalMiddleware.filter(m => m.global); middleware.ts
72 > }
73 }
74
lib/utils/process-argv.ts 2 introduced LOC · 1 range

Open complete file

26
27 export function getProcessArgvBin() {
28 > return process.argv[getProcessArgvBinIndex()]; process-argv.ts
29 > }
30
31 interface ElectronProcess extends NodeJS.Process {