84 lines
2.5 KiB
TypeScript
84 lines
2.5 KiB
TypeScript
import { NestFactory } from '@nestjs/core';
|
|
import { AppModule } from './app.module';
|
|
import { ValidationPipe, Logger } from '@nestjs/common';
|
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
import * as bodyParser from 'body-parser';
|
|
import { createWinstonLogger } from './common/logger/winston.config';
|
|
|
|
async function bootstrap() {
|
|
const app = await NestFactory.create(AppModule, {
|
|
logger: createWinstonLogger(),
|
|
});
|
|
app.useGlobalPipes(
|
|
new ValidationPipe({
|
|
whitelist: true,
|
|
transform: true,
|
|
forbidNonWhitelisted: true,
|
|
}),
|
|
);
|
|
|
|
app.use(bodyParser.json({ limit: '10mb' }));
|
|
app.use(bodyParser.urlencoded({ limit: '10mb', extended: true }));
|
|
|
|
app.setGlobalPrefix('api');
|
|
|
|
// 使用全局中间件记录请求日志
|
|
const logger = new Logger('HTTP');
|
|
app.use((req, res, next) => {
|
|
const startTime = Date.now();
|
|
|
|
// 捕获响应体
|
|
const originalSend = res.send;
|
|
let responseBody: any;
|
|
res.send = function (body) {
|
|
responseBody = body;
|
|
return originalSend.call(this, body);
|
|
};
|
|
|
|
res.on('finish', () => {
|
|
const duration = Date.now() - startTime;
|
|
const appVersion = req.headers['x-app-version'] || 'unknown';
|
|
const logMessage = `${req.method} ${req.originalUrl} ${res.statusCode} ${duration}ms [v${appVersion}]`;
|
|
|
|
// 解析响应体
|
|
let responseStr = '';
|
|
try {
|
|
if (typeof responseBody === 'string') {
|
|
responseStr = responseBody;
|
|
} else if (responseBody) {
|
|
responseStr = JSON.stringify(responseBody);
|
|
}
|
|
} catch {
|
|
responseStr = '[Unable to stringify response]';
|
|
}
|
|
|
|
if (res.statusCode >= 400) {
|
|
logger.error(`${logMessage} - Body: ${JSON.stringify(req.body)} - Response: ${responseStr}`);
|
|
} else {
|
|
logger.log(`${logMessage} - Body: ${JSON.stringify(req.body)} - Response: ${responseStr}`);
|
|
}
|
|
});
|
|
|
|
next();
|
|
});
|
|
|
|
// swigger
|
|
const config = new DocumentBuilder()
|
|
.setTitle('Pilates API')
|
|
.setDescription('Pilates API description')
|
|
.setVersion('1.0')
|
|
.build();
|
|
const documentFactory = () => SwaggerModule.createDocument(app, config);
|
|
SwaggerModule.setup('api/docs', app, documentFactory);
|
|
|
|
|
|
const port = process.env.PORT ?? 3002;
|
|
await app.listen(port);
|
|
|
|
const appLogger = new Logger('Bootstrap');
|
|
appLogger.log(`Server is running on port ${port}`);
|
|
appLogger.log(`Swagger documentation available at http://localhost:${port}/api/docs`);
|
|
}
|
|
|
|
bootstrap();
|