@navios/commander 1.6.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/.turbo/turbo-build.log +21 -21
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test$colon$ci.log +4 -4
  4. package/.turbo/turbo-test.log +7 -5
  5. package/CHANGELOG.md +20 -0
  6. package/dist/src/services/cli-parser.service.d.mts +55 -1
  7. package/dist/src/services/cli-parser.service.d.mts.map +1 -1
  8. package/dist/src/services/command-registry.service.d.mts +12 -0
  9. package/dist/src/services/command-registry.service.d.mts.map +1 -1
  10. package/dist/src/services/commander-adapter.service.d.mts.map +1 -1
  11. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  12. package/dist/tsconfig.tsbuildinfo +1 -1
  13. package/lib/{help-command.token-DamE31Aw.cjs → help-command.token-BI5XnE07.cjs} +35 -2
  14. package/lib/help-command.token-BI5XnE07.cjs.map +1 -0
  15. package/lib/{help-command.token-XHx3WkoD.mjs → help-command.token-D81bRnnl.mjs} +35 -2
  16. package/lib/help-command.token-D81bRnnl.mjs.map +1 -0
  17. package/lib/{help.command-Bynoll_7.mjs → help.command-B14cbwE_.mjs} +2 -2
  18. package/lib/{help.command-Bynoll_7.mjs.map → help.command-B14cbwE_.mjs.map} +1 -1
  19. package/lib/{help.command-DvKmMpB7.cjs → help.command-Dg-0v-yP.cjs} +2 -2
  20. package/lib/{help.command-DvKmMpB7.cjs.map → help.command-Dg-0v-yP.cjs.map} +1 -1
  21. package/lib/index.cjs +141 -11
  22. package/lib/index.cjs.map +1 -1
  23. package/lib/index.d.cts +67 -1
  24. package/lib/index.d.cts.map +1 -1
  25. package/lib/index.d.mts +67 -1
  26. package/lib/index.d.mts.map +1 -1
  27. package/lib/index.mjs +141 -11
  28. package/lib/index.mjs.map +1 -1
  29. package/package.json +2 -2
  30. package/src/services/__tests__/cli-parser.service.spec.mts +404 -0
  31. package/src/services/cli-parser.service.mts +243 -34
  32. package/src/services/command-registry.service.mts +61 -0
  33. package/src/services/commander-adapter.service.mts +8 -4
  34. package/lib/help-command.token-DamE31Aw.cjs.map +0 -1
  35. package/lib/help-command.token-XHx3WkoD.mjs.map +0 -1
@@ -358,15 +358,40 @@ var CommandRegistryService = class {
358
358
  try {
359
359
  const shape = metadata.optionsSchema.def.shape;
360
360
  if (shape && typeof shape === "object") for (const [key, fieldSchema] of Object.entries(shape)) {
361
- const optionFlag = `--${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`;
361
+ const kebabKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
362
+ const optionFlag = `--${kebabKey}`;
362
363
  const fieldType = this.getSchemaTypeName(fieldSchema);
363
364
  lines.push(` ${optionFlag.padEnd(20)} ${fieldType}`);
365
+ this.formatNestedObjectOptions(fieldSchema, kebabKey, lines, " ");
364
366
  }
365
367
  } catch {}
366
368
  }
367
369
  return lines.join("\n");
368
370
  }
369
371
  /**
372
+ * Recursively formats nested object options for help display.
373
+ * Shows nested fields with dot notation (e.g., --config.port)
374
+ */ formatNestedObjectOptions(schema, parentPath, lines, indent) {
375
+ try {
376
+ let currentSchema = schema;
377
+ let typeName = currentSchema?.def?.type;
378
+ while (typeName === "optional" || typeName === "default") {
379
+ currentSchema = currentSchema?.def?.innerType;
380
+ typeName = currentSchema?.def?.type;
381
+ }
382
+ if (typeName !== "object") return;
383
+ const shape = currentSchema?.def?.shape;
384
+ if (!shape || typeof shape !== "object") return;
385
+ for (const [key, fieldSchema] of Object.entries(shape)) {
386
+ const kebabKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
387
+ const optionFlag = `--${parentPath}.${kebabKey}`;
388
+ const fieldType = this.getSchemaTypeName(fieldSchema);
389
+ lines.push(`${indent}${optionFlag.padEnd(20 - indent.length + 2)} ${fieldType}`);
390
+ this.formatNestedObjectOptions(fieldSchema, `${parentPath}.${kebabKey}`, lines, indent + " ");
391
+ }
392
+ } catch {}
393
+ }
394
+ /**
370
395
  * Gets a human-readable type name from a zod/v4 schema.
371
396
  */ getSchemaTypeName(schema) {
372
397
  try {
@@ -409,6 +434,14 @@ var CommandRegistryService = class {
409
434
  }
410
435
  }
411
436
  /**
437
+ * Get all registered command paths.
438
+ * Useful for smart command detection in argv parsing.
439
+ *
440
+ * @returns Array of command paths
441
+ */ getAllPaths() {
442
+ return Array.from(this.commands.keys());
443
+ }
444
+ /**
412
445
  * Clear all registered commands.
413
446
  */ clear() {
414
447
  this.commands.clear();
@@ -435,4 +468,4 @@ Object.defineProperty(exports, '_CommandRegistryService', {
435
468
  return _CommandRegistryService;
436
469
  }
437
470
  });
438
- //# sourceMappingURL=help-command.token-DamE31Aw.cjs.map
471
+ //# sourceMappingURL=help-command.token-BI5XnE07.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help-command.token-BI5XnE07.cjs","names":["Injectable","CommandRegistryService","commands","Map","register","path","command","has","Error","set","getByPath","get","getAll","getAllAsArray","result","class","cls","push","formatCommandList","lines","metadata","description","padEnd","join","formatCommandHelp","commandPath","optionsSchema","shape","def","key","fieldSchema","Object","entries","kebabKey","replace","toLowerCase","optionFlag","fieldType","getSchemaTypeName","formatNestedObjectOptions","schema","parentPath","indent","currentSchema","typeName","type","innerType","length","isOptional","defaultValue","undefined","JSON","stringify","getSchemaMeta","directMeta","meta","getAllPaths","Array","from","keys","clear","InjectionToken","HelpCommandToken","create"],"sources":["../src/services/command-registry.service.mts","../src/tokens/help-command.token.mts"],"sourcesContent":["import { Injectable } from '@navios/core'\n\nimport type { ClassType } from '@navios/core'\n\nimport type { CommandMetadata } from '../metadata/index.mjs'\n\n/**\n * Represents a registered command with its metadata and module information.\n *\n * @public\n */\nexport interface RegisteredCommand {\n /**\n * The command class\n */\n class: ClassType\n /**\n * The command metadata from @Command decorator\n */\n metadata: CommandMetadata\n /**\n * Name of the module this command belongs to\n */\n moduleName: string\n}\n\n/**\n * Service for registering and looking up CLI commands.\n * Used internally by the CLI adapter to manage discovered commands.\n *\n * @public\n */\n@Injectable()\nexport class CommandRegistryService {\n private commands = new Map<string, RegisteredCommand>()\n\n /**\n * Register a command with its metadata.\n *\n * @param path - The command path (e.g., 'greet', 'user:create')\n * @param command - The registered command data\n * @throws Error if a command with the same path is already registered\n */\n register(path: string, command: RegisteredCommand): void {\n if (this.commands.has(path)) {\n throw new Error(`[Navios Commander] Duplicate command path: ${path}`)\n }\n this.commands.set(path, command)\n }\n\n /**\n * Get a command by its path.\n *\n * @param path - The command path\n * @returns The registered command or undefined if not found\n */\n getByPath(path: string): RegisteredCommand | undefined {\n return this.commands.get(path)\n }\n\n /**\n * Get all registered commands.\n *\n * @returns Map of path to registered command\n */\n getAll(): Map<string, RegisteredCommand> {\n return new Map(this.commands)\n }\n\n /**\n * Get all registered commands as an array of path and class pairs.\n * Useful for listing available commands.\n *\n * @returns Array of objects containing path and class\n */\n getAllAsArray(): Array<{ path: string; class: ClassType }> {\n const result: Array<{ path: string; class: ClassType }> = []\n for (const [path, { class: cls }] of this.commands) {\n result.push({ path, class: cls })\n }\n return result\n }\n\n /**\n * Formats help text listing all available commands with descriptions.\n *\n * @returns Formatted string listing all commands\n */\n formatCommandList(): string {\n const lines = ['Available commands:', '']\n for (const [path, { metadata }] of this.commands) {\n const description = metadata.description\n if (description) {\n lines.push(` ${path.padEnd(20)} ${description}`)\n } else {\n lines.push(` ${path}`)\n }\n }\n return lines.join('\\n')\n }\n\n /**\n * Formats help text for a specific command.\n *\n * @param commandPath - The command path to show help for\n * @returns Formatted string with command help\n */\n formatCommandHelp(commandPath: string): string {\n const command = this.commands.get(commandPath)\n if (!command) {\n return `Unknown command: ${commandPath}\\n\\n${this.formatCommandList()}`\n }\n\n const { metadata } = command\n const lines: string[] = []\n\n lines.push(`Usage: ${metadata.path} [options]`)\n lines.push('')\n\n if (metadata.description) {\n lines.push(metadata.description)\n lines.push('')\n }\n\n // Extract options from schema if available\n if (metadata.optionsSchema) {\n lines.push('Options:')\n try {\n const shape = metadata.optionsSchema.def.shape\n if (shape && typeof shape === 'object') {\n for (const [key, fieldSchema] of Object.entries(shape)) {\n const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase()\n const optionFlag = `--${kebabKey}`\n const fieldType = this.getSchemaTypeName(fieldSchema as any)\n lines.push(` ${optionFlag.padEnd(20)} ${fieldType}`)\n\n // Check for nested object fields and display them with dot notation\n this.formatNestedObjectOptions(fieldSchema as any, kebabKey, lines, ' ')\n }\n }\n } catch {\n // Schema introspection failed, skip options\n }\n }\n\n return lines.join('\\n')\n }\n\n /**\n * Recursively formats nested object options for help display.\n * Shows nested fields with dot notation (e.g., --config.port)\n */\n private formatNestedObjectOptions(\n schema: any,\n parentPath: string,\n lines: string[],\n indent: string,\n ): void {\n try {\n let currentSchema = schema\n let typeName = currentSchema?.def?.type\n\n // Unwrap optional/default wrappers\n while (typeName === 'optional' || typeName === 'default') {\n currentSchema = currentSchema?.def?.innerType\n typeName = currentSchema?.def?.type\n }\n\n if (typeName !== 'object') {\n return\n }\n\n const shape = currentSchema?.def?.shape\n if (!shape || typeof shape !== 'object') {\n return\n }\n\n for (const [key, fieldSchema] of Object.entries(shape)) {\n const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase()\n const optionFlag = `--${parentPath}.${kebabKey}`\n const fieldType = this.getSchemaTypeName(fieldSchema as any)\n lines.push(`${indent}${optionFlag.padEnd(20 - indent.length + 2)} ${fieldType}`)\n\n // Recurse for deeper nesting\n this.formatNestedObjectOptions(\n fieldSchema as any,\n `${parentPath}.${kebabKey}`,\n lines,\n indent + ' ',\n )\n }\n } catch {\n // Silently fail if schema introspection fails\n }\n }\n\n /**\n * Gets a human-readable type name from a zod/v4 schema.\n */\n private getSchemaTypeName(schema: any): string {\n try {\n let currentSchema = schema\n let typeName = currentSchema?.def?.type\n let isOptional = false\n let defaultValue: any\n\n // Unwrap optional/default wrappers\n while (typeName === 'optional' || typeName === 'default') {\n if (typeName === 'optional') {\n isOptional = true\n }\n if (typeName === 'default') {\n isOptional = true\n defaultValue = currentSchema?.def?.defaultValue?.()\n }\n currentSchema = currentSchema?.def?.innerType\n typeName = currentSchema?.def?.type\n }\n\n let result = `<${typeName || 'unknown'}>`\n if (defaultValue !== undefined) {\n result += ` (default: ${JSON.stringify(defaultValue)})`\n } else if (isOptional) {\n result += ' (optional)'\n }\n\n // Get description from meta() if available\n const description = this.getSchemaMeta(schema)?.description\n if (description) {\n result += ` - ${description}`\n }\n\n return result\n } catch {\n return '<unknown>'\n }\n }\n\n /**\n * Gets metadata from a zod/v4 schema, traversing innerType if needed.\n * zod/v4 v4 stores meta at the outermost layer when .meta() is called last,\n * or in innerType when .meta() is called before .optional()/.default().\n */\n private getSchemaMeta(schema: any): Record<string, unknown> | undefined {\n try {\n // First check direct meta (when .meta() is called last in chain)\n const directMeta = schema.meta?.()\n if (directMeta) return directMeta\n\n // Check innerType for wrapped schemas (optional, default, etc.)\n const innerType = schema.def?.innerType\n if (innerType) {\n return this.getSchemaMeta(innerType)\n }\n\n return undefined\n } catch {\n return undefined\n }\n }\n\n /**\n * Get all registered command paths.\n * Useful for smart command detection in argv parsing.\n *\n * @returns Array of command paths\n */\n getAllPaths(): string[] {\n return Array.from(this.commands.keys())\n }\n\n /**\n * Clear all registered commands.\n */\n clear(): void {\n this.commands.clear()\n }\n}\n","import { InjectionToken } from '@navios/core'\n\nimport type { HelpCommand } from '../overrides/help.command.mjs'\n\nexport const HelpCommandToken = InjectionToken.create<HelpCommand>('HelpCommand')\n"],"mappings":"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"}
@@ -358,15 +358,40 @@ var CommandRegistryService = class {
358
358
  try {
359
359
  const shape = metadata.optionsSchema.def.shape;
360
360
  if (shape && typeof shape === "object") for (const [key, fieldSchema] of Object.entries(shape)) {
361
- const optionFlag = `--${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`;
361
+ const kebabKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
362
+ const optionFlag = `--${kebabKey}`;
362
363
  const fieldType = this.getSchemaTypeName(fieldSchema);
363
364
  lines.push(` ${optionFlag.padEnd(20)} ${fieldType}`);
365
+ this.formatNestedObjectOptions(fieldSchema, kebabKey, lines, " ");
364
366
  }
365
367
  } catch {}
366
368
  }
367
369
  return lines.join("\n");
368
370
  }
369
371
  /**
372
+ * Recursively formats nested object options for help display.
373
+ * Shows nested fields with dot notation (e.g., --config.port)
374
+ */ formatNestedObjectOptions(schema, parentPath, lines, indent) {
375
+ try {
376
+ let currentSchema = schema;
377
+ let typeName = currentSchema?.def?.type;
378
+ while (typeName === "optional" || typeName === "default") {
379
+ currentSchema = currentSchema?.def?.innerType;
380
+ typeName = currentSchema?.def?.type;
381
+ }
382
+ if (typeName !== "object") return;
383
+ const shape = currentSchema?.def?.shape;
384
+ if (!shape || typeof shape !== "object") return;
385
+ for (const [key, fieldSchema] of Object.entries(shape)) {
386
+ const kebabKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
387
+ const optionFlag = `--${parentPath}.${kebabKey}`;
388
+ const fieldType = this.getSchemaTypeName(fieldSchema);
389
+ lines.push(`${indent}${optionFlag.padEnd(20 - indent.length + 2)} ${fieldType}`);
390
+ this.formatNestedObjectOptions(fieldSchema, `${parentPath}.${kebabKey}`, lines, indent + " ");
391
+ }
392
+ } catch {}
393
+ }
394
+ /**
370
395
  * Gets a human-readable type name from a zod/v4 schema.
371
396
  */ getSchemaTypeName(schema) {
372
397
  try {
@@ -409,6 +434,14 @@ var CommandRegistryService = class {
409
434
  }
410
435
  }
411
436
  /**
437
+ * Get all registered command paths.
438
+ * Useful for smart command detection in argv parsing.
439
+ *
440
+ * @returns Array of command paths
441
+ */ getAllPaths() {
442
+ return Array.from(this.commands.keys());
443
+ }
444
+ /**
412
445
  * Clear all registered commands.
413
446
  */ clear() {
414
447
  this.commands.clear();
@@ -424,4 +457,4 @@ const HelpCommandToken = InjectionToken.create("HelpCommand");
424
457
 
425
458
  //#endregion
426
459
  export { _CommandRegistryService as n, HelpCommandToken as t };
427
- //# sourceMappingURL=help-command.token-XHx3WkoD.mjs.map
460
+ //# sourceMappingURL=help-command.token-D81bRnnl.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help-command.token-D81bRnnl.mjs","names":["Injectable","CommandRegistryService","commands","Map","register","path","command","has","Error","set","getByPath","get","getAll","getAllAsArray","result","class","cls","push","formatCommandList","lines","metadata","description","padEnd","join","formatCommandHelp","commandPath","optionsSchema","shape","def","key","fieldSchema","Object","entries","kebabKey","replace","toLowerCase","optionFlag","fieldType","getSchemaTypeName","formatNestedObjectOptions","schema","parentPath","indent","currentSchema","typeName","type","innerType","length","isOptional","defaultValue","undefined","JSON","stringify","getSchemaMeta","directMeta","meta","getAllPaths","Array","from","keys","clear","InjectionToken","HelpCommandToken","create"],"sources":["../src/services/command-registry.service.mts","../src/tokens/help-command.token.mts"],"sourcesContent":["import { Injectable } from '@navios/core'\n\nimport type { ClassType } from '@navios/core'\n\nimport type { CommandMetadata } from '../metadata/index.mjs'\n\n/**\n * Represents a registered command with its metadata and module information.\n *\n * @public\n */\nexport interface RegisteredCommand {\n /**\n * The command class\n */\n class: ClassType\n /**\n * The command metadata from @Command decorator\n */\n metadata: CommandMetadata\n /**\n * Name of the module this command belongs to\n */\n moduleName: string\n}\n\n/**\n * Service for registering and looking up CLI commands.\n * Used internally by the CLI adapter to manage discovered commands.\n *\n * @public\n */\n@Injectable()\nexport class CommandRegistryService {\n private commands = new Map<string, RegisteredCommand>()\n\n /**\n * Register a command with its metadata.\n *\n * @param path - The command path (e.g., 'greet', 'user:create')\n * @param command - The registered command data\n * @throws Error if a command with the same path is already registered\n */\n register(path: string, command: RegisteredCommand): void {\n if (this.commands.has(path)) {\n throw new Error(`[Navios Commander] Duplicate command path: ${path}`)\n }\n this.commands.set(path, command)\n }\n\n /**\n * Get a command by its path.\n *\n * @param path - The command path\n * @returns The registered command or undefined if not found\n */\n getByPath(path: string): RegisteredCommand | undefined {\n return this.commands.get(path)\n }\n\n /**\n * Get all registered commands.\n *\n * @returns Map of path to registered command\n */\n getAll(): Map<string, RegisteredCommand> {\n return new Map(this.commands)\n }\n\n /**\n * Get all registered commands as an array of path and class pairs.\n * Useful for listing available commands.\n *\n * @returns Array of objects containing path and class\n */\n getAllAsArray(): Array<{ path: string; class: ClassType }> {\n const result: Array<{ path: string; class: ClassType }> = []\n for (const [path, { class: cls }] of this.commands) {\n result.push({ path, class: cls })\n }\n return result\n }\n\n /**\n * Formats help text listing all available commands with descriptions.\n *\n * @returns Formatted string listing all commands\n */\n formatCommandList(): string {\n const lines = ['Available commands:', '']\n for (const [path, { metadata }] of this.commands) {\n const description = metadata.description\n if (description) {\n lines.push(` ${path.padEnd(20)} ${description}`)\n } else {\n lines.push(` ${path}`)\n }\n }\n return lines.join('\\n')\n }\n\n /**\n * Formats help text for a specific command.\n *\n * @param commandPath - The command path to show help for\n * @returns Formatted string with command help\n */\n formatCommandHelp(commandPath: string): string {\n const command = this.commands.get(commandPath)\n if (!command) {\n return `Unknown command: ${commandPath}\\n\\n${this.formatCommandList()}`\n }\n\n const { metadata } = command\n const lines: string[] = []\n\n lines.push(`Usage: ${metadata.path} [options]`)\n lines.push('')\n\n if (metadata.description) {\n lines.push(metadata.description)\n lines.push('')\n }\n\n // Extract options from schema if available\n if (metadata.optionsSchema) {\n lines.push('Options:')\n try {\n const shape = metadata.optionsSchema.def.shape\n if (shape && typeof shape === 'object') {\n for (const [key, fieldSchema] of Object.entries(shape)) {\n const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase()\n const optionFlag = `--${kebabKey}`\n const fieldType = this.getSchemaTypeName(fieldSchema as any)\n lines.push(` ${optionFlag.padEnd(20)} ${fieldType}`)\n\n // Check for nested object fields and display them with dot notation\n this.formatNestedObjectOptions(fieldSchema as any, kebabKey, lines, ' ')\n }\n }\n } catch {\n // Schema introspection failed, skip options\n }\n }\n\n return lines.join('\\n')\n }\n\n /**\n * Recursively formats nested object options for help display.\n * Shows nested fields with dot notation (e.g., --config.port)\n */\n private formatNestedObjectOptions(\n schema: any,\n parentPath: string,\n lines: string[],\n indent: string,\n ): void {\n try {\n let currentSchema = schema\n let typeName = currentSchema?.def?.type\n\n // Unwrap optional/default wrappers\n while (typeName === 'optional' || typeName === 'default') {\n currentSchema = currentSchema?.def?.innerType\n typeName = currentSchema?.def?.type\n }\n\n if (typeName !== 'object') {\n return\n }\n\n const shape = currentSchema?.def?.shape\n if (!shape || typeof shape !== 'object') {\n return\n }\n\n for (const [key, fieldSchema] of Object.entries(shape)) {\n const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase()\n const optionFlag = `--${parentPath}.${kebabKey}`\n const fieldType = this.getSchemaTypeName(fieldSchema as any)\n lines.push(`${indent}${optionFlag.padEnd(20 - indent.length + 2)} ${fieldType}`)\n\n // Recurse for deeper nesting\n this.formatNestedObjectOptions(\n fieldSchema as any,\n `${parentPath}.${kebabKey}`,\n lines,\n indent + ' ',\n )\n }\n } catch {\n // Silently fail if schema introspection fails\n }\n }\n\n /**\n * Gets a human-readable type name from a zod/v4 schema.\n */\n private getSchemaTypeName(schema: any): string {\n try {\n let currentSchema = schema\n let typeName = currentSchema?.def?.type\n let isOptional = false\n let defaultValue: any\n\n // Unwrap optional/default wrappers\n while (typeName === 'optional' || typeName === 'default') {\n if (typeName === 'optional') {\n isOptional = true\n }\n if (typeName === 'default') {\n isOptional = true\n defaultValue = currentSchema?.def?.defaultValue?.()\n }\n currentSchema = currentSchema?.def?.innerType\n typeName = currentSchema?.def?.type\n }\n\n let result = `<${typeName || 'unknown'}>`\n if (defaultValue !== undefined) {\n result += ` (default: ${JSON.stringify(defaultValue)})`\n } else if (isOptional) {\n result += ' (optional)'\n }\n\n // Get description from meta() if available\n const description = this.getSchemaMeta(schema)?.description\n if (description) {\n result += ` - ${description}`\n }\n\n return result\n } catch {\n return '<unknown>'\n }\n }\n\n /**\n * Gets metadata from a zod/v4 schema, traversing innerType if needed.\n * zod/v4 v4 stores meta at the outermost layer when .meta() is called last,\n * or in innerType when .meta() is called before .optional()/.default().\n */\n private getSchemaMeta(schema: any): Record<string, unknown> | undefined {\n try {\n // First check direct meta (when .meta() is called last in chain)\n const directMeta = schema.meta?.()\n if (directMeta) return directMeta\n\n // Check innerType for wrapped schemas (optional, default, etc.)\n const innerType = schema.def?.innerType\n if (innerType) {\n return this.getSchemaMeta(innerType)\n }\n\n return undefined\n } catch {\n return undefined\n }\n }\n\n /**\n * Get all registered command paths.\n * Useful for smart command detection in argv parsing.\n *\n * @returns Array of command paths\n */\n getAllPaths(): string[] {\n return Array.from(this.commands.keys())\n }\n\n /**\n * Clear all registered commands.\n */\n clear(): void {\n this.commands.clear()\n }\n}\n","import { InjectionToken } from '@navios/core'\n\nimport type { HelpCommand } from '../overrides/help.command.mjs'\n\nexport const HelpCommandToken = InjectionToken.create<HelpCommand>('HelpCommand')\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { t as Command } from "./command.decorator-QiRU7ny3.mjs";
2
- import { n as _CommandRegistryService, t as HelpCommandToken } from "./help-command.token-XHx3WkoD.mjs";
2
+ import { n as _CommandRegistryService, t as HelpCommandToken } from "./help-command.token-D81bRnnl.mjs";
3
3
  import { inject } from "@navios/core";
4
4
  import { z } from "zod/v4";
5
5
  import { ScreenLogger } from "@navios/commander-tui";
@@ -312,4 +312,4 @@ var HelpCommand = class {
312
312
 
313
313
  //#endregion
314
314
  export { };
315
- //# sourceMappingURL=help.command-Bynoll_7.mjs.map
315
+ //# sourceMappingURL=help.command-B14cbwE_.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"help.command-Bynoll_7.mjs","names":["ScreenLogger","inject","z","Command","CommandRegistryService","HelpCommandToken","helpOptionsSchema","object","command","string","optional","token","path","description","optionsSchema","priority","HelpCommand","logger","screen","context","commandRegistry","execute","options","log","formatCommandHelp","formatCommandList"],"sources":["../src/overrides/help.command.mts"],"sourcesContent":["import { ScreenLogger } from '@navios/commander-tui'\nimport { inject } from '@navios/core'\nimport { z } from 'zod/v4'\n\nimport { Command } from '../decorators/command.decorator.mjs'\nimport { CommandRegistryService } from '../services/command-registry.service.mjs'\nimport { HelpCommandToken } from '../tokens/help-command.token.mjs'\n\nimport type { CommandHandler } from '../interfaces/command-handler.interface.mjs'\n\nconst helpOptionsSchema = z.object({\n command: z.string().optional(),\n})\n\ntype HelpOptions = z.infer<typeof helpOptionsSchema>\n\n/**\n * Built-in help command that lists all available commands or shows help for a specific command.\n *\n * @public\n */\n@Command({\n token: HelpCommandToken,\n path: 'help',\n description: 'Show available commands or help for a specific command',\n optionsSchema: helpOptionsSchema,\n priority: 1000,\n})\nexport class HelpCommand implements CommandHandler<HelpOptions> {\n private logger = inject(ScreenLogger, { screen: 'Help', context: 'Help' })\n private commandRegistry = inject(CommandRegistryService)\n\n async execute(options: HelpOptions): Promise<void> {\n if (options.command) {\n this.logger.log(this.commandRegistry.formatCommandHelp(options.command))\n } else {\n this.logger.log(this.commandRegistry.formatCommandList())\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,MAAMM,oBAAoBJ,EAAEK,OAAO,EACjCC,SAASN,EAAEO,QAAM,CAAGC,UAAQ,EAC9B,CAAA;;OASCP,QAAQ;CACPQ,OAAON;CACPO,MAAM;CACNC,aAAa;CACbC,eAAeR;CACfS,UAAU;CACZ,CAAA;AACO,IAAMC,cAAN,MAAMA;;;;CACHC,SAAShB,OAAOD,cAAc;EAAEkB,QAAQ;EAAQC,SAAS;EAAO,CAAA;CAChEC,kBAAkBnB,OAAOG,wBAAAA;CAEjC,MAAMiB,QAAQC,SAAqC;AACjD,MAAIA,QAAQd,QACV,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBI,kBAAkBF,QAAQd,QAAO,CAAA;MAEtE,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBK,mBAAiB,CAAA"}
1
+ {"version":3,"file":"help.command-B14cbwE_.mjs","names":["ScreenLogger","inject","z","Command","CommandRegistryService","HelpCommandToken","helpOptionsSchema","object","command","string","optional","token","path","description","optionsSchema","priority","HelpCommand","logger","screen","context","commandRegistry","execute","options","log","formatCommandHelp","formatCommandList"],"sources":["../src/overrides/help.command.mts"],"sourcesContent":["import { ScreenLogger } from '@navios/commander-tui'\nimport { inject } from '@navios/core'\nimport { z } from 'zod/v4'\n\nimport { Command } from '../decorators/command.decorator.mjs'\nimport { CommandRegistryService } from '../services/command-registry.service.mjs'\nimport { HelpCommandToken } from '../tokens/help-command.token.mjs'\n\nimport type { CommandHandler } from '../interfaces/command-handler.interface.mjs'\n\nconst helpOptionsSchema = z.object({\n command: z.string().optional(),\n})\n\ntype HelpOptions = z.infer<typeof helpOptionsSchema>\n\n/**\n * Built-in help command that lists all available commands or shows help for a specific command.\n *\n * @public\n */\n@Command({\n token: HelpCommandToken,\n path: 'help',\n description: 'Show available commands or help for a specific command',\n optionsSchema: helpOptionsSchema,\n priority: 1000,\n})\nexport class HelpCommand implements CommandHandler<HelpOptions> {\n private logger = inject(ScreenLogger, { screen: 'Help', context: 'Help' })\n private commandRegistry = inject(CommandRegistryService)\n\n async execute(options: HelpOptions): Promise<void> {\n if (options.command) {\n this.logger.log(this.commandRegistry.formatCommandHelp(options.command))\n } else {\n this.logger.log(this.commandRegistry.formatCommandList())\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,MAAMM,oBAAoBJ,EAAEK,OAAO,EACjCC,SAASN,EAAEO,QAAM,CAAGC,UAAQ,EAC9B,CAAA;;OASCP,QAAQ;CACPQ,OAAON;CACPO,MAAM;CACNC,aAAa;CACbC,eAAeR;CACfS,UAAU;CACZ,CAAA;AACO,IAAMC,cAAN,MAAMA;;;;CACHC,SAAShB,OAAOD,cAAc;EAAEkB,QAAQ;EAAQC,SAAS;EAAO,CAAA;CAChEC,kBAAkBnB,OAAOG,wBAAAA;CAEjC,MAAMiB,QAAQC,SAAqC;AACjD,MAAIA,QAAQd,QACV,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBI,kBAAkBF,QAAQd,QAAO,CAAA;MAEtE,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBK,mBAAiB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  const require_command_decorator = require('./command.decorator-HziankUv.cjs');
2
- const require_help_command_token = require('./help-command.token-DamE31Aw.cjs');
2
+ const require_help_command_token = require('./help-command.token-BI5XnE07.cjs');
3
3
  let _navios_core = require("@navios/core");
4
4
  let zod_v4 = require("zod/v4");
5
5
  let _navios_commander_tui = require("@navios/commander-tui");
@@ -311,4 +311,4 @@ var HelpCommand = class {
311
311
  };
312
312
 
313
313
  //#endregion
314
- //# sourceMappingURL=help.command-DvKmMpB7.cjs.map
314
+ //# sourceMappingURL=help.command-Dg-0v-yP.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"help.command-DvKmMpB7.cjs","names":["ScreenLogger","inject","z","Command","CommandRegistryService","HelpCommandToken","helpOptionsSchema","object","command","string","optional","token","path","description","optionsSchema","priority","HelpCommand","logger","screen","context","commandRegistry","execute","options","log","formatCommandHelp","formatCommandList"],"sources":["../src/overrides/help.command.mts"],"sourcesContent":["import { ScreenLogger } from '@navios/commander-tui'\nimport { inject } from '@navios/core'\nimport { z } from 'zod/v4'\n\nimport { Command } from '../decorators/command.decorator.mjs'\nimport { CommandRegistryService } from '../services/command-registry.service.mjs'\nimport { HelpCommandToken } from '../tokens/help-command.token.mjs'\n\nimport type { CommandHandler } from '../interfaces/command-handler.interface.mjs'\n\nconst helpOptionsSchema = z.object({\n command: z.string().optional(),\n})\n\ntype HelpOptions = z.infer<typeof helpOptionsSchema>\n\n/**\n * Built-in help command that lists all available commands or shows help for a specific command.\n *\n * @public\n */\n@Command({\n token: HelpCommandToken,\n path: 'help',\n description: 'Show available commands or help for a specific command',\n optionsSchema: helpOptionsSchema,\n priority: 1000,\n})\nexport class HelpCommand implements CommandHandler<HelpOptions> {\n private logger = inject(ScreenLogger, { screen: 'Help', context: 'Help' })\n private commandRegistry = inject(CommandRegistryService)\n\n async execute(options: HelpOptions): Promise<void> {\n if (options.command) {\n this.logger.log(this.commandRegistry.formatCommandHelp(options.command))\n } else {\n this.logger.log(this.commandRegistry.formatCommandList())\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,MAAMM,oBAAoBJ,SAAEK,OAAO,EACjCC,SAASN,SAAEO,QAAM,CAAGC,UAAQ,EAC9B,CAAA;;OASCP,kCAAQ;CACPQ,OAAON;CACPO,MAAM;CACNC,aAAa;CACbC,eAAeR;CACfS,UAAU;CACZ,CAAA;AACO,IAAMC,cAAN,MAAMA;;;;CACHC,kCAAgBjB,oCAAc;EAAEkB,QAAQ;EAAQC,SAAS;EAAO,CAAA;CAChEC,2CAAyBhB,mDAAAA;CAEjC,MAAMiB,QAAQC,SAAqC;AACjD,MAAIA,QAAQd,QACV,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBI,kBAAkBF,QAAQd,QAAO,CAAA;MAEtE,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBK,mBAAiB,CAAA"}
1
+ {"version":3,"file":"help.command-Dg-0v-yP.cjs","names":["ScreenLogger","inject","z","Command","CommandRegistryService","HelpCommandToken","helpOptionsSchema","object","command","string","optional","token","path","description","optionsSchema","priority","HelpCommand","logger","screen","context","commandRegistry","execute","options","log","formatCommandHelp","formatCommandList"],"sources":["../src/overrides/help.command.mts"],"sourcesContent":["import { ScreenLogger } from '@navios/commander-tui'\nimport { inject } from '@navios/core'\nimport { z } from 'zod/v4'\n\nimport { Command } from '../decorators/command.decorator.mjs'\nimport { CommandRegistryService } from '../services/command-registry.service.mjs'\nimport { HelpCommandToken } from '../tokens/help-command.token.mjs'\n\nimport type { CommandHandler } from '../interfaces/command-handler.interface.mjs'\n\nconst helpOptionsSchema = z.object({\n command: z.string().optional(),\n})\n\ntype HelpOptions = z.infer<typeof helpOptionsSchema>\n\n/**\n * Built-in help command that lists all available commands or shows help for a specific command.\n *\n * @public\n */\n@Command({\n token: HelpCommandToken,\n path: 'help',\n description: 'Show available commands or help for a specific command',\n optionsSchema: helpOptionsSchema,\n priority: 1000,\n})\nexport class HelpCommand implements CommandHandler<HelpOptions> {\n private logger = inject(ScreenLogger, { screen: 'Help', context: 'Help' })\n private commandRegistry = inject(CommandRegistryService)\n\n async execute(options: HelpOptions): Promise<void> {\n if (options.command) {\n this.logger.log(this.commandRegistry.formatCommandHelp(options.command))\n } else {\n this.logger.log(this.commandRegistry.formatCommandList())\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,MAAMM,oBAAoBJ,SAAEK,OAAO,EACjCC,SAASN,SAAEO,QAAM,CAAGC,UAAQ,EAC9B,CAAA;;OASCP,kCAAQ;CACPQ,OAAON;CACPO,MAAM;CACNC,aAAa;CACbC,eAAeR;CACfS,UAAU;CACZ,CAAA;AACO,IAAMC,cAAN,MAAMA;;;;CACHC,kCAAgBjB,oCAAc;EAAEkB,QAAQ;EAAQC,SAAS;EAAO,CAAA;CAChEC,2CAAyBhB,mDAAAA;CAEjC,MAAMiB,QAAQC,SAAqC;AACjD,MAAIA,QAAQd,QACV,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBI,kBAAkBF,QAAQd,QAAO,CAAA;MAEtE,MAAKS,OAAOM,IAAI,KAAKH,gBAAgBK,mBAAiB,CAAA"}
package/lib/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  const require_command_decorator = require('./command.decorator-HziankUv.cjs');
2
- const require_help_command_token = require('./help-command.token-DamE31Aw.cjs');
2
+ const require_help_command_token = require('./help-command.token-BI5XnE07.cjs');
3
3
  const require_cli_module_decorator = require('./cli-module.decorator-CXt38aqF.cjs');
4
4
  let _navios_core = require("@navios/core");
5
5
  let zod_v4 = require("zod/v4");
@@ -599,9 +599,13 @@ var CliParserService = class {
599
599
  *
600
600
  * @param argv - Array of command-line arguments (typically process.argv)
601
601
  * @param optionsSchema - Optional zod/v4 schema to determine boolean flags and option types
602
+ * @param availableCommands - Optional list of registered command paths for smart detection.
603
+ * When provided, scans argv to find the best matching command, enabling support for
604
+ * custom launchers (tsx, ts-node, npx, etc.) that add extra args before the command.
602
605
  * @returns Parsed command (space-separated if multi-word), options, and positional arguments
603
- */ parse(argv, optionsSchema) {
604
- const args = argv.slice(2);
606
+ */ parse(argv, optionsSchema, availableCommands) {
607
+ const startIndex = availableCommands?.length ? this.findCommandStartIndex(argv, availableCommands) : 2;
608
+ const args = argv.slice(startIndex);
605
609
  if (args.length === 0) throw new Error("[Navios Commander] No command provided");
606
610
  const booleanFields = optionsSchema ? this.extractBooleanFields(optionsSchema) : /* @__PURE__ */ new Set();
607
611
  const arrayFields = optionsSchema ? this.extractArrayFields(optionsSchema) : /* @__PURE__ */ new Set();
@@ -623,12 +627,41 @@ var CliParserService = class {
623
627
  if (equalIndex !== -1) {
624
628
  const optionName = key.slice(0, equalIndex);
625
629
  const optionValue = key.slice(equalIndex + 1);
626
- const camelCaseKey = this.camelCase(optionName);
627
- if (arrayFields.has(camelCaseKey) || arrayFields.has(optionName)) {
628
- if (!options[camelCaseKey]) options[camelCaseKey] = [];
629
- options[camelCaseKey].push(this.parseValue(optionValue));
630
- } else options[camelCaseKey] = this.parseValue(optionValue);
630
+ if (this.isObjectNotation(optionName)) {
631
+ const processedPath = this.processObjectNotationKey(optionName);
632
+ if (optionsSchema ? this.isNestedArray(optionsSchema, processedPath) : false) {
633
+ const existingValue = this.getNestedProperty(options, processedPath);
634
+ if (!Array.isArray(existingValue)) this.setNestedProperty(options, processedPath, []);
635
+ this.getNestedProperty(options, processedPath).push(this.parseValue(optionValue));
636
+ } else this.setNestedProperty(options, processedPath, this.parseValue(optionValue));
637
+ } else {
638
+ const camelCaseKey = this.camelCase(optionName);
639
+ if (arrayFields.has(camelCaseKey) || arrayFields.has(optionName)) {
640
+ if (!options[camelCaseKey]) options[camelCaseKey] = [];
641
+ options[camelCaseKey].push(this.parseValue(optionValue));
642
+ } else options[camelCaseKey] = this.parseValue(optionValue);
643
+ }
631
644
  i++;
645
+ } else if (this.isObjectNotation(key)) {
646
+ const processedPath = this.processObjectNotationKey(key);
647
+ const isBoolean = optionsSchema ? this.isNestedBoolean(optionsSchema, processedPath) : false;
648
+ const isArray = optionsSchema ? this.isNestedArray(optionsSchema, processedPath) : false;
649
+ const nextArg = args[i + 1];
650
+ if (isBoolean) {
651
+ this.setNestedProperty(options, processedPath, true);
652
+ i++;
653
+ } else if (isArray && nextArg && !nextArg.startsWith("-")) {
654
+ const existingValue = this.getNestedProperty(options, processedPath);
655
+ if (!Array.isArray(existingValue)) this.setNestedProperty(options, processedPath, []);
656
+ this.getNestedProperty(options, processedPath).push(this.parseValue(nextArg));
657
+ i += 2;
658
+ } else if (nextArg && !nextArg.startsWith("-")) {
659
+ this.setNestedProperty(options, processedPath, this.parseValue(nextArg));
660
+ i += 2;
661
+ } else {
662
+ this.setNestedProperty(options, processedPath, true);
663
+ i++;
664
+ }
632
665
  } else {
633
666
  const camelCaseKey = this.camelCase(key);
634
667
  const isBoolean = booleanFields.has(camelCaseKey) || booleanFields.has(key);
@@ -685,6 +718,28 @@ var CliParserService = class {
685
718
  };
686
719
  }
687
720
  /**
721
+ * Finds the index in argv where the command starts by matching against available commands.
722
+ * Prioritizes longer/more specific commands (e.g., 'db migrate' matches before 'db').
723
+ *
724
+ * @param argv - Full argv array
725
+ * @param availableCommands - List of registered command paths
726
+ * @returns Index where the command starts, or 2 as fallback
727
+ */ findCommandStartIndex(argv, availableCommands) {
728
+ const sortedCommands = [...availableCommands].sort((a, b) => {
729
+ const aParts = a.split(" ").length;
730
+ const bParts = b.split(" ").length;
731
+ if (bParts !== aParts) return bParts - aParts;
732
+ return b.length - a.length;
733
+ });
734
+ for (let startIdx = 1; startIdx < argv.length; startIdx++) for (const cmd of sortedCommands) {
735
+ const cmdParts = cmd.split(" ");
736
+ const endIdx = startIdx + cmdParts.length;
737
+ if (endIdx > argv.length) continue;
738
+ if (argv.slice(startIdx, endIdx).join(" ") === cmd) return startIdx;
739
+ }
740
+ return 2;
741
+ }
742
+ /**
688
743
  * Converts kebab-case to camelCase
689
744
  */ camelCase(str) {
690
745
  return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
@@ -767,6 +822,80 @@ var CliParserService = class {
767
822
  return false;
768
823
  }
769
824
  }
825
+ /**
826
+ * Sets a nested property on an object using dot notation path.
827
+ * Creates intermediate objects as needed.
828
+ *
829
+ * @example
830
+ * setNestedProperty({}, 'a.b.c', 'value') // { a: { b: { c: 'value' } } }
831
+ */ setNestedProperty(obj, path, value) {
832
+ const parts = path.split(".");
833
+ let current = obj;
834
+ for (let i = 0; i < parts.length - 1; i++) {
835
+ const part = parts[i];
836
+ if (!(part in current) || typeof current[part] !== "object" || current[part] === null) current[part] = {};
837
+ current = current[part];
838
+ }
839
+ current[parts[parts.length - 1]] = value;
840
+ }
841
+ /**
842
+ * Gets a nested property from an object using dot notation path.
843
+ * Returns undefined if path doesn't exist.
844
+ */ getNestedProperty(obj, path) {
845
+ const parts = path.split(".");
846
+ let current = obj;
847
+ for (const part of parts) {
848
+ if (current === void 0 || current === null || typeof current !== "object") return;
849
+ current = current[part];
850
+ }
851
+ return current;
852
+ }
853
+ /**
854
+ * Checks if an option key contains dot notation (object notation).
855
+ * Returns true for keys like "obj.field" or "deep.nested.value".
856
+ */ isObjectNotation(key) {
857
+ return key.includes(".");
858
+ }
859
+ /**
860
+ * Processes an option key that may contain object notation.
861
+ * Converts each segment from kebab-case to camelCase.
862
+ *
863
+ * @example
864
+ * processObjectNotationKey('my-obj.field-name') // 'myObj.fieldName'
865
+ */ processObjectNotationKey(key) {
866
+ return key.split(".").map((segment) => this.camelCase(segment)).join(".");
867
+ }
868
+ /**
869
+ * Gets the nested schema for a given dot-notation path.
870
+ * Returns undefined if the path doesn't lead to a valid schema.
871
+ */ getNestedSchema(schema, path) {
872
+ try {
873
+ const parts = path.split(".");
874
+ let currentSchema = schema;
875
+ for (const part of parts) {
876
+ while (currentSchema?.def?.type === "optional" || currentSchema?.def?.type === "default") currentSchema = currentSchema.def.innerType;
877
+ if (currentSchema?.def?.type !== "object") return;
878
+ const shape = currentSchema.def.shape;
879
+ if (!shape || !(part in shape)) return;
880
+ currentSchema = shape[part];
881
+ }
882
+ return currentSchema;
883
+ } catch {
884
+ return;
885
+ }
886
+ }
887
+ /**
888
+ * Checks if a nested path represents a boolean field in the schema.
889
+ */ isNestedBoolean(schema, path) {
890
+ const nestedSchema = this.getNestedSchema(schema, path);
891
+ return nestedSchema ? this.isSchemaBoolean(nestedSchema) : false;
892
+ }
893
+ /**
894
+ * Checks if a nested path represents an array field in the schema.
895
+ */ isNestedArray(schema, path) {
896
+ const nestedSchema = this.getNestedSchema(schema, path);
897
+ return nestedSchema ? this.isSchemaArray(nestedSchema) : false;
898
+ }
770
899
  static {
771
900
  _initClass$1();
772
901
  }
@@ -1218,14 +1347,15 @@ var CommanderAdapterService = class {
1218
1347
  */ async run(argv = process.argv) {
1219
1348
  if (!this.isReady) throw new Error("Adapter not ready. Call app.init() first.");
1220
1349
  try {
1221
- const preliminaryParse = this.cliParser.parse(argv);
1350
+ const commandPaths = this.commandRegistry.getAllPaths();
1351
+ const preliminaryParse = this.cliParser.parse(argv, void 0, commandPaths);
1222
1352
  if (preliminaryParse.options.help || preliminaryParse.options.h) {
1223
1353
  if (preliminaryParse.command === "help") await this.executeCommand("help", {});
1224
1354
  else await this.executeCommand("help", { command: preliminaryParse.command });
1225
1355
  return;
1226
1356
  }
1227
1357
  const command = this.commandRegistry.getByPath(preliminaryParse.command);
1228
- const parsed = command?.metadata.optionsSchema ? this.cliParser.parse(argv, command.metadata.optionsSchema) : preliminaryParse;
1358
+ const parsed = command?.metadata.optionsSchema ? this.cliParser.parse(argv, command.metadata.optionsSchema, commandPaths) : preliminaryParse;
1229
1359
  await this.executeCommand(parsed.command, parsed.options, parsed.positionals);
1230
1360
  } catch (error) {
1231
1361
  if (error instanceof Error) {
@@ -1372,7 +1502,7 @@ function dynamicImport(modulePath) {
1372
1502
  }
1373
1503
  const { overrideConsoleLogger, ScreenManager } = tuiModule;
1374
1504
  overrideConsoleLogger(options.tuiOptions?.hideDefaultScreen ?? false);
1375
- if (options.tuiOptions?.hideDefaultScreen) await Promise.resolve().then(() => require("./help.command-DvKmMpB7.cjs"));
1505
+ if (options.tuiOptions?.hideDefaultScreen) await Promise.resolve().then(() => require("./help.command-Dg-0v-yP.cjs"));
1376
1506
  const app = await _navios_core.NaviosFactory.create(appModule, {
1377
1507
  adapter: defineCliEnvironment(),
1378
1508
  logger: options.logLevels