@navios/commander 1.5.1 → 1.6.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.
Files changed (35) hide show
  1. package/.turbo/turbo-build.log +48 -49
  2. package/.turbo/turbo-check.log +0 -2
  3. package/.turbo/turbo-lint.log +2 -3
  4. package/.turbo/turbo-test$colon$ci.log +109 -117
  5. package/.turbo/turbo-test.log +107 -0
  6. package/CHANGELOG.md +12 -0
  7. package/dist/src/interfaces/command-handler.interface.d.mts +7 -3
  8. package/dist/src/interfaces/command-handler.interface.d.mts.map +1 -1
  9. package/dist/src/interfaces/commander-execution-context.interface.d.mts +11 -1
  10. package/dist/src/interfaces/commander-execution-context.interface.d.mts.map +1 -1
  11. package/dist/src/services/commander-adapter.service.d.mts +5 -1
  12. package/dist/src/services/commander-adapter.service.d.mts.map +1 -1
  13. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  14. package/dist/tsconfig.tsbuildinfo +1 -1
  15. package/lib/{cli-module.decorator-BzsOEMPH.d.cts → cli-module.decorator-BV3vVKlR.d.cts} +8 -4
  16. package/lib/cli-module.decorator-BV3vVKlR.d.cts.map +1 -0
  17. package/lib/{cli-module.decorator-CCV_elPP.d.mts → cli-module.decorator-DDlgpTgI.d.mts} +19 -5
  18. package/lib/cli-module.decorator-DDlgpTgI.d.mts.map +1 -0
  19. package/lib/index.cjs +17 -5
  20. package/lib/index.cjs.map +1 -1
  21. package/lib/index.d.cts +13 -3
  22. package/lib/index.d.cts.map +1 -1
  23. package/lib/index.d.mts +2 -2
  24. package/lib/index.d.mts.map +1 -1
  25. package/lib/index.mjs +17 -5
  26. package/lib/index.mjs.map +1 -1
  27. package/lib/legacy-compat/index.d.cts +1 -1
  28. package/lib/legacy-compat/index.d.mts +1 -1
  29. package/package.json +2 -2
  30. package/src/__tests__/commander.factory.e2e.spec.mts +105 -13
  31. package/src/interfaces/command-handler.interface.mts +7 -3
  32. package/src/interfaces/commander-execution-context.interface.mts +13 -0
  33. package/src/services/commander-adapter.service.mts +13 -4
  34. package/lib/cli-module.decorator-BzsOEMPH.d.cts.map +0 -1
  35. package/lib/cli-module.decorator-CCV_elPP.d.mts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navios/commander",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "Oleksandr Hanzha",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "@navios/builder": "^1.0.0",
53
- "@navios/commander-tui": "1.5.1",
53
+ "@navios/commander-tui": "1.6.1",
54
54
  "tsx": "^4.21.0",
55
55
  "typescript": "^5.9.3",
56
56
  "zod": "^4.3.5"
@@ -1,9 +1,11 @@
1
+ import { inject } from '@navios/core'
1
2
  import { beforeEach, describe, expect, it, vi } from 'vitest'
2
3
  import { z } from 'zod/v4'
3
4
 
4
5
  import { CommanderFactory } from '../commander.factory.mjs'
5
6
  import { CliModule } from '../decorators/cli-module.decorator.mjs'
6
7
  import { Command } from '../decorators/command.decorator.mjs'
8
+ import { CommandExecutionContext } from '../tokens/index.mjs'
7
9
 
8
10
  import type { CommandHandler } from '../interfaces/command-handler.interface.mjs'
9
11
 
@@ -573,44 +575,134 @@ describe('CommanderApplication E2E - run() with different argv', () => {
573
575
 
574
576
  @Command({ path: 'copy', optionsSchema })
575
577
  class CopyCommand implements CommandHandler<z.infer<typeof optionsSchema>> {
576
- async execute(options: z.infer<typeof optionsSchema>) {
577
- executeMock(options)
578
+ async execute(options: z.infer<typeof optionsSchema>, positionals?: string[]) {
579
+ executeMock(options, positionals)
580
+ }
581
+ }
582
+
583
+ const noOptionsMock = vi.fn()
584
+
585
+ @Command({ path: 'ping' })
586
+ class PingCommand implements CommandHandler {
587
+ async execute(_options: unknown, positionals?: string[]) {
588
+ noOptionsMock(positionals)
578
589
  }
579
590
  }
580
591
 
581
592
  @CliModule({
582
- commands: [CopyCommand],
593
+ commands: [CopyCommand, PingCommand],
583
594
  })
584
595
  class TestModule {}
585
596
 
586
597
  beforeEach(() => {
587
598
  executeMock.mockClear()
599
+ noOptionsMock.mockClear()
588
600
  })
589
601
 
590
- it('should parse command with options only', async () => {
602
+ it('should pass empty positionals for command without options', async () => {
591
603
  const app = await CommanderFactory.create(TestModule)
592
604
  await app.init()
593
605
 
594
606
  const adapter = app.getAdapter()
595
- await adapter.run(['node', 'script.js', 'copy', '--force'])
607
+ await adapter.run(['node', 'script.js', 'ping'])
596
608
 
597
- expect(executeMock).toHaveBeenCalledWith({
598
- force: true,
599
- })
609
+ expect(noOptionsMock).toHaveBeenCalledWith([])
600
610
  await app.close()
601
611
  })
602
612
 
603
- it('should parse command with mixed options and positionals', async () => {
613
+ it('should parse command with options only and empty positionals', async () => {
604
614
  const app = await CommanderFactory.create(TestModule)
605
615
  await app.init()
606
616
 
607
617
  const adapter = app.getAdapter()
608
- // Note: positionals are not extracted in this test, but the command should still execute
609
618
  await adapter.run(['node', 'script.js', 'copy', '--force'])
610
619
 
611
- expect(executeMock).toHaveBeenCalledWith({
612
- force: true,
613
- })
620
+ expect(executeMock).toHaveBeenCalledWith({ force: true }, [])
621
+ await app.close()
622
+ })
623
+
624
+ it('should pass positionals as second argument to execute', async () => {
625
+ const app = await CommanderFactory.create(TestModule)
626
+ await app.init()
627
+
628
+ const adapter = app.getAdapter()
629
+ // Positionals must come after at least one option because the parser
630
+ // collects command words until it hits an argument starting with '-'
631
+ await adapter.run(['node', 'script.js', 'copy', '--force', 'source.txt', 'dest.txt'])
632
+
633
+ expect(executeMock).toHaveBeenCalledWith({ force: true }, ['source.txt', 'dest.txt'])
634
+ await app.close()
635
+ })
636
+
637
+ it('should pass multiple positionals after options', async () => {
638
+ const app = await CommanderFactory.create(TestModule)
639
+ await app.init()
640
+
641
+ const adapter = app.getAdapter()
642
+ await adapter.run([
643
+ 'node',
644
+ 'script.js',
645
+ 'copy',
646
+ '--force',
647
+ 'file1.txt',
648
+ 'file2.txt',
649
+ 'file3.txt',
650
+ ])
651
+
652
+ expect(executeMock).toHaveBeenCalledWith({ force: true }, [
653
+ 'file1.txt',
654
+ 'file2.txt',
655
+ 'file3.txt',
656
+ ])
657
+ await app.close()
658
+ })
659
+ })
660
+
661
+ describe('positionals via execution context', () => {
662
+ const contextMock = vi.fn()
663
+
664
+ const processSchema = z.object({
665
+ verbose: z.boolean().optional().default(false),
666
+ })
667
+
668
+ @Command({ path: 'process', optionsSchema: processSchema })
669
+ class ProcessCommand implements CommandHandler<z.infer<typeof processSchema>> {
670
+ private ctx = inject(CommandExecutionContext)
671
+
672
+ async execute() {
673
+ contextMock(this.ctx.getPositionals())
674
+ }
675
+ }
676
+
677
+ @CliModule({
678
+ commands: [ProcessCommand],
679
+ })
680
+ class ContextTestModule {}
681
+
682
+ beforeEach(() => {
683
+ contextMock.mockClear()
684
+ })
685
+
686
+ it('should access positionals via CommandExecutionContext', async () => {
687
+ const app = await CommanderFactory.create(ContextTestModule)
688
+ await app.init()
689
+
690
+ const adapter = app.getAdapter()
691
+ // Positionals must come after at least one option
692
+ await adapter.run(['node', 'script.js', 'process', '--verbose', 'file1.txt', 'file2.txt'])
693
+
694
+ expect(contextMock).toHaveBeenCalledWith(['file1.txt', 'file2.txt'])
695
+ await app.close()
696
+ })
697
+
698
+ it('should return empty array when no positionals via context', async () => {
699
+ const app = await CommanderFactory.create(ContextTestModule)
700
+ await app.init()
701
+
702
+ const adapter = app.getAdapter()
703
+ await adapter.run(['node', 'script.js', 'process', '--verbose'])
704
+
705
+ expect(contextMock).toHaveBeenCalledWith([])
614
706
  await app.close()
615
707
  })
616
708
  })
@@ -19,18 +19,22 @@
19
19
  *
20
20
  * @Command({ path: 'greet', optionsSchema })
21
21
  * export class GreetCommand implements CommandHandler<Options> {
22
- * async execute(options: Options) {
22
+ * async execute(options: Options, positionals?: string[]) {
23
23
  * console.log(`Hello, ${options.name}!`)
24
+ * if (positionals?.length) {
25
+ * console.log(`Files: ${positionals.join(', ')}`)
26
+ * }
24
27
  * }
25
28
  * }
26
29
  * ```
27
30
  */
28
31
  export interface CommandHandler<TOptions = any> {
29
32
  /**
30
- * Executes the command with the provided options.
33
+ * Executes the command with the provided options and positional arguments.
31
34
  *
32
35
  * @param options - The validated command options (validated against the command's schema if provided)
36
+ * @param positionals - Positional arguments that don't match any option flags
33
37
  * @returns A promise or void
34
38
  */
35
- execute(options: TOptions): void | Promise<void>
39
+ execute(options: TOptions, positionals?: string[]): void | Promise<void>
36
40
  }
@@ -31,6 +31,7 @@ export class CommanderExecutionContext {
31
31
  private readonly command: CommandMetadata,
32
32
  private readonly commandPath: string,
33
33
  private readonly options: any,
34
+ private readonly positionals: string[] = [],
34
35
  ) {}
35
36
 
36
37
  /**
@@ -61,4 +62,16 @@ export class CommanderExecutionContext {
61
62
  getOptions(): any {
62
63
  return this.options
63
64
  }
65
+
66
+ /**
67
+ * Gets the positional arguments.
68
+ *
69
+ * Positional arguments are values that don't match any option flags.
70
+ * For example, in `copy --force source.txt dest.txt`, the positionals are `['source.txt', 'dest.txt']`.
71
+ *
72
+ * @returns The positional arguments array
73
+ */
74
+ getPositionals(): string[] {
75
+ return this.positionals
76
+ }
64
77
  }
@@ -130,7 +130,7 @@ export class CommanderAdapterService implements AbstractCliAdapterInterface {
130
130
  ? this.cliParser.parse(argv, command.metadata.optionsSchema)
131
131
  : preliminaryParse
132
132
 
133
- await this.executeCommand(parsed.command, parsed.options)
133
+ await this.executeCommand(parsed.command, parsed.options, parsed.positionals)
134
134
  } catch (error) {
135
135
  if (error instanceof Error) {
136
136
  this.logger.error(`Error: ${error.message}`)
@@ -146,7 +146,11 @@ export class CommanderAdapterService implements AbstractCliAdapterInterface {
146
146
  /**
147
147
  * Execute a command programmatically with the provided options.
148
148
  */
149
- async executeCommand(path: string, options: Record<string, unknown> = {}): Promise<void> {
149
+ async executeCommand(
150
+ path: string,
151
+ options: Record<string, unknown> = {},
152
+ positionals: string[] = [],
153
+ ): Promise<void> {
150
154
  const command = this.commandRegistry.getByPath(path)
151
155
  if (!command) {
152
156
  throw new Error(`[Navios Commander] Command not found: ${path}`)
@@ -161,7 +165,12 @@ export class CommanderAdapterService implements AbstractCliAdapterInterface {
161
165
  }
162
166
 
163
167
  // Create execution context
164
- const executionContext = new CommanderExecutionContext(metadata, path, validatedOptions)
168
+ const executionContext = new CommanderExecutionContext(
169
+ metadata,
170
+ path,
171
+ validatedOptions,
172
+ positionals,
173
+ )
165
174
 
166
175
  // Begin request scope
167
176
  const requestId = `cmd-${Date.now()}-${Math.random().toString(36).substring(7)}`
@@ -177,7 +186,7 @@ export class CommanderAdapterService implements AbstractCliAdapterInterface {
177
186
  throw new Error(`Command ${path} does not implement execute method`)
178
187
  }
179
188
 
180
- await commandInstance.execute(validatedOptions)
189
+ await commandInstance.execute(validatedOptions, positionals)
181
190
  } finally {
182
191
  await scopeContainer.endRequest()
183
192
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli-module.decorator-BzsOEMPH.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) {\n * console.log(`Hello, ${options.name}!`)\n * }\n * }\n * ```\n */\nexport interface CommandHandler<TOptions = any> {\n /**\n * Executes the command with the provided options.\n *\n * @param options - The validated command options (validated against the command's schema if provided)\n * @returns A promise or void\n */\n execute(options: TOptions): 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":";;;;;;;;;AA2BA;;;;AChBA;;;;;;;AA8DA;;;;;;;;;;;;UD9CiBA;;AErBjB;;;;;EAUkCmB,OAAAA,CAAAA,OAAAA,EFkBflB,QElBekB,CAAAA,EAAAA,IAAAA,GFkBGjB,OElBHiB,CAAAA,IAAAA,CAAAA;;;;;;ADLlC;;;AAKUhB,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;;;;;;ADvDX;;UErBiBG,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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli-module.decorator-CCV_elPP.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) {\n * console.log(`Hello, ${options.name}!`)\n * }\n * }\n * ```\n */\nexport interface CommandHandler<TOptions = any> {\n /**\n * Executes the command with the provided options.\n *\n * @param options - The validated command options (validated against the command's schema if provided)\n * @returns A promise or void\n */\n execute(options: TOptions): 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 /**\n * @internal\n * Creates a new execution context.\n */\n constructor(command: CommandMetadata, commandPath: string, options: any)\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//# 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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"}