@navios/commander 0.5.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 (72) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +242 -0
  3. package/dist/src/commander.application.d.mts +29 -0
  4. package/dist/src/commander.application.d.mts.map +1 -0
  5. package/dist/src/commander.factory.d.mts +8 -0
  6. package/dist/src/commander.factory.d.mts.map +1 -0
  7. package/dist/src/decorators/cli-module.decorator.d.mts +7 -0
  8. package/dist/src/decorators/cli-module.decorator.d.mts.map +1 -0
  9. package/dist/src/decorators/command.decorator.d.mts +8 -0
  10. package/dist/src/decorators/command.decorator.d.mts.map +1 -0
  11. package/dist/src/decorators/index.d.mts +3 -0
  12. package/dist/src/decorators/index.d.mts.map +1 -0
  13. package/dist/src/index.d.mts +8 -0
  14. package/dist/src/index.d.mts.map +1 -0
  15. package/dist/src/interfaces/cli-module.interface.d.mts +5 -0
  16. package/dist/src/interfaces/cli-module.interface.d.mts.map +1 -0
  17. package/dist/src/interfaces/command-handler.interface.d.mts +4 -0
  18. package/dist/src/interfaces/command-handler.interface.d.mts.map +1 -0
  19. package/dist/src/interfaces/index.d.mts +3 -0
  20. package/dist/src/interfaces/index.d.mts.map +1 -0
  21. package/dist/src/interfaces/module.interface.d.mts +5 -0
  22. package/dist/src/interfaces/module.interface.d.mts.map +1 -0
  23. package/dist/src/metadata/cli-module.metadata.d.mts +11 -0
  24. package/dist/src/metadata/cli-module.metadata.d.mts.map +1 -0
  25. package/dist/src/metadata/command.metadata.d.mts +12 -0
  26. package/dist/src/metadata/command.metadata.d.mts.map +1 -0
  27. package/dist/src/metadata/index.d.mts +3 -0
  28. package/dist/src/metadata/index.d.mts.map +1 -0
  29. package/dist/src/services/cli-parser.service.d.mts +44 -0
  30. package/dist/src/services/cli-parser.service.d.mts.map +1 -0
  31. package/dist/src/services/index.d.mts +3 -0
  32. package/dist/src/services/index.d.mts.map +1 -0
  33. package/dist/src/services/module-loader.service.d.mts +33 -0
  34. package/dist/src/services/module-loader.service.d.mts.map +1 -0
  35. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  36. package/dist/tsconfig.tsbuildinfo +1 -0
  37. package/dist/tsup.config.d.mts +3 -0
  38. package/dist/tsup.config.d.mts.map +1 -0
  39. package/dist/vitest.config.d.mts +3 -0
  40. package/dist/vitest.config.d.mts.map +1 -0
  41. package/lib/_tsup-dts-rollup.d.mts +456 -0
  42. package/lib/_tsup-dts-rollup.d.ts +456 -0
  43. package/lib/index.d.mts +98 -0
  44. package/lib/index.d.ts +98 -0
  45. package/lib/index.js +541 -0
  46. package/lib/index.js.map +1 -0
  47. package/lib/index.mjs +524 -0
  48. package/lib/index.mjs.map +1 -0
  49. package/package.json +40 -0
  50. package/project.json +66 -0
  51. package/src/__tests__/commander.factory.e2e.spec.mts +965 -0
  52. package/src/commander.application.mts +159 -0
  53. package/src/commander.factory.mts +20 -0
  54. package/src/decorators/cli-module.decorator.mts +39 -0
  55. package/src/decorators/command.decorator.mts +29 -0
  56. package/src/decorators/index.mts +2 -0
  57. package/src/index.mts +7 -0
  58. package/src/interfaces/command-handler.interface.mts +3 -0
  59. package/src/interfaces/index.mts +2 -0
  60. package/src/interfaces/module.interface.mts +4 -0
  61. package/src/metadata/cli-module.metadata.mts +54 -0
  62. package/src/metadata/command.metadata.mts +54 -0
  63. package/src/metadata/index.mts +2 -0
  64. package/src/services/__tests__/cli-parser.service.spec.mts +404 -0
  65. package/src/services/cli-parser.service.mts +231 -0
  66. package/src/services/index.mts +2 -0
  67. package/src/services/module-loader.service.mts +120 -0
  68. package/tsconfig.json +18 -0
  69. package/tsconfig.lib.json +8 -0
  70. package/tsconfig.spec.json +13 -0
  71. package/tsup.config.mts +12 -0
  72. package/vitest.config.mts +9 -0
@@ -0,0 +1,120 @@
1
+ import type { ClassTypeWithInstance } from '@navios/di'
2
+
3
+ import { Container, inject, Injectable } from '@navios/di'
4
+
5
+ import type { CommandHandler, Module } from '../interfaces/index.mjs'
6
+ import type { CliModuleMetadata, CommandMetadata } from '../metadata/index.mjs'
7
+
8
+ import {
9
+ extractCliModuleMetadata,
10
+ extractCommandMetadata,
11
+ } from '../metadata/index.mjs'
12
+
13
+ export interface CommandWithMetadata {
14
+ class: ClassTypeWithInstance<CommandHandler>
15
+ metadata: CommandMetadata
16
+ }
17
+
18
+ @Injectable()
19
+ export class ModuleLoaderService {
20
+ protected container = inject(Container)
21
+ private modulesMetadata: Map<string, CliModuleMetadata> = new Map()
22
+ private loadedModules: Map<string, any> = new Map()
23
+ private commandsMetadata: Map<string, CommandWithMetadata> = new Map()
24
+ private initialized = false
25
+
26
+ async loadModules(appModule: ClassTypeWithInstance<Module>) {
27
+ if (this.initialized) {
28
+ return
29
+ }
30
+ await this.traverseModules(appModule)
31
+ this.initialized = true
32
+ }
33
+
34
+ private async traverseModules(
35
+ module: ClassTypeWithInstance<Module>,
36
+ parentMetadata?: CliModuleMetadata,
37
+ ) {
38
+ const metadata = extractCliModuleMetadata(module)
39
+ if (parentMetadata) {
40
+ this.mergeMetadata(metadata, parentMetadata)
41
+ }
42
+ const moduleName = module.name
43
+ if (this.modulesMetadata.has(moduleName)) {
44
+ return
45
+ }
46
+ this.modulesMetadata.set(moduleName, metadata)
47
+
48
+ // Collect command metadata during module loading
49
+ for (const command of metadata.commands) {
50
+ const commandMetadata = extractCommandMetadata(command)
51
+ this.commandsMetadata.set(commandMetadata.path, {
52
+ class: command,
53
+ metadata: commandMetadata,
54
+ })
55
+ }
56
+
57
+ const imports = metadata.imports ?? new Set()
58
+ const loadingPromises = Array.from(imports).map(async (importedModule) =>
59
+ this.traverseModules(importedModule, metadata),
60
+ )
61
+ await Promise.all(loadingPromises)
62
+ const instance = await this.container.get(module)
63
+ if (instance.onModuleInit) {
64
+ await instance.onModuleInit()
65
+ }
66
+ this.loadedModules.set(moduleName, instance)
67
+ }
68
+
69
+ private mergeMetadata(
70
+ metadata: CliModuleMetadata,
71
+ parentMetadata: CliModuleMetadata,
72
+ ): void {
73
+ if (parentMetadata.customAttributes) {
74
+ for (const [key, value] of parentMetadata.customAttributes) {
75
+ if (metadata.customAttributes.has(key)) {
76
+ continue
77
+ }
78
+ metadata.customAttributes.set(key, value)
79
+ }
80
+ }
81
+ }
82
+
83
+ getAllModules(): Map<string, CliModuleMetadata> {
84
+ return this.modulesMetadata
85
+ }
86
+
87
+ getAllCommands(): Map<string, ClassTypeWithInstance<any>> {
88
+ const commands = new Map<string, ClassTypeWithInstance<any>>()
89
+ for (const metadata of this.modulesMetadata.values()) {
90
+ for (const command of metadata.commands) {
91
+ commands.set(command.name, command)
92
+ }
93
+ }
94
+ return commands
95
+ }
96
+
97
+ /**
98
+ * Get all commands with their metadata, indexed by command path.
99
+ * This is populated during loadModules, so path information is available
100
+ * before parsing CLI argv.
101
+ */
102
+ getAllCommandsWithMetadata(): Map<string, CommandWithMetadata> {
103
+ return this.commandsMetadata
104
+ }
105
+
106
+ /**
107
+ * Get a command by its path, with metadata already extracted.
108
+ * Returns undefined if command is not found.
109
+ */
110
+ getCommandByPath(path: string): CommandWithMetadata | undefined {
111
+ return this.commandsMetadata.get(path)
112
+ }
113
+
114
+ dispose() {
115
+ this.modulesMetadata.clear()
116
+ this.loadedModules.clear()
117
+ this.commandsMetadata.clear()
118
+ this.initialized = false
119
+ }
120
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "Node18",
5
+ "outDir": "dist"
6
+ },
7
+ "references": [
8
+ {
9
+ "path": "./tsconfig.lib.json"
10
+ },
11
+ {
12
+ "path": "./tsconfig.spec.json"
13
+ },
14
+ {
15
+ "path": "../di"
16
+ }
17
+ ]
18
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist"
5
+ },
6
+ "include": ["src/**/*"],
7
+ "exclude": ["src/**/*.spec.mts"]
8
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "types": ["bun-types"]
6
+ },
7
+ "include": ["src/**/*.spec.mts"],
8
+ "references": [
9
+ {
10
+ "path": "./tsconfig.lib.json"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,12 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.mts', 'src/testing/index.mts'],
5
+ outDir: 'lib',
6
+ format: ['esm', 'cjs'],
7
+ clean: true,
8
+ treeshake: 'smallest',
9
+ sourcemap: true,
10
+ platform: 'node',
11
+ experimentalDts: true,
12
+ })
@@ -0,0 +1,9 @@
1
+ import { defineProject } from 'vitest/config'
2
+
3
+ export default defineProject({
4
+ test: {
5
+ typecheck: {
6
+ enabled: true,
7
+ },
8
+ },
9
+ })