import { fileURLToPath } from "node:url"; import { loadConfig, validateConfig } from "./config.js"; import { createApp } from "./app.js"; import { InMemoryMediaStore } from "./services/mediaStore.js"; import { createAudioConversionService } from "./services/audioConversionService.js"; import { createRequestNormalizationService } from "./services/requestNormalizationService.js"; import { createResponseNormalizationService } from "./services/responseNormalizationService.js"; import { createOpenAiService } from "./services/openAiService.js"; import { createChatController } from "./controllers/chatController.js"; import { createMediaController } from "./controllers/mediaController.js"; const config = loadConfig(); validateConfig(config); const publicDir = fileURLToPath(new URL("../public", import.meta.url)); const mediaStore = new InMemoryMediaStore({ ttlSeconds: config.mediaTtlSeconds }); const audioConversionService = createAudioConversionService({ maxAudioDownloadMb: config.maxAudioDownloadMb }); const requestNormalizationService = createRequestNormalizationService({ audioConversionService }); const responseNormalizationService = createResponseNormalizationService({ mediaStore }); const openAiService = createOpenAiService({ apiKey: config.openAiApiKey, baseUrl: config.openAiBaseUrl, timeoutMs: config.requestTimeoutMs }); const chatController = createChatController({ openAiService, requestNormalizationService, responseNormalizationService }); const mediaController = createMediaController({ mediaStore }); const app = createApp({ jsonLimit: config.jsonLimit, publicDir, chatController, mediaController }); app.listen(config.port, () => { console.log(`oapix listening on http://localhost:${config.port}`); });