import * as fs from 'fs';
import * as path from 'path';
export function ensureDir(dirPath: string): void {
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
}
}
export function copyDir(src: string, dest: string): void {
ensureDir(dest);
const entries = fs.readdirSync(src, { withFileTypes: true });
for (const entry of entries) {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
if (entry.isDirectory()) {
copyDir(srcPath, destPath);
} else {
fs.copyFileSync(srcPath, destPath);
}
}
}
export function removeDir(dirPath: string): void {
if (fs.existsSync(dirPath)) {
fs.rmSync(dirPath, { recursive: true, force: true });
}
}
export function listDirs(dirPath: string): string[] {
if (!fs.existsSync(dirPath)) {
return [];
}
return fs.readdirSync(dirPath, { withFileTypes: true })
.filter(entry => entry.isDirectory())
.map(entry => entry.name);
}
export function listFiles(dirPath: string, recursive = false): string[] {
if (!fs.existsSync(dirPath)) {
return [];
}
const files: string[] = [];
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dirPath, entry.name);
if (entry.isDirectory() && recursive) {
files.push(...listFiles(fullPath, true).map(f => path.join(entry.name, f)));
} else if (entry.isFile()) {
files.push(entry.name);
}
}
return files;
}
export function readJsonFile<T>(filePath: string): T | null {
if (!fs.existsSync(filePath)) {
return null;
}
const content = fs.readFileSync(filePath, 'utf-8');
return JSON.parse(content);
}
export function writeJsonFile<T>(filePath: string, data: T): void {
ensureDir(path.dirname(filePath));
fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
}
export function createSymlink(target: string, linkPath: string): void {
if (fs.existsSync(linkPath)) {
fs.unlinkSync(linkPath);
}
fs.symlinkSync(target, linkPath);
}
export function getSymlinkTarget(linkPath: string): string | null {
try {
return fs.readlinkSync(linkPath);
} catch {
return null;
}
}