diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f7fece..d8b5a41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,26 @@ The version numbering does not follow semantic versioning but instead aligns wit +## [11.1.0] (2023-10-15) + +### Added + +- `Option` properties: `envVar`, `presetArg` ([#48]) +- `Argument` properties: `argChoices`, `defaultValue`, `defaultValueDescription` ([#48]) +- `Command` properties: `options`, `registeredArguments` ([#50]) + +### Changed + +- `commands` property of `Command` is now readonly ([#48]) +- update `peerDependencies` to `commander@11.1.x` ([#48]) + +### Fixed + +- remove unused `Option.optionFlags` property ([#48]) +- add that `Command.version()` can also be used as getter ([#48]) +- add null return type to `Commands.executableDir()`, for when not configured ([#48]) +- preserve option typings when adding arguments to `Command` ([#49]) + ## [11.0.0] (2023-06-16) ### Changed @@ -113,6 +133,7 @@ The version numbering does not follow semantic versioning but instead aligns wit - inferred types for `.action()` - inferred types for `.opts()` +[11.1.0]: https://github.com/commander-js/extra-typings/compare/v11.0.0...v11.1.0 [11.0.0]: https://github.com/commander-js/extra-typings/compare/v10.0.3...v11.0.0 [10.0.3]: https://github.com/commander-js/extra-typings/compare/v10.0.2...v10.0.3 [10.0.2]: https://github.com/commander-js/extra-typings/compare/v10.0.1...v10.0.2 @@ -132,3 +153,6 @@ The version numbering does not follow semantic versioning but instead aligns wit [#29]: https://github.com/commander-js/extra-typings/pull/29 [#31]: https://github.com/commander-js/extra-typings/pull/31 [#33]: https://github.com/commander-js/extra-typings/pull/33 +[#48]: https://github.com/commander-js/extra-typings/pull/48 +[#49]: https://github.com/commander-js/extra-typings/pull/49 +[#50]: https://github.com/commander-js/extra-typings/pull/50 diff --git a/index.d.ts b/index.d.ts index fd791a5..c250d17 100644 --- a/index.d.ts +++ b/index.d.ts @@ -212,7 +212,10 @@ export class CommanderError extends Error { description: string; required: boolean; variadic: boolean; - + defaultValue?: any; + defaultValueDescription?: string; + argChoices?: string[]; + /** * Initialize a new command argument with the given name and description. * The default is that the argument is required, and you can explicitly @@ -259,12 +262,13 @@ export class CommanderError extends Error { optional: boolean; // A value is optional when the option is specified. variadic: boolean; mandatory: boolean; // The option must have a value after parsing, which usually means it must be specified on command line. - optionFlags: string; short?: string; long?: string; negate: boolean; defaultValue?: any; defaultValueDescription?: string; + presetArg?: unknown; + envVar?: string; parseArg?: (value: string, previous: T) => T; hidden: boolean; argChoices?: string[]; @@ -446,14 +450,12 @@ export class CommanderError extends Error { // The source is a string so author can define their own too. export type OptionValueSource = LiteralUnion<'default' | 'config' | 'env' | 'cli' | 'implied', string> | undefined; - export interface OptionValues { - [key: string]: unknown; - } + export type OptionValues = Record; export class Command { args: string[]; processedArgs: Args; - commands: CommandUnknownOpts[]; + readonly commands: readonly CommandUnknownOpts[]; readonly options: readonly Option[]; readonly registeredArguments: readonly Argument[]; parent: CommandUnknownOpts | null; @@ -469,7 +471,10 @@ export class CommanderError extends Error { * You can optionally supply the flags and description to override the defaults. */ version(str: string, flags?: string, description?: string): this; - + /** + * Get the program version. + */ + version(): string | undefined; /** * Define a command, implemented using an action handler. * @@ -681,45 +686,21 @@ export class CommanderError extends Error { action(fn: (...args: [...Args, Opts, this]) => void | Promise): this; /** - * Define option with `flags`, `description` and optional - * coercion `fn`. + * Define option with `flags`, `description`, and optional argument parsing function or `defaultValue` or both. * - * The `flags` string contains the short and/or long flags, - * separated by comma, a pipe or space. The following are all valid - * all will output this way when `--help` is used. + * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space. A required + * option-argument is indicated by `<>` and an optional option-argument by `[]`. * - * "-p, --pepper" - * "-p|--pepper" - * "-p --pepper" + * See the README for more details, and see also addOption() and requiredOption(). * * @example - * ``` - * // simple boolean defaulting to false - * program.option('-p, --pepper', 'add pepper'); - * - * --pepper - * program.pepper - * // => Boolean - * - * // simple boolean defaulting to true - * program.option('-C, --no-cheese', 'remove cheese'); - * - * program.cheese - * // => true * - * --no-cheese - * program.cheese - * // => false - * - * // required argument - * program.option('-C, --chdir ', 'change the working directory'); - * - * --chdir /tmp - * program.chdir - * // => "/tmp" - * - * // optional argument - * program.option('-c, --cheese [type]', 'add cheese [marble]'); + * ```js + * program + * .option('-p, --pepper', 'add pepper') + * .option('-p, --pizza-type ', 'type of pizza') // required option-argument + * .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default + * .option('-t, --tip ', 'add tip to purchase cost', parseFloat) // custom parse function * ``` * * @returns `this` command for chaining @@ -729,9 +710,9 @@ export class CommanderError extends Error { option( usage: S, description?: string, defaultValue?: DefaultT): Command>; option( - usage: S, description: string, fn: (value: string, previous: T) => T): Command>; + usage: S, description: string, parseArg: (value: string, previous: T) => T): Command>; option( - usage: S, description: string, fn: (value: string, previous: T) => T, defaultValue?: T): Command>; + usage: S, description: string, parseArg: (value: string, previous: T) => T, defaultValue?: T): Command>; /** * Define a required option, which must have a value after parsing. This usually means @@ -744,9 +725,9 @@ export class CommanderError extends Error { requiredOption( usage: S, description?: string, defaultValue?: DefaultT): Command>; requiredOption( - usage: S, description: string, fn: (value: string, previous: T) => T): Command>; + usage: S, description: string, parseArg: (value: string, previous: T) => T): Command>; requiredOption( - usage: S, description: string, fn: (value: string, previous: T) => T, defaultValue?: D): Command>; + usage: S, description: string, parseArg: (value: string, previous: T) => T, defaultValue?: D): Command>; /** * Factory routine to create a new unattached option. @@ -920,7 +901,7 @@ export class CommanderError extends Error { description(str: string): this; /** @deprecated since v8, instead use .argument to add command argument with description */ - description(str: string, argsDescription: {[argName: string]: string}): this; + description(str: string, argsDescription: Record): this; /** * Get the description. */ @@ -1017,7 +998,7 @@ export class CommanderError extends Error { /** * Get the executable search directory. */ - executableDir(): string; + executableDir(): string | null; /** * Output help information for this command. diff --git a/package-lock.json b/package-lock.json index 167916f..17ba8d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,24 @@ { "name": "@commander-js/extra-typings", - "version": "11.0.0", + "version": "11.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@commander-js/extra-typings", - "version": "11.0.0", + "version": "11.1.0", "license": "MIT", "devDependencies": { "@types/jest": "^29.2.6", "@types/node": "^18.7.16", - "commander": "~11.0.0", + "commander": "~11.1.0", "jest": "^29.3.1", "ts-jest": "^29.0.5", "tsd": "^0.22.0", "typescript": "^4.7.4" }, "peerDependencies": { - "commander": "11.0.x" + "commander": "11.1.x" } }, "node_modules/@ampproject/remapping": { diff --git a/package.json b/package.json index 1709d84..97a8062 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@commander-js/extra-typings", - "version": "11.0.0", + "version": "11.1.0", "description": "Infer strong typings for commander options and action handlers", "main": "index.js", "scripts": { @@ -45,7 +45,7 @@ ] }, "peerDependencies": { - "commander": "11.0.x" + "commander": "11.1.x" }, "devDependencies": { "@types/jest": "^29.2.6", diff --git a/tests/commander.test-d.ts b/tests/commander.test-d.ts index 0fde6ec..c9f2e41 100644 --- a/tests/commander.test-d.ts +++ b/tests/commander.test-d.ts @@ -40,7 +40,7 @@ expectType(commander.createArgument('')); expectType(program.args); // eslint-disable-next-line @typescript-eslint/no-explicit-any expectType<[]>(program.processedArgs); -expectType(program.commands); +expectType(program.commands); expectType(program.options); expectType(program.registeredArguments); expectType(program.parent); @@ -49,6 +49,7 @@ expectType(program.parent); expectChainedCommand(program.version('1.2.3')); expectChainedCommand(program.version('1.2.3', '-r,--revision')); expectChainedCommand(program.version('1.2.3', '-r,--revision', 'show revision information')); +expectType(program.version()); // command (and CommandOptions) expectChainedCommand(program.command('action')); @@ -294,7 +295,7 @@ expectChainedCommand(program.nameFromFilename(__filename)); // executableDir expectChainedCommand(program.executableDir(__dirname)); -expectType(program.executableDir()); +expectType(program.executableDir()); // outputHelp // eslint-disable-next-line @typescript-eslint/no-invalid-void-type @@ -416,9 +417,26 @@ expectType(helper.wrap('a b c', 50, 3)); expectType(helper.formatHelp(helperCommand, helper)); -// Option methods +// Option properties const baseOption = new commander.Option('-f,--foo', 'foo description'); +expectType(baseOption.flags); +expectType(baseOption.description); +expectType(baseOption.required); +expectType(baseOption.optional); +expectType(baseOption.variadic); +expectType(baseOption.mandatory); +expectType(baseOption.short); +expectType(baseOption.long); +expectType(baseOption.negate); +expectType(baseOption.defaultValue); +expectType(baseOption.defaultValueDescription); +expectType(baseOption.presetArg); +expectType(baseOption.envVar); +expectType(baseOption.hidden); +expectType(baseOption.argChoices); + +// Option methods // default expectType(baseOption.default(3)); @@ -472,6 +490,9 @@ const baseArgument = new commander.Argument('(baseArgument.description); expectType(baseArgument.required); expectType(baseArgument.variadic); +expectType(baseArgument.defaultValue); +expectType(baseArgument.defaultValueDescription); +expectType(baseArgument.argChoices); // Argument methods