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'; // Determine the environment const environment = process.env.NODE_ENV || 'dev'; const configFile = `config_${environment}.json`; // Load the appropriate configuration 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); } 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; } } const backendDirectory = path.resolve('/Users/gotthardg/PycharmProjects/heidi-v2/backend/app'); 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}`);