UNPKG

@push.rocks/smartbucket

Version:

A TypeScript library providing a cloud-agnostic interface for managing object storage with functionalities like bucket management, file and directory operations, and advanced features such as metadata handling and file locking.

212 lines 15.8 kB
import * as plugins from './smartbucket.plugins.js'; import { Bucket } from './smartbucket.classes.bucket.js'; import { File } from './smartbucket.classes.file.js'; export class Directory { constructor(bucketRefArg, parentDiretory, name) { this.bucketRef = bucketRefArg; this.parentDirectoryRef = parentDiretory; this.name = name; } /** * returns an array of parent directories */ getParentDirectories() { let parentDirectories = []; if (this.parentDirectoryRef) { parentDirectories.push(this.parentDirectoryRef); parentDirectories = parentDirectories.concat(this.parentDirectoryRef.getParentDirectories()); } return parentDirectories; } /** * returns the directory level */ getDirectoryLevel() { return this.getParentDirectories().length; } /** * updates the base path */ getBasePath() { const parentDirectories = this.getParentDirectories(); let basePath = ''; for (const parentDir of parentDirectories) { if (!parentDir.name && !basePath) { basePath = this.name + '/'; continue; } if (parentDir.name && !basePath) { basePath = parentDir.name + '/' + this.name + '/'; continue; } if (parentDir.name && basePath) { basePath = parentDir.name + '/' + basePath; continue; } } return basePath; } /** * lists all files */ async listFiles() { const done = plugins.smartpromise.defer(); const fileNameStream = await this.bucketRef.smartbucketRef.minioClient.listObjectsV2(this.bucketRef.name, this.getBasePath(), false); const fileArray = []; const duplexStream = new plugins.smartstream.SmartDuplex({ objectMode: true, writeFunction: async (bucketItem) => { if (bucketItem.prefix) { return; } if (!bucketItem.name) { return; } let subtractedPath = bucketItem.name.replace(this.getBasePath(), ''); if (subtractedPath.startsWith('/')) { subtractedPath = subtractedPath.substr(1); } if (!subtractedPath.includes('/')) { fileArray.push(new File({ directoryRefArg: this, fileName: subtractedPath, })); } }, finalFunction: async (tools) => { done.resolve(); } }); fileNameStream.pipe(duplexStream); await done.promise; return fileArray; } /** * lists all folders */ async listDirectories() { const done = plugins.smartpromise.defer(); const basePath = this.getBasePath(); const completeDirStream = await this.bucketRef.smartbucketRef.minioClient.listObjectsV2(this.bucketRef.name, this.getBasePath(), false); const directoryArray = []; const duplexStream = new plugins.smartstream.SmartDuplex({ objectMode: true, writeFunction: async (bucketItem) => { if (bucketItem.name) { return; } let subtractedPath = bucketItem.prefix.replace(this.getBasePath(), ''); if (subtractedPath.startsWith('/')) { subtractedPath = subtractedPath.substr(1); } if (subtractedPath.includes('/')) { const dirName = subtractedPath.split('/')[0]; if (directoryArray.find((directory) => directory.name === dirName)) { return; } directoryArray.push(new Directory(this.bucketRef, this, dirName)); } }, finalFunction: async (tools) => { done.resolve(); } }); completeDirStream.pipe(duplexStream); await done.promise; return directoryArray; } /** * gets an array that has all objects with a certain prefix; */ async getTreeArray() { const treeArray = await this.bucketRef.smartbucketRef.minioClient.listObjectsV2(this.bucketRef.name, this.getBasePath(), true); } /** * gets a sub directory */ async getSubDirectoryByName(dirNameArg) { const dirNameArray = dirNameArg.split('/'); const getDirectory = async (directoryArg, dirNameToSearch) => { const directories = await directoryArg.listDirectories(); return directories.find((directory) => { return directory.name === dirNameToSearch; }); }; let wantedDirectory; for (const dirNameToSearch of dirNameArray) { const directoryToSearchIn = wantedDirectory ? wantedDirectory : this; wantedDirectory = await getDirectory(directoryToSearchIn, dirNameToSearch); } return wantedDirectory; } /** * moves the directory */ async move() { // TODO throw new Error('moving a directory is not yet implemented'); } /** * creates a file within this directory * @param relativePathArg */ async createEmptyFile(relativePathArg) { const emtpyFile = await File.create({ directory: this, name: relativePathArg, contents: '', }); } // file operations async fastPut(optionsArg) { const path = plugins.path.join(this.getBasePath(), optionsArg.path); await this.bucketRef.fastPut({ path, contents: optionsArg.contents, }); } async fastGet(optionsArg) { const path = plugins.path.join(this.getBasePath(), optionsArg.path); const result = await this.bucketRef.fastGet({ path, }); return result; } async fastGetStream(pathArg) { const path = plugins.path.join(this.getBasePath(), pathArg); const result = await this.bucketRef.fastGetStream({ path, }); return result; } async fastRemove(optionsArg) { const path = plugins.path.join(this.getBasePath(), optionsArg.path); await this.bucketRef.fastRemove({ path, }); } /** * deletes the directory with all its contents */ async delete() { const deleteDirectory = async (directoryArg) => { const childDirectories = await directoryArg.listDirectories(); if (childDirectories.length === 0) { console.log('directory empty! Path complete!'); } else { for (const childDir of childDirectories) { await deleteDirectory(childDir); } } const files = await directoryArg.listFiles(); for (const file of files) { await directoryArg.fastRemove({ path: file.name, }); } }; await deleteDirectory(this); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRidWNrZXQuY2xhc3Nlcy5kaXJlY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGJ1Y2tldC5jbGFzc2VzLmRpcmVjdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFckQsTUFBTSxPQUFPLFNBQVM7SUFTcEIsWUFBWSxZQUFvQixFQUFFLGNBQXlCLEVBQUUsSUFBWTtRQUN2RSxJQUFJLENBQUMsU0FBUyxHQUFHLFlBQVksQ0FBQztRQUM5QixJQUFJLENBQUMsa0JBQWtCLEdBQUcsY0FBYyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7SUFFRDs7T0FFRztJQUNJLG9CQUFvQjtRQUN6QixJQUFJLGlCQUFpQixHQUFnQixFQUFFLENBQUM7UUFDeEMsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUM1QixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDaEQsaUJBQWlCLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUM7UUFDL0YsQ0FBQztRQUNELE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVEOztPQUVHO0lBQ0ksaUJBQWlCO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsTUFBTSxDQUFDO0lBQzVDLENBQUM7SUFFRDs7T0FFRztJQUNJLFdBQVc7UUFDaEIsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUN0RCxJQUFJLFFBQVEsR0FB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