import * as plugins from './plugins.js'; import { SmartFile } from './classes.smartfile.js'; import { StreamFile } from './classes.streamfile.js'; import { VirtualDirectory } from './classes.virtualdirectory.js'; export class SmartFileFactory { private smartFs: any; // Will be typed as SmartFs once we import from @push.rocks/smartfs constructor(smartFs: any) { this.smartFs = smartFs; } /** * Creates a default factory using Node.js filesystem provider */ public static nodeFs(): SmartFileFactory { // Temporarily using a placeholder - will be replaced with actual SmartFs initialization // const smartFs = new SmartFs(new SmartFsProviderNode()); const smartFs = null; // Placeholder return new SmartFileFactory(smartFs); } /** * Get the underlying SmartFs instance */ public getSmartFs(): any { return this.smartFs; } // ============================================ // SmartFile Factory Methods // ============================================ /** * Creates a SmartFile from a file path on disk */ public async fromFilePath( filePath: string, baseArg: string = process.cwd() ): Promise { if (!this.smartFs) { throw new Error('No SmartFs instance available. Cannot read from filesystem without SmartFs.'); } filePath = plugins.path.resolve(filePath); const content = await this.smartFs.file(filePath).read(); const fileBuffer = Buffer.from(content); return new SmartFile({ contentBuffer: fileBuffer, base: baseArg, path: plugins.path.relative(baseArg, filePath), }, this.smartFs); } /** * Creates a SmartFile from a URL */ public async fromUrl(urlArg: string): Promise { const response = await plugins.smartrequest.SmartRequest.create() .url(urlArg) .accept('binary') .get(); const buffer = Buffer.from(await response.arrayBuffer()); return new SmartFile({ contentBuffer: buffer, base: process.cwd(), path: urlArg, }, this.smartFs); } /** * Creates a SmartFile from a Buffer */ public fromBuffer( filePath: string, contentBufferArg: Buffer, baseArg: string = process.cwd() ): SmartFile { // Use filePath as-is if it's already relative, otherwise compute relative path const relativePath = plugins.path.isAbsolute(filePath) ? plugins.path.relative(baseArg, filePath) : filePath; return new SmartFile({ contentBuffer: contentBufferArg, base: baseArg, path: relativePath, }, this.smartFs); } /** * Creates a SmartFile from a string */ public fromString( filePath: string, contentStringArg: string, encodingArg: 'utf8' | 'binary' = 'utf8', baseArg: string = process.cwd() ): SmartFile { // Use filePath as-is if it's already relative, otherwise compute relative path const relativePath = plugins.path.isAbsolute(filePath) ? plugins.path.relative(baseArg, filePath) : filePath; return new SmartFile({ contentBuffer: Buffer.from(contentStringArg, encodingArg), base: baseArg, path: relativePath, }, this.smartFs); } /** * Creates a SmartFile from a stream */ public async fromStream( stream: plugins.stream.Readable, filePath: string, baseArg: string = process.cwd() ): Promise { return new Promise((resolve, reject) => { const chunks: Buffer[] = []; stream.on('data', (chunk) => chunks.push(Buffer.from(chunk))); stream.on('error', (error) => reject(error)); stream.on('end', () => { const contentBuffer = Buffer.concat(chunks); const smartfile = new SmartFile({ contentBuffer: contentBuffer, base: baseArg, path: plugins.path.relative(baseArg, filePath), }, this.smartFs); resolve(smartfile); }); }); } /** * Creates a SmartFile from folded JSON */ public async fromFoldedJson(foldedJsonArg: string): Promise { const parsed = plugins.smartjson.parse(foldedJsonArg); return new SmartFile(parsed, this.smartFs); } // ============================================ // StreamFile Factory Methods // ============================================ /** * Creates a StreamFile from a file path */ public async streamFromPath(filePath: string): Promise { return StreamFile.fromPath(filePath, this.smartFs); } /** * Creates a StreamFile from a URL */ public async streamFromUrl(url: string): Promise { return StreamFile.fromUrl(url, this.smartFs); } /** * Creates a StreamFile from a Buffer */ public streamFromBuffer(buffer: Buffer, relativeFilePath?: string): StreamFile { return StreamFile.fromBuffer(buffer, relativeFilePath, this.smartFs); } /** * Creates a StreamFile from a Node.js Readable stream */ public streamFromStream( stream: plugins.stream.Readable, relativeFilePath?: string, multiUse: boolean = false ): StreamFile { return StreamFile.fromStream(stream, relativeFilePath, multiUse, this.smartFs); } // ============================================ // VirtualDirectory Factory Methods // ============================================ /** * Creates a VirtualDirectory from a filesystem directory path */ public async virtualDirectoryFromPath(pathArg: string): Promise { return VirtualDirectory.fromFsDirPath(pathArg, this.smartFs, this); } /** * Creates an empty VirtualDirectory */ public virtualDirectoryEmpty(): VirtualDirectory { return new VirtualDirectory(this.smartFs, this); } /** * Creates a VirtualDirectory from an array of SmartFiles */ public virtualDirectoryFromFileArray(files: SmartFile[]): VirtualDirectory { const vdir = new VirtualDirectory(this.smartFs, this); vdir.addSmartfiles(files); return vdir; } /** * Creates a VirtualDirectory from a transferable object */ public async virtualDirectoryFromTransferable( virtualDirTransferableObjectArg: plugins.smartfileInterfaces.VirtualDirTransferableObject ): Promise { const newVirtualDir = new VirtualDirectory(this.smartFs, this); for (const fileArg of virtualDirTransferableObjectArg.files) { const smartFile = SmartFile.enfoldFromJson(fileArg) as SmartFile; // Update the smartFs reference (smartFile as any).smartFs = this.smartFs; newVirtualDir.addSmartfiles([smartFile]); } return newVirtualDir; } }