@navios/core 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +95 -2
  2. package/docs/README.md +310 -3
  3. package/docs/adapters.md +308 -0
  4. package/docs/application-setup.md +524 -0
  5. package/docs/attributes.md +689 -0
  6. package/docs/controllers.md +373 -0
  7. package/docs/endpoints.md +444 -0
  8. package/docs/exceptions.md +316 -0
  9. package/docs/guards.md +550 -0
  10. package/docs/modules.md +377 -0
  11. package/docs/quick-start.md +295 -0
  12. package/docs/services.md +427 -0
  13. package/docs/testing.md +704 -0
  14. package/lib/_tsup-dts-rollup.d.mts +310 -239
  15. package/lib/_tsup-dts-rollup.d.ts +310 -239
  16. package/lib/index.d.mts +51 -28
  17. package/lib/index.d.ts +51 -28
  18. package/lib/index.js +633 -1072
  19. package/lib/index.js.map +1 -1
  20. package/lib/index.mjs +631 -1064
  21. package/lib/index.mjs.map +1 -1
  22. package/package.json +5 -9
  23. package/project.json +9 -1
  24. package/src/__tests__/config.service.spec.mts +11 -9
  25. package/src/__tests__/controller.spec.mts +0 -1
  26. package/src/config/config.service.mts +2 -2
  27. package/src/decorators/controller.decorator.mts +1 -1
  28. package/src/decorators/endpoint.decorator.mts +2 -2
  29. package/src/decorators/header.decorator.mts +1 -1
  30. package/src/decorators/multipart.decorator.mts +1 -2
  31. package/src/decorators/stream.decorator.mts +2 -3
  32. package/src/factories/endpoint-adapter.factory.mts +21 -0
  33. package/src/factories/http-adapter.factory.mts +20 -0
  34. package/src/factories/index.mts +6 -0
  35. package/src/factories/multipart-adapter.factory.mts +21 -0
  36. package/src/factories/reply.factory.mts +21 -0
  37. package/src/factories/request.factory.mts +21 -0
  38. package/src/factories/stream-adapter.factory.mts +20 -0
  39. package/src/index.mts +1 -1
  40. package/src/interfaces/abstract-execution-context.inteface.mts +13 -0
  41. package/src/interfaces/abstract-http-adapter.interface.mts +20 -0
  42. package/src/interfaces/abstract-http-cors-options.interface.mts +59 -0
  43. package/src/interfaces/abstract-http-handler-adapter.interface.mts +13 -0
  44. package/src/interfaces/abstract-http-listen-options.interface.mts +4 -0
  45. package/src/interfaces/can-activate.mts +4 -2
  46. package/src/interfaces/http-header.mts +18 -0
  47. package/src/interfaces/index.mts +6 -0
  48. package/src/logger/console-logger.service.mts +28 -44
  49. package/src/logger/index.mts +1 -2
  50. package/src/logger/logger.service.mts +9 -128
  51. package/src/logger/logger.tokens.mts +21 -0
  52. package/src/metadata/handler.metadata.mts +7 -5
  53. package/src/navios.application.mts +65 -172
  54. package/src/navios.environment.mts +30 -0
  55. package/src/navios.factory.mts +53 -12
  56. package/src/services/guard-runner.service.mts +19 -9
  57. package/src/services/index.mts +0 -2
  58. package/src/services/module-loader.service.mts +4 -3
  59. package/src/tokens/endpoint-adapter.token.mts +8 -0
  60. package/src/tokens/execution-context.token.mts +2 -2
  61. package/src/tokens/http-adapter.token.mts +8 -0
  62. package/src/tokens/index.mts +4 -1
  63. package/src/tokens/multipart-adapter.token.mts +8 -0
  64. package/src/tokens/reply.token.mts +1 -5
  65. package/src/tokens/request.token.mts +1 -7
  66. package/src/tokens/stream-adapter.token.mts +8 -0
  67. package/docs/recipes/prisma.md +0 -60
  68. package/e2e/endpoints/get.spec.mts +0 -97
  69. package/e2e/endpoints/post.spec.mts +0 -113
  70. package/examples/simple-test/api/index.mts +0 -64
  71. package/examples/simple-test/config/config.service.mts +0 -14
  72. package/examples/simple-test/config/configuration.mts +0 -7
  73. package/examples/simple-test/index.mts +0 -16
  74. package/examples/simple-test/src/acl/acl-modern.guard.mts +0 -15
  75. package/examples/simple-test/src/acl/acl.guard.mts +0 -14
  76. package/examples/simple-test/src/acl/app.guard.mts +0 -27
  77. package/examples/simple-test/src/acl/one-more.guard.mts +0 -15
  78. package/examples/simple-test/src/acl/public.attribute.mts +0 -21
  79. package/examples/simple-test/src/app.module.mts +0 -9
  80. package/examples/simple-test/src/user/user.controller.mts +0 -72
  81. package/examples/simple-test/src/user/user.module.mts +0 -14
  82. package/examples/simple-test/src/user/user.service.mts +0 -14
  83. package/src/adapters/endpoint-adapter.service.mts +0 -72
  84. package/src/adapters/handler-adapter.interface.mts +0 -21
  85. package/src/adapters/index.mts +0 -4
  86. package/src/adapters/multipart-adapter.service.mts +0 -135
  87. package/src/adapters/stream-adapter.service.mts +0 -91
  88. package/src/logger/logger.factory.mts +0 -36
  89. package/src/logger/pino-wrapper.mts +0 -64
  90. package/src/services/controller-adapter.service.mts +0 -124
  91. package/src/services/execution-context.mts +0 -54
  92. 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 { getGlobalServiceLocator, Injectable } from '@navios/di'
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 { Request } from '../tokens/index.mjs'
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 static lastTimestampAt?: number
150
+ protected lastTimestampAt?: number
153
151
 
154
- constructor()
155
- constructor(context: string)
156
- constructor(options: ConsoleLoggerOptions)
157
- constructor(context: string, options: ConsoleLoggerOptions)
158
- constructor(
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 && this.requestId) {
407
- logObject.requestId = this.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 && this.requestId) {
446
- return `(${this.colorize(this.requestId, 'log')}) `
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() - ConsoleLogger.lastTimestampAt!)
480
+ ? this.formatTimestampDiff(Date.now() - this.lastTimestampAt!)
497
481
  : ''
498
- ConsoleLogger.lastTimestampAt = Date.now()
482
+ this.lastTimestampAt = Date.now()
499
483
  return result
500
484
  }
501
485
 
@@ -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.factory.mjs'
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 { ConsoleLogger } from './console-logger.service.mjs'
7
- import { isLogLevelEnabled, isObject } from './utils/index.mjs'
6
+ import { Logger, LoggerOutput } from './logger.tokens.mjs'
8
7
 
9
- const DEFAULT_LOGGER = new ConsoleLogger()
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 static staticInstanceRef?: LoggerService = DEFAULT_LOGGER
23
- protected static logLevels?: LogLevel[]
24
-
25
- protected localInstanceRef?: LoggerService
12
+ protected localInstance = inject(LoggerOutput)
26
13
 
27
- constructor()
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
- get localInstance(): LoggerService {
36
- if (LoggerInstance.staticInstanceRef === DEFAULT_LOGGER) {
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 { HandlerAdapterInterface } from '../adapters/index.mjs'
6
- import type { CanActivate } from '../interfaces/index.mjs'
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<HandlerAdapterInterface, undefined>
16
- | ClassTypeWithInstance<HandlerAdapterInterface>
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
- FastifyInstance,
6
- FastifyListenOptions,
7
- FastifyServerOptions,
8
- } from 'fastify'
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 { HttpException } from './exceptions/index.mjs'
29
- import { Logger, PinoWrapper } from './logger/index.mjs'
30
- import {
31
- ControllerAdapterService,
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 Omit<FastifyServerOptions, 'logger'>,
45
- NaviosApplicationContextOptions {}
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 moduleLoader = syncInject(ModuleLoaderService)
50
- private controllerAdapter = syncInject(ControllerAdapterService)
51
- private logger = syncInject(Logger, {
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
- private server: FastifyInstance | null = null
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
- this.server = await this.getFastifyInstance(this.options)
78
- this.configureFastifyInstance(this.server)
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
- await this.server.ready()
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
- const promises: PromiseLike<any>[] = []
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: FastifyCorsOptions) {
202
- this.corsOptions = options
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: FastifyMultipartOptions) {
206
- this.multipartOptions = options
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.globalPrefix = prefix
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(): FastifyInstance {
214
- if (!this.server) {
215
- throw new Error('Server is not initialized. Call init() first.')
108
+ getServer() {
109
+ if (!this.httpApplication) {
110
+ throw new Error('HTTP application is not set')
216
111
  }
217
- return this.server
112
+ return this.httpApplication.getServer()
218
113
  }
219
114
 
220
- async listen(options: FastifyListenOptions) {
221
- if (!this.server) {
222
- throw new Error('Server is not initialized. Call init() first.')
115
+ async listen(options: AbstractHttpListenOptions) {
116
+ if (!this.httpApplication) {
117
+ throw new Error('HTTP application is not set')
223
118
  }
224
- const res = await this.server.listen(options)
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.server) {
230
- await this.server.close()
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()