@navios/commander 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/README.md +22 -0
- package/dist/src/commander.factory.d.mts +59 -0
- package/dist/src/commander.factory.d.mts.map +1 -1
- package/dist/src/commands/help.command.d.mts.map +1 -1
- package/dist/src/decorators/command.decorator.d.mts +9 -2
- package/dist/src/decorators/command.decorator.d.mts.map +1 -1
- package/dist/src/legacy-compat/decorators/cli-module.decorator.d.mts +26 -0
- package/dist/src/legacy-compat/decorators/cli-module.decorator.d.mts.map +1 -0
- package/dist/src/legacy-compat/decorators/command.decorator.d.mts +34 -0
- package/dist/src/legacy-compat/decorators/command.decorator.d.mts.map +1 -0
- package/dist/src/legacy-compat/decorators/index.d.mts +3 -0
- package/dist/src/legacy-compat/decorators/index.d.mts.map +1 -0
- package/dist/src/legacy-compat/index.d.mts +28 -0
- package/dist/src/legacy-compat/index.d.mts.map +1 -0
- package/dist/src/overrides/help.command.d.mts +18 -0
- package/dist/src/overrides/help.command.d.mts.map +1 -0
- package/dist/src/tokens/help-command.token.d.mts +4 -0
- package/dist/src/tokens/help-command.token.d.mts.map +1 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/lib/cli-module.decorator-CkP22084.cjs +71 -0
- package/lib/cli-module.decorator-CkP22084.cjs.map +1 -0
- package/lib/cli-module.decorator-DGuGfpex.d.mts +411 -0
- package/lib/cli-module.decorator-DGuGfpex.d.mts.map +1 -0
- package/lib/cli-module.decorator-DVl8009Q.d.cts +213 -0
- package/lib/cli-module.decorator-DVl8009Q.d.cts.map +1 -0
- package/lib/cli-module.decorator-UGbtkRYc.mjs +66 -0
- package/lib/cli-module.decorator-UGbtkRYc.mjs.map +1 -0
- package/lib/command.decorator-DVLSAqYZ.mjs +135 -0
- package/lib/command.decorator-DVLSAqYZ.mjs.map +1 -0
- package/lib/command.decorator-UrNJmQN0.cjs +176 -0
- package/lib/command.decorator-UrNJmQN0.cjs.map +1 -0
- package/lib/help-command.token-C0Kgj60o.mjs +427 -0
- package/lib/help-command.token-C0Kgj60o.mjs.map +1 -0
- package/lib/help-command.token-CMWYI6em.cjs +438 -0
- package/lib/help-command.token-CMWYI6em.cjs.map +1 -0
- package/lib/help.command-DQyv6ali.cjs +317 -0
- package/lib/help.command-DQyv6ali.cjs.map +1 -0
- package/lib/help.command-dtZbhq0w.mjs +318 -0
- package/lib/help.command-dtZbhq0w.mjs.map +1 -0
- package/lib/index.cjs +45 -627
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +139 -281
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.mts +62 -402
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +30 -612
- package/lib/index.mjs.map +1 -1
- package/lib/legacy-compat/index.cjs +108 -0
- package/lib/legacy-compat/index.cjs.map +1 -0
- package/lib/legacy-compat/index.d.cts +63 -0
- package/lib/legacy-compat/index.d.cts.map +1 -0
- package/lib/legacy-compat/index.d.mts +63 -0
- package/lib/legacy-compat/index.d.mts.map +1 -0
- package/lib/legacy-compat/index.mjs +101 -0
- package/lib/legacy-compat/index.mjs.map +1 -0
- package/package.json +20 -3
- package/src/commander.factory.mts +107 -8
- package/src/commands/help.command.mts +4 -3
- package/src/decorators/command.decorator.mts +17 -8
- package/src/legacy-compat/decorators/cli-module.decorator.mts +46 -0
- package/src/legacy-compat/decorators/command.decorator.mts +46 -0
- package/src/legacy-compat/decorators/index.mts +2 -0
- package/src/legacy-compat/index.mts +31 -0
- package/src/overrides/help.command.mts +40 -0
- package/src/tokens/help-command.token.mts +5 -0
- package/tsconfig.json +0 -3
- package/tsconfig.spec.json +1 -1
- package/tsdown.config.mts +1 -1
- package/dist/src/commander.application.d.mts +0 -147
- package/dist/src/commander.application.d.mts.map +0 -1
- package/dist/src/metadata/cli-module.metadata.d.mts +0 -60
- package/dist/src/metadata/cli-module.metadata.d.mts.map +0 -1
- package/dist/src/services/module-loader.service.d.mts +0 -74
- package/dist/src/services/module-loader.service.d.mts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["createClassContext","Command","OriginalCommand","options","target","context","originalDecorator","createClassContext","CliModule","OriginalCliModule","options","commands","controllers","imports","guards","overrides","target","context","originalDecorator"],"sources":["../../../../node_modules/@navios/di/lib/legacy-compat/index.mjs","../../src/legacy-compat/decorators/command.decorator.mts","../../src/legacy-compat/decorators/cli-module.decorator.mts"],"sourcesContent":["import { t as Injectable$1 } from \"../injectable.decorator-CyPrBzBN.mjs\";\nimport { t as Factory$1 } from \"../factory.decorator-_IPWcwQn.mjs\";\n\n//#region src/legacy-compat/context-compat.mts\n/**\n* Compatibility layer for converting legacy decorator signatures to Stage 3 format.\n*\n* This module provides utilities to create mock Stage 3 decorator contexts\n* from legacy decorator arguments, and manages metadata storage using WeakMap.\n*/ const classMetadataMap = /* @__PURE__ */ new WeakMap();\n/**\n* Gets the constructor from a prototype (for method decorators).\n*/ function getConstructor(prototype) {\n\tif (!prototype || typeof prototype !== \"object\") return null;\n\tconst constructor = prototype.constructor;\n\tif (constructor && typeof constructor === \"function\") return constructor;\n\treturn null;\n}\n/**\n* Creates a mock ClassDecoratorContext for legacy class decorators.\n* @internal\n*/ function createClassContext(target) {\n\tif (!classMetadataMap.has(target)) classMetadataMap.set(target, {});\n\tconst metadata = classMetadataMap.get(target);\n\treturn {\n\t\tkind: \"class\",\n\t\tname: target.name,\n\t\tmetadata,\n\t\taddInitializer() {}\n\t};\n}\n/**\n* Creates a mock ClassMethodDecoratorContext for legacy method decorators.\n*\n* Note: Method decorators need to share metadata with the class context\n* because endpoint metadata is stored at the class level.\n* @internal\n*/ function createMethodContext(target, propertyKey, descriptor) {\n\tconst constructor = getConstructor(target);\n\tif (!constructor) throw new Error(\"[Navios] Could not determine class constructor from method decorator target.\");\n\tif (!classMetadataMap.has(constructor)) classMetadataMap.set(constructor, {});\n\treturn {\n\t\tkind: \"method\",\n\t\tname: propertyKey,\n\t\tmetadata: classMetadataMap.get(constructor),\n\t\tstatic: false,\n\t\tprivate: false,\n\t\taccess: {\n\t\t\thas: () => true,\n\t\t\tget: () => descriptor.value,\n\t\t\tset: () => {}\n\t\t},\n\t\taddInitializer() {}\n\t};\n}\n\n//#endregion\n//#region src/legacy-compat/injectable.decorator.mts\n/**\n* Legacy-compatible Injectable decorator.\n*\n* Works with TypeScript experimental decorators (legacy API).\n*\n* @param options - Injectable configuration options\n* @returns A class decorator compatible with legacy decorator API\n*\n* @example\n* ```typescript\n* @Injectable()\n* export class UserService {\n* getUser(id: string) {\n* return { id, name: 'John' }\n* }\n* }\n* ```\n*/ function Injectable(options = {}) {\n\treturn function(target) {\n\t\tconst context = createClassContext(target);\n\t\treturn (Object.keys(options).length === 0 ? Injectable$1() : Injectable$1(options))(target, context);\n\t};\n}\n\n//#endregion\n//#region src/legacy-compat/factory.decorator.mts\n/**\n* Legacy-compatible Factory decorator.\n*\n* Works with TypeScript experimental decorators (legacy API).\n*\n* @param options - Factory configuration options\n* @returns A class decorator compatible with legacy decorator API\n*\n* @example\n* ```typescript\n* @Factory()\n* export class DatabaseConnectionFactory {\n* create() {\n* return { host: 'localhost', port: 5432 }\n* }\n* }\n* ```\n*/ function Factory(options = {}) {\n\treturn function(target) {\n\t\tconst context = createClassContext(target);\n\t\treturn (Object.keys(options).length === 0 ? Factory$1() : Factory$1(options))(target, context);\n\t};\n}\n\n//#endregion\nexport { Factory, Injectable, createClassContext, createMethodContext };\n//# sourceMappingURL=index.mjs.map","import type { ClassType } from '@navios/core'\nimport { createClassContext } from '@navios/di/legacy-compat'\n\nimport {\n Command as OriginalCommand,\n type CommandOptions,\n} from '../../decorators/command.decorator.mjs'\n\nexport type { CommandOptions }\n\n/**\n * Legacy-compatible Command decorator.\n *\n * Works with TypeScript experimental decorators (legacy API).\n *\n * @param options - Command configuration options\n * @returns A class decorator compatible with legacy decorator API\n *\n * @example\n * ```typescript\n * import { Command, CommandHandler } from '@navios/commander/legacy-compat'\n * import { z } from 'zod'\n *\n * const optionsSchema = z.object({\n * name: z.string(),\n * greeting: z.string().optional().default('Hello')\n * })\n *\n * @Command({\n * path: 'greet',\n * optionsSchema: optionsSchema\n * })\n * export class GreetCommand implements CommandHandler<z.infer<typeof optionsSchema>> {\n * async execute(options) {\n * console.log(`${options.greeting}, ${options.name}!`)\n * }\n * }\n * ```\n */\nexport function Command(options: CommandOptions) {\n return function (target: ClassType) {\n const context = createClassContext(target)\n const originalDecorator = OriginalCommand(options)\n return originalDecorator(target, context)\n }\n}\n","import type { ClassType } from '@navios/core'\nimport { createClassContext } from '@navios/di/legacy-compat'\n\nimport {\n CliModule as OriginalCliModule,\n type CliModuleOptions,\n} from '../../decorators/cli-module.decorator.mjs'\n\nexport type { CliModuleOptions }\n\n/**\n * Legacy-compatible CliModule decorator.\n *\n * Works with TypeScript experimental decorators (legacy API).\n *\n * @param options - CLI module configuration options\n * @returns A class decorator compatible with legacy decorator API\n *\n * @example\n * ```typescript\n * import { CliModule } from '@navios/commander/legacy-compat'\n * import { GreetCommand } from './greet.command'\n * import { UserModule } from './user.module'\n *\n * @CliModule({\n * commands: [GreetCommand],\n * imports: [UserModule]\n * })\n * export class AppModule {}\n * ```\n */\nexport function CliModule(\n options: CliModuleOptions = {\n commands: [],\n controllers: [],\n imports: [],\n guards: [],\n overrides: [],\n },\n) {\n return function (target: ClassType) {\n const context = createClassContext(target)\n const originalDecorator = OriginalCliModule(options)\n return originalDecorator(target, context)\n }\n}\n"],"x_google_ignoreList":[0],"mappings":";;;;;;;;;;;GASG,MAAM,mCAAmC,IAAI,SAAS;;;;GAYtD,SAAS,mBAAmB,QAAQ;AACtC,KAAI,CAAC,iBAAiB,IAAI,OAAO,CAAE,kBAAiB,IAAI,QAAQ,EAAE,CAAC;CACnE,MAAM,WAAW,iBAAiB,IAAI,OAAO;AAC7C,QAAO;EACN,MAAM;EACN,MAAM,OAAO;EACb;EACA,iBAAiB;EACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GCUF,SAAgBC,QAAQE,SAAuB;AAC7C,QAAO,SAAUC,QAAiB;EAChC,MAAMC,UAAUL,mBAAmBI,OAAAA;AAEnC,SAD0BF,UAAgBC,QAAAA,CACjBC,QAAQC,QAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GCZrC,SAAgBG,UACdE,UAA4B;CAC1BC,UAAU,EAAE;CACZC,aAAa,EAAE;CACfC,SAAS,EAAE;CACXC,QAAQ,EAAE;CACVC,WAAW,EAAE;CACd,EAAA;AAED,QAAO,SAAUC,QAAiB;EAChC,MAAMC,UAAUV,mBAAmBS,OAAAA;AAEnC,SAD0BP,YAAkBC,QAAAA,CACnBM,QAAQC,QAAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@navios/commander",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Oleksandr Hanzha",
|
|
6
6
|
"email": "alex@granted.name"
|
|
@@ -8,12 +8,18 @@
|
|
|
8
8
|
"repository": {
|
|
9
9
|
"directory": "packages/commander",
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "https://github.com/
|
|
11
|
+
"url": "https://github.com/navios-org/commander.git"
|
|
12
12
|
},
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"peerDependencies": {
|
|
15
|
+
"@navios/commander-tui": "^1.0.0",
|
|
15
16
|
"zod": "^4.0.0"
|
|
16
17
|
},
|
|
18
|
+
"peerDependenciesMeta": {
|
|
19
|
+
"@navios/commander-tui": {
|
|
20
|
+
"optional": true
|
|
21
|
+
}
|
|
22
|
+
},
|
|
17
23
|
"typings": "./lib/index.d.mts",
|
|
18
24
|
"main": "./lib/index.cjs",
|
|
19
25
|
"module": "./lib/index.mjs",
|
|
@@ -27,12 +33,23 @@
|
|
|
27
33
|
"types": "./lib/index.d.cts",
|
|
28
34
|
"default": "./lib/index.cjs"
|
|
29
35
|
}
|
|
36
|
+
},
|
|
37
|
+
"./legacy-compat": {
|
|
38
|
+
"import": {
|
|
39
|
+
"types": "./lib/legacy-compat/index.d.mts",
|
|
40
|
+
"default": "./lib/legacy-compat/index.mjs"
|
|
41
|
+
},
|
|
42
|
+
"require": {
|
|
43
|
+
"types": "./lib/legacy-compat/index.d.cts",
|
|
44
|
+
"default": "./lib/legacy-compat/index.cjs"
|
|
45
|
+
}
|
|
30
46
|
}
|
|
31
47
|
},
|
|
32
48
|
"devDependencies": {
|
|
49
|
+
"@navios/builder": "^1.0.0",
|
|
33
50
|
"tsx": "^4.21.0",
|
|
34
51
|
"typescript": "^5.9.3",
|
|
35
|
-
"zod": "^4.
|
|
52
|
+
"zod": "^4.3.5"
|
|
36
53
|
},
|
|
37
54
|
"dependencies": {
|
|
38
55
|
"@navios/core": "^1.0.0"
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ClassTypeWithInstance,
|
|
3
|
-
LogLevel,
|
|
4
|
-
NaviosApplication,
|
|
5
|
-
NaviosModule,
|
|
6
|
-
} from '@navios/core'
|
|
7
|
-
|
|
8
1
|
import { ConsoleLogger, NaviosFactory } from '@navios/core'
|
|
9
2
|
|
|
10
|
-
import type {
|
|
3
|
+
import type { ClassTypeWithInstance, LogLevel, NaviosApplication, NaviosModule } from '@navios/core'
|
|
11
4
|
|
|
12
5
|
import { defineCliEnvironment } from './define-environment.mjs'
|
|
13
6
|
|
|
7
|
+
import type { CliEnvironment } from './interfaces/environment.interface.mjs'
|
|
8
|
+
|
|
14
9
|
/**
|
|
15
10
|
* Logger display options for CLI applications.
|
|
16
11
|
* All options default to false for cleaner CLI output.
|
|
@@ -55,16 +50,76 @@ export interface CommanderLoggerOptions {
|
|
|
55
50
|
showTimeDiff?: boolean
|
|
56
51
|
}
|
|
57
52
|
|
|
53
|
+
/**
|
|
54
|
+
* TUI-specific options for terminal UI mode.
|
|
55
|
+
* Only used when enableTUI is true.
|
|
56
|
+
*
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
export interface CommanderTuiOptions {
|
|
60
|
+
/**
|
|
61
|
+
* Exit on Ctrl+C.
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
exitOnCtrlC?: boolean
|
|
65
|
+
/**
|
|
66
|
+
* Sidebar width in columns.
|
|
67
|
+
*/
|
|
68
|
+
sidebarWidth?: number
|
|
69
|
+
/**
|
|
70
|
+
* Sidebar position.
|
|
71
|
+
*/
|
|
72
|
+
sidebarPosition?: 'left' | 'right'
|
|
73
|
+
/**
|
|
74
|
+
* Sidebar header title.
|
|
75
|
+
*/
|
|
76
|
+
sidebarTitle?: string
|
|
77
|
+
/**
|
|
78
|
+
* Auto close after all screens complete successfully.
|
|
79
|
+
* Set to true for default delay (5000ms), or specify delay in milliseconds.
|
|
80
|
+
*/
|
|
81
|
+
autoClose?: boolean | number
|
|
82
|
+
/**
|
|
83
|
+
* Theme preset name ('dark', 'light', 'high-contrast') or custom theme object.
|
|
84
|
+
*/
|
|
85
|
+
theme?: string | Record<string, unknown>
|
|
86
|
+
/**
|
|
87
|
+
* Enable mouse support.
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
useMouse?: boolean
|
|
91
|
+
/**
|
|
92
|
+
* Hide the default console logger screen from the sidebar.
|
|
93
|
+
* @default false
|
|
94
|
+
*/
|
|
95
|
+
hideDefaultScreen?: boolean
|
|
96
|
+
}
|
|
97
|
+
|
|
58
98
|
/**
|
|
59
99
|
* Configuration options for CommanderFactory.
|
|
60
100
|
*
|
|
61
101
|
* @public
|
|
62
102
|
*/
|
|
63
103
|
export interface CommanderFactoryOptions {
|
|
104
|
+
/**
|
|
105
|
+
* Enabled log levels.
|
|
106
|
+
* @default ['log', 'error', 'warn', 'debug', 'verbose', 'fatal']
|
|
107
|
+
*/
|
|
108
|
+
logLevels?: LogLevel[]
|
|
64
109
|
/**
|
|
65
110
|
* Logger display options. These override the default CLI-friendly logger settings.
|
|
111
|
+
* Ignored when enableTUI is true.
|
|
66
112
|
*/
|
|
67
113
|
logger?: CommanderLoggerOptions
|
|
114
|
+
/**
|
|
115
|
+
* Enable TUI mode with @navios/commander-tui.
|
|
116
|
+
* Requires @navios/commander-tui to be installed.
|
|
117
|
+
*/
|
|
118
|
+
enableTUI?: boolean
|
|
119
|
+
/**
|
|
120
|
+
* TUI-specific options. Only used when enableTUI is true.
|
|
121
|
+
*/
|
|
122
|
+
tuiOptions?: CommanderTuiOptions
|
|
68
123
|
}
|
|
69
124
|
|
|
70
125
|
/**
|
|
@@ -122,6 +177,50 @@ export class CommanderFactory {
|
|
|
122
177
|
appModule: ClassTypeWithInstance<TModule>,
|
|
123
178
|
options: CommanderFactoryOptions = {},
|
|
124
179
|
): Promise<NaviosApplication<CliEnvironment>> {
|
|
180
|
+
if (options.enableTUI) {
|
|
181
|
+
// Dynamic import to keep commander-tui as optional peer dependency
|
|
182
|
+
let tuiModule: typeof import('@navios/commander-tui')
|
|
183
|
+
try {
|
|
184
|
+
tuiModule = await import('@navios/commander-tui')
|
|
185
|
+
} catch {
|
|
186
|
+
throw new Error(
|
|
187
|
+
'TUI mode requires @navios/commander-tui package. ' +
|
|
188
|
+
'Install it with: npm install @navios/commander-tui',
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const { overrideConsoleLogger, ScreenManager } = tuiModule
|
|
193
|
+
|
|
194
|
+
// Override the ConsoleLogger service to use the ScreenLogger service instead of the default ConsoleLogger service.
|
|
195
|
+
overrideConsoleLogger(options.tuiOptions?.hideDefaultScreen ?? false)
|
|
196
|
+
|
|
197
|
+
if (options.tuiOptions?.hideDefaultScreen) {
|
|
198
|
+
// Import the help command override to ensure it is registered
|
|
199
|
+
await import('./overrides/help.command.mjs')
|
|
200
|
+
}
|
|
201
|
+
// Create app without custom logger - TUI override handles it
|
|
202
|
+
const app = await NaviosFactory.create<CliEnvironment>(appModule, {
|
|
203
|
+
adapter: defineCliEnvironment(),
|
|
204
|
+
logger: options.logLevels,
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
// Get screen manager and bind TUI before returning
|
|
208
|
+
const screenManager = await app.get(ScreenManager)
|
|
209
|
+
await screenManager.bind({
|
|
210
|
+
exitOnCtrlC: options.tuiOptions?.exitOnCtrlC,
|
|
211
|
+
sidebarWidth: options.tuiOptions?.sidebarWidth,
|
|
212
|
+
sidebarPosition: options.tuiOptions?.sidebarPosition,
|
|
213
|
+
sidebarTitle: options.tuiOptions?.sidebarTitle,
|
|
214
|
+
autoClose: options.tuiOptions?.autoClose,
|
|
215
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
216
|
+
theme: options.tuiOptions?.theme as any,
|
|
217
|
+
useMouse: options.tuiOptions?.useMouse,
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
return app
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Standard (non-TUI) mode - existing behavior unchanged
|
|
125
224
|
const app = await NaviosFactory.create<CliEnvironment>(appModule, {
|
|
126
225
|
adapter: defineCliEnvironment(),
|
|
127
226
|
logger: ConsoleLogger.create({
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { inject, Logger } from '@navios/core'
|
|
2
|
-
|
|
3
2
|
import { z } from 'zod'
|
|
4
3
|
|
|
5
|
-
import type { CommandHandler } from '../interfaces/command-handler.interface.mjs'
|
|
6
|
-
|
|
7
4
|
import { Command } from '../decorators/command.decorator.mjs'
|
|
8
5
|
import { CommandRegistryService } from '../services/command-registry.service.mjs'
|
|
6
|
+
import { HelpCommandToken } from '../tokens/help-command.token.mjs'
|
|
7
|
+
|
|
8
|
+
import type { CommandHandler } from '../interfaces/command-handler.interface.mjs'
|
|
9
9
|
|
|
10
10
|
const helpOptionsSchema = z.object({
|
|
11
11
|
command: z.string().optional(),
|
|
@@ -19,6 +19,7 @@ type HelpOptions = z.infer<typeof helpOptionsSchema>
|
|
|
19
19
|
* @public
|
|
20
20
|
*/
|
|
21
21
|
@Command({
|
|
22
|
+
token: HelpCommandToken,
|
|
22
23
|
path: 'help',
|
|
23
24
|
description: 'Show available commands or help for a specific command',
|
|
24
25
|
optionsSchema: helpOptionsSchema,
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import type { ClassType, Registry } from '@navios/core'
|
|
2
|
-
import type { ZodObject } from 'zod'
|
|
3
|
-
|
|
4
1
|
import { Injectable, InjectableScope, InjectionToken } from '@navios/core'
|
|
5
2
|
|
|
3
|
+
import type { ClassType, ClassTypeWithInstance, Registry } from '@navios/core'
|
|
4
|
+
import type { ZodObject } from 'zod'
|
|
5
|
+
|
|
6
6
|
import { getCommandMetadata } from '../metadata/index.mjs'
|
|
7
7
|
|
|
8
|
+
import type { CommandHandler } from '../interfaces/index.mjs'
|
|
9
|
+
|
|
8
10
|
/**
|
|
9
11
|
* Options for the `@Command` decorator.
|
|
10
12
|
*
|
|
11
13
|
* @public
|
|
12
14
|
*/
|
|
13
15
|
export interface CommandOptions {
|
|
16
|
+
/**
|
|
17
|
+
* The token to use for the command.
|
|
18
|
+
* If provided, the command will be registered with this token.
|
|
19
|
+
*/
|
|
20
|
+
token?: InjectionToken<ClassTypeWithInstance<CommandHandler<any>>>
|
|
14
21
|
/**
|
|
15
22
|
* The command path that users will invoke from the CLI.
|
|
16
23
|
* Can be a single word (e.g., 'greet') or multi-word with colons (e.g., 'user:create', 'db:migrate').
|
|
@@ -71,22 +78,24 @@ export interface CommandOptions {
|
|
|
71
78
|
export function Command({
|
|
72
79
|
path,
|
|
73
80
|
description,
|
|
81
|
+
token,
|
|
74
82
|
optionsSchema,
|
|
75
83
|
priority,
|
|
76
84
|
registry,
|
|
77
85
|
}: CommandOptions) {
|
|
78
86
|
return function (target: ClassType, context: ClassDecoratorContext) {
|
|
79
87
|
if (context.kind !== 'class') {
|
|
80
|
-
throw new Error(
|
|
81
|
-
'[Navios Commander] @Command decorator can only be used on classes.',
|
|
82
|
-
)
|
|
88
|
+
throw new Error('[Navios Commander] @Command decorator can only be used on classes.')
|
|
83
89
|
}
|
|
84
|
-
const
|
|
90
|
+
const tokenToUse =
|
|
91
|
+
token ?? InjectionToken.create<ClassTypeWithInstance<CommandHandler<any>>>(target)
|
|
92
|
+
|
|
85
93
|
if (context.metadata) {
|
|
86
94
|
getCommandMetadata(target, context, path, description, optionsSchema)
|
|
87
95
|
}
|
|
96
|
+
// @ts-expect-error Injectable is callable
|
|
88
97
|
return Injectable({
|
|
89
|
-
token,
|
|
98
|
+
token: tokenToUse,
|
|
90
99
|
scope: InjectableScope.Singleton,
|
|
91
100
|
priority,
|
|
92
101
|
registry,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ClassType } from '@navios/core'
|
|
2
|
+
import { createClassContext } from '@navios/di/legacy-compat'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
CliModule as OriginalCliModule,
|
|
6
|
+
type CliModuleOptions,
|
|
7
|
+
} from '../../decorators/cli-module.decorator.mjs'
|
|
8
|
+
|
|
9
|
+
export type { CliModuleOptions }
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Legacy-compatible CliModule decorator.
|
|
13
|
+
*
|
|
14
|
+
* Works with TypeScript experimental decorators (legacy API).
|
|
15
|
+
*
|
|
16
|
+
* @param options - CLI module configuration options
|
|
17
|
+
* @returns A class decorator compatible with legacy decorator API
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { CliModule } from '@navios/commander/legacy-compat'
|
|
22
|
+
* import { GreetCommand } from './greet.command'
|
|
23
|
+
* import { UserModule } from './user.module'
|
|
24
|
+
*
|
|
25
|
+
* @CliModule({
|
|
26
|
+
* commands: [GreetCommand],
|
|
27
|
+
* imports: [UserModule]
|
|
28
|
+
* })
|
|
29
|
+
* export class AppModule {}
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function CliModule(
|
|
33
|
+
options: CliModuleOptions = {
|
|
34
|
+
commands: [],
|
|
35
|
+
controllers: [],
|
|
36
|
+
imports: [],
|
|
37
|
+
guards: [],
|
|
38
|
+
overrides: [],
|
|
39
|
+
},
|
|
40
|
+
) {
|
|
41
|
+
return function (target: ClassType) {
|
|
42
|
+
const context = createClassContext(target)
|
|
43
|
+
const originalDecorator = OriginalCliModule(options)
|
|
44
|
+
return originalDecorator(target, context)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ClassType } from '@navios/core'
|
|
2
|
+
import { createClassContext } from '@navios/di/legacy-compat'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
Command as OriginalCommand,
|
|
6
|
+
type CommandOptions,
|
|
7
|
+
} from '../../decorators/command.decorator.mjs'
|
|
8
|
+
|
|
9
|
+
export type { CommandOptions }
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Legacy-compatible Command decorator.
|
|
13
|
+
*
|
|
14
|
+
* Works with TypeScript experimental decorators (legacy API).
|
|
15
|
+
*
|
|
16
|
+
* @param options - Command configuration options
|
|
17
|
+
* @returns A class decorator compatible with legacy decorator API
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { Command, CommandHandler } from '@navios/commander/legacy-compat'
|
|
22
|
+
* import { z } from 'zod'
|
|
23
|
+
*
|
|
24
|
+
* const optionsSchema = z.object({
|
|
25
|
+
* name: z.string(),
|
|
26
|
+
* greeting: z.string().optional().default('Hello')
|
|
27
|
+
* })
|
|
28
|
+
*
|
|
29
|
+
* @Command({
|
|
30
|
+
* path: 'greet',
|
|
31
|
+
* optionsSchema: optionsSchema
|
|
32
|
+
* })
|
|
33
|
+
* export class GreetCommand implements CommandHandler<z.infer<typeof optionsSchema>> {
|
|
34
|
+
* async execute(options) {
|
|
35
|
+
* console.log(`${options.greeting}, ${options.name}!`)
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function Command(options: CommandOptions) {
|
|
41
|
+
return function (target: ClassType) {
|
|
42
|
+
const context = createClassContext(target)
|
|
43
|
+
const originalDecorator = OriginalCommand(options)
|
|
44
|
+
return originalDecorator(target, context)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy-compatible decorators for projects using TypeScript experimental decorators.
|
|
3
|
+
*
|
|
4
|
+
* These decorators wrap the Stage 3 decorator implementations and convert
|
|
5
|
+
* the legacy decorator arguments to Stage 3 format internally.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { Command, CliModule, CommandHandler } from '@navios/commander/legacy-compat'
|
|
10
|
+
*
|
|
11
|
+
* @Command({ path: 'greet' })
|
|
12
|
+
* export class GreetCommand implements CommandHandler {
|
|
13
|
+
* async execute() {
|
|
14
|
+
* console.log('Hello!')
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* @CliModule({
|
|
19
|
+
* commands: [GreetCommand],
|
|
20
|
+
* })
|
|
21
|
+
* export class AppModule {}
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @packageDocumentation
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
// Export legacy-compatible decorators (commander-specific)
|
|
28
|
+
export * from './decorators/index.mjs'
|
|
29
|
+
|
|
30
|
+
// Re-export core/DI legacy-compat utilities for convenience
|
|
31
|
+
export * from '@navios/core/legacy-compat'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ScreenLogger } from '@navios/commander-tui'
|
|
2
|
+
import { inject } from '@navios/core'
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
|
|
5
|
+
import { Command } from '../decorators/command.decorator.mjs'
|
|
6
|
+
import { CommandRegistryService } from '../services/command-registry.service.mjs'
|
|
7
|
+
import { HelpCommandToken } from '../tokens/help-command.token.mjs'
|
|
8
|
+
|
|
9
|
+
import type { CommandHandler } from '../interfaces/command-handler.interface.mjs'
|
|
10
|
+
|
|
11
|
+
const helpOptionsSchema = z.object({
|
|
12
|
+
command: z.string().optional(),
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
type HelpOptions = z.infer<typeof helpOptionsSchema>
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Built-in help command that lists all available commands or shows help for a specific command.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
@Command({
|
|
23
|
+
token: HelpCommandToken,
|
|
24
|
+
path: 'help',
|
|
25
|
+
description: 'Show available commands or help for a specific command',
|
|
26
|
+
optionsSchema: helpOptionsSchema,
|
|
27
|
+
priority: 1000,
|
|
28
|
+
})
|
|
29
|
+
export class HelpCommand implements CommandHandler<HelpOptions> {
|
|
30
|
+
private logger = inject(ScreenLogger, { screen: { name: 'Help', static: true }, context: 'Help' })
|
|
31
|
+
private commandRegistry = inject(CommandRegistryService)
|
|
32
|
+
|
|
33
|
+
async execute(options: HelpOptions): Promise<void> {
|
|
34
|
+
if (options.command) {
|
|
35
|
+
this.logger.log(this.commandRegistry.formatCommandHelp(options.command))
|
|
36
|
+
} else {
|
|
37
|
+
this.logger.log(this.commandRegistry.formatCommandList())
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
package/tsconfig.json
CHANGED
package/tsconfig.spec.json
CHANGED
package/tsdown.config.mts
CHANGED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import type { ClassTypeWithInstance, NaviosModule } from '@navios/core';
|
|
2
|
-
import { Container } from '@navios/core';
|
|
3
|
-
/**
|
|
4
|
-
* Configuration options for CommanderApplication.
|
|
5
|
-
*
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
export interface CommanderApplicationOptions {
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Main application class for managing CLI command execution.
|
|
12
|
-
*
|
|
13
|
-
* This class handles module loading, command registration, and command execution.
|
|
14
|
-
* It provides both programmatic and CLI-based command execution capabilities.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```typescript
|
|
18
|
-
* const app = await CommanderFactory.create(AppModule)
|
|
19
|
-
* await app.init()
|
|
20
|
-
* await app.run(process.argv)
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export declare class CommanderApplication {
|
|
24
|
-
private moduleLoader;
|
|
25
|
-
private cliParser;
|
|
26
|
-
protected container: Container;
|
|
27
|
-
private appModule;
|
|
28
|
-
private options;
|
|
29
|
-
/**
|
|
30
|
-
* Indicates whether the application has been initialized.
|
|
31
|
-
* Set to `true` after `init()` is called successfully.
|
|
32
|
-
*/
|
|
33
|
-
isInitialized: boolean;
|
|
34
|
-
/**
|
|
35
|
-
* @internal
|
|
36
|
-
* Sets up the application with the provided module and options.
|
|
37
|
-
* This is called automatically by CommanderFactory.create().
|
|
38
|
-
*/
|
|
39
|
-
setup(appModule: ClassTypeWithInstance<NaviosModule>, options?: CommanderApplicationOptions): Promise<void>;
|
|
40
|
-
/**
|
|
41
|
-
* Gets the dependency injection container used by this application.
|
|
42
|
-
*
|
|
43
|
-
* @returns The Container instance
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* ```typescript
|
|
47
|
-
* const container = app.getContainer()
|
|
48
|
-
* const service = await container.get(MyService)
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
getContainer(): Container;
|
|
52
|
-
/**
|
|
53
|
-
* Initializes the application by loading all modules and registering commands.
|
|
54
|
-
*
|
|
55
|
-
* This method must be called before executing commands or running the CLI.
|
|
56
|
-
* It traverses the module tree, loads all imported modules, and collects command metadata.
|
|
57
|
-
*
|
|
58
|
-
* @throws {Error} If the app module is not set (setup() was not called)
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* ```typescript
|
|
62
|
-
* const app = await CommanderFactory.create(AppModule)
|
|
63
|
-
* await app.init() // Must be called before run() or executeCommand()
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
init(): Promise<void>;
|
|
67
|
-
/**
|
|
68
|
-
* Executes a command programmatically with the provided options.
|
|
69
|
-
*
|
|
70
|
-
* This method is useful for testing, automation, or programmatic workflows.
|
|
71
|
-
* The options will be validated against the command's Zod schema if one is provided.
|
|
72
|
-
*
|
|
73
|
-
* @param commandPath - The command path (e.g., 'greet', 'user:create')
|
|
74
|
-
* @param options - The command options object (will be validated if schema exists)
|
|
75
|
-
* @throws {Error} If the application is not initialized
|
|
76
|
-
* @throws {Error} If the command is not found
|
|
77
|
-
* @throws {Error} If the command does not implement the execute method
|
|
78
|
-
* @throws {ZodError} If options validation fails
|
|
79
|
-
*
|
|
80
|
-
* @example
|
|
81
|
-
* ```typescript
|
|
82
|
-
* await app.executeCommand('greet', {
|
|
83
|
-
* name: 'World',
|
|
84
|
-
* greeting: 'Hi'
|
|
85
|
-
* })
|
|
86
|
-
* ```
|
|
87
|
-
*/
|
|
88
|
-
executeCommand(commandPath: string, options?: any): Promise<void>;
|
|
89
|
-
/**
|
|
90
|
-
* Gets all registered commands with their paths and class references.
|
|
91
|
-
*
|
|
92
|
-
* @returns An array of objects containing the command path and class
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* ```typescript
|
|
96
|
-
* const commands = app.getAllCommands()
|
|
97
|
-
* commands.forEach(({ path }) => {
|
|
98
|
-
* console.log(`Available: ${path}`)
|
|
99
|
-
* })
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
getAllCommands(): {
|
|
103
|
-
path: string;
|
|
104
|
-
class: ClassTypeWithInstance<any>;
|
|
105
|
-
}[];
|
|
106
|
-
/**
|
|
107
|
-
* Runs the CLI application by parsing command-line arguments and executing the appropriate command.
|
|
108
|
-
*
|
|
109
|
-
* This is the main entry point for CLI usage. It parses `argv`, validates options,
|
|
110
|
-
* and executes the matching command. Supports help command (`help`, `--help`, `-h`)
|
|
111
|
-
* which displays all available commands.
|
|
112
|
-
*
|
|
113
|
-
* @param argv - Command-line arguments array (defaults to `process.argv`)
|
|
114
|
-
* @throws {Error} If the application is not initialized
|
|
115
|
-
* @throws {Error} If no command is provided
|
|
116
|
-
* @throws {Error} If the command is not found
|
|
117
|
-
* @throws {ZodError} If options validation fails
|
|
118
|
-
*
|
|
119
|
-
* @example
|
|
120
|
-
* ```typescript
|
|
121
|
-
* // Parse and execute from process.argv
|
|
122
|
-
* await app.run()
|
|
123
|
-
*
|
|
124
|
-
* // Or provide custom arguments
|
|
125
|
-
* await app.run(['node', 'cli.js', 'greet', '--name', 'World'])
|
|
126
|
-
* ```
|
|
127
|
-
*/
|
|
128
|
-
run(argv?: string[]): Promise<void>;
|
|
129
|
-
/**
|
|
130
|
-
* @internal
|
|
131
|
-
* Disposes of resources used by the application.
|
|
132
|
-
*/
|
|
133
|
-
dispose(): Promise<void>;
|
|
134
|
-
/**
|
|
135
|
-
* Closes the application and cleans up resources.
|
|
136
|
-
*
|
|
137
|
-
* This should be called when the application is no longer needed to free up resources.
|
|
138
|
-
*
|
|
139
|
-
* @example
|
|
140
|
-
* ```typescript
|
|
141
|
-
* await app.run(process.argv)
|
|
142
|
-
* await app.close()
|
|
143
|
-
* ```
|
|
144
|
-
*/
|
|
145
|
-
close(): Promise<void>;
|
|
146
|
-
}
|
|
147
|
-
//# sourceMappingURL=commander.application.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commander.application.d.mts","sourceRoot":"","sources":["../../src/commander.application.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EAErB,YAAY,EACb,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,SAAS,EAAsB,MAAM,cAAc,CAAA;AAQ5D;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;CAAG;AAE/C;;;;;;;;;;;;GAYG;AACH,qBACa,oBAAoB;IAC/B,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,SAAS,CAA2B;IAC5C,SAAS,CAAC,SAAS,YAAoB;IAEvC,OAAO,CAAC,SAAS,CAAmD;IACpE,OAAO,CAAC,OAAO,CAAkC;IAEjD;;;OAGG;IACH,aAAa,UAAQ;IAErB;;;;OAIG;IACG,KAAK,CACT,SAAS,EAAE,qBAAqB,CAAC,YAAY,CAAC,EAC9C,OAAO,GAAE,2BAAgC;IAM3C;;;;;;;;;;OAUG;IACH,YAAY;IAIZ;;;;;;;;;;;;;OAaG;IACG,IAAI;IAUV;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,GAAQ;IAuD3D;;;;;;;;;;;;OAYG;IACH,cAAc;cAIJ,MAAM;eACL,qBAAqB,CAAC,GAAG,CAAC;;IAarC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,GAAG,CAAC,IAAI,GAAE,MAAM,EAAiB;IAgDvC;;;OAGG;IACG,OAAO;IAMb;;;;;;;;;;OAUG;IACG,KAAK;CAGZ"}
|