/** * Mock SmartFs implementation for testing * Provides fluent API matching @push.rocks/smartfs using native Node.js fs */ import { promises as fsPromises, createReadStream, createWriteStream } from 'fs'; import * as path from 'path'; import { Readable, Writable } from 'stream'; /** * Mock SmartFsFile - Fluent file operations builder */ class MockSmartFsFile { private filePath: string; private options: { encoding?: BufferEncoding; recursive?: boolean; } = {}; constructor(filePath: string) { this.filePath = filePath; } // Configuration methods (return this for chaining) public encoding(encoding: BufferEncoding): this { this.options.encoding = encoding; return this; } public recursive(): this { this.options.recursive = true; return this; } // Action methods (return Promises) public async read(): Promise { if (this.options.encoding) { return await fsPromises.readFile(this.filePath, this.options.encoding); } return await fsPromises.readFile(this.filePath); } public async write(content: string | Buffer): Promise { // Ensure directory exists const dirPath = path.dirname(this.filePath); await fsPromises.mkdir(dirPath, { recursive: true }); if (this.options.encoding && typeof content === 'string') { await fsPromises.writeFile(this.filePath, content, this.options.encoding); } else { await fsPromises.writeFile(this.filePath, content); } } public async exists(): Promise { try { await fsPromises.access(this.filePath); return true; } catch { return false; } } public async delete(): Promise { await fsPromises.unlink(this.filePath); } public async stat(): Promise { return await fsPromises.stat(this.filePath); } public async readStream(): Promise { return createReadStream(this.filePath); } public async writeStream(): Promise { // Ensure directory exists const dirPath = path.dirname(this.filePath); await fsPromises.mkdir(dirPath, { recursive: true }); return createWriteStream(this.filePath); } public async copy(dest: string): Promise { await fsPromises.copyFile(this.filePath, dest); } } /** * Mock SmartFsDirectory - Fluent directory operations builder */ class MockSmartFsDirectory { private dirPath: string; private options: { recursive?: boolean; } = {}; constructor(dirPath: string) { this.dirPath = dirPath; } // Configuration methods (return this for chaining) public recursive(): this { this.options.recursive = true; return this; } // Action methods (return Promises) public async list(): Promise> { const entries: Array<{ path: string; isFile: boolean; isDirectory: boolean }> = []; if (this.options.recursive) { // Recursive listing const walk = async (dir: string) => { const items = await fsPromises.readdir(dir); for (const item of items) { const fullPath = path.join(dir, item); const stats = await fsPromises.stat(fullPath); if (stats.isFile()) { entries.push({ path: fullPath, isFile: true, isDirectory: false }); } else if (stats.isDirectory()) { entries.push({ path: fullPath, isFile: false, isDirectory: true }); await walk(fullPath); } } }; await walk(this.dirPath); } else { // Non-recursive listing const items = await fsPromises.readdir(this.dirPath); for (const item of items) { const fullPath = path.join(this.dirPath, item); const stats = await fsPromises.stat(fullPath); entries.push({ path: fullPath, isFile: stats.isFile(), isDirectory: stats.isDirectory(), }); } } return entries; } public async create(): Promise { if (this.options.recursive) { await fsPromises.mkdir(this.dirPath, { recursive: true }); } else { await fsPromises.mkdir(this.dirPath); } } public async exists(): Promise { try { const stats = await fsPromises.stat(this.dirPath); return stats.isDirectory(); } catch { return false; } } public async delete(): Promise { if (this.options.recursive) { await fsPromises.rm(this.dirPath, { recursive: true, force: true }); } else { await fsPromises.rmdir(this.dirPath); } } } /** * Mock SmartFs - Main class matching @push.rocks/smartfs API */ export class MockSmartFs { public file(filePath: string): MockSmartFsFile { return new MockSmartFsFile(filePath); } public directory(dirPath: string): MockSmartFsDirectory { return new MockSmartFsDirectory(dirPath); } }