@navios/commander 0.5.1 → 0.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +56 -8
  3. package/dist/src/commander.application.d.mts +124 -6
  4. package/dist/src/commander.application.d.mts.map +1 -1
  5. package/dist/src/commander.factory.d.mts +31 -3
  6. package/dist/src/commander.factory.d.mts.map +1 -1
  7. package/dist/src/decorators/cli-module.decorator.d.mts +36 -1
  8. package/dist/src/decorators/cli-module.decorator.d.mts.map +1 -1
  9. package/dist/src/decorators/command.decorator.d.mts +44 -1
  10. package/dist/src/decorators/command.decorator.d.mts.map +1 -1
  11. package/dist/src/index.d.mts +2 -1
  12. package/dist/src/index.d.mts.map +1 -1
  13. package/dist/src/interfaces/command-handler.interface.d.mts +33 -0
  14. package/dist/src/interfaces/command-handler.interface.d.mts.map +1 -1
  15. package/dist/src/interfaces/commander-execution-context.interface.d.mts +54 -0
  16. package/dist/src/interfaces/commander-execution-context.interface.d.mts.map +1 -0
  17. package/dist/src/interfaces/index.d.mts +1 -1
  18. package/dist/src/interfaces/index.d.mts.map +1 -1
  19. package/dist/src/interfaces/module.interface.d.mts +1 -4
  20. package/dist/src/interfaces/module.interface.d.mts.map +1 -1
  21. package/dist/src/metadata/cli-module.metadata.d.mts +46 -1
  22. package/dist/src/metadata/cli-module.metadata.d.mts.map +1 -1
  23. package/dist/src/metadata/command.metadata.d.mts +48 -1
  24. package/dist/src/metadata/command.metadata.d.mts.map +1 -1
  25. package/dist/src/services/cli-parser.service.d.mts +32 -1
  26. package/dist/src/services/cli-parser.service.d.mts.map +1 -1
  27. package/dist/src/services/module-loader.service.d.mts +44 -5
  28. package/dist/src/services/module-loader.service.d.mts.map +1 -1
  29. package/dist/src/tokens/execution-context.token.d.mts +27 -0
  30. package/dist/src/tokens/execution-context.token.d.mts.map +1 -0
  31. package/dist/src/tokens/index.d.mts +2 -0
  32. package/dist/src/tokens/index.d.mts.map +1 -0
  33. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  34. package/dist/tsconfig.tsbuildinfo +1 -1
  35. package/dist/tsdown.config.d.mts +3 -0
  36. package/dist/tsdown.config.d.mts.map +1 -0
  37. package/lib/index.cjs +7721 -0
  38. package/lib/index.cjs.map +1 -0
  39. package/lib/index.d.cts +670 -0
  40. package/lib/index.d.cts.map +1 -0
  41. package/lib/index.d.mts +670 -98
  42. package/lib/index.d.mts.map +1 -0
  43. package/lib/index.mjs +7511 -565
  44. package/lib/index.mjs.map +1 -1
  45. package/package.json +5 -5
  46. package/project.json +2 -2
  47. package/src/commander.application.mts +161 -17
  48. package/src/commander.factory.mts +32 -4
  49. package/src/decorators/cli-module.decorator.mts +37 -2
  50. package/src/decorators/command.decorator.mts +45 -2
  51. package/src/index.mts +5 -1
  52. package/src/interfaces/command-handler.interface.mts +33 -0
  53. package/src/interfaces/commander-execution-context.interface.mts +64 -0
  54. package/src/interfaces/index.mts +1 -1
  55. package/src/metadata/cli-module.metadata.mts +48 -7
  56. package/src/metadata/command.metadata.mts +48 -1
  57. package/src/services/__tests__/cli-parser.service.spec.mts +15 -11
  58. package/src/services/cli-parser.service.mts +35 -3
  59. package/src/services/module-loader.service.mts +45 -6
  60. package/src/tokens/execution-context.token.mts +34 -0
  61. package/src/tokens/index.mts +1 -0
  62. package/tsdown.config.mts +33 -0
  63. package/lib/_tsup-dts-rollup.d.mts +0 -466
  64. package/lib/_tsup-dts-rollup.d.ts +0 -466
  65. package/lib/index.d.ts +0 -98
  66. package/lib/index.js +0 -604
  67. package/lib/index.js.map +0 -1
  68. package/src/interfaces/module.interface.mts +0 -4
  69. package/tsup.config.mts +0 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navios/commander",
3
- "version": "0.5.1",
3
+ "version": "0.7.0",
4
4
  "author": {
5
5
  "name": "Oleksandr Hanzha",
6
6
  "email": "alex@granted.name"
@@ -30,11 +30,11 @@
30
30
  }
31
31
  },
32
32
  "devDependencies": {
33
- "tsx": "^4.20.5",
34
- "typescript": "^5.9.2",
35
- "zod": "^4.1.8"
33
+ "tsx": "^4.21.0",
34
+ "typescript": "^5.9.3",
35
+ "zod": "^4.1.13"
36
36
  },
37
37
  "dependencies": {
38
- "@navios/di": "^0.4.2"
38
+ "@navios/di": "^0.6.0"
39
39
  }
40
40
  }
package/project.json CHANGED
@@ -38,11 +38,11 @@
38
38
  },
39
39
  "build": {
40
40
  "executor": "nx:run-commands",
41
- "inputs": ["projectSources", "{projectRoot}/tsup.config.mts"],
41
+ "inputs": ["projectSources", "{projectRoot}/tsdown.config.mts"],
42
42
  "outputs": ["{projectRoot}/lib"],
43
43
  "dependsOn": ["check", "test:ci", "lint"],
44
44
  "options": {
45
- "command": "tsup",
45
+ "command": "tsdown",
46
46
  "cwd": "packages/commander"
47
47
  }
48
48
  },
@@ -1,36 +1,94 @@
1
- import type { ClassTypeWithInstance, InjectionToken } from '@navios/di'
1
+ import type {
2
+ ClassTypeWithInstance,
3
+ InjectionToken,
4
+ NaviosModule,
5
+ } from '@navios/core'
2
6
 
3
- import { Container, inject, Injectable } from '@navios/di'
7
+ import { Container, inject, Injectable } from '@navios/core'
4
8
 
5
- import type { CommandHandler, Module } from './interfaces/index.mjs'
9
+ import type { CommandHandler } from './interfaces/index.mjs'
6
10
 
7
- import { CliParserService, ModuleLoaderService } from './services/index.mjs'
11
+ import { CommanderExecutionContext } from './interfaces/index.mjs'
12
+ import { CliModuleLoaderService, CliParserService } from './services/index.mjs'
13
+ import { CommandExecutionContext } from './tokens/index.mjs'
8
14
 
15
+ /**
16
+ * Configuration options for CommanderApplication.
17
+ *
18
+ * @public
19
+ */
9
20
  export interface CommanderApplicationOptions {}
10
21
 
22
+ /**
23
+ * Main application class for managing CLI command execution.
24
+ *
25
+ * This class handles module loading, command registration, and command execution.
26
+ * It provides both programmatic and CLI-based command execution capabilities.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const app = await CommanderFactory.create(AppModule)
31
+ * await app.init()
32
+ * await app.run(process.argv)
33
+ * ```
34
+ */
11
35
  @Injectable()
12
36
  export class CommanderApplication {
13
- private moduleLoader = inject(ModuleLoaderService)
37
+ private moduleLoader = inject(CliModuleLoaderService)
14
38
  private cliParser = inject(CliParserService)
15
39
  protected container = inject(Container)
16
40
 
17
- private appModule: ClassTypeWithInstance<Module> | null = null
41
+ private appModule: ClassTypeWithInstance<NaviosModule> | null = null
18
42
  private options: CommanderApplicationOptions = {}
19
43
 
44
+ /**
45
+ * Indicates whether the application has been initialized.
46
+ * Set to `true` after `init()` is called successfully.
47
+ */
20
48
  isInitialized = false
21
49
 
50
+ /**
51
+ * @internal
52
+ * Sets up the application with the provided module and options.
53
+ * This is called automatically by CommanderFactory.create().
54
+ */
22
55
  async setup(
23
- appModule: ClassTypeWithInstance<Module>,
56
+ appModule: ClassTypeWithInstance<NaviosModule>,
24
57
  options: CommanderApplicationOptions = {},
25
58
  ) {
26
59
  this.appModule = appModule
27
60
  this.options = options
28
61
  }
29
62
 
63
+ /**
64
+ * Gets the dependency injection container used by this application.
65
+ *
66
+ * @returns The Container instance
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const container = app.getContainer()
71
+ * const service = await container.get(MyService)
72
+ * ```
73
+ */
30
74
  getContainer() {
31
75
  return this.container
32
76
  }
33
77
 
78
+ /**
79
+ * Initializes the application by loading all modules and registering commands.
80
+ *
81
+ * This method must be called before executing commands or running the CLI.
82
+ * It traverses the module tree, loads all imported modules, and collects command metadata.
83
+ *
84
+ * @throws {Error} If the app module is not set (setup() was not called)
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * const app = await CommanderFactory.create(AppModule)
89
+ * await app.init() // Must be called before run() or executeCommand()
90
+ * ```
91
+ */
34
92
  async init() {
35
93
  if (!this.appModule) {
36
94
  throw new Error(
@@ -41,6 +99,27 @@ export class CommanderApplication {
41
99
  this.isInitialized = true
42
100
  }
43
101
 
102
+ /**
103
+ * Executes a command programmatically with the provided options.
104
+ *
105
+ * This method is useful for testing, automation, or programmatic workflows.
106
+ * The options will be validated against the command's Zod schema if one is provided.
107
+ *
108
+ * @param commandPath - The command path (e.g., 'greet', 'user:create')
109
+ * @param options - The command options object (will be validated if schema exists)
110
+ * @throws {Error} If the application is not initialized
111
+ * @throws {Error} If the command is not found
112
+ * @throws {Error} If the command does not implement the execute method
113
+ * @throws {ZodError} If options validation fails
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * await app.executeCommand('greet', {
118
+ * name: 'World',
119
+ * greeting: 'Hi'
120
+ * })
121
+ * ```
122
+ */
44
123
  async executeCommand(commandPath: string, options: any = {}) {
45
124
  if (!this.isInitialized) {
46
125
  throw new Error(
@@ -63,20 +142,52 @@ export class CommanderApplication {
63
142
  validatedOptions = metadata.optionsSchema.parse(options)
64
143
  }
65
144
 
66
- // Get command instance and execute
67
- const commandInstance = await this.container.get<CommandHandler>(
68
- commandClass as unknown as InjectionToken<CommandHandler>,
145
+ // Create execution context and provide it to the container
146
+ const executionContext = new CommanderExecutionContext(
147
+ metadata,
148
+ commandPath,
149
+ validatedOptions,
69
150
  )
70
151
 
71
- if (!commandInstance.execute) {
72
- throw new Error(
73
- `[Navios Commander] Command ${commandPath} does not implement execute method`,
152
+ // Generate a unique request ID for this command execution
153
+ const requestId = `cmd-${Date.now()}-${Math.random().toString(36).substring(7)}`
154
+
155
+ // Begin request context and add ExecutionContext
156
+ const scopeContainer = this.container.beginRequest(requestId)
157
+ scopeContainer.addInstance(CommandExecutionContext, executionContext)
158
+
159
+ try {
160
+ // Get command instance and execute
161
+ const commandInstance = await scopeContainer.get<CommandHandler>(
162
+ commandClass as unknown as InjectionToken<CommandHandler>,
74
163
  )
75
- }
76
164
 
77
- await commandInstance.execute(validatedOptions)
165
+ if (!commandInstance.execute) {
166
+ throw new Error(
167
+ `[Navios Commander] Command ${commandPath} does not implement execute method`,
168
+ )
169
+ }
170
+
171
+ await commandInstance.execute(validatedOptions)
172
+ } finally {
173
+ // Clean up request context
174
+ await scopeContainer.endRequest()
175
+ }
78
176
  }
79
177
 
178
+ /**
179
+ * Gets all registered commands with their paths and class references.
180
+ *
181
+ * @returns An array of objects containing the command path and class
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * const commands = app.getAllCommands()
186
+ * commands.forEach(({ path }) => {
187
+ * console.log(`Available: ${path}`)
188
+ * })
189
+ * ```
190
+ */
80
191
  getAllCommands() {
81
192
  // Use pre-collected command metadata from module loading
82
193
  const commandsMap = this.moduleLoader.getAllCommandsWithMetadata()
@@ -96,8 +207,26 @@ export class CommanderApplication {
96
207
  }
97
208
 
98
209
  /**
99
- * Runs the CLI application by parsing process.argv and executing the command
100
- * @param argv - Command-line arguments (defaults to process.argv)
210
+ * Runs the CLI application by parsing command-line arguments and executing the appropriate command.
211
+ *
212
+ * This is the main entry point for CLI usage. It parses `argv`, validates options,
213
+ * and executes the matching command. Supports help command (`help`, `--help`, `-h`)
214
+ * which displays all available commands.
215
+ *
216
+ * @param argv - Command-line arguments array (defaults to `process.argv`)
217
+ * @throws {Error} If the application is not initialized
218
+ * @throws {Error} If no command is provided
219
+ * @throws {Error} If the command is not found
220
+ * @throws {ZodError} If options validation fails
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * // Parse and execute from process.argv
225
+ * await app.run()
226
+ *
227
+ * // Or provide custom arguments
228
+ * await app.run(['node', 'cli.js', 'greet', '--name', 'World'])
229
+ * ```
101
230
  */
102
231
  async run(argv: string[] = process.argv) {
103
232
  if (!this.isInitialized) {
@@ -147,12 +276,27 @@ export class CommanderApplication {
147
276
  }
148
277
  }
149
278
 
279
+ /**
280
+ * @internal
281
+ * Disposes of resources used by the application.
282
+ */
150
283
  async dispose() {
151
284
  if (this.moduleLoader) {
152
285
  this.moduleLoader.dispose()
153
286
  }
154
287
  }
155
288
 
289
+ /**
290
+ * Closes the application and cleans up resources.
291
+ *
292
+ * This should be called when the application is no longer needed to free up resources.
293
+ *
294
+ * @example
295
+ * ```typescript
296
+ * await app.run(process.argv)
297
+ * await app.close()
298
+ * ```
299
+ */
156
300
  async close() {
157
301
  await this.dispose()
158
302
  }
@@ -1,15 +1,43 @@
1
- import type { ClassTypeWithInstance } from '@navios/di'
1
+ import type { ClassTypeWithInstance, NaviosModule } from '@navios/core'
2
2
 
3
- import { Container } from '@navios/di'
3
+ import { Container } from '@navios/core'
4
4
 
5
5
  import type { CommanderApplicationOptions } from './commander.application.mjs'
6
- import type { Module } from './interfaces/index.mjs'
7
6
 
8
7
  import { CommanderApplication } from './commander.application.mjs'
9
8
 
9
+ /**
10
+ * Factory class for creating and configuring CLI applications.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { CommanderFactory } from '@navios/commander'
15
+ * import { AppModule } from './app.module'
16
+ *
17
+ * async function bootstrap() {
18
+ * const app = await CommanderFactory.create(AppModule)
19
+ * await app.init()
20
+ * await app.run(process.argv)
21
+ * await app.close()
22
+ * }
23
+ * ```
24
+ */
10
25
  export class CommanderFactory {
26
+ /**
27
+ * Creates a new CommanderApplication instance and configures it with the provided module.
28
+ *
29
+ * @param appModule - The root CLI module class that contains commands and/or imports other modules
30
+ * @param options - Optional configuration options for the application
31
+ * @returns A promise that resolves to a configured CommanderApplication instance
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const app = await CommanderFactory.create(AppModule)
36
+ * await app.init()
37
+ * ```
38
+ */
11
39
  static async create(
12
- appModule: ClassTypeWithInstance<Module>,
40
+ appModule: ClassTypeWithInstance<NaviosModule>,
13
41
  options: CommanderApplicationOptions = {},
14
42
  ) {
15
43
  const container = new Container()
@@ -1,14 +1,49 @@
1
- import type { ClassType } from '@navios/di'
1
+ import type { ClassType } from '@navios/core'
2
2
 
3
- import { Injectable, InjectableScope, InjectionToken } from '@navios/di'
3
+ import { Injectable, InjectableScope, InjectionToken } from '@navios/core'
4
4
 
5
5
  import { getCliModuleMetadata } from '../metadata/index.mjs'
6
6
 
7
+ /**
8
+ * Options for the `@CliModule` decorator.
9
+ *
10
+ * @public
11
+ */
7
12
  export interface CliModuleOptions {
13
+ /**
14
+ * Array or Set of command classes to register in this module.
15
+ * Commands must be decorated with `@Command`.
16
+ */
8
17
  commands?: ClassType[] | Set<ClassType>
18
+ /**
19
+ * Array or Set of other CLI modules to import.
20
+ * Imported modules' commands will be available in this module.
21
+ */
9
22
  imports?: ClassType[] | Set<ClassType>
10
23
  }
11
24
 
25
+ /**
26
+ * Decorator that marks a class as a CLI module.
27
+ *
28
+ * Modules organize commands and can import other modules to compose larger CLI applications.
29
+ * The module can optionally implement `NaviosModule` interface for lifecycle hooks.
30
+ *
31
+ * @param options - Configuration options for the module
32
+ * @returns A class decorator function
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * import { CliModule } from '@navios/commander'
37
+ * import { GreetCommand } from './greet.command'
38
+ * import { UserModule } from './user.module'
39
+ *
40
+ * @CliModule({
41
+ * commands: [GreetCommand],
42
+ * imports: [UserModule]
43
+ * })
44
+ * export class AppModule {}
45
+ * ```
46
+ */
12
47
  export function CliModule(
13
48
  { commands = [], imports = [] }: CliModuleOptions = {
14
49
  commands: [],
@@ -1,15 +1,58 @@
1
- import type { ClassType } from '@navios/di'
1
+ import type { ClassType } from '@navios/core'
2
2
  import type { ZodObject } from 'zod'
3
3
 
4
- import { Injectable, InjectableScope, InjectionToken } from '@navios/di'
4
+ import { Injectable, InjectableScope, InjectionToken } from '@navios/core'
5
5
 
6
6
  import { getCommandMetadata } from '../metadata/index.mjs'
7
7
 
8
+ /**
9
+ * Options for the `@Command` decorator.
10
+ *
11
+ * @public
12
+ */
8
13
  export interface CommandOptions {
14
+ /**
15
+ * The command path that users will invoke from the CLI.
16
+ * Can be a single word (e.g., 'greet') or multi-word with colons (e.g., 'user:create', 'db:migrate').
17
+ */
9
18
  path: string
19
+ /**
20
+ * Optional Zod schema for validating command options.
21
+ * If provided, options will be validated and parsed according to this schema.
22
+ */
10
23
  optionsSchema?: ZodObject
11
24
  }
12
25
 
26
+ /**
27
+ * Decorator that marks a class as a CLI command.
28
+ *
29
+ * The decorated class must implement the `CommandHandler` interface with an `execute` method.
30
+ * The command will be automatically registered when its module is loaded.
31
+ *
32
+ * @param options - Configuration options for the command
33
+ * @returns A class decorator function
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * import { Command, CommandHandler } from '@navios/commander'
38
+ * import { z } from 'zod'
39
+ *
40
+ * const optionsSchema = z.object({
41
+ * name: z.string(),
42
+ * greeting: z.string().optional().default('Hello')
43
+ * })
44
+ *
45
+ * @Command({
46
+ * path: 'greet',
47
+ * optionsSchema: optionsSchema
48
+ * })
49
+ * export class GreetCommand implements CommandHandler<z.infer<typeof optionsSchema>> {
50
+ * async execute(options) {
51
+ * console.log(`${options.greeting}, ${options.name}!`)
52
+ * }
53
+ * }
54
+ * ```
55
+ */
13
56
  export function Command({ path, optionsSchema }: CommandOptions) {
14
57
  return function (target: ClassType, context: ClassDecoratorContext) {
15
58
  if (context.kind !== 'class') {
package/src/index.mts CHANGED
@@ -1,7 +1,11 @@
1
- export * from '@navios/di'
1
+ // Re-export DI types and values that users might need
2
+ export * from '@navios/core'
3
+
4
+ // Export commander-specific exports
2
5
  export * from './commander.application.mjs'
3
6
  export * from './commander.factory.mjs'
4
7
  export * from './decorators/index.mjs'
5
8
  export * from './interfaces/index.mjs'
6
9
  export * from './metadata/index.mjs'
7
10
  export * from './services/index.mjs'
11
+ export * from './tokens/index.mjs'
@@ -1,3 +1,36 @@
1
+ /**
2
+ * Interface that all command classes must implement.
3
+ *
4
+ * Commands decorated with `@Command` must implement this interface.
5
+ * The `execute` method is called when the command is invoked.
6
+ *
7
+ * @template TOptions - The type of options that the command accepts
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { Command, CommandHandler } from '@navios/commander'
12
+ * import { z } from 'zod'
13
+ *
14
+ * const optionsSchema = z.object({
15
+ * name: z.string()
16
+ * })
17
+ *
18
+ * type Options = z.infer<typeof optionsSchema>
19
+ *
20
+ * @Command({ path: 'greet', optionsSchema })
21
+ * export class GreetCommand implements CommandHandler<Options> {
22
+ * async execute(options: Options) {
23
+ * console.log(`Hello, ${options.name}!`)
24
+ * }
25
+ * }
26
+ * ```
27
+ */
1
28
  export interface CommandHandler<TOptions = any> {
29
+ /**
30
+ * Executes the command with the provided options.
31
+ *
32
+ * @param options - The validated command options (validated against the command's schema if provided)
33
+ * @returns A promise or void
34
+ */
2
35
  execute(options: TOptions): void | Promise<void>
3
36
  }
@@ -0,0 +1,64 @@
1
+ import type { CommandMetadata } from '../metadata/command.metadata.mjs'
2
+
3
+ /**
4
+ * Execution context for a command execution.
5
+ *
6
+ * Provides access to command metadata, path, and validated options during command execution.
7
+ * This context is automatically injected and available via the `CommandExecutionContext` token.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { inject, Injectable } from '@navios/di'
12
+ * import { CommandExecutionContext } from '@navios/commander'
13
+ *
14
+ * @Injectable()
15
+ * class CommandLogger {
16
+ * private ctx = inject(CommandExecutionContext)
17
+ *
18
+ * log() {
19
+ * console.log('Command:', this.ctx.getCommandPath())
20
+ * console.log('Options:', this.ctx.getOptions())
21
+ * }
22
+ * }
23
+ * ```
24
+ */
25
+ export class CommanderExecutionContext {
26
+ /**
27
+ * @internal
28
+ * Creates a new execution context.
29
+ */
30
+ constructor(
31
+ private readonly command: CommandMetadata,
32
+ private readonly commandPath: string,
33
+ private readonly options: any,
34
+ ) {}
35
+
36
+ /**
37
+ * Gets the command metadata.
38
+ *
39
+ * @returns The command metadata including path and options schema
40
+ */
41
+ getCommand(): CommandMetadata {
42
+ return this.command
43
+ }
44
+
45
+ /**
46
+ * Gets the command path that was invoked.
47
+ *
48
+ * @returns The command path (e.g., 'greet', 'user:create')
49
+ */
50
+ getCommandPath(): string {
51
+ return this.commandPath
52
+ }
53
+
54
+ /**
55
+ * Gets the validated command options.
56
+ *
57
+ * Options are validated against the command's Zod schema if one was provided.
58
+ *
59
+ * @returns The validated options object
60
+ */
61
+ getOptions(): any {
62
+ return this.options
63
+ }
64
+ }
@@ -1,2 +1,2 @@
1
- export * from './module.interface.mjs'
2
1
  export * from './command-handler.interface.mjs'
2
+ export * from './commander-execution-context.interface.mjs'
@@ -1,13 +1,39 @@
1
- import type { ClassType } from '@navios/di'
1
+ import type { ClassType } from '@navios/core'
2
2
 
3
+ /**
4
+ * @internal
5
+ * Symbol key used to store CLI module metadata on classes.
6
+ */
3
7
  export const CliModuleMetadataKey = Symbol('CliModuleMetadataKey')
4
8
 
9
+ /**
10
+ * Metadata associated with a CLI module.
11
+ *
12
+ * @public
13
+ */
5
14
  export interface CliModuleMetadata {
15
+ /**
16
+ * Set of command classes registered in this module.
17
+ */
6
18
  commands: Set<ClassType>
19
+ /**
20
+ * Set of other modules imported by this module.
21
+ */
7
22
  imports: Set<ClassType>
23
+ /**
24
+ * Map of custom attributes that can be attached to the module.
25
+ */
8
26
  customAttributes: Map<string | symbol, any>
9
27
  }
10
28
 
29
+ /**
30
+ * Gets or creates CLI module metadata for a class.
31
+ *
32
+ * @internal
33
+ * @param target - The module class
34
+ * @param context - The decorator context
35
+ * @returns The module metadata
36
+ */
11
37
  export function getCliModuleMetadata(
12
38
  target: ClassType,
13
39
  context: ClassDecoratorContext,
@@ -33,13 +59,22 @@ export function getCliModuleMetadata(
33
59
  throw new Error('[Navios Commander] Wrong environment.')
34
60
  }
35
61
 
36
- export function extractCliModuleMetadata(
37
- target: ClassType,
38
- ): CliModuleMetadata {
62
+ /**
63
+ * Extracts CLI module metadata from a class.
64
+ *
65
+ * @param target - The module class
66
+ * @returns The module metadata
67
+ * @throws {Error} If the class is not decorated with @CliModule
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const metadata = extractCliModuleMetadata(AppModule)
72
+ * console.log(metadata.commands.size) // Number of commands
73
+ * ```
74
+ */
75
+ export function extractCliModuleMetadata(target: ClassType): CliModuleMetadata {
39
76
  // @ts-expect-error We add a custom metadata key to the target
40
- const metadata = target[CliModuleMetadataKey] as
41
- | CliModuleMetadata
42
- | undefined
77
+ const metadata = target[CliModuleMetadataKey] as CliModuleMetadata | undefined
43
78
  if (!metadata) {
44
79
  throw new Error(
45
80
  `[Navios Commander] Module metadata not found for ${target.name}. Make sure to use @CliModule decorator.`,
@@ -48,6 +83,12 @@ export function extractCliModuleMetadata(
48
83
  return metadata
49
84
  }
50
85
 
86
+ /**
87
+ * Checks if a class has CLI module metadata.
88
+ *
89
+ * @param target - The class to check
90
+ * @returns `true` if the class is decorated with @CliModule, `false` otherwise
91
+ */
51
92
  export function hasCliModuleMetadata(target: ClassType): boolean {
52
93
  // @ts-expect-error We add a custom metadata key to the target
53
94
  return !!target[CliModuleMetadataKey]