import { NestFactory } from '@nestjs/core'; import { ConfigService } from '@nestjs/config'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; import { AppModule } from './app.module'; import { HttpExceptionFilter } from './common/filters/http-exception.filter'; import { TransformInterceptor } from './common/interceptors/transform.interceptor'; import { LoggingInterceptor } from './common/interceptors/logging.interceptor'; import { ValidationPipe } from './common/pipes/validation.pipe'; import compression from 'compression'; async function bootstrap() { const app = await NestFactory.create(AppModule, { logger: process.env.NODE_ENV === 'production' ? ['error', 'warn', 'log'] : ['error', 'warn', 'log', 'debug', 'verbose'], }); const configService = app.get(ConfigService); const isProduction = configService.get('app.isProduction', false); // 启用压缩 if (configService.get('performance.enableCompression', true)) { app.use(compression()); } // 设置全局前缀 const apiPrefix = configService.get('app.apiPrefix', 'api'); app.setGlobalPrefix(apiPrefix); // 启用 CORS const corsOrigin = configService.get('performance.corsOrigin', '*'); app.enableCors({ origin: (origin, callback) => { // 开发环境允许所有来源 if (!isProduction) { callback(null, true); return; } // 生产环境使用配置的来源 if (!origin || corsOrigin === '*') { callback(null, true); } else { const allowedOrigins = corsOrigin.split(','); if (allowedOrigins.includes(origin)) { callback(null, true); } else { callback(new Error('Not allowed by CORS')); } } }, credentials: true, methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'], allowedHeaders: [ 'Content-Type', 'Authorization', 'Accept', 'X-Requested-With', 'Origin', 'Access-Control-Request-Method', 'Access-Control-Request-Headers', ], exposedHeaders: ['Content-Range', 'X-Content-Range'], preflightContinue: false, optionsSuccessStatus: 204, maxAge: 86400, }); // 全局过滤器、拦截器、管道 app.useGlobalFilters(new HttpExceptionFilter()); app.useGlobalInterceptors( new LoggingInterceptor(), new TransformInterceptor(), ); app.useGlobalPipes(new ValidationPipe()); // Swagger 文档(仅在开发环境) if (!isProduction) { const config = new DocumentBuilder() .setTitle('GameGroup API') .setDescription('GameGroup 游戏小组管理系统 API 文档') .setVersion('1.0') .addBearerAuth() .addTag('auth', '认证相关') .addTag('users', '用户管理') .addTag('groups', '小组管理') .addTag('games', '游戏库') .addTag('appointments', '预约管理') .addTag('ledgers', '账目管理') .addTag('schedules', '排班管理') .addTag('blacklist', '黑名单') .addTag('honors', '荣誉墙') .addTag('assets', '资产管理') .addTag('points', '积分系统') .addTag('bets', '竞猜系统') .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('docs', app, document); } const port = configService.get('app.port', 3000); await app.listen(port); const environment = configService.get('app.environment', 'development'); console.log(`🚀 Application is running on: http://localhost:${port}/${apiPrefix}`); console.log(`🌍 Environment: ${environment}`); if (!isProduction) { console.log(`📚 Swagger documentation: http://localhost:${port}/docs`); } } bootstrap();