@navios/commander 0.5.0 → 0.5.2

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 (33) hide show
  1. package/README.md +37 -0
  2. package/dist/src/commander.application.d.mts.map +1 -1
  3. package/dist/src/index.d.mts +1 -0
  4. package/dist/src/index.d.mts.map +1 -1
  5. package/dist/src/interfaces/commander-execution-context.interface.d.mts +11 -0
  6. package/dist/src/interfaces/commander-execution-context.interface.d.mts.map +1 -0
  7. package/dist/src/interfaces/index.d.mts +1 -0
  8. package/dist/src/interfaces/index.d.mts.map +1 -1
  9. package/dist/src/services/cli-parser.service.d.mts +10 -0
  10. package/dist/src/services/cli-parser.service.d.mts.map +1 -1
  11. package/dist/src/tokens/execution-context.token.d.mts +5 -0
  12. package/dist/src/tokens/execution-context.token.d.mts.map +1 -0
  13. package/dist/src/tokens/index.d.mts +2 -0
  14. package/dist/src/tokens/index.d.mts.map +1 -0
  15. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  16. package/dist/tsconfig.tsbuildinfo +1 -1
  17. package/lib/_tsup-dts-rollup.d.mts +33 -0
  18. package/lib/_tsup-dts-rollup.d.ts +33 -0
  19. package/lib/index.d.mts +3 -0
  20. package/lib/index.d.ts +3 -0
  21. package/lib/index.js +108 -7
  22. package/lib/index.js.map +1 -1
  23. package/lib/index.mjs +107 -9
  24. package/lib/index.mjs.map +1 -1
  25. package/package.json +1 -1
  26. package/src/commander.application.mts +32 -8
  27. package/src/index.mts +1 -0
  28. package/src/interfaces/commander-execution-context.interface.mts +21 -0
  29. package/src/interfaces/index.mts +1 -0
  30. package/src/services/__tests__/cli-parser.service.spec.mts +251 -0
  31. package/src/services/cli-parser.service.mts +81 -2
  32. package/src/tokens/execution-context.token.mts +10 -0
  33. package/src/tokens/index.mts +1 -0
package/lib/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { Injectable, inject, Container, InjectionToken, InjectableScope } from '@navios/di';
1
+ import { Injectable, InjectionToken, inject, Container, InjectableScope } from '@navios/di';
2
2
  export * from '@navios/di';
3
3
 
4
4
  var __create = Object.create;
@@ -33,6 +33,24 @@ var __decorateElement = (array, flags, name, decorators, target, extra) => {
33
33
  return __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
34
34
  };
35
35
 
36
+ // src/interfaces/commander-execution-context.interface.mts
37
+ var CommanderExecutionContext = class {
38
+ constructor(command, commandPath, options) {
39
+ this.command = command;
40
+ this.commandPath = commandPath;
41
+ this.options = options;
42
+ }
43
+ getCommand() {
44
+ return this.command;
45
+ }
46
+ getCommandPath() {
47
+ return this.commandPath;
48
+ }
49
+ getOptions() {
50
+ return this.options;
51
+ }
52
+ };
53
+
36
54
  // src/metadata/command.metadata.mts
37
55
  var CommandMetadataKey = Symbol("CommandMetadataKey");
38
56
  function getCommandMetadata(target, context, path, optionsSchema) {
@@ -209,6 +227,7 @@ var CliParserService = class {
209
227
  throw new Error("[Navios Commander] No command provided");
210
228
  }
211
229
  const booleanFields = optionsSchema ? this.extractBooleanFields(optionsSchema) : /* @__PURE__ */ new Set();
230
+ const arrayFields = optionsSchema ? this.extractArrayFields(optionsSchema) : /* @__PURE__ */ new Set();
212
231
  const commandParts = [];
213
232
  let i = 0;
214
233
  while (i < args.length && !args[i].startsWith("-")) {
@@ -229,15 +248,31 @@ var CliParserService = class {
229
248
  if (equalIndex !== -1) {
230
249
  const optionName = key.slice(0, equalIndex);
231
250
  const optionValue = key.slice(equalIndex + 1);
232
- options[this.camelCase(optionName)] = this.parseValue(optionValue);
251
+ const camelCaseKey = this.camelCase(optionName);
252
+ const isArray = arrayFields.has(camelCaseKey) || arrayFields.has(optionName);
253
+ if (isArray) {
254
+ if (!options[camelCaseKey]) {
255
+ options[camelCaseKey] = [];
256
+ }
257
+ options[camelCaseKey].push(this.parseValue(optionValue));
258
+ } else {
259
+ options[camelCaseKey] = this.parseValue(optionValue);
260
+ }
233
261
  i++;
234
262
  } else {
235
263
  const camelCaseKey = this.camelCase(key);
236
264
  const isBoolean = booleanFields.has(camelCaseKey) || booleanFields.has(key);
265
+ const isArray = arrayFields.has(camelCaseKey) || arrayFields.has(key);
237
266
  const nextArg = args[i + 1];
238
267
  if (isBoolean) {
239
268
  options[camelCaseKey] = true;
240
269
  i++;
270
+ } else if (isArray && nextArg && !nextArg.startsWith("-")) {
271
+ if (!options[camelCaseKey]) {
272
+ options[camelCaseKey] = [];
273
+ }
274
+ options[camelCaseKey].push(this.parseValue(nextArg));
275
+ i += 2;
241
276
  } else if (nextArg && !nextArg.startsWith("-")) {
242
277
  options[camelCaseKey] = this.parseValue(nextArg);
243
278
  i += 2;
@@ -250,10 +285,17 @@ var CliParserService = class {
250
285
  const flags = arg.slice(1);
251
286
  if (flags.length === 1) {
252
287
  const isBoolean = booleanFields.has(flags);
288
+ const isArray = arrayFields.has(flags);
253
289
  const nextArg = args[i + 1];
254
290
  if (isBoolean) {
255
291
  options[flags] = true;
256
292
  i++;
293
+ } else if (isArray && nextArg && !nextArg.startsWith("-")) {
294
+ if (!options[flags]) {
295
+ options[flags] = [];
296
+ }
297
+ options[flags].push(this.parseValue(nextArg));
298
+ i += 2;
257
299
  } else if (nextArg && !nextArg.startsWith("-")) {
258
300
  options[flags] = this.parseValue(nextArg);
259
301
  i += 2;
@@ -329,6 +371,28 @@ var CliParserService = class {
329
371
  }
330
372
  return booleanFields;
331
373
  }
374
+ /**
375
+ * Extracts array field names from a Zod schema
376
+ * Handles ZodObject, ZodOptional, and ZodDefault wrappers
377
+ */
378
+ extractArrayFields(schema) {
379
+ const arrayFields = /* @__PURE__ */ new Set();
380
+ try {
381
+ const typeName = schema.def.type;
382
+ if (typeName === "object") {
383
+ const shape = schema.def.shape;
384
+ if (shape && typeof shape === "object") {
385
+ for (const [key, fieldSchema] of Object.entries(shape)) {
386
+ if (this.isSchemaArray(fieldSchema)) {
387
+ arrayFields.add(key);
388
+ }
389
+ }
390
+ }
391
+ }
392
+ } catch {
393
+ }
394
+ return arrayFields;
395
+ }
332
396
  /**
333
397
  * Checks if a Zod schema represents a boolean type
334
398
  * Unwraps ZodOptional and ZodDefault
@@ -346,6 +410,23 @@ var CliParserService = class {
346
410
  return false;
347
411
  }
348
412
  }
413
+ /**
414
+ * Checks if a Zod schema represents an array type
415
+ * Unwraps ZodOptional and ZodDefault
416
+ */
417
+ isSchemaArray(schema) {
418
+ try {
419
+ let currentSchema = schema;
420
+ const typeName = currentSchema.def.type;
421
+ if (typeName === "optional" || typeName === "default") {
422
+ currentSchema = currentSchema?._def?.innerType || currentSchema;
423
+ }
424
+ const innerTypeName = currentSchema.def.type;
425
+ return innerTypeName === "array";
426
+ } catch {
427
+ return false;
428
+ }
429
+ }
349
430
  /**
350
431
  * Formats help text for available commands
351
432
  */
@@ -360,6 +441,10 @@ var CliParserService = class {
360
441
  _init2 = __decoratorStart();
361
442
  CliParserService = __decorateElement(_init2, 0, "CliParserService", _CliParserService_decorators, CliParserService);
362
443
  __runInitializers(_init2, 1, CliParserService);
444
+ var ExecutionContextInjectionToken = "CommanderExecutionContextInjectionToken";
445
+ var ExecutionContext = InjectionToken.create(
446
+ ExecutionContextInjectionToken
447
+ );
363
448
 
364
449
  // src/commander.application.mts
365
450
  var _CommanderApplication_decorators, _init3;
@@ -402,15 +487,28 @@ var CommanderApplication = class {
402
487
  if (metadata.optionsSchema) {
403
488
  validatedOptions = metadata.optionsSchema.parse(options);
404
489
  }
405
- const commandInstance = await this.container.get(
406
- commandClass
490
+ const executionContext = new CommanderExecutionContext(
491
+ metadata,
492
+ commandPath,
493
+ validatedOptions
407
494
  );
408
- if (!commandInstance.execute) {
409
- throw new Error(
410
- `[Navios Commander] Command ${commandPath} does not implement execute method`
495
+ const requestId = `cmd-${Date.now()}-${Math.random().toString(36).substring(7)}`;
496
+ const requestContext = this.container.beginRequest(requestId);
497
+ requestContext.addInstance(ExecutionContext, executionContext);
498
+ try {
499
+ this.container.setCurrentRequestContext(requestId);
500
+ const commandInstance = await this.container.get(
501
+ commandClass
411
502
  );
503
+ if (!commandInstance.execute) {
504
+ throw new Error(
505
+ `[Navios Commander] Command ${commandPath} does not implement execute method`
506
+ );
507
+ }
508
+ await commandInstance.execute(validatedOptions);
509
+ } finally {
510
+ await this.container.endRequest(requestId);
412
511
  }
413
- await commandInstance.execute(validatedOptions);
414
512
  }
415
513
  getAllCommands() {
416
514
  const commandsMap = this.moduleLoader.getAllCommandsWithMetadata();
@@ -519,6 +617,6 @@ function CliModule({ commands = [], imports = [] } = {
519
617
  };
520
618
  }
521
619
 
522
- export { CliModule, CliModuleMetadataKey, CliParserService, Command, CommandMetadataKey, CommanderApplication, CommanderFactory, ModuleLoaderService, extractCliModuleMetadata, extractCommandMetadata, getCliModuleMetadata, getCommandMetadata, hasCliModuleMetadata, hasCommandMetadata };
620
+ export { CliModule, CliModuleMetadataKey, CliParserService, Command, CommandMetadataKey, CommanderApplication, CommanderExecutionContext, CommanderFactory, ExecutionContext, ExecutionContextInjectionToken, ModuleLoaderService, extractCliModuleMetadata, extractCommandMetadata, getCliModuleMetadata, getCommandMetadata, hasCliModuleMetadata, hasCommandMetadata };
523
621
  //# sourceMappingURL=index.mjs.map
524
622
  //# sourceMappingURL=index.mjs.map
package/lib/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/metadata/command.metadata.mts","../src/metadata/cli-module.metadata.mts","../src/services/module-loader.service.mts","../src/services/cli-parser.service.mts","../src/commander.application.mts","../src/commander.factory.mts","../src/decorators/command.decorator.mts","../src/decorators/cli-module.decorator.mts"],"names":["_init","Injectable","inject","Container","InjectionToken","InjectableScope"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { ClassType } from '@navios/di'\nimport type { ZodObject } from 'zod'\n\nexport const CommandMetadataKey = Symbol('CommandMetadataKey')\n\nexport interface CommandMetadata {\n path: string\n optionsSchema?: ZodObject\n customAttributes: Map<string | symbol, any>\n}\n\nexport function getCommandMetadata(\n target: ClassType,\n context: ClassDecoratorContext,\n path: 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 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\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\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/di'\n\nexport const CliModuleMetadataKey = Symbol('CliModuleMetadataKey')\n\nexport interface CliModuleMetadata {\n commands: Set<ClassType>\n imports: Set<ClassType>\n customAttributes: Map<string | symbol, any>\n}\n\nexport function getCliModuleMetadata(\n target: ClassType,\n context: ClassDecoratorContext,\n): CliModuleMetadata {\n if (context.metadata) {\n const metadata = context.metadata[CliModuleMetadataKey] as\n | CliModuleMetadata\n | undefined\n if (metadata) {\n return metadata\n } else {\n const newMetadata: CliModuleMetadata = {\n commands: new Set<ClassType>(),\n imports: new Set<ClassType>(),\n customAttributes: new Map<string | symbol, any>(),\n }\n context.metadata[CliModuleMetadataKey] = newMetadata\n // @ts-expect-error We add a custom metadata key to the target\n target[CliModuleMetadataKey] = newMetadata\n return newMetadata\n }\n }\n throw new Error('[Navios Commander] Wrong environment.')\n}\n\nexport function extractCliModuleMetadata(\n target: ClassType,\n): CliModuleMetadata {\n // @ts-expect-error We add a custom metadata key to the target\n const metadata = target[CliModuleMetadataKey] as\n | CliModuleMetadata\n | undefined\n if (!metadata) {\n throw new Error(\n `[Navios Commander] Module metadata not found for ${target.name}. Make sure to use @CliModule decorator.`,\n )\n }\n return metadata\n}\n\nexport function hasCliModuleMetadata(target: ClassType): boolean {\n // @ts-expect-error We add a custom metadata key to the target\n return !!target[CliModuleMetadataKey]\n}\n","import type { ClassTypeWithInstance } from '@navios/di'\n\nimport { Container, inject, Injectable } from '@navios/di'\n\nimport type { CommandHandler, Module } from '../interfaces/index.mjs'\nimport type { CliModuleMetadata, CommandMetadata } from '../metadata/index.mjs'\n\nimport {\n extractCliModuleMetadata,\n extractCommandMetadata,\n} from '../metadata/index.mjs'\n\nexport interface CommandWithMetadata {\n class: ClassTypeWithInstance<CommandHandler>\n metadata: CommandMetadata\n}\n\n@Injectable()\nexport class ModuleLoaderService {\n protected container = inject(Container)\n private modulesMetadata: Map<string, CliModuleMetadata> = new Map()\n private loadedModules: Map<string, any> = new Map()\n private commandsMetadata: Map<string, CommandWithMetadata> = new Map()\n private initialized = false\n\n async loadModules(appModule: ClassTypeWithInstance<Module>) {\n if (this.initialized) {\n return\n }\n await this.traverseModules(appModule)\n this.initialized = true\n }\n\n private async traverseModules(\n module: ClassTypeWithInstance<Module>,\n parentMetadata?: CliModuleMetadata,\n ) {\n const metadata = extractCliModuleMetadata(module)\n if (parentMetadata) {\n this.mergeMetadata(metadata, parentMetadata)\n }\n const moduleName = module.name\n if (this.modulesMetadata.has(moduleName)) {\n return\n }\n this.modulesMetadata.set(moduleName, metadata)\n\n // Collect command metadata during module loading\n for (const command of metadata.commands) {\n const commandMetadata = extractCommandMetadata(command)\n this.commandsMetadata.set(commandMetadata.path, {\n class: command,\n metadata: commandMetadata,\n })\n }\n\n const imports = metadata.imports ?? new Set()\n const loadingPromises = Array.from(imports).map(async (importedModule) =>\n this.traverseModules(importedModule, metadata),\n )\n await Promise.all(loadingPromises)\n const instance = await this.container.get(module)\n if (instance.onModuleInit) {\n await instance.onModuleInit()\n }\n this.loadedModules.set(moduleName, instance)\n }\n\n private mergeMetadata(\n metadata: CliModuleMetadata,\n parentMetadata: CliModuleMetadata,\n ): void {\n if (parentMetadata.customAttributes) {\n for (const [key, value] of parentMetadata.customAttributes) {\n if (metadata.customAttributes.has(key)) {\n continue\n }\n metadata.customAttributes.set(key, value)\n }\n }\n }\n\n getAllModules(): Map<string, CliModuleMetadata> {\n return this.modulesMetadata\n }\n\n getAllCommands(): Map<string, ClassTypeWithInstance<any>> {\n const commands = new Map<string, ClassTypeWithInstance<any>>()\n for (const metadata of this.modulesMetadata.values()) {\n for (const command of metadata.commands) {\n commands.set(command.name, command)\n }\n }\n return commands\n }\n\n /**\n * Get all commands with their metadata, indexed by command path.\n * This is populated during loadModules, so path information is available\n * before parsing CLI argv.\n */\n getAllCommandsWithMetadata(): Map<string, CommandWithMetadata> {\n return this.commandsMetadata\n }\n\n /**\n * Get a command by its path, with metadata already extracted.\n * Returns undefined if command is not found.\n */\n getCommandByPath(path: string): CommandWithMetadata | undefined {\n return this.commandsMetadata.get(path)\n }\n\n dispose() {\n this.modulesMetadata.clear()\n this.loadedModules.clear()\n this.commandsMetadata.clear()\n this.initialized = false\n }\n}\n","import type { ZodObject, ZodType } from 'zod'\n\nimport { Injectable } from '@navios/di'\n\nexport interface ParsedCliArgs {\n command: string\n options: Record<string, any>\n positionals: string[]\n}\n\n@Injectable()\nexport class CliParserService {\n /**\n * Parses command-line arguments from process.argv\n * Commands can be multi-word (e.g., 'db migrate', 'cache clear')\n * Expected format: node script.js command [subcommand...] --flag value --boolean-flag positional1 positional2\n *\n * @param argv - Array of command-line arguments (typically process.argv)\n * @param optionsSchema - Optional Zod schema to determine boolean flags and option types\n * @returns Parsed command (space-separated if multi-word), options, and positional arguments\n */\n parse(argv: string[], optionsSchema?: ZodObject): ParsedCliArgs {\n // Skip first two args (node and script path)\n const args = argv.slice(2)\n\n if (args.length === 0) {\n throw new Error('[Navios Commander] No command provided')\n }\n\n // Extract boolean field names from schema for accurate parsing\n const booleanFields = optionsSchema\n ? this.extractBooleanFields(optionsSchema)\n : new Set<string>()\n\n // Collect command words until we hit an argument that starts with '-' or '--'\n const commandParts: string[] = []\n let i = 0\n while (i < args.length && !args[i].startsWith('-')) {\n commandParts.push(args[i])\n i++\n }\n\n if (commandParts.length === 0) {\n throw new Error('[Navios Commander] No command provided')\n }\n\n const command = commandParts.join(' ')\n const options: Record<string, any> = {}\n const positionals: string[] = []\n while (i < args.length) {\n const arg = args[i]\n\n if (arg.startsWith('--')) {\n // Long option format: --key=value or --key value\n const key = arg.slice(2)\n const equalIndex = key.indexOf('=')\n\n if (equalIndex !== -1) {\n // Format: --key=value\n const optionName = key.slice(0, equalIndex)\n const optionValue = key.slice(equalIndex + 1)\n options[this.camelCase(optionName)] = this.parseValue(optionValue)\n i++\n } else {\n // Format: --key value or --boolean-flag\n const camelCaseKey = this.camelCase(key)\n const isBoolean =\n booleanFields.has(camelCaseKey) || booleanFields.has(key)\n const nextArg = args[i + 1]\n\n if (isBoolean) {\n // Known boolean flag from schema\n options[camelCaseKey] = true\n i++\n } else if (nextArg && !nextArg.startsWith('-')) {\n // Has a value\n options[camelCaseKey] = this.parseValue(nextArg)\n i += 2\n } else {\n // Assume boolean flag\n options[camelCaseKey] = true\n i++\n }\n }\n } else if (arg.startsWith('-') && arg.length > 1 && arg !== '-') {\n // Short option format: -k value or -abc (multiple flags)\n const flags = arg.slice(1)\n\n if (flags.length === 1) {\n // Single short flag: -k value or -k\n const isBoolean = booleanFields.has(flags)\n const nextArg = args[i + 1]\n\n if (isBoolean) {\n // Known boolean flag from schema\n options[flags] = true\n i++\n } else if (nextArg && !nextArg.startsWith('-')) {\n options[flags] = this.parseValue(nextArg)\n i += 2\n } else {\n options[flags] = true\n i++\n }\n } else {\n // Multiple short flags: -abc -> {a: true, b: true, c: true}\n for (const flag of flags) {\n options[flag] = true\n }\n i++\n }\n } else {\n // Positional argument\n positionals.push(arg)\n i++\n }\n }\n\n return {\n command,\n options,\n positionals,\n }\n }\n\n /**\n * Converts kebab-case to camelCase\n */\n private camelCase(str: string): string {\n return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())\n }\n\n /**\n * Attempts to parse string values into appropriate types\n */\n private parseValue(value: string): any {\n // Check for boolean\n if (value === 'true') return true\n if (value === 'false') return false\n\n // Check for null/undefined\n if (value === 'null') return null\n if (value === 'undefined') return undefined\n\n // Check for number\n if (/^-?\\d+$/.test(value)) {\n return parseInt(value, 10)\n }\n if (/^-?\\d+\\.\\d+$/.test(value)) {\n return parseFloat(value)\n }\n\n // Check for JSON\n if (\n (value.startsWith('{') && value.endsWith('}')) ||\n (value.startsWith('[') && value.endsWith(']'))\n ) {\n try {\n return JSON.parse(value)\n } catch {\n // If parsing fails, return as string\n return value\n }\n }\n\n // Return as string\n return value\n }\n\n /**\n * Extracts boolean field names from a Zod schema\n * Handles ZodObject, ZodOptional, and ZodDefault wrappers\n */\n private extractBooleanFields(schema: ZodObject): Set<string> {\n const booleanFields = new Set<string>()\n\n try {\n // Check if schema has _def.typeName (Zod schema structure)\n const typeName = schema.def.type\n\n if (typeName === 'object') {\n // Extract shape from ZodObject\n const shape = schema.def.shape\n\n if (shape && typeof shape === 'object') {\n for (const [key, fieldSchema] of Object.entries(shape)) {\n if (this.isSchemaBoolean(fieldSchema as any)) {\n booleanFields.add(key)\n }\n }\n }\n }\n } catch {\n // Silently fail if schema introspection fails\n }\n\n return booleanFields\n }\n\n /**\n * Checks if a Zod schema represents a boolean type\n * Unwraps ZodOptional and ZodDefault\n */\n private isSchemaBoolean(schema: ZodType): boolean {\n try {\n let currentSchema = schema\n const typeName = currentSchema.def.type\n\n // Unwrap ZodOptional and ZodDefault\n if (typeName === 'optional' || typeName === 'default') {\n currentSchema = (currentSchema as any)?._def?.innerType || currentSchema\n }\n\n const innerTypeName = currentSchema.def.type\n return innerTypeName === 'boolean'\n } catch {\n return false\n }\n }\n\n /**\n * Formats help text for available commands\n */\n formatCommandList(commands: Array<{ path: string; class: any }>): string {\n const lines = ['Available commands:', '']\n for (const { path } of commands) {\n lines.push(` ${path}`)\n }\n return lines.join('\\n')\n }\n}\n","import type { ClassTypeWithInstance, InjectionToken } from '@navios/di'\n\nimport { Container, inject, Injectable } from '@navios/di'\n\nimport type { CommandHandler, Module } from './interfaces/index.mjs'\n\nimport { CliParserService, ModuleLoaderService } from './services/index.mjs'\n\nexport interface CommanderApplicationOptions {}\n\n@Injectable()\nexport class CommanderApplication {\n private moduleLoader = inject(ModuleLoaderService)\n private cliParser = inject(CliParserService)\n protected container = inject(Container)\n\n private appModule: ClassTypeWithInstance<Module> | null = null\n private options: CommanderApplicationOptions = {}\n\n isInitialized = false\n\n async setup(\n appModule: ClassTypeWithInstance<Module>,\n options: CommanderApplicationOptions = {},\n ) {\n this.appModule = appModule\n this.options = options\n }\n\n getContainer() {\n return this.container\n }\n\n async init() {\n if (!this.appModule) {\n throw new Error(\n '[Navios Commander] App module is not set. Call setup() first.',\n )\n }\n await this.moduleLoader.loadModules(this.appModule)\n this.isInitialized = true\n }\n\n async executeCommand(commandPath: string, options: any = {}) {\n if (!this.isInitialized) {\n throw new Error(\n '[Navios Commander] Application is not initialized. Call init() first.',\n )\n }\n\n // Use pre-collected command metadata from module loading\n const commandWithMetadata = this.moduleLoader.getCommandByPath(commandPath)\n\n if (!commandWithMetadata) {\n throw new Error(`[Navios Commander] Command not found: ${commandPath}`)\n }\n\n const { class: commandClass, metadata } = commandWithMetadata\n\n // Validate options with zod schema if provided\n let validatedOptions = options\n if (metadata.optionsSchema) {\n validatedOptions = metadata.optionsSchema.parse(options)\n }\n\n // Get command instance and execute\n const commandInstance = await this.container.get<CommandHandler>(\n commandClass as unknown as InjectionToken<CommandHandler>,\n )\n\n if (!commandInstance.execute) {\n throw new Error(\n `[Navios Commander] Command ${commandPath} does not implement execute method`,\n )\n }\n\n await commandInstance.execute(validatedOptions)\n }\n\n getAllCommands() {\n // Use pre-collected command metadata from module loading\n const commandsMap = this.moduleLoader.getAllCommandsWithMetadata()\n const commandsWithMetadata: Array<{\n path: string\n class: ClassTypeWithInstance<any>\n }> = []\n\n for (const [, { class: cmd, metadata }] of commandsMap) {\n commandsWithMetadata.push({\n path: metadata.path,\n class: cmd,\n })\n }\n\n return commandsWithMetadata\n }\n\n /**\n * Runs the CLI application by parsing process.argv and executing the command\n * @param argv - Command-line arguments (defaults to process.argv)\n */\n async run(argv: string[] = process.argv) {\n if (!this.isInitialized) {\n throw new Error(\n '[Navios Commander] Application is not initialized. Call init() first.',\n )\n }\n\n try {\n // First, try to extract the command path to get its schema\n // We need to do a preliminary parse to find the command\n const preliminaryParse = this.cliParser.parse(argv)\n const commandWithMetadata = this.moduleLoader.getCommandByPath(\n preliminaryParse.command,\n )\n\n // Re-parse with schema if available\n const parsed = commandWithMetadata?.metadata.optionsSchema\n ? this.cliParser.parse(argv, commandWithMetadata.metadata.optionsSchema)\n : preliminaryParse\n\n // Handle special commands\n if (\n parsed.command === 'help' ||\n parsed.options.help ||\n parsed.options.h\n ) {\n const commands = this.getAllCommands()\n console.log(this.cliParser.formatCommandList(commands))\n return\n }\n\n // Execute the command\n await this.executeCommand(parsed.command, parsed.options)\n } catch (error) {\n if (error instanceof Error) {\n console.error(`Error: ${error.message}`)\n\n // Show available commands on error\n if (error.message.includes('Command not found')) {\n console.log(\n '\\n' + this.cliParser.formatCommandList(this.getAllCommands()),\n )\n }\n }\n throw error\n }\n }\n\n async dispose() {\n if (this.moduleLoader) {\n this.moduleLoader.dispose()\n }\n }\n\n async close() {\n await this.dispose()\n }\n}\n","import type { ClassTypeWithInstance } from '@navios/di'\n\nimport { Container } from '@navios/di'\n\nimport type { CommanderApplicationOptions } from './commander.application.mjs'\nimport type { Module } from './interfaces/index.mjs'\n\nimport { CommanderApplication } from './commander.application.mjs'\n\nexport class CommanderFactory {\n static async create(\n appModule: ClassTypeWithInstance<Module>,\n options: CommanderApplicationOptions = {},\n ) {\n const container = new Container()\n const app = await container.get(CommanderApplication)\n await app.setup(appModule, options)\n return app\n }\n}\n","import type { ClassType } from '@navios/di'\nimport type { ZodObject } from 'zod'\n\nimport { Injectable, InjectableScope, InjectionToken } from '@navios/di'\n\nimport { getCommandMetadata } from '../metadata/index.mjs'\n\nexport interface CommandOptions {\n path: string\n optionsSchema?: ZodObject\n}\n\nexport function Command({ path, optionsSchema }: CommandOptions) {\n return function (target: ClassType, context: ClassDecoratorContext) {\n if (context.kind !== 'class') {\n throw new Error(\n '[Navios Commander] @Command decorator can only be used on classes.',\n )\n }\n const token = InjectionToken.create(target)\n if (context.metadata) {\n getCommandMetadata(target, context, path, optionsSchema)\n }\n return Injectable({\n token,\n scope: InjectableScope.Singleton,\n })(target, context)\n }\n}\n","import type { ClassType } from '@navios/di'\n\nimport { Injectable, InjectableScope, InjectionToken } from '@navios/di'\n\nimport { getCliModuleMetadata } from '../metadata/index.mjs'\n\nexport interface CliModuleOptions {\n commands?: ClassType[] | Set<ClassType>\n imports?: ClassType[] | Set<ClassType>\n}\n\nexport function CliModule(\n { commands = [], imports = [] }: CliModuleOptions = {\n commands: [],\n imports: [],\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 // Register the module in the service locator\n const token = InjectionToken.create(target)\n const moduleMetadata = getCliModuleMetadata(target, context)\n for (const command of commands) {\n moduleMetadata.commands.add(command)\n }\n for (const importedModule of imports) {\n moduleMetadata.imports.add(importedModule)\n }\n\n return Injectable({\n token,\n scope: InjectableScope.Singleton,\n })(target, context)\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/interfaces/commander-execution-context.interface.mts","../src/metadata/command.metadata.mts","../src/metadata/cli-module.metadata.mts","../src/services/module-loader.service.mts","../src/services/cli-parser.service.mts","../src/tokens/execution-context.token.mts","../src/commander.application.mts","../src/commander.factory.mts","../src/decorators/command.decorator.mts","../src/decorators/cli-module.decorator.mts"],"names":["_init","Injectable","inject","Container","InjectionToken","InjectableScope"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { CommandMetadata } from '../metadata/command.metadata.mjs'\n\nexport class CommanderExecutionContext {\n constructor(\n private readonly command: CommandMetadata,\n private readonly commandPath: string,\n private readonly options: any,\n ) {}\n\n getCommand(): CommandMetadata {\n return this.command\n }\n\n getCommandPath(): string {\n return this.commandPath\n }\n\n getOptions(): any {\n return this.options\n }\n}\n","import type { ClassType } from '@navios/di'\nimport type { ZodObject } from 'zod'\n\nexport const CommandMetadataKey = Symbol('CommandMetadataKey')\n\nexport interface CommandMetadata {\n path: string\n optionsSchema?: ZodObject\n customAttributes: Map<string | symbol, any>\n}\n\nexport function getCommandMetadata(\n target: ClassType,\n context: ClassDecoratorContext,\n path: 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 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\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\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/di'\n\nexport const CliModuleMetadataKey = Symbol('CliModuleMetadataKey')\n\nexport interface CliModuleMetadata {\n commands: Set<ClassType>\n imports: Set<ClassType>\n customAttributes: Map<string | symbol, any>\n}\n\nexport function getCliModuleMetadata(\n target: ClassType,\n context: ClassDecoratorContext,\n): CliModuleMetadata {\n if (context.metadata) {\n const metadata = context.metadata[CliModuleMetadataKey] as\n | CliModuleMetadata\n | undefined\n if (metadata) {\n return metadata\n } else {\n const newMetadata: CliModuleMetadata = {\n commands: new Set<ClassType>(),\n imports: new Set<ClassType>(),\n customAttributes: new Map<string | symbol, any>(),\n }\n context.metadata[CliModuleMetadataKey] = newMetadata\n // @ts-expect-error We add a custom metadata key to the target\n target[CliModuleMetadataKey] = newMetadata\n return newMetadata\n }\n }\n throw new Error('[Navios Commander] Wrong environment.')\n}\n\nexport function extractCliModuleMetadata(\n target: ClassType,\n): CliModuleMetadata {\n // @ts-expect-error We add a custom metadata key to the target\n const metadata = target[CliModuleMetadataKey] as\n | CliModuleMetadata\n | undefined\n if (!metadata) {\n throw new Error(\n `[Navios Commander] Module metadata not found for ${target.name}. Make sure to use @CliModule decorator.`,\n )\n }\n return metadata\n}\n\nexport function hasCliModuleMetadata(target: ClassType): boolean {\n // @ts-expect-error We add a custom metadata key to the target\n return !!target[CliModuleMetadataKey]\n}\n","import type { ClassTypeWithInstance } from '@navios/di'\n\nimport { Container, inject, Injectable } from '@navios/di'\n\nimport type { CommandHandler, Module } from '../interfaces/index.mjs'\nimport type { CliModuleMetadata, CommandMetadata } from '../metadata/index.mjs'\n\nimport {\n extractCliModuleMetadata,\n extractCommandMetadata,\n} from '../metadata/index.mjs'\n\nexport interface CommandWithMetadata {\n class: ClassTypeWithInstance<CommandHandler>\n metadata: CommandMetadata\n}\n\n@Injectable()\nexport class ModuleLoaderService {\n protected container = inject(Container)\n private modulesMetadata: Map<string, CliModuleMetadata> = new Map()\n private loadedModules: Map<string, any> = new Map()\n private commandsMetadata: Map<string, CommandWithMetadata> = new Map()\n private initialized = false\n\n async loadModules(appModule: ClassTypeWithInstance<Module>) {\n if (this.initialized) {\n return\n }\n await this.traverseModules(appModule)\n this.initialized = true\n }\n\n private async traverseModules(\n module: ClassTypeWithInstance<Module>,\n parentMetadata?: CliModuleMetadata,\n ) {\n const metadata = extractCliModuleMetadata(module)\n if (parentMetadata) {\n this.mergeMetadata(metadata, parentMetadata)\n }\n const moduleName = module.name\n if (this.modulesMetadata.has(moduleName)) {\n return\n }\n this.modulesMetadata.set(moduleName, metadata)\n\n // Collect command metadata during module loading\n for (const command of metadata.commands) {\n const commandMetadata = extractCommandMetadata(command)\n this.commandsMetadata.set(commandMetadata.path, {\n class: command,\n metadata: commandMetadata,\n })\n }\n\n const imports = metadata.imports ?? new Set()\n const loadingPromises = Array.from(imports).map(async (importedModule) =>\n this.traverseModules(importedModule, metadata),\n )\n await Promise.all(loadingPromises)\n const instance = await this.container.get(module)\n if (instance.onModuleInit) {\n await instance.onModuleInit()\n }\n this.loadedModules.set(moduleName, instance)\n }\n\n private mergeMetadata(\n metadata: CliModuleMetadata,\n parentMetadata: CliModuleMetadata,\n ): void {\n if (parentMetadata.customAttributes) {\n for (const [key, value] of parentMetadata.customAttributes) {\n if (metadata.customAttributes.has(key)) {\n continue\n }\n metadata.customAttributes.set(key, value)\n }\n }\n }\n\n getAllModules(): Map<string, CliModuleMetadata> {\n return this.modulesMetadata\n }\n\n getAllCommands(): Map<string, ClassTypeWithInstance<any>> {\n const commands = new Map<string, ClassTypeWithInstance<any>>()\n for (const metadata of this.modulesMetadata.values()) {\n for (const command of metadata.commands) {\n commands.set(command.name, command)\n }\n }\n return commands\n }\n\n /**\n * Get all commands with their metadata, indexed by command path.\n * This is populated during loadModules, so path information is available\n * before parsing CLI argv.\n */\n getAllCommandsWithMetadata(): Map<string, CommandWithMetadata> {\n return this.commandsMetadata\n }\n\n /**\n * Get a command by its path, with metadata already extracted.\n * Returns undefined if command is not found.\n */\n getCommandByPath(path: string): CommandWithMetadata | undefined {\n return this.commandsMetadata.get(path)\n }\n\n dispose() {\n this.modulesMetadata.clear()\n this.loadedModules.clear()\n this.commandsMetadata.clear()\n this.initialized = false\n }\n}\n","import type { ZodObject, ZodType } from 'zod'\n\nimport { Injectable } from '@navios/di'\n\nexport interface ParsedCliArgs {\n command: string\n options: Record<string, any>\n positionals: string[]\n}\n\n@Injectable()\nexport class CliParserService {\n /**\n * Parses command-line arguments from process.argv\n * Commands can be multi-word (e.g., 'db migrate', 'cache clear')\n * Expected format: node script.js command [subcommand...] --flag value --boolean-flag positional1 positional2\n *\n * @param argv - Array of command-line arguments (typically process.argv)\n * @param optionsSchema - Optional Zod schema to determine boolean flags and option types\n * @returns Parsed command (space-separated if multi-word), options, and positional arguments\n */\n parse(argv: string[], optionsSchema?: ZodObject): ParsedCliArgs {\n // Skip first two args (node and script path)\n const args = argv.slice(2)\n\n if (args.length === 0) {\n throw new Error('[Navios Commander] No command provided')\n }\n\n // Extract boolean and array field names from schema for accurate parsing\n const booleanFields = optionsSchema\n ? this.extractBooleanFields(optionsSchema)\n : new Set<string>()\n const arrayFields = optionsSchema\n ? this.extractArrayFields(optionsSchema)\n : new Set<string>()\n\n // Collect command words until we hit an argument that starts with '-' or '--'\n const commandParts: string[] = []\n let i = 0\n while (i < args.length && !args[i].startsWith('-')) {\n commandParts.push(args[i])\n i++\n }\n\n if (commandParts.length === 0) {\n throw new Error('[Navios Commander] No command provided')\n }\n\n const command = commandParts.join(' ')\n const options: Record<string, any> = {}\n const positionals: string[] = []\n while (i < args.length) {\n const arg = args[i]\n\n if (arg.startsWith('--')) {\n // Long option format: --key=value or --key value\n const key = arg.slice(2)\n const equalIndex = key.indexOf('=')\n\n if (equalIndex !== -1) {\n // Format: --key=value\n const optionName = key.slice(0, equalIndex)\n const optionValue = key.slice(equalIndex + 1)\n const camelCaseKey = this.camelCase(optionName)\n const isArray = arrayFields.has(camelCaseKey) || arrayFields.has(optionName)\n\n if (isArray) {\n // For array fields, accumulate values\n if (!options[camelCaseKey]) {\n options[camelCaseKey] = []\n }\n options[camelCaseKey].push(this.parseValue(optionValue))\n } else {\n options[camelCaseKey] = this.parseValue(optionValue)\n }\n i++\n } else {\n // Format: --key value or --boolean-flag\n const camelCaseKey = this.camelCase(key)\n const isBoolean =\n booleanFields.has(camelCaseKey) || booleanFields.has(key)\n const isArray = arrayFields.has(camelCaseKey) || arrayFields.has(key)\n const nextArg = args[i + 1]\n\n if (isBoolean) {\n // Known boolean flag from schema\n options[camelCaseKey] = true\n i++\n } else if (isArray && nextArg && !nextArg.startsWith('-')) {\n // Known array field from schema - accumulate values\n if (!options[camelCaseKey]) {\n options[camelCaseKey] = []\n }\n options[camelCaseKey].push(this.parseValue(nextArg))\n i += 2\n } else if (nextArg && !nextArg.startsWith('-')) {\n // Has a value\n options[camelCaseKey] = this.parseValue(nextArg)\n i += 2\n } else {\n // Assume boolean flag\n options[camelCaseKey] = true\n i++\n }\n }\n } else if (arg.startsWith('-') && arg.length > 1 && arg !== '-') {\n // Short option format: -k value or -abc (multiple flags)\n const flags = arg.slice(1)\n\n if (flags.length === 1) {\n // Single short flag: -k value or -k\n const isBoolean = booleanFields.has(flags)\n const isArray = arrayFields.has(flags)\n const nextArg = args[i + 1]\n\n if (isBoolean) {\n // Known boolean flag from schema\n options[flags] = true\n i++\n } else if (isArray && nextArg && !nextArg.startsWith('-')) {\n // Known array field from schema - accumulate values\n if (!options[flags]) {\n options[flags] = []\n }\n options[flags].push(this.parseValue(nextArg))\n i += 2\n } else if (nextArg && !nextArg.startsWith('-')) {\n options[flags] = this.parseValue(nextArg)\n i += 2\n } else {\n options[flags] = true\n i++\n }\n } else {\n // Multiple short flags: -abc -> {a: true, b: true, c: true}\n for (const flag of flags) {\n options[flag] = true\n }\n i++\n }\n } else {\n // Positional argument\n positionals.push(arg)\n i++\n }\n }\n\n return {\n command,\n options,\n positionals,\n }\n }\n\n /**\n * Converts kebab-case to camelCase\n */\n private camelCase(str: string): string {\n return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())\n }\n\n /**\n * Attempts to parse string values into appropriate types\n */\n private parseValue(value: string): any {\n // Check for boolean\n if (value === 'true') return true\n if (value === 'false') return false\n\n // Check for null/undefined\n if (value === 'null') return null\n if (value === 'undefined') return undefined\n\n // Check for number\n if (/^-?\\d+$/.test(value)) {\n return parseInt(value, 10)\n }\n if (/^-?\\d+\\.\\d+$/.test(value)) {\n return parseFloat(value)\n }\n\n // Check for JSON\n if (\n (value.startsWith('{') && value.endsWith('}')) ||\n (value.startsWith('[') && value.endsWith(']'))\n ) {\n try {\n return JSON.parse(value)\n } catch {\n // If parsing fails, return as string\n return value\n }\n }\n\n // Return as string\n return value\n }\n\n /**\n * Extracts boolean field names from a Zod schema\n * Handles ZodObject, ZodOptional, and ZodDefault wrappers\n */\n private extractBooleanFields(schema: ZodObject): Set<string> {\n const booleanFields = new Set<string>()\n\n try {\n // Check if schema has _def.typeName (Zod schema structure)\n const typeName = schema.def.type\n\n if (typeName === 'object') {\n // Extract shape from ZodObject\n const shape = schema.def.shape\n\n if (shape && typeof shape === 'object') {\n for (const [key, fieldSchema] of Object.entries(shape)) {\n if (this.isSchemaBoolean(fieldSchema as any)) {\n booleanFields.add(key)\n }\n }\n }\n }\n } catch {\n // Silently fail if schema introspection fails\n }\n\n return booleanFields\n }\n\n /**\n * Extracts array field names from a Zod schema\n * Handles ZodObject, ZodOptional, and ZodDefault wrappers\n */\n private extractArrayFields(schema: ZodObject): Set<string> {\n const arrayFields = new Set<string>()\n\n try {\n const typeName = schema.def.type\n\n if (typeName === 'object') {\n const shape = schema.def.shape\n\n if (shape && typeof shape === 'object') {\n for (const [key, fieldSchema] of Object.entries(shape)) {\n if (this.isSchemaArray(fieldSchema as any)) {\n arrayFields.add(key)\n }\n }\n }\n }\n } catch {\n // Silently fail if schema introspection fails\n }\n\n return arrayFields\n }\n\n /**\n * Checks if a Zod schema represents a boolean type\n * Unwraps ZodOptional and ZodDefault\n */\n private isSchemaBoolean(schema: ZodType): boolean {\n try {\n let currentSchema = schema\n const typeName = currentSchema.def.type\n\n // Unwrap ZodOptional and ZodDefault\n if (typeName === 'optional' || typeName === 'default') {\n currentSchema = (currentSchema as any)?._def?.innerType || currentSchema\n }\n\n const innerTypeName = currentSchema.def.type\n return innerTypeName === 'boolean'\n } catch {\n return false\n }\n }\n\n /**\n * Checks if a Zod schema represents an array type\n * Unwraps ZodOptional and ZodDefault\n */\n private isSchemaArray(schema: ZodType): boolean {\n try {\n let currentSchema = schema\n const typeName = currentSchema.def.type\n\n // Unwrap ZodOptional and ZodDefault\n if (typeName === 'optional' || typeName === 'default') {\n currentSchema = (currentSchema as any)?._def?.innerType || currentSchema\n }\n\n const innerTypeName = currentSchema.def.type\n return innerTypeName === 'array'\n } catch {\n return false\n }\n }\n\n /**\n * Formats help text for available commands\n */\n formatCommandList(commands: Array<{ path: string; class: any }>): string {\n const lines = ['Available commands:', '']\n for (const { path } of commands) {\n lines.push(` ${path}`)\n }\n return lines.join('\\n')\n }\n}\n","import { InjectionToken } from '@navios/di'\n\nimport type { CommanderExecutionContext } from '../interfaces/index.mjs'\n\nexport const ExecutionContextInjectionToken =\n 'CommanderExecutionContextInjectionToken'\n\nexport const ExecutionContext = InjectionToken.create<CommanderExecutionContext>(\n ExecutionContextInjectionToken,\n)\n","import type { ClassTypeWithInstance, InjectionToken } from '@navios/di'\n\nimport { Container, inject, Injectable } from '@navios/di'\n\nimport type { CommandHandler, Module } from './interfaces/index.mjs'\n\nimport { CommanderExecutionContext } from './interfaces/index.mjs'\nimport { CliParserService, ModuleLoaderService } from './services/index.mjs'\nimport { ExecutionContext } from './tokens/index.mjs'\n\nexport interface CommanderApplicationOptions {}\n\n@Injectable()\nexport class CommanderApplication {\n private moduleLoader = inject(ModuleLoaderService)\n private cliParser = inject(CliParserService)\n protected container = inject(Container)\n\n private appModule: ClassTypeWithInstance<Module> | null = null\n private options: CommanderApplicationOptions = {}\n\n isInitialized = false\n\n async setup(\n appModule: ClassTypeWithInstance<Module>,\n options: CommanderApplicationOptions = {},\n ) {\n this.appModule = appModule\n this.options = options\n }\n\n getContainer() {\n return this.container\n }\n\n async init() {\n if (!this.appModule) {\n throw new Error(\n '[Navios Commander] App module is not set. Call setup() first.',\n )\n }\n await this.moduleLoader.loadModules(this.appModule)\n this.isInitialized = true\n }\n\n async executeCommand(commandPath: string, options: any = {}) {\n if (!this.isInitialized) {\n throw new Error(\n '[Navios Commander] Application is not initialized. Call init() first.',\n )\n }\n\n // Use pre-collected command metadata from module loading\n const commandWithMetadata = this.moduleLoader.getCommandByPath(commandPath)\n\n if (!commandWithMetadata) {\n throw new Error(`[Navios Commander] Command not found: ${commandPath}`)\n }\n\n const { class: commandClass, metadata } = commandWithMetadata\n\n // Validate options with zod schema if provided\n let validatedOptions = options\n if (metadata.optionsSchema) {\n validatedOptions = metadata.optionsSchema.parse(options)\n }\n\n // Create execution context and provide it to the container\n const executionContext = new CommanderExecutionContext(\n metadata,\n commandPath,\n validatedOptions,\n )\n\n // Generate a unique request ID for this command execution\n const requestId = `cmd-${Date.now()}-${Math.random().toString(36).substring(7)}`\n\n // Begin request context and add ExecutionContext\n const requestContext = this.container.beginRequest(requestId)\n requestContext.addInstance(ExecutionContext, executionContext)\n\n try {\n // Set current request context\n this.container.setCurrentRequestContext(requestId)\n\n // Get command instance and execute\n const commandInstance = await this.container.get<CommandHandler>(\n commandClass as unknown as InjectionToken<CommandHandler>,\n )\n\n if (!commandInstance.execute) {\n throw new Error(\n `[Navios Commander] Command ${commandPath} does not implement execute method`,\n )\n }\n\n await commandInstance.execute(validatedOptions)\n } finally {\n // Clean up request context\n await this.container.endRequest(requestId)\n }\n }\n\n getAllCommands() {\n // Use pre-collected command metadata from module loading\n const commandsMap = this.moduleLoader.getAllCommandsWithMetadata()\n const commandsWithMetadata: Array<{\n path: string\n class: ClassTypeWithInstance<any>\n }> = []\n\n for (const [, { class: cmd, metadata }] of commandsMap) {\n commandsWithMetadata.push({\n path: metadata.path,\n class: cmd,\n })\n }\n\n return commandsWithMetadata\n }\n\n /**\n * Runs the CLI application by parsing process.argv and executing the command\n * @param argv - Command-line arguments (defaults to process.argv)\n */\n async run(argv: string[] = process.argv) {\n if (!this.isInitialized) {\n throw new Error(\n '[Navios Commander] Application is not initialized. Call init() first.',\n )\n }\n\n try {\n // First, try to extract the command path to get its schema\n // We need to do a preliminary parse to find the command\n const preliminaryParse = this.cliParser.parse(argv)\n const commandWithMetadata = this.moduleLoader.getCommandByPath(\n preliminaryParse.command,\n )\n\n // Re-parse with schema if available\n const parsed = commandWithMetadata?.metadata.optionsSchema\n ? this.cliParser.parse(argv, commandWithMetadata.metadata.optionsSchema)\n : preliminaryParse\n\n // Handle special commands\n if (\n parsed.command === 'help' ||\n parsed.options.help ||\n parsed.options.h\n ) {\n const commands = this.getAllCommands()\n console.log(this.cliParser.formatCommandList(commands))\n return\n }\n\n // Execute the command\n await this.executeCommand(parsed.command, parsed.options)\n } catch (error) {\n if (error instanceof Error) {\n console.error(`Error: ${error.message}`)\n\n // Show available commands on error\n if (error.message.includes('Command not found')) {\n console.log(\n '\\n' + this.cliParser.formatCommandList(this.getAllCommands()),\n )\n }\n }\n throw error\n }\n }\n\n async dispose() {\n if (this.moduleLoader) {\n this.moduleLoader.dispose()\n }\n }\n\n async close() {\n await this.dispose()\n }\n}\n","import type { ClassTypeWithInstance } from '@navios/di'\n\nimport { Container } from '@navios/di'\n\nimport type { CommanderApplicationOptions } from './commander.application.mjs'\nimport type { Module } from './interfaces/index.mjs'\n\nimport { CommanderApplication } from './commander.application.mjs'\n\nexport class CommanderFactory {\n static async create(\n appModule: ClassTypeWithInstance<Module>,\n options: CommanderApplicationOptions = {},\n ) {\n const container = new Container()\n const app = await container.get(CommanderApplication)\n await app.setup(appModule, options)\n return app\n }\n}\n","import type { ClassType } from '@navios/di'\nimport type { ZodObject } from 'zod'\n\nimport { Injectable, InjectableScope, InjectionToken } from '@navios/di'\n\nimport { getCommandMetadata } from '../metadata/index.mjs'\n\nexport interface CommandOptions {\n path: string\n optionsSchema?: ZodObject\n}\n\nexport function Command({ path, optionsSchema }: CommandOptions) {\n return function (target: ClassType, context: ClassDecoratorContext) {\n if (context.kind !== 'class') {\n throw new Error(\n '[Navios Commander] @Command decorator can only be used on classes.',\n )\n }\n const token = InjectionToken.create(target)\n if (context.metadata) {\n getCommandMetadata(target, context, path, optionsSchema)\n }\n return Injectable({\n token,\n scope: InjectableScope.Singleton,\n })(target, context)\n }\n}\n","import type { ClassType } from '@navios/di'\n\nimport { Injectable, InjectableScope, InjectionToken } from '@navios/di'\n\nimport { getCliModuleMetadata } from '../metadata/index.mjs'\n\nexport interface CliModuleOptions {\n commands?: ClassType[] | Set<ClassType>\n imports?: ClassType[] | Set<ClassType>\n}\n\nexport function CliModule(\n { commands = [], imports = [] }: CliModuleOptions = {\n commands: [],\n imports: [],\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 // Register the module in the service locator\n const token = InjectionToken.create(target)\n const moduleMetadata = getCliModuleMetadata(target, context)\n for (const command of commands) {\n moduleMetadata.commands.add(command)\n }\n for (const importedModule of imports) {\n moduleMetadata.imports.add(importedModule)\n }\n\n return Injectable({\n token,\n scope: InjectableScope.Singleton,\n })(target, context)\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navios/commander",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "author": {
5
5
  "name": "Oleksandr Hanzha",
6
6
  "email": "alex@granted.name"
@@ -4,7 +4,9 @@ import { Container, inject, Injectable } from '@navios/di'
4
4
 
5
5
  import type { CommandHandler, Module } from './interfaces/index.mjs'
6
6
 
7
+ import { CommanderExecutionContext } from './interfaces/index.mjs'
7
8
  import { CliParserService, ModuleLoaderService } from './services/index.mjs'
9
+ import { ExecutionContext } from './tokens/index.mjs'
8
10
 
9
11
  export interface CommanderApplicationOptions {}
10
12
 
@@ -63,18 +65,40 @@ export class CommanderApplication {
63
65
  validatedOptions = metadata.optionsSchema.parse(options)
64
66
  }
65
67
 
66
- // Get command instance and execute
67
- const commandInstance = await this.container.get<CommandHandler>(
68
- commandClass as unknown as InjectionToken<CommandHandler>,
68
+ // Create execution context and provide it to the container
69
+ const executionContext = new CommanderExecutionContext(
70
+ metadata,
71
+ commandPath,
72
+ validatedOptions,
69
73
  )
70
74
 
71
- if (!commandInstance.execute) {
72
- throw new Error(
73
- `[Navios Commander] Command ${commandPath} does not implement execute method`,
75
+ // Generate a unique request ID for this command execution
76
+ const requestId = `cmd-${Date.now()}-${Math.random().toString(36).substring(7)}`
77
+
78
+ // Begin request context and add ExecutionContext
79
+ const requestContext = this.container.beginRequest(requestId)
80
+ requestContext.addInstance(ExecutionContext, executionContext)
81
+
82
+ try {
83
+ // Set current request context
84
+ this.container.setCurrentRequestContext(requestId)
85
+
86
+ // Get command instance and execute
87
+ const commandInstance = await this.container.get<CommandHandler>(
88
+ commandClass as unknown as InjectionToken<CommandHandler>,
74
89
  )
75
- }
76
90
 
77
- await commandInstance.execute(validatedOptions)
91
+ if (!commandInstance.execute) {
92
+ throw new Error(
93
+ `[Navios Commander] Command ${commandPath} does not implement execute method`,
94
+ )
95
+ }
96
+
97
+ await commandInstance.execute(validatedOptions)
98
+ } finally {
99
+ // Clean up request context
100
+ await this.container.endRequest(requestId)
101
+ }
78
102
  }
79
103
 
80
104
  getAllCommands() {
package/src/index.mts CHANGED
@@ -5,3 +5,4 @@ export * from './decorators/index.mjs'
5
5
  export * from './interfaces/index.mjs'
6
6
  export * from './metadata/index.mjs'
7
7
  export * from './services/index.mjs'
8
+ export * from './tokens/index.mjs'
@@ -0,0 +1,21 @@
1
+ import type { CommandMetadata } from '../metadata/command.metadata.mjs'
2
+
3
+ export class CommanderExecutionContext {
4
+ constructor(
5
+ private readonly command: CommandMetadata,
6
+ private readonly commandPath: string,
7
+ private readonly options: any,
8
+ ) {}
9
+
10
+ getCommand(): CommandMetadata {
11
+ return this.command
12
+ }
13
+
14
+ getCommandPath(): string {
15
+ return this.commandPath
16
+ }
17
+
18
+ getOptions(): any {
19
+ return this.options
20
+ }
21
+ }
@@ -1,2 +1,3 @@
1
1
  export * from './module.interface.mjs'
2
2
  export * from './command-handler.interface.mjs'
3
+ export * from './commander-execution-context.interface.mjs'