@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.
- 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 +377 -0
- package/docs/quick-start.md +295 -0
- package/docs/services.md +427 -0
- package/docs/testing.md +704 -0
- package/lib/_tsup-dts-rollup.d.mts +310 -239
- package/lib/_tsup-dts-rollup.d.ts +310 -239
- package/lib/index.d.mts +51 -28
- package/lib/index.d.ts +51 -28
- 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 +5 -9
- 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 -2
- 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
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
# Application Setup and Configuration
|
|
2
|
+
|
|
3
|
+
This guide covers how to set up and configure a Navios application, including application creation, module loading, and server configuration.
|
|
4
|
+
|
|
5
|
+
## Creating a Navios Application
|
|
6
|
+
|
|
7
|
+
### Basic Application Setup
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { FastifyAdapter } from '@navios/adapter-fastify'
|
|
11
|
+
import { NaviosFactory } from '@navios/core'
|
|
12
|
+
|
|
13
|
+
import { AppModule } from './app.module'
|
|
14
|
+
|
|
15
|
+
async function bootstrap() {
|
|
16
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
17
|
+
adapter: new FastifyAdapter(),
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
await app.listen(3000)
|
|
21
|
+
console.log('Application is running on http://localhost:3000')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
bootstrap()
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Application with Multiple Adapters
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { BunAdapter } from '@navios/adapter-bun'
|
|
31
|
+
import { FastifyAdapter } from '@navios/adapter-fastify'
|
|
32
|
+
import { NaviosFactory } from '@navios/core'
|
|
33
|
+
|
|
34
|
+
async function bootstrap() {
|
|
35
|
+
const adapters =
|
|
36
|
+
process.env.NODE_ENV === 'production'
|
|
37
|
+
? [new FastifyAdapter()]
|
|
38
|
+
: [new BunAdapter(), new FastifyAdapter()]
|
|
39
|
+
|
|
40
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
41
|
+
adapter: adapters,
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
await app.listen(3000)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
bootstrap()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Application Factory
|
|
51
|
+
|
|
52
|
+
The `NaviosFactory` provides methods to create and configure applications:
|
|
53
|
+
|
|
54
|
+
### `NaviosFactory.create()`
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { NaviosFactory } from '@navios/core'
|
|
58
|
+
|
|
59
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
60
|
+
adapter: new FastifyAdapter(),
|
|
61
|
+
logger: ['error', 'warn', 'log'], // Log levels
|
|
62
|
+
// Additional options
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Factory Options
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
interface NaviosApplicationOptions {
|
|
70
|
+
adapter: NaviosEnvironmentOptions | NaviosEnvironmentOptions[]
|
|
71
|
+
logger?: LoggerService | LogLevel[] | false
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Application Module
|
|
76
|
+
|
|
77
|
+
The root application module serves as the entry point:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { Module } from '@navios/core'
|
|
81
|
+
|
|
82
|
+
import { AuthModule } from './auth/auth.module'
|
|
83
|
+
import { DatabaseModule } from './database/database.module'
|
|
84
|
+
import { UserModule } from './user/user.module'
|
|
85
|
+
|
|
86
|
+
@Module({
|
|
87
|
+
imports: [DatabaseModule, AuthModule, UserModule],
|
|
88
|
+
})
|
|
89
|
+
export class AppModule {}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Application Lifecycle
|
|
93
|
+
|
|
94
|
+
### Application Initialization
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
async function bootstrap() {
|
|
98
|
+
// 1. Create application
|
|
99
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
100
|
+
adapter: new FastifyAdapter(),
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
// 2. Configure middleware, CORS, etc.
|
|
104
|
+
app.enableCors({
|
|
105
|
+
origin: process.env.ALLOWED_ORIGINS?.split(',') || [
|
|
106
|
+
'http://localhost:3000',
|
|
107
|
+
],
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
app.enableMultipart({
|
|
111
|
+
limits: {
|
|
112
|
+
fileSize: 10_000_000, // 10MB
|
|
113
|
+
},
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
// 3. Start listening
|
|
117
|
+
await app.listen(3000)
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Graceful Shutdown
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
async function bootstrap() {
|
|
125
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
126
|
+
adapter: new FastifyAdapter(),
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
await app.listen(3000)
|
|
130
|
+
|
|
131
|
+
// Handle graceful shutdown
|
|
132
|
+
process.on('SIGTERM', async () => {
|
|
133
|
+
console.log('SIGTERM received, shutting down gracefully...')
|
|
134
|
+
await app.close()
|
|
135
|
+
process.exit(0)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
process.on('SIGINT', async () => {
|
|
139
|
+
console.log('SIGINT received, shutting down gracefully...')
|
|
140
|
+
await app.close()
|
|
141
|
+
process.exit(0)
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Environment Configuration
|
|
147
|
+
|
|
148
|
+
### Environment Variables
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
// config/environment.ts
|
|
152
|
+
export const environment = {
|
|
153
|
+
port: parseInt(process.env.PORT || '3000', 10),
|
|
154
|
+
nodeEnv: process.env.NODE_ENV || 'development',
|
|
155
|
+
database: {
|
|
156
|
+
url: process.env.DATABASE_URL || 'postgresql://localhost:5432/navios',
|
|
157
|
+
maxConnections: parseInt(process.env.DB_MAX_CONNECTIONS || '10', 10),
|
|
158
|
+
},
|
|
159
|
+
jwt: {
|
|
160
|
+
secret: process.env.JWT_SECRET || 'super-secret',
|
|
161
|
+
expiresIn: process.env.JWT_EXPIRES_IN || '1h',
|
|
162
|
+
},
|
|
163
|
+
cors: {
|
|
164
|
+
origin: process.env.CORS_ORIGIN?.split(',') || ['http://localhost:3000'],
|
|
165
|
+
},
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Configuration Service
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import { Injectable } from '@navios/core'
|
|
173
|
+
|
|
174
|
+
@Injectable()
|
|
175
|
+
export class ConfigService {
|
|
176
|
+
private config = new Map()
|
|
177
|
+
|
|
178
|
+
constructor() {
|
|
179
|
+
this.loadEnvironmentVariables()
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
get<T>(key: string): T {
|
|
183
|
+
return this.config.get(key)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private loadEnvironmentVariables() {
|
|
187
|
+
this.config.set('PORT', parseInt(process.env.PORT || '3000', 10))
|
|
188
|
+
this.config.set('NODE_ENV', process.env.NODE_ENV || 'development')
|
|
189
|
+
this.config.set('DATABASE_URL', process.env.DATABASE_URL)
|
|
190
|
+
this.config.set('JWT_SECRET', process.env.JWT_SECRET)
|
|
191
|
+
// ... more configuration
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Usage in bootstrap
|
|
196
|
+
async function bootstrap() {
|
|
197
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
198
|
+
adapter: new FastifyAdapter(),
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
const configService = app.getContainer().get(ConfigService)
|
|
202
|
+
const port = configService.get<number>('PORT')
|
|
203
|
+
|
|
204
|
+
await app.listen(port)
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## CORS Configuration
|
|
209
|
+
|
|
210
|
+
Enable Cross-Origin Resource Sharing:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
async function bootstrap() {
|
|
214
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
215
|
+
adapter: new FastifyAdapter(),
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
// Basic CORS
|
|
219
|
+
app.enableCors()
|
|
220
|
+
|
|
221
|
+
// Advanced CORS configuration
|
|
222
|
+
app.enableCors({
|
|
223
|
+
origin: ['http://localhost:3000', 'https://yourdomain.com'],
|
|
224
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
225
|
+
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
226
|
+
credentials: true,
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
await app.listen(3000)
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Multipart/File Upload Configuration
|
|
234
|
+
|
|
235
|
+
Enable file upload support:
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
async function bootstrap() {
|
|
239
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
240
|
+
adapter: new FastifyAdapter(),
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
app.enableMultipart({
|
|
244
|
+
limits: {
|
|
245
|
+
fieldNameSize: 100, // Max field name size in bytes
|
|
246
|
+
fieldSize: 100, // Max field value size in bytes
|
|
247
|
+
fields: 10, // Max number of non-file fields
|
|
248
|
+
fileSize: 10_000_000, // Max file size in bytes (10MB)
|
|
249
|
+
files: 5, // Max number of file fields
|
|
250
|
+
headerPairs: 2000, // Max number of header key=>value pairs
|
|
251
|
+
},
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
await app.listen(3000)
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Logging Configuration
|
|
259
|
+
|
|
260
|
+
### Custom Logger
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
import { LoggerService, LogLevel } from '@navios/core'
|
|
264
|
+
|
|
265
|
+
class CustomLogger implements LoggerService {
|
|
266
|
+
log(message: string, context?: string) {
|
|
267
|
+
console.log(`[${context}] ${message}`)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
error(message: string, trace?: string, context?: string) {
|
|
271
|
+
console.error(`[${context}] ERROR: ${message}`, trace)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
warn(message: string, context?: string) {
|
|
275
|
+
console.warn(`[${context}] WARN: ${message}`)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
debug(message: string, context?: string) {
|
|
279
|
+
if (process.env.DEBUG) {
|
|
280
|
+
console.debug(`[${context}] DEBUG: ${message}`)
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
verbose(message: string, context?: string) {
|
|
285
|
+
if (process.env.VERBOSE) {
|
|
286
|
+
console.log(`[${context}] VERBOSE: ${message}`)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Use custom logger
|
|
292
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
293
|
+
adapter: new FastifyAdapter(),
|
|
294
|
+
logger: new CustomLogger(),
|
|
295
|
+
})
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Log Levels
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
302
|
+
adapter: new FastifyAdapter(),
|
|
303
|
+
logger: ['error', 'warn', 'log'], // Only these levels will be logged
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
// Or disable logging
|
|
307
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
308
|
+
adapter: new FastifyAdapter(),
|
|
309
|
+
logger: false,
|
|
310
|
+
})
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Database Integration
|
|
314
|
+
|
|
315
|
+
### Database Module
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
import { Injectable, Module } from '@navios/core'
|
|
319
|
+
|
|
320
|
+
import { PrismaClient } from '@prisma/client'
|
|
321
|
+
|
|
322
|
+
@Injectable()
|
|
323
|
+
export class DatabaseService extends PrismaClient {
|
|
324
|
+
constructor() {
|
|
325
|
+
super({
|
|
326
|
+
datasources: {
|
|
327
|
+
db: {
|
|
328
|
+
url: process.env.DATABASE_URL,
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async onModuleInit() {
|
|
335
|
+
await this.$connect()
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async onModuleDestroy() {
|
|
339
|
+
await this.$disconnect()
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
@Module({
|
|
344
|
+
providers: [DatabaseService],
|
|
345
|
+
exports: [DatabaseService],
|
|
346
|
+
})
|
|
347
|
+
export class DatabaseModule {}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Health Checks
|
|
351
|
+
|
|
352
|
+
Add health check endpoints using `@navios/builder`:
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
// api/health.ts
|
|
356
|
+
import { builder } from '@navios/builder'
|
|
357
|
+
|
|
358
|
+
import { z } from 'zod'
|
|
359
|
+
|
|
360
|
+
export const api = builder()
|
|
361
|
+
|
|
362
|
+
export const healthEndpoint = api.declareEndpoint({
|
|
363
|
+
method: 'GET',
|
|
364
|
+
url: '/health',
|
|
365
|
+
responseSchema: z.object({
|
|
366
|
+
status: z.string(),
|
|
367
|
+
timestamp: z.string(),
|
|
368
|
+
uptime: z.number(),
|
|
369
|
+
}),
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
export const readinessEndpoint = api.declareEndpoint({
|
|
373
|
+
method: 'GET',
|
|
374
|
+
url: '/health/ready',
|
|
375
|
+
responseSchema: z.object({
|
|
376
|
+
ready: z.boolean(),
|
|
377
|
+
checks: z.record(z.string(), z.boolean()),
|
|
378
|
+
}),
|
|
379
|
+
})
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
import type { EndpointParams } from '@navios/core'
|
|
384
|
+
|
|
385
|
+
import { Controller, Endpoint } from '@navios/core'
|
|
386
|
+
|
|
387
|
+
import { healthEndpoint, readinessEndpoint } from '../api/health.js'
|
|
388
|
+
|
|
389
|
+
// controllers/health.controller.ts
|
|
390
|
+
|
|
391
|
+
@Controller()
|
|
392
|
+
export class HealthController {
|
|
393
|
+
@Endpoint(healthEndpoint)
|
|
394
|
+
async getHealth(params: EndpointParams<typeof healthEndpoint>) {
|
|
395
|
+
return {
|
|
396
|
+
status: 'ok',
|
|
397
|
+
timestamp: new Date().toISOString(),
|
|
398
|
+
uptime: process.uptime(),
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
@Endpoint(readinessEndpoint)
|
|
403
|
+
async getReadiness(params: EndpointParams<typeof readinessEndpoint>) {
|
|
404
|
+
// Check database connectivity, external services, etc.
|
|
405
|
+
try {
|
|
406
|
+
await this.databaseService.isConnected()
|
|
407
|
+
return { status: 'ready' }
|
|
408
|
+
} catch (error) {
|
|
409
|
+
throw new InternalServerErrorException('Service not ready')
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Production Configuration
|
|
416
|
+
|
|
417
|
+
### Production Bootstrap
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
import { defineFastifyEnvironment } from '@navios/adapter-fastify'
|
|
421
|
+
import { NaviosFactory } from '@navios/core'
|
|
422
|
+
|
|
423
|
+
import { AppModule } from './app.module'
|
|
424
|
+
|
|
425
|
+
async function bootstrap() {
|
|
426
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
427
|
+
adapter: defineFastifyEnvironment({
|
|
428
|
+
logger: process.env.NODE_ENV === 'production',
|
|
429
|
+
trustProxy: true,
|
|
430
|
+
}),
|
|
431
|
+
logger:
|
|
432
|
+
process.env.NODE_ENV === 'production'
|
|
433
|
+
? ['error', 'warn', 'log']
|
|
434
|
+
: ['error', 'warn', 'log', 'debug', 'verbose'],
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
// Production middleware
|
|
438
|
+
if (process.env.NODE_ENV === 'production') {
|
|
439
|
+
app.enableCors({
|
|
440
|
+
origin: process.env.ALLOWED_ORIGINS?.split(','),
|
|
441
|
+
credentials: true,
|
|
442
|
+
})
|
|
443
|
+
} else {
|
|
444
|
+
app.enableCors() // Allow all origins in development
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const port = process.env.PORT || 3000
|
|
448
|
+
await app.listen({
|
|
449
|
+
port: parseInt(port, 10),
|
|
450
|
+
host: '0.0.0.0',
|
|
451
|
+
})
|
|
452
|
+
|
|
453
|
+
console.log(`🚀 Application is running on port ${port}`)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
bootstrap().catch((error) => {
|
|
457
|
+
console.error('Failed to start application:', error)
|
|
458
|
+
process.exit(1)
|
|
459
|
+
})
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### Docker Configuration
|
|
463
|
+
|
|
464
|
+
```dockerfile
|
|
465
|
+
FROM node:18-alpine
|
|
466
|
+
|
|
467
|
+
WORKDIR /app
|
|
468
|
+
|
|
469
|
+
COPY package*.json ./
|
|
470
|
+
RUN npm ci --only=production
|
|
471
|
+
|
|
472
|
+
COPY . .
|
|
473
|
+
RUN npm run build
|
|
474
|
+
|
|
475
|
+
EXPOSE 3000
|
|
476
|
+
|
|
477
|
+
USER node
|
|
478
|
+
|
|
479
|
+
CMD ["node", "dist/main.js"]
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Environment Variables for Production
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
# .env.production
|
|
486
|
+
NODE_ENV=production
|
|
487
|
+
PORT=3000
|
|
488
|
+
DATABASE_URL=postgresql://user:password@db:5432/navios_prod
|
|
489
|
+
LOG_LEVEL=error,warn,log
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## Testing Configuration
|
|
493
|
+
|
|
494
|
+
### Test Application Setup
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
import { Test } from '@navios/testing'
|
|
498
|
+
|
|
499
|
+
import { AppModule } from '../src/app.module'
|
|
500
|
+
|
|
501
|
+
describe('Application', () => {
|
|
502
|
+
let app: any
|
|
503
|
+
|
|
504
|
+
beforeAll(async () => {
|
|
505
|
+
const moduleRef = await Test.createTestingModule({
|
|
506
|
+
imports: [AppModule],
|
|
507
|
+
})
|
|
508
|
+
.overrideProvider(DatabaseService)
|
|
509
|
+
.useValue(mockDatabaseService)
|
|
510
|
+
.compile()
|
|
511
|
+
|
|
512
|
+
app = moduleRef.createNaviosApplication()
|
|
513
|
+
await app.init()
|
|
514
|
+
})
|
|
515
|
+
|
|
516
|
+
afterAll(async () => {
|
|
517
|
+
await app.close()
|
|
518
|
+
})
|
|
519
|
+
|
|
520
|
+
it('should be defined', () => {
|
|
521
|
+
expect(app).toBeDefined()
|
|
522
|
+
})
|
|
523
|
+
})
|
|
524
|
+
```
|