202 lines
6.1 KiB
TypeScript
202 lines
6.1 KiB
TypeScript
import { SmartFile } from './classes.smartfile.js';
|
|
import * as plugins from './plugins.js';
|
|
|
|
export interface IVirtualDirectoryConstructorOptions {
|
|
mode: '';
|
|
}
|
|
|
|
/**
|
|
* a virtual directory exposes a fs api
|
|
* Use SmartFileFactory to create instances of this class
|
|
*/
|
|
export class VirtualDirectory {
|
|
// STATIC
|
|
public static async fromFsDirPath(
|
|
pathArg: string,
|
|
smartFs?: any,
|
|
factory?: any
|
|
): Promise<VirtualDirectory> {
|
|
if (!smartFs || !factory) {
|
|
throw new Error('No SmartFs/Factory instance available. Create VirtualDirectory through SmartFileFactory.');
|
|
}
|
|
|
|
const newVirtualDir = new VirtualDirectory(smartFs, factory);
|
|
|
|
// Use smartFs to list directory and factory to create SmartFiles
|
|
const entries = await smartFs.directory(pathArg).recursive().list();
|
|
const smartfiles = await Promise.all(
|
|
entries
|
|
.filter((entry: any) => entry.isFile)
|
|
.map((entry: any) => factory.fromFilePath(entry.path, pathArg))
|
|
);
|
|
newVirtualDir.addSmartfiles(smartfiles);
|
|
|
|
return newVirtualDir;
|
|
}
|
|
|
|
public static async fromVirtualDirTransferableObject(
|
|
virtualDirTransferableObjectArg: plugins.smartfileInterfaces.VirtualDirTransferableObject,
|
|
smartFs?: any,
|
|
factory?: any
|
|
): Promise<VirtualDirectory> {
|
|
const newVirtualDir = new VirtualDirectory(smartFs, factory);
|
|
for (const fileArg of virtualDirTransferableObjectArg.files) {
|
|
const smartFile = SmartFile.enfoldFromJson(fileArg) as SmartFile;
|
|
// Update smartFs reference if available
|
|
if (smartFs) {
|
|
(smartFile as any).smartFs = smartFs;
|
|
}
|
|
newVirtualDir.addSmartfiles([smartFile]);
|
|
}
|
|
return newVirtualDir;
|
|
}
|
|
|
|
public static fromFileArray(files: SmartFile[], smartFs?: any, factory?: any): VirtualDirectory {
|
|
const vdir = new VirtualDirectory(smartFs, factory);
|
|
vdir.addSmartfiles(files);
|
|
return vdir;
|
|
}
|
|
|
|
public static empty(smartFs?: any, factory?: any): VirtualDirectory {
|
|
return new VirtualDirectory(smartFs, factory);
|
|
}
|
|
|
|
// INSTANCE
|
|
public smartfileArray: SmartFile[] = [];
|
|
private smartFs?: any;
|
|
private factory?: any;
|
|
|
|
constructor(smartFs?: any, factory?: any) {
|
|
this.smartFs = smartFs;
|
|
this.factory = factory;
|
|
}
|
|
|
|
// ============================================
|
|
// Collection Mutations
|
|
// ============================================
|
|
|
|
public addSmartfiles(smartfileArrayArg: SmartFile[]) {
|
|
this.smartfileArray = this.smartfileArray.concat(smartfileArrayArg);
|
|
}
|
|
|
|
public addSmartfile(smartfileArg: SmartFile): void {
|
|
this.smartfileArray.push(smartfileArg);
|
|
}
|
|
|
|
public removeByPath(pathArg: string): boolean {
|
|
const initialLength = this.smartfileArray.length;
|
|
this.smartfileArray = this.smartfileArray.filter(f => f.path !== pathArg);
|
|
return this.smartfileArray.length < initialLength;
|
|
}
|
|
|
|
public clear(): void {
|
|
this.smartfileArray = [];
|
|
}
|
|
|
|
public merge(otherVDir: VirtualDirectory): void {
|
|
this.addSmartfiles(otherVDir.smartfileArray);
|
|
}
|
|
|
|
// ============================================
|
|
// Collection Queries
|
|
// ============================================
|
|
|
|
public exists(pathArg: string): boolean {
|
|
return this.smartfileArray.some(f => f.path === pathArg);
|
|
}
|
|
|
|
public has(pathArg: string): boolean {
|
|
return this.exists(pathArg);
|
|
}
|
|
|
|
public async getFileByPath(pathArg: string): Promise<SmartFile | undefined> {
|
|
return this.smartfileArray.find(f => f.path === pathArg);
|
|
}
|
|
|
|
public listFiles(): SmartFile[] {
|
|
return [...this.smartfileArray];
|
|
}
|
|
|
|
public listDirectories(): string[] {
|
|
const dirs = new Set<string>();
|
|
for (const file of this.smartfileArray) {
|
|
const dir = plugins.path.dirname(file.path);
|
|
if (dir !== '.') {
|
|
dirs.add(dir);
|
|
}
|
|
}
|
|
return Array.from(dirs).sort();
|
|
}
|
|
|
|
public filter(predicate: (file: SmartFile) => boolean): VirtualDirectory {
|
|
const newVDir = new VirtualDirectory(this.smartFs, this.factory);
|
|
newVDir.addSmartfiles(this.smartfileArray.filter(predicate));
|
|
return newVDir;
|
|
}
|
|
|
|
public map(fn: (file: SmartFile) => SmartFile): VirtualDirectory {
|
|
const newVDir = new VirtualDirectory(this.smartFs, this.factory);
|
|
newVDir.addSmartfiles(this.smartfileArray.map(fn));
|
|
return newVDir;
|
|
}
|
|
|
|
public find(predicate: (file: SmartFile) => boolean): SmartFile | undefined {
|
|
return this.smartfileArray.find(predicate);
|
|
}
|
|
|
|
public size(): number {
|
|
return this.smartfileArray.length;
|
|
}
|
|
|
|
public isEmpty(): boolean {
|
|
return this.smartfileArray.length === 0;
|
|
}
|
|
|
|
public async toVirtualDirTransferableObject(): Promise<plugins.smartfileInterfaces.VirtualDirTransferableObject> {
|
|
return {
|
|
files: this.smartfileArray.map((smartfileArg) =>
|
|
smartfileArg.foldToJson(),
|
|
),
|
|
};
|
|
}
|
|
|
|
public async saveToDisk(dirArg: string) {
|
|
console.log(`writing VirtualDirectory with ${this.smartfileArray.length} files to directory:
|
|
--> ${dirArg}`);
|
|
for (const smartfileArg of this.smartfileArray) {
|
|
const filePath = await smartfileArg.writeToDir(dirArg);
|
|
console.log(`wrote ${smartfileArg.relative} to
|
|
--> ${filePath}`);
|
|
}
|
|
}
|
|
|
|
public async shiftToSubdirectory(subDir: string): Promise<VirtualDirectory> {
|
|
const newVirtualDir = new VirtualDirectory(this.smartFs, this.factory);
|
|
for (const file of this.smartfileArray) {
|
|
if (file.path.startsWith(subDir)) {
|
|
const adjustedFilePath = plugins.path.relative(subDir, file.path);
|
|
file.path = adjustedFilePath;
|
|
newVirtualDir.addSmartfiles([file]);
|
|
}
|
|
}
|
|
return newVirtualDir;
|
|
}
|
|
|
|
public async loadFromDisk(dirArg: string): Promise<void> {
|
|
// Load from disk, replacing current collection
|
|
this.clear();
|
|
const loaded = await VirtualDirectory.fromFsDirPath(dirArg, this.smartFs, this.factory);
|
|
this.addSmartfiles(loaded.smartfileArray);
|
|
}
|
|
|
|
public async addVirtualDirectory(
|
|
virtualDir: VirtualDirectory,
|
|
newRoot: string,
|
|
): Promise<void> {
|
|
for (const file of virtualDir.smartfileArray) {
|
|
file.path = plugins.path.join(newRoot, file.path);
|
|
}
|
|
this.addSmartfiles(virtualDir.smartfileArray);
|
|
}
|
|
}
|