import { ClassSerializerInterceptor , HttpStatus , UnprocessableEntityException , ValidationPipe , } from '@nestjs/common' ; import { NestFactory , Reflector } from '@nestjs/core' ; import { Transport } from '@nestjs/microservices' ; import type { NestExpressApplication } from '@nestjs/platform-express' ; import { ExpressAdapter } from '@nestjs/platform-express' ; import compression from 'compression' ; import { middleware as expressCtx } from 'express-ctx' ; import RateLimit from 'express-rate-limit' ; import helmet from 'helmet' ; import morgan from 'morgan' ; import { initializeTransactionalContext , patchTypeORMRepositoryWithBaseRepository , } from 'typeorm-transactional-cls-hooked' ; import { AppModule } from './app.module' ; import { HttpExceptionFilter } from './filters/bad-request.filter' ; import { QueryFailedFilter } from './filters/query-failed.filter' ; import { setupSwagger } from './setup-swagger' ; import { ApiConfigService } from './shared/services/api-config.service' ; import { SharedModule } from './shared/shared.module' ; export async function bootstrap ( ) { initializeTransactionalContext ( ) ; patchTypeORMRepositoryWithBaseRepository ( ) ; const app = await NestFactory . create < NestExpressApplication > ( AppModule , new ExpressAdapter ( ) , { cors : true } ) ; app . enable ( 'trust proxy' ) ; app . use ( helmet ( ) ) ; app . use ( RateLimit ( { windowMs : 15 * 60 * 1000 , max : 100 , } ) ) ; app . use ( compression ( ) ) ; app . use ( morgan ( 'combined' ) ) ; app . enableVersioning ( ) ; const reflector = app . get ( Reflector ) ; app . useGlobalFilters ( new HttpExceptionFilter ( reflector ) , new QueryFailedFilter ( reflector ) ) ; app . useGlobalInterceptors ( new ClassSerializerInterceptor ( reflector ) ) ; app . useGlobalPipes ( new ValidationPipe ( { whitelist : true , errorHttpStatusCode : HttpStatus . UNPROCESSABLE_ENTITY , transform : true , dismissDefaultMessages : true , exceptionFactory : ( errors ) => new UnprocessableEntityException ( errors ) , } ) ) ; const configService = app . select ( SharedModule ) . get ( ApiConfigService ) ; if ( configService . natsEnabled ) { const natsConfig = configService . natsConfig ; app . connectMicroservice ( { transport : Transport . NATS , options : { url : `nats://${ natsConfig . host }:${ natsConfig . port }` , queue : 'main_service' , } , } ) ; await app . startAllMicroservices ( ) ; } if ( configService . documentationEnabled ) { setupSwagger ( app ) ; } app . use ( expressCtx ) ; if ( process . env . NODE_ENV !== 'development' ) { app . enableShutdownHooks ( ) ; } const port = configService . appConfig . port ; await app . listen ( port ) ; console . info ( `server running on port ${ port }` ) ; return app ; } void bootstrap ( ) ;