diff --git a/types/yargs/index.d.ts b/types/yargs/index.d.ts index 249f9d176f0766..19c7cf19c5352d 100644 --- a/types/yargs/index.d.ts +++ b/types/yargs/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for yargs 16.0 +// Type definitions for yargs 17.0 // Project: https://github.com/chevex/yargs, https://yargs.js.org // Definitions by: Martin Poelstra // Mizunashi Mana @@ -8,6 +8,7 @@ // Emily Marigold Klassen // ExE Boss // Aankhen +// Ben Coe // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 3.0 @@ -44,7 +45,7 @@ declare namespace yargs { * `Arguments` to simplify the inferred type signature in client code. */ interface Argv { - (): { [key in keyof Arguments]: Arguments[key] }; + (): { [key in keyof Arguments]: Arguments[key] } | Promise<{ [key in keyof Arguments]: Arguments[key] }>; (args: ReadonlyArray, cwd?: string): Argv; /** @@ -70,7 +71,7 @@ declare namespace yargs { * it will ignore the first parameter since it expects it to be the script name. In order to override * this behavior, use `.parse(process.argv.slice(1))` instead of .argv and the first parameter won't be ignored. */ - argv: { [key in keyof Arguments]: Arguments[key] }; + argv: { [key in keyof Arguments]: Arguments[key] } | Promise<{ [key in keyof Arguments]: Arguments[key] }>; /** * Tell the parser to interpret `key` as an array. @@ -332,7 +333,7 @@ declare namespace yargs { * Method to execute when a failure occurs, rather than printing the failure message. * @param func Is called with the failure message that would have been printed, the Error instance originally thrown and yargs state when the failure occurred. */ - fail(func: (msg: string, err: Error, yargs: Argv) => any): Argv; + fail(func: ((msg: string, err: Error, yargs: Argv) => any) | boolean): Argv; /** * Allows to programmatically get completion choices for any line. @@ -453,8 +454,13 @@ declare namespace yargs { * Note: Providing a callback to parse() disables the `exitProcess` setting until after the callback is invoked. * @param [context] Provides a useful mechanism for passing state information to commands */ - parse(): { [key in keyof Arguments]: Arguments[key] }; - parse(arg: string | ReadonlyArray, context?: object, parseCallback?: ParseCallback): { [key in keyof Arguments]: Arguments[key] }; + parse(): { [key in keyof Arguments]: Arguments[key] } | Promise<{ [key in keyof Arguments]: Arguments[key] }>; + parse(arg: string | ReadonlyArray, context?: object, parseCallback?: ParseCallback): { [key in keyof Arguments]: Arguments[key] } + | Promise<{ [key in keyof Arguments]: Arguments[key] }>; + parseSync(): { [key in keyof Arguments]: Arguments[key] }; + parseSync(arg: string | ReadonlyArray, context?: object, parseCallback?: ParseCallback): { [key in keyof Arguments]: Arguments[key] }; + parseAsync(): Promise<{ [key in keyof Arguments]: Arguments[key] }>; + parseAsync(arg: string | ReadonlyArray, context?: object, parseCallback?: ParseCallback): Promise<{ [key in keyof Arguments]: Arguments[key] }>; /** * If the arguments have not been parsed, this property is `false`. @@ -508,12 +514,6 @@ declare namespace yargs { requiresArg(key: string | ReadonlyArray): Argv; - /** - * @deprecated since version 6.6.0 - * Use '.global()' instead - */ - reset(): Argv; - /** Set the name of your script ($0). Default is the base filename executed by node (`process.argv[1]`) */ scriptName($0: string): Argv; @@ -836,7 +836,7 @@ declare namespace yargs { handler: (args: Arguments) => void; } - type ParseCallback = (err: Error | undefined, argv: Arguments, output: string) => void; + type ParseCallback = (err: Error | undefined, argv: Arguments|Promise>, output: string) => void; type CommandBuilder = { [key: string]: Options } | ((args: Argv) => Argv) | ((args: Argv) => PromiseLike>); type SyncCompletionFunction = (current: string, argv: any) => string[]; type AsyncCompletionFunction = (current: string, argv: any, done: (completion: ReadonlyArray) => void) => void; diff --git a/types/yargs/v16/helpers.d.ts b/types/yargs/v16/helpers.d.ts new file mode 100644 index 00000000000000..6ed18149ab1297 --- /dev/null +++ b/types/yargs/v16/helpers.d.ts @@ -0,0 +1,5 @@ +import * as Parser from 'yargs-parser'; + +export function applyExtends(config: Record, cwd: string, mergeExtends: boolean): Record; +export function hideBin(argv: string[]): string[]; +export { Parser }; diff --git a/types/yargs/v16/index.d.ts b/types/yargs/v16/index.d.ts new file mode 100644 index 00000000000000..557de27dc8c197 --- /dev/null +++ b/types/yargs/v16/index.d.ts @@ -0,0 +1,844 @@ +// Type definitions for yargs 16.0 +// Project: https://github.com/chevex/yargs, https://yargs.js.org +// Definitions by: Martin Poelstra +// Mizunashi Mana +// Jeffery Grajkowski +// Jimi (Dimitris) Charalampidis +// Steffen Viken ValvÄg +// Emily Marigold Klassen +// ExE Boss +// Aankhen +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 3.0 + +// The following TSLint rules have been disabled: +// unified-signatures: Because there is useful information in the argument names of the overloaded signatures + +// Convention: +// Use 'union types' when: +// - parameter types have similar signature type (i.e. 'string | ReadonlyArray') +// - parameter names have the same semantic meaning (i.e. ['command', 'commands'] , ['key', 'keys']) +// An example for not using 'union types' is the declaration of 'env' where `prefix` and `enable` parameters +// have different semantics. On the other hand, in the declaration of 'usage', a `command: string` parameter +// has the same semantic meaning with declaring an overload method by using `commands: ReadonlyArray`, +// thus it's preferred to use `command: string | ReadonlyArray` +// Use parameterless declaration instead of declaring all parameters optional, +// when all parameters are optional and more than one + +import { DetailedArguments, Configuration } from 'yargs-parser'; + +declare namespace yargs { + type BuilderCallback = ((args: Argv) => PromiseLike>) | ((args: Argv) => Argv) | ((args: Argv) => void); + + type ParserConfigurationOptions = Configuration & { + /** Sort commands alphabetically. Default is `false` */ + 'sort-commands': boolean; + }; + + /** + * The type parameter `T` is the expected shape of the parsed options. + * `Arguments` is those options plus `_` and `$0`, and an indexer falling + * back to `unknown` for unknown options. + * + * For the return type / `argv` property, we create a mapped type over + * `Arguments` to simplify the inferred type signature in client code. + */ + interface Argv { + (): { [key in keyof Arguments]: Arguments[key] }; + (args: ReadonlyArray, cwd?: string): Argv; + + /** + * Set key names as equivalent such that updates to a key will propagate to aliases and vice-versa. + * + * Optionally `.alias()` can take an object that maps keys to aliases. + * Each key of this object should be the canonical version of the option, and each value should be a string or an array of strings. + */ + // Aliases for previously declared options can inherit the types of those options. + alias(shortName: K1, longName: K2 | ReadonlyArray): Argv; + alias(shortName: K2, longName: K1 | ReadonlyArray): Argv; + alias(shortName: string | ReadonlyArray, longName: string | ReadonlyArray): Argv; + alias(aliases: { [shortName: string]: string | ReadonlyArray }): Argv; + + /** + * Get the arguments as a plain old object. + * + * Arguments without a corresponding flag show up in the `argv._` array. + * + * The script name or node command is available at `argv.$0` similarly to how `$0` works in bash or perl. + * + * If `yargs` is executed in an environment that embeds node and there's no script name (e.g. Electron or nw.js), + * it will ignore the first parameter since it expects it to be the script name. In order to override + * this behavior, use `.parse(process.argv.slice(1))` instead of .argv and the first parameter won't be ignored. + */ + argv: { [key in keyof Arguments]: Arguments[key] }; + + /** + * Tell the parser to interpret `key` as an array. + * If `.array('foo')` is set, `--foo foo bar` will be parsed as `['foo', 'bar']` rather than as `'foo'`. + * Also, if you use the option multiple times all the values will be flattened in one array so `--foo foo --foo bar` will be parsed as `['foo', 'bar']` + * + * When the option is used with a positional, use `--` to tell `yargs` to stop adding values to the array. + */ + array(key: K | ReadonlyArray): Argv & { [key in K]: ToArray }>; + array(key: K | ReadonlyArray): Argv | undefined }>; + + /** + * Interpret `key` as a boolean. If a non-flag option follows `key` in `process.argv`, that string won't get set as the value of `key`. + * + * `key` will default to `false`, unless a `default(key, undefined)` is explicitly set. + * + * If `key` is an array, interpret all the elements as booleans. + */ + boolean(key: K | ReadonlyArray): Argv & { [key in K]: boolean | undefined }>; + boolean(key: K | ReadonlyArray): Argv; + + /** + * Check that certain conditions are met in the provided arguments. + * @param func Called with two arguments, the parsed `argv` hash and an array of options and their aliases. + * If `func` throws or returns a non-truthy value, show the thrown error, usage information, and exit. + * @param global Indicates whether `check()` should be enabled both at the top-level and for each sub-command. + */ + check(func: (argv: Arguments, aliases: { [alias: string]: string }) => any, global?: boolean): Argv; + + /** + * Limit valid values for key to a predefined set of choices, given as an array or as an individual value. + * If this method is called multiple times, all enumerated values will be merged together. + * Choices are generally strings or numbers, and value matching is case-sensitive. + * + * Optionally `.choices()` can take an object that maps multiple keys to their choices. + * + * Choices can also be specified as choices in the object given to `option()`. + */ + choices>(key: K, values: C): Argv & { [key in K]: C[number] | undefined }>; + choices>(key: K, values: C): Argv; + choices }>(choices: C): Argv & { [key in keyof C]: C[key][number] | undefined }>; + + /** + * Provide a synchronous function to coerce or transform the value(s) given on the command line for `key`. + * + * The coercion function should accept one argument, representing the parsed value from the command line, and should return a new value or throw an error. + * The returned value will be used as the value for `key` (or one of its aliases) in `argv`. + * + * If the function throws, the error will be treated as a validation failure, delegating to either a custom `.fail()` handler or printing the error message in the console. + * + * Coercion will be applied to a value after all other modifications, such as `.normalize()`. + * + * Optionally `.coerce()` can take an object that maps several keys to their respective coercion function. + * + * You can also map the same function to several keys at one time. Just pass an array of keys as the first argument to `.coerce()`. + * + * If you are using dot-notion or arrays, .e.g., `user.email` and `user.password`, coercion will be applied to the final object that has been parsed + */ + coerce(key: K | ReadonlyArray, func: (arg: any) => V): Argv & { [key in K]: V | undefined }>; + coerce(key: K | ReadonlyArray, func: (arg: any) => V): Argv; + coerce any }>(opts: O): Argv & { [key in keyof O]: ReturnType | undefined }>; + + /** + * Define the commands exposed by your application. + * @param command Should be a string representing the command or an array of strings representing the command and its aliases. + * @param description Use to provide a description for each command your application accepts (the values stored in `argv._`). + * Set `description` to false to create a hidden command. Hidden commands don't show up in the help output and aren't available for completion. + * @param [builder] Object to give hints about the options that your command accepts. + * Can also be a function. This function is executed with a yargs instance, and can be used to provide advanced command specific help. + * + * Note that when `void` is returned, the handler `argv` object type will not include command-specific arguments. + * @param [handler] Function, which will be executed with the parsed `argv` object. + */ + command( + command: string | ReadonlyArray, + description: string, + builder?: BuilderCallback, + handler?: (args: Arguments) => void, + middlewares?: MiddlewareFunction[], + deprecated?: boolean | string, + ): Argv; + command( + command: string | ReadonlyArray, + description: string, + builder?: O, + handler?: (args: Arguments>) => void, + middlewares?: MiddlewareFunction[], + deprecated?: boolean | string, + ): Argv; + command(command: string | ReadonlyArray, description: string, module: CommandModule): Argv; + command( + command: string | ReadonlyArray, + showInHelp: false, + builder?: BuilderCallback, + handler?: (args: Arguments) => void, + middlewares?: MiddlewareFunction[], + deprecated?: boolean | string, + ): Argv; + command( + command: string | ReadonlyArray, + showInHelp: false, + builder?: O, + handler?: (args: Arguments>) => void, + ): Argv; + command(command: string | ReadonlyArray, showInHelp: false, module: CommandModule): Argv; + command(module: CommandModule): Argv; + + // Advanced API + /** Apply command modules from a directory relative to the module calling this method. */ + commandDir(dir: string, opts?: RequireDirectoryOptions): Argv; + + /** + * Enable bash/zsh-completion shortcuts for commands and options. + * + * If invoked without parameters, `.completion()` will make completion the command to output the completion script. + * + * @param [cmd] When present in `argv._`, will result in the `.bashrc` or `.zshrc` completion script being outputted. + * To enable bash/zsh completions, concat the generated script to your `.bashrc` or `.bash_profile` (or `.zshrc` for zsh). + * @param [description] Provide a description in your usage instructions for the command that generates the completion scripts. + * @param [func] Rather than relying on yargs' default completion functionality, which shiver me timbers is pretty awesome, you can provide your own completion method. + */ + completion(): Argv; + completion(cmd: string, func?: AsyncCompletionFunction): Argv; + completion(cmd: string, func?: SyncCompletionFunction): Argv; + completion(cmd: string, func?: PromiseCompletionFunction): Argv; + completion(cmd: string, description?: string | false, func?: AsyncCompletionFunction): Argv; + completion(cmd: string, description?: string | false, func?: SyncCompletionFunction): Argv; + completion(cmd: string, description?: string | false, func?: PromiseCompletionFunction): Argv; + + /** + * Tells the parser that if the option specified by `key` is passed in, it should be interpreted as a path to a JSON config file. + * The file is loaded and parsed, and its properties are set as arguments. + * Because the file is loaded using Node's require(), the filename MUST end in `.json` to be interpreted correctly. + * + * If invoked without parameters, `.config()` will make --config the option to pass the JSON config file. + * + * @param [description] Provided to customize the config (`key`) option in the usage string. + * @param [explicitConfigurationObject] An explicit configuration `object` + */ + config(): Argv; + config(key: string | ReadonlyArray, description?: string, parseFn?: (configPath: string) => object): Argv; + config(key: string | ReadonlyArray, parseFn: (configPath: string) => object): Argv; + config(explicitConfigurationObject: object): Argv; + + /** + * Given the key `x` is set, the key `y` must not be set. `y` can either be a single string or an array of argument names that `x` conflicts with. + * + * Optionally `.conflicts()` can accept an object specifying multiple conflicting keys. + */ + conflicts(key: string, value: string | ReadonlyArray): Argv; + conflicts(conflicts: { [key: string]: string | ReadonlyArray }): Argv; + + /** + * Interpret `key` as a boolean flag, but set its parsed value to the number of flag occurrences rather than `true` or `false`. Default value is thus `0`. + */ + count(key: K | ReadonlyArray): Argv & { [key in K]: number }>; + count(key: K | ReadonlyArray): Argv; + + /** + * Set `argv[key]` to `value` if no option was specified in `process.argv`. + * + * Optionally `.default()` can take an object that maps keys to default values. + * + * The default value can be a `function` which returns a value. The name of the function will be used in the usage string. + * + * Optionally, `description` can also be provided and will take precedence over displaying the value in the usage instructions. + */ + default(key: K, value: V, description?: string): Argv & { [key in K]: V }>; + default(key: K, value: V, description?: string): Argv; + default(defaults: D, description?: string): Argv & D>; + + /** + * @deprecated since version 6.6.0 + * Use '.demandCommand()' or '.demandOption()' instead + */ + demand(key: K | ReadonlyArray, msg?: string | true): Argv>; + demand(key: K | ReadonlyArray, msg?: string | true): Argv; + demand(key: string | ReadonlyArray, required?: boolean): Argv; + demand(positionals: number, msg: string): Argv; + demand(positionals: number, required?: boolean): Argv; + demand(positionals: number, max: number, msg?: string): Argv; + + /** + * @param key If is a string, show the usage information and exit if key wasn't specified in `process.argv`. + * If is an array, demand each element. + * @param msg If string is given, it will be printed when the argument is missing, instead of the standard error message. + * @param demand Controls whether the option is demanded; this is useful when using .options() to specify command line parameters. + */ + demandOption(key: K | ReadonlyArray, msg?: string | true): Argv>; + demandOption(key: K | ReadonlyArray, msg?: string | true): Argv; + demandOption(key: string | ReadonlyArray, demand?: boolean): Argv; + + /** + * Demand in context of commands. + * You can demand a minimum and a maximum number a user can have within your program, as well as provide corresponding error messages if either of the demands is not met. + */ + demandCommand(): Argv; + demandCommand(min: number, minMsg?: string): Argv; + demandCommand(min: number, max?: number, minMsg?: string, maxMsg?: string): Argv; + + /** + * Shows a [deprecated] notice in front of the option + */ + deprecateOption(option: string, msg?: string): Argv; + + /** + * Describe a `key` for the generated usage information. + * + * Optionally `.describe()` can take an object that maps keys to descriptions. + */ + describe(key: string | ReadonlyArray, description: string): Argv; + describe(descriptions: { [key: string]: string }): Argv; + + /** Should yargs attempt to detect the os' locale? Defaults to `true`. */ + detectLocale(detect: boolean): Argv; + + /** + * Tell yargs to parse environment variables matching the given prefix and apply them to argv as though they were command line arguments. + * + * Use the "__" separator in the environment variable to indicate nested options. (e.g. prefix_nested__foo => nested.foo) + * + * If this method is called with no argument or with an empty string or with true, then all env vars will be applied to argv. + * + * Program arguments are defined in this order of precedence: + * 1. Command line args + * 2. Env vars + * 3. Config file/objects + * 4. Configured defaults + * + * Env var parsing is disabled by default, but you can also explicitly disable it by calling `.env(false)`, e.g. if you need to undo previous configuration. + */ + env(): Argv; + env(prefix: string): Argv; + env(enable: boolean): Argv; + + /** A message to print at the end of the usage instructions */ + epilog(msg: string): Argv; + /** A message to print at the end of the usage instructions */ + epilogue(msg: string): Argv; + + /** + * Give some example invocations of your program. + * Inside `cmd`, the string `$0` will get interpolated to the current script name or node command for the present script similar to how `$0` works in bash or perl. + * Examples will be printed out as part of the help message. + */ + example(command: string, description: string): Argv; + example(command: ReadonlyArray<[string, string?]>): Argv; + + /** Manually indicate that the program should exit, and provide context about why we wanted to exit. Follows the behavior set by `.exitProcess().` */ + exit(code: number, err: Error): void; + + /** + * By default, yargs exits the process when the user passes a help flag, the user uses the `.version` functionality, validation fails, or the command handler fails. + * Calling `.exitProcess(false)` disables this behavior, enabling further actions after yargs have been validated. + */ + exitProcess(enabled: boolean): Argv; + + /** + * Method to execute when a failure occurs, rather than printing the failure message. + * @param func Is called with the failure message that would have been printed, the Error instance originally thrown and yargs state when the failure occurred. + */ + fail(func: (msg: string, err: Error, yargs: Argv) => any): Argv; + + /** + * Allows to programmatically get completion choices for any line. + * @param args An array of the words in the command line to complete. + * @param done The callback to be called with the resulting completions. + */ + getCompletion(args: ReadonlyArray, done: (completions: ReadonlyArray) => void): Argv; + + /** + * Indicate that an option (or group of options) should not be reset when a command is executed + * + * Options default to being global. + */ + global(key: string | ReadonlyArray): Argv; + + /** Given a key, or an array of keys, places options under an alternative heading when displaying usage instructions */ + group(key: string | ReadonlyArray, groupName: string): Argv; + + /** Hides a key from the generated usage information. Unless a `--show-hidden` option is also passed with `--help` (see `showHidden()`). */ + hide(key: string): Argv; + + /** + * Configure an (e.g. `--help`) and implicit command that displays the usage string and exits the process. + * By default yargs enables help on the `--help` option. + * + * Note that any multi-char aliases (e.g. `help`) used for the help option will also be used for the implicit command. + * If there are no multi-char aliases (e.g. `h`), then all single-char aliases will be used for the command. + * + * If invoked without parameters, `.help()` will use `--help` as the option and help as the implicit command to trigger help output. + * + * @param [description] Customizes the description of the help option in the usage string. + * @param [enableExplicit] If `false` is provided, it will disable --help. + */ + help(): Argv; + help(enableExplicit: boolean): Argv; + help(option: string, enableExplicit: boolean): Argv; + help(option: string, description?: string, enableExplicit?: boolean): Argv; + + /** + * Given the key `x` is set, it is required that the key `y` is set. + * y` can either be the name of an argument to imply, a number indicating the position of an argument or an array of multiple implications to associate with `x`. + * + * Optionally `.implies()` can accept an object specifying multiple implications. + */ + implies(key: string, value: string | ReadonlyArray): Argv; + implies(implies: { [key: string]: string | ReadonlyArray }): Argv; + + /** + * Return the locale that yargs is currently using. + * + * By default, yargs will auto-detect the operating system's locale so that yargs-generated help content will display in the user's language. + */ + locale(): string; + /** + * Override the auto-detected locale from the user's operating system with a static locale. + * Note that the OS locale can be modified by setting/exporting the `LC_ALL` environment variable. + */ + locale(loc: string): Argv; + + /** + * Define global middleware functions to be called first, in list order, for all cli command. + * @param callbacks Can be a function or a list of functions. Each callback gets passed a reference to argv. + * @param [applyBeforeValidation] Set to `true` to apply middleware before validation. This will execute the middleware prior to validation checks, but after parsing. + */ + middleware(callbacks: MiddlewareFunction | ReadonlyArray>, applyBeforeValidation?: boolean): Argv; + + /** + * The number of arguments that should be consumed after a key. This can be a useful hint to prevent parsing ambiguity. + * + * Optionally `.nargs()` can take an object of `key`/`narg` pairs. + */ + nargs(key: string, count: number): Argv; + nargs(nargs: { [key: string]: number }): Argv; + + /** The key provided represents a path and should have `path.normalize()` applied. */ + normalize(key: K | ReadonlyArray): Argv & { [key in K]: ToString }>; + normalize(key: K | ReadonlyArray): Argv; + + /** + * Tell the parser to always interpret key as a number. + * + * If `key` is an array, all elements will be parsed as numbers. + * + * If the option is given on the command line without a value, `argv` will be populated with `undefined`. + * + * If the value given on the command line cannot be parsed as a number, `argv` will be populated with `NaN`. + * + * Note that decimals, hexadecimals, and scientific notation are all accepted. + */ + number(key: K | ReadonlyArray): Argv & { [key in K]: ToNumber }>; + number(key: K | ReadonlyArray): Argv; + + /** + * Method to execute when a command finishes successfully. + * @param func Is called with the successful result of the command that finished. + */ + onFinishCommand(func: (result: any) => void): Argv; + + /** + * This method can be used to make yargs aware of options that could exist. + * You can also pass an opt object which can hold further customization, like `.alias()`, `.demandOption()` etc. for that option. + */ + option(key: K, options: O): Argv & { [key in K]: InferredOptionType }>; + option(key: K, options: O): Argv }>; + option(options: O): Argv & InferredOptionTypes>; + + /** + * This method can be used to make yargs aware of options that could exist. + * You can also pass an opt object which can hold further customization, like `.alias()`, `.demandOption()` etc. for that option. + */ + options(key: K, options: O): Argv & { [key in K]: InferredOptionType }>; + options(key: K, options: O): Argv }>; + options(options: O): Argv & InferredOptionTypes>; + + /** + * Parse `args` instead of `process.argv`. Returns the `argv` object. `args` may either be a pre-processed argv array, or a raw argument string. + * + * Note: Providing a callback to parse() disables the `exitProcess` setting until after the callback is invoked. + * @param [context] Provides a useful mechanism for passing state information to commands + */ + parse(): { [key in keyof Arguments]: Arguments[key] }; + parse(arg: string | ReadonlyArray, context?: object, parseCallback?: ParseCallback): { [key in keyof Arguments]: Arguments[key] }; + + /** + * If the arguments have not been parsed, this property is `false`. + * + * If the arguments have been parsed, this contain detailed parsed arguments. + */ + parsed: DetailedArguments | false; + + /** Allows to configure advanced yargs features. */ + parserConfiguration(configuration: Partial): Argv; + + /** + * Similar to `config()`, indicates that yargs should interpret the object from the specified key in package.json as a configuration object. + * @param [cwd] If provided, the package.json will be read from this location + */ + pkgConf(key: string | ReadonlyArray, cwd?: string): Argv; + + /** + * Allows you to configure a command's positional arguments with an API similar to `.option()`. + * `.positional()` should be called in a command's builder function, and is not available on the top-level yargs instance. If so, it will throw an error. + */ + positional(key: K, opt: O): Argv & { [key in K]: InferredOptionType }>; + positional(key: K, opt: O): Argv }>; + + /** Should yargs provide suggestions regarding similar commands if no matching command is found? */ + recommendCommands(): Argv; + + /** + * @deprecated since version 6.6.0 + * Use '.demandCommand()' or '.demandOption()' instead + */ + require(key: K | ReadonlyArray, msg?: string | true): Argv>; + require(key: string, msg: string): Argv; + require(key: string, required: boolean): Argv; + require(keys: ReadonlyArray, msg: string): Argv; + require(keys: ReadonlyArray, required: boolean): Argv; + require(positionals: number, required: boolean): Argv; + require(positionals: number, msg: string): Argv; + + /** + * @deprecated since version 6.6.0 + * Use '.demandCommand()' or '.demandOption()' instead + */ + required(key: K | ReadonlyArray, msg?: string | true): Argv>; + required(key: string, msg: string): Argv; + required(key: string, required: boolean): Argv; + required(keys: ReadonlyArray, msg: string): Argv; + required(keys: ReadonlyArray, required: boolean): Argv; + required(positionals: number, required: boolean): Argv; + required(positionals: number, msg: string): Argv; + + requiresArg(key: string | ReadonlyArray): Argv; + + /** + * @deprecated since version 6.6.0 + * Use '.global()' instead + */ + reset(): Argv; + + /** Set the name of your script ($0). Default is the base filename executed by node (`process.argv[1]`) */ + scriptName($0: string): Argv; + + /** + * Generate a bash completion script. + * Users of your application can install this script in their `.bashrc`, and yargs will provide completion shortcuts for commands and options. + */ + showCompletionScript(): Argv; + + /** + * Configure the `--show-hidden` option that displays the hidden keys (see `hide()`). + * @param option If `boolean`, it enables/disables this option altogether. i.e. hidden keys will be permanently hidden if first argument is `false`. + * If `string` it changes the key name ("--show-hidden"). + * @param description Changes the default description ("Show hidden options") + */ + showHidden(option?: string | boolean): Argv; + showHidden(option: string, description?: string): Argv; + + /** + * Print the usage data using the console function consoleLevel for printing. + * @param [consoleLevel='error'] + */ + showHelp(consoleLevel?: string): Argv; + + /** + * Provide the usage data as a string. + * @param printCallback a function with a single argument. + */ + showHelp(printCallback: (s: string) => void): Argv; + + /** + * By default, yargs outputs a usage string if any error is detected. + * Use the `.showHelpOnFail()` method to customize this behavior. + * @param enable If `false`, the usage string is not output. + * @param [message] Message that is output after the error message. + */ + showHelpOnFail(enable: boolean, message?: string): Argv; + + /** Specifies either a single option key (string), or an array of options. If any of the options is present, yargs validation is skipped. */ + skipValidation(key: string | ReadonlyArray): Argv; + + /** + * Any command-line argument given that is not demanded, or does not have a corresponding description, will be reported as an error. + * + * Unrecognized commands will also be reported as errors. + */ + strict(): Argv; + strict(enabled: boolean): Argv; + + /** + * Similar to .strict(), except that it only applies to unrecognized commands. + * A user can still provide arbitrary options, but unknown positional commands + * will raise an error. + */ + strictCommands(): Argv; + strictCommands(enabled: boolean): Argv; + + /** + * Similar to `.strict()`, except that it only applies to unrecognized options. A + * user can still provide arbitrary positional options, but unknown options + * will raise an error. + */ + strictOptions(): Argv; + strictOptions(enabled: boolean): Argv; + + /** + * Tell the parser logic not to interpret `key` as a number or boolean. This can be useful if you need to preserve leading zeros in an input. + * + * If `key` is an array, interpret all the elements as strings. + * + * `.string('_')` will result in non-hyphenated arguments being interpreted as strings, regardless of whether they resemble numbers. + */ + string(key: K | ReadonlyArray): Argv & { [key in K]: ToString }>; + string(key: K | ReadonlyArray): Argv; + + // Intended to be used with '.wrap()' + terminalWidth(): number; + + updateLocale(obj: { [key: string]: string }): Argv; + + /** + * Override the default strings used by yargs with the key/value pairs provided in obj + * + * If you explicitly specify a locale(), you should do so before calling `updateStrings()`. + */ + updateStrings(obj: { [key: string]: string }): Argv; + + /** + * Set a usage message to show which commands to use. + * Inside `message`, the string `$0` will get interpolated to the current script name or node command for the present script similar to how `$0` works in bash or perl. + * + * If the optional `description`/`builder`/`handler` are provided, `.usage()` acts an an alias for `.command()`. + * This allows you to use `.usage()` to configure the default command that will be run as an entry-point to your application + * and allows you to provide configuration for the positional arguments accepted by your program: + */ + usage(message: string): Argv; + usage(command: string | ReadonlyArray, description: string, builder?: (args: Argv) => Argv, handler?: (args: Arguments) => void): Argv; + usage(command: string | ReadonlyArray, showInHelp: boolean, builder?: (args: Argv) => Argv, handler?: (args: Arguments) => void): Argv; + usage(command: string | ReadonlyArray, description: string, builder?: O, handler?: (args: Arguments>) => void): Argv; + usage(command: string | ReadonlyArray, showInHelp: boolean, builder?: O, handler?: (args: Arguments>) => void): Argv; + + /** + * Add an option (e.g. `--version`) that displays the version number (given by the version parameter) and exits the process. + * By default yargs enables version for the `--version` option. + * + * If no arguments are passed to version (`.version()`), yargs will parse the package.json of your module and use its version value. + * + * If the boolean argument `false` is provided, it will disable `--version`. + */ + version(): Argv; + version(version: string): Argv; + version(enable: boolean): Argv; + version(optionKey: string, version: string): Argv; + version(optionKey: string, description: string, version: string): Argv; + + /** + * Format usage output to wrap at columns many columns. + * + * By default wrap will be set to `Math.min(80, windowWidth)`. Use `.wrap(null)` to specify no column limit (no right-align). + * Use `.wrap(yargs.terminalWidth())` to maximize the width of yargs' usage instructions. + */ + wrap(columns: number | null): Argv; + } + + type Arguments = T & { + /** Non-option arguments */ + _: Array; + /** The script name or node command */ + $0: string; + /** All remaining options */ + [argName: string]: unknown; + }; + + interface RequireDirectoryOptions { + /** Look for command modules in all subdirectories and apply them as a flattened (non-hierarchical) list. */ + recurse?: boolean; + /** The types of files to look for when requiring command modules. */ + extensions?: ReadonlyArray; + /** + * A synchronous function called for each command module encountered. + * Accepts `commandObject`, `pathToFile`, and `filename` as arguments. + * Returns `commandObject` to include the command; any falsy value to exclude/skip it. + */ + visit?: (commandObject: any, pathToFile?: string, filename?: string) => any; + /** Whitelist certain modules */ + include?: RegExp | ((pathToFile: string) => boolean); + /** Blacklist certain modules. */ + exclude?: RegExp | ((pathToFile: string) => boolean); + } + + interface Options { + /** string or array of strings, alias(es) for the canonical option key, see `alias()` */ + alias?: string | ReadonlyArray; + /** boolean, interpret option as an array, see `array()` */ + array?: boolean; + /** boolean, interpret option as a boolean flag, see `boolean()` */ + boolean?: boolean; + /** value or array of values, limit valid option arguments to a predefined set, see `choices()` */ + choices?: Choices; + /** function, coerce or transform parsed command line values into another value, see `coerce()` */ + coerce?: (arg: any) => any; + /** boolean, interpret option as a path to a JSON config file, see `config()` */ + config?: boolean; + /** function, provide a custom config parsing function, see `config()` */ + configParser?: (configPath: string) => object; + /** string or object, require certain keys not to be set, see `conflicts()` */ + conflicts?: string | ReadonlyArray | { [key: string]: string | ReadonlyArray }; + /** boolean, interpret option as a count of boolean flags, see `count()` */ + count?: boolean; + /** value, set a default value for the option, see `default()` */ + default?: any; + /** string, use this description for the default value in help content, see `default()` */ + defaultDescription?: string; + /** + * @deprecated since version 6.6.0 + * Use 'demandOption' instead + */ + demand?: boolean | string; + /** boolean or string, mark the argument as deprecated, see `deprecateOption()` */ + deprecate?: boolean | string; + /** boolean or string, mark the argument as deprecated, see `deprecateOption()` */ + deprecated?: boolean | string; + /** boolean or string, demand the option be given, with optional error message, see `demandOption()` */ + demandOption?: boolean | string; + /** string, the option description for help content, see `describe()` */ + desc?: string; + /** string, the option description for help content, see `describe()` */ + describe?: string; + /** string, the option description for help content, see `describe()` */ + description?: string; + /** boolean, indicate that this key should not be reset when a command is invoked, see `global()` */ + global?: boolean; + /** string, when displaying usage instructions place the option under an alternative group heading, see `group()` */ + group?: string; + /** don't display option in help output. */ + hidden?: boolean; + /** string or object, require certain keys to be set, see `implies()` */ + implies?: string | ReadonlyArray | { [key: string]: string | ReadonlyArray }; + /** number, specify how many arguments should be consumed for the option, see `nargs()` */ + nargs?: number; + /** boolean, apply path.normalize() to the option, see `normalize()` */ + normalize?: boolean; + /** boolean, interpret option as a number, `number()` */ + number?: boolean; + /** + * @deprecated since version 6.6.0 + * Use 'demandOption' instead + */ + require?: boolean | string; + /** + * @deprecated since version 6.6.0 + * Use 'demandOption' instead + */ + required?: boolean | string; + /** boolean, require the option be specified with a value, see `requiresArg()` */ + requiresArg?: boolean; + /** boolean, skips validation if the option is present, see `skipValidation()` */ + skipValidation?: boolean; + /** boolean, interpret option as a string, see `string()` */ + string?: boolean; + type?: "array" | "count" | PositionalOptionsType; + } + + interface PositionalOptions { + /** string or array of strings, see `alias()` */ + alias?: string | ReadonlyArray; + /** boolean, interpret option as an array, see `array()` */ + array?: boolean; + /** value or array of values, limit valid option arguments to a predefined set, see `choices()` */ + choices?: Choices; + /** function, coerce or transform parsed command line values into another value, see `coerce()` */ + coerce?: (arg: any) => any; + /** string or object, require certain keys not to be set, see `conflicts()` */ + conflicts?: string | ReadonlyArray | { [key: string]: string | ReadonlyArray }; + /** value, set a default value for the option, see `default()` */ + default?: any; + /** boolean or string, demand the option be given, with optional error message, see `demandOption()` */ + demandOption?: boolean | string; + /** string, the option description for help content, see `describe()` */ + desc?: string; + /** string, the option description for help content, see `describe()` */ + describe?: string; + /** string, the option description for help content, see `describe()` */ + description?: string; + /** string or object, require certain keys to be set, see `implies()` */ + implies?: string | ReadonlyArray | { [key: string]: string | ReadonlyArray }; + /** boolean, apply path.normalize() to the option, see normalize() */ + normalize?: boolean; + type?: PositionalOptionsType; + } + + /** Remove keys K in T */ + type Omit = { [key in Exclude]: T[key] }; + + /** Remove undefined as a possible value for keys K in T */ + type Defined = Omit & { [key in K]: Exclude }; + + /** Convert T to T[] and T | undefined to T[] | undefined */ + type ToArray = Array> | Extract; + + /** Gives string[] if T is an array type, otherwise string. Preserves | undefined. */ + type ToString = (Exclude extends any[] ? string[] : string) | Extract; + + /** Gives number[] if T is an array type, otherwise number. Preserves | undefined. */ + type ToNumber = (Exclude extends any[] ? number[] : number) | Extract; + + type InferredOptionType = + O extends { default: any, coerce: (arg: any) => infer T } ? T : + O extends { default: infer D } ? D : + O extends { type: "count" } ? number : + O extends { count: true } ? number : + O extends { required: string | true } ? RequiredOptionType : + O extends { require: string | true } ? RequiredOptionType : + O extends { demand: string | true } ? RequiredOptionType : + O extends { demandOption: string | true } ? RequiredOptionType : + RequiredOptionType | undefined; + + type RequiredOptionType = + O extends { type: "array", string: true } ? string[] : + O extends { type: "array", number: true } ? number[] : + O extends { type: "array", normalize: true } ? string[] : + O extends { type: "string", array: true } ? string[] : + O extends { type: "number", array: true } ? number[] : + O extends { string: true, array: true } ? string[] : + O extends { number: true, array: true } ? number[] : + O extends { normalize: true, array: true } ? string[] : + O extends { type: "array" } ? Array : + O extends { type: "boolean" } ? boolean : + O extends { type: "number" } ? number : + O extends { type: "string" } ? string : + O extends { array: true } ? Array : + O extends { boolean: true } ? boolean : + O extends { number: true } ? number : + O extends { string: true } ? string : + O extends { normalize: true } ? string : + O extends { choices: ReadonlyArray } ? C : + O extends { coerce: (arg: any) => infer T } ? T : + unknown; + + type InferredOptionTypes = { [key in keyof O]: InferredOptionType }; + + interface CommandModule { + /** array of strings (or a single string) representing aliases of `exports.command`, positional args defined in an alias are ignored */ + aliases?: ReadonlyArray | string; + /** object declaring the options the command accepts, or a function accepting and returning a yargs instance */ + builder?: CommandBuilder; + /** string (or array of strings) that executes this command when given on the command line, first string may contain positional args */ + command?: ReadonlyArray | string; + /** boolean (or string) to show deprecation notice */ + deprecated?: boolean | string; + /** string used as the description for the command in help text, use `false` for a hidden command */ + describe?: string | false; + /** a function which will be passed the parsed argv. */ + handler: (args: Arguments) => void; + } + + type ParseCallback = (err: Error | undefined, argv: Arguments, output: string) => void; + type CommandBuilder = { [key: string]: Options } | ((args: Argv) => Argv) | ((args: Argv) => PromiseLike>); + type SyncCompletionFunction = (current: string, argv: any) => string[]; + type AsyncCompletionFunction = (current: string, argv: any, done: (completion: ReadonlyArray) => void) => void; + type PromiseCompletionFunction = (current: string, argv: any) => Promise; + type MiddlewareFunction = (args: Arguments) => void; + type Choices = ReadonlyArray; + type PositionalOptionsType = "boolean" | "number" | "string"; +} + +declare var yargs: yargs.Argv; +export = yargs; diff --git a/types/yargs/v16/tsconfig.json b/types/yargs/v16/tsconfig.json new file mode 100644 index 00000000000000..33668ffc47df09 --- /dev/null +++ b/types/yargs/v16/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../../", + "paths": { + "yargs": [ + "yargs/v16" + ], + "yargs/*": [ + "yargs/v16/*" + ] + }, + "typeRoots": [ + "../../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "yargs-tests.ts" + ] +} diff --git a/types/yargs/v16/tslint.json b/types/yargs/v16/tslint.json new file mode 100644 index 00000000000000..9322b1998c69ec --- /dev/null +++ b/types/yargs/v16/tslint.json @@ -0,0 +1,12 @@ +{ + "extends": "dtslint/dt.json", + "rules": { + "npm-naming": [ + true, + { + "mode": "name-only" + } + ], + "unified-signatures": false + } +} diff --git a/types/yargs/v16/yargs-tests.ts b/types/yargs/v16/yargs-tests.ts new file mode 100644 index 00000000000000..5607a6f59bcb06 --- /dev/null +++ b/types/yargs/v16/yargs-tests.ts @@ -0,0 +1,1329 @@ +/// + +import yargs = require('yargs'); +import yargsHelpers = require('yargs/helpers'); +import yargsSingleton = require('yargs/yargs'); + +import * as fs from 'fs'; +import * as path from 'path'; +import { Arguments } from 'yargs'; + +const stringVal = 'string'; + +// Examples taken from yargs website +// https://github.com/chevex/yargs + +// With yargs, the options be just a hash! +function xup() { + const argv = yargs.argv; + + if (typeof argv.rif === "number" && typeof argv.xup === "number" && argv.rif - 5 * argv.xup > 7.138) { + console.log('Plunder more riffiwobbles!'); + } else { + console.log('Drop the xupptumblers!'); + } +} + +// And non-hyphenated options too! Just use argv._! +function nonopt() { + const argv = yargs.argv; + console.log('(%d,%d)', argv.x, argv.y); + console.log(argv._); +} + +// Yargs even counts your booleans! +function count() { + const argv = yargs + .count('verbose') + .alias('v', 'verbose') + .argv; + + const VERBOSE_LEVEL: number = argv.verbose; + + function WARN() { VERBOSE_LEVEL >= 0 && console.log.apply(console, arguments); } + function INFO() { VERBOSE_LEVEL >= 1 && console.log.apply(console, arguments); } + function DEBUG() { VERBOSE_LEVEL >= 2 && console.log.apply(console, arguments); } +} + +// Tell users how to use yer options and make demands. +function divide() { + const argv = yargs + .usage('Usage: $0 -x [num] -y [num]') + .demand(['x', 'y']) + .number(['x', 'y']) + .argv; + + console.log(argv.x / argv.y); +} + +// After yer demands have been met, demand more! Ask for non-hypenated arguments! +function demand_count() { + const argv = yargs + .demand(2) + .demand(2, false) + .demand(2, 2) + .demand(2, 2, "message") + .argv; + console.dir(argv); +} + +// EVEN MORE SHIVER ME TIMBERS! +function default_singles() { + const argv = yargs + .default('x', 10) + .default('y', 10) + .argv + ; + console.log(argv.x + argv.y); +} + +function default_hash() { + const argv = yargs + .default({ x: 10, y: 10 }) + .argv + ; + console.log(argv.x + argv.y); +} + +// And if you really want to get all descriptive about it... +function boolean_single() { + const argv = yargs + .boolean('v') + .argv + ; + console.dir(argv.v); + console.dir(argv._); +} + +function boolean_double() { + const argv = yargs + .boolean(['x', 'y', 'z']) + .argv + ; + console.dir([argv.x, argv.y, argv.z]); + console.dir(argv._); +} + +// Yargs is here to help you... +function line_count() { + const argv = yargs + .usage('Count the lines in a file.\nUsage: $0') + .example('$0 -f', 'count the lines in the given file') + .demand('f') + .alias('f', 'file') + .describe('f', 'Load a file') + .argv + ; +} + +// Below are tests for individual methods. +// Not all methods are covered yet, and neither are all possible invocations of methods. + +function Argv$argv() { + const argv = yargs.argv; + console.log("command name: " + argv.$0); + console.log("command: " + argv._[1]); +} + +function Argv$parsing() { + const argv1 = yargs.parse(); + const argv2 = yargs(['-x', '1', '-y', '2']).argv; + const argv3 = yargs.parse(['-x', '1', '-y', '2']); + const argv4 = yargs(); + console.log(argv1.x, argv2.x, argv3.x, argv4.x); + + // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } + yargs.parse(); + + // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } + yargs([]).argv; + + // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } + yargs.argv; + + // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } + yargs(); + + // $ExpectType { [x: string]: unknown; update: boolean | undefined; extern: boolean | undefined; _: (string | number)[]; $0: string; } + yargs(['--update']) + .boolean('update') + .boolean('extern') + .argv; +} + +function Argv$options() { + const argv1 = yargs + .options('f', { + alias: 'file', + default: '/etc/passwd', + defaultDescription: 'The /etc/passwd file', + group: 'files', + normalize: true, + global: false, + array: true, + nargs: 3, + implies: 'other-arg', + conflicts: 'conflicting-arg', + }) + .argv + ; + + const argv2 = yargs + .alias('f', 'file') + .default('f', '/etc/passwd') + .argv + ; +} + +function Argv$global() { + const argv = yargs + .global('foo') + .global(['bar', 'baz', 'fizz', 'buzz']); +} + +function Argv$group() { + const argv = yargs + .group('foo', 'foogroup') + .group(['bing', 'bang', 'buzz'], 'onomatopoeia'); +} + +function Argv$env() { + const argv = yargs + .env('YARGS_PREFIX_') + .env() + .env(true); +} + +function Argv$array() { + const argv = yargs + .array('foo') + .array(['bar', 'baz']); +} + +function Argv$nargs() { + const argv = yargs + .nargs('foo', 12) + .nargs({ bing: 3, bang: 2, buzz: 4 }); +} + +function Argv$choices() { + // example from documentation + const argv = yargs + .alias('i', 'ingredient') + .describe('i', 'choose your sandwich ingredients') + .choices('i', ['peanut-butter', 'jelly', 'banana', 'pickles']) + .help('help') + .argv; + + yargs + .choices('i', [undefined, true, 'asdf', 'test']) + .choices({ + test: [undefined, true, 'test-value'] + }); +} + +function Argv$usage_as_default_command() { + const argv = yargs + .usage( + "$0 get", + 'make a get HTTP request', + (yargs) => { + return yargs.option('u', { + alias: 'url', + describe: 'the URL to make an HTTP request to' + }); + }, + (argv) => { + console.dir(argv.url); + } + ) + .argv; +} + +function Argv$command() { + const argv = yargs + .usage('npm ') + .command('install', 'tis a mighty fine package to install') + .command('publish', 'shiver me timbers, should you be sharing all that', yargs => + yargs.option('f', { + alias: 'force', + description: 'yar, it usually be a bad idea' + }) + .help('help') + ) + .command("build", "arghh, build it mate", { + tag: { + default: true, + demand: true, + description: "Tag the build, mate!" + }, + publish: { + default: false, + description: "Should i publish?" + } + }) + .command({ + command: "test", + describe: "test package", + builder: { + mateys: { + demand: false + } + }, + deprecated: false, + handler: (args: any) => { + /* handle me mateys! */ + } + }) + .command("test", "test mateys", { + handler: (args: any) => { + /* handle me mateys! */ + } + }) + .help('help') + .argv; + + yargs + .command('get', 'make a get HTTP request', (yargs) => { + return yargs.option('url', { + alias: 'u', + default: 'http://yargs.js.org/' + }); + }) + .help() + .argv; + + yargs + .command( + 'get', + 'make a get HTTP request', + (yargs) => { + return yargs.option('u', { + alias: 'url', + describe: 'the URL to make an HTTP request to' + }); + }, + (argv) => { + console.dir(argv.url); + }, + // middlewares + [], + // deprecated + 'use --newGet' + ) + .help() + .argv; + + yargs + .command('get [proxy]', 'make a get HTTP request', yargs => { + yargs.positional('source', { + describe: 'URL to fetch content from', + type: 'string', + default: 'http://www.google.com' + }).positional('proxy', { + describe: 'optional proxy URL' + }); + }) + .help() + .argv; +} + +function Argv$example() { + yargs + .command({ + command: 'get', + handler: () => { + // command + }, + }) + .command({ + command: 'post', + handler: () => { + // command + }, + }) + .command({ + command: 'delete', + handler: () => { + // command + }, + }) + .example([ + ['$0 get', 'get https://example.com/'], + ['$0 post', 'post https://example.com/'], + ]) + .example('$0 delete', 'delete https://example.com').argv; +} + +function Argv$positional() { + const module: yargs.CommandModule<{}, { paths: string[] }> = { + command: 'test ', + builder(yargs) { + return yargs.positional('paths', { + type: 'string', + array: true, + demandOption: true + }); + }, + handler(argv) { + argv.paths.map((path) => path); + } + }; +} + +function Argv$commandModule() { + class CommandOne implements yargs.CommandModule { + handler(args: yargs.Arguments): void { + console.log("one"); + } + deprecated: true; + } + + const CommandTwo: yargs.CommandModule<{ a: string }, { b: number }> = { + builder: yargs => { + // $ExpectType: string + yargs.argv.a; + return yargs.number("b").default("b", parseInt(yargs.argv.a, 10)); + }, + + handler: argv => { + // $ExpectType: number + argv.b; + } + }; + + class Configure implements yargs.CommandModule<{ verbose: boolean }, { verbose: boolean, key: string, value: boolean }> { + command = 'configure [value]'; + aliases = ['config', 'cfg']; + describe = 'Set a config variable'; + + builder(yargs: yargs.Argv<{ verbose: boolean }>) { + return yargs.positional('key', { default: '' }).positional('value', { default: true }); + } + + handler(argv: yargs.Arguments<{ verbose: boolean, key: string, value: string | boolean }>) { + if (argv.verbose) { + console.log(`setting ${argv.key} to ${argv.value}`); + } + } + } + + const Configure2: yargs.CommandModule<{ verbose: boolean }, { verbose: boolean, key: string, value: boolean }> = { + command: 'configure [value]', + aliases: ['config', 'cfg'], + describe: 'Set a config variable', + + builder: yargs => { + return yargs.positional('key', { default: '' }).positional('value', { default: true }); + }, + + handler: argv => { + if (argv.verbose) { + console.log(`setting ${argv.key} to ${argv.value}`); + } + } + }; + + const command = 'import-file '; + const describe = 'run the importer on a single file'; + const builder = (yargs: yargs.Argv) => { + return yargs + .positional('file', { + describe: 'path to file to import' + }) + .options({ + cleanDestination: { + boolean: true, + describe: 'Clean the destination folder from previously generated files before proceeding.' + } + }); + }; + + const commandArgs = builder(yargs).argv; + + // $ExpectType: { [x: string]: unknown; file: unknown; cleanDestination: boolean | undefined; _: (string | number)[]; $0: string; } + commandArgs; + + // Backwards compatibility with older types + const builder2: yargs.CommandBuilder = builder; + const commandArgs2: yargs.Arguments = builder(yargs).argv; + const commandArgs3: yargs.Arguments = builder2(yargs).argv; +} + +function Argv$completion_hide() { + // no func + yargs.completion('completion', false).argv; + + // sync func + yargs.completion('complation', false, (current, argv) => { + // 'current' is the current command being completed. + // 'argv' is the parsed arguments so far. + // simply return an array of completions. + return ['foo', 'bar']; + }).argv; + + // async func + yargs.completion('complation', false, (current: string, argv: any, done: (completion: string[]) => void) => { + setTimeout(() => { + done(['apple', 'banana']); + }, 500); + }).argv; + + // promise func + yargs.completion('complation', false, (current: string, argv: any) => { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve(['apple', 'banana']); + }, 10); + }); + }).argv; +} + +function Argv$completion_sync() { + const argv = yargs + .completion('completion', (current, argv) => { + // 'current' is the current command being completed. + // 'argv' is the parsed arguments so far. + // simply return an array of completions. + return [ + 'foo', + 'bar' + ]; + }) + .argv; +} + +function Argv$completion_async() { + const argv = yargs + .completion('completion', (current: string, argv: any, done: (completion: string[]) => void) => { + setTimeout(() => { + done([ + 'apple', + 'banana' + ]); + }, 500); + }) + .argv; +} + +function Argv$completion_promise() { + const argv = yargs + .completion('completion', (current: string, argv: any) => { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve(['apple', 'banana']); + }, 10); + }); + }) + .argv; +} + +function Argv$help() { + const argv = yargs + .usage("$0 -operand1 number -operand2 number -operation [add|subtract]") + .help() + .argv; +} + +function Argv$showHelpOnFail() { + const argv = yargs + .usage('Count the lines in a file.\nUsage: $0') + .demand('f') + .alias('f', 'file') + .describe('f', 'Load a file') + .showHelpOnFail(false, "Specify --help for available options") + .argv; +} + +function Argv$showHelp() { + const yargs1 = yargs + .usage("$0 -operand1 number -operand2 number -operation [add|subtract]"); + yargs1.showHelp(); +} + +function Argv$showHelpWithCallback() { + const yargs1 = yargs.option('test', { + describe: "it's a test" + }); + yargs1.showHelp(s => console.log(`Help! ${s}`)); +} + +function Argv$version() { + const argv1 = yargs + .version(); + + const argv2 = yargs + .version('1.0.0'); + + const argv3 = yargs + .version('--version', '1.0.0'); + + const argv4 = yargs + .version('--version', 'Show version', '1.0.0'); + + const argv5 = yargs + .version(false); +} + +function Argv$wrap() { + const argv1 = yargs + .wrap(null); + + const argv2 = yargs + .wrap(yargs.terminalWidth()); +} + +function Argv$locale() { + const argv = yargs + .usage('./$0 - follow ye instructions true') + .option('option', { + alias: 'o', + describe: "'tis a mighty fine option", + demand: true + }) + .command('run', "Arrr, ya best be knowin' what yer doin'") + .example('$0 run foo', "shiver me timbers, here's an example for ye") + .help('help') + .wrap(70) + .locale('pirate') + .argv; +} + +function Argv$middleware() { + const mwFunc1 = (argv: Arguments) => console.log(`I'm a middleware function`, argv); + const mwFunc2 = (argv: Arguments) => console.log(`I'm another middleware function`, argv); + + const argv = yargs + .middleware([mwFunc1, mwFunc2]) + .middleware((argv) => { + if (process.env.HOME) argv.home = process.env.HOME; + }, true) + .argv; +} + +function Argv$epilogue() { + const argv = yargs + .epilogue('for more information, find our manual at http://example.com'); +} + +function Argv$reset() { + const ya = yargs + .usage('$0 command') + .command('hello', 'hello command') + .command('world', 'world command') + .demand(1, 'must provide a valid command'); + const argv = yargs.argv; + const command = argv._[0]; + + if (command === 'hello') { + ya.reset() + .usage('$0 hello') + .help('h') + .example('$0 hello', 'print the hello message!') + .argv; + + console.log('hello!'); + } else if (command === 'world') { + ya.reset() + .usage('$0 world') + .help('h') + .example('$0 world', 'print the world message!') + .argv; + + console.log('world!'); + } else { + ya.showHelp(); + } +} + +// http://yargs.js.org/docs/#methods-commanddirdirectory-opts +function Argv$commandDir() { + const ya = yargs + .commandDir('.') + .argv; +} + +// http://yargs.js.org/docs/#methods-commanddirdirectory-opts +function Argv$commandDirWithOptions() { + const ya = yargs + .commandDir('.', { + recurse: false, + extensions: ['js'], + visit: (commandObject: any, pathToFile?: string, filename?: string) => void 0, + include: /.*\.js$/, + exclude: /.*\.spec.js$/, + }) + .argv; +} + +function Argv$normalize() { + const ya = yargs + .normalize('path') + .normalize(['user', 'group']) + .argv; +} + +// From http://yargs.js.org/docs/#methods-coercekey-fn +function Argv$coerce() { + const ya = yargs + .coerce('file', (arg: string) => { + return fs.readFileSync(arg, 'utf8'); + }) + .argv; +} +function Argv$coerces() { + const ya = yargs + .coerce({ + date: Date.parse, + json: JSON.parse + }) + .argv; +} +function Argv$coerceWithKeys() { + const ya = yargs + .coerce(['src', 'dest'], path.resolve) + .argv; +} + +// From http://yargs.js.org/docs/#methods-failfn +function Argv$fail() { + const ya = yargs + .fail((msg, err, { help }) => { + if (err) throw err; // preserve stack + console.error('You broke it!'); + console.error(msg); + console.error(help()); + process.exit(1); + }) + .argv; +} + +function Argv$implies() { + const ya = yargs + .implies('foo', 'snuh') + .implies({ + x: 'y' + }) + .argv; +} + +function Argv$count() { + const ya = yargs + .count('size') + .count(['w', 'h']) + .argv; +} + +function Argv$number() { + const ya = yargs + .number('n') + .number(['width', 'height']) + .argv; +} + +function Argv$updateStrings() { + const ya = yargs + .command('run', 'the run command') + .help('help') + .updateStrings({ + 'Commands:': 'My Commands -->\n' + }) + .wrap(null) + .argv; +} + +function Argv$default() { + const ya = yargs + .default('random', function randomValue() { + return Math.random() * 256; + }) + .argv; +} + +function Argv$configObject() { + const ya = yargs + .config({ foo: 1, bar: 2 }) + .argv; +} + +function Argv$configParseFunction() { + const ya = yargs + .config('settings', (configPath) => { + return JSON.parse(fs.readFileSync(configPath, 'utf-8')); + }) + .config('settings', 'description', (configPath) => { + return JSON.parse(fs.readFileSync(configPath, 'utf-8')); + }) + .argv; +} + +function Argv$helpDescriptionExplicit() { + const ya = yargs + .help('help', 'description', true) + .argv; +} + +function Argv$showHelpConsoleLevel() { + yargs.showHelp("log"); // prints to stdout using console.log() +} + +function Argv$getCompletion() { + const ya = yargs + .option('foobar', {}) + .option('foobaz', {}) + .completion() + .getCompletion(['./test.js', '--foo'], (completions) => { + console.log(completions); + }) + .argv; +} + +function Argv$parserConfiguration() { + const argv1 = yargs.parserConfiguration({ + 'boolean-negation': false, + 'camel-case-expansion': false, + 'combine-arrays': false, + 'dot-notation': false, + 'duplicate-arguments-array': false, + 'flatten-duplicate-arrays': false, + 'halt-at-non-option': true, + 'negation-prefix': 'non-', + 'parse-numbers': false, + 'populate--': false, + 'set-placeholder-key': false, + 'short-option-groups': false, + 'sort-commands': true, + }).parse(); + + const argv2 = yargs.parserConfiguration({ + 'negation-prefix': 'nope-', + }).parse(); +} + +function Argv$pkgConf() { + const ya = yargs + .pkgConf(['key1', 'key2'], 'configFile.json') + .argv; +} + +function Argv$recommendCommands() { + const ya = yargs + .recommendCommands() + .argv; +} + +function Argv$showCompletionScript() { + const ya = yargs + .showCompletionScript() + .argv; +} + +function Argv$skipValidation() { + const ya = yargs + .skipValidation('arg1') + .skipValidation(['arg2', 'arg3']) + .argv; +} + +function Argv$commandObject() { + const options: yargs.Options = { + alias: "string", + array: true, + boolean: true, + choices: [undefined, true, "a", "b", "c"], + coerce: f => JSON.stringify(f), + config: true, + configParser: t => JSON.parse(fs.readFileSync(t, "utf8")), + count: true, + default: "myvalue", + defaultDescription: "description", + demand: true, + demandOption: true, + deprecate: true, + deprecated: "deprecated", + desc: "desc", + describe: "describe", + description: "description", + global: false, + group: "group", + nargs: 1, + normalize: false, + number: true, + requiresArg: true, + skipValidation: false, + string: true, + type: "string" + }; + const ya = yargs.command("commandname", "description", { arg: options }); +} + +function Argv$demandCommand() { + const ya = yargs + .demandCommand(1) + .demandCommand(1, 'at least 1 command required') + .demandCommand(1, 2) + .demandCommand(1, 2, 'at least 1 command required') + .demandCommand(1, 2, 'at least 1 command required', 'at most 2 commands required') + .argv; +} + +function Argv$demandOption() { + const ya = yargs + .demandOption('a') + .demandOption('a', 'a is required') + .demandOption('a', true) + .demandOption(['a', 'b']) + .demandOption(['a', 'b'], 'a and b are required') + .demandOption(['a', 'b'], true) + .argv; +} + +function Argv$deprecateOption() { + const ya = yargs + .option('old', {}) + .deprecateOption('old', 'use --new') + .option('new', {}) + .argv; +} + +function Argv$conflicts() { + const ya = yargs + .conflicts('a', 'b') + .conflicts({ + a: 'b' + }) + .argv; +} + +function Argv$commandArray() { + const ya = yargs + .command(['commandName', 'commandAlias'], 'command description') + .argv; +} + +function Argv$check() { + const ya = yargs + .check((argv, aliases) => void 0) + .check((argv, aliases) => void 0, false); +} + +function Argv$hide() { + const ya = yargs + .hide('a'); +} + +function Argv$showHidden() { + const ya = yargs + .showHidden() + .showHidden(true) + .showHidden('show-hidden') + .showHidden('show-hidden', 'Show hidden options'); +} + +function Argv$scriptName() { + const ya = yargs + .scriptName("my-script"); +} + +type Color = "red" | "blue" | "green"; +const colors: ReadonlyArray = ["red", "blue", "green"]; + +type Stage = 1 | 2 | 3 | 4; +const stages: ReadonlyArray = [1, 2, 3, 4]; + +function Argv$inferOptionTypes() { + // $ExpectType { [x: string]: unknown; a: (string | number)[] | undefined; b: boolean | undefined; c: number; n: number | undefined; s: string | undefined; _: (string | number)[]; $0: string; } + yargs + .option("a", { type: "array" }) + .option("b", { type: "boolean" }) + .option("c", { type: "count" }) + .option("n", { type: "number" }) + .option("s", { type: "string" }) + .argv; + + // $ExpectType { [x: string]: unknown; a: number; b: boolean; c: string; _: (string | number)[]; $0: string; } + yargs + .option("a", { default: 42 }) + .option("b", { default: false }) + .option("c", { default: "tmp" }) + .argv; + + // $ExpectType { [x: string]: unknown; a: (string | number)[] | undefined; b: boolean | undefined; n: number | undefined; s: string | undefined; _: (string | number)[]; $0: string; } + yargs + .option("a", { array: true }) + .option("b", { boolean: true }) + .option("n", { number: true }) + .option("s", { string: true }) + .argv; + + // $ExpectType { [x: string]: unknown; choices: Color; numberChoices: Stage; coerce: Date | undefined; count: number; normalize: string | undefined; _: (string | number)[]; $0: string; } + yargs + .option("choices", { choices: colors, required: true }) + .option("numberChoices", { choices: stages, demandOption: true }) + .option("coerce", { coerce: () => new Date() }) + .option("count", { count: true }) + .option("normalize", { normalize: true }) + .argv; + + // $ExpectType (string | number)[] | undefined + yargs.array("x").argv.x; + + // $ExpectType boolean | undefined + yargs.boolean("x").argv.x; + + // $ExpectType "red" | "blue" | "green" | undefined || Color | undefined + yargs.choices("x", colors).argv.x; + + // $ExpectType number | undefined + yargs.choices('x', [1, 2, 3, 4]).argv.x; + + // $ExpectType number | undefined + yargs.coerce("x", Date.parse).argv.x; + + // $ExpectType number + yargs.count("x").argv.x; + + // $ExpectType Date + yargs.default("x", new Date()).argv.x; + + // $ExpectType string | undefined + yargs.normalize("x").argv.x; + + // $ExpectType number | undefined + yargs.number("x").argv.x; + + // $ExpectType string | undefined + yargs.string("x").argv.x; +} + +function Argv$inferRequiredOptionTypes() { + // $ExpectType string + yargs.string("x").demand("x").argv.x; + + // $ExpectType string + yargs.demand("x").string("x").argv.x; + + // $ExpectType string + yargs.string("x").demandOption("x").argv.x; + + // $ExpectType string | undefined + yargs.string("x").demandOption("x", false).argv.x; + + // $ExpectType { [x: string]: unknown; x: string; y: number; _: (string | number)[]; $0: string; } + yargs.string("x").number("y").demandOption(["x", "y"]).argv; + + // $ExpectType { [x: string]: unknown; x: string; y: number; _: (string | number)[]; $0: string; } + yargs.string("x").number("y").demandOption(["x", "y"], true).argv; + + // $ExpectType { [x: string]: unknown; x: string | undefined; y: number | undefined; _: (string | number)[]; $0: string; } + yargs.string("x").number("y").demandOption(["x", "y"], false).argv; + + // $ExpectType { [x: string]: unknown; x: string; y: number; _: (string | number)[]; $0: string; } + yargs.demandOption(["x", "y"]).string("x").number("y").argv; + + // $ExpectType { [x: string]: unknown; x: string; y: number; _: (string | number)[]; $0: string; } + yargs.demandOption(["x", "y"], true).string("x").number("y").argv; + + // $ExpectType { [x: string]: unknown; x: string | undefined; y: number | undefined; _: (string | number)[]; $0: string; } + yargs.demandOption(["x", "y"], false).string("x").number("y").argv; + + // $ExpectType string + yargs.option("x", { string: true, require: true }).argv.x; + + // $ExpectType string + yargs.option("x", { string: true, required: true }).argv.x; + + // $ExpectType string + yargs.option("x", { string: true, demand: true }).argv.x; + + // $ExpectType string + yargs.option("x", { string: true, demandOption: true }).argv.x; + + // $ExpectType string | undefined + yargs.option("x", { string: true, demandOption: false }).argv.x; + + // $ExpectType number + yargs.option("x", { count: true }).argv.x; + + // $ExpectType number + yargs.option("x", { number: true, default: 42 }).argv.x; + + // $ExpectType (string | number)[] + yargs.option("x", { array: true, demandOption: true }).argv.x; +} + +function Argv$inferMultipleOptionTypes() { + // $ExpectType { [x: string]: unknown; a: string; b: boolean; c: number; d: number; e: number; _: (string | number)[]; $0: string; } + yargs + .option({ a: { default: "a" }, b: { default: false } }) + .number(["c", "d", "e"]) + .demandOption(["c", "d", "e"]) + .argv; + + // $ExpectType { [x: string]: unknown; a: string; b: boolean; c: number; d: number; e: number; _: (string | number)[]; $0: string; } + yargs + .options({ a: { default: "a" }, b: { default: false } }) + .number(["c", "d", "e"]) + .demandOption(["c", "d", "e"]) + .argv; + + // $ExpectType { [x: string]: unknown; a: number; b: string; c: boolean; _: (string | number)[]; $0: string; } + yargs + .default({ a: 42, b: "b", c: false }) + .argv; + + // $ExpectType { [x: string]: unknown; a: number; b: string; c: Date; _: (string | number)[]; $0: string; } + yargs + .coerce({ a: Date.parse, b: String.prototype.toLowerCase, c: (s: string) => new Date(s) }) + .demandOption(["a", "b", "c"]) + .argv; + + // $ExpectType { [x: string]: unknown; a: number; b: string[]; _: (string | number)[]; $0: string; } + yargs + .options({ + a: { + type: 'number', + default: 4 + }, + b: { + coerce: (arg: string) => arg.split(','), + default: 'one,two,three' + } + }) + .argv; + + // $ExpectType { [x: string]: unknown; a: number | undefined; b: string | undefined; c: Color; _: (string | number)[]; $0: string; } + yargs + .choices({ a: [1, 2, 3], b: ["black", "white"], c: colors }) + .demandOption("c") + .argv; +} + +function Argv$inferOptionTypesForAliases() { + // $ExpectType { [x: string]: unknown; u: string | undefined; url: string | undefined; _: (string | number)[]; $0: string; } + yargs + .option("u", { type: "string" }) + .alias("u", "url") + .argv; + + // $ExpectType { [x: string]: unknown; v: boolean; loud: boolean; noisy: boolean; verbose: boolean; n: boolean; _: (string | number)[]; $0: string; } + yargs + .option("v", { default: false }) + .alias("v", ["loud", "noisy", "verbose"]) + .alias("n", "noisy") + .argv; + + // $ExpectType { [x: string]: unknown; n: number; count: number; num: number; _: (string | number)[]; $0: string; } + yargs + .option("n", { number: true, demandOption: true }) + .alias("n", "count") + .alias("num", ["n", "count"]) + .argv; +} + +function Argv$inferArrayOptionTypes() { + // $ExpectType (string | number)[] + yargs.option("a", { array: true, demandOption: true }).argv.a; + + // $ExpectType string[] + yargs.option("a", { array: true, string: true, demandOption: true }).argv.a; + + // $ExpectType number[] + yargs.option("a", { array: true, number: true, demandOption: true }).argv.a; + + // $ExpectType string[] + yargs.option("a", { array: true, normalize: true, demandOption: true }).argv.a; + + // $ExpectType string[] | undefined + yargs.option("a", { array: true, type: "string" }).argv.a; + + // $ExpectType number[] | undefined + yargs.option("a", { array: true, type: "number" }).argv.a; + + // $ExpectType string[] | undefined + yargs.option("a", { array: true, normalize: true }).argv.a; + + // $ExpectType string[] | undefined + yargs.option("a", { string: true, type: "array" }).argv.a; + + // $ExpectType number[] | undefined + yargs.option("a", { number: true, type: "array" }).argv.a; + + // $ExpectType string[] | undefined + yargs.option("a", { normalize: true, type: "array" }).argv.a; + + // $ExpectType string[] | undefined || ToArray + yargs.string("a").array("a").argv.a; + + // $ExpectType string[] | undefined || ToString<(string | number)[] | undefined> + yargs.array("a").string("a").argv.a; + + // $ExpectType string[] + yargs.string("a").array("a").demandOption("a").argv.a; + + // $ExpectType string[] + yargs.array("a").string("a").demandOption("a").argv.a; + + // $ExpectType string[] + yargs.string("a").demandOption("a").array("a").argv.a; + + // $ExpectType string[] + yargs.array("a").demandOption("a").string("a").argv.a; + + // $ExpectType number[] + yargs.number("a").array("a").demandOption("a").argv.a; + + // $ExpectType number[] + yargs.array("a").number("a").demandOption("a").argv.a; + + // $ExpectType number[] + yargs.array("a").demandOption("a").number("a").argv.a; + + // $ExpectType string[] + yargs.normalize("a").array("a").demandOption("a").argv.a; + + // $ExpectType string[] + yargs.array("a").normalize("a").demandOption("a").argv.a; + + // $ExpectType string[] + yargs.array("a").demandOption("a").normalize("a").argv.a; +} + +function Argv$inferRepeatedOptionTypes() { + // $ExpectType boolean | undefined + yargs.string("a").boolean("a").argv.a; + + // $ExpectType string | undefined || ToString + yargs.number("a").string("a").argv.a; + + // $ExpectType number | undefined || ToNumber + yargs.string("a").number("a").argv.a; + + // $ExpectType boolean | undefined + yargs.string("a").option("a", { number: true }).boolean("a").argv.a; + + // $ExpectType boolean | undefined + yargs.number("a").option("a", { string: true }).boolean("a").argv.a; + + // $ExpectType string | undefined + yargs.boolean("a").option("a", { number: true }).option("a", { string: true }).argv.a; + + // $ExpectType number | undefined + yargs.boolean("a").option("a", { string: true }).option("a", { number: true }).argv.a; +} + +function Argv$fallbackToUnknownForUnknownOptions() { + // $ExpectType unknown + yargs.argv.bogus; + + // $ExpectType unknown + yargs + .option({ a: { type: "string" }, b: { type: "boolean" } }) + .argv + .bogus; + + const argv = yargs.option({ a: {}, b: {} }).option("c", {}).argv; + // $ExpectType unknown + argv.a; + // $ExpectType unknown + argv.b; + // $ExpectType unknown + argv.c; + + // $ExpectError + const x: string = yargs.argv.x; + return x; +} + +function Argv$exit() { + yargs.exit(1, new Error("oh no")); +} + +function Argv$parsed() { + const parsedArgs = yargs.parsed; +} + +function Argv$defaultCommandWithPositional(): string { + const argv = yargs.command( + "$0 ", + "default command", + (yargs) => + yargs.positional("arg", { + demandOption: true, + describe: "argument", + type: "string", + }), + () => { }).argv; + + return argv.arg; +} + +function Argv$commandsWithAsynchronousBuilders() { + const argv1 = yargs.command( + "command ", + "some command", + (yargs) => + Promise.resolve( + yargs.positional("arg", { + demandOption: true, + describe: "argument", + type: "string", + })), + () => { }).argv; + + const arg1: string = argv1.arg; + + const argv2 = yargs.command({ + command: "command ", + describe: "some command", + builder: (yargs) => + Promise.resolve( + yargs.positional("arg", { + demandOption: true, + describe: "argument", + type: "string", + })), + handler: () => {} + }).argv; + + const arg2: string = argv2.arg; +} + +function makeSingleton() { + yargsSingleton(process.argv.slice(2)); +} + +function Argv$strictOptions() { + // test taken from https://github.com/yargs/yargs/blob/master/test/validation.cjs#L1036 + const argv1 = yargs + .command('foo', 'foo command') + .option('a', { + describe: 'a is for option' + }) + .strictOptions() + .argv; +} + +function Argv$strictCommands() { + const argv1 = yargs.strictCommands().command('foo', 'foo command').argv; + const argv2 = yargs.strictCommands(true).command('foo', 'foo command').argv; +} + +function Argv$applyExtendsHelper() { + // $ExpectType Record + const arvg = yargsHelpers.applyExtends( + { extends: './package.json', apple: 'red' }, + process.cwd(), + true + ); +} + +function Argv$hideBinHelper() { + // $ExpectType string[] + const arvg = yargsHelpers.hideBin(process.argv); +} + +function Argv$ParserHelper() { + // $ExpectType Arguments + const argv = yargsHelpers.Parser('--foo --bar=99'); +} diff --git a/types/yargs/v16/yargs.d.ts b/types/yargs/v16/yargs.d.ts new file mode 100644 index 00000000000000..f370783b922af1 --- /dev/null +++ b/types/yargs/v16/yargs.d.ts @@ -0,0 +1,9 @@ +import { Argv } from '.'; + +export = Yargs; + +declare function Yargs( + processArgs?: ReadonlyArray, + cwd?: string, + parentRequire?: NodeRequire, +): Argv; diff --git a/types/yargs/yargs-tests.ts b/types/yargs/yargs-tests.ts index f0a5f4160a071b..d62a883085fafa 100644 --- a/types/yargs/yargs-tests.ts +++ b/types/yargs/yargs-tests.ts @@ -14,9 +14,8 @@ const stringVal = 'string'; // https://github.com/chevex/yargs // With yargs, the options be just a hash! -function xup() { - const argv = yargs.argv; - +async function xup() { + const argv = await yargs.parse(); if (typeof argv.rif === "number" && typeof argv.xup === "number" && argv.rif - 5 * argv.xup > 7.138) { console.log('Plunder more riffiwobbles!'); } else { @@ -26,7 +25,7 @@ function xup() { // And non-hyphenated options too! Just use argv._! function nonopt() { - const argv = yargs.argv; + const argv = yargs.parseSync(); console.log('(%d,%d)', argv.x, argv.y); console.log(argv._); } @@ -36,7 +35,7 @@ function count() { const argv = yargs .count('verbose') .alias('v', 'verbose') - .argv; + .parseSync(); const VERBOSE_LEVEL: number = argv.verbose; @@ -51,7 +50,7 @@ function divide() { .usage('Usage: $0 -x [num] -y [num]') .demand(['x', 'y']) .number(['x', 'y']) - .argv; + .parseSync(); console.log(argv.x / argv.y); } @@ -72,16 +71,14 @@ function default_singles() { const argv = yargs .default('x', 10) .default('y', 10) - .argv - ; + .parseSync(); console.log(argv.x + argv.y); } function default_hash() { const argv = yargs .default({ x: 10, y: 10 }) - .argv - ; + .parseSync(); console.log(argv.x + argv.y); } @@ -89,8 +86,7 @@ function default_hash() { function boolean_single() { const argv = yargs .boolean('v') - .argv - ; + .parseSync(); console.dir(argv.v); console.dir(argv._); } @@ -98,8 +94,7 @@ function boolean_single() { function boolean_double() { const argv = yargs .boolean(['x', 'y', 'z']) - .argv - ; + .parseSync(); console.dir([argv.x, argv.y, argv.z]); console.dir(argv._); } @@ -112,43 +107,42 @@ function line_count() { .demand('f') .alias('f', 'file') .describe('f', 'Load a file') - .argv - ; + .argv; } // Below are tests for individual methods. // Not all methods are covered yet, and neither are all possible invocations of methods. -function Argv$argv() { - const argv = yargs.argv; +async function Argv$argv() { + const argv = await yargs.parse(); console.log("command name: " + argv.$0); console.log("command: " + argv._[1]); } -function Argv$parsing() { - const argv1 = yargs.parse(); - const argv2 = yargs(['-x', '1', '-y', '2']).argv; - const argv3 = yargs.parse(['-x', '1', '-y', '2']); - const argv4 = yargs(); +async function Argv$parsing() { + const argv1 = await yargs.parse(); + const argv2 = yargs(['-x', '1', '-y', '2']).parseSync(); + const argv3 = yargs.parseSync(['-x', '1', '-y', '2']); + const argv4 = await yargs(); console.log(argv1.x, argv2.x, argv3.x, argv4.x); - // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } + // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } | Promise<{ [x: string]: unknown; _: (string | number)[]; $0: string; }> yargs.parse(); - // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } + // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } | Promise<{ [x: string]: unknown; _: (string | number)[]; $0: string; }> yargs([]).argv; - // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } + // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } | Promise<{ [x: string]: unknown; _: (string | number)[]; $0: string; }> yargs.argv; - // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } + // $ExpectType { [x: string]: unknown; _: (string | number)[]; $0: string; } | Promise<{ [x: string]: unknown; _: (string | number)[]; $0: string; }> yargs(); // $ExpectType { [x: string]: unknown; update: boolean | undefined; extern: boolean | undefined; _: (string | number)[]; $0: string; } yargs(['--update']) .boolean('update') .boolean('extern') - .argv; + .parseSync(); } function Argv$options() { @@ -371,7 +365,7 @@ function Argv$positional() { }; } -function Argv$commandModule() { +async function Argv$commandModule() { class CommandOne implements yargs.CommandModule { handler(args: yargs.Arguments): void { console.log("one"); @@ -380,10 +374,10 @@ function Argv$commandModule() { } const CommandTwo: yargs.CommandModule<{ a: string }, { b: number }> = { - builder: yargs => { + builder: async yargs => { // $ExpectType: string - yargs.argv.a; - return yargs.number("b").default("b", parseInt(yargs.argv.a, 10)); + (await yargs.argv).a; + return yargs.number("b").default("b", parseInt((await yargs.argv).a, 10)); }, handler: argv => { @@ -446,8 +440,8 @@ function Argv$commandModule() { // Backwards compatibility with older types const builder2: yargs.CommandBuilder = builder; - const commandArgs2: yargs.Arguments = builder(yargs).argv; - const commandArgs3: yargs.Arguments = builder2(yargs).argv; + const commandArgs2: yargs.Arguments = await builder(yargs).argv; + const commandArgs3: yargs.Arguments = await builder2(yargs).argv; } function Argv$completion_hide() { @@ -606,36 +600,6 @@ function Argv$epilogue() { .epilogue('for more information, find our manual at http://example.com'); } -function Argv$reset() { - const ya = yargs - .usage('$0 command') - .command('hello', 'hello command') - .command('world', 'world command') - .demand(1, 'must provide a valid command'); - const argv = yargs.argv; - const command = argv._[0]; - - if (command === 'hello') { - ya.reset() - .usage('$0 hello') - .help('h') - .example('$0 hello', 'print the hello message!') - .argv; - - console.log('hello!'); - } else if (command === 'world') { - ya.reset() - .usage('$0 world') - .help('h') - .example('$0 world', 'print the world message!') - .argv; - - console.log('world!'); - } else { - ya.showHelp(); - } -} - // http://yargs.js.org/docs/#methods-commanddirdirectory-opts function Argv$commandDir() { const ya = yargs @@ -696,6 +660,12 @@ function Argv$fail() { process.exit(1); }) .argv; + + // Providing false as a value for fn can be used to prevent yargs from + // exiting and printing a failure message + const ya2 = yargs + .fail(false) + .argv; } function Argv$implies() { @@ -931,30 +901,30 @@ const colors: ReadonlyArray = ["red", "blue", "green"]; type Stage = 1 | 2 | 3 | 4; const stages: ReadonlyArray = [1, 2, 3, 4]; -function Argv$inferOptionTypes() { +async function Argv$inferOptionTypes() { // $ExpectType { [x: string]: unknown; a: (string | number)[] | undefined; b: boolean | undefined; c: number; n: number | undefined; s: string | undefined; _: (string | number)[]; $0: string; } - yargs + await yargs .option("a", { type: "array" }) .option("b", { type: "boolean" }) .option("c", { type: "count" }) .option("n", { type: "number" }) .option("s", { type: "string" }) - .argv; + .parseAsync(); // $ExpectType { [x: string]: unknown; a: number; b: boolean; c: string; _: (string | number)[]; $0: string; } yargs .option("a", { default: 42 }) .option("b", { default: false }) .option("c", { default: "tmp" }) - .argv; + .parseSync(); // $ExpectType { [x: string]: unknown; a: (string | number)[] | undefined; b: boolean | undefined; n: number | undefined; s: string | undefined; _: (string | number)[]; $0: string; } - yargs + await yargs .option("a", { array: true }) .option("b", { boolean: true }) .option("n", { number: true }) .option("s", { string: true }) - .argv; + .parseAsync(); // $ExpectType { [x: string]: unknown; choices: Color; numberChoices: Stage; coerce: Date | undefined; count: number; normalize: string | undefined; _: (string | number)[]; $0: string; } yargs @@ -963,105 +933,105 @@ function Argv$inferOptionTypes() { .option("coerce", { coerce: () => new Date() }) .option("count", { count: true }) .option("normalize", { normalize: true }) - .argv; + .parseSync(); // $ExpectType (string | number)[] | undefined - yargs.array("x").argv.x; + (await yargs.array("x").argv).x; // $ExpectType boolean | undefined - yargs.boolean("x").argv.x; + (await yargs.boolean("x").argv).x; // $ExpectType "red" | "blue" | "green" | undefined || Color | undefined - yargs.choices("x", colors).argv.x; + yargs.choices("x", colors).parseSync().x; // $ExpectType number | undefined - yargs.choices('x', [1, 2, 3, 4]).argv.x; + yargs.choices('x', [1, 2, 3, 4]).parseSync().x; // $ExpectType number | undefined - yargs.coerce("x", Date.parse).argv.x; + (await yargs.coerce("x", Date.parse).argv).x; // $ExpectType number - yargs.count("x").argv.x; + yargs.count("x").parseSync().x; // $ExpectType Date - yargs.default("x", new Date()).argv.x; + yargs.default("x", new Date()).parseSync().x; // $ExpectType string | undefined - yargs.normalize("x").argv.x; + (await yargs.normalize("x").argv).x; // $ExpectType number | undefined - yargs.number("x").argv.x; + (await yargs.number("x").argv).x; // $ExpectType string | undefined - yargs.string("x").argv.x; + yargs.string("x").parseSync().x; } function Argv$inferRequiredOptionTypes() { // $ExpectType string - yargs.string("x").demand("x").argv.x; + yargs.string("x").demand("x").parseSync().x; // $ExpectType string - yargs.demand("x").string("x").argv.x; + yargs.demand("x").string("x").parseSync().x; // $ExpectType string - yargs.string("x").demandOption("x").argv.x; + yargs.string("x").demandOption("x").parseSync().x; // $ExpectType string | undefined - yargs.string("x").demandOption("x", false).argv.x; + yargs.string("x").demandOption("x", false).parseSync().x; // $ExpectType { [x: string]: unknown; x: string; y: number; _: (string | number)[]; $0: string; } - yargs.string("x").number("y").demandOption(["x", "y"]).argv; + yargs.string("x").number("y").demandOption(["x", "y"]).parseSync(); // $ExpectType { [x: string]: unknown; x: string; y: number; _: (string | number)[]; $0: string; } - yargs.string("x").number("y").demandOption(["x", "y"], true).argv; + yargs.string("x").number("y").demandOption(["x", "y"], true).parseSync(); // $ExpectType { [x: string]: unknown; x: string | undefined; y: number | undefined; _: (string | number)[]; $0: string; } - yargs.string("x").number("y").demandOption(["x", "y"], false).argv; + yargs.string("x").number("y").demandOption(["x", "y"], false).parseSync(); // $ExpectType { [x: string]: unknown; x: string; y: number; _: (string | number)[]; $0: string; } - yargs.demandOption(["x", "y"]).string("x").number("y").argv; + yargs.demandOption(["x", "y"]).string("x").number("y").parseSync(); // $ExpectType { [x: string]: unknown; x: string; y: number; _: (string | number)[]; $0: string; } - yargs.demandOption(["x", "y"], true).string("x").number("y").argv; + yargs.demandOption(["x", "y"], true).string("x").number("y").parseSync(); // $ExpectType { [x: string]: unknown; x: string | undefined; y: number | undefined; _: (string | number)[]; $0: string; } - yargs.demandOption(["x", "y"], false).string("x").number("y").argv; + yargs.demandOption(["x", "y"], false).string("x").number("y").parseSync(); // $ExpectType string - yargs.option("x", { string: true, require: true }).argv.x; + yargs.option("x", { string: true, require: true }).parseSync().x; // $ExpectType string - yargs.option("x", { string: true, required: true }).argv.x; + yargs.option("x", { string: true, required: true }).parseSync().x; // $ExpectType string - yargs.option("x", { string: true, demand: true }).argv.x; + yargs.option("x", { string: true, demand: true }).parseSync().x; // $ExpectType string - yargs.option("x", { string: true, demandOption: true }).argv.x; + yargs.option("x", { string: true, demandOption: true }).parseSync().x; // $ExpectType string | undefined - yargs.option("x", { string: true, demandOption: false }).argv.x; + yargs.option("x", { string: true, demandOption: false }).parseSync().x; // $ExpectType number - yargs.option("x", { count: true }).argv.x; + yargs.option("x", { count: true }).parseSync().x; // $ExpectType number - yargs.option("x", { number: true, default: 42 }).argv.x; + yargs.option("x", { number: true, default: 42 }).parseSync().x; // $ExpectType (string | number)[] - yargs.option("x", { array: true, demandOption: true }).argv.x; + yargs.option("x", { array: true, demandOption: true }).parseSync().x; // $ExpectType string - yargs.option("x", { default: "default" as string | undefined, demandOption: true }).argv.x; + yargs.option("x", { default: "default" as string | undefined, demandOption: true }).parseSync().x; // $ExpectType string - yargs.option("x", { default: "default" as string | undefined, demand: true }).argv.x; + yargs.option("x", { default: "default" as string | undefined, demand: true }).parseSync().x; // $ExpectType string - yargs.option("x", { default: "default" as string | undefined, require: true }).argv.x; + yargs.option("x", { default: "default" as string | undefined, require: true }).parseSync().x; // $ExpectType string - yargs.option("x", { default: "default" as string | undefined, required: true }).argv.x; + yargs.option("x", { default: "default" as string | undefined, required: true }).parseSync().x; } function Argv$inferMultipleOptionTypes() { @@ -1070,25 +1040,25 @@ function Argv$inferMultipleOptionTypes() { .option({ a: { default: "a" }, b: { default: false } }) .number(["c", "d", "e"]) .demandOption(["c", "d", "e"]) - .argv; + .parseSync(); // $ExpectType { [x: string]: unknown; a: string; b: boolean; c: number; d: number; e: number; _: (string | number)[]; $0: string; } yargs .options({ a: { default: "a" }, b: { default: false } }) .number(["c", "d", "e"]) .demandOption(["c", "d", "e"]) - .argv; + .parseSync(); // $ExpectType { [x: string]: unknown; a: number; b: string; c: boolean; _: (string | number)[]; $0: string; } yargs .default({ a: 42, b: "b", c: false }) - .argv; + .parseSync(); // $ExpectType { [x: string]: unknown; a: number; b: string; c: Date; _: (string | number)[]; $0: string; } yargs .coerce({ a: Date.parse, b: String.prototype.toLowerCase, c: (s: string) => new Date(s) }) .demandOption(["a", "b", "c"]) - .argv; + .parseSync(); // $ExpectType { [x: string]: unknown; a: number; b: string[]; _: (string | number)[]; $0: string; } yargs @@ -1102,13 +1072,13 @@ function Argv$inferMultipleOptionTypes() { default: 'one,two,three' } }) - .argv; + .parseSync(); // $ExpectType { [x: string]: unknown; a: number | undefined; b: string | undefined; c: Color; _: (string | number)[]; $0: string; } yargs .choices({ a: [1, 2, 3], b: ["black", "white"], c: colors }) .demandOption("c") - .argv; + .parseSync(); } function Argv$inferOptionTypesForAliases() { @@ -1116,125 +1086,125 @@ function Argv$inferOptionTypesForAliases() { yargs .option("u", { type: "string" }) .alias("u", "url") - .argv; + .parseSync(); // $ExpectType { [x: string]: unknown; v: boolean; loud: boolean; noisy: boolean; verbose: boolean; n: boolean; _: (string | number)[]; $0: string; } yargs .option("v", { default: false }) .alias("v", ["loud", "noisy", "verbose"]) .alias("n", "noisy") - .argv; + .parseSync(); // $ExpectType { [x: string]: unknown; n: number; count: number; num: number; _: (string | number)[]; $0: string; } yargs .option("n", { number: true, demandOption: true }) .alias("n", "count") .alias("num", ["n", "count"]) - .argv; + .parseSync(); } -function Argv$inferArrayOptionTypes() { +async function Argv$inferArrayOptionTypes() { // $ExpectType (string | number)[] - yargs.option("a", { array: true, demandOption: true }).argv.a; + (await yargs.option("a", { array: true, demandOption: true }).argv).a; // $ExpectType string[] - yargs.option("a", { array: true, string: true, demandOption: true }).argv.a; + (await yargs.option("a", { array: true, string: true, demandOption: true }).parseAsync()).a; // $ExpectType number[] - yargs.option("a", { array: true, number: true, demandOption: true }).argv.a; + yargs.option("a", { array: true, number: true, demandOption: true }).parseSync().a; // $ExpectType string[] - yargs.option("a", { array: true, normalize: true, demandOption: true }).argv.a; + yargs.option("a", { array: true, normalize: true, demandOption: true }).parseSync().a; // $ExpectType string[] | undefined - yargs.option("a", { array: true, type: "string" }).argv.a; + yargs.option("a", { array: true, type: "string" }).parseSync().a; // $ExpectType number[] | undefined - yargs.option("a", { array: true, type: "number" }).argv.a; + yargs.option("a", { array: true, type: "number" }).parseSync().a; // $ExpectType string[] | undefined - yargs.option("a", { array: true, normalize: true }).argv.a; + yargs.option("a", { array: true, normalize: true }).parseSync().a; // $ExpectType string[] | undefined - yargs.option("a", { string: true, type: "array" }).argv.a; + yargs.option("a", { string: true, type: "array" }).parseSync().a; // $ExpectType number[] | undefined - yargs.option("a", { number: true, type: "array" }).argv.a; + yargs.option("a", { number: true, type: "array" }).parseSync().a; // $ExpectType string[] | undefined - yargs.option("a", { normalize: true, type: "array" }).argv.a; + yargs.option("a", { normalize: true, type: "array" }).parseSync().a; // $ExpectType string[] | undefined || ToArray - yargs.string("a").array("a").argv.a; + yargs.string("a").array("a").parseSync().a; // $ExpectType string[] | undefined || ToString<(string | number)[] | undefined> - yargs.array("a").string("a").argv.a; + yargs.array("a").string("a").parseSync().a; // $ExpectType string[] - yargs.string("a").array("a").demandOption("a").argv.a; + yargs.string("a").array("a").demandOption("a").parseSync().a; // $ExpectType string[] - yargs.array("a").string("a").demandOption("a").argv.a; + yargs.array("a").string("a").demandOption("a").parseSync().a; // $ExpectType string[] - yargs.string("a").demandOption("a").array("a").argv.a; + yargs.string("a").demandOption("a").array("a").parseSync().a; // $ExpectType string[] - yargs.array("a").demandOption("a").string("a").argv.a; + yargs.array("a").demandOption("a").string("a").parseSync().a; // $ExpectType number[] - yargs.number("a").array("a").demandOption("a").argv.a; + yargs.number("a").array("a").demandOption("a").parseSync().a; // $ExpectType number[] - yargs.array("a").number("a").demandOption("a").argv.a; + yargs.array("a").number("a").demandOption("a").parseSync().a; // $ExpectType number[] - yargs.array("a").demandOption("a").number("a").argv.a; + yargs.array("a").demandOption("a").number("a").parseSync().a; // $ExpectType string[] - yargs.normalize("a").array("a").demandOption("a").argv.a; + yargs.normalize("a").array("a").demandOption("a").parseSync().a; // $ExpectType string[] - yargs.array("a").normalize("a").demandOption("a").argv.a; + yargs.array("a").normalize("a").demandOption("a").parseSync().a; // $ExpectType string[] - yargs.array("a").demandOption("a").normalize("a").argv.a; + yargs.array("a").demandOption("a").normalize("a").parseSync().a; } function Argv$inferRepeatedOptionTypes() { // $ExpectType boolean | undefined - yargs.string("a").boolean("a").argv.a; + yargs.string("a").boolean("a").parseSync().a; // $ExpectType string | undefined || ToString - yargs.number("a").string("a").argv.a; + yargs.number("a").string("a").parseSync().a; // $ExpectType number | undefined || ToNumber - yargs.string("a").number("a").argv.a; + yargs.string("a").number("a").parseSync().a; // $ExpectType boolean | undefined - yargs.string("a").option("a", { number: true }).boolean("a").argv.a; + yargs.string("a").option("a", { number: true }).boolean("a").parseSync().a; // $ExpectType boolean | undefined - yargs.number("a").option("a", { string: true }).boolean("a").argv.a; + yargs.number("a").option("a", { string: true }).boolean("a").parseSync().a; // $ExpectType string | undefined - yargs.boolean("a").option("a", { number: true }).option("a", { string: true }).argv.a; + yargs.boolean("a").option("a", { number: true }).option("a", { string: true }).parseSync().a; // $ExpectType number | undefined - yargs.boolean("a").option("a", { string: true }).option("a", { number: true }).argv.a; + yargs.boolean("a").option("a", { string: true }).option("a", { number: true }).parseSync().a; } -function Argv$fallbackToUnknownForUnknownOptions() { +async function Argv$fallbackToUnknownForUnknownOptions() { // $ExpectType unknown - yargs.argv.bogus; + (await yargs.argv).bogus; // $ExpectType unknown yargs .option({ a: { type: "string" }, b: { type: "boolean" } }) - .argv + .parseSync() .bogus; - const argv = yargs.option({ a: {}, b: {} }).option("c", {}).argv; + const argv = await yargs.option({ a: {}, b: {} }).option("c", {}).argv; // $ExpectType unknown argv.a; // $ExpectType unknown @@ -1243,7 +1213,7 @@ function Argv$fallbackToUnknownForUnknownOptions() { argv.c; // $ExpectError - const x: string = yargs.argv.x; + const x: string = (await yargs.argv).x; return x; } @@ -1255,7 +1225,7 @@ function Argv$parsed() { const parsedArgs = yargs.parsed; } -function Argv$defaultCommandWithPositional(): string { +async function Argv$defaultCommandWithPositional(): Promise { const argv = yargs.command( "$0 ", "default command", @@ -1267,7 +1237,7 @@ function Argv$defaultCommandWithPositional(): string { }), () => { }).argv; - return argv.arg; + return (await argv).arg; } function Argv$commandsWithAsynchronousBuilders() { @@ -1281,7 +1251,7 @@ function Argv$commandsWithAsynchronousBuilders() { describe: "argument", type: "string", })), - () => { }).argv; + () => { }).parseSync(); const arg1: string = argv1.arg; @@ -1296,7 +1266,7 @@ function Argv$commandsWithAsynchronousBuilders() { type: "string", })), handler: () => {} - }).argv; + }).parseSync(); const arg2: string = argv2.arg; }