"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fastify_1 = __importDefault(require("fastify")); const cors_1 = __importDefault(require("@fastify/cors")); const multipart_1 = __importDefault(require("@fastify/multipart")); const env_1 = require("./config/env"); const logger_1 = require("./utils/logger"); const videos_routes_1 = require("./modules/media/routes/videos.routes"); const video_streaming_routes_1 = require("./modules/media/routes/video-streaming.routes"); const reactions_routes_1 = require("./modules/media/routes/reactions.routes"); const public_media_routes_1 = require("./modules/media/routes/public-media.routes"); const comments_routes_1 = require("./modules/media/routes/comments.routes"); const upload_routes_1 = require("./modules/media/routes/upload.routes"); const video_actions_routes_1 = require("./modules/media/routes/video-actions.routes"); const video_schedule_routes_1 = require("./modules/media/routes/video-schedule.routes"); const video_tracking_routes_1 = require("./modules/media/routes/video-tracking.routes"); const video_schedule_queue_service_1 = require("./services/video-schedule-queue.service"); // Add BigInt serialization support for Prisma BigInt fields // This converts BigInt values to strings when JSON.stringify() is called BigInt.prototype.toJSON = function () { return this.toString(); }; const fastify = (0, fastify_1.default)({ logger: { level: env_1.env.NODE_ENV === 'production' ? 'info' : 'debug', }, maxParamLength: 500, trustProxy: true, }); // Graceful shutdown handler process.on('SIGTERM', async () => { logger_1.logger.info('SIGTERM received, shutting down gracefully...'); await video_schedule_queue_service_1.videoScheduleQueueService.close(); fastify.close(() => { logger_1.logger.info('Media API server closed'); process.exit(0); }); }); // Global error handlers process.on('unhandledRejection', (reason, promise) => { logger_1.logger.error('Unhandled Promise Rejection in Media API', { reason: JSON.stringify(reason), promise: JSON.stringify(promise) }); }); process.on('uncaughtException', (error) => { logger_1.logger.error('Uncaught Exception in Media API', { error: error instanceof Error ? error.message : JSON.stringify(error) }); fastify.close(() => { process.exit(1); }); }); // Start server const start = async () => { try { // CORS configuration const allowedOrigins = env_1.env.CORS_ORIGINS.split(',').map(o => o.trim()); await fastify.register(cors_1.default, { origin: (origin, cb) => { // Allow requests with no origin (mobile apps, curl, etc.) if (!origin) { cb(null, true); return; } // Check if origin is in allowed list if (allowedOrigins.includes(origin)) { cb(null, true); } else { cb(new Error('CORS not allowed'), false); } }, credentials: true, }); // Multipart support for file uploads (10GB limit) await fastify.register(multipart_1.default, { limits: { fileSize: env_1.env.MAX_UPLOAD_SIZE_GB * 1024 * 1024 * 1024, }, }); // Health check fastify.get('/health', async () => { return { status: 'ok', timestamp: new Date().toISOString(), service: 'media-api' }; }); // Register routes await fastify.register(videos_routes_1.videosRoutes, { prefix: '/api/videos' }); await fastify.register(video_streaming_routes_1.videoStreamingRoutes, { prefix: '/api/videos' }); await fastify.register(upload_routes_1.uploadRoutes, { prefix: '/api/videos' }); await fastify.register(video_actions_routes_1.videoActionsRoutes, { prefix: '/api/videos' }); await fastify.register(video_schedule_routes_1.videoScheduleRoutes, { prefix: '/api/videos' }); await fastify.register(video_tracking_routes_1.videoTrackingRoutes, { prefix: '/api/track' }); await fastify.register(reactions_routes_1.reactionsRoutes, { prefix: '/api/reactions' }); await fastify.register(public_media_routes_1.publicMediaRoutes, { prefix: '/api/media' }); await fastify.register(comments_routes_1.commentsRoutes, { prefix: '/api/media' }); // TODO: Add more routes // await fastify.register(jobsRoutes, { prefix: '/api/jobs' }); const port = env_1.env.MEDIA_API_PORT; const host = '0.0.0.0'; await fastify.listen({ port, host }); logger_1.logger.info(`Media API listening on http://${host}:${port}`); // Start video schedule queue worker video_schedule_queue_service_1.videoScheduleQueueService.startWorker(); logger_1.logger.info('Video schedule queue worker initialized'); if (env_1.env.ENABLE_MEDIA_FEATURES !== 'true') { logger_1.logger.warn('Media features are disabled (ENABLE_MEDIA_FEATURES=false)'); } } catch (err) { logger_1.logger.error('Media API startup error', { error: err instanceof Error ? err.message : JSON.stringify(err) }); process.exit(1); } }; start(); //# sourceMappingURL=media-server.js.map