import { NestFactory } from '@nestjs/core'; import { ValidationPipe } from '@nestjs/common'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; import { ConfigService } from '@nestjs/config'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); const configService = app.get(ConfigService); // Global prefix app.setGlobalPrefix('api'); // Validation app.useGlobalPipes( new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true, transformOptions: { enableImplicitConversion: true, }, }), ); // CORS const nodeEnv = configService.get('NODE_ENV', 'development'); app.enableCors({ origin: (origin, callback) => { // Allow requests with no origin (mobile apps, curl, etc.) if (!origin) return callback(null, true); // In development, allow all localhost origins if (nodeEnv === 'development' && /^https?:\/\/localhost(:\d+)?$/.test(origin)) { return callback(null, true); } // Check against configured origins const corsOrigins = configService.get('CORS_ORIGINS', 'http://localhost:3000,http://localhost:5173'); if (corsOrigins.split(',').includes(origin)) { return callback(null, true); } callback(new Error('Not allowed by CORS')); }, credentials: true, }); // Swagger API Documentation const config = new DocumentBuilder() .setTitle('Dimension47 API') .setDescription('TTRPG Campaign Management Platform API') .setVersion('1.0') .addBearerAuth() .addTag('Auth', 'Authentication endpoints') .addTag('Campaigns', 'Campaign management') .addTag('Characters', 'Character management') .addTag('Battle', 'Battle screen and combat') .addTag('Documents', 'Document management') .addTag('Library', 'Combatants and maps library') .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('api/docs', app, document); // Start server const port = configService.get('PORT', 5000); await app.listen(port); console.log(`🚀 Dimension47 Server running on http://localhost:${port}`); console.log(`📚 API Documentation: http://localhost:${port}/api/docs`); } bootstrap();