import { NestFactory } from '@nestjs/core'; import { ConfigService } from '@nestjs/config'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { AppModule } from './app.module'; import { ApiEnvelopeInterceptor } from './common/http/api-envelope.interceptor'; import { AllExceptionsFilter } from './common/http/all-exceptions.filter'; import { HttpRequestLoggingInterceptor } from './common/logging/http-request-logging.interceptor'; import { StructuredLoggerService } from './common/logging/structured-logger.service'; import { EnvConfig } from './config/env.schema'; type RequestWithStartedAt = { startedAt?: number; }; async function bootstrap(): Promise { const app = await NestFactory.create(AppModule, { bufferLogs: true, rawBody: true, }); const config = app.get(ConfigService); const corsOrigin = config.get('CORS_ORIGIN', { infer: true }); const structuredLogger = app.get(StructuredLoggerService); app.use((request: RequestWithStartedAt, _response: unknown, next: () => void) => { request.startedAt = Date.now(); next(); }); app.enableCors({ origin: corsOrigin ? corsOrigin.split(',').map((origin) => origin.trim()) : true, credentials: true, }); app.useGlobalFilters(new AllExceptionsFilter(structuredLogger)); app.useGlobalInterceptors( app.get(HttpRequestLoggingInterceptor), new ApiEnvelopeInterceptor(), ); const swaggerConfig = new DocumentBuilder() .setTitle('运维平台 API') .setDescription('提供 Jenkins、Gitea、通知、发布流程、账号权限和 Agent 运维能力接口。') .setVersion('0.1.0') .build(); const document = SwaggerModule.createDocument(app, swaggerConfig); SwaggerModule.setup('docs', app, document); await app.listen(config.get('PORT', { infer: true })); } void bootstrap();