@guanghechen/commander 1.0.12 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,137 +1,217 @@
1
- import { ICommandConfigurationOptions } from '@guanghechen/cli';
2
- export * from '@guanghechen/cli';
3
- import { Command as Command$1, OptionValues, CommandOptions } from 'commander';
4
- import { IReporter } from '@guanghechen/reporter.types';
5
-
6
1
  /**
7
- * Callback for handling the command
2
+ * Type definitions for @guanghechen/commander
8
3
  *
9
- * @param args command arguments
10
- * @param options command options
11
- * @param extra extra args (neither declared command arguments nor command options)
12
- * @param self current command
4
+ * @module @guanghechen/commander
5
+ */
6
+ /**
7
+ * Reporter interface for logging.
8
+ * Users should provide their own implementation.
13
9
  */
14
- type ICommandActionCallback<T extends ICommandConfigurationOptions> = (args: string[], options: T, extra: string[], self: Command) => void | Promise<void> | never;
15
- declare class Command extends Command$1 {
16
- protected _actionHandler: ((args: string[]) => void) | null | undefined;
17
- protected _optionValues: object;
18
- protected _storeOptionsAsProperties: boolean;
19
- protected _version: string | undefined;
20
- protected _versionOptionName: string | undefined;
21
- constructor();
22
- /**
23
- * Register callback `fn` for the command.
24
- *
25
- * @example
26
- * program
27
- * .command('serve')
28
- * .description('start service')
29
- * .action(function() {
30
- * // do work here
31
- * });
32
- *
33
- * @param {Function} fn
34
- * @return {Command} `this` command for chaining
35
- */
36
- action<T extends ICommandConfigurationOptions>(fn: ICommandActionCallback<T>): this;
37
- opts<T extends OptionValues>(): T;
10
+ interface IReporter {
11
+ debug(message: string, ...args: unknown[]): void;
12
+ info(message: string, ...args: unknown[]): void;
13
+ warn(message: string, ...args: unknown[]): void;
14
+ error(message: string, ...args: unknown[]): void;
38
15
  }
39
-
40
- type IMainCommandProcessor<O extends ICommandConfigurationOptions> = (options: O) => void | Promise<void>;
41
- type IMainCommandCreator<O extends ICommandConfigurationOptions> = (handle?: IMainCommandProcessor<O>) => Command;
42
- type IMainCommandMounter = (parentCommand: Command, opts?: CommandOptions) => void;
43
- type IMainCommandExecutor<V = void> = (args: string[]) => Promise<V>;
16
+ /** Supported option value types */
17
+ type IOptionType = 'boolean' | 'string' | 'number' | 'string[]' | 'number[]';
44
18
  /**
45
- * Create main command mounter
46
- *
47
- * @param create main command creator
48
- * @param handle main command processor
19
+ * Option definition.
20
+ * @template T - The type of the option value
49
21
  */
50
- declare function createMainCommandMounter<O extends ICommandConfigurationOptions>(create: IMainCommandCreator<O>, handle: IMainCommandProcessor<O>): IMainCommandMounter;
22
+ interface IOption<T = unknown> {
23
+ /** Long option (e.g., 'verbose' for --verbose), also used as merge key */
24
+ long: string;
25
+ /** Short option (single character, e.g., 'v' for -v) */
26
+ short?: string;
27
+ /** Value type, defaults to 'string' */
28
+ type?: IOptionType;
29
+ /** Description for help text */
30
+ description: string;
31
+ /** Whether this option is required (cannot be used with default or boolean type) */
32
+ required?: boolean;
33
+ /** Default value when not provided */
34
+ default?: T;
35
+ /** Allowed values for validation and completion */
36
+ choices?: T extends Array<infer U> ? U[] : T[];
37
+ /** Single value transformation (ignored when resolver is present) */
38
+ coerce?: (rawValue: string) => T extends Array<infer U> ? U : T;
39
+ /** Custom resolver that fully replaces builtin parsing (ignores type/coerce) */
40
+ resolver?: (argv: string[]) => {
41
+ value: T;
42
+ remaining: string[];
43
+ };
44
+ /** Callback after parsing, applies value to context */
45
+ apply?: (value: T, ctx: ICommandContext) => void;
46
+ }
47
+ /** Argument kind */
48
+ type IArgumentKind = 'required' | 'optional' | 'variadic';
49
+ /** Positional argument definition */
50
+ interface IArgument {
51
+ /** Argument name */
52
+ name: string;
53
+ /** Argument description */
54
+ description: string;
55
+ /** Argument kind: required / optional / variadic */
56
+ kind: IArgumentKind;
57
+ }
58
+ /** Command configuration */
59
+ interface ICommandConfig {
60
+ /** Command name (used for routing) */
61
+ name: string;
62
+ /** Command aliases */
63
+ aliases?: string[];
64
+ /** Command description */
65
+ description: string;
66
+ /** Version (only effective for root command) */
67
+ version?: string;
68
+ }
69
+ /** Forward declaration for Command class */
70
+ interface ICommand {
71
+ readonly name: string;
72
+ readonly aliases: string[];
73
+ readonly description: string;
74
+ readonly version: string | undefined;
75
+ readonly parent: ICommand | undefined;
76
+ readonly options: IOption[];
77
+ readonly arguments: IArgument[];
78
+ }
79
+ /** Execution context */
80
+ interface ICommandContext {
81
+ /** Current command node */
82
+ cmd: ICommand;
83
+ /** Environment variables passed in */
84
+ envs: Record<string, string | undefined>;
85
+ /** Reporter instance */
86
+ reporter: IReporter;
87
+ /** Original argv */
88
+ argv: string[];
89
+ }
90
+ /** Action parameters */
91
+ interface IActionParams {
92
+ /** Execution context */
93
+ ctx: ICommandContext;
94
+ /** Parsed options */
95
+ opts: Record<string, unknown>;
96
+ /** Parsed positional arguments */
97
+ args: string[];
98
+ }
99
+ /** Action handler function */
100
+ type IAction = (params: IActionParams) => void | Promise<void>;
101
+ /** run() method parameters */
102
+ interface IRunParams {
103
+ /** Command line arguments (usually process.argv.slice(2)) */
104
+ argv: string[];
105
+ /** Environment variables (usually process.env) */
106
+ envs: Record<string, string | undefined>;
107
+ /** Optional reporter for logging (defaults to console reporter) */
108
+ reporter?: IReporter;
109
+ }
110
+ /** parse() method result */
111
+ interface IParseResult {
112
+ /** Parsed options */
113
+ opts: Record<string, unknown>;
114
+ /** Parsed positional arguments */
115
+ args: string[];
116
+ }
117
+ /** Error kinds for command parsing */
118
+ type ICommanderErrorKind = 'UnknownOption' | 'MissingValue' | 'InvalidType' | 'UnsupportedShortSyntax' | 'OptionConflict' | 'MissingRequired' | 'InvalidChoice' | 'InvalidBooleanValue' | 'MissingRequiredArgument' | 'ConfigurationError';
119
+ /** Commander error with structured information */
120
+ declare class CommanderError extends Error {
121
+ readonly kind: ICommanderErrorKind;
122
+ readonly commandPath: string;
123
+ constructor(kind: ICommanderErrorKind, message: string, commandPath: string);
124
+ /** Format error with help hint */
125
+ format(): string;
126
+ }
127
+ /** Shell type for completion */
128
+ type IShellType = 'bash' | 'fish' | 'pwsh';
129
+ /** Option metadata for completion */
130
+ interface ICompletionOptionMeta {
131
+ long: string;
132
+ short?: string;
133
+ description: string;
134
+ takesValue: boolean;
135
+ choices?: string[];
136
+ }
137
+ /** Command metadata for completion */
138
+ interface ICompletionMeta {
139
+ name: string;
140
+ description: string;
141
+ aliases: string[];
142
+ options: ICompletionOptionMeta[];
143
+ subcommands: ICompletionMeta[];
144
+ }
145
+ /** CompletionCommand configuration */
146
+ interface ICompletionCommandConfig {
147
+ /** Subcommand name, defaults to 'completion' */
148
+ name?: string;
149
+ }
150
+
51
151
  /**
52
- * Create main command executor
152
+ * Command class - CLI command builder with fluent API
53
153
  *
54
- * @param create main command creator
55
- * @param handle main command processor
154
+ * @module @guanghechen/commander
56
155
  */
57
- declare function createMainCommandExecutor<O extends ICommandConfigurationOptions>(create: IMainCommandCreator<O>, handle: IMainCommandProcessor<O>): IMainCommandExecutor;
58
156
 
59
- interface ISubCommandOptions extends ICommandConfigurationOptions {
60
- }
61
- interface ISubCommandProcessor<O extends ISubCommandOptions> {
62
- /**
63
- * Process the command arguments and options.
64
- * @param args Command arguments.
65
- * @param options Command options.
66
- */
67
- process(args: string[], options: O): Promise<void>;
68
- }
69
- interface ISubCommand<O extends ISubCommandOptions> extends ISubCommandProcessor<O> {
70
- /**
71
- * Sub command name.
72
- */
73
- readonly subCommandName: string;
74
- /**
75
- * Sub command alias.
76
- */
77
- readonly aliases: string[];
78
- /**
79
- * Create an commander instance.
80
- * @param processor
81
- */
82
- command(processor: ISubCommandProcessor<O>): Command;
83
- /**
84
- * Create a sub-command instance and execute it immediately.
85
- * @param args Command arguments.
86
- * @param options Command options.
87
- */
88
- execute(parentCommand: Command, rawArgs: string[]): Promise<void>;
89
- /**
90
- * Create a sub-command instance and mount it to the parentCommand.
91
- * @param parentCommand
92
- * @param opts
93
- */
94
- mount(parentCommand: Command, opts: CommandOptions | undefined): void;
95
- /**
96
- * Process the command options and rawArgs.
97
- * @param args Command arguments.
98
- * @param options Command options.
99
- */
100
- process(args: string[], options: O): Promise<void>;
101
- /**
102
- * Resolve a processor for process the command.
103
- * @param args
104
- * @param options
105
- */
106
- resolveProcessor(args: string[], options: O): Promise<ISubCommandProcessor<O>>;
107
- }
108
- declare abstract class SubCommand<O extends ISubCommandOptions> implements ISubCommand<O> {
109
- abstract subCommandName: string;
110
- abstract aliases: string[];
111
- abstract command(processor: ISubCommandProcessor<O>): Command;
112
- mount(parentCommand: Command, opts: CommandOptions | undefined): void;
113
- execute(parentCommand: Command, rawArgs: string[]): Promise<void>;
114
- process(args: string[], options: O): Promise<void>;
115
- abstract resolveProcessor(args: string[], options: O): Promise<ISubCommandProcessor<O>>;
157
+ declare class Command {
158
+ #private;
159
+ constructor(config: ICommandConfig);
160
+ get name(): string;
161
+ get aliases(): string[];
162
+ get description(): string;
163
+ get version(): string | undefined;
164
+ get parent(): Command | undefined;
165
+ get options(): IOption[];
166
+ get arguments(): IArgument[];
167
+ option(opt: IOption): this;
168
+ argument(arg: IArgument): this;
169
+ action(fn: IAction): this;
170
+ subcommand(cmd: Command): this;
171
+ run(params: IRunParams): Promise<void>;
172
+ parse(argv: string[]): IParseResult;
173
+ formatHelp(): string;
174
+ getCompletionMeta(): ICompletionMeta;
116
175
  }
117
176
 
118
177
  /**
119
- * Create top command
120
- * @param commandName
121
- * @param version
178
+ * Shell completion generators
179
+ *
180
+ * @module @guanghechen/commander
122
181
  */
123
- declare function createTopCommand(commandName: string, version: string): Command;
124
182
 
125
- declare const hasGitInstalled: () => boolean;
126
- interface IInstallDependenciesParams {
127
- readonly cwd: string;
128
- readonly plopBypass: string[];
129
- readonly reporter?: IReporter;
130
- }
131
183
  /**
132
- * Run `npm/yarn install` to Install node.js dependencies
184
+ * Built-in completion command that generates shell completion scripts.
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * const root = new Command({ name: 'mycli', description: 'My CLI' })
189
+ * root.subcommand(new CompletionCommand(root))
190
+ *
191
+ * // Usage:
192
+ * // mycli completion --bash > ~/.local/share/bash-completion/completions/mycli
193
+ * // mycli completion --fish > ~/.config/fish/completions/mycli.fish
194
+ * // mycli completion --pwsh >> $PROFILE
195
+ * ```
133
196
  */
134
- declare function installDependencies(params: IInstallDependenciesParams): Promise<void>;
197
+ declare class CompletionCommand extends Command {
198
+ constructor(root: Command, config?: ICompletionCommandConfig);
199
+ }
200
+ declare class BashCompletion {
201
+ #private;
202
+ constructor(meta: ICompletionMeta, programName: string);
203
+ generate(): string;
204
+ }
205
+ declare class FishCompletion {
206
+ #private;
207
+ constructor(meta: ICompletionMeta, programName: string);
208
+ generate(): string;
209
+ }
210
+ declare class PwshCompletion {
211
+ #private;
212
+ constructor(meta: ICompletionMeta, programName: string);
213
+ generate(): string;
214
+ }
135
215
 
136
- export { Command, SubCommand, createMainCommandExecutor, createMainCommandMounter, createTopCommand, hasGitInstalled, installDependencies };
137
- export type { ICommandActionCallback, IInstallDependenciesParams, IMainCommandCreator, IMainCommandExecutor, IMainCommandMounter, IMainCommandProcessor, ISubCommand, ISubCommandOptions, ISubCommandProcessor };
216
+ export { BashCompletion, Command, CommanderError, CompletionCommand, FishCompletion, PwshCompletion };
217
+ export type { IAction, IActionParams, IArgument, IArgumentKind, ICommand, ICommandConfig, ICommandContext, ICommanderErrorKind, ICompletionCommandConfig, ICompletionMeta, ICompletionOptionMeta, IOption, IOptionType, IParseResult, IReporter, IRunParams, IShellType };
package/package.json CHANGED
@@ -1,27 +1,30 @@
1
1
  {
2
2
  "name": "@guanghechen/commander",
3
- "version": "1.0.12",
4
- "description": "A wrapper of commander.js with some utilities",
3
+ "version": "2.0.1",
4
+ "description": "A minimal, type-safe command-line interface builder with fluent API",
5
5
  "author": {
6
6
  "name": "guanghechen",
7
7
  "url": "https://github.com/guanghechen/"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "https://github.com/guanghechen/node-scaffolds/tree/@guanghechen/commander@1.0.11",
11
+ "url": "https://github.com/guanghechen/sora/tree/@guanghechen/commander@2.0.0",
12
12
  "directory": "packages/commander"
13
13
  },
14
- "homepage": "https://github.com/guanghechen/node-scaffolds/tree/@guanghechen/commander@1.0.11/packages/commander#readme",
14
+ "homepage": "https://github.com/guanghechen/sora/tree/@guanghechen/commander@2.0.0/packages/commander#readme",
15
15
  "keywords": [
16
- "commander"
16
+ "cli",
17
+ "command",
18
+ "commander",
19
+ "completion"
17
20
  ],
18
21
  "type": "module",
19
22
  "exports": {
20
23
  ".": {
24
+ "types": "./lib/types/index.d.ts",
21
25
  "source": "./src/index.ts",
22
26
  "import": "./lib/esm/index.mjs",
23
- "require": "./lib/cjs/index.cjs",
24
- "types": "./lib/types/index.d.ts"
27
+ "require": "./lib/cjs/index.cjs"
25
28
  }
26
29
  },
27
30
  "source": "./src/index.ts",
@@ -29,9 +32,6 @@
29
32
  "module": "./lib/esm/index.mjs",
30
33
  "types": "./lib/types/index.d.ts",
31
34
  "license": "MIT",
32
- "engines": {
33
- "node": ">= 20.0.0"
34
- },
35
35
  "files": [
36
36
  "lib/",
37
37
  "!lib/**/*.map",
@@ -40,12 +40,11 @@
40
40
  "LICENSE",
41
41
  "README.md"
42
42
  ],
43
- "dependencies": {
44
- "@guanghechen/cli": "^1.0.8",
45
- "@guanghechen/exec": "^1.0.9",
46
- "@guanghechen/reporter.types": "^1.0.5",
47
- "@inquirer/select": "4.3.2",
48
- "commander": "12.1.0"
49
- },
50
- "gitHead": "26026650aac329e6342b68d80111d82fd0213a20"
51
- }
43
+ "scripts": {
44
+ "build": "rollup -c ../../rollup.config.mjs",
45
+ "clean": "rimraf lib",
46
+ "test": "vitest run --config ../../vitest.config.ts",
47
+ "test:coverage": "vitest run --config ../../vitest.config.ts --coverage",
48
+ "test:update": "vitest run --config ../../vitest.config.ts -u"
49
+ }
50
+ }
package/CHANGELOG.md DELETED
@@ -1,115 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- ## <small>1.0.12 (2025-08-29)</small>
7
-
8
- * improve: refine READMEs ([c41c1f2](https://github.com/guanghechen/node-scaffolds/commit/c41c1f2))
9
- * :wrench: chore: upgrade dependencies & update the node requirement from ([8ddfde1](https://github.com/guanghechen/node-scaffolds/commit/8ddfde1))
10
-
11
-
12
-
13
-
14
-
15
- ## <small>1.0.11 (2025-07-04)</small>
16
-
17
- * :bookmark: release ([2313a96](https://github.com/guanghechen/node-scaffolds/commit/2313a96))
18
- * :bookmark: release ([fbef5fd](https://github.com/guanghechen/node-scaffolds/commit/fbef5fd))
19
- * :wrench: chore: upgrade dependencies ([8623304](https://github.com/guanghechen/node-scaffolds/commit/8623304))
20
- * chore: upgrade dependencies ([a5b7a87](https://github.com/guanghechen/node-scaffolds/commit/a5b7a87))
21
-
22
-
23
-
24
-
25
-
26
- ## <small>1.0.10 (2025-03-30)</small>
27
-
28
- * chore: upgrade dependencies ([a5b7a87](https://github.com/guanghechen/node-scaffolds/commit/a5b7a87))
29
-
30
-
31
-
32
-
33
-
34
- ## <small>1.0.9 (2025-02-26)</small>
35
-
36
- * :bookmark: release ([9d47297](https://github.com/guanghechen/node-scaffolds/commit/9d47297))
37
- * chore: sharp dependencies ([914ba6f](https://github.com/guanghechen/node-scaffolds/commit/914ba6f))
38
-
39
-
40
-
41
-
42
-
43
- ## <small>1.0.8 (2025-02-26)</small>
44
-
45
- * chore: sharp dependencies ([914ba6f](https://github.com/guanghechen/node-scaffolds/commit/914ba6f))
46
- * chore: upgrade devDependencies ([ca5de6d](https://github.com/guanghechen/node-scaffolds/commit/ca5de6d))
47
- * :bookmark: release ([6fe5681](https://github.com/guanghechen/node-scaffolds/commit/6fe5681))
48
-
49
-
50
-
51
-
52
-
53
- ## <small>1.0.7 (2025-02-07)</small>
54
-
55
- * chore: upgrade devDependencies ([ca5de6d](https://github.com/guanghechen/node-scaffolds/commit/ca5de6d))
56
- * :arrow_up: chore: upgrade dependencies & no longer rely on globby since it breaking build ([b5d0fdd](https://github.com/guanghechen/node-scaffolds/commit/b5d0fdd))
57
- * :bookmark: release ([6524942](https://github.com/guanghechen/node-scaffolds/commit/6524942))
58
-
59
-
60
-
61
-
62
-
63
- ## <small>1.0.6 (2025-01-09)</small>
64
-
65
- * :arrow_up: chore: upgrade dependencies & no longer rely on globby since it breaking build ([b5d0fdd](https://github.com/guanghechen/node-scaffolds/commit/b5d0fdd))
66
-
67
-
68
-
69
-
70
-
71
- ## <small>1.0.5 (2024-10-03)</small>
72
-
73
- * :arrow_up: chore: upgrade dependencies ([ba63623](https://github.com/guanghechen/node-scaffolds/commit/ba63623))
74
-
75
-
76
-
77
-
78
-
79
- ## <small>1.0.4 (2024-10-03)</small>
80
-
81
- * :arrow_up: chore: upgrade dependencies ([e41de75](https://github.com/guanghechen/node-scaffolds/commit/e41de75))
82
- * :wrench: chore: don't gen sourcemap in production env ([f7075d1](https://github.com/guanghechen/node-scaffolds/commit/f7075d1))
83
-
84
-
85
-
86
-
87
-
88
- ## <small>1.0.3 (2024-09-29)</small>
89
-
90
- **Note:** Version bump only for package @guanghechen/commander
91
-
92
-
93
-
94
-
95
-
96
- ## <small>1.0.2 (2024-09-29)</small>
97
-
98
- * :art: improve(commander): remove unnecessary third-party dependencies ([d5cb553](https://github.com/guanghechen/node-scaffolds/commit/d5cb553))
99
-
100
-
101
-
102
-
103
-
104
- ## <small>1.0.1 (2024-09-28)</small>
105
-
106
- * :art: improve: reuse @guanghechen/cli ([6c8e6a0](https://github.com/guanghechen/node-scaffolds/commit/6c8e6a0))
107
- * :wrench: chore: fix publish issues ([7316526](https://github.com/guanghechen/node-scaffolds/commit/7316526))
108
-
109
-
110
-
111
-
112
-
113
- ## <small>1.0.1 (2024-09-28)</small>
114
-
115
- * :art: improve: reuse @guanghechen/cli ([6c8e6a0](https://github.com/guanghechen/node-scaffolds/commit/6c8e6a0))