UNPKG

hayai-db

Version:

⚡ Instantly create and manage local databases with one command

150 lines (149 loc) 4.54 kB
import { readFile, writeFile, access, mkdir } from 'fs/promises'; import { constants } from 'fs'; import * as path from 'path'; import * as yaml from 'yaml'; export class ConfigManager { static instance; config = null; configPath; constructor(configPath) { this.configPath = configPath || path.join(process.cwd(), 'hayai.config.yaml'); } static getInstance(configPath) { if (!ConfigManager.instance) { ConfigManager.instance = new ConfigManager(configPath); } return ConfigManager.instance; } async pathExists(filePath) { try { await access(filePath, constants.F_OK); return true; } catch { return false; } } async ensureDir(dirPath) { try { await mkdir(dirPath, { recursive: true }); } catch (error) { if (error.code !== 'EEXIST') { throw error; } } } async loadConfig() { if (this.config) { return this.config; } try { if (await this.pathExists(this.configPath)) { const configContent = await readFile(this.configPath, 'utf-8'); this.config = yaml.parse(configContent); } else { this.config = this.getDefaultConfig(); await this.saveConfig(); } return this.config; } catch (error) { console.error('Failed to load configuration:', error); this.config = this.getDefaultConfig(); return this.config; } } async saveConfig() { if (!this.config) { throw new Error('No configuration to save'); } try { // Ensure directory exists await this.ensureDir(path.dirname(this.configPath)); const configContent = yaml.stringify(this.config, { indent: 2, lineWidth: 80, minContentWidth: 20, }); await writeFile(this.configPath, configContent, 'utf-8'); } catch (error) { console.error('Failed to save configuration:', error); throw error; } } getConfig() { if (!this.config) { throw new Error('Configuration not loaded. Call loadConfig() first.'); } return this.config; } updateConfig(updates) { if (!this.config) { throw new Error('Configuration not loaded. Call loadConfig() first.'); } this.config = { ...this.config, ...updates }; } getDataDirectory() { return path.resolve(this.getConfig().docker.data_directory); } getComposeFilePath() { return path.resolve(this.getConfig().docker.compose_file); } getLogFilePath() { return path.resolve(this.getConfig().logging.file); } getPortRange() { return this.getConfig().defaults.port_range; } getDefaultConfig() { return { version: '1.0.0', docker: { network_name: 'hayai-network', compose_file: 'docker-compose.yml', data_directory: './data', }, logging: { level: 'info', file: 'hayai.log', }, defaults: { port_range: { start: 5000, end: 6000, }, volume_driver: 'local', restart_policy: 'unless-stopped', }, }; } } // Convenience functions for global access export const getConfig = async () => { const manager = ConfigManager.getInstance(); return await manager.loadConfig(); }; export const updateConfig = async (updates) => { const manager = ConfigManager.getInstance(); await manager.loadConfig(); manager.updateConfig(updates); await manager.saveConfig(); }; export const getDataDirectory = async () => { const manager = ConfigManager.getInstance(); await manager.loadConfig(); return manager.getDataDirectory(); }; export const getComposeFilePath = async () => { const manager = ConfigManager.getInstance(); await manager.loadConfig(); return manager.getComposeFilePath(); }; export const getLogFilePath = async () => { const manager = ConfigManager.getInstance(); await manager.loadConfig(); return manager.getLogFilePath(); };