|
@@ -64,19 +64,23 @@ async function bootstrap() {
|
|
|
const port =
|
|
const port =
|
|
|
configService.get<number>('APP_PORT') ?? Number(process.env.PORT ?? 3300);
|
|
configService.get<number>('APP_PORT') ?? Number(process.env.PORT ?? 3300);
|
|
|
|
|
|
|
|
- const crossOrigin =
|
|
|
|
|
- configService.get<string>('APP_CROSS_ORIGIN') ??
|
|
|
|
|
- configService.get<string>('CROSS_ORIGIN') ??
|
|
|
|
|
- '*';
|
|
|
|
|
|
|
+ const corsOrigin = configService.get<string>('APP_CORS_ORIGIN') ?? '*';
|
|
|
|
|
+ const corsOriginOption =
|
|
|
|
|
+ corsOrigin === '*'
|
|
|
|
|
+ ? true
|
|
|
|
|
+ : corsOrigin
|
|
|
|
|
+ .split(',')
|
|
|
|
|
+ .map((o) => o.trim())
|
|
|
|
|
+ .filter(Boolean);
|
|
|
|
|
|
|
|
app.enableCors({
|
|
app.enableCors({
|
|
|
- origin:
|
|
|
|
|
- crossOrigin === '*' ? true : crossOrigin.split(',').map((o) => o.trim()),
|
|
|
|
|
|
|
+ origin: corsOriginOption,
|
|
|
methods: 'GET,PUT,PATCH,POST,DELETE',
|
|
methods: 'GET,PUT,PATCH,POST,DELETE',
|
|
|
|
|
+ credentials: true,
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
|
- const config = new DocumentBuilder()
|
|
|
|
|
|
|
+ const swaggerConfig = new DocumentBuilder()
|
|
|
.setTitle('盒子管理系统管理后台 API 文档')
|
|
.setTitle('盒子管理系统管理后台 API 文档')
|
|
|
.setDescription('盒子管理系统管理后台接口 (api/v1/mgnt/*)')
|
|
.setDescription('盒子管理系统管理后台接口 (api/v1/mgnt/*)')
|
|
|
.setVersion('1.0')
|
|
.setVersion('1.0')
|
|
@@ -88,14 +92,34 @@ async function bootstrap() {
|
|
|
.addTag('系统 - 菜单', '管理后台菜单管理接口 (mgnt/menus)')
|
|
.addTag('系统 - 菜单', '管理后台菜单管理接口 (mgnt/menus)')
|
|
|
.build();
|
|
.build();
|
|
|
|
|
|
|
|
- const document = SwaggerModule.createDocument(app, config);
|
|
|
|
|
- SwaggerModule.setup('api-docs', app, document, {
|
|
|
|
|
|
|
+ const swaggerDocument = SwaggerModule.createDocument(app, swaggerConfig);
|
|
|
|
|
+
|
|
|
|
|
+ SwaggerModule.setup('api-docs', app, swaggerDocument, {
|
|
|
|
|
+ jsonDocumentUrl: '/api-docs-json',
|
|
|
swaggerOptions: {
|
|
swaggerOptions: {
|
|
|
docExpansion: 'none',
|
|
docExpansion: 'none',
|
|
|
tagsSorter: 'alpha',
|
|
tagsSorter: 'alpha',
|
|
|
operationsSorter: 'alpha',
|
|
operationsSorter: 'alpha',
|
|
|
},
|
|
},
|
|
|
});
|
|
});
|
|
|
|
|
+
|
|
|
|
|
+ // Prevent Swagger UI/JSON from being cached (browser + proxies)
|
|
|
|
|
+ const fastify = app.getHttpAdapter().getInstance();
|
|
|
|
|
+ fastify.addHook('onSend', (request, reply, payload, done) => {
|
|
|
|
|
+ if (
|
|
|
|
|
+ request.url?.startsWith('/api-docs') ||
|
|
|
|
|
+ request.url === '/api-docs-json'
|
|
|
|
|
+ ) {
|
|
|
|
|
+ reply.header(
|
|
|
|
|
+ 'Cache-Control',
|
|
|
|
|
+ 'no-store, no-cache, must-revalidate, proxy-revalidate',
|
|
|
|
|
+ );
|
|
|
|
|
+ reply.header('Pragma', 'no-cache');
|
|
|
|
|
+ reply.header('Expires', '0');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ done(null, payload);
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
await app.listen(port, host);
|
|
await app.listen(port, host);
|
|
@@ -103,6 +127,7 @@ async function bootstrap() {
|
|
|
const url = `http://${host}:${port}`;
|
|
const url = `http://${host}:${port}`;
|
|
|
console.log(`🚀 box-mgnt-api is running at: ${url}`);
|
|
console.log(`🚀 box-mgnt-api is running at: ${url}`);
|
|
|
console.log(`📚 API Documentation: ${url}/api-docs`);
|
|
console.log(`📚 API Documentation: ${url}/api-docs`);
|
|
|
|
|
+ console.log(`📄 Swagger JSON: ${url}/api-docs-json`);
|
|
|
console.log(`🔧 Management APIs: ${url}/api/v1/mgnt/*`);
|
|
console.log(`🔧 Management APIs: ${url}/api/v1/mgnt/*`);
|
|
|
}
|
|
}
|
|
|
|
|
|