/** * File builder for fluent file operations */ import type { ISmartFsProvider } from '../interfaces/mod.provider.js'; import type { TEncoding, TFileMode, IFileStats, IReadOptions, IWriteOptions, IStreamOptions, ICopyOptions, } from '../interfaces/mod.types.js'; /** * File builder class for fluent file operations * Configuration methods return `this` for chaining * Action methods return Promises for execution */ export class SmartFsFile { private provider: ISmartFsProvider; private path: string; // Configuration options private options: { encoding?: TEncoding; mode?: TFileMode; atomic?: boolean; chunkSize?: number; preserveTimestamps?: boolean; overwrite?: boolean; } = {}; constructor(provider: ISmartFsProvider, path: string) { this.provider = provider; this.path = this.provider.normalizePath(path); } // --- Configuration Methods (return this for chaining) --- /** * Set encoding for read/write operations * @param encoding - File encoding */ public encoding(encoding: TEncoding): this { this.options.encoding = encoding; return this; } /** * Set file permissions/mode * @param mode - File mode (e.g., 0o644) */ public mode(mode: TFileMode): this { this.options.mode = mode; return this; } /** * Enable atomic write operations * Writes to a temporary file first, then renames */ public atomic(): this { this.options.atomic = true; return this; } /** * Set chunk size for streaming operations * @param size - Chunk size in bytes */ public chunkSize(size: number): this { this.options.chunkSize = size; return this; } /** * Preserve timestamps when copying/moving */ public preserveTimestamps(): this { this.options.preserveTimestamps = true; return this; } /** * Allow overwriting existing files */ public overwrite(): this { this.options.overwrite = true; return this; } // --- Action Methods (return Promises) --- /** * Read the file * @returns File content as Buffer or string (if encoding is set) */ public async read(): Promise { const readOptions: IReadOptions = { encoding: this.options.encoding, }; return this.provider.readFile(this.path, readOptions); } /** * Write content to the file * @param content - Content to write */ public async write(content: string | Buffer): Promise { const writeOptions: IWriteOptions = { encoding: this.options.encoding, mode: this.options.mode, atomic: this.options.atomic, }; return this.provider.writeFile(this.path, content, writeOptions); } /** * Append content to the file * @param content - Content to append */ public async append(content: string | Buffer): Promise { const writeOptions: IWriteOptions = { encoding: this.options.encoding, mode: this.options.mode, }; return this.provider.appendFile(this.path, content, writeOptions); } /** * Get a readable stream for the file * @returns ReadableStream of Uint8Array */ public async readStream(): Promise> { const streamOptions: IStreamOptions = { chunkSize: this.options.chunkSize, }; return this.provider.createReadStream(this.path, streamOptions); } /** * Get a writable stream for the file * @returns WritableStream of Uint8Array */ public async writeStream(): Promise> { const streamOptions: IStreamOptions = { chunkSize: this.options.chunkSize, }; return this.provider.createWriteStream(this.path, streamOptions); } /** * Copy the file to a new location * @param targetPath - Destination path */ public async copy(targetPath: string): Promise { const normalizedTarget = this.provider.normalizePath(targetPath); const copyOptions: ICopyOptions = { preserveTimestamps: this.options.preserveTimestamps, overwrite: this.options.overwrite, }; return this.provider.copyFile(this.path, normalizedTarget, copyOptions); } /** * Move the file to a new location * @param targetPath - Destination path */ public async move(targetPath: string): Promise { const normalizedTarget = this.provider.normalizePath(targetPath); const copyOptions: ICopyOptions = { preserveTimestamps: this.options.preserveTimestamps, overwrite: this.options.overwrite, }; return this.provider.moveFile(this.path, normalizedTarget, copyOptions); } /** * Delete the file */ public async delete(): Promise { return this.provider.deleteFile(this.path); } /** * Check if the file exists * @returns True if file exists */ public async exists(): Promise { return this.provider.fileExists(this.path); } /** * Get file statistics * @returns File stats */ public async stat(): Promise { return this.provider.fileStat(this.path); } /** * Get the file path */ public getPath(): string { return this.path; } }