225 lines
6.5 KiB
TypeScript
225 lines
6.5 KiB
TypeScript
|
|
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;
|
||
|
|
}
|
||
|
|
}
|