maoda-commander-tt 0.0.28 → 0.0.30
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.
- package/README.md +9 -8
- package/dist/{chunk-2WEWI76D.js → chunk-S2SVYY3T.js} +23 -22
- package/dist/chunk-S2SVYY3T.js.map +1 -0
- package/dist/index.d.ts +12 -11
- package/dist/index.js +1 -1
- package/dist/main.js +2507 -1194
- package/dist/main.js.map +1 -1
- package/package.json +6 -5
- package/dist/chunk-2WEWI76D.js.map +0 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- **面向对象架构** — 所有命令继承 `BaseCommand<TOptions>`,统一生命周期管理
|
|
8
8
|
- **Disposable 体系** — 继承自 rockbed `Disposable` 基类,自动管理资源释放
|
|
9
9
|
- **事件系统** — 基于 rockbed `Emitter` 提供 `onBeforeExecute` / `onAfterExecute` 等生命周期钩子
|
|
10
|
-
- **结构化错误处理** — 使用 `
|
|
10
|
+
- **结构化错误处理** — 使用 `Result<T>` 代替 throw/reject,错误码可追溯
|
|
11
11
|
- **TypeScript 严格模式** — 全量 strict,类型安全
|
|
12
12
|
- **开发热调试** — 基于 tsx 直接运行 TS,支持 `--inspect` 调试
|
|
13
13
|
|
|
@@ -65,7 +65,7 @@ import type { Command } from 'commander';
|
|
|
65
65
|
import { BaseCommand } from '../core/base-command.js';
|
|
66
66
|
import type { ICommandActionContext } from '../core/base-command.js';
|
|
67
67
|
import type { ICommandMeta } from '../core/command-types.js';
|
|
68
|
-
import type {
|
|
68
|
+
import type { Result } from 'rockbed/error';
|
|
69
69
|
|
|
70
70
|
interface IMyOptions {
|
|
71
71
|
verbose: boolean;
|
|
@@ -88,7 +88,7 @@ export class MyCommand extends BaseCommand<IMyOptions> {
|
|
|
88
88
|
cmd.option('--verbose', '详细输出', false);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
protected async _execute(ctx: ICommandActionContext<IMyOptions>): Promise<
|
|
91
|
+
protected async _execute(ctx: ICommandActionContext<IMyOptions>): Promise<Result<void>> {
|
|
92
92
|
const target = ctx.args[0] as string;
|
|
93
93
|
|
|
94
94
|
if (ctx.options.verbose) {
|
|
@@ -122,7 +122,7 @@ app.registerCommand(new MyCommand());
|
|
|
122
122
|
| 方法 | 说明 |
|
|
123
123
|
|---|---|
|
|
124
124
|
| `_meta()` | 返回命令名、描述、别名 |
|
|
125
|
-
| `_execute(ctx)` | 命令核心逻辑,返回 `
|
|
125
|
+
| `_execute(ctx)` | 命令核心逻辑,返回 `Result<void>` |
|
|
126
126
|
| `_configureOptions(cmd)` | (可选) 配置 commander 选项 |
|
|
127
127
|
| `_configureArguments(cmd)` | (可选) 配置 commander 参数 |
|
|
128
128
|
| `getExample()` | 根据已注册的参数和选项自动生成命令执行示例 |
|
|
@@ -140,7 +140,7 @@ cmd.onAfterExecute((result) => {
|
|
|
140
140
|
|
|
141
141
|
### 错误处理
|
|
142
142
|
|
|
143
|
-
使用 `
|
|
143
|
+
使用 `Result<T>` 而非 throw:
|
|
144
144
|
|
|
145
145
|
```typescript
|
|
146
146
|
// 成功
|
|
@@ -149,9 +149,10 @@ return this._makeOk();
|
|
|
149
149
|
// 失败 (错误码 + 消息)
|
|
150
150
|
return this._makeError(1001, '文件不存在');
|
|
151
151
|
|
|
152
|
-
//
|
|
153
|
-
import {
|
|
154
|
-
|
|
152
|
+
// 也可定义可复用错误
|
|
153
|
+
import { defineError } from 'rockbed/error';
|
|
154
|
+
const missingNameError = defineError(1002, '参数 name 不能为空');
|
|
155
|
+
return missingNameError();
|
|
155
156
|
```
|
|
156
157
|
|
|
157
158
|
## Scripts
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { Disposable } from "rockbed/dispose";
|
|
4
4
|
import { Emitter } from "rockbed/event";
|
|
5
|
-
import {
|
|
5
|
+
import { ok, err } from "rockbed/error";
|
|
6
6
|
var CliApp = class extends Disposable {
|
|
7
7
|
constructor(_options) {
|
|
8
8
|
super();
|
|
@@ -37,14 +37,14 @@ var CliApp = class extends Disposable {
|
|
|
37
37
|
if (this._isDoubleHelp(args)) {
|
|
38
38
|
this.outputHelp(true);
|
|
39
39
|
this._onAfterRun.fire();
|
|
40
|
-
return
|
|
40
|
+
return ok();
|
|
41
41
|
}
|
|
42
42
|
await this._program.parseAsync(args);
|
|
43
43
|
this._onAfterRun.fire();
|
|
44
|
-
return
|
|
45
|
-
} catch (
|
|
46
|
-
const message =
|
|
47
|
-
return
|
|
44
|
+
return ok();
|
|
45
|
+
} catch (caughtError) {
|
|
46
|
+
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
|
47
|
+
return err(1, `CLI execution failed: ${message}`);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
dispose() {
|
|
@@ -84,7 +84,7 @@ var CliApp = class extends Disposable {
|
|
|
84
84
|
import { Command as Command2 } from "commander";
|
|
85
85
|
import { Disposable as Disposable2 } from "rockbed/dispose";
|
|
86
86
|
import { Emitter as Emitter2 } from "rockbed/event";
|
|
87
|
-
import {
|
|
87
|
+
import { ok as ok2, err as err2 } from "rockbed/error";
|
|
88
88
|
import { makeSuccessResponse, makeErrorResponse } from "rockbed/response";
|
|
89
89
|
|
|
90
90
|
// src/core/command-example.ts
|
|
@@ -190,9 +190,9 @@ var BaseCommand = class extends Disposable2 {
|
|
|
190
190
|
let result;
|
|
191
191
|
try {
|
|
192
192
|
result = await this._execute(ctx);
|
|
193
|
-
} catch (
|
|
194
|
-
const message =
|
|
195
|
-
result =
|
|
193
|
+
} catch (caughtError) {
|
|
194
|
+
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
|
195
|
+
result = err2(1, `Command "${meta.name}" failed: ${message}`);
|
|
196
196
|
}
|
|
197
197
|
this._onAfterExecute.fire(result);
|
|
198
198
|
if (!result.ok) {
|
|
@@ -216,10 +216,10 @@ var BaseCommand = class extends Disposable2 {
|
|
|
216
216
|
_configureArguments(_cmd) {
|
|
217
217
|
}
|
|
218
218
|
_makeOk() {
|
|
219
|
-
return
|
|
219
|
+
return ok2();
|
|
220
220
|
}
|
|
221
221
|
_makeError(code, msg) {
|
|
222
|
-
return
|
|
222
|
+
return err2(code, msg);
|
|
223
223
|
}
|
|
224
224
|
/**
|
|
225
225
|
* 向 stdout 输出一行文本(最终用户可见的输出)
|
|
@@ -262,11 +262,10 @@ var BaseCommand = class extends Disposable2 {
|
|
|
262
262
|
import { Command as Command3 } from "commander";
|
|
263
263
|
import { Disposable as Disposable3 } from "rockbed/dispose";
|
|
264
264
|
import { Emitter as Emitter3 } from "rockbed/event";
|
|
265
|
-
import {
|
|
265
|
+
import { ok as ok3, err as err3 } from "rockbed/error";
|
|
266
266
|
import { makeSuccessResponse as makeSuccessResponse2, makeErrorResponse as makeErrorResponse2 } from "rockbed/response";
|
|
267
267
|
var BaseSubcommandHost = class extends Disposable3 {
|
|
268
268
|
_command;
|
|
269
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
270
269
|
_subcommands = [];
|
|
271
270
|
_onBeforeExecute = this._register(new Emitter3());
|
|
272
271
|
_onAfterExecute = this._register(
|
|
@@ -283,6 +282,7 @@ var BaseSubcommandHost = class extends Disposable3 {
|
|
|
283
282
|
this._command.aliases(meta.aliases);
|
|
284
283
|
}
|
|
285
284
|
this._configureOptions(this._command);
|
|
285
|
+
this._configureArguments(this._command);
|
|
286
286
|
this._registerSubcommands();
|
|
287
287
|
this._command.action(async (...rawArgs) => {
|
|
288
288
|
const ctx = this._parseActionArgs(rawArgs);
|
|
@@ -290,9 +290,9 @@ var BaseSubcommandHost = class extends Disposable3 {
|
|
|
290
290
|
let result;
|
|
291
291
|
try {
|
|
292
292
|
result = await this._executeFallback(ctx);
|
|
293
|
-
} catch (
|
|
294
|
-
const message =
|
|
295
|
-
result =
|
|
293
|
+
} catch (caughtError) {
|
|
294
|
+
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
|
295
|
+
result = err3(1, `Command "${meta.name}" failed: ${message}`);
|
|
296
296
|
}
|
|
297
297
|
this._onAfterExecute.fire(result);
|
|
298
298
|
if (!result.ok) {
|
|
@@ -317,21 +317,22 @@ var BaseSubcommandHost = class extends Disposable3 {
|
|
|
317
317
|
*/
|
|
318
318
|
_executeFallback(_ctx) {
|
|
319
319
|
this._command.outputHelp();
|
|
320
|
-
return Promise.resolve(
|
|
320
|
+
return Promise.resolve(ok3());
|
|
321
321
|
}
|
|
322
322
|
_configureOptions(_cmd) {
|
|
323
323
|
}
|
|
324
|
-
|
|
324
|
+
_configureArguments(_cmd) {
|
|
325
|
+
}
|
|
325
326
|
_addSubcommand(cmd) {
|
|
326
327
|
this._subcommands.push(cmd);
|
|
327
328
|
this._register(cmd);
|
|
328
329
|
this._command.addCommand(cmd.command);
|
|
329
330
|
}
|
|
330
331
|
_makeOk() {
|
|
331
|
-
return
|
|
332
|
+
return ok3();
|
|
332
333
|
}
|
|
333
334
|
_makeError(code, msg) {
|
|
334
|
-
return
|
|
335
|
+
return err3(code, msg);
|
|
335
336
|
}
|
|
336
337
|
_output(text) {
|
|
337
338
|
process.stdout.write(text + "\n");
|
|
@@ -363,4 +364,4 @@ export {
|
|
|
363
364
|
BaseCommand,
|
|
364
365
|
BaseSubcommandHost
|
|
365
366
|
};
|
|
366
|
-
//# sourceMappingURL=chunk-
|
|
367
|
+
//# sourceMappingURL=chunk-S2SVYY3T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/cli-app.ts","../src/core/base-command.ts","../src/core/command-example.ts","../src/core/base-subcommand-host.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { Disposable } from 'rockbed/dispose';\nimport { Emitter } from 'rockbed/event';\nimport type { Event } from 'rockbed/event';\nimport type { Result } from 'rockbed/error';\nimport { ok, err } from 'rockbed/error';\nimport type { IRegistrableCommand } from './command-types';\n\nexport interface IRegisterCommandOptions {\n readonly hidden?: boolean;\n}\n\ninterface IRegisteredCommand {\n readonly command: IRegistrableCommand;\n readonly hidden: boolean;\n}\n\nexport interface ICliAppOptions {\n readonly name: string;\n readonly version: string;\n readonly description: string;\n}\n\nexport class CliApp extends Disposable {\n private readonly _program: Command;\n private readonly _commands: IRegisteredCommand[] = [];\n\n private readonly _onBeforeRun = this._register(new Emitter<[string[]]>());\n private readonly _onAfterRun = this._register(new Emitter<[]>());\n\n public readonly onBeforeRun: Event<[string[]]> = this._onBeforeRun.event;\n public readonly onAfterRun: Event<[]> = this._onAfterRun.event;\n\n constructor(private readonly _options: ICliAppOptions) {\n super();\n this._program = new Command();\n this._program\n .name(_options.name)\n .version(_options.version, '-v, --version', '输出版本号')\n .description(_options.description)\n .helpOption('-h, --help', '显示帮助信息')\n .addHelpCommand('help [command]', '显示指定命令的帮助信息');\n }\n\n public get program(): Command {\n return this._program;\n }\n\n public registerCommand(\n cmd: IRegistrableCommand,\n options: IRegisterCommandOptions = {},\n ): void {\n this._commands.push({\n command: cmd,\n hidden: options.hidden ?? false,\n });\n this._register(cmd);\n this._program.addCommand(\n cmd.command,\n options.hidden ? { hidden: true } : undefined,\n );\n }\n\n public async run(argv?: string[]): Promise<Result<void>> {\n const args = argv ?? process.argv;\n this._onBeforeRun.fire(args);\n\n try {\n if (this._isDoubleHelp(args)) {\n this.outputHelp(true);\n this._onAfterRun.fire();\n return ok();\n }\n\n await this._program.parseAsync(args);\n this._onAfterRun.fire();\n return ok();\n } catch (caughtError) {\n const message =\n caughtError instanceof Error ? caughtError.message : String(caughtError);\n return err(1, `CLI execution failed: ${message}`);\n }\n }\n\n public override dispose(): void {\n this._commands.length = 0;\n super.dispose();\n }\n\n public outputHelp(includeHidden = false): void {\n process.stdout.write(this.helpInformation(includeHidden));\n }\n\n public helpInformation(includeHidden = false): string {\n if (!includeHidden) {\n return this._program.helpInformation();\n }\n\n const hiddenCommands = this._commands\n .filter((entry) => entry.hidden)\n .map((entry) => entry.command.command);\n const previousHiddenStates = hiddenCommands.map((command) => {\n const rawCommand = command as unknown as { _hidden?: boolean };\n const previousHidden = rawCommand._hidden;\n rawCommand._hidden = false;\n return previousHidden;\n });\n\n try {\n return this._program.helpInformation();\n } finally {\n hiddenCommands.forEach((command, index) => {\n const rawCommand = command as unknown as { _hidden?: boolean };\n rawCommand._hidden = previousHiddenStates[index];\n });\n }\n }\n\n private _isDoubleHelp(argv: string[]): boolean {\n const userArgs = argv.slice(2);\n return userArgs.length > 0 && userArgs[0] === '-hh';\n }\n}\n","import { Command } from \"commander\";\nimport { Disposable } from 'rockbed/dispose';\nimport { Emitter } from 'rockbed/event';\nimport type { Event } from 'rockbed/event';\nimport type { Result } from 'rockbed/error';\nimport { ok, err } from 'rockbed/error';\nimport { makeSuccessResponse, makeErrorResponse } from 'rockbed/response';\nimport { makeCommandExample } from \"./command-example\";\nimport type { ICommandMeta } from \"./command-types\";\n\nexport interface ICommandActionContext<TOptions = Record<string, unknown>> {\n readonly args: unknown[];\n readonly options: TOptions;\n readonly command: Command;\n}\n\nexport abstract class BaseCommand<\n TOptions = Record<string, unknown>,\n> extends Disposable {\n private readonly _command: Command;\n private readonly _onBeforeExecute = this._register(new Emitter<[]>());\n private readonly _onAfterExecute = this._register(\n new Emitter<[Result<void>]>(),\n );\n\n public readonly onBeforeExecute: Event<[]> = this._onBeforeExecute.event;\n public readonly onAfterExecute: Event<[Result<void>]> =\n this._onAfterExecute.event;\n\n constructor() {\n super();\n const meta = this._meta();\n this._command = new Command(meta.name);\n this._command.description(meta.description);\n\n if (meta.aliases) {\n this._command.aliases(meta.aliases);\n }\n\n this._configureOptions(this._command);\n this._configureArguments(this._command);\n this._command.addHelpText(\"after\", () => {\n return `\\n执行案例:\\n ${this.getExample()}\\n`;\n });\n\n this._command.action(async (...rawArgs: unknown[]) => {\n const ctx = this._parseActionArgs(rawArgs);\n this._onBeforeExecute.fire();\n\n let result: Result<void>;\n try {\n result = await this._execute(ctx);\n } catch (caughtError) {\n const message = caughtError instanceof Error ? caughtError.message : String(caughtError);\n result = err(1, `Command \"${meta.name}\" failed: ${message}`);\n }\n this._onAfterExecute.fire(result);\n\n if (!result.ok) {\n process.stderr.write(`Error [${result.code}]: ${result.msg}\\n`);\n process.exitCode = 1;\n }\n });\n }\n\n public get command(): Command {\n return this._command;\n }\n\n /**\n * 返回该命令的执行示例,供外部展示或调试使用。\n */\n public getExample(): string {\n return makeCommandExample(this._command);\n }\n\n protected abstract _meta(): ICommandMeta;\n\n protected abstract _execute(\n ctx: ICommandActionContext<TOptions>,\n ): Promise<Result<void>>;\n\n protected _configureOptions(_cmd: Command): void {}\n\n protected _configureArguments(_cmd: Command): void {}\n\n protected _makeOk(): Result<void> {\n return ok();\n }\n\n protected _makeError(code: number, msg: string): Result<void> {\n return err(code, msg);\n }\n\n /**\n * 向 stdout 输出一行文本(最终用户可见的输出)\n */\n protected _output(text: string): void {\n process.stdout.write(text + \"\\n\");\n }\n\n /**\n * 向 stderr 输出调试 / 诊断信息(不会混入最终输出)\n */\n protected _debug(text: string): void {\n process.stderr.write(`[debug] ${text}\\n`);\n }\n\n /**\n * 以 JSON 字符串形式输出成功结果到 stdout\n */\n protected _outputJsonOk<T>(data: T): void {\n process.stdout.write(\n JSON.stringify(makeSuccessResponse(data), null, 2) + \"\\n\",\n );\n }\n\n /**\n * 以 JSON 字符串形式输出错误结果到 stdout\n */\n protected _outputJsonError(code: number, msg: string): void {\n process.stdout.write(\n JSON.stringify(makeErrorResponse(code, msg), null, 2) + \"\\n\",\n );\n }\n\n private _parseActionArgs(\n rawArgs: unknown[],\n ): ICommandActionContext<TOptions> {\n const command = rawArgs[rawArgs.length - 1] as Command;\n const options = rawArgs[rawArgs.length - 2] as TOptions;\n const args = rawArgs.slice(0, rawArgs.length - 2);\n return { args, options, command };\n }\n}\n","import type { Argument, Command, Option } from \"commander\";\n\nfunction _getCommandPath(command: Command): string[] {\n const names: string[] = [];\n for (let current: Command | null = command; current; current = current.parent) {\n names.unshift(current.name());\n }\n return names;\n}\n\nfunction _getRepresentativeValue(\n name: string,\n defaultValue: unknown,\n choices: readonly string[] | undefined,\n): string {\n if (defaultValue !== undefined) {\n return String(defaultValue);\n }\n\n if (choices && choices.length > 0) {\n return choices[0];\n }\n\n return name;\n}\n\nfunction _formatArgument(argument: Argument): string {\n const name = argument.name();\n const token = _getRepresentativeValue(name, argument.defaultValue, argument.argChoices);\n const hasConcreteValue =\n argument.defaultValue !== undefined ||\n (argument.argChoices !== undefined && argument.argChoices.length > 0);\n\n if (hasConcreteValue) {\n return argument.variadic ? `${token}...` : token;\n }\n\n if (argument.required) {\n return `<${argument.variadic ? `${token}...` : token}>`;\n }\n\n return `[${argument.variadic ? `${token}...` : token}]`;\n}\n\nfunction _getOptionFlag(option: Option): string {\n return option.short ?? option.long ?? option.flags.split(\",\")[0].trim();\n}\n\nfunction _isNegatedBooleanOption(option: Option): boolean {\n return option.flags\n .split(\",\")\n .map((flag) => flag.trim())\n .some((flag) => flag.startsWith(\"--no-\") && !flag.includes(\"<\") && !flag.includes(\"[\"));\n}\n\nfunction _isHiddenHelpOption(option: Option): boolean {\n return option.hidden || option.flags.includes(\"--help\");\n}\n\nfunction _formatOption(option: Option): string | null {\n if (_isHiddenHelpOption(option)) {\n return null;\n }\n\n const flag = _getOptionFlag(option);\n if (option.isBoolean() || _isNegatedBooleanOption(option)) {\n if (!option.mandatory && option.defaultValue === false) {\n return null;\n }\n\n return flag;\n }\n\n const value = _getRepresentativeValue(\n option.attributeName(),\n option.defaultValue,\n option.argChoices,\n );\n const hasConcreteValue =\n option.defaultValue !== undefined ||\n (option.argChoices !== undefined && option.argChoices.length > 0);\n\n if (!option.mandatory && option.defaultValue !== undefined) {\n return null;\n }\n\n if (hasConcreteValue) {\n return `${flag} ${value}`;\n }\n\n return `${flag} ${option.required ? value : `[${value}]`}`;\n}\n\n/**\n * 根据命令本身的注册配置生成一条执行示例。\n */\nexport function makeCommandExample(command: Command): string {\n const parts = _getCommandPath(command);\n const optionParts = command.options\n .map((option) => _formatOption(option))\n .filter((part): part is string => part !== null);\n const argumentParts = command.registeredArguments.map((argument) =>\n _formatArgument(argument),\n );\n\n return [...parts, ...optionParts, ...argumentParts].join(\" \").replace(/\\s+/g, \" \").trim();\n}\n","import { Command } from \"commander\";\nimport { Disposable } from 'rockbed/dispose';\nimport { Emitter } from 'rockbed/event';\nimport type { Event } from 'rockbed/event';\nimport type { Result } from 'rockbed/error';\nimport { ok, err } from 'rockbed/error';\nimport { makeSuccessResponse, makeErrorResponse } from 'rockbed/response';\nimport { makeCommandExample } from \"./command-example\";\nimport type { ICommandMeta } from \"./command-types\";\nimport type { ICommandActionContext } from \"./base-command\";\nimport type { IRegistrableCommand } from \"./command-types\";\n\n/**\n * 带子命令的命令宿主基类。\n *\n * 用于 `mycli hello greet` / `mycli hello info` 这类场景:\n * - hello 本身是一个 command group(SubcommandHost)\n * - greet / info 是它下面注册的子命令(BaseCommand)\n *\n * 也支持宿主自身直接处理(不带子命令时)的 fallback 逻辑。\n */\nexport abstract class BaseSubcommandHost extends Disposable {\n private readonly _command: Command;\n private readonly _subcommands: IRegistrableCommand[] = [];\n\n private readonly _onBeforeExecute = this._register(new Emitter<[]>());\n private readonly _onAfterExecute = this._register(\n new Emitter<[Result<void>]>(),\n );\n\n public readonly onBeforeExecute: Event<[]> = this._onBeforeExecute.event;\n public readonly onAfterExecute: Event<[Result<void>]> =\n this._onAfterExecute.event;\n\n constructor() {\n super();\n const meta = this._meta();\n this._command = new Command(meta.name);\n this._command.description(meta.description);\n\n if (meta.aliases) {\n this._command.aliases(meta.aliases);\n }\n\n this._configureOptions(this._command);\n this._configureArguments(this._command);\n this._registerSubcommands();\n // 仅在子命令场景,展示执行案例\n // this._command.addHelpText('after', () => {\n // return `\\n执行案例:\\n ${this.getExample()}\\n`;\n // });\n\n this._command.action(async (...rawArgs: unknown[]) => {\n const ctx = this._parseActionArgs(rawArgs);\n this._onBeforeExecute.fire();\n\n let result: Result<void>;\n try {\n result = await this._executeFallback(ctx);\n } catch (caughtError) {\n const message =\n caughtError instanceof Error ? caughtError.message : String(caughtError);\n result = err(1, `Command \"${meta.name}\" failed: ${message}`);\n }\n this._onAfterExecute.fire(result);\n\n if (!result.ok) {\n process.stderr.write(`Error [${result.code}]: ${result.msg}\\n`);\n process.exitCode = 1;\n }\n });\n }\n\n public get command(): Command {\n return this._command;\n }\n\n /**\n * 返回该命令宿主的执行示例,供外部展示或调试使用。\n */\n public getExample(): string {\n return makeCommandExample(this._command);\n }\n\n protected abstract _meta(): ICommandMeta;\n\n /**\n * 子类在此方法中调用 _addSubcommand 注册子命令\n */\n protected abstract _registerSubcommands(): void;\n\n /**\n * 当用户没有指定子命令时的默认行为。\n * 默认显示帮助信息,子类可覆盖。\n */\n protected _executeFallback(\n _ctx: ICommandActionContext,\n ): Promise<Result<void>> {\n this._command.outputHelp();\n return Promise.resolve(ok());\n }\n\n protected _configureOptions(_cmd: Command): void {}\n\n protected _configureArguments(_cmd: Command): void {}\n\n protected _addSubcommand(cmd: IRegistrableCommand): void {\n this._subcommands.push(cmd);\n this._register(cmd);\n this._command.addCommand(cmd.command);\n }\n\n protected _makeOk(): Result<void> {\n return ok();\n }\n\n protected _makeError(code: number, msg: string): Result<void> {\n return err(code, msg);\n }\n\n protected _output(text: string): void {\n process.stdout.write(text + \"\\n\");\n }\n\n protected _debug(text: string): void {\n process.stderr.write(`[debug] ${text}\\n`);\n }\n\n protected _outputJsonOk<T>(data: T): void {\n process.stdout.write(JSON.stringify(makeSuccessResponse(data)) + \"\\n\");\n }\n\n protected _outputJsonError(code: number, msg: string): void {\n process.stdout.write(JSON.stringify(makeErrorResponse(code, msg)) + \"\\n\");\n }\n\n public override dispose(): void {\n this._subcommands.length = 0;\n super.dispose();\n }\n\n private _parseActionArgs(rawArgs: unknown[]): ICommandActionContext {\n const command = rawArgs[rawArgs.length - 1] as Command;\n const options = rawArgs[rawArgs.length - 2] as Record<string, unknown>;\n const args = rawArgs.slice(0, rawArgs.length - 2);\n return { args, options, command };\n }\n}\n"],"mappings":"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","names":["Command","Disposable","Emitter","ok","err","Disposable","Emitter","Command","err","ok","Command","Disposable","Emitter","ok","err","makeSuccessResponse","makeErrorResponse","Disposable","Emitter","Command","err","ok","makeSuccessResponse","makeErrorResponse"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { IDisposable, Disposable } from 'rockbed/dispose';
|
|
3
3
|
import { Event } from 'rockbed/event';
|
|
4
|
-
import {
|
|
4
|
+
import { Result } from 'rockbed/error';
|
|
5
5
|
|
|
6
6
|
interface ICommandMeta {
|
|
7
7
|
readonly name: string;
|
|
@@ -35,7 +35,7 @@ declare class CliApp extends Disposable {
|
|
|
35
35
|
constructor(_options: ICliAppOptions);
|
|
36
36
|
get program(): Command;
|
|
37
37
|
registerCommand(cmd: IRegistrableCommand, options?: IRegisterCommandOptions): void;
|
|
38
|
-
run(argv?: string[]): Promise<
|
|
38
|
+
run(argv?: string[]): Promise<Result<void>>;
|
|
39
39
|
dispose(): void;
|
|
40
40
|
outputHelp(includeHidden?: boolean): void;
|
|
41
41
|
helpInformation(includeHidden?: boolean): string;
|
|
@@ -52,7 +52,7 @@ declare abstract class BaseCommand<TOptions = Record<string, unknown>> extends D
|
|
|
52
52
|
private readonly _onBeforeExecute;
|
|
53
53
|
private readonly _onAfterExecute;
|
|
54
54
|
readonly onBeforeExecute: Event<[]>;
|
|
55
|
-
readonly onAfterExecute: Event<[
|
|
55
|
+
readonly onAfterExecute: Event<[Result<void>]>;
|
|
56
56
|
constructor();
|
|
57
57
|
get command(): Command;
|
|
58
58
|
/**
|
|
@@ -60,11 +60,11 @@ declare abstract class BaseCommand<TOptions = Record<string, unknown>> extends D
|
|
|
60
60
|
*/
|
|
61
61
|
getExample(): string;
|
|
62
62
|
protected abstract _meta(): ICommandMeta;
|
|
63
|
-
protected abstract _execute(ctx: ICommandActionContext<TOptions>): Promise<
|
|
63
|
+
protected abstract _execute(ctx: ICommandActionContext<TOptions>): Promise<Result<void>>;
|
|
64
64
|
protected _configureOptions(_cmd: Command): void;
|
|
65
65
|
protected _configureArguments(_cmd: Command): void;
|
|
66
|
-
protected _makeOk():
|
|
67
|
-
protected _makeError(code: number, msg: string):
|
|
66
|
+
protected _makeOk(): Result<void>;
|
|
67
|
+
protected _makeError(code: number, msg: string): Result<void>;
|
|
68
68
|
/**
|
|
69
69
|
* 向 stdout 输出一行文本(最终用户可见的输出)
|
|
70
70
|
*/
|
|
@@ -99,7 +99,7 @@ declare abstract class BaseSubcommandHost extends Disposable {
|
|
|
99
99
|
private readonly _onBeforeExecute;
|
|
100
100
|
private readonly _onAfterExecute;
|
|
101
101
|
readonly onBeforeExecute: Event<[]>;
|
|
102
|
-
readonly onAfterExecute: Event<[
|
|
102
|
+
readonly onAfterExecute: Event<[Result<void>]>;
|
|
103
103
|
constructor();
|
|
104
104
|
get command(): Command;
|
|
105
105
|
/**
|
|
@@ -115,11 +115,12 @@ declare abstract class BaseSubcommandHost extends Disposable {
|
|
|
115
115
|
* 当用户没有指定子命令时的默认行为。
|
|
116
116
|
* 默认显示帮助信息,子类可覆盖。
|
|
117
117
|
*/
|
|
118
|
-
protected _executeFallback(_ctx: ICommandActionContext): Promise<
|
|
118
|
+
protected _executeFallback(_ctx: ICommandActionContext): Promise<Result<void>>;
|
|
119
119
|
protected _configureOptions(_cmd: Command): void;
|
|
120
|
-
protected
|
|
121
|
-
protected
|
|
122
|
-
protected
|
|
120
|
+
protected _configureArguments(_cmd: Command): void;
|
|
121
|
+
protected _addSubcommand(cmd: IRegistrableCommand): void;
|
|
122
|
+
protected _makeOk(): Result<void>;
|
|
123
|
+
protected _makeError(code: number, msg: string): Result<void>;
|
|
123
124
|
protected _output(text: string): void;
|
|
124
125
|
protected _debug(text: string): void;
|
|
125
126
|
protected _outputJsonOk<T>(data: T): void;
|