NestJS 11 + Fastify 统一错误体与 trace_id,/health 真实探活 DB/Redis,OpenAPI 3.1 契约含 20 个错误码;shared 包提供错误码、权限点、ULID、分页与通用 schema;worker 完成队列进程骨架。
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import helmet from '@fastify/helmet';
|
|
import { API_PREFIX } from '@lingxi/shared';
|
|
import { NestFactory } from '@nestjs/core';
|
|
import { FastifyAdapter, type NestFastifyApplication } from '@nestjs/platform-fastify';
|
|
import { Logger } from 'nestjs-pino';
|
|
|
|
import { AppModule } from './app.module';
|
|
import { AllExceptionsFilter } from './common/filters/all-exceptions.filter';
|
|
import { APP_CONFIG } from './config/config.module';
|
|
import type { AppConfig } from './config/env';
|
|
import { buildOpenApiDocument, setupOpenApi } from './openapi/document';
|
|
|
|
export interface CreatedApiApp {
|
|
app: NestFastifyApplication;
|
|
config: AppConfig;
|
|
}
|
|
|
|
/** 创建并配置 API 应用(测试与 OpenAPI 导出复用,不负责监听端口) */
|
|
export async function createApp(): Promise<CreatedApiApp> {
|
|
const app = await NestFactory.create<NestFastifyApplication>(
|
|
AppModule,
|
|
new FastifyAdapter({ trustProxy: true, bodyLimit: 1024 * 1024 }),
|
|
{ bufferLogs: true },
|
|
);
|
|
|
|
const config = app.get<AppConfig>(APP_CONFIG);
|
|
app.useLogger(app.get(Logger));
|
|
|
|
app.setGlobalPrefix(API_PREFIX, { exclude: ['health'] });
|
|
app.useGlobalFilters(new AllExceptionsFilter());
|
|
app.enableCors({
|
|
origin: config.webOrigins,
|
|
credentials: true,
|
|
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
|
});
|
|
|
|
// 安全响应头;Swagger UI 需要内联脚本,CSP 在关闭文档页后再开启
|
|
await app.register(helmet, { contentSecurityPolicy: false });
|
|
app.enableShutdownHooks();
|
|
|
|
return { app, config };
|
|
}
|
|
|
|
export { buildOpenApiDocument, setupOpenApi };
|