Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | #!/usr/bin/env node import * as dotenv from 'dotenv'; dotenv.config(); // IMPORTANT: Initialize tracing BEFORE any other imports, especially NestFactory. import { initTracing } from './tracing'; import { Agent, setGlobalDispatcher } from 'undici'; import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { AllExceptionsFilter } from './http-exception.filter'; import { ValidationPipe } from '@nestjs/common'; import { SeedingService } from './seeding/seeding.service'; import { TimeoutInterceptor } from './timeout.interceptor'; import { json, urlencoded } from 'express'; import { AppService } from './app.service'; import * as net from 'net'; import { WsAdapter } from '@nestjs/platform-ws'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; function isPortInUse(port: number): Promise<boolean> { return new Promise((resolve) => { const server = net.createServer(); server.once('error', (err: any) => { Iif (err.code === 'EADDRINUSE') { resolve(true); } }); server.once('listening', () => { server.close(() => { resolve(false); }); }); server.listen(port); }); } async function findAvailablePort(startPort: number): Promise<number> { let port = startPort; while (await isPortInUse(port)) { port++; } return port; } async function bootstrap() { // Start tracing before anything else await initTracing(); // Override global undici dispatcher to increase fetch timeouts for LLM API calls setGlobalDispatcher( new Agent({ headersTimeout: 1_200_000, // 20 min — time to receive response headers bodyTimeout: 1_200_000, // 20 min — time to receive full response body connect: { timeout: 60_000 }, // 60s — TCP connect timeout }), ); Iif (process.env.REPOBURG_PROJECT_PATH) { try { process.chdir(process.env.REPOBURG_PROJECT_PATH); } catch (err) { console.error( `[FATAL] Could not change directory to specified path: ${process.env.REPOBURG_PROJECT_PATH}`, ); console.error(err); process.exit(1); } } const app = await NestFactory.create(AppModule); app.useWebSocketAdapter(new WsAdapter(app)); app.use(json({ limit: '50mb' })); app.use(urlencoded({ extended: true, limit: '50mb' })); const seeder = app.get(SeedingService); await seeder.seed(); // Enable CORS app.enableCors({ origin: '*', // Allow all methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', credentials: true, }); // Apply global interceptor for request timeouts app.useGlobalInterceptors(new TimeoutInterceptor()); // Apply global filter for consistent error responses app.useGlobalFilters(new AllExceptionsFilter()); // Apply global validation pipe to ensure all endpoints are protected app.useGlobalPipes( new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true, }), ); const preferredPort = process.env.PORT ? parseInt(process.env.PORT, 10) : 3000; const port = await findAvailablePort(preferredPort); const appService = app.get(AppService); appService.setPort(port); // Setup Swagger/OpenAPI const config = new DocumentBuilder() .setTitle('Repoburg API') .setDescription('API documentation for Repoburg backend') .setVersion('1.0') .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('docs/openapi', app, document); await app.listen(port); console.log(`Application is running on: ${await app.getUrl()}`); console.log(`Repoburg backend serving project from: ${process.cwd()}`); console.log(`Open in browser: http://localhost:3001?bport=${port}`); console.log(`API Docs: http://localhost:${port}/docs/openapi`); } bootstrap(); |