import { NestFactory } from '@nestjs/core'; import { RequestMethod, ValidationPipe } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { NestExpressApplication } from '@nestjs/platform-express'; import { AppModule } from './app.module'; import { ensureUploadsDirs, UPLOADS_ROOT } from './uploads/uploads.util'; async function bootstrap() { const app = await NestFactory.create(AppModule); const config = app.get(ConfigService); ensureUploadsDirs(); app.useStaticAssets(UPLOADS_ROOT, { prefix: '/uploads/' }); app.setGlobalPrefix('api', { exclude: [ { path: 'get_user', method: RequestMethod.GET }, { path: 'get_version', method: RequestMethod.GET }, { path: 'uploads/(.*)', method: RequestMethod.GET }, ], }); const corsOriginRaw = config.get( 'CORS_ORIGIN', 'http://localhost:5173,http://localhost:3100', ); const corsOrigins = corsOriginRaw .split(',') .map((item) => item.trim()) .filter(Boolean); const isDev = (config.get('NODE_ENV') ?? process.env.NODE_ENV) !== 'production'; app.enableCors({ origin: ( origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void, ) => { if (!origin) { callback(null, true); return; } if (corsOrigins.includes('*') || corsOrigins.includes(origin)) { callback(null, true); return; } // Sold versions (Hamkar/Khanegi) call public /get_user cross-origin over HTTPS. if (/^https:\/\/[a-z0-9.-]+(?::\d+)?$/i.test(origin)) { callback(null, true); return; } // Vite روی LAN (مثلاً 172.x / 192.168.x) در توسعه if ( isDev && /^http:\/\/(localhost|127\.0\.0\.1|192\.168\.\d+\.\d+|172\.\d+\.\d+\.\d+|10\.\d+\.\d+\.\d+):\d+$/.test( origin, ) ) { callback(null, true); return; } callback(null, false); }, credentials: true, }); app.useGlobalPipes( new ValidationPipe({ whitelist: true, transform: true, forbidNonWhitelisted: true, }), ); const port = Number(config.get('PORT') ?? 3001); await app.listen(port); console.log(`SuperAdmin API listening on http://localhost:${port}`); } bootstrap();