@navios/core 0.4.0 → 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.
- package/README.md +95 -2
- package/docs/README.md +310 -3
- package/docs/adapters.md +308 -0
- package/docs/application-setup.md +524 -0
- package/docs/attributes.md +689 -0
- package/docs/controllers.md +373 -0
- package/docs/endpoints.md +444 -0
- package/docs/exceptions.md +316 -0
- package/docs/guards.md +550 -0
- package/docs/modules.md +251 -0
- package/docs/quick-start.md +295 -0
- package/docs/services.md +428 -0
- package/docs/testing.md +704 -0
- package/lib/_tsup-dts-rollup.d.mts +300 -235
- package/lib/_tsup-dts-rollup.d.ts +300 -235
- package/lib/index.d.mts +47 -26
- package/lib/index.d.ts +47 -26
- package/lib/index.js +633 -1072
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +631 -1064
- package/lib/index.mjs.map +1 -1
- package/package.json +4 -7
- package/project.json +9 -1
- package/src/__tests__/config.service.spec.mts +11 -9
- package/src/__tests__/controller.spec.mts +0 -1
- package/src/config/config.service.mts +2 -2
- package/src/decorators/controller.decorator.mts +1 -1
- package/src/decorators/endpoint.decorator.mts +2 -2
- package/src/decorators/header.decorator.mts +1 -1
- package/src/decorators/multipart.decorator.mts +1 -1
- package/src/decorators/stream.decorator.mts +2 -3
- package/src/factories/endpoint-adapter.factory.mts +21 -0
- package/src/factories/http-adapter.factory.mts +20 -0
- package/src/factories/index.mts +6 -0
- package/src/factories/multipart-adapter.factory.mts +21 -0
- package/src/factories/reply.factory.mts +21 -0
- package/src/factories/request.factory.mts +21 -0
- package/src/factories/stream-adapter.factory.mts +20 -0
- package/src/index.mts +1 -1
- package/src/interfaces/abstract-execution-context.inteface.mts +13 -0
- package/src/interfaces/abstract-http-adapter.interface.mts +20 -0
- package/src/interfaces/abstract-http-cors-options.interface.mts +59 -0
- package/src/interfaces/abstract-http-handler-adapter.interface.mts +13 -0
- package/src/interfaces/abstract-http-listen-options.interface.mts +4 -0
- package/src/interfaces/can-activate.mts +4 -2
- package/src/interfaces/http-header.mts +18 -0
- package/src/interfaces/index.mts +6 -0
- package/src/logger/console-logger.service.mts +28 -44
- package/src/logger/index.mts +1 -2
- package/src/logger/logger.service.mts +9 -128
- package/src/logger/logger.tokens.mts +21 -0
- package/src/metadata/handler.metadata.mts +7 -5
- package/src/navios.application.mts +65 -172
- package/src/navios.environment.mts +30 -0
- package/src/navios.factory.mts +53 -12
- package/src/services/guard-runner.service.mts +19 -9
- package/src/services/index.mts +0 -2
- package/src/services/module-loader.service.mts +4 -3
- package/src/tokens/endpoint-adapter.token.mts +8 -0
- package/src/tokens/execution-context.token.mts +2 -2
- package/src/tokens/http-adapter.token.mts +8 -0
- package/src/tokens/index.mts +4 -1
- package/src/tokens/multipart-adapter.token.mts +8 -0
- package/src/tokens/reply.token.mts +1 -5
- package/src/tokens/request.token.mts +1 -7
- package/src/tokens/stream-adapter.token.mts +8 -0
- package/docs/recipes/prisma.md +0 -60
- package/e2e/endpoints/get.spec.mts +0 -97
- package/e2e/endpoints/post.spec.mts +0 -113
- package/examples/simple-test/api/index.mts +0 -64
- package/examples/simple-test/config/config.service.mts +0 -14
- package/examples/simple-test/config/configuration.mts +0 -7
- package/examples/simple-test/index.mts +0 -16
- package/examples/simple-test/src/acl/acl-modern.guard.mts +0 -15
- package/examples/simple-test/src/acl/acl.guard.mts +0 -14
- package/examples/simple-test/src/acl/app.guard.mts +0 -27
- package/examples/simple-test/src/acl/one-more.guard.mts +0 -15
- package/examples/simple-test/src/acl/public.attribute.mts +0 -21
- package/examples/simple-test/src/app.module.mts +0 -9
- package/examples/simple-test/src/user/user.controller.mts +0 -72
- package/examples/simple-test/src/user/user.module.mts +0 -14
- package/examples/simple-test/src/user/user.service.mts +0 -14
- package/src/adapters/endpoint-adapter.service.mts +0 -72
- package/src/adapters/handler-adapter.interface.mts +0 -21
- package/src/adapters/index.mts +0 -4
- package/src/adapters/multipart-adapter.service.mts +0 -135
- package/src/adapters/stream-adapter.service.mts +0 -91
- package/src/logger/logger.factory.mts +0 -36
- package/src/logger/pino-wrapper.mts +0 -64
- package/src/services/controller-adapter.service.mts +0 -124
- package/src/services/execution-context.mts +0 -54
- package/src/tokens/application.token.mts +0 -9
|
@@ -2,12 +2,12 @@ import type { InspectOptions } from 'util'
|
|
|
2
2
|
|
|
3
3
|
import { inspect } from 'util'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Injectable } from '@navios/di'
|
|
6
6
|
|
|
7
7
|
import type { LogLevel } from './log-levels.mjs'
|
|
8
8
|
import type { LoggerService } from './logger-service.interface.mjs'
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { LoggerOutput } from './logger.tokens.mjs'
|
|
11
11
|
import {
|
|
12
12
|
clc,
|
|
13
13
|
isFunction,
|
|
@@ -124,20 +124,18 @@ const dateTimeFormatter = new Intl.DateTimeFormat(undefined, {
|
|
|
124
124
|
/**
|
|
125
125
|
* @publicApi
|
|
126
126
|
*/
|
|
127
|
-
@Injectable(
|
|
127
|
+
@Injectable({
|
|
128
|
+
token: LoggerOutput,
|
|
129
|
+
})
|
|
128
130
|
export class ConsoleLogger implements LoggerService {
|
|
129
131
|
/**
|
|
130
132
|
* The options of the logger.
|
|
131
133
|
*/
|
|
132
|
-
protected options: ConsoleLoggerOptions
|
|
134
|
+
protected options: ConsoleLoggerOptions = {}
|
|
133
135
|
/**
|
|
134
136
|
* The context of the logger (can be set manually or automatically inferred).
|
|
135
137
|
*/
|
|
136
138
|
protected context?: string
|
|
137
|
-
/**
|
|
138
|
-
* Request ID (if enabled).
|
|
139
|
-
*/
|
|
140
|
-
protected requestId: string | null = null
|
|
141
139
|
/**
|
|
142
140
|
* The original context of the logger (set in the constructor).
|
|
143
141
|
*/
|
|
@@ -145,17 +143,17 @@ export class ConsoleLogger implements LoggerService {
|
|
|
145
143
|
/**
|
|
146
144
|
* The options used for the "inspect" method.
|
|
147
145
|
*/
|
|
148
|
-
protected inspectOptions: InspectOptions
|
|
146
|
+
protected inspectOptions: InspectOptions = this.getInspectOptions()
|
|
149
147
|
/**
|
|
150
148
|
* The last timestamp at which the log message was printed.
|
|
151
149
|
*/
|
|
152
|
-
protected
|
|
150
|
+
protected lastTimestampAt?: number
|
|
153
151
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
152
|
+
setup(): void
|
|
153
|
+
setup(context: string): void
|
|
154
|
+
setup(options: ConsoleLoggerOptions): void
|
|
155
|
+
setup(context: string, options: ConsoleLoggerOptions): void
|
|
156
|
+
setup(
|
|
159
157
|
contextOrOptions?: string | ConsoleLoggerOptions,
|
|
160
158
|
options?: ConsoleLoggerOptions,
|
|
161
159
|
) {
|
|
@@ -178,24 +176,6 @@ export class ConsoleLogger implements LoggerService {
|
|
|
178
176
|
this.context = context
|
|
179
177
|
this.originalContext = context
|
|
180
178
|
}
|
|
181
|
-
if (opts?.requestId) {
|
|
182
|
-
const locator = getGlobalServiceLocator()
|
|
183
|
-
locator
|
|
184
|
-
.getEventBus()
|
|
185
|
-
.on(locator.getInstanceIdentifier(Request, undefined), 'create', () => {
|
|
186
|
-
const request = locator.getSyncInstance(Request, undefined)
|
|
187
|
-
this.requestId = request?.id ?? null
|
|
188
|
-
})
|
|
189
|
-
locator
|
|
190
|
-
.getEventBus()
|
|
191
|
-
.on(
|
|
192
|
-
locator.getInstanceIdentifier(Request, undefined),
|
|
193
|
-
'destroy',
|
|
194
|
-
() => {
|
|
195
|
-
this.requestId = null
|
|
196
|
-
},
|
|
197
|
-
)
|
|
198
|
-
}
|
|
199
179
|
}
|
|
200
180
|
|
|
201
181
|
/**
|
|
@@ -229,7 +209,7 @@ export class ConsoleLogger implements LoggerService {
|
|
|
229
209
|
const { messages, context, stack } =
|
|
230
210
|
this.getContextAndStackAndMessagesToPrint([message, ...optionalParams])
|
|
231
211
|
|
|
232
|
-
this.printMessages(messages, context, 'error', 'stderr', stack)
|
|
212
|
+
this.printMessages(messages, context, 'error', undefined, 'stderr', stack)
|
|
233
213
|
this.printStackTrace(stack!)
|
|
234
214
|
}
|
|
235
215
|
|
|
@@ -340,6 +320,7 @@ export class ConsoleLogger implements LoggerService {
|
|
|
340
320
|
messages: unknown[],
|
|
341
321
|
context = '',
|
|
342
322
|
logLevel: LogLevel = 'log',
|
|
323
|
+
requestId?: string,
|
|
343
324
|
writeStreamType?: 'stdout' | 'stderr',
|
|
344
325
|
errorStack?: unknown,
|
|
345
326
|
) {
|
|
@@ -350,6 +331,7 @@ export class ConsoleLogger implements LoggerService {
|
|
|
350
331
|
logLevel,
|
|
351
332
|
writeStreamType,
|
|
352
333
|
errorStack,
|
|
334
|
+
requestId,
|
|
353
335
|
})
|
|
354
336
|
return
|
|
355
337
|
}
|
|
@@ -364,6 +346,7 @@ export class ConsoleLogger implements LoggerService {
|
|
|
364
346
|
formattedLogLevel,
|
|
365
347
|
contextMessage,
|
|
366
348
|
timestampDiff,
|
|
349
|
+
requestId,
|
|
367
350
|
)
|
|
368
351
|
|
|
369
352
|
process[writeStreamType ?? 'stdout'].write(formattedMessage)
|
|
@@ -377,6 +360,7 @@ export class ConsoleLogger implements LoggerService {
|
|
|
377
360
|
logLevel: LogLevel
|
|
378
361
|
writeStreamType?: 'stdout' | 'stderr'
|
|
379
362
|
errorStack?: unknown
|
|
363
|
+
requestId?: string
|
|
380
364
|
},
|
|
381
365
|
) {
|
|
382
366
|
type JsonLogObject = {
|
|
@@ -403,8 +387,8 @@ export class ConsoleLogger implements LoggerService {
|
|
|
403
387
|
if (options.errorStack) {
|
|
404
388
|
logObject.stack = options.errorStack
|
|
405
389
|
}
|
|
406
|
-
if (this.options.requestId &&
|
|
407
|
-
logObject.requestId =
|
|
390
|
+
if (this.options.requestId && options.requestId) {
|
|
391
|
+
logObject.requestId = options.requestId
|
|
408
392
|
}
|
|
409
393
|
|
|
410
394
|
const formattedMessage =
|
|
@@ -434,16 +418,17 @@ export class ConsoleLogger implements LoggerService {
|
|
|
434
418
|
formattedLogLevel: string,
|
|
435
419
|
contextMessage: string,
|
|
436
420
|
timestampDiff: string,
|
|
421
|
+
requestId?: string,
|
|
437
422
|
) {
|
|
438
423
|
const output = this.stringifyMessage(message, logLevel)
|
|
439
424
|
pidMessage = this.colorize(pidMessage, logLevel)
|
|
440
425
|
formattedLogLevel = this.colorize(formattedLogLevel, logLevel)
|
|
441
|
-
return `${pidMessage}${this.getRequestId()}${this.getTimestamp()} ${formattedLogLevel} ${contextMessage}${output}${timestampDiff}\n`
|
|
426
|
+
return `${pidMessage}${this.getRequestId(requestId)}${this.getTimestamp()} ${formattedLogLevel} ${contextMessage}${output}${timestampDiff}\n`
|
|
442
427
|
}
|
|
443
428
|
|
|
444
|
-
protected getRequestId() {
|
|
445
|
-
if (this.options.requestId &&
|
|
446
|
-
return `(${this.colorize(
|
|
429
|
+
protected getRequestId(requestId?: string) {
|
|
430
|
+
if (this.options.requestId && requestId) {
|
|
431
|
+
return `(${this.colorize(requestId, 'log')}) `
|
|
447
432
|
}
|
|
448
433
|
return ''
|
|
449
434
|
}
|
|
@@ -490,12 +475,11 @@ export class ConsoleLogger implements LoggerService {
|
|
|
490
475
|
}
|
|
491
476
|
|
|
492
477
|
protected updateAndGetTimestampDiff(): string {
|
|
493
|
-
const includeTimestamp =
|
|
494
|
-
ConsoleLogger.lastTimestampAt && this.options?.timestamp
|
|
478
|
+
const includeTimestamp = this.lastTimestampAt && this.options?.timestamp
|
|
495
479
|
const result = includeTimestamp
|
|
496
|
-
? this.formatTimestampDiff(Date.now() -
|
|
480
|
+
? this.formatTimestampDiff(Date.now() - this.lastTimestampAt!)
|
|
497
481
|
: ''
|
|
498
|
-
|
|
482
|
+
this.lastTimestampAt = Date.now()
|
|
499
483
|
return result
|
|
500
484
|
}
|
|
501
485
|
|
package/src/logger/index.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export * from './utils/index.mjs'
|
|
2
2
|
export * from './console-logger.service.mjs'
|
|
3
3
|
export * from './log-levels.mjs'
|
|
4
|
-
export * from './logger.
|
|
4
|
+
export * from './logger.tokens.mjs'
|
|
5
5
|
export * from './logger.service.mjs'
|
|
6
6
|
export * from './logger-service.interface.mjs'
|
|
7
|
-
export * from './pino-wrapper.mjs'
|
|
@@ -1,47 +1,20 @@
|
|
|
1
|
-
import { Injectable } from '@navios/di'
|
|
1
|
+
import { inject, Injectable } from '@navios/di'
|
|
2
2
|
|
|
3
|
-
import type { LogLevel } from './log-levels.mjs'
|
|
4
3
|
import type { LoggerService } from './logger-service.interface.mjs'
|
|
4
|
+
import type { LoggerOptions } from './logger.tokens.mjs'
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { isLogLevelEnabled, isObject } from './utils/index.mjs'
|
|
6
|
+
import { Logger, LoggerOutput } from './logger.tokens.mjs'
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const dateTimeFormatter = new Intl.DateTimeFormat(undefined, {
|
|
12
|
-
year: 'numeric',
|
|
13
|
-
hour: 'numeric',
|
|
14
|
-
minute: 'numeric',
|
|
15
|
-
second: 'numeric',
|
|
16
|
-
day: '2-digit',
|
|
17
|
-
month: '2-digit',
|
|
8
|
+
@Injectable({
|
|
9
|
+
token: Logger,
|
|
18
10
|
})
|
|
19
|
-
|
|
20
|
-
@Injectable()
|
|
21
11
|
export class LoggerInstance implements LoggerService {
|
|
22
|
-
protected
|
|
23
|
-
protected static logLevels?: LogLevel[]
|
|
24
|
-
|
|
25
|
-
protected localInstanceRef?: LoggerService
|
|
12
|
+
protected localInstance = inject(LoggerOutput)
|
|
26
13
|
|
|
27
|
-
|
|
28
|
-
constructor(context: string)
|
|
29
|
-
constructor(context: string, options?: { timestamp?: boolean })
|
|
30
|
-
constructor(
|
|
31
|
-
protected context?: string,
|
|
32
|
-
protected options: { timestamp?: boolean } = {},
|
|
33
|
-
) {}
|
|
14
|
+
protected context?: string
|
|
34
15
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return this.registerLocalInstanceRef()
|
|
38
|
-
} else if (LoggerInstance.staticInstanceRef instanceof LoggerInstance) {
|
|
39
|
-
const prototype = Object.getPrototypeOf(LoggerInstance.staticInstanceRef)
|
|
40
|
-
if (prototype.constructor === LoggerInstance) {
|
|
41
|
-
return this.registerLocalInstanceRef()
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return LoggerInstance.staticInstanceRef!
|
|
16
|
+
constructor(config: LoggerOptions = {}) {
|
|
17
|
+
this.context = config.context
|
|
45
18
|
}
|
|
46
19
|
|
|
47
20
|
/**
|
|
@@ -118,96 +91,4 @@ export class LoggerInstance implements LoggerService {
|
|
|
118
91
|
: optionalParams
|
|
119
92
|
this.localInstance?.fatal?.(message, ...optionalParams)
|
|
120
93
|
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Write an 'error' level log.
|
|
124
|
-
*/
|
|
125
|
-
static error(message: any, stackOrContext?: string): void
|
|
126
|
-
static error(message: any, context?: string): void
|
|
127
|
-
static error(message: any, stack?: string, context?: string): void
|
|
128
|
-
static error(
|
|
129
|
-
message: any,
|
|
130
|
-
...optionalParams: [...any, string?, string?]
|
|
131
|
-
): void
|
|
132
|
-
static error(message: any, ...optionalParams: any[]) {
|
|
133
|
-
this.staticInstanceRef?.error(message, ...optionalParams)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Write a 'log' level log.
|
|
138
|
-
*/
|
|
139
|
-
static log(message: any, context?: string): void
|
|
140
|
-
static log(message: any, ...optionalParams: [...any, string?]): void
|
|
141
|
-
static log(message: any, ...optionalParams: any[]) {
|
|
142
|
-
this.staticInstanceRef?.log(message, ...optionalParams)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Write a 'warn' level log.
|
|
147
|
-
*/
|
|
148
|
-
static warn(message: any, context?: string): void
|
|
149
|
-
static warn(message: any, ...optionalParams: [...any, string?]): void
|
|
150
|
-
static warn(message: any, ...optionalParams: any[]) {
|
|
151
|
-
this.staticInstanceRef?.warn(message, ...optionalParams)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Write a 'debug' level log, if the configured level allows for it.
|
|
156
|
-
* Prints to `stdout` with newline.
|
|
157
|
-
*/
|
|
158
|
-
static debug(message: any, context?: string): void
|
|
159
|
-
static debug(message: any, ...optionalParams: [...any, string?]): void
|
|
160
|
-
static debug(message: any, ...optionalParams: any[]) {
|
|
161
|
-
this.staticInstanceRef?.debug?.(message, ...optionalParams)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Write a 'verbose' level log.
|
|
166
|
-
*/
|
|
167
|
-
static verbose(message: any, context?: string): void
|
|
168
|
-
static verbose(message: any, ...optionalParams: [...any, string?]): void
|
|
169
|
-
static verbose(message: any, ...optionalParams: any[]) {
|
|
170
|
-
this.staticInstanceRef?.verbose?.(message, ...optionalParams)
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Write a 'fatal' level log.
|
|
175
|
-
*/
|
|
176
|
-
static fatal(message: any, context?: string): void
|
|
177
|
-
static fatal(message: any, ...optionalParams: [...any, string?]): void
|
|
178
|
-
static fatal(message: any, ...optionalParams: any[]) {
|
|
179
|
-
this.staticInstanceRef?.fatal?.(message, ...optionalParams)
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
static getTimestamp() {
|
|
183
|
-
return dateTimeFormatter.format(Date.now())
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
static overrideLogger(logger: LoggerService | LogLevel[] | boolean) {
|
|
187
|
-
if (Array.isArray(logger)) {
|
|
188
|
-
LoggerInstance.logLevels = logger
|
|
189
|
-
return this.staticInstanceRef?.setLogLevels?.(logger)
|
|
190
|
-
}
|
|
191
|
-
if (isObject(logger)) {
|
|
192
|
-
this.staticInstanceRef = logger as LoggerService
|
|
193
|
-
} else {
|
|
194
|
-
this.staticInstanceRef = undefined
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
static isLevelEnabled(level: LogLevel): boolean {
|
|
199
|
-
const logLevels = LoggerInstance.logLevels
|
|
200
|
-
return isLogLevelEnabled(level, logLevels)
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
private registerLocalInstanceRef() {
|
|
204
|
-
if (this.localInstanceRef) {
|
|
205
|
-
return this.localInstanceRef
|
|
206
|
-
}
|
|
207
|
-
this.localInstanceRef = new ConsoleLogger(this.context!, {
|
|
208
|
-
timestamp: this.options?.timestamp,
|
|
209
|
-
logLevels: LoggerInstance.logLevels,
|
|
210
|
-
})
|
|
211
|
-
return this.localInstanceRef
|
|
212
|
-
}
|
|
213
94
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { InjectionToken } from '@navios/di'
|
|
2
|
+
|
|
3
|
+
import z from 'zod/v4'
|
|
4
|
+
|
|
5
|
+
import type { LoggerService } from './logger-service.interface.mjs'
|
|
6
|
+
import type { LoggerInstance } from './logger.service.mjs'
|
|
7
|
+
|
|
8
|
+
export const LoggerOutput = InjectionToken.create<LoggerService>('LoggerOutput')
|
|
9
|
+
|
|
10
|
+
export const loggerOptionsSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
context: z.string().optional(),
|
|
13
|
+
})
|
|
14
|
+
.optional()
|
|
15
|
+
|
|
16
|
+
export type LoggerOptions = z.infer<typeof loggerOptionsSchema>
|
|
17
|
+
|
|
18
|
+
export const Logger = InjectionToken.create<
|
|
19
|
+
LoggerInstance,
|
|
20
|
+
typeof loggerOptionsSchema
|
|
21
|
+
>('Logger', loggerOptionsSchema)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { HttpMethod } from '@navios/builder'
|
|
2
2
|
import type { ClassTypeWithInstance, InjectionToken } from '@navios/di'
|
|
3
|
-
import type { HttpHeader } from 'fastify/types/utils.js'
|
|
4
3
|
|
|
5
|
-
import type {
|
|
6
|
-
|
|
4
|
+
import type {
|
|
5
|
+
AbstractHttpHandlerAdapterInterface,
|
|
6
|
+
CanActivate,
|
|
7
|
+
HttpHeader,
|
|
8
|
+
} from '../interfaces/index.mjs'
|
|
7
9
|
|
|
8
10
|
export const EndpointMetadataKey = Symbol('EndpointMetadataKey')
|
|
9
11
|
|
|
@@ -12,8 +14,8 @@ export interface HandlerMetadata<Config = null> {
|
|
|
12
14
|
url: string
|
|
13
15
|
successStatusCode: number
|
|
14
16
|
adapterToken:
|
|
15
|
-
| InjectionToken<
|
|
16
|
-
| ClassTypeWithInstance<
|
|
17
|
+
| InjectionToken<AbstractHttpHandlerAdapterInterface, undefined>
|
|
18
|
+
| ClassTypeWithInstance<AbstractHttpHandlerAdapterInterface>
|
|
17
19
|
| null
|
|
18
20
|
headers: Partial<Record<HttpHeader, number | string | string[] | undefined>>
|
|
19
21
|
httpMethod: HttpMethod
|
|
@@ -1,37 +1,19 @@
|
|
|
1
|
-
import type { FastifyCorsOptions } from '@fastify/cors'
|
|
2
|
-
import type { FastifyMultipartOptions } from '@fastify/multipart'
|
|
3
1
|
import type { ClassTypeWithInstance } from '@navios/di'
|
|
2
|
+
|
|
3
|
+
import { Container, inject, Injectable } from '@navios/di'
|
|
4
|
+
|
|
4
5
|
import type {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from '
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
getGlobalServiceLocator,
|
|
12
|
-
inject,
|
|
13
|
-
Injectable,
|
|
14
|
-
syncInject,
|
|
15
|
-
} from '@navios/di'
|
|
16
|
-
|
|
17
|
-
import cors from '@fastify/cors'
|
|
18
|
-
import multipart from '@fastify/multipart'
|
|
19
|
-
import { fastify } from 'fastify'
|
|
20
|
-
import {
|
|
21
|
-
serializerCompiler,
|
|
22
|
-
validatorCompiler,
|
|
23
|
-
} from 'fastify-type-provider-zod'
|
|
24
|
-
|
|
25
|
-
import type { NaviosModule } from './interfaces/index.mjs'
|
|
6
|
+
AbstractHttpAdapterInterface,
|
|
7
|
+
AbstractHttpListenOptions,
|
|
8
|
+
NaviosModule,
|
|
9
|
+
} from './interfaces/index.mjs'
|
|
26
10
|
import type { LoggerService, LogLevel } from './logger/index.mjs'
|
|
11
|
+
import type { NaviosEnvironmentOptions } from './navios.environment.mjs'
|
|
27
12
|
|
|
28
|
-
import {
|
|
29
|
-
import { Logger
|
|
30
|
-
import {
|
|
31
|
-
|
|
32
|
-
ModuleLoaderService,
|
|
33
|
-
} from './services/index.mjs'
|
|
34
|
-
import { Application } from './tokens/index.mjs'
|
|
13
|
+
import { HttpAdapterToken } from './index.mjs'
|
|
14
|
+
import { Logger } from './logger/index.mjs'
|
|
15
|
+
import { NaviosEnvironment } from './navios.environment.mjs'
|
|
16
|
+
import { ModuleLoaderService } from './services/index.mjs'
|
|
35
17
|
|
|
36
18
|
export interface NaviosApplicationContextOptions {
|
|
37
19
|
/**
|
|
@@ -41,32 +23,43 @@ export interface NaviosApplicationContextOptions {
|
|
|
41
23
|
}
|
|
42
24
|
|
|
43
25
|
export interface NaviosApplicationOptions
|
|
44
|
-
extends
|
|
45
|
-
|
|
26
|
+
extends NaviosApplicationContextOptions {
|
|
27
|
+
// Fastify server options will be handled by FastifyApplicationService
|
|
28
|
+
adapter: NaviosEnvironmentOptions | NaviosEnvironmentOptions[]
|
|
29
|
+
}
|
|
46
30
|
|
|
47
31
|
@Injectable()
|
|
48
32
|
export class NaviosApplication {
|
|
49
|
-
private
|
|
50
|
-
private
|
|
51
|
-
private
|
|
33
|
+
private environment = inject(NaviosEnvironment)
|
|
34
|
+
private moduleLoader = inject(ModuleLoaderService)
|
|
35
|
+
private httpApplication: AbstractHttpAdapterInterface<any> | null = null
|
|
36
|
+
private logger = inject(Logger, {
|
|
52
37
|
context: NaviosApplication.name,
|
|
53
38
|
})
|
|
54
|
-
|
|
55
|
-
private corsOptions: FastifyCorsOptions | null = null
|
|
56
|
-
private multipartOptions: FastifyMultipartOptions | true | null = null
|
|
57
|
-
private globalPrefix: string | null = null
|
|
39
|
+
protected container = inject(Container)
|
|
58
40
|
|
|
59
41
|
private appModule: ClassTypeWithInstance<NaviosModule> | null = null
|
|
60
|
-
private options: NaviosApplicationOptions = {
|
|
42
|
+
private options: NaviosApplicationOptions = {
|
|
43
|
+
adapter: [],
|
|
44
|
+
}
|
|
61
45
|
|
|
62
46
|
isInitialized = false
|
|
63
47
|
|
|
64
|
-
setup(
|
|
48
|
+
async setup(
|
|
65
49
|
appModule: ClassTypeWithInstance<NaviosModule>,
|
|
66
|
-
options: NaviosApplicationOptions = {
|
|
50
|
+
options: NaviosApplicationOptions = {
|
|
51
|
+
adapter: [],
|
|
52
|
+
},
|
|
67
53
|
) {
|
|
68
54
|
this.appModule = appModule
|
|
69
55
|
this.options = options
|
|
56
|
+
if (this.environment.hasHttpSetup()) {
|
|
57
|
+
this.httpApplication = await this.container.get(HttpAdapterToken)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
getContainer() {
|
|
62
|
+
return this.container
|
|
70
63
|
}
|
|
71
64
|
|
|
72
65
|
async init() {
|
|
@@ -74,161 +67,61 @@ export class NaviosApplication {
|
|
|
74
67
|
throw new Error('App module is not set. Call setAppModule() first.')
|
|
75
68
|
}
|
|
76
69
|
await this.moduleLoader.loadModules(this.appModule)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
getGlobalServiceLocator().storeInstance(this.server, Application)
|
|
80
|
-
// Add schema validator and serializer
|
|
81
|
-
this.server.setValidatorCompiler(validatorCompiler)
|
|
82
|
-
this.server.setSerializerCompiler(serializerCompiler)
|
|
83
|
-
|
|
84
|
-
if (this.corsOptions) {
|
|
85
|
-
await this.server.register(cors, this.corsOptions)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (this.multipartOptions) {
|
|
89
|
-
await this.configureMultipart(this.server, this.multipartOptions)
|
|
70
|
+
if (this.environment.hasHttpSetup()) {
|
|
71
|
+
await this.httpApplication?.setupHttpServer(this.options)
|
|
90
72
|
}
|
|
91
|
-
|
|
92
73
|
await this.initModules()
|
|
93
|
-
|
|
74
|
+
if (this.environment.hasHttpSetup()) {
|
|
75
|
+
await this.httpApplication?.ready()
|
|
76
|
+
}
|
|
94
77
|
|
|
95
78
|
this.isInitialized = true
|
|
96
79
|
this.logger.debug('Navios application initialized')
|
|
97
80
|
}
|
|
98
81
|
|
|
99
|
-
private async getFastifyInstance(rawOptions: NaviosApplicationOptions) {
|
|
100
|
-
const { logger, ...options } = rawOptions
|
|
101
|
-
if (logger) {
|
|
102
|
-
const fastifyOptions = options as FastifyServerOptions
|
|
103
|
-
if (typeof logger === 'boolean') {
|
|
104
|
-
if (!logger) {
|
|
105
|
-
fastifyOptions.logger = false
|
|
106
|
-
}
|
|
107
|
-
} else {
|
|
108
|
-
fastifyOptions.loggerInstance = new PinoWrapper(
|
|
109
|
-
await inject(Logger, {
|
|
110
|
-
context: 'FastifyAdapter',
|
|
111
|
-
}),
|
|
112
|
-
)
|
|
113
|
-
}
|
|
114
|
-
return fastify(fastifyOptions)
|
|
115
|
-
} else {
|
|
116
|
-
return fastify({
|
|
117
|
-
...options,
|
|
118
|
-
loggerInstance: new PinoWrapper(
|
|
119
|
-
await inject(Logger, {
|
|
120
|
-
context: 'FastifyAdapter',
|
|
121
|
-
}),
|
|
122
|
-
),
|
|
123
|
-
} as FastifyServerOptions)
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
private configureFastifyInstance(fastifyInstance: FastifyInstance) {
|
|
128
|
-
fastifyInstance.setErrorHandler((error, request, reply) => {
|
|
129
|
-
if (error instanceof HttpException) {
|
|
130
|
-
return reply.status(error.statusCode).send(error.response)
|
|
131
|
-
} else {
|
|
132
|
-
const statusCode = error.statusCode || 500
|
|
133
|
-
const message = error.message || 'Internal Server Error'
|
|
134
|
-
const response = {
|
|
135
|
-
statusCode,
|
|
136
|
-
message,
|
|
137
|
-
error: error.name || 'InternalServerError',
|
|
138
|
-
}
|
|
139
|
-
this.logger.error(
|
|
140
|
-
`Error occurred: ${error.message} on ${request.url}`,
|
|
141
|
-
error,
|
|
142
|
-
)
|
|
143
|
-
return reply.status(statusCode).send(response)
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
fastifyInstance.setNotFoundHandler((req, reply) => {
|
|
148
|
-
const response = {
|
|
149
|
-
statusCode: 404,
|
|
150
|
-
message: 'Not Found',
|
|
151
|
-
error: 'NotFound',
|
|
152
|
-
}
|
|
153
|
-
this.logger.error(`Route not found: [${req.method}] ${req.url}`)
|
|
154
|
-
return reply.status(404).send(response)
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
async configureMultipart(
|
|
159
|
-
server: FastifyInstance,
|
|
160
|
-
options: FastifyMultipartOptions | true,
|
|
161
|
-
): Promise<void> {
|
|
162
|
-
if (options) {
|
|
163
|
-
await server.register(
|
|
164
|
-
multipart,
|
|
165
|
-
typeof options === 'object' ? options : {},
|
|
166
|
-
)
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
82
|
private async initModules() {
|
|
171
83
|
const modules = this.moduleLoader.getAllModules()
|
|
172
|
-
|
|
173
|
-
for (const [moduleName, moduleMetadata] of modules) {
|
|
174
|
-
if (
|
|
175
|
-
!moduleMetadata.controllers ||
|
|
176
|
-
moduleMetadata.controllers.size === 0
|
|
177
|
-
) {
|
|
178
|
-
continue
|
|
179
|
-
}
|
|
180
|
-
promises.push(
|
|
181
|
-
this.server!.register(
|
|
182
|
-
async (instance, opts) => {
|
|
183
|
-
for (const controller of moduleMetadata.controllers) {
|
|
184
|
-
await this.controllerAdapter.setupController(
|
|
185
|
-
controller,
|
|
186
|
-
instance,
|
|
187
|
-
moduleMetadata,
|
|
188
|
-
)
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
prefix: this.globalPrefix ?? '',
|
|
193
|
-
},
|
|
194
|
-
),
|
|
195
|
-
)
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
await Promise.all(promises)
|
|
84
|
+
await this.httpApplication?.onModulesInit(modules)
|
|
199
85
|
}
|
|
200
86
|
|
|
201
|
-
enableCors(options:
|
|
202
|
-
this.
|
|
87
|
+
enableCors(options: any) {
|
|
88
|
+
if (!this.httpApplication) {
|
|
89
|
+
throw new Error('HTTP application is not set')
|
|
90
|
+
}
|
|
91
|
+
this.httpApplication.enableCors(options)
|
|
203
92
|
}
|
|
204
93
|
|
|
205
|
-
enableMultipart(options:
|
|
206
|
-
this.
|
|
94
|
+
enableMultipart(options: any) {
|
|
95
|
+
if (!this.httpApplication) {
|
|
96
|
+
throw new Error('HTTP application is not set')
|
|
97
|
+
}
|
|
98
|
+
this.httpApplication.enableMultipart(options)
|
|
207
99
|
}
|
|
208
100
|
|
|
209
101
|
setGlobalPrefix(prefix: string) {
|
|
210
|
-
this.
|
|
102
|
+
if (!this.httpApplication) {
|
|
103
|
+
throw new Error('HTTP application is not set')
|
|
104
|
+
}
|
|
105
|
+
this.httpApplication.setGlobalPrefix(prefix)
|
|
211
106
|
}
|
|
212
107
|
|
|
213
|
-
getServer()
|
|
214
|
-
if (!this.
|
|
215
|
-
throw new Error('
|
|
108
|
+
getServer() {
|
|
109
|
+
if (!this.httpApplication) {
|
|
110
|
+
throw new Error('HTTP application is not set')
|
|
216
111
|
}
|
|
217
|
-
return this.
|
|
112
|
+
return this.httpApplication.getServer()
|
|
218
113
|
}
|
|
219
114
|
|
|
220
|
-
async listen(options:
|
|
221
|
-
if (!this.
|
|
222
|
-
throw new Error('
|
|
115
|
+
async listen(options: AbstractHttpListenOptions) {
|
|
116
|
+
if (!this.httpApplication) {
|
|
117
|
+
throw new Error('HTTP application is not set')
|
|
223
118
|
}
|
|
224
|
-
|
|
225
|
-
this.logger.debug(`Navios is listening on ${res}`)
|
|
119
|
+
await this.httpApplication.listen(options)
|
|
226
120
|
}
|
|
227
121
|
|
|
228
122
|
async dispose() {
|
|
229
|
-
if (this.
|
|
230
|
-
await this.
|
|
231
|
-
this.server = null
|
|
123
|
+
if (this.httpApplication) {
|
|
124
|
+
await this.httpApplication.dispose()
|
|
232
125
|
}
|
|
233
126
|
if (this.moduleLoader) {
|
|
234
127
|
this.moduleLoader.dispose()
|