import fs from 'fs'; import https from 'https'; import { exec } from 'child_process'; import chokidar from 'chokidar'; import path from 'path'; import util from 'util'; import dotenv from 'dotenv'; if (!process.env.ENVIRONMENT) { console.error("❌ Missing ENVIRONMENT variable."); process.exit(1); } dotenv.config(); // Determine the environment const environment = process.env.ENVIRONMENT || 'dev'; const nodeEnv = process.env.NODE_ENV || 'dev'; const configFile = `config_${nodeEnv}.json`; // Load the appropriate configuration if (!configFile) { console.error("❌ Configuration file path is missing."); process.exit(1); } let config; try { config = JSON.parse(fs.readFileSync(path.resolve('../', configFile), 'utf8')); } catch (error) { console.error(`❌ Error reading configuration file: ${error.message}`); process.exit(1); } if (!config.OPENAPI_URL || !config.SCHEMA_PATH || !config.OUTPUT_DIRECTORY || !config.SSL_KEY_PATH || !config.SSL_CERT_PATH) { console.error("❌ Missing essential configuration values."); process.exit(1); } const OPENAPI_URL = config.OPENAPI_URL; const SCHEMA_PATH = path.resolve(config.SCHEMA_PATH); const OUTPUT_DIRECTORY = path.resolve(config.OUTPUT_DIRECTORY); const SSL_KEY_PATH = path.resolve(config.SSL_KEY_PATH); const SSL_CERT_PATH = path.resolve(config.SSL_CERT_PATH); console.log(`Using SCHEMA_PATH: ${SCHEMA_PATH}`); console.log(`Using OUTPUT_DIRECTORY: ${OUTPUT_DIRECTORY}`); const execPromisified = util.promisify(exec); let isGenerating = false; const debounceDelay = 500; // 500ms debounce function debounce(func, delay) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, delay); }; } async function fetchAndGenerate() { if (isGenerating) { console.log("⚠️ Generation is already running."); return; } isGenerating = true; console.log("🚀 Fetching OpenAPI schema..."); try { const options = { rejectUnauthorized: false, key: fs.readFileSync(SSL_KEY_PATH), cert: fs.readFileSync(SSL_CERT_PATH), }; const res = await new Promise((resolve, reject) => { https.get(OPENAPI_URL, options, resolve).on('error', reject); }); let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', async () => { try { fs.writeFileSync(SCHEMA_PATH, data, 'utf8'); console.log(`✅ OpenAPI schema saved to ${SCHEMA_PATH}`); } catch (writeError) { console.error(`❌ Error saving OpenAPI schema: ${writeError}`); isGenerating = false; return; } console.log("🧼 Cleaning output directory..."); try { await fs.promises.rm(OUTPUT_DIRECTORY, { recursive: true, force: true }); console.log(`✅ Output directory cleaned at ${OUTPUT_DIRECTORY}`); if (fs.existsSync(OUTPUT_DIRECTORY)) { console.error(`❌ Output directory still exists: ${OUTPUT_DIRECTORY}`); } else { console.log(`✅ Confirmed removal of ${OUTPUT_DIRECTORY}`); } const command = `npx openapi -i ${SCHEMA_PATH} -o ${OUTPUT_DIRECTORY}`; console.log(`Executing debug command: ${command}`); const { stdout, stderr } = await execPromisified(command); if (stderr) { console.error(`⚠️ stderr while generating services: ${stderr}`); } else { console.log(`✅ Command executed successfully, output:\n${stdout}`); } } catch (error) { console.error(`❌ Error cleaning or executing command: ${error}`); } isGenerating = false; }); } catch (error) { console.error('❌ Error fetching OpenAPI schema: ' + error.message); isGenerating = false; } } // Define backendDirectory based on ENVIRONMENT variable const ENVIRONMENT = process.env.ENVIRONMENT || 'dev'; const backendDirectory = environment === 'test' ? path.resolve('/home/jungfrau/heidi-v2/backend/app') : path.resolve('/Users/gotthardg/PycharmProjects/heidi-v2/backend/app'); if (!backendDirectory) { console.error("❌ Failed to resolve backend directory path."); process.exit(1); } console.log(`👀 Watching for changes in ${backendDirectory}`); const watcher = chokidar.watch(backendDirectory, { persistent: true, ignored: [SCHEMA_PATH, OUTPUT_DIRECTORY] }); watcher .on('add', debounce(fetchAndGenerate, debounceDelay)) .on('change', debounce(fetchAndGenerate, debounceDelay)) .on('unlink', debounce(fetchAndGenerate, debounceDelay)); console.log(`👀 Watching for changes in ${backendDirectory}`);