smartbucket/ts/classes.directory.ts

275 lines
7.6 KiB
TypeScript
Raw Normal View History

2024-05-20 23:22:21 +00:00
import * as plugins from './plugins.js';
import { Bucket } from './classes.bucket.js';
import { File } from './classes.file.js';
2019-10-14 18:55:07 +00:00
2019-10-16 16:12:18 +00:00
export class Directory {
public bucketRef: Bucket;
2019-10-18 13:43:06 +00:00
public parentDirectoryRef: Directory;
2019-10-16 17:11:28 +00:00
public name: string;
2019-10-16 16:12:18 +00:00
public tree: string[];
public files: string[];
public folders: string[];
2019-10-16 17:11:28 +00:00
constructor(bucketRefArg: Bucket, parentDiretory: Directory, name: string) {
2019-10-16 16:12:18 +00:00
this.bucketRef = bucketRefArg;
2019-10-18 13:43:06 +00:00
this.parentDirectoryRef = parentDiretory;
2019-10-16 17:11:28 +00:00
this.name = name;
}
/**
* returns an array of parent directories
*/
public getParentDirectories(): Directory[] {
let parentDirectories: Directory[] = [];
2019-10-18 13:43:06 +00:00
if (this.parentDirectoryRef) {
parentDirectories.push(this.parentDirectoryRef);
parentDirectories = parentDirectories.concat(this.parentDirectoryRef.getParentDirectories());
2019-10-16 17:11:28 +00:00
}
return parentDirectories;
}
/**
* returns the directory level
*/
public getDirectoryLevel(): number {
return this.getParentDirectories().length;
2019-10-16 17:15:48 +00:00
}
2019-10-16 17:11:28 +00:00
/**
* updates the base path
*/
public getBasePath(): string {
const parentDirectories = this.getParentDirectories();
let basePath = '';
2019-10-16 17:15:48 +00:00
for (const parentDir of parentDirectories) {
2020-10-12 00:23:25 +00:00
if (!parentDir.name && !basePath) {
2020-05-17 19:23:26 +00:00
basePath = this.name + '/';
2019-10-19 23:18:13 +00:00
continue;
}
2020-10-12 00:23:25 +00:00
if (parentDir.name && !basePath) {
basePath = parentDir.name + '/' + this.name + '/';
continue;
}
if (parentDir.name && basePath) {
basePath = parentDir.name + '/' + basePath;
continue;
}
2019-10-16 17:11:28 +00:00
}
return basePath;
2019-10-16 16:12:18 +00:00
}
2024-05-20 23:22:21 +00:00
/**
* gets a file by name
*/
public async getFile(optionsArg: {
name: string;
createWithContents?: string | Buffer;
}): Promise<File> {
// check wether the file exists
const exists = await this.bucketRef.fastExists({
path: this.getBasePath() + optionsArg.name,
});
if (!exists && !optionsArg.createWithContents) {
return null;
}
if (!exists && optionsArg.createWithContents) {
await this.fastPut({
path: optionsArg.name,
contents: optionsArg.createWithContents,
});
}
return new File({
directoryRefArg: this,
fileName: optionsArg.name,
})
}
2019-10-16 16:12:18 +00:00
/**
* lists all files
*/
public async listFiles(): Promise<File[]> {
const done = plugins.smartpromise.defer();
2020-05-17 19:23:26 +00:00
const fileNameStream = await this.bucketRef.smartbucketRef.minioClient.listObjectsV2(
2019-10-16 16:12:18 +00:00
this.bucketRef.name,
2020-05-17 19:23:26 +00:00
this.getBasePath(),
false
2019-10-16 16:12:18 +00:00
);
const fileArray: File[] = [];
2024-05-17 16:53:11 +00:00
const duplexStream = new plugins.smartstream.SmartDuplex<plugins.minio.BucketItem, void>({
2024-05-17 17:09:00 +00:00
objectMode: true,
2024-05-17 16:53:11 +00:00
writeFunction: async (bucketItem) => {
2020-05-17 19:23:26 +00:00
if (bucketItem.prefix) {
return;
}
2020-05-17 15:57:12 +00:00
if (!bucketItem.name) {
2019-10-18 13:43:06 +00:00
return;
}
2019-10-19 23:19:34 +00:00
let subtractedPath = bucketItem.name.replace(this.getBasePath(), '');
if (subtractedPath.startsWith('/')) {
subtractedPath = subtractedPath.substr(1);
}
2019-10-18 13:43:06 +00:00
if (!subtractedPath.includes('/')) {
2024-05-17 16:53:11 +00:00
fileArray.push(
new File({
directoryRefArg: this,
fileName: subtractedPath,
})
);
2019-10-18 13:43:06 +00:00
}
2019-10-16 17:15:48 +00:00
},
2024-05-17 16:53:11 +00:00
finalFunction: async (tools) => {
2019-10-16 17:15:48 +00:00
done.resolve();
}
2024-05-17 16:53:11 +00:00
});
2019-10-16 16:12:18 +00:00
fileNameStream.pipe(duplexStream);
await done.promise;
return fileArray;
}
/**
* lists all folders
*/
2019-10-16 17:11:28 +00:00
public async listDirectories(): Promise<Directory[]> {
2019-10-16 16:12:18 +00:00
const done = plugins.smartpromise.defer();
2020-05-17 19:23:26 +00:00
const basePath = this.getBasePath();
const completeDirStream = await this.bucketRef.smartbucketRef.minioClient.listObjectsV2(
2019-10-16 16:12:18 +00:00
this.bucketRef.name,
2019-10-16 17:11:28 +00:00
this.getBasePath(),
2020-05-17 19:23:26 +00:00
false
2019-10-16 16:12:18 +00:00
);
2019-10-16 17:11:28 +00:00
const directoryArray: Directory[] = [];
2024-05-17 16:53:11 +00:00
const duplexStream = new plugins.smartstream.SmartDuplex<plugins.minio.BucketItem, void>({
2024-05-17 17:09:00 +00:00
objectMode: true,
2024-05-17 16:53:11 +00:00
writeFunction: async (bucketItem) => {
2020-05-17 19:23:26 +00:00
if (bucketItem.name) {
return;
}
let subtractedPath = bucketItem.prefix.replace(this.getBasePath(), '');
2019-10-19 23:18:13 +00:00
if (subtractedPath.startsWith('/')) {
subtractedPath = subtractedPath.substr(1);
}
2019-10-16 17:15:48 +00:00
if (subtractedPath.includes('/')) {
2019-10-19 23:18:13 +00:00
const dirName = subtractedPath.split('/')[0];
2020-10-12 00:37:50 +00:00
if (directoryArray.find((directory) => directory.name === dirName)) {
2019-10-16 17:15:48 +00:00
return;
}
directoryArray.push(new Directory(this.bucketRef, this, dirName));
2019-10-16 17:11:28 +00:00
}
2019-10-16 17:15:48 +00:00
},
2024-05-17 16:53:11 +00:00
finalFunction: async (tools) => {
2019-10-16 17:15:48 +00:00
done.resolve();
2019-10-16 17:11:28 +00:00
}
2024-05-17 16:53:11 +00:00
});
2019-10-16 16:12:18 +00:00
completeDirStream.pipe(duplexStream);
await done.promise;
2019-10-16 17:11:28 +00:00
return directoryArray;
2019-10-16 16:12:18 +00:00
}
/**
* gets an array that has all objects with a certain prefix;
*/
public async getTreeArray() {
2020-05-17 19:23:26 +00:00
const treeArray = await this.bucketRef.smartbucketRef.minioClient.listObjectsV2(
2019-10-16 16:12:18 +00:00
this.bucketRef.name,
2019-10-16 17:11:28 +00:00
this.getBasePath(),
2019-10-16 16:12:18 +00:00
true
);
}
2019-10-16 17:11:28 +00:00
/**
* gets a sub directory
*/
2019-10-18 16:37:43 +00:00
public async getSubDirectoryByName(dirNameArg: string): Promise<Directory> {
2019-10-19 23:18:13 +00:00
const dirNameArray = dirNameArg.split('/');
const getDirectory = async (directoryArg: Directory, dirNameToSearch: string) => {
const directories = await directoryArg.listDirectories();
2020-10-12 00:37:50 +00:00
return directories.find((directory) => {
2019-10-19 23:18:13 +00:00
return directory.name === dirNameToSearch;
});
};
let wantedDirectory: Directory;
for (const dirNameToSearch of dirNameArray) {
const directoryToSearchIn = wantedDirectory ? wantedDirectory : this;
wantedDirectory = await getDirectory(directoryToSearchIn, dirNameToSearch);
}
return wantedDirectory;
2019-10-16 17:11:28 +00:00
}
/**
* moves the directory
*/
2019-10-16 17:15:48 +00:00
public async move() {
2019-10-16 17:11:28 +00:00
// TODO
2022-03-30 23:45:46 +00:00
throw new Error('moving a directory is not yet implemented');
2019-10-16 17:11:28 +00:00
}
/**
* creates a file within this directory
2019-10-16 17:15:48 +00:00
* @param relativePathArg
2019-10-16 17:11:28 +00:00
*/
2021-06-02 09:14:24 +00:00
public async createEmptyFile(relativePathArg: string) {
2024-05-17 16:53:11 +00:00
const emtpyFile = await File.create({
directory: this,
name: relativePathArg,
contents: '',
});
2019-10-16 17:11:28 +00:00
}
2019-10-18 16:44:54 +00:00
// file operations
2024-05-17 16:53:11 +00:00
public async fastPut(optionsArg: { path: string; contents: string | Buffer }) {
const path = plugins.path.join(this.getBasePath(), optionsArg.path);
await this.bucketRef.fastPut({
path,
contents: optionsArg.contents,
});
2019-10-18 16:44:54 +00:00
}
2024-05-17 16:53:11 +00:00
public async fastGet(optionsArg: { path: string }) {
const path = plugins.path.join(this.getBasePath(), optionsArg.path);
const result = await this.bucketRef.fastGet({
path,
});
2019-10-19 20:57:36 +00:00
return result;
2019-10-18 16:44:54 +00:00
}
2020-06-19 00:42:26 +00:00
public async fastGetStream(pathArg: string): Promise<plugins.smartrx.rxjs.ReplaySubject<Buffer>> {
2019-10-20 10:27:58 +00:00
const path = plugins.path.join(this.getBasePath(), pathArg);
2024-05-17 16:53:11 +00:00
const result = await this.bucketRef.fastGetStream({
path,
});
2019-10-20 10:27:58 +00:00
return result;
}
2024-05-17 16:53:11 +00:00
public async fastRemove(optionsArg: { path: string }) {
const path = plugins.path.join(this.getBasePath(), optionsArg.path);
await this.bucketRef.fastRemove({
path,
});
2019-10-18 16:44:54 +00:00
}
2021-04-06 02:34:52 +00:00
/**
* deletes the directory with all its contents
*/
2024-05-17 16:53:11 +00:00
public async delete() {
2021-04-06 02:34:52 +00:00
const deleteDirectory = async (directoryArg: Directory) => {
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) {
2024-05-17 16:53:11 +00:00
await directoryArg.fastRemove({
path: file.name,
});
2021-04-06 02:34:52 +00:00
}
};
await deleteDirectory(this);
}
2019-10-16 16:12:18 +00:00
}