import 'reflect-metadata'; import { ValidationPipe } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { AppModule } from './app.module.js'; import { createRequestContextMiddleware } from './common/request-context.middleware.js'; import { MetricsService } from './common/metrics.service.js'; function requireEnv(name: string): string { const value = process.env[name]; if (!value || value.trim() === '') { throw new Error(`Missing required env: ${name}`); } return value; } function validateEnv(): void { requireEnv('FABRIC_BACKEND_CENTER_DB_HOST'); requireEnv('FABRIC_BACKEND_CENTER_DB_PORT'); requireEnv('FABRIC_BACKEND_CENTER_DB_USER'); requireEnv('FABRIC_BACKEND_CENTER_DB_PASSWORD'); requireEnv('FABRIC_BACKEND_CENTER_DB_NAME'); requireEnv('FABRIC_BACKEND_CENTER_JWT_ACCESS_SECRET'); requireEnv('FABRIC_BACKEND_CENTER_JWT_REFRESH_SECRET'); } async function bootstrap() { validateEnv(); const app = await NestFactory.create(AppModule); const corsOrigins = (process.env.FABRIC_BACKEND_CENTER_CORS_ORIGINS ?? '') .split(',') .map((x) => x.trim()) .filter(Boolean); app.enableCors({ origin: (origin, callback) => { // no Origin header: curl/server-to-server/most desktop local calls if (!origin) return callback(null, true); // desktop/electron local file origin if (origin === 'null') return callback(null, true); // empty allowlist => allow all origins if (!corsOrigins.length) return callback(null, true); if (corsOrigins.includes(origin)) return callback(null, true); return callback(new Error('CORS origin not allowed'), false); }, methods: ['GET', 'POST', 'PATCH', 'PUT', 'DELETE', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization', 'x-client-name', 'x-request-id', 'x-api-key'], credentials: false, }); app.setGlobalPrefix('api'); const metrics = app.get(MetricsService); app.use(createRequestContextMiddleware('center', metrics)); app.useGlobalPipes( new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true, }), ); const swaggerConfig = new DocumentBuilder() .setTitle('Fabric Backend Center API') .setDescription('Identity Hub APIs for Fabric') .setVersion('1.0.0') .build(); const swaggerDoc = SwaggerModule.createDocument(app, swaggerConfig); SwaggerModule.setup('docs', app, swaggerDoc); const port = process.env.FABRIC_BACKEND_CENTER_PORT ? Number(process.env.FABRIC_BACKEND_CENTER_PORT) : 7001; await app.listen(port); console.log(`Fabric.Backend.Center listening on :${port}`); } void bootstrap();