Spaces:
Sleeping
Sleeping
| import { NestFactory } from '@nestjs/core'; | |
| import { ExpressAdapter } from '@nestjs/platform-express'; | |
| import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; | |
| import type { INestApplication } from '@nestjs/common'; | |
| import { AppModule } from './nest/app.module'; | |
| import { applyGlobalMiddleware } from './middleware/globalMiddleware'; | |
| import { applyPlatformUploads, applyPlatformTransport, applyPlatformStatic } from './nest/platform/platform.routes'; | |
| /** | |
| * Builds the unified TREK NestJS application that serves the ENTIRE surface β the | |
| * former Express app is gone. One builder is shared by the production bootstrap | |
| * (index.ts) and the integration-test harness so the two can never drift. | |
| * | |
| * Composition order is load-bearing. Everything except the SPA index.html fallback | |
| * is registered on the underlying Express instance BEFORE `app.init()`, because | |
| * Nest's router terminates an unmatched request by throwing NotFoundException β it | |
| * does NOT fall through to a route registered after init, so a post-init Express | |
| * route is unreachable. The platform routes are all specific paths (/uploads/*, | |
| * /api/health, /mcp, /.well-known/*, /oauth/{authorize,register,consent}) so they | |
| * match their own requests and `next()` everything else through to the Nest | |
| * controllers registered during init. | |
| * | |
| * 1. applyGlobalMiddleware β helmet/CSP, CORS, HSTS, forced-HTTPS, the global MFA | |
| * policy, request logging + cookie-parser. `bodyParser: false` so Nest does its | |
| * own parsing and the raw /mcp body reaches the MCP handler unparsed. | |
| * 2. applyPlatformUploads β the static + guarded /uploads/* routes. | |
| * 3. applyPlatformTransport β /api/health, the OAuth/MCP SDK + /.well-known | |
| * metadata, the /mcp routes, the /oauth/consent COOP header. | |
| * 4. applyPlatformStatic β the production built-client static assets (so a real | |
| * asset request returns the file before the Nest router 404s it). | |
| * 5. app.init() β registers every migrated /api domain (the Nest controllers). | |
| * | |
| * The SPA index.html fallback (unmatched GET β index.html in production) is the | |
| * SpaFallbackFilter (APP_FILTER in AppModule); the global error envelope is the | |
| * TrekExceptionFilter (also APP_FILTER). | |
| */ | |
| export async function buildApp(): Promise<INestApplication> { | |
| const app = await NestFactory.create(AppModule, new ExpressAdapter()); | |
| const instance = app.getHttpAdapter().getInstance(); | |
| applyGlobalMiddleware(instance, { bodyParser: false }); | |
| applyPlatformUploads(instance); | |
| applyPlatformTransport(instance); | |
| applyPlatformStatic(instance); | |
| const config = new DocumentBuilder() | |
| .setTitle('TREK API') | |
| .setDescription('The TREK API documentation') | |
| .setVersion('1.0') | |
| .build(); | |
| const document = SwaggerModule.createDocument(app, config); | |
| SwaggerModule.setup('api-docs', app, document); | |
| await app.init(); | |
| return app; | |
| } | |