@navios/core 1.0.0-alpha.2 → 1.0.0-alpha.4
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 +90 -0
- package/lib/{index-BJjk2X1S.d.mts → index-6S7veHKD.d.mts} +845 -294
- package/lib/index-6S7veHKD.d.mts.map +1 -0
- package/lib/{index-DZ6NU03y.d.cts → index-r0i2txmg.d.cts} +845 -294
- package/lib/index-r0i2txmg.d.cts.map +1 -0
- package/lib/index.cjs +4420 -84
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +2 -2
- package/lib/index.d.mts +2 -2
- package/lib/index.mjs +4328 -3
- package/lib/index.mjs.map +1 -0
- package/lib/legacy-compat/index.cjs +41 -126
- package/lib/legacy-compat/index.cjs.map +1 -1
- package/lib/legacy-compat/index.d.cts +4 -60
- package/lib/legacy-compat/index.d.cts.map +1 -1
- package/lib/legacy-compat/index.d.mts +4 -60
- package/lib/legacy-compat/index.d.mts.map +1 -1
- package/lib/legacy-compat/index.mjs +14 -119
- package/lib/legacy-compat/index.mjs.map +1 -1
- package/lib/navios.factory-BanZIvtR.cjs +4134 -0
- package/lib/navios.factory-BanZIvtR.cjs.map +1 -0
- package/lib/navios.factory-C75yZCoD.mjs +3831 -0
- package/lib/navios.factory-C75yZCoD.mjs.map +1 -0
- package/lib/testing/index.cjs +3 -3
- package/lib/testing/index.cjs.map +1 -1
- package/lib/testing/index.d.cts +1 -1
- package/lib/testing/index.d.mts +1 -1
- package/lib/testing/index.mjs +2 -2
- package/lib/tokens-4J9sredA.mjs +100 -0
- package/lib/tokens-4J9sredA.mjs.map +1 -0
- package/lib/tokens-BuXXB01L.cjs +196 -0
- package/lib/tokens-BuXXB01L.cjs.map +1 -0
- package/lib/{use-guards.decorator-Be_QUx6b.mjs → use-guards.decorator-BecoQSmE.mjs} +3 -70
- package/lib/use-guards.decorator-BecoQSmE.mjs.map +1 -0
- package/lib/{use-guards.decorator-B6tghdxM.cjs → use-guards.decorator-DgD-kxF5.cjs} +7 -158
- package/lib/use-guards.decorator-DgD-kxF5.cjs.map +1 -0
- package/package.json +4 -4
- package/src/__tests__/attribute.factory.spec.mts +300 -0
- package/src/__tests__/console-logger.service.spec.mts +312 -0
- package/src/__tests__/guard-runner.service.spec.mts +399 -0
- package/src/__tests__/logger.service.spec.mts +147 -0
- package/src/__tests__/responders.spec.mts +6 -5
- package/src/factories/adapter.factory.mts +20 -0
- package/src/factories/endpoint-adapter.factory.mts +1 -1
- package/src/factories/http-adapter.factory.mts +1 -1
- package/src/factories/index.mts +1 -0
- package/src/factories/multipart-adapter.factory.mts +1 -1
- package/src/factories/reply.factory.mts +1 -1
- package/src/factories/request.factory.mts +1 -1
- package/src/factories/stream-adapter.factory.mts +1 -1
- package/src/factories/xml-stream-adapter.factory.mts +1 -1
- package/src/index.mts +1 -0
- package/src/interfaces/abstract-adapter.interface.mts +32 -0
- package/src/interfaces/abstract-http-adapter.interface.mts +27 -20
- package/src/interfaces/abstract-http-handler-adapter.interface.mts +86 -2
- package/src/interfaces/adapter-environment.interface.mts +74 -0
- package/src/interfaces/index.mts +2 -0
- package/src/interfaces/plugin.interface.mts +50 -16
- package/src/legacy-compat/attribute.factory.mts +2 -2
- package/src/legacy-compat/decorators/controller.decorator.mts +1 -1
- package/src/legacy-compat/decorators/endpoint.decorator.mts +1 -1
- package/src/legacy-compat/decorators/header.decorator.mts +2 -1
- package/src/legacy-compat/decorators/http-code.decorator.mts +2 -1
- package/src/legacy-compat/decorators/index.mts +2 -2
- package/src/legacy-compat/decorators/module.decorator.mts +1 -1
- package/src/legacy-compat/decorators/multipart.decorator.mts +1 -1
- package/src/legacy-compat/decorators/stream.decorator.mts +1 -1
- package/src/legacy-compat/decorators/use-guards.decorator.mts +1 -1
- package/src/legacy-compat/index.mts +10 -5
- package/src/logger/console-logger.service.mts +97 -7
- package/src/metadata/module.metadata.mts +43 -0
- package/src/navios.application.mts +172 -60
- package/src/navios.environment.mts +22 -12
- package/src/navios.factory.mts +31 -10
- package/src/services/abstract-handler-adapter.service.mts +366 -0
- package/src/services/index.mts +1 -0
- package/src/services/module-loader.service.mts +1 -0
- package/src/tokens/adapter.token.mts +6 -0
- package/src/tokens/http-adapter.token.mts +1 -1
- package/src/tokens/index.mts +1 -0
- package/src/utils/adapter-supports.util.mts +47 -0
- package/src/utils/index.mts +1 -0
- package/lib/index-BJjk2X1S.d.mts.map +0 -1
- package/lib/index-DZ6NU03y.d.cts.map +0 -1
- package/lib/src-C46ePe3d.cjs +0 -8022
- package/lib/src-C46ePe3d.cjs.map +0 -1
- package/lib/src-K2k0riYJ.mjs +0 -7587
- package/lib/src-K2k0riYJ.mjs.map +0 -1
- package/lib/use-guards.decorator-B6tghdxM.cjs.map +0 -1
- package/lib/use-guards.decorator-Be_QUx6b.mjs.map +0 -1
- package/src/legacy-compat/context-compat.mts +0 -95
- package/src/legacy-compat/decorators/factory.decorator.mts +0 -37
- package/src/legacy-compat/decorators/injectable.decorator.mts +0 -41
|
@@ -30,15 +30,46 @@ export interface ConsoleLoggerOptions {
|
|
|
30
30
|
*/
|
|
31
31
|
logLevels?: LogLevel[]
|
|
32
32
|
/**
|
|
33
|
-
* If enabled, will print timestamp
|
|
33
|
+
* If enabled, will print timestamp difference between current and previous log message.
|
|
34
34
|
* Note: This option is not used when `json` is enabled.
|
|
35
|
+
* @default false
|
|
35
36
|
*/
|
|
36
|
-
|
|
37
|
+
showTimeDiff?: boolean
|
|
37
38
|
/**
|
|
38
39
|
* A prefix to be used for each log message.
|
|
39
40
|
* Note: This option is not used when `json` is enabled.
|
|
40
41
|
*/
|
|
41
42
|
prefix?: string
|
|
43
|
+
/**
|
|
44
|
+
* If true, will print the process ID in the log message.
|
|
45
|
+
* Note: This option is not used when `json` is enabled.
|
|
46
|
+
* @default true
|
|
47
|
+
*/
|
|
48
|
+
showPid?: boolean
|
|
49
|
+
/**
|
|
50
|
+
* If true, will print the log level in the log message.
|
|
51
|
+
* Note: This option is not used when `json` is enabled.
|
|
52
|
+
* @default true
|
|
53
|
+
*/
|
|
54
|
+
showLogLevel?: boolean
|
|
55
|
+
/**
|
|
56
|
+
* If true, will print the prefix/app name in the log message.
|
|
57
|
+
* Note: This option is not used when `json` is enabled.
|
|
58
|
+
* @default true
|
|
59
|
+
*/
|
|
60
|
+
showPrefix?: boolean
|
|
61
|
+
/**
|
|
62
|
+
* If true, will print the context in the log message.
|
|
63
|
+
* Note: This option is not used when `json` is enabled.
|
|
64
|
+
* @default true
|
|
65
|
+
*/
|
|
66
|
+
showContext?: boolean
|
|
67
|
+
/**
|
|
68
|
+
* If true, will print the absolute timestamp in the log message.
|
|
69
|
+
* Note: This option is not used when `json` is enabled.
|
|
70
|
+
* @default true
|
|
71
|
+
*/
|
|
72
|
+
showTimestamp?: boolean
|
|
42
73
|
/**
|
|
43
74
|
* If enabled, will add a request ID to the log message.
|
|
44
75
|
*/
|
|
@@ -129,6 +160,31 @@ const dateTimeFormatter = new Intl.DateTimeFormat(undefined, {
|
|
|
129
160
|
token: LoggerOutput,
|
|
130
161
|
})
|
|
131
162
|
export class ConsoleLogger implements LoggerService {
|
|
163
|
+
/**
|
|
164
|
+
* Creates a new ConsoleLogger instance with the given options.
|
|
165
|
+
* This is a convenience method that instantiates and sets up the logger in one call.
|
|
166
|
+
*/
|
|
167
|
+
static create(): ConsoleLogger
|
|
168
|
+
static create(context: string): ConsoleLogger
|
|
169
|
+
static create(options: ConsoleLoggerOptions): ConsoleLogger
|
|
170
|
+
static create(context: string, options: ConsoleLoggerOptions): ConsoleLogger
|
|
171
|
+
static create(
|
|
172
|
+
contextOrOptions?: string | ConsoleLoggerOptions,
|
|
173
|
+
options?: ConsoleLoggerOptions,
|
|
174
|
+
): ConsoleLogger {
|
|
175
|
+
const logger = new ConsoleLogger()
|
|
176
|
+
if (contextOrOptions !== undefined) {
|
|
177
|
+
if (typeof contextOrOptions === 'string') {
|
|
178
|
+
logger.setup(contextOrOptions, options ?? {})
|
|
179
|
+
} else {
|
|
180
|
+
logger.setup(contextOrOptions)
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
logger.setup()
|
|
184
|
+
}
|
|
185
|
+
return logger
|
|
186
|
+
}
|
|
187
|
+
|
|
132
188
|
/**
|
|
133
189
|
* The options of the logger.
|
|
134
190
|
*/
|
|
@@ -412,11 +468,24 @@ export class ConsoleLogger implements LoggerService {
|
|
|
412
468
|
}
|
|
413
469
|
|
|
414
470
|
protected formatPid(pid: number) {
|
|
415
|
-
|
|
471
|
+
const showPrefix = this.options.showPrefix ?? true
|
|
472
|
+
const showPid = this.options.showPid ?? true
|
|
473
|
+
|
|
474
|
+
if (!showPrefix && !showPid) {
|
|
475
|
+
return ''
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const prefix = showPrefix ? `[${this.options.prefix}]` : ''
|
|
479
|
+
const pidPart = showPid ? `${pid}` : ''
|
|
480
|
+
const separator = showPrefix && showPid ? ' ' : ''
|
|
481
|
+
const suffix = showPrefix || showPid ? ' - ' : ''
|
|
482
|
+
|
|
483
|
+
return `${prefix}${separator}${pidPart}${suffix}`
|
|
416
484
|
}
|
|
417
485
|
|
|
418
486
|
protected formatContext(context: string): string {
|
|
419
|
-
|
|
487
|
+
const showContext = this.options.showContext ?? true
|
|
488
|
+
if (!context || !showContext) {
|
|
420
489
|
return ''
|
|
421
490
|
}
|
|
422
491
|
|
|
@@ -434,9 +503,29 @@ export class ConsoleLogger implements LoggerService {
|
|
|
434
503
|
requestId?: string,
|
|
435
504
|
) {
|
|
436
505
|
const output = this.stringifyMessage(message, logLevel)
|
|
506
|
+
const showLogLevel = this.options.showLogLevel ?? true
|
|
507
|
+
const showTimestamp = this.options.showTimestamp ?? true
|
|
508
|
+
|
|
437
509
|
pidMessage = this.colorize(pidMessage, logLevel)
|
|
438
|
-
formattedLogLevel =
|
|
439
|
-
|
|
510
|
+
formattedLogLevel = showLogLevel
|
|
511
|
+
? this.colorize(formattedLogLevel, logLevel)
|
|
512
|
+
: ''
|
|
513
|
+
|
|
514
|
+
const timestamp = showTimestamp ? this.getTimestamp() : ''
|
|
515
|
+
const requestIdPart = this.getRequestId(requestId)
|
|
516
|
+
|
|
517
|
+
// Build the message parts, filtering out empty ones
|
|
518
|
+
const parts: string[] = []
|
|
519
|
+
|
|
520
|
+
if (pidMessage) parts.push(pidMessage.trimEnd())
|
|
521
|
+
if (requestIdPart) parts.push(requestIdPart.trimEnd())
|
|
522
|
+
if (timestamp) parts.push(timestamp)
|
|
523
|
+
if (formattedLogLevel) parts.push(formattedLogLevel)
|
|
524
|
+
if (contextMessage) parts.push(contextMessage.trimEnd())
|
|
525
|
+
|
|
526
|
+
const prefix = parts.length > 0 ? parts.join(' ') + ' ' : ''
|
|
527
|
+
|
|
528
|
+
return `${prefix}${output}${timestampDiff}\n`
|
|
440
529
|
}
|
|
441
530
|
|
|
442
531
|
protected getRequestId(requestId?: string) {
|
|
@@ -488,7 +577,8 @@ export class ConsoleLogger implements LoggerService {
|
|
|
488
577
|
}
|
|
489
578
|
|
|
490
579
|
protected updateAndGetTimestampDiff(): string {
|
|
491
|
-
const
|
|
580
|
+
const showTimeDiff = this.options?.showTimeDiff ?? false
|
|
581
|
+
const includeTimestamp = this.lastTimestampAt && showTimeDiff
|
|
492
582
|
const result = includeTimestamp
|
|
493
583
|
? this.formatTimestampDiff(Date.now() - this.lastTimestampAt!)
|
|
494
584
|
: ''
|
|
@@ -16,6 +16,17 @@ export interface ModuleMetadata {
|
|
|
16
16
|
>
|
|
17
17
|
overrides: Set<ClassType>
|
|
18
18
|
customAttributes: Map<string | symbol, any>
|
|
19
|
+
/**
|
|
20
|
+
* Extensible entries for adapter-specific data.
|
|
21
|
+
* Adapters can store custom metadata using symbol keys.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const CommandEntryKey = Symbol('CommandEntryKey')
|
|
26
|
+
* metadata.customEntries.set(CommandEntryKey, new Set([Command1, Command2]))
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
customEntries: Map<symbol, unknown>
|
|
19
30
|
}
|
|
20
31
|
|
|
21
32
|
export function getModuleMetadata(
|
|
@@ -38,6 +49,7 @@ export function getModuleMetadata(
|
|
|
38
49
|
>(),
|
|
39
50
|
overrides: new Set<ClassType>(),
|
|
40
51
|
customAttributes: new Map<string | symbol, any>(),
|
|
52
|
+
customEntries: new Map<symbol, unknown>(),
|
|
41
53
|
}
|
|
42
54
|
context.metadata[ModuleMetadataKey] = newMetadata
|
|
43
55
|
// @ts-expect-error We add a custom metadata key to the target
|
|
@@ -63,3 +75,34 @@ export function hasModuleMetadata(target: ClassType): boolean {
|
|
|
63
75
|
// @ts-expect-error We add a custom metadata key to the target
|
|
64
76
|
return !!target[ModuleMetadataKey]
|
|
65
77
|
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Type-safe helper to get or create a custom entry in module metadata.
|
|
81
|
+
* Adapters use this to store their own metadata in modules.
|
|
82
|
+
*
|
|
83
|
+
* @param metadata - The module metadata object
|
|
84
|
+
* @param key - Symbol key for the custom entry
|
|
85
|
+
* @param defaultValue - Factory function to create default value if entry doesn't exist
|
|
86
|
+
* @returns The existing or newly created entry value
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const CommandEntryKey = Symbol('CommandEntryKey')
|
|
91
|
+
* const commands = getModuleCustomEntry<Set<ClassType>>(
|
|
92
|
+
* metadata,
|
|
93
|
+
* CommandEntryKey,
|
|
94
|
+
* () => new Set(),
|
|
95
|
+
* )
|
|
96
|
+
* commands.add(MyCommand)
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export function getModuleCustomEntry<T>(
|
|
100
|
+
metadata: ModuleMetadata,
|
|
101
|
+
key: symbol,
|
|
102
|
+
defaultValue: () => T,
|
|
103
|
+
): T {
|
|
104
|
+
if (!metadata.customEntries.has(key)) {
|
|
105
|
+
metadata.customEntries.set(key, defaultValue())
|
|
106
|
+
}
|
|
107
|
+
return metadata.customEntries.get(key) as T
|
|
108
|
+
}
|
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ClassType,
|
|
3
|
+
ClassTypeWithArgument,
|
|
4
|
+
ClassTypeWithInstance,
|
|
5
|
+
InjectionTokenSchemaType,
|
|
6
|
+
Registry,
|
|
7
|
+
} from '@navios/di'
|
|
8
|
+
import type { z } from 'zod/v4'
|
|
2
9
|
|
|
3
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
BoundInjectionToken,
|
|
12
|
+
Container,
|
|
13
|
+
FactoryInjectionToken,
|
|
14
|
+
inject,
|
|
15
|
+
Injectable,
|
|
16
|
+
InjectionToken,
|
|
17
|
+
} from '@navios/di'
|
|
4
18
|
|
|
5
19
|
import type {
|
|
6
|
-
|
|
7
|
-
|
|
20
|
+
AbstractAdapterInterface,
|
|
21
|
+
AdapterEnvironment,
|
|
22
|
+
DefaultAdapterEnvironment,
|
|
23
|
+
HttpAdapterEnvironment,
|
|
8
24
|
NaviosModule,
|
|
9
25
|
PluginContext,
|
|
10
26
|
PluginDefinition,
|
|
@@ -12,10 +28,11 @@ import type {
|
|
|
12
28
|
import type { LoggerService, LogLevel } from './logger/index.mjs'
|
|
13
29
|
import type { NaviosEnvironmentOptions } from './navios.environment.mjs'
|
|
14
30
|
|
|
15
|
-
import { HttpAdapterToken } from './index.mjs'
|
|
16
31
|
import { Logger } from './logger/index.mjs'
|
|
17
32
|
import { NaviosEnvironment } from './navios.environment.mjs'
|
|
18
33
|
import { ModuleLoaderService } from './services/index.mjs'
|
|
34
|
+
import { AdapterToken } from './tokens/index.mjs'
|
|
35
|
+
import { assertAdapterSupports } from './utils/index.mjs'
|
|
19
36
|
|
|
20
37
|
/**
|
|
21
38
|
* Options for configuring the Navios application context.
|
|
@@ -44,14 +61,14 @@ export interface NaviosApplicationOptions {
|
|
|
44
61
|
container?: Container
|
|
45
62
|
|
|
46
63
|
/**
|
|
47
|
-
*
|
|
64
|
+
* Adapter environment(s) to use for the application.
|
|
48
65
|
* Can be a single adapter or an array of adapters.
|
|
49
66
|
*
|
|
50
67
|
* @example
|
|
51
68
|
* ```typescript
|
|
52
69
|
* adapter: defineFastifyEnvironment()
|
|
53
70
|
* // or
|
|
54
|
-
* adapter: [defineFastifyEnvironment()
|
|
71
|
+
* adapter: [defineFastifyEnvironment()]
|
|
55
72
|
* ```
|
|
56
73
|
*/
|
|
57
74
|
adapter: NaviosEnvironmentOptions | NaviosEnvironmentOptions[]
|
|
@@ -75,7 +92,7 @@ export interface NaviosApplicationOptions {
|
|
|
75
92
|
* Main application class for Navios.
|
|
76
93
|
*
|
|
77
94
|
* This class represents a Navios application instance and provides methods
|
|
78
|
-
* for initializing, configuring, and managing the
|
|
95
|
+
* for initializing, configuring, and managing the application lifecycle.
|
|
79
96
|
*
|
|
80
97
|
* @example
|
|
81
98
|
* ```typescript
|
|
@@ -90,10 +107,12 @@ export interface NaviosApplicationOptions {
|
|
|
90
107
|
* ```
|
|
91
108
|
*/
|
|
92
109
|
@Injectable()
|
|
93
|
-
export class NaviosApplication
|
|
110
|
+
export class NaviosApplication<
|
|
111
|
+
Environment extends AdapterEnvironment = DefaultAdapterEnvironment,
|
|
112
|
+
> {
|
|
94
113
|
private environment = inject(NaviosEnvironment)
|
|
95
114
|
private moduleLoader = inject(ModuleLoaderService)
|
|
96
|
-
private
|
|
115
|
+
private adapter: Environment['adapter'] | null = null
|
|
97
116
|
private logger = inject(Logger, {
|
|
98
117
|
context: NaviosApplication.name,
|
|
99
118
|
})
|
|
@@ -103,7 +122,7 @@ export class NaviosApplication {
|
|
|
103
122
|
private options: NaviosApplicationOptions = {
|
|
104
123
|
adapter: [],
|
|
105
124
|
}
|
|
106
|
-
private plugins: PluginDefinition<any>[] = []
|
|
125
|
+
private plugins: PluginDefinition<any, any>[] = []
|
|
107
126
|
|
|
108
127
|
/**
|
|
109
128
|
* Indicates whether the application has been initialized.
|
|
@@ -127,8 +146,10 @@ export class NaviosApplication {
|
|
|
127
146
|
) {
|
|
128
147
|
this.appModule = appModule
|
|
129
148
|
this.options = options
|
|
130
|
-
if (this.environment.
|
|
131
|
-
this.
|
|
149
|
+
if (this.environment.hasAdapterSetup()) {
|
|
150
|
+
this.adapter = (await this.container.get(
|
|
151
|
+
AdapterToken,
|
|
152
|
+
)) as Environment['adapter']
|
|
132
153
|
}
|
|
133
154
|
}
|
|
134
155
|
|
|
@@ -141,6 +162,19 @@ export class NaviosApplication {
|
|
|
141
162
|
return this.container
|
|
142
163
|
}
|
|
143
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Returns the current adapter instance.
|
|
167
|
+
*
|
|
168
|
+
* @returns The adapter instance
|
|
169
|
+
* @throws Error if adapter is not initialized
|
|
170
|
+
*/
|
|
171
|
+
getAdapter(): Environment['adapter'] {
|
|
172
|
+
if (!this.adapter) {
|
|
173
|
+
throw new Error('Adapter not initialized')
|
|
174
|
+
}
|
|
175
|
+
return this.adapter
|
|
176
|
+
}
|
|
177
|
+
|
|
144
178
|
/**
|
|
145
179
|
* Registers a plugin to be initialized after modules are loaded.
|
|
146
180
|
*
|
|
@@ -159,7 +193,9 @@ export class NaviosApplication {
|
|
|
159
193
|
* }))
|
|
160
194
|
* ```
|
|
161
195
|
*/
|
|
162
|
-
usePlugin<TOptions
|
|
196
|
+
usePlugin<TOptions, TAdapter extends AbstractAdapterInterface>(
|
|
197
|
+
definition: PluginDefinition<TOptions, TAdapter>,
|
|
198
|
+
): this {
|
|
163
199
|
this.plugins.push(definition)
|
|
164
200
|
return this
|
|
165
201
|
}
|
|
@@ -169,7 +205,7 @@ export class NaviosApplication {
|
|
|
169
205
|
*
|
|
170
206
|
* This method:
|
|
171
207
|
* - Loads all modules and their dependencies
|
|
172
|
-
* - Sets up the
|
|
208
|
+
* - Sets up the adapter if one is configured
|
|
173
209
|
* - Calls onModuleInit hooks on all modules
|
|
174
210
|
* - Initializes registered plugins
|
|
175
211
|
* - Marks the application as initialized
|
|
@@ -192,13 +228,16 @@ export class NaviosApplication {
|
|
|
192
228
|
throw new Error('App module is not set. Call setAppModule() first.')
|
|
193
229
|
}
|
|
194
230
|
await this.moduleLoader.loadModules(this.appModule)
|
|
195
|
-
|
|
196
|
-
|
|
231
|
+
|
|
232
|
+
if (this.environment.hasAdapterSetup() && this.adapter) {
|
|
233
|
+
await this.adapter.setupAdapter(this.options)
|
|
197
234
|
}
|
|
235
|
+
|
|
198
236
|
await this.initPlugins()
|
|
199
237
|
await this.initModules()
|
|
200
|
-
|
|
201
|
-
|
|
238
|
+
|
|
239
|
+
if (this.adapter) {
|
|
240
|
+
await this.adapter.ready()
|
|
202
241
|
}
|
|
203
242
|
|
|
204
243
|
this.isInitialized = true
|
|
@@ -207,23 +246,22 @@ export class NaviosApplication {
|
|
|
207
246
|
|
|
208
247
|
private async initModules() {
|
|
209
248
|
const modules = this.moduleLoader.getAllModules()
|
|
210
|
-
|
|
249
|
+
if (this.adapter) {
|
|
250
|
+
await this.adapter.onModulesInit(modules)
|
|
251
|
+
}
|
|
211
252
|
}
|
|
212
253
|
|
|
213
254
|
private async initPlugins() {
|
|
214
255
|
if (this.plugins.length === 0) return
|
|
215
256
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
server = this.httpApplication?.getServer() ?? null
|
|
219
|
-
} catch {
|
|
220
|
-
// ignore
|
|
257
|
+
if (!this.adapter) {
|
|
258
|
+
throw new Error('Cannot initialize plugins without an adapter')
|
|
221
259
|
}
|
|
260
|
+
|
|
222
261
|
const context: PluginContext = {
|
|
223
262
|
modules: this.moduleLoader.getAllModules(),
|
|
224
|
-
|
|
263
|
+
adapter: this.adapter,
|
|
225
264
|
container: this.container,
|
|
226
|
-
globalPrefix: this.httpApplication?.getGlobalPrefix() ?? '',
|
|
227
265
|
moduleLoader: this.moduleLoader,
|
|
228
266
|
}
|
|
229
267
|
|
|
@@ -233,11 +271,79 @@ export class NaviosApplication {
|
|
|
233
271
|
}
|
|
234
272
|
}
|
|
235
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Gets a service instance from the dependency injection container.
|
|
276
|
+
*
|
|
277
|
+
* This is a shorthand for `app.getContainer().get(token)`.
|
|
278
|
+
*
|
|
279
|
+
* @param token - The injection token or class to resolve
|
|
280
|
+
* @returns Promise resolving to the service instance
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```typescript
|
|
284
|
+
* const userService = await app.get(UserService)
|
|
285
|
+
* const config = await app.get(ConfigToken)
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
get<T extends ClassType>(token: T): Promise<InstanceType<T>>
|
|
289
|
+
get<T extends ClassTypeWithArgument<R>, R>(
|
|
290
|
+
token: T,
|
|
291
|
+
args: R,
|
|
292
|
+
): Promise<InstanceType<T>>
|
|
293
|
+
get<T, S extends InjectionTokenSchemaType>(
|
|
294
|
+
token: InjectionToken<T, S>,
|
|
295
|
+
args: z.input<S>,
|
|
296
|
+
): Promise<T>
|
|
297
|
+
get<T, S extends InjectionTokenSchemaType, R extends boolean>(
|
|
298
|
+
token: InjectionToken<T, S, R>,
|
|
299
|
+
): Promise<T>
|
|
300
|
+
get<T>(token: InjectionToken<T, undefined>): Promise<T>
|
|
301
|
+
get<T>(token: BoundInjectionToken<T, any>): Promise<T>
|
|
302
|
+
get<T>(token: FactoryInjectionToken<T, any>): Promise<T>
|
|
303
|
+
async get(
|
|
304
|
+
token:
|
|
305
|
+
| ClassType
|
|
306
|
+
| InjectionToken<any>
|
|
307
|
+
| BoundInjectionToken<any, any>
|
|
308
|
+
| FactoryInjectionToken<any, any>,
|
|
309
|
+
args?: unknown,
|
|
310
|
+
): Promise<any> {
|
|
311
|
+
return this.container.get(token as any, args)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Configures the adapter with additional options before initialization.
|
|
316
|
+
*
|
|
317
|
+
* This method allows setting adapter-specific configuration options
|
|
318
|
+
* before the adapter is initialized. Must be called before `init()`.
|
|
319
|
+
*
|
|
320
|
+
* @param options - Adapter-specific configuration options
|
|
321
|
+
* @returns this for method chaining
|
|
322
|
+
* @throws Error if called after init() or if adapter doesn't support configure
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```typescript
|
|
326
|
+
* // With Fastify adapter
|
|
327
|
+
* app.configure({ trustProxy: true, logger: true })
|
|
328
|
+
*
|
|
329
|
+
* // With Bun adapter
|
|
330
|
+
* app.configure({ development: true })
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
configure(options: Partial<Environment['options']>): this {
|
|
334
|
+
if (this.isInitialized) {
|
|
335
|
+
throw new Error('configure() must be called before init()')
|
|
336
|
+
}
|
|
337
|
+
assertAdapterSupports(this.adapter, 'configure')
|
|
338
|
+
this.adapter.configure(options)
|
|
339
|
+
return this
|
|
340
|
+
}
|
|
341
|
+
|
|
236
342
|
/**
|
|
237
343
|
* Enables CORS (Cross-Origin Resource Sharing) for the application.
|
|
238
344
|
*
|
|
239
345
|
* @param options - CORS configuration options (adapter-specific)
|
|
240
|
-
* @throws Error if
|
|
346
|
+
* @throws Error if adapter doesn't support enableCors
|
|
241
347
|
*
|
|
242
348
|
* @example
|
|
243
349
|
* ```typescript
|
|
@@ -248,18 +354,20 @@ export class NaviosApplication {
|
|
|
248
354
|
* })
|
|
249
355
|
* ```
|
|
250
356
|
*/
|
|
251
|
-
enableCors(
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
357
|
+
enableCors(
|
|
358
|
+
options: Environment extends HttpAdapterEnvironment
|
|
359
|
+
? Environment['corsOptions']
|
|
360
|
+
: never,
|
|
361
|
+
): void {
|
|
362
|
+
assertAdapterSupports(this.adapter, 'enableCors')
|
|
363
|
+
this.adapter.enableCors(options)
|
|
256
364
|
}
|
|
257
365
|
|
|
258
366
|
/**
|
|
259
367
|
* Enables multipart/form-data support for file uploads.
|
|
260
368
|
*
|
|
261
369
|
* @param options - Multipart configuration options (adapter-specific)
|
|
262
|
-
* @throws Error if
|
|
370
|
+
* @throws Error if adapter doesn't support enableMultipart
|
|
263
371
|
*
|
|
264
372
|
* @example
|
|
265
373
|
* ```typescript
|
|
@@ -270,18 +378,20 @@ export class NaviosApplication {
|
|
|
270
378
|
* })
|
|
271
379
|
* ```
|
|
272
380
|
*/
|
|
273
|
-
enableMultipart(
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
381
|
+
enableMultipart(
|
|
382
|
+
options: Environment extends HttpAdapterEnvironment
|
|
383
|
+
? Environment['multipartOptions']
|
|
384
|
+
: never,
|
|
385
|
+
): void {
|
|
386
|
+
assertAdapterSupports(this.adapter, 'enableMultipart')
|
|
387
|
+
this.adapter.enableMultipart(options)
|
|
278
388
|
}
|
|
279
389
|
|
|
280
390
|
/**
|
|
281
391
|
* Sets a global prefix for all routes.
|
|
282
392
|
*
|
|
283
393
|
* @param prefix - The prefix to prepend to all route URLs (e.g., '/api')
|
|
284
|
-
* @throws Error if
|
|
394
|
+
* @throws Error if adapter doesn't support setGlobalPrefix
|
|
285
395
|
*
|
|
286
396
|
* @example
|
|
287
397
|
* ```typescript
|
|
@@ -289,11 +399,9 @@ export class NaviosApplication {
|
|
|
289
399
|
* // All routes will be prefixed with /api/v1
|
|
290
400
|
* ```
|
|
291
401
|
*/
|
|
292
|
-
setGlobalPrefix(prefix: string) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
296
|
-
this.httpApplication.setGlobalPrefix(prefix)
|
|
402
|
+
setGlobalPrefix(prefix: string): void {
|
|
403
|
+
assertAdapterSupports(this.adapter, 'setGlobalPrefix')
|
|
404
|
+
this.adapter.setGlobalPrefix(prefix)
|
|
297
405
|
}
|
|
298
406
|
|
|
299
407
|
/**
|
|
@@ -304,7 +412,7 @@ export class NaviosApplication {
|
|
|
304
412
|
* - Bun adapter: Returns Bun.Server
|
|
305
413
|
*
|
|
306
414
|
* @returns The HTTP server instance
|
|
307
|
-
* @throws Error if
|
|
415
|
+
* @throws Error if adapter doesn't support getServer
|
|
308
416
|
*
|
|
309
417
|
* @example
|
|
310
418
|
* ```typescript
|
|
@@ -312,40 +420,44 @@ export class NaviosApplication {
|
|
|
312
420
|
* // Use adapter-specific server methods
|
|
313
421
|
* ```
|
|
314
422
|
*/
|
|
315
|
-
getServer()
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return this.
|
|
423
|
+
getServer(): Environment extends HttpAdapterEnvironment
|
|
424
|
+
? Environment['server']
|
|
425
|
+
: never {
|
|
426
|
+
assertAdapterSupports(this.adapter, 'getServer')
|
|
427
|
+
return this.adapter.getServer() as Environment extends HttpAdapterEnvironment
|
|
428
|
+
? Environment['server']
|
|
429
|
+
: never
|
|
320
430
|
}
|
|
321
431
|
|
|
322
432
|
/**
|
|
323
433
|
* Starts the HTTP server and begins listening for requests.
|
|
324
434
|
*
|
|
325
435
|
* @param options - Listen options (port, host, etc.)
|
|
326
|
-
* @throws Error if
|
|
436
|
+
* @throws Error if adapter doesn't support listen
|
|
327
437
|
*
|
|
328
438
|
* @example
|
|
329
439
|
* ```typescript
|
|
330
440
|
* await app.listen({ port: 3000, host: '0.0.0.0' })
|
|
331
441
|
* ```
|
|
332
442
|
*/
|
|
333
|
-
async listen(
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
443
|
+
async listen(
|
|
444
|
+
options: Environment extends HttpAdapterEnvironment
|
|
445
|
+
? Environment['listenOptions']
|
|
446
|
+
: never,
|
|
447
|
+
): Promise<string> {
|
|
448
|
+
assertAdapterSupports(this.adapter, 'listen')
|
|
449
|
+
return this.adapter.listen(options) as Promise<string>
|
|
338
450
|
}
|
|
339
451
|
|
|
340
452
|
/**
|
|
341
453
|
* Disposes of application resources.
|
|
342
454
|
*
|
|
343
|
-
* Cleans up the
|
|
455
|
+
* Cleans up the adapter and module loader.
|
|
344
456
|
* This method is called automatically by `close()`.
|
|
345
457
|
*/
|
|
346
458
|
async dispose() {
|
|
347
|
-
if (this.
|
|
348
|
-
await this.
|
|
459
|
+
if (this.adapter) {
|
|
460
|
+
await this.adapter.dispose()
|
|
349
461
|
}
|
|
350
462
|
if (this.moduleLoader) {
|
|
351
463
|
this.moduleLoader.dispose()
|
|
@@ -2,31 +2,41 @@ import type { AnyInjectableType, InjectionToken } from '@navios/di'
|
|
|
2
2
|
|
|
3
3
|
import { Injectable } from '@navios/di'
|
|
4
4
|
|
|
5
|
+
import { AdapterToken } from './tokens/index.mjs'
|
|
6
|
+
|
|
5
7
|
export interface NaviosEnvironmentOptions {
|
|
6
|
-
|
|
7
|
-
httpTokens?: Map<InjectionToken<any, undefined>, AnyInjectableType>
|
|
8
|
+
tokens?: Map<InjectionToken<any, undefined>, AnyInjectableType>
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
@Injectable()
|
|
11
12
|
export class NaviosEnvironment {
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
AnyInjectableType
|
|
15
|
-
>()
|
|
13
|
+
private adapterConfigured = false
|
|
14
|
+
private tokens = new Map<InjectionToken<any, undefined>, AnyInjectableType>()
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
setupEnvironment(
|
|
18
17
|
tokens: Map<InjectionToken<any, undefined>, AnyInjectableType>,
|
|
19
18
|
) {
|
|
19
|
+
const hasAdapterToken = tokens.has(AdapterToken)
|
|
20
|
+
if (hasAdapterToken && this.adapterConfigured) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
'Adapter already configured. Only one adapter per application.',
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
for (const [token, value] of tokens) {
|
|
21
|
-
this.
|
|
27
|
+
this.tokens.set(token, value)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (hasAdapterToken) {
|
|
31
|
+
this.adapterConfigured = true
|
|
22
32
|
}
|
|
23
33
|
}
|
|
24
34
|
|
|
25
|
-
|
|
26
|
-
return this.
|
|
35
|
+
getToken(token: InjectionToken<any, undefined>) {
|
|
36
|
+
return this.tokens.get(token)
|
|
27
37
|
}
|
|
28
38
|
|
|
29
|
-
|
|
30
|
-
return this.
|
|
39
|
+
hasAdapterSetup() {
|
|
40
|
+
return this.adapterConfigured
|
|
31
41
|
}
|
|
32
42
|
}
|