Files
ai/backend/src/main.ts
T
2026-06-15 17:45:28 +08:00

92 lines
2.7 KiB
TypeScript

import 'reflect-metadata';
import './config/load-env';
import type { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
import type { INestApplication } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { json, urlencoded } from 'express';
import { AppModule } from './app.module';
type ExpressLikeApp = {
set?: (key: string, value: boolean | number | string) => void;
};
function isProduction() {
return process.env.NODE_ENV === 'production';
}
function parseBoolean(value: string | undefined, fallback: boolean) {
if (value === undefined) return fallback;
const normalized = value.trim().toLowerCase();
if (['1', 'true', 'yes', 'on'].includes(normalized)) return true;
if (['0', 'false', 'no', 'off'].includes(normalized)) return false;
return fallback;
}
function parseCommaList(value: string | undefined) {
return (value ?? '')
.split(',')
.map((item) => item.trim())
.filter(Boolean);
}
function createCorsOptions(): CorsOptions {
const allowedOrigins = parseCommaList(process.env.CORS_ORIGINS);
return {
origin:
allowedOrigins.length > 0
? (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
return;
}
callback(new Error('Origin is not allowed by CORS'), false);
}
: !isProduction(),
methods: ['GET', 'POST', 'PATCH', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: [
'authorization',
'content-type',
'x-request-id',
'x-api-encrypted',
'x-api-session-id',
'x-api-client-public-key'
],
exposedHeaders: ['content-disposition', 'x-request-id', 'x-api-encrypted'],
maxAge: 86400
};
}
function configureTrustProxy(app: INestApplication) {
const express = app.getHttpAdapter().getInstance() as ExpressLikeApp;
const shouldTrustProxy = parseBoolean(process.env.TRUST_PROXY, isProduction());
express.set?.('trust proxy', shouldTrustProxy);
}
function requestBodyLimit() {
return process.env.REQUEST_BODY_LIMIT || process.env.MAX_REQUEST_BODY_SIZE || '160mb';
}
async function bootstrap() {
const app = await NestFactory.create(AppModule, { bodyParser: false });
const bodyLimit = requestBodyLimit();
app.use(json({ limit: bodyLimit }));
app.use(urlencoded({ limit: bodyLimit, extended: true }));
configureTrustProxy(app);
app.enableCors(createCorsOptions());
app.setGlobalPrefix('api');
const port = Number(process.env.PORT ?? 3000);
await app.listen(port, '0.0.0.0');
// eslint-disable-next-line no-console
console.log(`Backend API listening on http://127.0.0.1:${port}/api`);
}
void bootstrap();