BREAKING CHANGE(SmartFileFactory): Refactor to in-memory file API and introduce SmartFileFactory; delegate filesystem operations to @push.rocks/smartfs; bump to 12.0.0
This commit is contained in:
224
ts/classes.smartfile.factory.ts
Normal file
224
ts/classes.smartfile.factory.ts
Normal file
@@ -0,0 +1,224 @@
|
||||
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<SmartFile> {
|
||||
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<SmartFile> {
|
||||
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<SmartFile> {
|
||||
return new Promise<SmartFile>((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<SmartFile> {
|
||||
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<StreamFile> {
|
||||
return StreamFile.fromPath(filePath, this.smartFs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a StreamFile from a URL
|
||||
*/
|
||||
public async streamFromUrl(url: string): Promise<StreamFile> {
|
||||
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<VirtualDirectory> {
|
||||
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<VirtualDirectory> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user