hayai-db
Version:
⚡ Instantly create and manage local databases with one command
150 lines (149 loc) • 4.54 kB
JavaScript
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();
};