import * as fs from 'fs-extra'; import * as path from 'path'; import * as os from 'os'; import * as yaml from 'js-yaml'; import { UserConfig } from '../models/types'; const CONFIG_FILE_NAME = 'config.json'; const LAYOUTS_DIR = 'layouts'; const TEMPLATES_DIR = 'templates'; export class FileUtils { private baseDir: string; constructor(baseDir?: string) { this.baseDir = baseDir || this.getDefaultBaseDir(); } private getDefaultBaseDir(): string { const homeDir = os.homedir(); return path.join(homeDir, '.config', 'terminal-layouts'); } async initialize(): Promise { await fs.ensureDir(this.baseDir); await fs.ensureDir(path.join(this.baseDir, LAYOUTS_DIR)); await fs.ensureDir(path.join(this.baseDir, TEMPLATES_DIR)); const configPath = path.join(this.baseDir, CONFIG_FILE_NAME); if (!(await fs.pathExists(configPath))) { const defaultConfig: UserConfig = { layoutDir: path.join(this.baseDir, LAYOUTS_DIR), defaultFormat: 'json', gitSyncEnabled: true, templatesDir: path.join(this.baseDir, TEMPLATES_DIR), }; await fs.writeJson(configPath, defaultConfig, { spaces: 2 }); } } getConfigPath(): string { return path.join(this.baseDir, CONFIG_FILE_NAME); } getLayoutsDir(): string { return path.join(this.baseDir, LAYOUTS_DIR); } getTemplatesDir(): string { return path.join(this.baseDir, TEMPLATES_DIR); } async readConfig(): Promise { const configPath = this.getConfigPath(); if (await fs.pathExists(configPath)) { return fs.readJson(configPath) as Promise; } throw new Error(`Configuration file not found: ${configPath}`); } async saveConfig(config: UserConfig): Promise { const configPath = this.getConfigPath(); await fs.writeJson(configPath, config, { spaces: 2 }); } async readLayout(fileName: string): Promise { const filePath = path.join(this.getLayoutsDir(), fileName); const content = await fs.readFile(filePath, 'utf-8'); if (fileName.endsWith('.yaml') || fileName.endsWith('.yml')) { return yaml.load(content); } return fs.readJson(filePath); } async saveLayout(fileName: string, data: unknown, format: 'json' | 'yaml' = 'json'): Promise { const layoutsDir = this.getLayoutsDir(); let filePath: string; if (format === 'yaml') { const yamlName = fileName.replace(/\.json$/, '.yaml'); filePath = path.join(layoutsDir, yamlName); const content = yaml.dump(data); await fs.writeFile(filePath, content); } else { if (!fileName.endsWith('.json')) { filePath = path.join(layoutsDir, `${fileName}.json`); } else { filePath = path.join(layoutsDir, fileName); } await fs.writeJson(filePath, data, { spaces: 2 }); } return filePath; } async deleteLayout(fileName: string): Promise { const filePath = path.join(this.getLayoutsDir(), fileName); if (await fs.pathExists(filePath)) { await fs.remove(filePath); } } async listLayouts(): Promise { const layoutsDir = this.getLayoutsDir(); if (!(await fs.pathExists(layoutsDir))) { return []; } const files = await fs.readdir(layoutsDir); return files.filter((file) => file.endsWith('.json') || file.endsWith('.yaml') || file.endsWith('.yml')); } async readTemplate(fileName: string): Promise { const filePath = path.join(this.getTemplatesDir(), fileName); const content = await fs.readFile(filePath, 'utf-8'); if (fileName.endsWith('.yaml') || fileName.endsWith('.yml')) { return yaml.load(content); } return fs.readJson(filePath); } async saveTemplate(fileName: string, data: unknown): Promise { const templatesDir = this.getTemplatesDir(); const filePath = path.join(templatesDir, fileName.endsWith('.json') ? fileName : `${fileName}.json`); await fs.writeJson(filePath, data, { spaces: 2 }); return filePath; } async listTemplates(): Promise { const templatesDir = this.getTemplatesDir(); if (!(await fs.pathExists(templatesDir))) { return []; } const files = await fs.readdir(templatesDir); return files.filter((file) => file.endsWith('.json') || file.endsWith('.yaml') || file.endsWith('.yml')); } async deleteTemplate(fileName: string): Promise { const filePath = path.join(this.getTemplatesDir(), fileName); if (await fs.pathExists(filePath)) { await fs.remove(filePath); } } async fileExists(filePath: string): Promise { return fs.pathExists(filePath); } async readFile(filePath: string): Promise { return fs.readFile(filePath, 'utf-8'); } async writeFile(filePath: string, content: string): Promise { await fs.writeFile(filePath, content); } async ensureDir(dirPath: string): Promise { await fs.ensureDir(dirPath); } } export const fileUtils = new FileUtils();