@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
@@ -0,0 +1,373 @@
1
+ # Controllers
2
+
3
+ Controllers in Navios are classes that handle HTTP requests and define your API endpoints. They are decorated with the `@Controller()` decorator and contain methods decorated with endpoint decorators like `@Endpoint()`.
4
+
5
+ ## What is a Controller?
6
+
7
+ A controller is a TypeScript class that groups related request handling logic. Each controller method represents an HTTP endpoint and defines how to process incoming requests and generate responses.
8
+
9
+ ## Creating a Controller
10
+
11
+ ### Basic Controller
12
+
13
+ ```typescript
14
+ import { Controller } from '@navios/core'
15
+
16
+ @Controller()
17
+ export class UserController {
18
+ // Controller methods go here
19
+ }
20
+ ```
21
+
22
+ ### Controller with Guards
23
+
24
+ ```typescript
25
+ import { Controller } from '@navios/core'
26
+
27
+ import { AuthGuard } from './auth.guard'
28
+
29
+ @Controller({
30
+ guards: [AuthGuard], // Applied to all endpoints in this controller
31
+ })
32
+ export class UserController {
33
+ // All methods will require authentication
34
+ }
35
+ ```
36
+
37
+ ## Controller Options
38
+
39
+ The `@Controller()` decorator accepts the following options:
40
+
41
+ ### `guards`
42
+
43
+ - **Type**: `ClassType[] | Set<ClassType>`
44
+ - **Description**: Array of guard classes that will be applied to all endpoints in this controller
45
+ - **Example**:
46
+
47
+ ```typescript
48
+ @Controller({
49
+ guards: [AuthGuard, RoleGuard],
50
+ })
51
+ export class AdminController {}
52
+ ```
53
+
54
+ ## Controller Lifecycle
55
+
56
+ Controllers in Navios have a specific lifecycle:
57
+
58
+ 1. **Registration**: Controllers are registered during module loading
59
+ 2. **Instantiation**: Controller instances are created with request scope by default
60
+ 3. **Dependency Injection**: Dependencies are injected into the controller
61
+ 4. **Endpoint Discovery**: Methods decorated with `@Endpoint()` are discovered
62
+ 5. **Guard Application**: Controller and endpoint-level guards are applied
63
+ 6. **Request Handling**: Methods are called to handle incoming requests
64
+
65
+ ## Controller Scope
66
+
67
+ Controllers are registered with **Request Scope** by default, meaning:
68
+
69
+ - A new instance is created for each HTTP request
70
+ - Dependencies are resolved per request
71
+ - State is not shared between requests
72
+
73
+ ## Best Practices
74
+
75
+ ### 1. Logical Grouping
76
+
77
+ Group related endpoints in the same controller:
78
+
79
+ ```typescript
80
+ @Controller()
81
+ export class UserController {
82
+ // All user-related endpoints
83
+ async getUsers() {
84
+ /* ... */
85
+ }
86
+ async getUserById() {
87
+ /* ... */
88
+ }
89
+ async createUser() {
90
+ /* ... */
91
+ }
92
+ async updateUser() {
93
+ /* ... */
94
+ }
95
+ async deleteUser() {
96
+ /* ... */
97
+ }
98
+ }
99
+ ```
100
+
101
+ ### 2. Use Guards Appropriately
102
+
103
+ Apply guards at the appropriate level:
104
+
105
+ ```typescript
106
+ // Controller-level guards for all endpoints
107
+ @Controller({
108
+ guards: [AuthGuard],
109
+ })
110
+ export class UserController {
111
+ // All methods require authentication
112
+
113
+ @Endpoint(deleteUserEndpoint)
114
+ @UseGuards([RoleGuard]) // Additional endpoint-specific guard
115
+ async deleteUser() {
116
+ // Requires both authentication and role check
117
+ }
118
+ }
119
+ ```
120
+
121
+ ### 3. Keep Controllers Thin
122
+
123
+ Controllers should orchestrate business logic, not implement it:
124
+
125
+ ```typescript
126
+ // api/users.ts
127
+ import { builder } from '@navios/builder'
128
+
129
+ import { z } from 'zod'
130
+
131
+ export const api = builder()
132
+
133
+ const UserSchema = z.object({
134
+ id: z.string(),
135
+ name: z.string(),
136
+ email: z.string(),
137
+ })
138
+
139
+ export const getUserByIdEndpoint = api.declareEndpoint({
140
+ method: 'GET',
141
+ url: '/users/$id',
142
+ responseSchema: UserSchema,
143
+ })
144
+ ```
145
+
146
+ ```typescript
147
+ // controllers/user.controller.ts
148
+ import { inject } from '@navios/di'
149
+
150
+ import { getUserByIdEndpoint } from '../api/users.js'
151
+
152
+ @Controller()
153
+ export class UserController {
154
+ private userService = inject(UserService)
155
+
156
+ @Endpoint(getUserByIdEndpoint)
157
+ async getUserById(params: EndpointParams<typeof getUserByIdEndpoint>) {
158
+ // Delegate business logic to service
159
+ return this.userService.findById(params.params.id)
160
+ }
161
+ }
162
+ ```
163
+
164
+ ### 4. Use TypeScript Types
165
+
166
+ Leverage TypeScript and `@navios/builder` for better type safety:
167
+
168
+ ```typescript
169
+ // api/users.ts
170
+ import { builder } from '@navios/builder'
171
+
172
+ import { z } from 'zod'
173
+
174
+ export const api = builder()
175
+
176
+ const UserResponseSchema = z.object({
177
+ id: z.string(),
178
+ name: z.string(),
179
+ email: z.string().email(),
180
+ })
181
+
182
+ export const getUserByIdEndpoint = api.declareEndpoint({
183
+ method: 'GET',
184
+ url: '/users/$id', // $id is automatically typed as string
185
+ responseSchema: UserResponseSchema,
186
+ })
187
+ ```
188
+
189
+ ```typescript
190
+ // controllers/user.controller.ts
191
+ @Controller()
192
+ export class UserController {
193
+ @Endpoint(getUserByIdEndpoint)
194
+ async getUserById(params: EndpointParams<typeof getUserByIdEndpoint>) {
195
+ // params is properly typed with full intellisense
196
+ // params.params.id is string (from URL parameter)
197
+ return { id: params.params.id, name: 'John', email: 'john@example.com' }
198
+ }
199
+ }
200
+ ```
201
+
202
+ ## Dependency Injection in Controllers
203
+
204
+ Controllers support full dependency injection:
205
+
206
+ ```typescript
207
+ import { Controller } from '@navios/core'
208
+ import { inject } from '@navios/di'
209
+
210
+ @Controller()
211
+ export class UserController {
212
+ // Inject services
213
+ private userService = inject(UserService)
214
+ private logger = inject(Logger, { context: 'UserController' })
215
+
216
+ @Endpoint(createUserEndpoint)
217
+ async createUser({ body }: { body: CreateUserDto }) {
218
+ this.logger.debug('Creating new user')
219
+ return this.userService.create(body)
220
+ }
221
+ }
222
+ ```
223
+
224
+ ## Error Handling in Controllers
225
+
226
+ Controllers can throw HTTP exceptions that are automatically handled:
227
+
228
+ ```typescript
229
+ import { BadRequestException, NotFoundException } from '@navios/core'
230
+
231
+ @Controller()
232
+ export class UserController {
233
+ private userService = inject(UserService)
234
+
235
+ @Endpoint(getUserByIdEndpoint)
236
+ async getUserById({ params }: { params: { id: string } }) {
237
+ if (!params.id) {
238
+ throw new BadRequestException('User ID is required')
239
+ }
240
+
241
+ const user = await this.userService.findById(params.id)
242
+ if (!user) {
243
+ throw new NotFoundException('User not found')
244
+ }
245
+
246
+ return user
247
+ }
248
+ }
249
+ ```
250
+
251
+ ## Controller Metadata
252
+
253
+ Each controller decorated with `@Controller()` has associated metadata:
254
+
255
+ ```typescript
256
+ export interface ControllerMetadata {
257
+ guards: Set<ClassType>
258
+ attributes: Map<symbol, unknown>
259
+ }
260
+ ```
261
+
262
+ This metadata is used internally by Navios to:
263
+
264
+ - Apply guards to all controller endpoints
265
+ - Store custom attributes
266
+ - Manage controller lifecycle
267
+
268
+ ## Advanced Patterns
269
+
270
+ ### Resource Controllers
271
+
272
+ Create controllers that follow REST conventions using `@navios/builder`:
273
+
274
+ ```typescript
275
+ // api/users.ts
276
+ import { builder } from '@navios/builder'
277
+
278
+ import { z } from 'zod'
279
+
280
+ export const api = builder()
281
+
282
+ const UserSchema = z.object({
283
+ id: z.string(),
284
+ name: z.string(),
285
+ email: z.string(),
286
+ })
287
+
288
+ const CreateUserSchema = z.object({
289
+ name: z.string(),
290
+ email: z.string(),
291
+ })
292
+
293
+ const UpdateUserSchema = CreateUserSchema.partial()
294
+
295
+ export const getAllUsersEndpoint = api.declareEndpoint({
296
+ method: 'GET',
297
+ url: '/users',
298
+ responseSchema: z.array(UserSchema),
299
+ })
300
+
301
+ export const getUserByIdEndpoint = api.declareEndpoint({
302
+ method: 'GET',
303
+ url: '/users/$id',
304
+ responseSchema: UserSchema,
305
+ })
306
+
307
+ export const createUserEndpoint = api.declareEndpoint({
308
+ method: 'POST',
309
+ url: '/users',
310
+ requestSchema: CreateUserSchema,
311
+ responseSchema: UserSchema,
312
+ })
313
+
314
+ export const updateUserEndpoint = api.declareEndpoint({
315
+ method: 'PUT',
316
+ url: '/users/$id',
317
+ requestSchema: UpdateUserSchema,
318
+ responseSchema: UserSchema,
319
+ })
320
+
321
+ export const deleteUserEndpoint = api.declareEndpoint({
322
+ method: 'DELETE',
323
+ url: '/users/$id',
324
+ responseSchema: z.object({ success: z.boolean() }),
325
+ })
326
+ ```
327
+
328
+ ```typescript
329
+ // controllers/user.controller.ts
330
+ import type { EndpointParams } from '@navios/core'
331
+
332
+ import { Controller, Endpoint } from '@navios/core'
333
+ import { inject } from '@navios/di'
334
+
335
+ import {
336
+ createUserEndpoint,
337
+ deleteUserEndpoint,
338
+ getAllUsersEndpoint,
339
+ getUserByIdEndpoint,
340
+ updateUserEndpoint,
341
+ } from '../api/users.js'
342
+
343
+ @Controller()
344
+ export class UserController {
345
+ private userService = inject(UserService)
346
+
347
+ @Endpoint(getAllUsersEndpoint)
348
+ async index(params: EndpointParams<typeof getAllUsersEndpoint>) {
349
+ return this.userService.findAll()
350
+ }
351
+
352
+ @Endpoint(getUserByIdEndpoint)
353
+ async show(params: EndpointParams<typeof getUserByIdEndpoint>) {
354
+ return this.userService.findById(params.params.id)
355
+ }
356
+
357
+ @Endpoint(createUserEndpoint)
358
+ async create(params: EndpointParams<typeof createUserEndpoint>) {
359
+ return this.userService.create(params.data)
360
+ }
361
+
362
+ @Endpoint(updateUserEndpoint)
363
+ async update(params: EndpointParams<typeof updateUserEndpoint>) {
364
+ return this.userService.update(params.params.id, params.data)
365
+ }
366
+
367
+ @Endpoint(deleteUserEndpoint)
368
+ async destroy(params: EndpointParams<typeof deleteUserEndpoint>) {
369
+ await this.userService.delete(params.params.id)
370
+ return { success: true }
371
+ }
372
+ }
373
+ ```