UNPKG

agentic-qe

Version:

Agentic Quality Engineering Fleet System - AI-driven quality management platform

263 lines 9.48 kB
"use strict"; /** * Config - Configuration management for the AQE Fleet * * Handles loading and validation of fleet configuration from multiple sources * including environment variables, config files, and defaults. */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Config = void 0; const fs_1 = require("fs"); const path_1 = require("path"); const yaml_1 = __importDefault(require("yaml")); const dotenv_1 = __importDefault(require("dotenv")); class Config { constructor(config) { this.config = config; } /** * Load configuration from multiple sources */ static async load(configPath) { // Load environment variables dotenv_1.default.config(); // Default configuration const defaultConfig = { fleet: { id: process.env.FLEET_ID || 'default-fleet', name: process.env.FLEET_NAME || 'AQE Fleet', maxAgents: parseInt(process.env.MAX_AGENTS || '10'), heartbeatInterval: parseInt(process.env.HEARTBEAT_INTERVAL || '30000'), taskTimeout: parseInt(process.env.TASK_TIMEOUT || '300000') }, agents: [ { type: 'test-executor', count: parseInt(process.env.TEST_EXECUTOR_COUNT || '2'), config: {} }, { type: 'quality-analyzer', count: parseInt(process.env.QUALITY_ANALYZER_COUNT || '2'), config: {} }, { type: 'performance-monitor', count: parseInt(process.env.PERFORMANCE_MONITOR_COUNT || '1'), config: {} } ], database: { type: process.env.DB_TYPE || 'sqlite', host: process.env.DB_HOST || 'localhost', port: parseInt(process.env.DB_PORT || '5432'), database: process.env.DB_NAME || 'agentic_qe', username: process.env.DB_USER, password: process.env.DB_PASSWORD, filename: process.env.DB_FILENAME || './data/fleet.db' }, logging: { level: process.env.LOG_LEVEL || 'info', format: process.env.LOG_FORMAT || 'json', outputs: (process.env.LOG_OUTPUTS || 'console,file').split(',') }, api: { port: parseInt(process.env.API_PORT || '3000'), host: process.env.API_HOST || '0.0.0.0', cors: process.env.API_CORS === 'true', rateLimit: { windowMs: parseInt(process.env.RATE_LIMIT_WINDOW || '900000'), // 15 minutes max: parseInt(process.env.RATE_LIMIT_MAX || '100') } }, security: { apiKey: process.env.API_KEY, jwtSecret: process.env.JWT_SECRET, encryption: { algorithm: process.env.ENCRYPTION_ALGORITHM || 'aes-256-gcm', keyLength: parseInt(process.env.ENCRYPTION_KEY_LENGTH || '32') } } }; // Load from config file if provided or exists let fileConfig = {}; const configFilePath = configPath || process.env.CONFIG_FILE || (0, path_1.join)(process.cwd(), 'config', 'fleet.yaml'); if ((0, fs_1.existsSync)(configFilePath)) { try { const configFileContent = (0, fs_1.readFileSync)(configFilePath, 'utf8'); if (configFilePath.endsWith('.yaml') || configFilePath.endsWith('.yml')) { fileConfig = yaml_1.default.parse(configFileContent); } else if (configFilePath.endsWith('.json')) { fileConfig = JSON.parse(configFileContent); } } catch (error) { console.warn(`Failed to load config file ${configFilePath}:`, error); } } // Merge configurations (file config overrides defaults, env vars override both) const mergedConfig = Config.mergeConfigs(defaultConfig, fileConfig); // Validate configuration Config.validateConfig(mergedConfig); // Create singleton instance Config.instance = new Config(mergedConfig); return mergedConfig; } /** * Get configuration instance */ static getInstance() { if (!Config.instance) { throw new Error('Config not loaded. Call Config.load() first.'); } return Config.instance; } /** * Get full configuration */ getConfig() { return this.config; } /** * Get fleet configuration */ getFleetConfig() { return this.config.fleet; } /** * Get agents configuration */ getAgentsConfig() { return this.config.agents; } /** * Get database configuration */ getDatabaseConfig() { return this.config.database; } /** * Get logging configuration */ getLoggingConfig() { return this.config.logging; } /** * Get API configuration */ getApiConfig() { return this.config.api; } /** * Get security configuration */ getSecurityConfig() { return this.config.security; } /** * Deep merge configurations */ static mergeConfigs(base, override) { const merged = { ...base }; if (override.fleet) { merged.fleet = { ...merged.fleet, ...override.fleet }; } if (override.agents) { merged.agents = override.agents; } if (override.database) { merged.database = { ...merged.database, ...override.database }; } if (override.logging) { merged.logging = { ...merged.logging, ...override.logging }; } if (override.api) { merged.api = { ...merged.api, ...override.api }; if (override.api.rateLimit) { merged.api.rateLimit = { ...merged.api.rateLimit, ...override.api.rateLimit }; } } if (override.security) { merged.security = { ...merged.security, ...override.security }; if (override.security.encryption) { merged.security.encryption = { ...merged.security.encryption, ...override.security.encryption }; } } return merged; } /** * Save configuration to file */ static async save(config, filePath) { const fs = await Promise.resolve().then(() => __importStar(require('fs-extra'))); await fs.ensureDir(require('path').dirname(filePath)); await fs.writeJson(filePath, config, { spaces: 2 }); } /** * Validate configuration */ static validateConfig(config) { // Validate fleet config if (!config.fleet.id) { throw new Error('Fleet ID is required'); } if (config.fleet.maxAgents <= 0) { throw new Error('Max agents must be greater than 0'); } // Validate agents config if (!Array.isArray(config.agents) || config.agents.length === 0) { throw new Error('At least one agent configuration is required'); } for (const agent of config.agents) { if (!agent.type) { throw new Error('Agent type is required'); } if (agent.count <= 0) { throw new Error('Agent count must be greater than 0'); } } // Validate database config if (!config.database.database) { throw new Error('Database name is required'); } if (config.database.type === 'sqlite' && !config.database.filename) { throw new Error('SQLite filename is required'); } // Validate API config if (config.api.port <= 0 || config.api.port > 65535) { throw new Error('API port must be between 1 and 65535'); } } } exports.Config = Config; Config.instance = null; //# sourceMappingURL=Config.js.map