import { NestFactory } from '@nestjs/core'; import { Logger, ValidationPipe } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import helmet from 'helmet'; import compression from 'compression'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule, { bufferLogs: true, }); const logger = new Logger('Bootstrap'); app.useLogger(logger); const configService = app.get(ConfigService); const host = configService.get('APP_HOST') ?? configService.get('HOST') ?? '0.0.0.0'; const port = configService.get('APP_PORT') ?? Number(process.env.PORT ?? 3301); const crossOrigin = configService.get('APP_CROSS_ORIGIN') ?? configService.get('CROSS_ORIGIN') ?? '*'; app.enableCors({ origin: crossOrigin === '*' ? true : crossOrigin.split(',').map((o) => o.trim()), methods: 'GET,PUT,PATCH,POST,DELETE', }); // 👇 Important: this makes /health become /api/v1/health app.setGlobalPrefix('api/v1', { exclude: ['/'], }); app.use(helmet()); app.use(compression()); app.enableCors({ origin: true, credentials: true, }); app.useGlobalPipes( new ValidationPipe({ whitelist: true, transform: true, transformOptions: { enableImplicitConversion: true, }, forbidNonWhitelisted: false, }), ); await app.listen(port, host); const url = `http://${host}:${port}`; logger.log(`🚀 box-app-api listening on ${url} (global prefix: /api/v1)`); } bootstrap().catch((error) => { // eslint-disable-next-line no-console console.error('❌ Failed to bootstrap box-app-api', error); process.exit(1); });