@navios/commander 1.0.0 → 1.2.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 (76) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +22 -0
  3. package/dist/src/commander.factory.d.mts +59 -0
  4. package/dist/src/commander.factory.d.mts.map +1 -1
  5. package/dist/src/commands/help.command.d.mts.map +1 -1
  6. package/dist/src/decorators/command.decorator.d.mts +9 -2
  7. package/dist/src/decorators/command.decorator.d.mts.map +1 -1
  8. package/dist/src/legacy-compat/decorators/cli-module.decorator.d.mts +26 -0
  9. package/dist/src/legacy-compat/decorators/cli-module.decorator.d.mts.map +1 -0
  10. package/dist/src/legacy-compat/decorators/command.decorator.d.mts +34 -0
  11. package/dist/src/legacy-compat/decorators/command.decorator.d.mts.map +1 -0
  12. package/dist/src/legacy-compat/decorators/index.d.mts +3 -0
  13. package/dist/src/legacy-compat/decorators/index.d.mts.map +1 -0
  14. package/dist/src/legacy-compat/index.d.mts +28 -0
  15. package/dist/src/legacy-compat/index.d.mts.map +1 -0
  16. package/dist/src/overrides/help.command.d.mts +18 -0
  17. package/dist/src/overrides/help.command.d.mts.map +1 -0
  18. package/dist/src/tokens/help-command.token.d.mts +4 -0
  19. package/dist/src/tokens/help-command.token.d.mts.map +1 -0
  20. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  21. package/dist/tsconfig.tsbuildinfo +1 -1
  22. package/lib/cli-module.decorator-CkP22084.cjs +71 -0
  23. package/lib/cli-module.decorator-CkP22084.cjs.map +1 -0
  24. package/lib/cli-module.decorator-DGuGfpex.d.mts +411 -0
  25. package/lib/cli-module.decorator-DGuGfpex.d.mts.map +1 -0
  26. package/lib/cli-module.decorator-DVl8009Q.d.cts +213 -0
  27. package/lib/cli-module.decorator-DVl8009Q.d.cts.map +1 -0
  28. package/lib/cli-module.decorator-UGbtkRYc.mjs +66 -0
  29. package/lib/cli-module.decorator-UGbtkRYc.mjs.map +1 -0
  30. package/lib/command.decorator-DVLSAqYZ.mjs +135 -0
  31. package/lib/command.decorator-DVLSAqYZ.mjs.map +1 -0
  32. package/lib/command.decorator-UrNJmQN0.cjs +176 -0
  33. package/lib/command.decorator-UrNJmQN0.cjs.map +1 -0
  34. package/lib/help-command.token-C0Kgj60o.mjs +427 -0
  35. package/lib/help-command.token-C0Kgj60o.mjs.map +1 -0
  36. package/lib/help-command.token-CMWYI6em.cjs +438 -0
  37. package/lib/help-command.token-CMWYI6em.cjs.map +1 -0
  38. package/lib/help.command-DQyv6ali.cjs +317 -0
  39. package/lib/help.command-DQyv6ali.cjs.map +1 -0
  40. package/lib/help.command-dtZbhq0w.mjs +318 -0
  41. package/lib/help.command-dtZbhq0w.mjs.map +1 -0
  42. package/lib/index.cjs +45 -627
  43. package/lib/index.cjs.map +1 -1
  44. package/lib/index.d.cts +139 -281
  45. package/lib/index.d.cts.map +1 -1
  46. package/lib/index.d.mts +62 -402
  47. package/lib/index.d.mts.map +1 -1
  48. package/lib/index.mjs +30 -612
  49. package/lib/index.mjs.map +1 -1
  50. package/lib/legacy-compat/index.cjs +108 -0
  51. package/lib/legacy-compat/index.cjs.map +1 -0
  52. package/lib/legacy-compat/index.d.cts +63 -0
  53. package/lib/legacy-compat/index.d.cts.map +1 -0
  54. package/lib/legacy-compat/index.d.mts +63 -0
  55. package/lib/legacy-compat/index.d.mts.map +1 -0
  56. package/lib/legacy-compat/index.mjs +101 -0
  57. package/lib/legacy-compat/index.mjs.map +1 -0
  58. package/package.json +20 -3
  59. package/src/commander.factory.mts +107 -8
  60. package/src/commands/help.command.mts +4 -3
  61. package/src/decorators/command.decorator.mts +17 -8
  62. package/src/legacy-compat/decorators/cli-module.decorator.mts +46 -0
  63. package/src/legacy-compat/decorators/command.decorator.mts +46 -0
  64. package/src/legacy-compat/decorators/index.mts +2 -0
  65. package/src/legacy-compat/index.mts +31 -0
  66. package/src/overrides/help.command.mts +40 -0
  67. package/src/tokens/help-command.token.mts +5 -0
  68. package/tsconfig.json +0 -3
  69. package/tsconfig.spec.json +1 -1
  70. package/tsdown.config.mts +1 -1
  71. package/dist/src/commander.application.d.mts +0 -147
  72. package/dist/src/commander.application.d.mts.map +0 -1
  73. package/dist/src/metadata/cli-module.metadata.d.mts +0 -60
  74. package/dist/src/metadata/cli-module.metadata.d.mts.map +0 -1
  75. package/dist/src/services/module-loader.service.d.mts +0 -74
  76. package/dist/src/services/module-loader.service.d.mts.map +0 -1
@@ -0,0 +1,213 @@
1
+ import { ClassType, ClassTypeWithInstance, InjectionToken, Registry } from "@navios/core";
2
+ import { ZodObject } from "zod";
3
+
4
+ //#region src/interfaces/command-handler.interface.d.mts
5
+
6
+ /**
7
+ * Interface that all command classes must implement.
8
+ *
9
+ * Commands decorated with `@Command` must implement this interface.
10
+ * The `execute` method is called when the command is invoked.
11
+ *
12
+ * @template TOptions - The type of options that the command accepts
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { Command, CommandHandler } from '@navios/commander'
17
+ * import { z } from 'zod'
18
+ *
19
+ * const optionsSchema = z.object({
20
+ * name: z.string()
21
+ * })
22
+ *
23
+ * type Options = z.infer<typeof optionsSchema>
24
+ *
25
+ * @Command({ path: 'greet', optionsSchema })
26
+ * export class GreetCommand implements CommandHandler<Options> {
27
+ * async execute(options: Options) {
28
+ * console.log(`Hello, ${options.name}!`)
29
+ * }
30
+ * }
31
+ * ```
32
+ */
33
+ interface CommandHandler<TOptions = any> {
34
+ /**
35
+ * Executes the command with the provided options.
36
+ *
37
+ * @param options - The validated command options (validated against the command's schema if provided)
38
+ * @returns A promise or void
39
+ */
40
+ execute(options: TOptions): void | Promise<void>;
41
+ }
42
+ //#endregion
43
+ //#region src/decorators/command.decorator.d.mts
44
+ /**
45
+ * Options for the `@Command` decorator.
46
+ *
47
+ * @public
48
+ */
49
+ interface CommandOptions {
50
+ /**
51
+ * The token to use for the command.
52
+ * If provided, the command will be registered with this token.
53
+ */
54
+ token?: InjectionToken<ClassTypeWithInstance<CommandHandler<any>>>;
55
+ /**
56
+ * The command path that users will invoke from the CLI.
57
+ * Can be a single word (e.g., 'greet') or multi-word with colons (e.g., 'user:create', 'db:migrate').
58
+ */
59
+ path: string;
60
+ /**
61
+ * Optional description of the command for help text.
62
+ * Displayed when users run `help` or `--help`.
63
+ */
64
+ description?: string;
65
+ /**
66
+ * Optional Zod schema for validating command options.
67
+ * If provided, options will be validated and parsed according to this schema.
68
+ */
69
+ optionsSchema?: ZodObject;
70
+ /**
71
+ * Priority level for the command.
72
+ * Higher priority commands will be loaded first.
73
+ */
74
+ priority?: number;
75
+ /**
76
+ * Registry to use for the command.
77
+ * Registry is used to store the command and its options schema.
78
+ */
79
+ registry?: Registry;
80
+ }
81
+ /**
82
+ * Decorator that marks a class as a CLI command.
83
+ *
84
+ * The decorated class must implement the `CommandHandler` interface with an `execute` method.
85
+ * The command will be automatically registered when its module is loaded.
86
+ *
87
+ * @param options - Configuration options for the command
88
+ * @returns A class decorator function
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * import { Command, CommandHandler } from '@navios/commander'
93
+ * import { z } from 'zod'
94
+ *
95
+ * const optionsSchema = z.object({
96
+ * name: z.string(),
97
+ * greeting: z.string().optional().default('Hello')
98
+ * })
99
+ *
100
+ * @Command({
101
+ * path: 'greet',
102
+ * optionsSchema: optionsSchema
103
+ * })
104
+ * export class GreetCommand implements CommandHandler<z.infer<typeof optionsSchema>> {
105
+ * async execute(options) {
106
+ * console.log(`${options.greeting}, ${options.name}!`)
107
+ * }
108
+ * }
109
+ * ```
110
+ */
111
+ declare function Command({
112
+ path,
113
+ description,
114
+ token,
115
+ optionsSchema,
116
+ priority,
117
+ registry
118
+ }: CommandOptions): (target: ClassType, context: ClassDecoratorContext) => any;
119
+ //#endregion
120
+ //#region src/decorators/cli-module.decorator.d.mts
121
+ /**
122
+ * Options for the `@CliModule` decorator.
123
+ *
124
+ * @public
125
+ */
126
+ interface CliModuleOptions {
127
+ /**
128
+ * Array or Set of command classes to register in this module.
129
+ * Commands must be decorated with `@Command`.
130
+ */
131
+ commands?: ClassType[] | Set<ClassType>;
132
+ /**
133
+ * Array or Set of controller classes for HTTP endpoints.
134
+ * Allows mixing HTTP and CLI functionality in the same module.
135
+ */
136
+ controllers?: ClassType[] | Set<ClassType>;
137
+ /**
138
+ * Array or Set of other modules to import.
139
+ * Imported modules' commands and controllers will be available.
140
+ */
141
+ imports?: ClassType[] | Set<ClassType>;
142
+ /**
143
+ * Guards to apply to all controllers in this module.
144
+ * Guards are executed in reverse order (last guard first).
145
+ */
146
+ guards?: ClassType[] | Set<ClassType>;
147
+ /**
148
+ * Service override classes to import for side effects.
149
+ * These classes are imported to ensure their @Injectable decorators execute,
150
+ * allowing them to register with the DI system. Overrides should use the same
151
+ * InjectionToken as the original service with a higher priority.
152
+ */
153
+ overrides?: ClassType[] | Set<ClassType>;
154
+ /**
155
+ * Priority level for the module.
156
+ * Higher priority modules will be loaded first.
157
+ */
158
+ priority?: number;
159
+ /**
160
+ * Registry to use for the module.
161
+ * Registry is used to store the module and its commands.
162
+ */
163
+ registry?: Registry;
164
+ }
165
+ /**
166
+ * Decorator that marks a class as a CLI module.
167
+ *
168
+ * This decorator extends the standard @Module decorator, adding support for
169
+ * CLI commands while maintaining full compatibility with HTTP controllers.
170
+ * Modules organize commands and can import other modules to compose larger
171
+ * CLI applications.
172
+ *
173
+ * The module can optionally implement `NaviosModule` interface for lifecycle hooks.
174
+ *
175
+ * @param options - Configuration options for the module
176
+ * @returns A class decorator function
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * import { CliModule } from '@navios/commander'
181
+ * import { GreetCommand } from './greet.command'
182
+ * import { UserModule } from './user.module'
183
+ *
184
+ * @CliModule({
185
+ * commands: [GreetCommand],
186
+ * imports: [UserModule]
187
+ * })
188
+ * export class AppModule {}
189
+ * ```
190
+ *
191
+ * @example
192
+ * ```typescript
193
+ * // Mixed HTTP and CLI module
194
+ * @CliModule({
195
+ * controllers: [HealthController],
196
+ * commands: [MigrateCommand],
197
+ * imports: [DatabaseModule],
198
+ * })
199
+ * export class AppModule {}
200
+ * ```
201
+ */
202
+ declare function CliModule({
203
+ commands,
204
+ controllers,
205
+ imports,
206
+ guards,
207
+ overrides,
208
+ priority,
209
+ registry
210
+ }?: CliModuleOptions): (target: ClassType, context: ClassDecoratorContext) => ClassType;
211
+ //#endregion
212
+ export { CommandHandler as a, CommandOptions as i, CliModuleOptions as n, Command as r, CliModule as t };
213
+ //# sourceMappingURL=cli-module.decorator-DVl8009Q.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-module.decorator-DVl8009Q.d.cts","names":["CommandHandler","TOptions","Promise","InjectionToken","ClassType","ClassTypeWithInstance","Registry","ZodObject","CommandHandler","CommandOptions","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'\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","import { InjectionToken } from '@navios/core';\nimport type { ClassType, ClassTypeWithInstance, Registry } from '@navios/core';\nimport type { ZodObject } from 'zod';\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 schema for validating command options.\n * If provided, options will be validated and parsed according to this schema.\n */\n optionsSchema?: 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'\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({ path, description, token, optionsSchema, priority, registry, }: CommandOptions): (target: ClassType, context: ClassDecoratorContext) => any;\n//# sourceMappingURL=command.decorator.d.mts.map","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({ commands, controllers, imports, guards, overrides, priority, registry, }?: CliModuleOptions): (target: ClassType, context: ClassDecoratorContext) => ClassType;\n//# sourceMappingURL=cli-module.decorator.d.mts.map"],"mappings":";;;;;;;;;AA2BA;;;;AClBA;;;;;;;AA8DA;;;;;;;;;;;;UD5CiBA;;AErBjB;;;;;EAUoCkB,OAAAA,CAAAA,OAAAA,EFkBfjB,QElBeiB,CAAAA,EAAAA,IAAAA,GFkBGhB,OElBHgB,CAAAA,IAAAA,CAAAA;;;;AFWpC;;;;AClBA;AAKiDV,UALhCC,cAAAA,CAKgCD;EAAtBH;;;;EAyBJ,KAAA,CAAA,EAzBXF,cAyBW,CAzBIE,qBAyBJ,CAzB0BG,cAyB1B,CAAA,GAAA,CAAA,CAAA,CAAA;EAgCCE;;;;EAAoCI,IAAAA,EAAAA,MAAAA;EAAeC;;;;EAAqEE,WAAAA,CAAAA,EAAAA,MAAAA;EAAqB;;;;ECjEpJG,aAAAA,CAAAA,EDuBGb,SCvBa;EAKlBW;;;;EAKqBA,QAAAA,CAAAA,EAAAA,MAAAA;EAAJG;;;;EAUnBH,QAAAA,CAAAA,EDaEZ,QCbFY;;;;;;;;AAwDb;;;;;;;;;;;;;;;;;;;;;;;;iBDXwBR,OAAAA;;;;;;;GAA0ED,0BAA0BL,oBAAoBa;;;;;;AD5ChJ;;UErBiBG,gBAAAA;;ADGjB;;;EAKYjB,QAAAA,CAAAA,ECHGe,SDGHf,EAAAA,GCHiBkB,GDGjBlB,CCHqBe,SDGrBf,CAAAA;EAeQI;;;AA0CpB;EAAkCI,WAAAA,CAAAA,ECvDhBO,SDuDgBP,EAAAA,GCvDFU,GDuDEV,CCvDEO,SDuDFP,CAAAA;EAAMC;;;;EAA6CI,OAAAA,CAAAA,EClDvEE,SDkDuEF,EAAAA,GClDzDK,GDkDyDL,CClDrDE,SDkDqDF,CAAAA;EAAaP;;;;WC7CrFS,cAAcG,IAAIH;;;AApB/B;;;;EAUkBA,SAAAA,CAAAA,EAiBFA,SAjBEA,EAAAA,GAiBYG,GAjBZH,CAiBgBA,SAjBhBA,CAAAA;EAAkBA;;;;EAKRG,QAAAA,CAAAA,EAAAA,MAAAA;EAKfH;;;;EAOqBA,QAAAA,CAAAA,EAUnBC,QAVmBD;;;;AAiDlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAwBI,SAAAA;;;;;;;;IAAuFF,4BAA4BF,oBAAoBY,0BAA0BZ"}
@@ -0,0 +1,66 @@
1
+ import { n as CommandEntryKey } from "./command.decorator-DVLSAqYZ.mjs";
2
+ import { Module, getModuleCustomEntry, getModuleMetadata } from "@navios/core";
3
+
4
+ //#region src/decorators/cli-module.decorator.mts
5
+ /**
6
+ * Decorator that marks a class as a CLI module.
7
+ *
8
+ * This decorator extends the standard @Module decorator, adding support for
9
+ * CLI commands while maintaining full compatibility with HTTP controllers.
10
+ * Modules organize commands and can import other modules to compose larger
11
+ * CLI applications.
12
+ *
13
+ * The module can optionally implement `NaviosModule` interface for lifecycle hooks.
14
+ *
15
+ * @param options - Configuration options for the module
16
+ * @returns A class decorator function
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { CliModule } from '@navios/commander'
21
+ * import { GreetCommand } from './greet.command'
22
+ * import { UserModule } from './user.module'
23
+ *
24
+ * @CliModule({
25
+ * commands: [GreetCommand],
26
+ * imports: [UserModule]
27
+ * })
28
+ * export class AppModule {}
29
+ * ```
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // Mixed HTTP and CLI module
34
+ * @CliModule({
35
+ * controllers: [HealthController],
36
+ * commands: [MigrateCommand],
37
+ * imports: [DatabaseModule],
38
+ * })
39
+ * export class AppModule {}
40
+ * ```
41
+ */ function CliModule({ commands = [], controllers = [], imports = [], guards = [], overrides = [], priority, registry } = {
42
+ commands: [],
43
+ controllers: [],
44
+ imports: [],
45
+ guards: [],
46
+ overrides: []
47
+ }) {
48
+ return (target, context) => {
49
+ if (context.kind !== "class") throw new Error("[Navios Commander] @CliModule decorator can only be used on classes.");
50
+ const result = Module({
51
+ controllers,
52
+ imports,
53
+ guards,
54
+ overrides,
55
+ priority,
56
+ registry
57
+ })(target, context);
58
+ const commandSet = getModuleCustomEntry(getModuleMetadata(target, context), CommandEntryKey, () => /* @__PURE__ */ new Set());
59
+ for (const command of commands) commandSet.add(command);
60
+ return result;
61
+ };
62
+ }
63
+
64
+ //#endregion
65
+ export { CliModule as t };
66
+ //# sourceMappingURL=cli-module.decorator-UGbtkRYc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-module.decorator-UGbtkRYc.mjs","names":["Module","getModuleMetadata","getModuleCustomEntry","CommandEntryKey","CliModule","commands","controllers","imports","guards","overrides","priority","registry","target","context","kind","Error","result","metadata","commandSet","Set","command","add"],"sources":["../src/decorators/cli-module.decorator.mts"],"sourcesContent":["import type { ClassType, Registry } from '@navios/core'\n\nimport { Module, getModuleMetadata, getModuleCustomEntry } from '@navios/core'\n\nimport {\n CommandEntryKey,\n type CommandEntryValue,\n} from '../metadata/command-entry.metadata.mjs'\n\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/**\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 function CliModule(\n {\n commands = [],\n controllers = [],\n imports = [],\n guards = [],\n overrides = [],\n priority,\n registry,\n }: CliModuleOptions = {\n commands: [],\n controllers: [],\n imports: [],\n guards: [],\n overrides: [],\n },\n) {\n return (target: ClassType, context: ClassDecoratorContext) => {\n if (context.kind !== 'class') {\n throw new Error(\n '[Navios Commander] @CliModule decorator can only be used on classes.',\n )\n }\n\n // Apply standard @Module decorator first\n const result = Module({\n controllers,\n imports,\n guards,\n overrides,\n priority,\n registry,\n })(target, context)\n\n // Get the module metadata that @Module just created\n const metadata = getModuleMetadata(target, context)\n\n // Store commands in customEntries\n const commandSet = getModuleCustomEntry<CommandEntryValue>(\n metadata,\n CommandEntryKey,\n () => new Set(),\n )\n for (const command of commands) {\n commandSet.add(command)\n }\n\n return result\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2FA,SAAgBI,UACd,EACEC,WAAW,EAAE,EACbC,cAAc,EAAE,EAChBC,UAAU,EAAE,EACZC,SAAS,EAAE,EACXC,YAAY,EAAE,EACdC,UACAC,aACoB;CACpBN,UAAU,EAAE;CACZC,aAAa,EAAE;CACfC,SAAS,EAAE;CACXC,QAAQ,EAAE;CACVC,WAAW,EAAE;CACd,EAAA;AAED,SAAQG,QAAmBC,YAAAA;AACzB,MAAIA,QAAQC,SAAS,QACnB,OAAM,IAAIC,MACR,uEAAA;EAKJ,MAAMC,SAAShB,OAAO;GACpBM;GACAC;GACAC;GACAC;GACAC;GACAC;GACF,CAAA,CAAGC,QAAQC,QAAAA;EAMX,MAAMK,aAAahB,qBAHFD,kBAAkBW,QAAQC,QAAAA,EAKzCV,uCACM,IAAIgB,KAAAA,CAAAA;AAEZ,OAAK,MAAMC,WAAWf,SACpBa,YAAWG,IAAID,QAAAA;AAGjB,SAAOJ"}
@@ -0,0 +1,135 @@
1
+ import { Injectable, InjectableScope, InjectionToken, extractModuleMetadata } from "@navios/core";
2
+
3
+ //#region src/metadata/command.metadata.mts
4
+ /**
5
+ * @internal
6
+ * Symbol key used to store command metadata on classes.
7
+ */ const CommandMetadataKey = Symbol("CommandMetadataKey");
8
+ /**
9
+ * Gets or creates command metadata for a class.
10
+ *
11
+ * @internal
12
+ * @param target - The command class
13
+ * @param context - The decorator context
14
+ * @param path - The command path
15
+ * @param description - Optional description for help text
16
+ * @param optionsSchema - Optional Zod schema
17
+ * @returns The command metadata
18
+ */ function getCommandMetadata(target, context, path, description, optionsSchema) {
19
+ if (context.metadata) {
20
+ const metadata = context.metadata[CommandMetadataKey];
21
+ if (metadata) return metadata;
22
+ else {
23
+ const newMetadata = {
24
+ path,
25
+ description,
26
+ optionsSchema,
27
+ customAttributes: /* @__PURE__ */ new Map()
28
+ };
29
+ context.metadata[CommandMetadataKey] = newMetadata;
30
+ target[CommandMetadataKey] = newMetadata;
31
+ return newMetadata;
32
+ }
33
+ }
34
+ throw new Error("[Navios Commander] Wrong environment.");
35
+ }
36
+ /**
37
+ * Extracts command metadata from a class.
38
+ *
39
+ * @param target - The command class
40
+ * @returns The command metadata
41
+ * @throws {Error} If the class is not decorated with @Command
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const metadata = extractCommandMetadata(GreetCommand)
46
+ * console.log(metadata.path) // 'greet'
47
+ * ```
48
+ */ function extractCommandMetadata(target) {
49
+ const metadata = target[CommandMetadataKey];
50
+ if (!metadata) throw new Error("[Navios Commander] Command metadata not found. Make sure to use @Command decorator.");
51
+ return metadata;
52
+ }
53
+ /**
54
+ * Checks if a class has command metadata.
55
+ *
56
+ * @param target - The class to check
57
+ * @returns `true` if the class is decorated with @Command, `false` otherwise
58
+ */ function hasCommandMetadata(target) {
59
+ return !!target[CommandMetadataKey];
60
+ }
61
+
62
+ //#endregion
63
+ //#region src/metadata/command-entry.metadata.mts
64
+ /**
65
+ * Symbol key for storing commands in ModuleMetadata.customEntries.
66
+ * Used by @CliModule to store command classes.
67
+ *
68
+ * @public
69
+ */ const CommandEntryKey = Symbol("CommandEntryKey");
70
+ /**
71
+ * Extracts commands from a module's metadata.
72
+ * Returns empty set if no commands are defined.
73
+ *
74
+ * @param moduleClass - The module class decorated with @CliModule or @Module
75
+ * @returns Set of command classes registered in the module
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const commands = extractModuleCommands(AppModule)
80
+ * for (const command of commands) {
81
+ * console.log(command.name)
82
+ * }
83
+ * ```
84
+ */ function extractModuleCommands(moduleClass) {
85
+ return extractModuleMetadata(moduleClass).customEntries.get(CommandEntryKey) ?? /* @__PURE__ */ new Set();
86
+ }
87
+
88
+ //#endregion
89
+ //#region src/decorators/command.decorator.mts
90
+ /**
91
+ * Decorator that marks a class as a CLI command.
92
+ *
93
+ * The decorated class must implement the `CommandHandler` interface with an `execute` method.
94
+ * The command will be automatically registered when its module is loaded.
95
+ *
96
+ * @param options - Configuration options for the command
97
+ * @returns A class decorator function
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * import { Command, CommandHandler } from '@navios/commander'
102
+ * import { z } from 'zod'
103
+ *
104
+ * const optionsSchema = z.object({
105
+ * name: z.string(),
106
+ * greeting: z.string().optional().default('Hello')
107
+ * })
108
+ *
109
+ * @Command({
110
+ * path: 'greet',
111
+ * optionsSchema: optionsSchema
112
+ * })
113
+ * export class GreetCommand implements CommandHandler<z.infer<typeof optionsSchema>> {
114
+ * async execute(options) {
115
+ * console.log(`${options.greeting}, ${options.name}!`)
116
+ * }
117
+ * }
118
+ * ```
119
+ */ function Command({ path, description, token, optionsSchema, priority, registry }) {
120
+ return function(target, context) {
121
+ if (context.kind !== "class") throw new Error("[Navios Commander] @Command decorator can only be used on classes.");
122
+ const tokenToUse = token ?? InjectionToken.create(target);
123
+ if (context.metadata) getCommandMetadata(target, context, path, description, optionsSchema);
124
+ return Injectable({
125
+ token: tokenToUse,
126
+ scope: InjectableScope.Singleton,
127
+ priority,
128
+ registry
129
+ })(target, context);
130
+ };
131
+ }
132
+
133
+ //#endregion
134
+ export { extractCommandMetadata as a, CommandMetadataKey as i, CommandEntryKey as n, getCommandMetadata as o, extractModuleCommands as r, hasCommandMetadata as s, Command as t };
135
+ //# sourceMappingURL=command.decorator-DVLSAqYZ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.decorator-DVLSAqYZ.mjs","names":["CommandMetadataKey","Symbol","getCommandMetadata","target","context","path","description","optionsSchema","metadata","newMetadata","customAttributes","Map","Error","extractCommandMetadata","hasCommandMetadata","extractModuleMetadata","CommandEntryKey","Symbol","extractModuleCommands","moduleClass","metadata","customEntries","get","Set","Injectable","InjectableScope","InjectionToken","getCommandMetadata","Command","path","description","token","optionsSchema","priority","registry","target","context","kind","Error","tokenToUse","create","metadata","scope","Singleton"],"sources":["../src/metadata/command.metadata.mts","../src/metadata/command-entry.metadata.mts","../src/decorators/command.decorator.mts"],"sourcesContent":["import type { ClassType } from '@navios/core'\nimport type { ZodObject } from 'zod'\n\n/**\n * @internal\n * Symbol key used to store command metadata on classes.\n */\nexport const CommandMetadataKey = Symbol('CommandMetadataKey')\n\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 schema for validating command options.\n */\n optionsSchema?: ZodObject\n /**\n * Map of custom attributes that can be attached to the command.\n */\n customAttributes: Map<string | symbol, any>\n}\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 schema\n * @returns The command metadata\n */\nexport function getCommandMetadata(\n target: ClassType,\n context: ClassDecoratorContext,\n path: string,\n description?: string,\n optionsSchema?: ZodObject,\n): CommandMetadata {\n if (context.metadata) {\n const metadata = context.metadata[CommandMetadataKey] as\n | CommandMetadata\n | undefined\n if (metadata) {\n return metadata\n } else {\n const newMetadata: CommandMetadata = {\n path,\n description,\n optionsSchema,\n customAttributes: new Map<string | symbol, any>(),\n }\n context.metadata[CommandMetadataKey] = newMetadata\n // @ts-expect-error We add a custom metadata key to the target\n target[CommandMetadataKey] = newMetadata\n return newMetadata\n }\n }\n throw new Error('[Navios Commander] Wrong environment.')\n}\n\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 function extractCommandMetadata(target: ClassType): CommandMetadata {\n // @ts-expect-error We add a custom metadata key to the target\n const metadata = target[CommandMetadataKey] as CommandMetadata | undefined\n if (!metadata) {\n throw new Error(\n '[Navios Commander] Command metadata not found. Make sure to use @Command decorator.',\n )\n }\n return metadata\n}\n\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 function hasCommandMetadata(target: ClassType): boolean {\n // @ts-expect-error We add a custom metadata key to the target\n const metadata = target[CommandMetadataKey] as CommandMetadata | undefined\n return !!metadata\n}\n","import type { ClassType } from '@navios/core'\n\nimport { extractModuleMetadata } from '@navios/core'\n\n/**\n * Symbol key for storing commands in ModuleMetadata.customEntries.\n * Used by @CliModule to store command classes.\n *\n * @public\n */\nexport const CommandEntryKey = Symbol('CommandEntryKey')\n\n/**\n * Type for the command entry value stored in customEntries.\n *\n * @public\n */\nexport type CommandEntryValue = Set<ClassType>\n\n/**\n * Extracts commands from a module's metadata.\n * Returns empty set if no commands are defined.\n *\n * @param moduleClass - The module class decorated with @CliModule or @Module\n * @returns Set of command classes registered in the module\n *\n * @example\n * ```typescript\n * const commands = extractModuleCommands(AppModule)\n * for (const command of commands) {\n * console.log(command.name)\n * }\n * ```\n */\nexport function extractModuleCommands(moduleClass: ClassType): Set<ClassType> {\n const metadata = extractModuleMetadata(moduleClass)\n return (\n (metadata.customEntries.get(CommandEntryKey) as CommandEntryValue) ??\n new Set()\n )\n}\n","import { Injectable, InjectableScope, InjectionToken } from '@navios/core'\n\nimport type { ClassType, ClassTypeWithInstance, Registry } from '@navios/core'\nimport type { ZodObject } from 'zod'\n\nimport { getCommandMetadata } from '../metadata/index.mjs'\n\nimport type { CommandHandler } from '../interfaces/index.mjs'\n\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 schema for validating command options.\n * If provided, options will be validated and parsed according to this schema.\n */\n optionsSchema?: 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/**\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'\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 function Command({\n path,\n description,\n token,\n optionsSchema,\n priority,\n registry,\n}: CommandOptions) {\n return function (target: ClassType, context: ClassDecoratorContext) {\n if (context.kind !== 'class') {\n throw new Error('[Navios Commander] @Command decorator can only be used on classes.')\n }\n const tokenToUse =\n token ?? InjectionToken.create<ClassTypeWithInstance<CommandHandler<any>>>(target)\n\n if (context.metadata) {\n getCommandMetadata(target, context, path, description, optionsSchema)\n }\n // @ts-expect-error Injectable is callable\n return Injectable({\n token: tokenToUse,\n scope: InjectableScope.Singleton,\n priority,\n registry,\n })(target, context)\n }\n}\n"],"mappings":";;;;;;GAOA,MAAaA,qBAAqBC,OAAO,qBAAA;;;;;;;;;;;GAqCzC,SAAgBC,mBACdC,QACAC,SACAC,MACAC,aACAC,eAAyB;AAEzB,KAAIH,QAAQI,UAAU;EACpB,MAAMA,WAAWJ,QAAQI,SAASR;AAGlC,MAAIQ,SACF,QAAOA;OACF;GACL,MAAMC,cAA+B;IACnCJ;IACAC;IACAC;IACAG,kCAAkB,IAAIC,KAAAA;IACxB;AACAP,WAAQI,SAASR,sBAAsBS;AAEvCN,UAAOH,sBAAsBS;AAC7B,UAAOA;;;AAGX,OAAM,IAAIG,MAAM,wCAAA;;;;;;;;;;;;;;GAgBlB,SAAgBC,uBAAuBV,QAAiB;CAEtD,MAAMK,WAAWL,OAAOH;AACxB,KAAI,CAACQ,SACH,OAAM,IAAII,MACR,sFAAA;AAGJ,QAAOJ;;;;;;;GAST,SAAgBM,mBAAmBX,QAAiB;AAGlD,QAAO,CAAC,CADSA,OAAOH;;;;;;;;;;GC/F1B,MAAagB,kBAAkBC,OAAO,kBAAA;;;;;;;;;;;;;;;GAwBtC,SAAgBC,sBAAsBC,aAAsB;AAE1D,QADiBJ,sBAAsBI,YAAAA,CAE3BE,cAAcC,IAAIN,gBAAAA,oBAC5B,IAAIO,KAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GCuCR,SAAgBK,QAAQ,EACtBC,MACAC,aACAC,OACAC,eACAC,UACAC,YACe;AACf,QAAO,SAAUC,QAAmBC,SAA8B;AAChE,MAAIA,QAAQC,SAAS,QACnB,OAAM,IAAIC,MAAM,qEAAA;EAElB,MAAMC,aACJR,SAASL,eAAec,OAAmDL,OAAAA;AAE7E,MAAIC,QAAQK,SACVd,oBAAmBQ,QAAQC,SAASP,MAAMC,aAAaE,cAAAA;AAGzD,SAAOR,WAAW;GAChBO,OAAOQ;GACPG,OAAOjB,gBAAgBkB;GACvBV;GACAC;GACF,CAAA,CAAGC,QAAQC,QAAAA"}
@@ -0,0 +1,176 @@
1
+ let _navios_core = require("@navios/core");
2
+
3
+ //#region src/metadata/command.metadata.mts
4
+ /**
5
+ * @internal
6
+ * Symbol key used to store command metadata on classes.
7
+ */ const CommandMetadataKey = Symbol("CommandMetadataKey");
8
+ /**
9
+ * Gets or creates command metadata for a class.
10
+ *
11
+ * @internal
12
+ * @param target - The command class
13
+ * @param context - The decorator context
14
+ * @param path - The command path
15
+ * @param description - Optional description for help text
16
+ * @param optionsSchema - Optional Zod schema
17
+ * @returns The command metadata
18
+ */ function getCommandMetadata(target, context, path, description, optionsSchema) {
19
+ if (context.metadata) {
20
+ const metadata = context.metadata[CommandMetadataKey];
21
+ if (metadata) return metadata;
22
+ else {
23
+ const newMetadata = {
24
+ path,
25
+ description,
26
+ optionsSchema,
27
+ customAttributes: /* @__PURE__ */ new Map()
28
+ };
29
+ context.metadata[CommandMetadataKey] = newMetadata;
30
+ target[CommandMetadataKey] = newMetadata;
31
+ return newMetadata;
32
+ }
33
+ }
34
+ throw new Error("[Navios Commander] Wrong environment.");
35
+ }
36
+ /**
37
+ * Extracts command metadata from a class.
38
+ *
39
+ * @param target - The command class
40
+ * @returns The command metadata
41
+ * @throws {Error} If the class is not decorated with @Command
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const metadata = extractCommandMetadata(GreetCommand)
46
+ * console.log(metadata.path) // 'greet'
47
+ * ```
48
+ */ function extractCommandMetadata(target) {
49
+ const metadata = target[CommandMetadataKey];
50
+ if (!metadata) throw new Error("[Navios Commander] Command metadata not found. Make sure to use @Command decorator.");
51
+ return metadata;
52
+ }
53
+ /**
54
+ * Checks if a class has command metadata.
55
+ *
56
+ * @param target - The class to check
57
+ * @returns `true` if the class is decorated with @Command, `false` otherwise
58
+ */ function hasCommandMetadata(target) {
59
+ return !!target[CommandMetadataKey];
60
+ }
61
+
62
+ //#endregion
63
+ //#region src/metadata/command-entry.metadata.mts
64
+ /**
65
+ * Symbol key for storing commands in ModuleMetadata.customEntries.
66
+ * Used by @CliModule to store command classes.
67
+ *
68
+ * @public
69
+ */ const CommandEntryKey = Symbol("CommandEntryKey");
70
+ /**
71
+ * Extracts commands from a module's metadata.
72
+ * Returns empty set if no commands are defined.
73
+ *
74
+ * @param moduleClass - The module class decorated with @CliModule or @Module
75
+ * @returns Set of command classes registered in the module
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const commands = extractModuleCommands(AppModule)
80
+ * for (const command of commands) {
81
+ * console.log(command.name)
82
+ * }
83
+ * ```
84
+ */ function extractModuleCommands(moduleClass) {
85
+ return (0, _navios_core.extractModuleMetadata)(moduleClass).customEntries.get(CommandEntryKey) ?? /* @__PURE__ */ new Set();
86
+ }
87
+
88
+ //#endregion
89
+ //#region src/decorators/command.decorator.mts
90
+ /**
91
+ * Decorator that marks a class as a CLI command.
92
+ *
93
+ * The decorated class must implement the `CommandHandler` interface with an `execute` method.
94
+ * The command will be automatically registered when its module is loaded.
95
+ *
96
+ * @param options - Configuration options for the command
97
+ * @returns A class decorator function
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * import { Command, CommandHandler } from '@navios/commander'
102
+ * import { z } from 'zod'
103
+ *
104
+ * const optionsSchema = z.object({
105
+ * name: z.string(),
106
+ * greeting: z.string().optional().default('Hello')
107
+ * })
108
+ *
109
+ * @Command({
110
+ * path: 'greet',
111
+ * optionsSchema: optionsSchema
112
+ * })
113
+ * export class GreetCommand implements CommandHandler<z.infer<typeof optionsSchema>> {
114
+ * async execute(options) {
115
+ * console.log(`${options.greeting}, ${options.name}!`)
116
+ * }
117
+ * }
118
+ * ```
119
+ */ function Command({ path, description, token, optionsSchema, priority, registry }) {
120
+ return function(target, context) {
121
+ if (context.kind !== "class") throw new Error("[Navios Commander] @Command decorator can only be used on classes.");
122
+ const tokenToUse = token ?? _navios_core.InjectionToken.create(target);
123
+ if (context.metadata) getCommandMetadata(target, context, path, description, optionsSchema);
124
+ return (0, _navios_core.Injectable)({
125
+ token: tokenToUse,
126
+ scope: _navios_core.InjectableScope.Singleton,
127
+ priority,
128
+ registry
129
+ })(target, context);
130
+ };
131
+ }
132
+
133
+ //#endregion
134
+ Object.defineProperty(exports, 'Command', {
135
+ enumerable: true,
136
+ get: function () {
137
+ return Command;
138
+ }
139
+ });
140
+ Object.defineProperty(exports, 'CommandEntryKey', {
141
+ enumerable: true,
142
+ get: function () {
143
+ return CommandEntryKey;
144
+ }
145
+ });
146
+ Object.defineProperty(exports, 'CommandMetadataKey', {
147
+ enumerable: true,
148
+ get: function () {
149
+ return CommandMetadataKey;
150
+ }
151
+ });
152
+ Object.defineProperty(exports, 'extractCommandMetadata', {
153
+ enumerable: true,
154
+ get: function () {
155
+ return extractCommandMetadata;
156
+ }
157
+ });
158
+ Object.defineProperty(exports, 'extractModuleCommands', {
159
+ enumerable: true,
160
+ get: function () {
161
+ return extractModuleCommands;
162
+ }
163
+ });
164
+ Object.defineProperty(exports, 'getCommandMetadata', {
165
+ enumerable: true,
166
+ get: function () {
167
+ return getCommandMetadata;
168
+ }
169
+ });
170
+ Object.defineProperty(exports, 'hasCommandMetadata', {
171
+ enumerable: true,
172
+ get: function () {
173
+ return hasCommandMetadata;
174
+ }
175
+ });
176
+ //# sourceMappingURL=command.decorator-UrNJmQN0.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.decorator-UrNJmQN0.cjs","names":["CommandMetadataKey","Symbol","getCommandMetadata","target","context","path","description","optionsSchema","metadata","newMetadata","customAttributes","Map","Error","extractCommandMetadata","hasCommandMetadata","extractModuleMetadata","CommandEntryKey","Symbol","extractModuleCommands","moduleClass","metadata","customEntries","get","Set","Injectable","InjectableScope","InjectionToken","getCommandMetadata","Command","path","description","token","optionsSchema","priority","registry","target","context","kind","Error","tokenToUse","create","metadata","scope","Singleton"],"sources":["../src/metadata/command.metadata.mts","../src/metadata/command-entry.metadata.mts","../src/decorators/command.decorator.mts"],"sourcesContent":["import type { ClassType } from '@navios/core'\nimport type { ZodObject } from 'zod'\n\n/**\n * @internal\n * Symbol key used to store command metadata on classes.\n */\nexport const CommandMetadataKey = Symbol('CommandMetadataKey')\n\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 schema for validating command options.\n */\n optionsSchema?: ZodObject\n /**\n * Map of custom attributes that can be attached to the command.\n */\n customAttributes: Map<string | symbol, any>\n}\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 schema\n * @returns The command metadata\n */\nexport function getCommandMetadata(\n target: ClassType,\n context: ClassDecoratorContext,\n path: string,\n description?: string,\n optionsSchema?: ZodObject,\n): CommandMetadata {\n if (context.metadata) {\n const metadata = context.metadata[CommandMetadataKey] as\n | CommandMetadata\n | undefined\n if (metadata) {\n return metadata\n } else {\n const newMetadata: CommandMetadata = {\n path,\n description,\n optionsSchema,\n customAttributes: new Map<string | symbol, any>(),\n }\n context.metadata[CommandMetadataKey] = newMetadata\n // @ts-expect-error We add a custom metadata key to the target\n target[CommandMetadataKey] = newMetadata\n return newMetadata\n }\n }\n throw new Error('[Navios Commander] Wrong environment.')\n}\n\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 function extractCommandMetadata(target: ClassType): CommandMetadata {\n // @ts-expect-error We add a custom metadata key to the target\n const metadata = target[CommandMetadataKey] as CommandMetadata | undefined\n if (!metadata) {\n throw new Error(\n '[Navios Commander] Command metadata not found. Make sure to use @Command decorator.',\n )\n }\n return metadata\n}\n\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 function hasCommandMetadata(target: ClassType): boolean {\n // @ts-expect-error We add a custom metadata key to the target\n const metadata = target[CommandMetadataKey] as CommandMetadata | undefined\n return !!metadata\n}\n","import type { ClassType } from '@navios/core'\n\nimport { extractModuleMetadata } from '@navios/core'\n\n/**\n * Symbol key for storing commands in ModuleMetadata.customEntries.\n * Used by @CliModule to store command classes.\n *\n * @public\n */\nexport const CommandEntryKey = Symbol('CommandEntryKey')\n\n/**\n * Type for the command entry value stored in customEntries.\n *\n * @public\n */\nexport type CommandEntryValue = Set<ClassType>\n\n/**\n * Extracts commands from a module's metadata.\n * Returns empty set if no commands are defined.\n *\n * @param moduleClass - The module class decorated with @CliModule or @Module\n * @returns Set of command classes registered in the module\n *\n * @example\n * ```typescript\n * const commands = extractModuleCommands(AppModule)\n * for (const command of commands) {\n * console.log(command.name)\n * }\n * ```\n */\nexport function extractModuleCommands(moduleClass: ClassType): Set<ClassType> {\n const metadata = extractModuleMetadata(moduleClass)\n return (\n (metadata.customEntries.get(CommandEntryKey) as CommandEntryValue) ??\n new Set()\n )\n}\n","import { Injectable, InjectableScope, InjectionToken } from '@navios/core'\n\nimport type { ClassType, ClassTypeWithInstance, Registry } from '@navios/core'\nimport type { ZodObject } from 'zod'\n\nimport { getCommandMetadata } from '../metadata/index.mjs'\n\nimport type { CommandHandler } from '../interfaces/index.mjs'\n\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 schema for validating command options.\n * If provided, options will be validated and parsed according to this schema.\n */\n optionsSchema?: 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/**\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'\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 function Command({\n path,\n description,\n token,\n optionsSchema,\n priority,\n registry,\n}: CommandOptions) {\n return function (target: ClassType, context: ClassDecoratorContext) {\n if (context.kind !== 'class') {\n throw new Error('[Navios Commander] @Command decorator can only be used on classes.')\n }\n const tokenToUse =\n token ?? InjectionToken.create<ClassTypeWithInstance<CommandHandler<any>>>(target)\n\n if (context.metadata) {\n getCommandMetadata(target, context, path, description, optionsSchema)\n }\n // @ts-expect-error Injectable is callable\n return Injectable({\n token: tokenToUse,\n scope: InjectableScope.Singleton,\n priority,\n registry,\n })(target, context)\n }\n}\n"],"mappings":";;;;;;GAOA,MAAaA,qBAAqBC,OAAO,qBAAA;;;;;;;;;;;GAqCzC,SAAgBC,mBACdC,QACAC,SACAC,MACAC,aACAC,eAAyB;AAEzB,KAAIH,QAAQI,UAAU;EACpB,MAAMA,WAAWJ,QAAQI,SAASR;AAGlC,MAAIQ,SACF,QAAOA;OACF;GACL,MAAMC,cAA+B;IACnCJ;IACAC;IACAC;IACAG,kCAAkB,IAAIC,KAAAA;IACxB;AACAP,WAAQI,SAASR,sBAAsBS;AAEvCN,UAAOH,sBAAsBS;AAC7B,UAAOA;;;AAGX,OAAM,IAAIG,MAAM,wCAAA;;;;;;;;;;;;;;GAgBlB,SAAgBC,uBAAuBV,QAAiB;CAEtD,MAAMK,WAAWL,OAAOH;AACxB,KAAI,CAACQ,SACH,OAAM,IAAII,MACR,sFAAA;AAGJ,QAAOJ;;;;;;;GAST,SAAgBM,mBAAmBX,QAAiB;AAGlD,QAAO,CAAC,CADSA,OAAOH;;;;;;;;;;GC/F1B,MAAagB,kBAAkBC,OAAO,kBAAA;;;;;;;;;;;;;;;GAwBtC,SAAgBC,sBAAsBC,aAAsB;AAE1D,gDADuCA,YAAAA,CAE3BE,cAAcC,IAAIN,gBAAAA,oBAC5B,IAAIO,KAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GCuCR,SAAgBK,QAAQ,EACtBC,MACAC,aACAC,OACAC,eACAC,UACAC,YACe;AACf,QAAO,SAAUC,QAAmBC,SAA8B;AAChE,MAAIA,QAAQC,SAAS,QACnB,OAAM,IAAIC,MAAM,qEAAA;EAElB,MAAMC,aACJR,SAASL,4BAAec,OAAmDL,OAAAA;AAE7E,MAAIC,QAAQK,SACVd,oBAAmBQ,QAAQC,SAASP,MAAMC,aAAaE,cAAAA;AAGzD,sCAAkB;GAChBD,OAAOQ;GACPG,OAAOjB,6BAAgBkB;GACvBV;GACAC;GACF,CAAA,CAAGC,QAAQC,QAAAA"}