@navios/commander 1.5.1 → 1.7.0
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/.turbo/turbo-build.log +48 -49
- package/.turbo/turbo-check.log +0 -2
- package/.turbo/turbo-lint.log +2 -3
- package/.turbo/turbo-test$colon$ci.log +109 -117
- package/.turbo/turbo-test.log +107 -0
- package/CHANGELOG.md +21 -0
- package/dist/src/interfaces/command-handler.interface.d.mts +7 -3
- package/dist/src/interfaces/command-handler.interface.d.mts.map +1 -1
- package/dist/src/interfaces/commander-execution-context.interface.d.mts +11 -1
- package/dist/src/interfaces/commander-execution-context.interface.d.mts.map +1 -1
- package/dist/src/services/cli-parser.service.d.mts +42 -0
- package/dist/src/services/cli-parser.service.d.mts.map +1 -1
- package/dist/src/services/command-registry.service.d.mts +5 -0
- package/dist/src/services/command-registry.service.d.mts.map +1 -1
- package/dist/src/services/commander-adapter.service.d.mts +5 -1
- package/dist/src/services/commander-adapter.service.d.mts.map +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/lib/{cli-module.decorator-BzsOEMPH.d.cts → cli-module.decorator-BV3vVKlR.d.cts} +8 -4
- package/lib/cli-module.decorator-BV3vVKlR.d.cts.map +1 -0
- package/lib/{cli-module.decorator-CCV_elPP.d.mts → cli-module.decorator-DDlgpTgI.d.mts} +19 -5
- package/lib/cli-module.decorator-DDlgpTgI.d.mts.map +1 -0
- package/lib/{help-command.token-XHx3WkoD.mjs → help-command.token-ChAUjOyV.mjs} +27 -2
- package/lib/help-command.token-ChAUjOyV.mjs.map +1 -0
- package/lib/{help-command.token-DamE31Aw.cjs → help-command.token-mlwEyWij.cjs} +27 -2
- package/lib/help-command.token-mlwEyWij.cjs.map +1 -0
- package/lib/{help.command-Bynoll_7.mjs → help.command-CzQymUFY.mjs} +2 -2
- package/lib/{help.command-Bynoll_7.mjs.map → help.command-CzQymUFY.mjs.map} +1 -1
- package/lib/{help.command-DvKmMpB7.cjs → help.command-knivRhJz.cjs} +2 -2
- package/lib/{help.command-DvKmMpB7.cjs.map → help.command-knivRhJz.cjs.map} +1 -1
- package/lib/index.cjs +127 -12
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +60 -3
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.mts +49 -2
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +127 -12
- package/lib/index.mjs.map +1 -1
- package/lib/legacy-compat/index.d.cts +1 -1
- package/lib/legacy-compat/index.d.mts +1 -1
- package/package.json +2 -2
- package/src/__tests__/commander.factory.e2e.spec.mts +105 -13
- package/src/interfaces/command-handler.interface.mts +7 -3
- package/src/interfaces/commander-execution-context.interface.mts +13 -0
- package/src/services/__tests__/cli-parser.service.spec.mts +294 -0
- package/src/services/cli-parser.service.mts +196 -31
- package/src/services/command-registry.service.mts +51 -0
- package/src/services/commander-adapter.service.mts +13 -4
- package/lib/cli-module.decorator-BzsOEMPH.d.cts.map +0 -1
- package/lib/cli-module.decorator-CCV_elPP.d.mts.map +0 -1
- package/lib/help-command.token-DamE31Aw.cjs.map +0 -1
- package/lib/help-command.token-XHx3WkoD.mjs.map +0 -1
|
@@ -24,20 +24,24 @@ import { z } from "zod/v4";
|
|
|
24
24
|
*
|
|
25
25
|
* @Command({ path: 'greet', optionsSchema })
|
|
26
26
|
* export class GreetCommand implements CommandHandler<Options> {
|
|
27
|
-
* async execute(options: Options) {
|
|
27
|
+
* async execute(options: Options, positionals?: string[]) {
|
|
28
28
|
* console.log(`Hello, ${options.name}!`)
|
|
29
|
+
* if (positionals?.length) {
|
|
30
|
+
* console.log(`Files: ${positionals.join(', ')}`)
|
|
31
|
+
* }
|
|
29
32
|
* }
|
|
30
33
|
* }
|
|
31
34
|
* ```
|
|
32
35
|
*/
|
|
33
36
|
interface CommandHandler<TOptions = any> {
|
|
34
37
|
/**
|
|
35
|
-
* Executes the command with the provided options.
|
|
38
|
+
* Executes the command with the provided options and positional arguments.
|
|
36
39
|
*
|
|
37
40
|
* @param options - The validated command options (validated against the command's schema if provided)
|
|
41
|
+
* @param positionals - Positional arguments that don't match any option flags
|
|
38
42
|
* @returns A promise or void
|
|
39
43
|
*/
|
|
40
|
-
execute(options: TOptions): void | Promise<void>;
|
|
44
|
+
execute(options: TOptions, positionals?: string[]): void | Promise<void>;
|
|
41
45
|
}
|
|
42
46
|
//#endregion
|
|
43
47
|
//#region src/decorators/command.decorator.d.mts
|
|
@@ -210,4 +214,4 @@ declare function CliModule({
|
|
|
210
214
|
}?: CliModuleOptions): (target: ClassType, context: ClassDecoratorContext<abstract new (...args: any) => any>) => ClassType;
|
|
211
215
|
//#endregion
|
|
212
216
|
export { CommandHandler as a, CommandOptions as i, CliModuleOptions as n, Command as r, CliModule as t };
|
|
213
|
-
//# sourceMappingURL=cli-module.decorator-
|
|
217
|
+
//# sourceMappingURL=cli-module.decorator-BV3vVKlR.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-module.decorator-BV3vVKlR.d.cts","names":["CommandHandler","TOptions","Promise","InjectionToken","ClassType","ClassTypeWithInstance","Registry","z","CommandHandler","CommandOptions","ZodObject","Command","path","description","token","optionsSchema","priority","registry","ClassDecoratorContext","ClassType","Registry","CliModuleOptions","Set","CliModule","commands","controllers","imports","guards","overrides","priority","registry","ClassDecoratorContext"],"sources":["../src/interfaces/command-handler.interface.d.mts","../src/decorators/command.decorator.d.mts","../src/decorators/cli-module.decorator.d.mts"],"sourcesContent":["/**\n * Interface that all command classes must implement.\n *\n * Commands decorated with `@Command` must implement this interface.\n * The `execute` method is called when the command is invoked.\n *\n * @template TOptions - The type of options that the command accepts\n *\n * @example\n * ```typescript\n * import { Command, CommandHandler } from '@navios/commander'\n * import { z } from 'zod/v4'\n *\n * const optionsSchema = z.object({\n * name: z.string()\n * })\n *\n * type Options = z.infer<typeof optionsSchema>\n *\n * @Command({ path: 'greet', optionsSchema })\n * export class GreetCommand implements CommandHandler<Options> {\n * async execute(options: Options, positionals?: string[]) {\n * console.log(`Hello, ${options.name}!`)\n * if (positionals?.length) {\n * console.log(`Files: ${positionals.join(', ')}`)\n * }\n * }\n * }\n * ```\n */\nexport interface CommandHandler<TOptions = any> {\n /**\n * Executes the command with the provided options and positional arguments.\n *\n * @param options - The validated command options (validated against the command's schema if provided)\n * @param positionals - Positional arguments that don't match any option flags\n * @returns A promise or void\n */\n execute(options: TOptions, positionals?: string[]): void | Promise<void>\n}\n//# sourceMappingURL=command-handler.interface.d.mts.map\n","import { InjectionToken } from '@navios/core'\n\nimport type { ClassType, ClassTypeWithInstance, Registry } from '@navios/core'\nimport type { z } from 'zod/v4'\n\nimport type { CommandHandler } from '../interfaces/index.mjs'\n/**\n * Options for the `@Command` decorator.\n *\n * @public\n */\nexport interface CommandOptions {\n /**\n * The token to use for the command.\n * If provided, the command will be registered with this token.\n */\n token?: InjectionToken<ClassTypeWithInstance<CommandHandler<any>>>\n /**\n * The command path that users will invoke from the CLI.\n * Can be a single word (e.g., 'greet') or multi-word with colons (e.g., 'user:create', 'db:migrate').\n */\n path: string\n /**\n * Optional description of the command for help text.\n * Displayed when users run `help` or `--help`.\n */\n description?: string\n /**\n * Optional zod/v4 schema for validating command options.\n * If provided, options will be validated and parsed according to this schema.\n */\n optionsSchema?: z.ZodObject\n /**\n * Priority level for the command.\n * Higher priority commands will be loaded first.\n */\n priority?: number\n /**\n * Registry to use for the command.\n * Registry is used to store the command and its options schema.\n */\n registry?: Registry\n}\n/**\n * Decorator that marks a class as a CLI command.\n *\n * The decorated class must implement the `CommandHandler` interface with an `execute` method.\n * The command will be automatically registered when its module is loaded.\n *\n * @param options - Configuration options for the command\n * @returns A class decorator function\n *\n * @example\n * ```typescript\n * import { Command, CommandHandler } from '@navios/commander'\n * import { z } from 'zod/v4'\n *\n * const optionsSchema = z.object({\n * name: z.string(),\n * greeting: z.string().optional().default('Hello')\n * })\n *\n * @Command({\n * path: 'greet',\n * optionsSchema: optionsSchema\n * })\n * export class GreetCommand implements CommandHandler<z.infer<typeof optionsSchema>> {\n * async execute(options) {\n * console.log(`${options.greeting}, ${options.name}!`)\n * }\n * }\n * ```\n */\nexport declare function Command({\n path,\n description,\n token,\n optionsSchema,\n priority,\n registry,\n}: CommandOptions): (\n target: ClassType,\n context: ClassDecoratorContext<abstract new (...args: any) => any>,\n) => any\n//# sourceMappingURL=command.decorator.d.mts.map\n","import type { ClassType, Registry } from '@navios/core'\n/**\n * Options for the `@CliModule` decorator.\n *\n * @public\n */\nexport interface CliModuleOptions {\n /**\n * Array or Set of command classes to register in this module.\n * Commands must be decorated with `@Command`.\n */\n commands?: ClassType[] | Set<ClassType>\n /**\n * Array or Set of controller classes for HTTP endpoints.\n * Allows mixing HTTP and CLI functionality in the same module.\n */\n controllers?: ClassType[] | Set<ClassType>\n /**\n * Array or Set of other modules to import.\n * Imported modules' commands and controllers will be available.\n */\n imports?: ClassType[] | Set<ClassType>\n /**\n * Guards to apply to all controllers in this module.\n * Guards are executed in reverse order (last guard first).\n */\n guards?: ClassType[] | Set<ClassType>\n /**\n * Service override classes to import for side effects.\n * These classes are imported to ensure their @Injectable decorators execute,\n * allowing them to register with the DI system. Overrides should use the same\n * InjectionToken as the original service with a higher priority.\n */\n overrides?: ClassType[] | Set<ClassType>\n /**\n * Priority level for the module.\n * Higher priority modules will be loaded first.\n */\n priority?: number\n /**\n * Registry to use for the module.\n * Registry is used to store the module and its commands.\n */\n registry?: Registry\n}\n/**\n * Decorator that marks a class as a CLI module.\n *\n * This decorator extends the standard @Module decorator, adding support for\n * CLI commands while maintaining full compatibility with HTTP controllers.\n * Modules organize commands and can import other modules to compose larger\n * CLI applications.\n *\n * The module can optionally implement `NaviosModule` interface for lifecycle hooks.\n *\n * @param options - Configuration options for the module\n * @returns A class decorator function\n *\n * @example\n * ```typescript\n * import { CliModule } from '@navios/commander'\n * import { GreetCommand } from './greet.command'\n * import { UserModule } from './user.module'\n *\n * @CliModule({\n * commands: [GreetCommand],\n * imports: [UserModule]\n * })\n * export class AppModule {}\n * ```\n *\n * @example\n * ```typescript\n * // Mixed HTTP and CLI module\n * @CliModule({\n * controllers: [HealthController],\n * commands: [MigrateCommand],\n * imports: [DatabaseModule],\n * })\n * export class AppModule {}\n * ```\n */\nexport declare function CliModule({\n commands,\n controllers,\n imports,\n guards,\n overrides,\n priority,\n registry,\n}?: CliModuleOptions): (\n target: ClassType,\n context: ClassDecoratorContext<abstract new (...args: any) => any>,\n) => ClassType\n//# sourceMappingURL=cli-module.decorator.d.mts.map\n"],"mappings":";;;;;;;;;AA8BA;;;;ACnBA;;;;;;;AA8DA;;;;;;;;;;;;;;ACnEA;AAKamB,UFmBInB,cEnBJmB,CAAAA,WAAAA,GAAAA,CAAAA,CAAAA;EAAkBA;;;;;;;EAULG,OAAAA,CAAAA,OAAAA,EFiBPrB,QEjBOqB,EAAAA,WAAAA,CAAAA,EAAAA,MAAAA,EAAAA,CAAAA,EAAAA,IAAAA,GFiBmCpB,OEjBnCoB,CAAAA,IAAAA,CAAAA;;;;;;ADV1B;;;AAKUnB,UALOM,cAAAA,CAKPN;EAeQI;;;AA0ClB;EACEK,KAAAA,CAAAA,EA1DQT,cA0DRS,CA1DuBP,qBA0DvBO,CA1D6CJ,cA0D7CI,CAAAA,GAAAA,CAAAA,CAAAA,CAAAA;EACAC;;;;EAIAI,IAAAA,EAAAA,MAAAA;EACCR;;;;;;;AC1EH;;EAK+BU,aAAAA,CAAAA,EDoBbZ,CAAAA,CAAEG,SCpBWS;EAAJG;;;;EAUfH,QAAAA,CAAAA,EAAAA,MAAAA;EAAkBA;;;;EAKLG,QAAAA,CAAAA,EDeZhB,QCfYgB;;;;;;AAwDzB;;;;;;;;;;;;;;;;;;;;;;;;;;iBDTwBX,OAAAA;;;;;;;GAOrBF,0BACOL,oBACCc;;;;;;ADpDX;;UExBiBG,gBAAAA;;ADKjB;;;EAKUlB,QAAAA,CAAAA,ECLGgB,SDKHhB,EAAAA,GCLiBmB,GDKjBnB,CCLqBgB,SDKrBhB,CAAAA;EAeQI;;;AA0ClB;EACEK,WAAAA,CAAAA,EC1DcO,SD0DdP,EAAAA,GC1D4BU,GD0D5BV,CC1DgCO,SD0DhCP,CAAAA;EACAC;;;;EAIAI,OAAAA,CAAAA,EC1DUE,SD0DVF,EAAAA,GC1DwBK,GD0DxBL,CC1D4BE,SD0D5BF,CAAAA;EACCR;;;;WCtDQU,cAAcG,IAAIH;;;AApB7B;;;;EAUgBA,SAAAA,CAAAA,EAiBFA,SAjBEA,EAAAA,GAiBYG,GAjBZH,CAiBgBA,SAjBhBA,CAAAA;EAAkBA;;;;EAKRG,QAAAA,CAAAA,EAAAA,MAAAA;EAKfH;;;;EAOqBA,QAAAA,CAAAA,EAUnBC,QAVmBD;;;;AAiDhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAwBI,SAAAA;;;;;;;;IAQpBF,4BACMF,oBACCY,8DACNZ"}
|
|
@@ -24,20 +24,24 @@ import { z } from "zod/v4";
|
|
|
24
24
|
*
|
|
25
25
|
* @Command({ path: 'greet', optionsSchema })
|
|
26
26
|
* export class GreetCommand implements CommandHandler<Options> {
|
|
27
|
-
* async execute(options: Options) {
|
|
27
|
+
* async execute(options: Options, positionals?: string[]) {
|
|
28
28
|
* console.log(`Hello, ${options.name}!`)
|
|
29
|
+
* if (positionals?.length) {
|
|
30
|
+
* console.log(`Files: ${positionals.join(', ')}`)
|
|
31
|
+
* }
|
|
29
32
|
* }
|
|
30
33
|
* }
|
|
31
34
|
* ```
|
|
32
35
|
*/
|
|
33
36
|
interface CommandHandler<TOptions = any> {
|
|
34
37
|
/**
|
|
35
|
-
* Executes the command with the provided options.
|
|
38
|
+
* Executes the command with the provided options and positional arguments.
|
|
36
39
|
*
|
|
37
40
|
* @param options - The validated command options (validated against the command's schema if provided)
|
|
41
|
+
* @param positionals - Positional arguments that don't match any option flags
|
|
38
42
|
* @returns A promise or void
|
|
39
43
|
*/
|
|
40
|
-
execute(options: TOptions): void | Promise<void>;
|
|
44
|
+
execute(options: TOptions, positionals?: string[]): void | Promise<void>;
|
|
41
45
|
}
|
|
42
46
|
//#endregion
|
|
43
47
|
//#region src/interfaces/abstract-cli-adapter.interface.d.mts
|
|
@@ -211,11 +215,12 @@ declare class CommanderExecutionContext {
|
|
|
211
215
|
private readonly command;
|
|
212
216
|
private readonly commandPath;
|
|
213
217
|
private readonly options;
|
|
218
|
+
private readonly positionals;
|
|
214
219
|
/**
|
|
215
220
|
* @internal
|
|
216
221
|
* Creates a new execution context.
|
|
217
222
|
*/
|
|
218
|
-
constructor(command: CommandMetadata, commandPath: string, options: any);
|
|
223
|
+
constructor(command: CommandMetadata, commandPath: string, options: any, positionals?: string[]);
|
|
219
224
|
/**
|
|
220
225
|
* Gets the command metadata.
|
|
221
226
|
*
|
|
@@ -236,6 +241,15 @@ declare class CommanderExecutionContext {
|
|
|
236
241
|
* @returns The validated options object
|
|
237
242
|
*/
|
|
238
243
|
getOptions(): any;
|
|
244
|
+
/**
|
|
245
|
+
* Gets the positional arguments.
|
|
246
|
+
*
|
|
247
|
+
* Positional arguments are values that don't match any option flags.
|
|
248
|
+
* For example, in `copy --force source.txt dest.txt`, the positionals are `['source.txt', 'dest.txt']`.
|
|
249
|
+
*
|
|
250
|
+
* @returns The positional arguments array
|
|
251
|
+
*/
|
|
252
|
+
getPositionals(): string[];
|
|
239
253
|
}
|
|
240
254
|
//#endregion
|
|
241
255
|
//#region src/decorators/command.decorator.d.mts
|
|
@@ -408,4 +422,4 @@ declare function CliModule({
|
|
|
408
422
|
}?: CliModuleOptions): (target: ClassType, context: ClassDecoratorContext<abstract new (...args: any) => any>) => ClassType;
|
|
409
423
|
//#endregion
|
|
410
424
|
export { CommanderExecutionContext as a, extractCommandMetadata as c, CliAdapterOptions as d, CliEnvironment as f, CommandOptions as i, getCommandMetadata as l, CommandHandler as m, CliModuleOptions as n, CommandMetadata as o, AbstractCliAdapterInterface as p, Command as r, CommandMetadataKey as s, CliModule as t, hasCommandMetadata as u };
|
|
411
|
-
//# sourceMappingURL=cli-module.decorator-
|
|
425
|
+
//# sourceMappingURL=cli-module.decorator-DDlgpTgI.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-module.decorator-DDlgpTgI.d.mts","names":["CommandHandler","TOptions","Promise","AbstractAdapterInterface","AbstractCliAdapterInterface","Promise","Record","Array","AdapterEnvironment","AbstractCliAdapterInterface","CliAdapterOptions","CliEnvironment","ClassType","z","CommandMetadataKey","CommandMetadata","ZodObject","Map","getCommandMetadata","ClassDecoratorContext","extractCommandMetadata","hasCommandMetadata","CommandMetadata","CommanderExecutionContext","InjectionToken","ClassType","ClassTypeWithInstance","Registry","z","CommandHandler","CommandOptions","ZodObject","Command","path","description","token","optionsSchema","priority","registry","ClassDecoratorContext","ClassType","Registry","CliModuleOptions","Set","CliModule","commands","controllers","imports","guards","overrides","priority","registry","ClassDecoratorContext"],"sources":["../src/interfaces/command-handler.interface.d.mts","../src/interfaces/abstract-cli-adapter.interface.d.mts","../src/interfaces/environment.interface.d.mts","../src/metadata/command.metadata.d.mts","../src/interfaces/commander-execution-context.interface.d.mts","../src/decorators/command.decorator.d.mts","../src/decorators/cli-module.decorator.d.mts"],"sourcesContent":["/**\n * Interface that all command classes must implement.\n *\n * Commands decorated with `@Command` must implement this interface.\n * The `execute` method is called when the command is invoked.\n *\n * @template TOptions - The type of options that the command accepts\n *\n * @example\n * ```typescript\n * import { Command, CommandHandler } from '@navios/commander'\n * import { z } from 'zod/v4'\n *\n * const optionsSchema = z.object({\n * name: z.string()\n * })\n *\n * type Options = z.infer<typeof optionsSchema>\n *\n * @Command({ path: 'greet', optionsSchema })\n * export class GreetCommand implements CommandHandler<Options> {\n * async execute(options: Options, positionals?: string[]) {\n * console.log(`Hello, ${options.name}!`)\n * if (positionals?.length) {\n * console.log(`Files: ${positionals.join(', ')}`)\n * }\n * }\n * }\n * ```\n */\nexport interface CommandHandler<TOptions = any> {\n /**\n * Executes the command with the provided options and positional arguments.\n *\n * @param options - The validated command options (validated against the command's schema if provided)\n * @param positionals - Positional arguments that don't match any option flags\n * @returns A promise or void\n */\n execute(options: TOptions, positionals?: string[]): void | Promise<void>\n}\n//# sourceMappingURL=command-handler.interface.d.mts.map\n","import type { AbstractAdapterInterface } from '@navios/core'\n/**\n * Interface for CLI adapters.\n * Extends the base adapter interface with CLI-specific methods.\n *\n * @public\n */\nexport interface AbstractCliAdapterInterface extends AbstractAdapterInterface {\n /**\n * Run the CLI application with the given arguments.\n * Parses arguments and executes the matching command.\n *\n * @param argv - Command-line arguments array (defaults to `process.argv`)\n *\n * @example\n * ```typescript\n * const adapter = app.getAdapter() as AbstractCliAdapterInterface\n * await adapter.run(process.argv)\n * ```\n */\n run(argv?: string[]): Promise<void>\n /**\n * Execute a command programmatically with the provided options.\n *\n * @param path - The command path (e.g., 'greet', 'user:create')\n * @param options - The command options object\n *\n * @example\n * ```typescript\n * await adapter.executeCommand('user:create', {\n * name: 'John',\n * email: 'john@example.com',\n * })\n * ```\n */\n executeCommand(path: string, options: Record<string, unknown>): Promise<void>\n /**\n * Get all registered command paths and their class references.\n *\n * @returns Array of objects containing path and class\n *\n * @example\n * ```typescript\n * const commands = adapter.getAllCommands()\n * commands.forEach(({ path }) => console.log(path))\n * ```\n */\n getAllCommands(): Array<{\n path: string\n class: unknown\n }>\n}\n//# sourceMappingURL=abstract-cli-adapter.interface.d.mts.map\n","import type { AdapterEnvironment } from '@navios/core'\n\nimport type { AbstractCliAdapterInterface } from './abstract-cli-adapter.interface.mjs'\n/**\n * Options for configuring the CLI adapter.\n *\n * @public\n */\nexport interface CliAdapterOptions {}\n/**\n * Environment type definition for CLI adapters.\n * Used with NaviosFactory.create<CliEnvironment>() for type-safe CLI applications.\n *\n * @public\n *\n * @example\n * ```typescript\n * import { NaviosFactory } from '@navios/core'\n * import { defineCliEnvironment, type CliEnvironment } from '@navios/commander'\n *\n * const app = await NaviosFactory.create<CliEnvironment>(AppModule, {\n * adapter: defineCliEnvironment(),\n * })\n * ```\n */\nexport interface CliEnvironment extends AdapterEnvironment {\n options: CliAdapterOptions\n adapter: AbstractCliAdapterInterface\n}\n//# sourceMappingURL=environment.interface.d.mts.map\n","import type { ClassType } from '@navios/core'\nimport type { z } from 'zod/v4'\n/**\n * @internal\n * Symbol key used to store command metadata on classes.\n */\nexport declare const CommandMetadataKey: unique symbol\n/**\n * Metadata associated with a command.\n *\n * @public\n */\nexport interface CommandMetadata {\n /**\n * The command path (e.g., 'greet', 'user:create').\n */\n path: string\n /**\n * Optional description of the command for help text.\n */\n description?: string\n /**\n * Optional zod/v4 schema for validating command options.\n */\n optionsSchema?: z.ZodObject\n /**\n * Map of custom attributes that can be attached to the command.\n */\n customAttributes: Map<string | symbol, any>\n}\n/**\n * Gets or creates command metadata for a class.\n *\n * @internal\n * @param target - The command class\n * @param context - The decorator context\n * @param path - The command path\n * @param description - Optional description for help text\n * @param optionsSchema - Optional zod/v4 schema\n * @returns The command metadata\n */\nexport declare function getCommandMetadata(\n target: ClassType,\n context: ClassDecoratorContext,\n path: string,\n description?: string,\n optionsSchema?: z.ZodObject,\n): CommandMetadata\n/**\n * Extracts command metadata from a class.\n *\n * @param target - The command class\n * @returns The command metadata\n * @throws {Error} If the class is not decorated with @Command\n *\n * @example\n * ```typescript\n * const metadata = extractCommandMetadata(GreetCommand)\n * console.log(metadata.path) // 'greet'\n * ```\n */\nexport declare function extractCommandMetadata(target: ClassType): CommandMetadata\n/**\n * Checks if a class has command metadata.\n *\n * @param target - The class to check\n * @returns `true` if the class is decorated with @Command, `false` otherwise\n */\nexport declare function hasCommandMetadata(target: ClassType): boolean\n//# sourceMappingURL=command.metadata.d.mts.map\n","import type { CommandMetadata } from '../metadata/command.metadata.mjs'\n/**\n * Execution context for a command execution.\n *\n * Provides access to command metadata, path, and validated options during command execution.\n * This context is automatically injected and available via the `CommandExecutionContext` token.\n *\n * @example\n * ```typescript\n * import { inject, Injectable } from '@navios/core'\n * import { CommandExecutionContext } from '@navios/commander'\n *\n * @Injectable()\n * class CommandLogger {\n * private ctx = inject(CommandExecutionContext)\n *\n * log() {\n * console.log('Command:', this.ctx.getCommandPath())\n * console.log('Options:', this.ctx.getOptions())\n * }\n * }\n * ```\n */\nexport declare class CommanderExecutionContext {\n private readonly command\n private readonly commandPath\n private readonly options\n private readonly positionals\n /**\n * @internal\n * Creates a new execution context.\n */\n constructor(command: CommandMetadata, commandPath: string, options: any, positionals?: string[])\n /**\n * Gets the command metadata.\n *\n * @returns The command metadata including path and options schema\n */\n getCommand(): CommandMetadata\n /**\n * Gets the command path that was invoked.\n *\n * @returns The command path (e.g., 'greet', 'user:create')\n */\n getCommandPath(): string\n /**\n * Gets the validated command options.\n *\n * Options are validated against the command's zod/v4 schema if one was provided.\n *\n * @returns The validated options object\n */\n getOptions(): any\n /**\n * Gets the positional arguments.\n *\n * Positional arguments are values that don't match any option flags.\n * For example, in `copy --force source.txt dest.txt`, the positionals are `['source.txt', 'dest.txt']`.\n *\n * @returns The positional arguments array\n */\n getPositionals(): string[]\n}\n//# sourceMappingURL=commander-execution-context.interface.d.mts.map\n","import { InjectionToken } from '@navios/core'\n\nimport type { ClassType, ClassTypeWithInstance, Registry } from '@navios/core'\nimport type { z } from 'zod/v4'\n\nimport type { CommandHandler } from '../interfaces/index.mjs'\n/**\n * Options for the `@Command` decorator.\n *\n * @public\n */\nexport interface CommandOptions {\n /**\n * The token to use for the command.\n * If provided, the command will be registered with this token.\n */\n token?: InjectionToken<ClassTypeWithInstance<CommandHandler<any>>>\n /**\n * The command path that users will invoke from the CLI.\n * Can be a single word (e.g., 'greet') or multi-word with colons (e.g., 'user:create', 'db:migrate').\n */\n path: string\n /**\n * Optional description of the command for help text.\n * Displayed when users run `help` or `--help`.\n */\n description?: string\n /**\n * Optional zod/v4 schema for validating command options.\n * If provided, options will be validated and parsed according to this schema.\n */\n optionsSchema?: z.ZodObject\n /**\n * Priority level for the command.\n * Higher priority commands will be loaded first.\n */\n priority?: number\n /**\n * Registry to use for the command.\n * Registry is used to store the command and its options schema.\n */\n registry?: Registry\n}\n/**\n * Decorator that marks a class as a CLI command.\n *\n * The decorated class must implement the `CommandHandler` interface with an `execute` method.\n * The command will be automatically registered when its module is loaded.\n *\n * @param options - Configuration options for the command\n * @returns A class decorator function\n *\n * @example\n * ```typescript\n * import { Command, CommandHandler } from '@navios/commander'\n * import { z } from 'zod/v4'\n *\n * const optionsSchema = z.object({\n * name: z.string(),\n * greeting: z.string().optional().default('Hello')\n * })\n *\n * @Command({\n * path: 'greet',\n * optionsSchema: optionsSchema\n * })\n * export class GreetCommand implements CommandHandler<z.infer<typeof optionsSchema>> {\n * async execute(options) {\n * console.log(`${options.greeting}, ${options.name}!`)\n * }\n * }\n * ```\n */\nexport declare function Command({\n path,\n description,\n token,\n optionsSchema,\n priority,\n registry,\n}: CommandOptions): (\n target: ClassType,\n context: ClassDecoratorContext<abstract new (...args: any) => any>,\n) => any\n//# sourceMappingURL=command.decorator.d.mts.map\n","import type { ClassType, Registry } from '@navios/core'\n/**\n * Options for the `@CliModule` decorator.\n *\n * @public\n */\nexport interface CliModuleOptions {\n /**\n * Array or Set of command classes to register in this module.\n * Commands must be decorated with `@Command`.\n */\n commands?: ClassType[] | Set<ClassType>\n /**\n * Array or Set of controller classes for HTTP endpoints.\n * Allows mixing HTTP and CLI functionality in the same module.\n */\n controllers?: ClassType[] | Set<ClassType>\n /**\n * Array or Set of other modules to import.\n * Imported modules' commands and controllers will be available.\n */\n imports?: ClassType[] | Set<ClassType>\n /**\n * Guards to apply to all controllers in this module.\n * Guards are executed in reverse order (last guard first).\n */\n guards?: ClassType[] | Set<ClassType>\n /**\n * Service override classes to import for side effects.\n * These classes are imported to ensure their @Injectable decorators execute,\n * allowing them to register with the DI system. Overrides should use the same\n * InjectionToken as the original service with a higher priority.\n */\n overrides?: ClassType[] | Set<ClassType>\n /**\n * Priority level for the module.\n * Higher priority modules will be loaded first.\n */\n priority?: number\n /**\n * Registry to use for the module.\n * Registry is used to store the module and its commands.\n */\n registry?: Registry\n}\n/**\n * Decorator that marks a class as a CLI module.\n *\n * This decorator extends the standard @Module decorator, adding support for\n * CLI commands while maintaining full compatibility with HTTP controllers.\n * Modules organize commands and can import other modules to compose larger\n * CLI applications.\n *\n * The module can optionally implement `NaviosModule` interface for lifecycle hooks.\n *\n * @param options - Configuration options for the module\n * @returns A class decorator function\n *\n * @example\n * ```typescript\n * import { CliModule } from '@navios/commander'\n * import { GreetCommand } from './greet.command'\n * import { UserModule } from './user.module'\n *\n * @CliModule({\n * commands: [GreetCommand],\n * imports: [UserModule]\n * })\n * export class AppModule {}\n * ```\n *\n * @example\n * ```typescript\n * // Mixed HTTP and CLI module\n * @CliModule({\n * controllers: [HealthController],\n * commands: [MigrateCommand],\n * imports: [DatabaseModule],\n * })\n * export class AppModule {}\n * ```\n */\nexport declare function CliModule({\n commands,\n controllers,\n imports,\n guards,\n overrides,\n priority,\n registry,\n}?: CliModuleOptions): (\n target: ClassType,\n context: ClassDecoratorContext<abstract new (...args: any) => any>,\n) => ClassType\n//# sourceMappingURL=cli-module.decorator.d.mts.map\n"],"mappings":"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"}
|
|
@@ -358,15 +358,40 @@ var CommandRegistryService = class {
|
|
|
358
358
|
try {
|
|
359
359
|
const shape = metadata.optionsSchema.def.shape;
|
|
360
360
|
if (shape && typeof shape === "object") for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
361
|
-
const
|
|
361
|
+
const kebabKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
362
|
+
const optionFlag = `--${kebabKey}`;
|
|
362
363
|
const fieldType = this.getSchemaTypeName(fieldSchema);
|
|
363
364
|
lines.push(` ${optionFlag.padEnd(20)} ${fieldType}`);
|
|
365
|
+
this.formatNestedObjectOptions(fieldSchema, kebabKey, lines, " ");
|
|
364
366
|
}
|
|
365
367
|
} catch {}
|
|
366
368
|
}
|
|
367
369
|
return lines.join("\n");
|
|
368
370
|
}
|
|
369
371
|
/**
|
|
372
|
+
* Recursively formats nested object options for help display.
|
|
373
|
+
* Shows nested fields with dot notation (e.g., --config.port)
|
|
374
|
+
*/ formatNestedObjectOptions(schema, parentPath, lines, indent) {
|
|
375
|
+
try {
|
|
376
|
+
let currentSchema = schema;
|
|
377
|
+
let typeName = currentSchema?.def?.type;
|
|
378
|
+
while (typeName === "optional" || typeName === "default") {
|
|
379
|
+
currentSchema = currentSchema?.def?.innerType;
|
|
380
|
+
typeName = currentSchema?.def?.type;
|
|
381
|
+
}
|
|
382
|
+
if (typeName !== "object") return;
|
|
383
|
+
const shape = currentSchema?.def?.shape;
|
|
384
|
+
if (!shape || typeof shape !== "object") return;
|
|
385
|
+
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
386
|
+
const kebabKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
387
|
+
const optionFlag = `--${parentPath}.${kebabKey}`;
|
|
388
|
+
const fieldType = this.getSchemaTypeName(fieldSchema);
|
|
389
|
+
lines.push(`${indent}${optionFlag.padEnd(20 - indent.length + 2)} ${fieldType}`);
|
|
390
|
+
this.formatNestedObjectOptions(fieldSchema, `${parentPath}.${kebabKey}`, lines, indent + " ");
|
|
391
|
+
}
|
|
392
|
+
} catch {}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
370
395
|
* Gets a human-readable type name from a zod/v4 schema.
|
|
371
396
|
*/ getSchemaTypeName(schema) {
|
|
372
397
|
try {
|
|
@@ -424,4 +449,4 @@ const HelpCommandToken = InjectionToken.create("HelpCommand");
|
|
|
424
449
|
|
|
425
450
|
//#endregion
|
|
426
451
|
export { _CommandRegistryService as n, HelpCommandToken as t };
|
|
427
|
-
//# sourceMappingURL=help-command.token-
|
|
452
|
+
//# sourceMappingURL=help-command.token-ChAUjOyV.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help-command.token-ChAUjOyV.mjs","names":["Injectable","CommandRegistryService","commands","Map","register","path","command","has","Error","set","getByPath","get","getAll","getAllAsArray","result","class","cls","push","formatCommandList","lines","metadata","description","padEnd","join","formatCommandHelp","commandPath","optionsSchema","shape","def","key","fieldSchema","Object","entries","kebabKey","replace","toLowerCase","optionFlag","fieldType","getSchemaTypeName","formatNestedObjectOptions","schema","parentPath","indent","currentSchema","typeName","type","innerType","length","isOptional","defaultValue","undefined","JSON","stringify","getSchemaMeta","directMeta","meta","clear","InjectionToken","HelpCommandToken","create"],"sources":["../src/services/command-registry.service.mts","../src/tokens/help-command.token.mts"],"sourcesContent":["import { Injectable } from '@navios/core'\n\nimport type { ClassType } from '@navios/core'\n\nimport type { CommandMetadata } from '../metadata/index.mjs'\n\n/**\n * Represents a registered command with its metadata and module information.\n *\n * @public\n */\nexport interface RegisteredCommand {\n /**\n * The command class\n */\n class: ClassType\n /**\n * The command metadata from @Command decorator\n */\n metadata: CommandMetadata\n /**\n * Name of the module this command belongs to\n */\n moduleName: string\n}\n\n/**\n * Service for registering and looking up CLI commands.\n * Used internally by the CLI adapter to manage discovered commands.\n *\n * @public\n */\n@Injectable()\nexport class CommandRegistryService {\n private commands = new Map<string, RegisteredCommand>()\n\n /**\n * Register a command with its metadata.\n *\n * @param path - The command path (e.g., 'greet', 'user:create')\n * @param command - The registered command data\n * @throws Error if a command with the same path is already registered\n */\n register(path: string, command: RegisteredCommand): void {\n if (this.commands.has(path)) {\n throw new Error(`[Navios Commander] Duplicate command path: ${path}`)\n }\n this.commands.set(path, command)\n }\n\n /**\n * Get a command by its path.\n *\n * @param path - The command path\n * @returns The registered command or undefined if not found\n */\n getByPath(path: string): RegisteredCommand | undefined {\n return this.commands.get(path)\n }\n\n /**\n * Get all registered commands.\n *\n * @returns Map of path to registered command\n */\n getAll(): Map<string, RegisteredCommand> {\n return new Map(this.commands)\n }\n\n /**\n * Get all registered commands as an array of path and class pairs.\n * Useful for listing available commands.\n *\n * @returns Array of objects containing path and class\n */\n getAllAsArray(): Array<{ path: string; class: ClassType }> {\n const result: Array<{ path: string; class: ClassType }> = []\n for (const [path, { class: cls }] of this.commands) {\n result.push({ path, class: cls })\n }\n return result\n }\n\n /**\n * Formats help text listing all available commands with descriptions.\n *\n * @returns Formatted string listing all commands\n */\n formatCommandList(): string {\n const lines = ['Available commands:', '']\n for (const [path, { metadata }] of this.commands) {\n const description = metadata.description\n if (description) {\n lines.push(` ${path.padEnd(20)} ${description}`)\n } else {\n lines.push(` ${path}`)\n }\n }\n return lines.join('\\n')\n }\n\n /**\n * Formats help text for a specific command.\n *\n * @param commandPath - The command path to show help for\n * @returns Formatted string with command help\n */\n formatCommandHelp(commandPath: string): string {\n const command = this.commands.get(commandPath)\n if (!command) {\n return `Unknown command: ${commandPath}\\n\\n${this.formatCommandList()}`\n }\n\n const { metadata } = command\n const lines: string[] = []\n\n lines.push(`Usage: ${metadata.path} [options]`)\n lines.push('')\n\n if (metadata.description) {\n lines.push(metadata.description)\n lines.push('')\n }\n\n // Extract options from schema if available\n if (metadata.optionsSchema) {\n lines.push('Options:')\n try {\n const shape = metadata.optionsSchema.def.shape\n if (shape && typeof shape === 'object') {\n for (const [key, fieldSchema] of Object.entries(shape)) {\n const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase()\n const optionFlag = `--${kebabKey}`\n const fieldType = this.getSchemaTypeName(fieldSchema as any)\n lines.push(` ${optionFlag.padEnd(20)} ${fieldType}`)\n\n // Check for nested object fields and display them with dot notation\n this.formatNestedObjectOptions(fieldSchema as any, kebabKey, lines, ' ')\n }\n }\n } catch {\n // Schema introspection failed, skip options\n }\n }\n\n return lines.join('\\n')\n }\n\n /**\n * Recursively formats nested object options for help display.\n * Shows nested fields with dot notation (e.g., --config.port)\n */\n private formatNestedObjectOptions(\n schema: any,\n parentPath: string,\n lines: string[],\n indent: string,\n ): void {\n try {\n let currentSchema = schema\n let typeName = currentSchema?.def?.type\n\n // Unwrap optional/default wrappers\n while (typeName === 'optional' || typeName === 'default') {\n currentSchema = currentSchema?.def?.innerType\n typeName = currentSchema?.def?.type\n }\n\n if (typeName !== 'object') {\n return\n }\n\n const shape = currentSchema?.def?.shape\n if (!shape || typeof shape !== 'object') {\n return\n }\n\n for (const [key, fieldSchema] of Object.entries(shape)) {\n const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase()\n const optionFlag = `--${parentPath}.${kebabKey}`\n const fieldType = this.getSchemaTypeName(fieldSchema as any)\n lines.push(`${indent}${optionFlag.padEnd(20 - indent.length + 2)} ${fieldType}`)\n\n // Recurse for deeper nesting\n this.formatNestedObjectOptions(\n fieldSchema as any,\n `${parentPath}.${kebabKey}`,\n lines,\n indent + ' ',\n )\n }\n } catch {\n // Silently fail if schema introspection fails\n }\n }\n\n /**\n * Gets a human-readable type name from a zod/v4 schema.\n */\n private getSchemaTypeName(schema: any): string {\n try {\n let currentSchema = schema\n let typeName = currentSchema?.def?.type\n let isOptional = false\n let defaultValue: any\n\n // Unwrap optional/default wrappers\n while (typeName === 'optional' || typeName === 'default') {\n if (typeName === 'optional') {\n isOptional = true\n }\n if (typeName === 'default') {\n isOptional = true\n defaultValue = currentSchema?.def?.defaultValue?.()\n }\n currentSchema = currentSchema?.def?.innerType\n typeName = currentSchema?.def?.type\n }\n\n let result = `<${typeName || 'unknown'}>`\n if (defaultValue !== undefined) {\n result += ` (default: ${JSON.stringify(defaultValue)})`\n } else if (isOptional) {\n result += ' (optional)'\n }\n\n // Get description from meta() if available\n const description = this.getSchemaMeta(schema)?.description\n if (description) {\n result += ` - ${description}`\n }\n\n return result\n } catch {\n return '<unknown>'\n }\n }\n\n /**\n * Gets metadata from a zod/v4 schema, traversing innerType if needed.\n * zod/v4 v4 stores meta at the outermost layer when .meta() is called last,\n * or in innerType when .meta() is called before .optional()/.default().\n */\n private getSchemaMeta(schema: any): Record<string, unknown> | undefined {\n try {\n // First check direct meta (when .meta() is called last in chain)\n const directMeta = schema.meta?.()\n if (directMeta) return directMeta\n\n // Check innerType for wrapped schemas (optional, default, etc.)\n const innerType = schema.def?.innerType\n if (innerType) {\n return this.getSchemaMeta(innerType)\n }\n\n return undefined\n } catch {\n return undefined\n }\n }\n\n /**\n * Clear all registered commands.\n */\n clear(): void {\n this.commands.clear()\n }\n}\n","import { InjectionToken } from '@navios/core'\n\nimport type { HelpCommand } from '../overrides/help.command.mjs'\n\nexport const HelpCommandToken = InjectionToken.create<HelpCommand>('HelpCommand')\n"],"mappings":"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"}
|
|
@@ -358,15 +358,40 @@ var CommandRegistryService = class {
|
|
|
358
358
|
try {
|
|
359
359
|
const shape = metadata.optionsSchema.def.shape;
|
|
360
360
|
if (shape && typeof shape === "object") for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
361
|
-
const
|
|
361
|
+
const kebabKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
362
|
+
const optionFlag = `--${kebabKey}`;
|
|
362
363
|
const fieldType = this.getSchemaTypeName(fieldSchema);
|
|
363
364
|
lines.push(` ${optionFlag.padEnd(20)} ${fieldType}`);
|
|
365
|
+
this.formatNestedObjectOptions(fieldSchema, kebabKey, lines, " ");
|
|
364
366
|
}
|
|
365
367
|
} catch {}
|
|
366
368
|
}
|
|
367
369
|
return lines.join("\n");
|
|
368
370
|
}
|
|
369
371
|
/**
|
|
372
|
+
* Recursively formats nested object options for help display.
|
|
373
|
+
* Shows nested fields with dot notation (e.g., --config.port)
|
|
374
|
+
*/ formatNestedObjectOptions(schema, parentPath, lines, indent) {
|
|
375
|
+
try {
|
|
376
|
+
let currentSchema = schema;
|
|
377
|
+
let typeName = currentSchema?.def?.type;
|
|
378
|
+
while (typeName === "optional" || typeName === "default") {
|
|
379
|
+
currentSchema = currentSchema?.def?.innerType;
|
|
380
|
+
typeName = currentSchema?.def?.type;
|
|
381
|
+
}
|
|
382
|
+
if (typeName !== "object") return;
|
|
383
|
+
const shape = currentSchema?.def?.shape;
|
|
384
|
+
if (!shape || typeof shape !== "object") return;
|
|
385
|
+
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
386
|
+
const kebabKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
387
|
+
const optionFlag = `--${parentPath}.${kebabKey}`;
|
|
388
|
+
const fieldType = this.getSchemaTypeName(fieldSchema);
|
|
389
|
+
lines.push(`${indent}${optionFlag.padEnd(20 - indent.length + 2)} ${fieldType}`);
|
|
390
|
+
this.formatNestedObjectOptions(fieldSchema, `${parentPath}.${kebabKey}`, lines, indent + " ");
|
|
391
|
+
}
|
|
392
|
+
} catch {}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
370
395
|
* Gets a human-readable type name from a zod/v4 schema.
|
|
371
396
|
*/ getSchemaTypeName(schema) {
|
|
372
397
|
try {
|
|
@@ -435,4 +460,4 @@ Object.defineProperty(exports, '_CommandRegistryService', {
|
|
|
435
460
|
return _CommandRegistryService;
|
|
436
461
|
}
|
|
437
462
|
});
|
|
438
|
-
//# sourceMappingURL=help-command.token-
|
|
463
|
+
//# sourceMappingURL=help-command.token-mlwEyWij.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help-command.token-mlwEyWij.cjs","names":["Injectable","CommandRegistryService","commands","Map","register","path","command","has","Error","set","getByPath","get","getAll","getAllAsArray","result","class","cls","push","formatCommandList","lines","metadata","description","padEnd","join","formatCommandHelp","commandPath","optionsSchema","shape","def","key","fieldSchema","Object","entries","kebabKey","replace","toLowerCase","optionFlag","fieldType","getSchemaTypeName","formatNestedObjectOptions","schema","parentPath","indent","currentSchema","typeName","type","innerType","length","isOptional","defaultValue","undefined","JSON","stringify","getSchemaMeta","directMeta","meta","clear","InjectionToken","HelpCommandToken","create"],"sources":["../src/services/command-registry.service.mts","../src/tokens/help-command.token.mts"],"sourcesContent":["import { Injectable } from '@navios/core'\n\nimport type { ClassType } from '@navios/core'\n\nimport type { CommandMetadata } from '../metadata/index.mjs'\n\n/**\n * Represents a registered command with its metadata and module information.\n *\n * @public\n */\nexport interface RegisteredCommand {\n /**\n * The command class\n */\n class: ClassType\n /**\n * The command metadata from @Command decorator\n */\n metadata: CommandMetadata\n /**\n * Name of the module this command belongs to\n */\n moduleName: string\n}\n\n/**\n * Service for registering and looking up CLI commands.\n * Used internally by the CLI adapter to manage discovered commands.\n *\n * @public\n */\n@Injectable()\nexport class CommandRegistryService {\n private commands = new Map<string, RegisteredCommand>()\n\n /**\n * Register a command with its metadata.\n *\n * @param path - The command path (e.g., 'greet', 'user:create')\n * @param command - The registered command data\n * @throws Error if a command with the same path is already registered\n */\n register(path: string, command: RegisteredCommand): void {\n if (this.commands.has(path)) {\n throw new Error(`[Navios Commander] Duplicate command path: ${path}`)\n }\n this.commands.set(path, command)\n }\n\n /**\n * Get a command by its path.\n *\n * @param path - The command path\n * @returns The registered command or undefined if not found\n */\n getByPath(path: string): RegisteredCommand | undefined {\n return this.commands.get(path)\n }\n\n /**\n * Get all registered commands.\n *\n * @returns Map of path to registered command\n */\n getAll(): Map<string, RegisteredCommand> {\n return new Map(this.commands)\n }\n\n /**\n * Get all registered commands as an array of path and class pairs.\n * Useful for listing available commands.\n *\n * @returns Array of objects containing path and class\n */\n getAllAsArray(): Array<{ path: string; class: ClassType }> {\n const result: Array<{ path: string; class: ClassType }> = []\n for (const [path, { class: cls }] of this.commands) {\n result.push({ path, class: cls })\n }\n return result\n }\n\n /**\n * Formats help text listing all available commands with descriptions.\n *\n * @returns Formatted string listing all commands\n */\n formatCommandList(): string {\n const lines = ['Available commands:', '']\n for (const [path, { metadata }] of this.commands) {\n const description = metadata.description\n if (description) {\n lines.push(` ${path.padEnd(20)} ${description}`)\n } else {\n lines.push(` ${path}`)\n }\n }\n return lines.join('\\n')\n }\n\n /**\n * Formats help text for a specific command.\n *\n * @param commandPath - The command path to show help for\n * @returns Formatted string with command help\n */\n formatCommandHelp(commandPath: string): string {\n const command = this.commands.get(commandPath)\n if (!command) {\n return `Unknown command: ${commandPath}\\n\\n${this.formatCommandList()}`\n }\n\n const { metadata } = command\n const lines: string[] = []\n\n lines.push(`Usage: ${metadata.path} [options]`)\n lines.push('')\n\n if (metadata.description) {\n lines.push(metadata.description)\n lines.push('')\n }\n\n // Extract options from schema if available\n if (metadata.optionsSchema) {\n lines.push('Options:')\n try {\n const shape = metadata.optionsSchema.def.shape\n if (shape && typeof shape === 'object') {\n for (const [key, fieldSchema] of Object.entries(shape)) {\n const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase()\n const optionFlag = `--${kebabKey}`\n const fieldType = this.getSchemaTypeName(fieldSchema as any)\n lines.push(` ${optionFlag.padEnd(20)} ${fieldType}`)\n\n // Check for nested object fields and display them with dot notation\n this.formatNestedObjectOptions(fieldSchema as any, kebabKey, lines, ' ')\n }\n }\n } catch {\n // Schema introspection failed, skip options\n }\n }\n\n return lines.join('\\n')\n }\n\n /**\n * Recursively formats nested object options for help display.\n * Shows nested fields with dot notation (e.g., --config.port)\n */\n private formatNestedObjectOptions(\n schema: any,\n parentPath: string,\n lines: string[],\n indent: string,\n ): void {\n try {\n let currentSchema = schema\n let typeName = currentSchema?.def?.type\n\n // Unwrap optional/default wrappers\n while (typeName === 'optional' || typeName === 'default') {\n currentSchema = currentSchema?.def?.innerType\n typeName = currentSchema?.def?.type\n }\n\n if (typeName !== 'object') {\n return\n }\n\n const shape = currentSchema?.def?.shape\n if (!shape || typeof shape !== 'object') {\n return\n }\n\n for (const [key, fieldSchema] of Object.entries(shape)) {\n const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase()\n const optionFlag = `--${parentPath}.${kebabKey}`\n const fieldType = this.getSchemaTypeName(fieldSchema as any)\n lines.push(`${indent}${optionFlag.padEnd(20 - indent.length + 2)} ${fieldType}`)\n\n // Recurse for deeper nesting\n this.formatNestedObjectOptions(\n fieldSchema as any,\n `${parentPath}.${kebabKey}`,\n lines,\n indent + ' ',\n )\n }\n } catch {\n // Silently fail if schema introspection fails\n }\n }\n\n /**\n * Gets a human-readable type name from a zod/v4 schema.\n */\n private getSchemaTypeName(schema: any): string {\n try {\n let currentSchema = schema\n let typeName = currentSchema?.def?.type\n let isOptional = false\n let defaultValue: any\n\n // Unwrap optional/default wrappers\n while (typeName === 'optional' || typeName === 'default') {\n if (typeName === 'optional') {\n isOptional = true\n }\n if (typeName === 'default') {\n isOptional = true\n defaultValue = currentSchema?.def?.defaultValue?.()\n }\n currentSchema = currentSchema?.def?.innerType\n typeName = currentSchema?.def?.type\n }\n\n let result = `<${typeName || 'unknown'}>`\n if (defaultValue !== undefined) {\n result += ` (default: ${JSON.stringify(defaultValue)})`\n } else if (isOptional) {\n result += ' (optional)'\n }\n\n // Get description from meta() if available\n const description = this.getSchemaMeta(schema)?.description\n if (description) {\n result += ` - ${description}`\n }\n\n return result\n } catch {\n return '<unknown>'\n }\n }\n\n /**\n * Gets metadata from a zod/v4 schema, traversing innerType if needed.\n * zod/v4 v4 stores meta at the outermost layer when .meta() is called last,\n * or in innerType when .meta() is called before .optional()/.default().\n */\n private getSchemaMeta(schema: any): Record<string, unknown> | undefined {\n try {\n // First check direct meta (when .meta() is called last in chain)\n const directMeta = schema.meta?.()\n if (directMeta) return directMeta\n\n // Check innerType for wrapped schemas (optional, default, etc.)\n const innerType = schema.def?.innerType\n if (innerType) {\n return this.getSchemaMeta(innerType)\n }\n\n return undefined\n } catch {\n return undefined\n }\n }\n\n /**\n * Clear all registered commands.\n */\n clear(): void {\n this.commands.clear()\n }\n}\n","import { InjectionToken } from '@navios/core'\n\nimport type { HelpCommand } from '../overrides/help.command.mjs'\n\nexport const HelpCommandToken = InjectionToken.create<HelpCommand>('HelpCommand')\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as Command } from "./command.decorator-QiRU7ny3.mjs";
|
|
2
|
-
import { n as _CommandRegistryService, t as HelpCommandToken } from "./help-command.token-
|
|
2
|
+
import { n as _CommandRegistryService, t as HelpCommandToken } from "./help-command.token-ChAUjOyV.mjs";
|
|
3
3
|
import { inject } from "@navios/core";
|
|
4
4
|
import { z } from "zod/v4";
|
|
5
5
|
import { ScreenLogger } from "@navios/commander-tui";
|
|
@@ -312,4 +312,4 @@ var HelpCommand = class {
|
|
|
312
312
|
|
|
313
313
|
//#endregion
|
|
314
314
|
export { };
|
|
315
|
-
//# sourceMappingURL=help.command-
|
|
315
|
+
//# sourceMappingURL=help.command-CzQymUFY.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.command-
|
|
1
|
+
{"version":3,"file":"help.command-CzQymUFY.mjs","names":["ScreenLogger","inject","z","Command","CommandRegistryService","HelpCommandToken","helpOptionsSchema","object","command","string","optional","token","path","description","optionsSchema","priority","HelpCommand","logger","screen","context","commandRegistry","execute","options","log","formatCommandHelp","formatCommandList"],"sources":["../src/overrides/help.command.mts"],"sourcesContent":["import { ScreenLogger } from '@navios/commander-tui'\nimport { inject } from '@navios/core'\nimport { z } from 'zod/v4'\n\nimport { Command } from '../decorators/command.decorator.mjs'\nimport { CommandRegistryService } from '../services/command-registry.service.mjs'\nimport { HelpCommandToken } from '../tokens/help-command.token.mjs'\n\nimport type { CommandHandler } from '../interfaces/command-handler.interface.mjs'\n\nconst helpOptionsSchema = z.object({\n command: z.string().optional(),\n})\n\ntype HelpOptions = z.infer<typeof helpOptionsSchema>\n\n/**\n * Built-in help command that lists all available commands or shows help for a specific command.\n *\n * @public\n */\n@Command({\n token: HelpCommandToken,\n path: 'help',\n description: 'Show available commands or help for a specific command',\n optionsSchema: helpOptionsSchema,\n priority: 1000,\n})\nexport class HelpCommand implements CommandHandler<HelpOptions> {\n private logger = inject(ScreenLogger, { screen: 'Help', context: 'Help' })\n private commandRegistry = inject(CommandRegistryService)\n\n async execute(options: HelpOptions): Promise<void> {\n if (options.command) {\n this.logger.log(this.commandRegistry.formatCommandHelp(options.command))\n } else {\n this.logger.log(this.commandRegistry.formatCommandList())\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,MAAMM,oBAAoBJ,EAAEK,OAAO,EACjCC,SAASN,EAAEO,QAAM,CAAGC,UAAQ,EAC9B,CAAA;;OASCP,QAAQ;CACPQ,OAAON;CACPO,MAAM;CACNC,aAAa;CACbC,eAAeR;CACfS,UAAU;CACZ,CAAA;AACO,IAAMC,cAAN,MAAMA;;;;CACHC,SAAShB,OAAOD,cAAc;EAAEkB,QAAQ;EAAQC,SAAS;EAAO,CAAA;CAChEC,kBAAkBnB,OAAOG,wBAAAA;CAEjC,MAAMiB,QAAQC,SAAqC;AACjD,MAAIA,QAAQd,QACV,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBI,kBAAkBF,QAAQd,QAAO,CAAA;MAEtE,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBK,mBAAiB,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_command_decorator = require('./command.decorator-HziankUv.cjs');
|
|
2
|
-
const require_help_command_token = require('./help-command.token-
|
|
2
|
+
const require_help_command_token = require('./help-command.token-mlwEyWij.cjs');
|
|
3
3
|
let _navios_core = require("@navios/core");
|
|
4
4
|
let zod_v4 = require("zod/v4");
|
|
5
5
|
let _navios_commander_tui = require("@navios/commander-tui");
|
|
@@ -311,4 +311,4 @@ var HelpCommand = class {
|
|
|
311
311
|
};
|
|
312
312
|
|
|
313
313
|
//#endregion
|
|
314
|
-
//# sourceMappingURL=help.command-
|
|
314
|
+
//# sourceMappingURL=help.command-knivRhJz.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.command-
|
|
1
|
+
{"version":3,"file":"help.command-knivRhJz.cjs","names":["ScreenLogger","inject","z","Command","CommandRegistryService","HelpCommandToken","helpOptionsSchema","object","command","string","optional","token","path","description","optionsSchema","priority","HelpCommand","logger","screen","context","commandRegistry","execute","options","log","formatCommandHelp","formatCommandList"],"sources":["../src/overrides/help.command.mts"],"sourcesContent":["import { ScreenLogger } from '@navios/commander-tui'\nimport { inject } from '@navios/core'\nimport { z } from 'zod/v4'\n\nimport { Command } from '../decorators/command.decorator.mjs'\nimport { CommandRegistryService } from '../services/command-registry.service.mjs'\nimport { HelpCommandToken } from '../tokens/help-command.token.mjs'\n\nimport type { CommandHandler } from '../interfaces/command-handler.interface.mjs'\n\nconst helpOptionsSchema = z.object({\n command: z.string().optional(),\n})\n\ntype HelpOptions = z.infer<typeof helpOptionsSchema>\n\n/**\n * Built-in help command that lists all available commands or shows help for a specific command.\n *\n * @public\n */\n@Command({\n token: HelpCommandToken,\n path: 'help',\n description: 'Show available commands or help for a specific command',\n optionsSchema: helpOptionsSchema,\n priority: 1000,\n})\nexport class HelpCommand implements CommandHandler<HelpOptions> {\n private logger = inject(ScreenLogger, { screen: 'Help', context: 'Help' })\n private commandRegistry = inject(CommandRegistryService)\n\n async execute(options: HelpOptions): Promise<void> {\n if (options.command) {\n this.logger.log(this.commandRegistry.formatCommandHelp(options.command))\n } else {\n this.logger.log(this.commandRegistry.formatCommandList())\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,MAAMM,oBAAoBJ,SAAEK,OAAO,EACjCC,SAASN,SAAEO,QAAM,CAAGC,UAAQ,EAC9B,CAAA;;OASCP,kCAAQ;CACPQ,OAAON;CACPO,MAAM;CACNC,aAAa;CACbC,eAAeR;CACfS,UAAU;CACZ,CAAA;AACO,IAAMC,cAAN,MAAMA;;;;CACHC,kCAAgBjB,oCAAc;EAAEkB,QAAQ;EAAQC,SAAS;EAAO,CAAA;CAChEC,2CAAyBhB,mDAAAA;CAEjC,MAAMiB,QAAQC,SAAqC;AACjD,MAAIA,QAAQd,QACV,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBI,kBAAkBF,QAAQd,QAAO,CAAA;MAEtE,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBK,mBAAiB,CAAA"}
|
package/lib/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_command_decorator = require('./command.decorator-HziankUv.cjs');
|
|
2
|
-
const require_help_command_token = require('./help-command.token-
|
|
2
|
+
const require_help_command_token = require('./help-command.token-mlwEyWij.cjs');
|
|
3
3
|
const require_cli_module_decorator = require('./cli-module.decorator-CXt38aqF.cjs');
|
|
4
4
|
let _navios_core = require("@navios/core");
|
|
5
5
|
let zod_v4 = require("zod/v4");
|
|
@@ -623,12 +623,41 @@ var CliParserService = class {
|
|
|
623
623
|
if (equalIndex !== -1) {
|
|
624
624
|
const optionName = key.slice(0, equalIndex);
|
|
625
625
|
const optionValue = key.slice(equalIndex + 1);
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
if (
|
|
629
|
-
|
|
630
|
-
|
|
626
|
+
if (this.isObjectNotation(optionName)) {
|
|
627
|
+
const processedPath = this.processObjectNotationKey(optionName);
|
|
628
|
+
if (optionsSchema ? this.isNestedArray(optionsSchema, processedPath) : false) {
|
|
629
|
+
const existingValue = this.getNestedProperty(options, processedPath);
|
|
630
|
+
if (!Array.isArray(existingValue)) this.setNestedProperty(options, processedPath, []);
|
|
631
|
+
this.getNestedProperty(options, processedPath).push(this.parseValue(optionValue));
|
|
632
|
+
} else this.setNestedProperty(options, processedPath, this.parseValue(optionValue));
|
|
633
|
+
} else {
|
|
634
|
+
const camelCaseKey = this.camelCase(optionName);
|
|
635
|
+
if (arrayFields.has(camelCaseKey) || arrayFields.has(optionName)) {
|
|
636
|
+
if (!options[camelCaseKey]) options[camelCaseKey] = [];
|
|
637
|
+
options[camelCaseKey].push(this.parseValue(optionValue));
|
|
638
|
+
} else options[camelCaseKey] = this.parseValue(optionValue);
|
|
639
|
+
}
|
|
631
640
|
i++;
|
|
641
|
+
} else if (this.isObjectNotation(key)) {
|
|
642
|
+
const processedPath = this.processObjectNotationKey(key);
|
|
643
|
+
const isBoolean = optionsSchema ? this.isNestedBoolean(optionsSchema, processedPath) : false;
|
|
644
|
+
const isArray = optionsSchema ? this.isNestedArray(optionsSchema, processedPath) : false;
|
|
645
|
+
const nextArg = args[i + 1];
|
|
646
|
+
if (isBoolean) {
|
|
647
|
+
this.setNestedProperty(options, processedPath, true);
|
|
648
|
+
i++;
|
|
649
|
+
} else if (isArray && nextArg && !nextArg.startsWith("-")) {
|
|
650
|
+
const existingValue = this.getNestedProperty(options, processedPath);
|
|
651
|
+
if (!Array.isArray(existingValue)) this.setNestedProperty(options, processedPath, []);
|
|
652
|
+
this.getNestedProperty(options, processedPath).push(this.parseValue(nextArg));
|
|
653
|
+
i += 2;
|
|
654
|
+
} else if (nextArg && !nextArg.startsWith("-")) {
|
|
655
|
+
this.setNestedProperty(options, processedPath, this.parseValue(nextArg));
|
|
656
|
+
i += 2;
|
|
657
|
+
} else {
|
|
658
|
+
this.setNestedProperty(options, processedPath, true);
|
|
659
|
+
i++;
|
|
660
|
+
}
|
|
632
661
|
} else {
|
|
633
662
|
const camelCaseKey = this.camelCase(key);
|
|
634
663
|
const isBoolean = booleanFields.has(camelCaseKey) || booleanFields.has(key);
|
|
@@ -767,6 +796,80 @@ var CliParserService = class {
|
|
|
767
796
|
return false;
|
|
768
797
|
}
|
|
769
798
|
}
|
|
799
|
+
/**
|
|
800
|
+
* Sets a nested property on an object using dot notation path.
|
|
801
|
+
* Creates intermediate objects as needed.
|
|
802
|
+
*
|
|
803
|
+
* @example
|
|
804
|
+
* setNestedProperty({}, 'a.b.c', 'value') // { a: { b: { c: 'value' } } }
|
|
805
|
+
*/ setNestedProperty(obj, path, value) {
|
|
806
|
+
const parts = path.split(".");
|
|
807
|
+
let current = obj;
|
|
808
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
809
|
+
const part = parts[i];
|
|
810
|
+
if (!(part in current) || typeof current[part] !== "object" || current[part] === null) current[part] = {};
|
|
811
|
+
current = current[part];
|
|
812
|
+
}
|
|
813
|
+
current[parts[parts.length - 1]] = value;
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Gets a nested property from an object using dot notation path.
|
|
817
|
+
* Returns undefined if path doesn't exist.
|
|
818
|
+
*/ getNestedProperty(obj, path) {
|
|
819
|
+
const parts = path.split(".");
|
|
820
|
+
let current = obj;
|
|
821
|
+
for (const part of parts) {
|
|
822
|
+
if (current === void 0 || current === null || typeof current !== "object") return;
|
|
823
|
+
current = current[part];
|
|
824
|
+
}
|
|
825
|
+
return current;
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Checks if an option key contains dot notation (object notation).
|
|
829
|
+
* Returns true for keys like "obj.field" or "deep.nested.value".
|
|
830
|
+
*/ isObjectNotation(key) {
|
|
831
|
+
return key.includes(".");
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Processes an option key that may contain object notation.
|
|
835
|
+
* Converts each segment from kebab-case to camelCase.
|
|
836
|
+
*
|
|
837
|
+
* @example
|
|
838
|
+
* processObjectNotationKey('my-obj.field-name') // 'myObj.fieldName'
|
|
839
|
+
*/ processObjectNotationKey(key) {
|
|
840
|
+
return key.split(".").map((segment) => this.camelCase(segment)).join(".");
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Gets the nested schema for a given dot-notation path.
|
|
844
|
+
* Returns undefined if the path doesn't lead to a valid schema.
|
|
845
|
+
*/ getNestedSchema(schema, path) {
|
|
846
|
+
try {
|
|
847
|
+
const parts = path.split(".");
|
|
848
|
+
let currentSchema = schema;
|
|
849
|
+
for (const part of parts) {
|
|
850
|
+
while (currentSchema?.def?.type === "optional" || currentSchema?.def?.type === "default") currentSchema = currentSchema.def.innerType;
|
|
851
|
+
if (currentSchema?.def?.type !== "object") return;
|
|
852
|
+
const shape = currentSchema.def.shape;
|
|
853
|
+
if (!shape || !(part in shape)) return;
|
|
854
|
+
currentSchema = shape[part];
|
|
855
|
+
}
|
|
856
|
+
return currentSchema;
|
|
857
|
+
} catch {
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Checks if a nested path represents a boolean field in the schema.
|
|
863
|
+
*/ isNestedBoolean(schema, path) {
|
|
864
|
+
const nestedSchema = this.getNestedSchema(schema, path);
|
|
865
|
+
return nestedSchema ? this.isSchemaBoolean(nestedSchema) : false;
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Checks if a nested path represents an array field in the schema.
|
|
869
|
+
*/ isNestedArray(schema, path) {
|
|
870
|
+
const nestedSchema = this.getNestedSchema(schema, path);
|
|
871
|
+
return nestedSchema ? this.isSchemaArray(nestedSchema) : false;
|
|
872
|
+
}
|
|
770
873
|
static {
|
|
771
874
|
_initClass$1();
|
|
772
875
|
}
|
|
@@ -799,13 +902,15 @@ var CliParserService = class {
|
|
|
799
902
|
command;
|
|
800
903
|
commandPath;
|
|
801
904
|
options;
|
|
905
|
+
positionals;
|
|
802
906
|
/**
|
|
803
907
|
* @internal
|
|
804
908
|
* Creates a new execution context.
|
|
805
|
-
*/ constructor(command, commandPath, options) {
|
|
909
|
+
*/ constructor(command, commandPath, options, positionals = []) {
|
|
806
910
|
this.command = command;
|
|
807
911
|
this.commandPath = commandPath;
|
|
808
912
|
this.options = options;
|
|
913
|
+
this.positionals = positionals;
|
|
809
914
|
}
|
|
810
915
|
/**
|
|
811
916
|
* Gets the command metadata.
|
|
@@ -830,6 +935,16 @@ var CliParserService = class {
|
|
|
830
935
|
*/ getOptions() {
|
|
831
936
|
return this.options;
|
|
832
937
|
}
|
|
938
|
+
/**
|
|
939
|
+
* Gets the positional arguments.
|
|
940
|
+
*
|
|
941
|
+
* Positional arguments are values that don't match any option flags.
|
|
942
|
+
* For example, in `copy --force source.txt dest.txt`, the positionals are `['source.txt', 'dest.txt']`.
|
|
943
|
+
*
|
|
944
|
+
* @returns The positional arguments array
|
|
945
|
+
*/ getPositionals() {
|
|
946
|
+
return this.positionals;
|
|
947
|
+
}
|
|
833
948
|
};
|
|
834
949
|
|
|
835
950
|
//#endregion
|
|
@@ -1214,7 +1329,7 @@ var CommanderAdapterService = class {
|
|
|
1214
1329
|
}
|
|
1215
1330
|
const command = this.commandRegistry.getByPath(preliminaryParse.command);
|
|
1216
1331
|
const parsed = command?.metadata.optionsSchema ? this.cliParser.parse(argv, command.metadata.optionsSchema) : preliminaryParse;
|
|
1217
|
-
await this.executeCommand(parsed.command, parsed.options);
|
|
1332
|
+
await this.executeCommand(parsed.command, parsed.options, parsed.positionals);
|
|
1218
1333
|
} catch (error) {
|
|
1219
1334
|
if (error instanceof Error) {
|
|
1220
1335
|
this.logger.error(`Error: ${error.message}`);
|
|
@@ -1228,20 +1343,20 @@ var CommanderAdapterService = class {
|
|
|
1228
1343
|
}
|
|
1229
1344
|
/**
|
|
1230
1345
|
* Execute a command programmatically with the provided options.
|
|
1231
|
-
*/ async executeCommand(path, options = {}) {
|
|
1346
|
+
*/ async executeCommand(path, options = {}, positionals = []) {
|
|
1232
1347
|
const command = this.commandRegistry.getByPath(path);
|
|
1233
1348
|
if (!command) throw new Error(`[Navios Commander] Command not found: ${path}`);
|
|
1234
1349
|
const { class: commandClass, metadata } = command;
|
|
1235
1350
|
let validatedOptions = options;
|
|
1236
1351
|
if (metadata.optionsSchema) validatedOptions = metadata.optionsSchema.parse(options);
|
|
1237
|
-
const executionContext = new CommanderExecutionContext(metadata, path, validatedOptions);
|
|
1352
|
+
const executionContext = new CommanderExecutionContext(metadata, path, validatedOptions, positionals);
|
|
1238
1353
|
const requestId = `cmd-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
1239
1354
|
const scopeContainer = this.container.beginRequest(requestId);
|
|
1240
1355
|
scopeContainer.addInstance(CommandExecutionContext, executionContext);
|
|
1241
1356
|
try {
|
|
1242
1357
|
const commandInstance = await scopeContainer.get(commandClass);
|
|
1243
1358
|
if (!commandInstance.execute) throw new Error(`Command ${path} does not implement execute method`);
|
|
1244
|
-
await commandInstance.execute(validatedOptions);
|
|
1359
|
+
await commandInstance.execute(validatedOptions, positionals);
|
|
1245
1360
|
} finally {
|
|
1246
1361
|
await scopeContainer.endRequest();
|
|
1247
1362
|
}
|
|
@@ -1360,7 +1475,7 @@ function dynamicImport(modulePath) {
|
|
|
1360
1475
|
}
|
|
1361
1476
|
const { overrideConsoleLogger, ScreenManager } = tuiModule;
|
|
1362
1477
|
overrideConsoleLogger(options.tuiOptions?.hideDefaultScreen ?? false);
|
|
1363
|
-
if (options.tuiOptions?.hideDefaultScreen) await Promise.resolve().then(() => require("./help.command-
|
|
1478
|
+
if (options.tuiOptions?.hideDefaultScreen) await Promise.resolve().then(() => require("./help.command-knivRhJz.cjs"));
|
|
1364
1479
|
const app = await _navios_core.NaviosFactory.create(appModule, {
|
|
1365
1480
|
adapter: defineCliEnvironment(),
|
|
1366
1481
|
logger: options.logLevels
|