#!/usr/bin/env node import { config } from 'dotenv'; import { existsSync } from 'node:fs'; import { resolve, join } from 'node:path'; import { homedir } from 'node:os'; // Load .env from daemon config dir (global install / daemon mode). // Loaded first so monorepo .env can override for local dev. const daemonEnv = join(homedir(), '.config', 'mosaic', 'gateway', '.env'); if (existsSync(daemonEnv)) config({ path: daemonEnv }); // Load .env from monorepo root (cwd is apps/gateway when run via pnpm filter) config({ path: resolve(process.cwd(), '../../.env') }); config(); // Also load apps/gateway/.env if present (overrides) import './tracing.js'; import 'reflect-metadata'; import { NestFactory } from '@nestjs/core'; import { Logger, ValidationPipe } from '@nestjs/common'; import { FastifyAdapter, type NestFastifyApplication } from '@nestjs/platform-fastify'; import helmet from '@fastify/helmet'; import { listSsoStartupWarnings } from '@mosaicstack/auth'; import { AppModule } from './app.module.js'; import { mountAuthHandler } from './auth/auth.controller.js'; import { mountMcpHandler } from './mcp/mcp.controller.js'; import { McpService } from './mcp/mcp.service.js'; async function bootstrap(): Promise { const logger = new Logger('Bootstrap'); if (!process.env['BETTER_AUTH_SECRET']) { throw new Error('BETTER_AUTH_SECRET is required'); } for (const warning of listSsoStartupWarnings()) { logger.warn(warning); } const app = await NestFactory.create( AppModule, new FastifyAdapter({ bodyLimit: 1_048_576 }), ); app.enableCors({ origin: process.env['GATEWAY_CORS_ORIGIN'] ?? 'http://localhost:3000', credentials: true, methods: ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], }); await app.register(helmet as never, { contentSecurityPolicy: false }); app.useGlobalPipes( new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true, }), ); mountAuthHandler(app); mountMcpHandler(app, app.get(McpService)); const port = Number(process.env['GATEWAY_PORT'] ?? 14242); await app.listen(port, '0.0.0.0'); logger.log(`Gateway listening on port ${port}`); } bootstrap().catch((err: unknown) => { const logger = new Logger('Bootstrap'); logger.error('Fatal startup error', err instanceof Error ? err.stack : String(err)); process.exit(1); });