Spaces:
Sleeping
Sleeping
File size: 2,902 Bytes
57a889c 46a0a8a 57a889c 46a0a8a 57a889c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 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;
}
|