@navios/core 0.7.0 → 0.7.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 (211) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/lib/{index-BFwNx9WQ.d.cts → index-DW9EPAE6.d.mts} +222 -17
  3. package/lib/index-DW9EPAE6.d.mts.map +1 -0
  4. package/lib/{index-D657ijFO.d.mts → index-pHp-dIGt.d.cts} +222 -17
  5. package/lib/index-pHp-dIGt.d.cts.map +1 -0
  6. package/lib/index.cjs +5 -5
  7. package/lib/index.d.cts +2 -2
  8. package/lib/index.d.mts +2 -2
  9. package/lib/index.mjs +1 -1
  10. package/lib/legacy-compat/index.cjs +1 -1
  11. package/lib/legacy-compat/index.d.cts +1 -1
  12. package/lib/legacy-compat/index.d.cts.map +1 -1
  13. package/lib/legacy-compat/index.d.mts +1 -1
  14. package/lib/legacy-compat/index.d.mts.map +1 -1
  15. package/lib/{src-DzPY5s6d.mjs → src-DyvCDuKO.mjs} +121 -31
  16. package/lib/src-DyvCDuKO.mjs.map +1 -0
  17. package/lib/{src-Cb1aTjl0.cjs → src-QnxR5b7c.cjs} +164 -74
  18. package/lib/src-QnxR5b7c.cjs.map +1 -0
  19. package/lib/testing/index.cjs +6 -6
  20. package/lib/testing/index.cjs.map +1 -1
  21. package/lib/testing/index.d.cts +1 -1
  22. package/lib/testing/index.d.mts +1 -1
  23. package/lib/testing/index.mjs +1 -1
  24. package/lib/{use-guards.decorator-DdvUhB03.cjs → use-guards.decorator-B6q_N0sf.cjs} +17 -17
  25. package/lib/{use-guards.decorator-DdvUhB03.cjs.map → use-guards.decorator-B6q_N0sf.cjs.map} +1 -1
  26. package/package.json +12 -12
  27. package/src/interfaces/abstract-http-adapter.interface.mts +52 -0
  28. package/src/interfaces/index.mts +1 -0
  29. package/src/interfaces/plugin.interface.mts +105 -0
  30. package/src/logger/logger.service.mts +5 -3
  31. package/src/navios.application.mts +77 -27
  32. package/src/navios.factory.mts +10 -9
  33. package/src/services/module-loader.service.mts +102 -1
  34. package/lib/index-BFwNx9WQ.d.cts.map +0 -1
  35. package/lib/index-D657ijFO.d.mts.map +0 -1
  36. package/lib/src-Cb1aTjl0.cjs.map +0 -1
  37. package/lib/src-DzPY5s6d.mjs.map +0 -1
  38. package/src/attribute.factory.d.mts +0 -175
  39. package/src/attribute.factory.d.mts.map +0 -1
  40. package/src/config/config-service.interface.d.mts +0 -39
  41. package/src/config/config-service.interface.d.mts.map +0 -1
  42. package/src/config/config.provider.d.mts +0 -46
  43. package/src/config/config.provider.d.mts.map +0 -1
  44. package/src/config/config.service.d.mts +0 -108
  45. package/src/config/config.service.d.mts.map +0 -1
  46. package/src/config/index.d.mts +0 -6
  47. package/src/config/index.d.mts.map +0 -1
  48. package/src/config/types.d.mts +0 -13
  49. package/src/config/types.d.mts.map +0 -1
  50. package/src/config/utils/helpers.d.mts +0 -3
  51. package/src/config/utils/helpers.d.mts.map +0 -1
  52. package/src/config/utils/index.d.mts +0 -2
  53. package/src/config/utils/index.d.mts.map +0 -1
  54. package/src/decorators/controller.decorator.d.mts +0 -33
  55. package/src/decorators/controller.decorator.d.mts.map +0 -1
  56. package/src/decorators/endpoint.decorator.d.mts +0 -89
  57. package/src/decorators/endpoint.decorator.d.mts.map +0 -1
  58. package/src/decorators/header.decorator.d.mts +0 -22
  59. package/src/decorators/header.decorator.d.mts.map +0 -1
  60. package/src/decorators/http-code.decorator.d.mts +0 -22
  61. package/src/decorators/http-code.decorator.d.mts.map +0 -1
  62. package/src/decorators/index.d.mts +0 -9
  63. package/src/decorators/index.d.mts.map +0 -1
  64. package/src/decorators/module.decorator.d.mts +0 -42
  65. package/src/decorators/module.decorator.d.mts.map +0 -1
  66. package/src/decorators/multipart.decorator.d.mts +0 -54
  67. package/src/decorators/multipart.decorator.d.mts.map +0 -1
  68. package/src/decorators/stream.decorator.d.mts +0 -42
  69. package/src/decorators/stream.decorator.d.mts.map +0 -1
  70. package/src/decorators/use-guards.decorator.d.mts +0 -33
  71. package/src/decorators/use-guards.decorator.d.mts.map +0 -1
  72. package/src/exceptions/bad-request.exception.d.mts +0 -26
  73. package/src/exceptions/bad-request.exception.d.mts.map +0 -1
  74. package/src/exceptions/conflict.exception.d.mts +0 -29
  75. package/src/exceptions/conflict.exception.d.mts.map +0 -1
  76. package/src/exceptions/forbidden.exception.d.mts +0 -28
  77. package/src/exceptions/forbidden.exception.d.mts.map +0 -1
  78. package/src/exceptions/http.exception.d.mts +0 -33
  79. package/src/exceptions/http.exception.d.mts.map +0 -1
  80. package/src/exceptions/index.d.mts +0 -8
  81. package/src/exceptions/index.d.mts.map +0 -1
  82. package/src/exceptions/internal-server-error.exception.d.mts +0 -31
  83. package/src/exceptions/internal-server-error.exception.d.mts.map +0 -1
  84. package/src/exceptions/not-found.exception.d.mts +0 -30
  85. package/src/exceptions/not-found.exception.d.mts.map +0 -1
  86. package/src/exceptions/unauthorized.exception.d.mts +0 -28
  87. package/src/exceptions/unauthorized.exception.d.mts.map +0 -1
  88. package/src/factories/endpoint-adapter.factory.d.mts +0 -6
  89. package/src/factories/endpoint-adapter.factory.d.mts.map +0 -1
  90. package/src/factories/http-adapter.factory.d.mts +0 -6
  91. package/src/factories/http-adapter.factory.d.mts.map +0 -1
  92. package/src/factories/index.d.mts +0 -8
  93. package/src/factories/index.d.mts.map +0 -1
  94. package/src/factories/multipart-adapter.factory.d.mts +0 -6
  95. package/src/factories/multipart-adapter.factory.d.mts.map +0 -1
  96. package/src/factories/reply.factory.d.mts +0 -6
  97. package/src/factories/reply.factory.d.mts.map +0 -1
  98. package/src/factories/request.factory.d.mts +0 -6
  99. package/src/factories/request.factory.d.mts.map +0 -1
  100. package/src/factories/stream-adapter.factory.d.mts +0 -6
  101. package/src/factories/stream-adapter.factory.d.mts.map +0 -1
  102. package/src/factories/xml-stream-adapter.factory.d.mts +0 -6
  103. package/src/factories/xml-stream-adapter.factory.d.mts.map +0 -1
  104. package/src/index.d.mts +0 -15
  105. package/src/index.d.mts.map +0 -1
  106. package/src/interfaces/abstract-execution-context.inteface.d.mts +0 -44
  107. package/src/interfaces/abstract-execution-context.inteface.d.mts.map +0 -1
  108. package/src/interfaces/abstract-http-adapter.interface.d.mts +0 -15
  109. package/src/interfaces/abstract-http-adapter.interface.d.mts.map +0 -1
  110. package/src/interfaces/abstract-http-cors-options.interface.d.mts +0 -58
  111. package/src/interfaces/abstract-http-cors-options.interface.d.mts.map +0 -1
  112. package/src/interfaces/abstract-http-handler-adapter.interface.d.mts +0 -7
  113. package/src/interfaces/abstract-http-handler-adapter.interface.d.mts.map +0 -1
  114. package/src/interfaces/abstract-http-listen-options.interface.d.mts +0 -5
  115. package/src/interfaces/abstract-http-listen-options.interface.d.mts.map +0 -1
  116. package/src/interfaces/can-activate.d.mts +0 -36
  117. package/src/interfaces/can-activate.d.mts.map +0 -1
  118. package/src/interfaces/http-header.d.mts +0 -10
  119. package/src/interfaces/http-header.d.mts.map +0 -1
  120. package/src/interfaces/index.d.mts +0 -9
  121. package/src/interfaces/index.d.mts.map +0 -1
  122. package/src/interfaces/navios-module.d.mts +0 -29
  123. package/src/interfaces/navios-module.d.mts.map +0 -1
  124. package/src/legacy-compat/context-compat.d.mts +0 -19
  125. package/src/legacy-compat/context-compat.d.mts.map +0 -1
  126. package/src/legacy-compat/decorators/controller.decorator.d.mts +0 -21
  127. package/src/legacy-compat/decorators/controller.decorator.d.mts.map +0 -1
  128. package/src/legacy-compat/decorators/endpoint.decorator.d.mts +0 -33
  129. package/src/legacy-compat/decorators/endpoint.decorator.d.mts.map +0 -1
  130. package/src/legacy-compat/decorators/header.decorator.d.mts +0 -24
  131. package/src/legacy-compat/decorators/header.decorator.d.mts.map +0 -1
  132. package/src/legacy-compat/decorators/http-code.decorator.d.mts +0 -22
  133. package/src/legacy-compat/decorators/http-code.decorator.d.mts.map +0 -1
  134. package/src/legacy-compat/decorators/index.d.mts +0 -9
  135. package/src/legacy-compat/decorators/index.d.mts.map +0 -1
  136. package/src/legacy-compat/decorators/module.decorator.d.mts +0 -22
  137. package/src/legacy-compat/decorators/module.decorator.d.mts.map +0 -1
  138. package/src/legacy-compat/decorators/multipart.decorator.d.mts +0 -34
  139. package/src/legacy-compat/decorators/multipart.decorator.d.mts.map +0 -1
  140. package/src/legacy-compat/decorators/stream.decorator.d.mts +0 -34
  141. package/src/legacy-compat/decorators/stream.decorator.d.mts.map +0 -1
  142. package/src/legacy-compat/decorators/use-guards.decorator.d.mts +0 -29
  143. package/src/legacy-compat/decorators/use-guards.decorator.d.mts.map +0 -1
  144. package/src/legacy-compat/index.d.mts +0 -19
  145. package/src/legacy-compat/index.d.mts.map +0 -1
  146. package/src/logger/console-logger.service.d.mts +0 -196
  147. package/src/logger/console-logger.service.d.mts.map +0 -1
  148. package/src/logger/index.d.mts +0 -7
  149. package/src/logger/index.d.mts.map +0 -1
  150. package/src/logger/log-levels.d.mts +0 -14
  151. package/src/logger/log-levels.d.mts.map +0 -1
  152. package/src/logger/logger-service.interface.d.mts +0 -36
  153. package/src/logger/logger-service.interface.d.mts.map +0 -1
  154. package/src/logger/logger.service.d.mts +0 -57
  155. package/src/logger/logger.service.d.mts.map +0 -1
  156. package/src/logger/logger.tokens.d.mts +0 -36
  157. package/src/logger/logger.tokens.d.mts.map +0 -1
  158. package/src/logger/utils/cli-colors.util.d.mts +0 -10
  159. package/src/logger/utils/cli-colors.util.d.mts.map +0 -1
  160. package/src/logger/utils/filter-log-levelts.util.d.mts +0 -6
  161. package/src/logger/utils/filter-log-levelts.util.d.mts.map +0 -1
  162. package/src/logger/utils/index.d.mts +0 -6
  163. package/src/logger/utils/index.d.mts.map +0 -1
  164. package/src/logger/utils/is-log-level-enabled.d.mts +0 -8
  165. package/src/logger/utils/is-log-level-enabled.d.mts.map +0 -1
  166. package/src/logger/utils/is-log-level.util.d.mts +0 -6
  167. package/src/logger/utils/is-log-level.util.d.mts.map +0 -1
  168. package/src/logger/utils/shared.utils.d.mts +0 -14
  169. package/src/logger/utils/shared.utils.d.mts.map +0 -1
  170. package/src/metadata/controller.metadata.d.mts +0 -13
  171. package/src/metadata/controller.metadata.d.mts.map +0 -1
  172. package/src/metadata/handler.metadata.d.mts +0 -18
  173. package/src/metadata/handler.metadata.d.mts.map +0 -1
  174. package/src/metadata/index.d.mts +0 -4
  175. package/src/metadata/index.d.mts.map +0 -1
  176. package/src/metadata/module.metadata.d.mts +0 -13
  177. package/src/metadata/module.metadata.d.mts.map +0 -1
  178. package/src/navios.application.d.mts +0 -210
  179. package/src/navios.application.d.mts.map +0 -1
  180. package/src/navios.environment.d.mts +0 -11
  181. package/src/navios.environment.d.mts.map +0 -1
  182. package/src/navios.factory.d.mts +0 -68
  183. package/src/navios.factory.d.mts.map +0 -1
  184. package/src/services/guard-runner.service.d.mts +0 -10
  185. package/src/services/guard-runner.service.d.mts.map +0 -1
  186. package/src/services/index.d.mts +0 -3
  187. package/src/services/index.d.mts.map +0 -1
  188. package/src/services/module-loader.service.d.mts +0 -17
  189. package/src/services/module-loader.service.d.mts.map +0 -1
  190. package/src/stores/index.d.mts +0 -2
  191. package/src/stores/index.d.mts.map +0 -1
  192. package/src/stores/request-id.store.d.mts +0 -37
  193. package/src/stores/request-id.store.d.mts.map +0 -1
  194. package/src/tokens/endpoint-adapter.token.d.mts +0 -4
  195. package/src/tokens/endpoint-adapter.token.d.mts.map +0 -1
  196. package/src/tokens/execution-context.token.d.mts +0 -5
  197. package/src/tokens/execution-context.token.d.mts.map +0 -1
  198. package/src/tokens/http-adapter.token.d.mts +0 -4
  199. package/src/tokens/http-adapter.token.d.mts.map +0 -1
  200. package/src/tokens/index.d.mts +0 -9
  201. package/src/tokens/index.d.mts.map +0 -1
  202. package/src/tokens/multipart-adapter.token.d.mts +0 -4
  203. package/src/tokens/multipart-adapter.token.d.mts.map +0 -1
  204. package/src/tokens/reply.token.d.mts +0 -3
  205. package/src/tokens/reply.token.d.mts.map +0 -1
  206. package/src/tokens/request.token.d.mts +0 -3
  207. package/src/tokens/request.token.d.mts.map +0 -1
  208. package/src/tokens/stream-adapter.token.d.mts +0 -4
  209. package/src/tokens/stream-adapter.token.d.mts.map +0 -1
  210. package/src/tokens/xml-stream-adapter.token.d.mts +0 -4
  211. package/src/tokens/xml-stream-adapter.token.d.mts.map +0 -1
@@ -6,6 +6,8 @@ import type {
6
6
  AbstractHttpAdapterInterface,
7
7
  AbstractHttpListenOptions,
8
8
  NaviosModule,
9
+ PluginContext,
10
+ PluginDefinition,
9
11
  } from './interfaces/index.mjs'
10
12
  import type { LoggerService, LogLevel } from './logger/index.mjs'
11
13
  import type { NaviosEnvironmentOptions } from './navios.environment.mjs'
@@ -22,7 +24,7 @@ import { ModuleLoaderService } from './services/index.mjs'
22
24
  export interface NaviosApplicationContextOptions {
23
25
  /**
24
26
  * Specifies the logger to use. Pass `false` to turn off logging.
25
- *
27
+ *
26
28
  * - `LoggerService` instance: Use a custom logger implementation
27
29
  * - `LogLevel[]`: Enable specific log levels (e.g., ['error', 'warn', 'log'])
28
30
  * - `false`: Disable logging completely
@@ -40,12 +42,11 @@ export interface NaviosApplicationContextOptions {
40
42
  * Complete options for creating a Navios application.
41
43
  * Extends NaviosApplicationContextOptions with adapter configuration.
42
44
  */
43
- export interface NaviosApplicationOptions
44
- extends NaviosApplicationContextOptions {
45
+ export interface NaviosApplicationOptions extends NaviosApplicationContextOptions {
45
46
  /**
46
47
  * HTTP adapter environment(s) to use for the application.
47
48
  * Can be a single adapter or an array of adapters.
48
- *
49
+ *
49
50
  * @example
50
51
  * ```typescript
51
52
  * adapter: defineFastifyEnvironment()
@@ -58,16 +59,16 @@ export interface NaviosApplicationOptions
58
59
 
59
60
  /**
60
61
  * Main application class for Navios.
61
- *
62
+ *
62
63
  * This class represents a Navios application instance and provides methods
63
64
  * for initializing, configuring, and managing the HTTP server.
64
- *
65
+ *
65
66
  * @example
66
67
  * ```typescript
67
68
  * const app = await NaviosFactory.create(AppModule, {
68
69
  * adapter: defineFastifyEnvironment(),
69
70
  * })
70
- *
71
+ *
71
72
  * app.setGlobalPrefix('/api')
72
73
  * app.enableCors({ origin: ['http://localhost:3000'] })
73
74
  * await app.init()
@@ -88,6 +89,7 @@ export class NaviosApplication {
88
89
  private options: NaviosApplicationOptions = {
89
90
  adapter: [],
90
91
  }
92
+ private plugins: PluginDefinition<any>[] = []
91
93
 
92
94
  /**
93
95
  * Indicates whether the application has been initialized.
@@ -98,7 +100,7 @@ export class NaviosApplication {
98
100
  /**
99
101
  * Sets up the application with the provided module and options.
100
102
  * This is called automatically by NaviosFactory.create().
101
- *
103
+ *
102
104
  * @param appModule - The root application module
103
105
  * @param options - Application configuration options
104
106
  * @internal
@@ -118,26 +120,50 @@ export class NaviosApplication {
118
120
 
119
121
  /**
120
122
  * Gets the dependency injection container used by this application.
121
- *
123
+ *
122
124
  * @returns The Container instance
123
125
  */
124
126
  getContainer() {
125
127
  return this.container
126
128
  }
127
129
 
130
+ /**
131
+ * Registers a plugin to be initialized after modules are loaded.
132
+ *
133
+ * Plugins are initialized in the order they are registered,
134
+ * after all modules are loaded but before the server starts listening.
135
+ *
136
+ * @param definition - Plugin definition with options
137
+ * @returns this for method chaining
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * import { defineOpenApiPlugin } from '@navios/openapi-fastify'
142
+ *
143
+ * app.usePlugin(defineOpenApiPlugin({
144
+ * info: { title: 'My API', version: '1.0.0' },
145
+ * }))
146
+ * ```
147
+ */
148
+ usePlugin<TOptions>(definition: PluginDefinition<TOptions>): this {
149
+ this.plugins.push(definition)
150
+ return this
151
+ }
152
+
128
153
  /**
129
154
  * Initializes the application.
130
- *
155
+ *
131
156
  * This method:
132
157
  * - Loads all modules and their dependencies
133
158
  * - Sets up the HTTP server if an adapter is configured
134
159
  * - Calls onModuleInit hooks on all modules
160
+ * - Initializes registered plugins
135
161
  * - Marks the application as initialized
136
- *
162
+ *
137
163
  * Must be called before `listen()`.
138
- *
164
+ *
139
165
  * @throws Error if app module is not set
140
- *
166
+ *
141
167
  * @example
142
168
  * ```typescript
143
169
  * const app = await NaviosFactory.create(AppModule, {
@@ -155,6 +181,7 @@ export class NaviosApplication {
155
181
  if (this.environment.hasHttpSetup()) {
156
182
  await this.httpApplication?.setupHttpServer(this.options)
157
183
  }
184
+ await this.initPlugins()
158
185
  await this.initModules()
159
186
  if (this.environment.hasHttpSetup()) {
160
187
  await this.httpApplication?.ready()
@@ -169,12 +196,35 @@ export class NaviosApplication {
169
196
  await this.httpApplication?.onModulesInit(modules)
170
197
  }
171
198
 
199
+ private async initPlugins() {
200
+ if (this.plugins.length === 0) return
201
+
202
+ let server: any = null
203
+ try {
204
+ server = this.httpApplication?.getServer() ?? null
205
+ } catch {
206
+ // ignore
207
+ }
208
+ const context: PluginContext = {
209
+ modules: this.moduleLoader.getAllModules(),
210
+ server,
211
+ container: this.container,
212
+ globalPrefix: this.httpApplication?.getGlobalPrefix() ?? '',
213
+ moduleLoader: this.moduleLoader,
214
+ }
215
+
216
+ for (const { plugin, options } of this.plugins) {
217
+ this.logger.debug(`Initializing plugin: ${plugin.name}`)
218
+ await plugin.register(context, options)
219
+ }
220
+ }
221
+
172
222
  /**
173
223
  * Enables CORS (Cross-Origin Resource Sharing) for the application.
174
- *
224
+ *
175
225
  * @param options - CORS configuration options (adapter-specific)
176
226
  * @throws Error if HTTP application is not set
177
- *
227
+ *
178
228
  * @example
179
229
  * ```typescript
180
230
  * app.enableCors({
@@ -193,10 +243,10 @@ export class NaviosApplication {
193
243
 
194
244
  /**
195
245
  * Enables multipart/form-data support for file uploads.
196
- *
246
+ *
197
247
  * @param options - Multipart configuration options (adapter-specific)
198
248
  * @throws Error if HTTP application is not set
199
- *
249
+ *
200
250
  * @example
201
251
  * ```typescript
202
252
  * app.enableMultipart({
@@ -215,10 +265,10 @@ export class NaviosApplication {
215
265
 
216
266
  /**
217
267
  * Sets a global prefix for all routes.
218
- *
268
+ *
219
269
  * @param prefix - The prefix to prepend to all route URLs (e.g., '/api')
220
270
  * @throws Error if HTTP application is not set
221
- *
271
+ *
222
272
  * @example
223
273
  * ```typescript
224
274
  * app.setGlobalPrefix('/api/v1')
@@ -234,14 +284,14 @@ export class NaviosApplication {
234
284
 
235
285
  /**
236
286
  * Gets the underlying HTTP server instance.
237
- *
287
+ *
238
288
  * The type of the returned server depends on the adapter used:
239
289
  * - Fastify adapter: Returns FastifyInstance
240
290
  * - Bun adapter: Returns Bun.Server
241
- *
291
+ *
242
292
  * @returns The HTTP server instance
243
293
  * @throws Error if HTTP application is not set
244
- *
294
+ *
245
295
  * @example
246
296
  * ```typescript
247
297
  * const server = app.getServer()
@@ -257,10 +307,10 @@ export class NaviosApplication {
257
307
 
258
308
  /**
259
309
  * Starts the HTTP server and begins listening for requests.
260
- *
310
+ *
261
311
  * @param options - Listen options (port, host, etc.)
262
312
  * @throws Error if HTTP application is not set
263
- *
313
+ *
264
314
  * @example
265
315
  * ```typescript
266
316
  * await app.listen({ port: 3000, host: '0.0.0.0' })
@@ -275,7 +325,7 @@ export class NaviosApplication {
275
325
 
276
326
  /**
277
327
  * Disposes of application resources.
278
- *
328
+ *
279
329
  * Cleans up the HTTP server and module loader.
280
330
  * This method is called automatically by `close()`.
281
331
  */
@@ -290,9 +340,9 @@ export class NaviosApplication {
290
340
 
291
341
  /**
292
342
  * Closes the application and cleans up all resources.
293
- *
343
+ *
294
344
  * This is an alias for `dispose()`.
295
- *
345
+ *
296
346
  * @example
297
347
  * ```typescript
298
348
  * // Graceful shutdown
@@ -18,21 +18,21 @@ import { NaviosEnvironment } from './navios.environment.mjs'
18
18
 
19
19
  /**
20
20
  * Factory class for creating and configuring Navios applications.
21
- *
21
+ *
22
22
  * This is the main entry point for bootstrapping a Navios application.
23
23
  * It handles dependency injection container setup, adapter registration,
24
24
  * and logger configuration.
25
- *
25
+ *
26
26
  * @example
27
27
  * ```typescript
28
28
  * import { NaviosFactory } from '@navios/core'
29
29
  * import { defineFastifyEnvironment } from '@navios/adapter-fastify'
30
- *
30
+ *
31
31
  * const app = await NaviosFactory.create(AppModule, {
32
32
  * adapter: defineFastifyEnvironment(),
33
33
  * logger: ['log', 'error', 'warn'],
34
34
  * })
35
- *
35
+ *
36
36
  * await app.init()
37
37
  * await app.listen({ port: 3000 })
38
38
  * ```
@@ -40,10 +40,10 @@ import { NaviosEnvironment } from './navios.environment.mjs'
40
40
  export class NaviosFactory {
41
41
  /**
42
42
  * Creates a new Navios application instance.
43
- *
43
+ *
44
44
  * This method sets up the dependency injection container, registers the HTTP adapter,
45
45
  * configures logging, and initializes the application with the provided module.
46
- *
46
+ *
47
47
  * @param appModule - The root application module class decorated with @Module()
48
48
  * @param options - Configuration options for the application
49
49
  * @param options.adapter - HTTP adapter environment (required for HTTP server functionality)
@@ -53,20 +53,20 @@ export class NaviosFactory {
53
53
  * - `false` to disable logging
54
54
  * @param options.container - Optional custom dependency injection container (useful for testing)
55
55
  * @returns A configured NaviosApplication instance ready to be initialized
56
- *
56
+ *
57
57
  * @example
58
58
  * ```typescript
59
59
  * // Basic setup with Fastify adapter
60
60
  * const app = await NaviosFactory.create(AppModule, {
61
61
  * adapter: defineFastifyEnvironment(),
62
62
  * })
63
- *
63
+ *
64
64
  * // With custom logger configuration
65
65
  * const app = await NaviosFactory.create(AppModule, {
66
66
  * adapter: defineFastifyEnvironment(),
67
67
  * logger: ['error', 'warn', 'log'],
68
68
  * })
69
- *
69
+ *
70
70
  * // With custom container for testing
71
71
  * const container = new Container()
72
72
  * const app = await NaviosFactory.create(AppModule, {
@@ -119,6 +119,7 @@ export class NaviosFactory {
119
119
  loggerInstance?.setup({
120
120
  logLevels: logger,
121
121
  })
122
+ return
122
123
  }
123
124
  if ((logger as boolean) !== true && !isNil(logger)) {
124
125
  container
@@ -1,4 +1,4 @@
1
- import type { ClassTypeWithInstance } from '@navios/di'
1
+ import type { ClassType, ClassTypeWithInstance } from '@navios/di'
2
2
 
3
3
  import { Container, inject, Injectable } from '@navios/di'
4
4
 
@@ -8,6 +8,30 @@ import type { ModuleMetadata } from '../metadata/index.mjs'
8
8
  import { Logger } from '../logger/index.mjs'
9
9
  import { extractModuleMetadata } from '../metadata/index.mjs'
10
10
 
11
+ /**
12
+ * Extension definition for dynamically adding to the module tree.
13
+ * Used by plugins to inject controllers or entire modules.
14
+ */
15
+ export interface ModuleExtension {
16
+ /**
17
+ * Module class to add. If provided, the module and all its
18
+ * controllers/imports will be processed.
19
+ */
20
+ module?: ClassTypeWithInstance<NaviosModule>
21
+
22
+ /**
23
+ * Controllers to add directly without a wrapper module.
24
+ * Will be registered under a synthetic module named after the plugin.
25
+ */
26
+ controllers?: ClassType[]
27
+
28
+ /**
29
+ * Name for the synthetic module when using controllers directly.
30
+ * Required if `controllers` is provided without `module`.
31
+ */
32
+ moduleName?: string
33
+ }
34
+
11
35
  @Injectable()
12
36
  export class ModuleLoaderService {
13
37
  private logger = inject(Logger, {
@@ -26,6 +50,83 @@ export class ModuleLoaderService {
26
50
  this.initialized = true
27
51
  }
28
52
 
53
+ /**
54
+ * Extends the module tree with additional modules or controllers.
55
+ *
56
+ * This method is designed to be called by plugins during registration,
57
+ * which happens after initial module loading but before route registration.
58
+ *
59
+ * @param extensions - Array of module extensions to add
60
+ * @throws Error if not initialized (loadModules must be called first)
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * // In plugin registration
65
+ * const moduleLoader = await context.container.get(ModuleLoaderService)
66
+ * await moduleLoader.extendModules([{
67
+ * controllers: [OpenApiJsonController, OpenApiYamlController],
68
+ * moduleName: 'OpenApiBunModule',
69
+ * }])
70
+ * ```
71
+ */
72
+ async extendModules(extensions: ModuleExtension[]): Promise<void> {
73
+ if (!this.initialized) {
74
+ throw new Error(
75
+ 'ModuleLoaderService must be initialized before extending. Call loadModules() first.',
76
+ )
77
+ }
78
+
79
+ for (const extension of extensions) {
80
+ if (extension.module) {
81
+ // Process a full module with its imports and controllers
82
+ await this.traverseModules(extension.module)
83
+ } else if (extension.controllers && extension.moduleName) {
84
+ // Create synthetic module metadata for loose controllers
85
+ await this.registerControllers(
86
+ extension.controllers,
87
+ extension.moduleName,
88
+ )
89
+ } else if (extension.controllers) {
90
+ throw new Error(
91
+ 'moduleName is required when providing controllers without a module',
92
+ )
93
+ }
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Registers controllers under a synthetic module.
99
+ * Used when plugins want to add controllers without a full module class.
100
+ */
101
+ private async registerControllers(
102
+ controllers: ClassType[],
103
+ moduleName: string,
104
+ ): Promise<void> {
105
+ if (this.modulesMetadata.has(moduleName)) {
106
+ // Merge controllers into existing module
107
+ const existing = this.modulesMetadata.get(moduleName)!
108
+ for (const controller of controllers) {
109
+ existing.controllers.add(controller)
110
+ }
111
+ this.logger.debug(
112
+ `Extended module ${moduleName} with ${controllers.length} controllers`,
113
+ )
114
+ } else {
115
+ // Create new synthetic module metadata
116
+ const metadata: ModuleMetadata = {
117
+ controllers: new Set(controllers),
118
+ imports: new Set(),
119
+ guards: new Set(),
120
+ customAttributes: new Map(),
121
+ }
122
+ this.modulesMetadata.set(moduleName, metadata)
123
+
124
+ this.logger.debug(
125
+ `Created module ${moduleName} with ${controllers.length} controllers`,
126
+ )
127
+ }
128
+ }
129
+
29
130
  private async traverseModules(
30
131
  module: ClassTypeWithInstance<NaviosModule>,
31
132
  parentMetadata?: ModuleMetadata,