import * as fs from 'fs'; import * as path from 'path'; export class FsHelpers { public static async fileExists(filePath: string): Promise { try { const stat = await fs.promises.stat(filePath); return stat.isFile(); } catch { return false; } } public static async directoryExists(dirPath: string): Promise { try { const stat = await fs.promises.stat(dirPath); return stat.isDirectory(); } catch { return false; } } public static async ensureEmptyDir(dirPath: string): Promise { if (await FsHelpers.directoryExists(dirPath)) { await fs.promises.rm(dirPath, { recursive: true, force: true }); } await fs.promises.mkdir(dirPath, { recursive: true }); } public static async copyFile(src: string, dest: string): Promise { const destDir = path.dirname(dest); await fs.promises.mkdir(destDir, { recursive: true }); await fs.promises.copyFile(src, dest); } public static async makeExecutable(filePath: string): Promise { await fs.promises.chmod(filePath, 0o755); } public static async getFileSize(filePath: string): Promise { const stat = await fs.promises.stat(filePath); return stat.size; } public static async removeDirectory(dirPath: string): Promise { if (await FsHelpers.directoryExists(dirPath)) { await fs.promises.rm(dirPath, { recursive: true, force: true }); } } public static formatFileSize(bytes: number): string { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; } }