Files
lingxi/apps/api/src/bootstrap.ts
T
Stev_Wang 23067edb8f feat(api): 搭建 API 与 Worker 骨架及契约基线
NestJS 11 + Fastify 统一错误体与 trace_id,/health 真实探活 DB/Redis,OpenAPI 3.1 契约含 20 个错误码;shared 包提供错误码、权限点、ULID、分页与通用 schema;worker 完成队列进程骨架。
2026-11-02 17:20:46 +08:00

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 };