import { NestFactory } from '@nestjs/core'; import { ValidationPipe } from '@nestjs/common'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; import { NestExpressApplication } from '@nestjs/platform-express'; import { AppModule } from './app.module'; import { GlobalExceptionFilter } from './shared/common/filters'; import { getUploadRoot } from './shared/uploads/upload-paths'; function envFlag(name: string) { return ['1', 'true', 'yes', 'on'].includes((process.env[name] ?? '').toLowerCase()); } function resolveCorsOrigin() { const raw = process.env.CORS_ORIGINS?.trim(); if (raw) { return raw .split(',') .map((origin) => origin.trim()) .filter(Boolean); } return process.env.NODE_ENV === 'production' ? false : true; } async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableShutdownHooks(); app.useGlobalFilters(new GlobalExceptionFilter()); app.useStaticAssets(getUploadRoot(), { prefix: '/uploads/' }); app.setGlobalPrefix('api'); app.enableCors({ origin: resolveCorsOrigin(), credentials: true }); app.useGlobalPipes( new ValidationPipe({ whitelist: true, transform: true, forbidNonWhitelisted: true, }), ); const swaggerEnabled = process.env.NODE_ENV !== 'production' || envFlag('ENABLE_SWAGGER'); if (swaggerEnabled) { const config = new DocumentBuilder() .setTitle('TheBet365 API') .setDescription('足球投注平台 MVP API') .setVersion('1.0') .addBearerAuth() .build(); SwaggerModule.setup('api/docs', app, SwaggerModule.createDocument(app, config)); } const port = process.env.PORT || 3000; await app.listen(port); console.log(`API running on http://localhost:${port}`); if (swaggerEnabled) { console.log(`Swagger docs: http://localhost:${port}/api/docs`); } } bootstrap();