import 'reflect-metadata'; import { NestFactory } from '@nestjs/core'; import cookieParser from 'cookie-parser'; import { json, urlencoded } from 'express'; import session from 'express-session'; import { AppModule } from './app.module.js'; import { AuthService } from './auth/auth.service.js'; import { ApiExceptionFilter } from './common/api-exception.filter.js'; import { PrismaService } from './prisma/prisma.service.js'; import { PrismaSessionStore } from './session/prisma-session.store.js'; import { attachSpeechProxy } from './speech/speech.gateway.js'; import { SpeechService } from './speech/speech.service.js'; const bootstrap = async () => { const app = await NestFactory.create(AppModule, { bodyParser: false }); const port = Number(process.env.API_PORT ?? 3100); const bodyLimit = process.env.API_BODY_LIMIT ?? '100mb'; app.setGlobalPrefix('api'); app.use(json({ limit: bodyLimit })); app.use(urlencoded({ extended: true, limit: bodyLimit })); app.useGlobalFilters(new ApiExceptionFilter()); app.enableCors({ origin: process.env.CORS_ORIGIN?.split(',') ?? ['http://localhost:3001', 'http://localhost:4002'], credentials: true, }); app.use(cookieParser()); const sessionMiddleware = session({ name: 'surclaw.sid', secret: process.env.SESSION_SECRET ?? 'dev-only-session-secret-change-me', store: new PrismaSessionStore(app.get(PrismaService)), resave: false, saveUninitialized: false, cookie: { httpOnly: true, sameSite: 'lax', secure: process.env.SESSION_COOKIE_SECURE === 'true', maxAge: 1000 * 60 * 60 * 8, }, }); app.use(sessionMiddleware); await app.listen(port, '0.0.0.0'); attachSpeechProxy( app.getHttpServer(), sessionMiddleware, app.get(AuthService), app.get(SpeechService), ); }; void bootstrap();