@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
JavaScript
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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