92 lines
2.7 KiB
TypeScript
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();
|