Initial AI manga platform
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
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();
|
||||
Reference in New Issue
Block a user