feat(core): Enhanced directory handling and file restoration from trash
This commit is contained in:
parent
8e9041fbbf
commit
154854dc21
@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2024-11-24 - 3.3.0 - feat(core)
|
||||||
|
Enhanced directory handling and file restoration from trash
|
||||||
|
|
||||||
|
- Refined getSubDirectoryByName to handle file paths treated as directories.
|
||||||
|
- Introduced file restoration function from trash to original or specified paths.
|
||||||
|
|
||||||
## 2024-11-24 - 3.2.2 - fix(core)
|
## 2024-11-24 - 3.2.2 - fix(core)
|
||||||
Refactor Bucket class for improved error handling
|
Refactor Bucket class for improved error handling
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ tap.test('should clean all contents', async () => {
|
|||||||
|
|
||||||
tap.test('should delete a file into the normally', async () => {
|
tap.test('should delete a file into the normally', async () => {
|
||||||
const path = 'trashtest/trashme.txt';
|
const path = 'trashtest/trashme.txt';
|
||||||
const file = await myBucket.fastPut({
|
const file = await myBucket.fastPutStrict({
|
||||||
path,
|
path,
|
||||||
contents: 'I\'m in the trash test content!',
|
contents: 'I\'m in the trash test content!',
|
||||||
});
|
});
|
||||||
@ -44,7 +44,7 @@ tap.test('should delete a file into the normally', async () => {
|
|||||||
|
|
||||||
tap.test('should put a file into the trash', async () => {
|
tap.test('should put a file into the trash', async () => {
|
||||||
const path = 'trashtest/trashme.txt';
|
const path = 'trashtest/trashme.txt';
|
||||||
const file = await myBucket.fastPut({
|
const file = await myBucket.fastPutStrict({
|
||||||
path,
|
path,
|
||||||
contents: 'I\'m in the trash test content!',
|
contents: 'I\'m in the trash test content!',
|
||||||
});
|
});
|
||||||
@ -60,4 +60,19 @@ tap.test('should put a file into the trash', async () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.test('should restore a file from trash', async () => {
|
||||||
|
const baseDirectory = await myBucket.getBaseDirectory();
|
||||||
|
const file = await baseDirectory.getFileStrict({
|
||||||
|
path: 'trashtest/trashme.txt',
|
||||||
|
getFromTrash: true
|
||||||
|
});
|
||||||
|
const trashFileMeta = await file.getMetaData();
|
||||||
|
const data = await trashFileMeta.getCustomMetaData({
|
||||||
|
key: 'recycle'
|
||||||
|
});
|
||||||
|
expect(file).toBeInstanceOf(smartbucket.File);
|
||||||
|
await file.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
export default tap.start();
|
export default tap.start();
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartbucket',
|
name: '@push.rocks/smartbucket',
|
||||||
version: '3.2.2',
|
version: '3.3.0',
|
||||||
description: 'A TypeScript library offering simple and cloud-agnostic object storage with advanced features like bucket creation, file and directory management, and data streaming.'
|
description: 'A TypeScript library offering simple and cloud-agnostic object storage with advanced features like bucket creation, file and directory management, and data streaming.'
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,9 @@ export class Directory {
|
|||||||
public parentDirectoryRef: Directory;
|
public parentDirectoryRef: Directory;
|
||||||
public name: string;
|
public name: string;
|
||||||
|
|
||||||
public tree: string[];
|
public tree!: string[];
|
||||||
public files: string[];
|
public files!: string[];
|
||||||
public folders: string[];
|
public folders!: string[];
|
||||||
|
|
||||||
constructor(bucketRefArg: Bucket, parentDirectory: Directory, name: string) {
|
constructor(bucketRefArg: Bucket, parentDirectory: Directory, name: string) {
|
||||||
this.bucketRef = bucketRefArg;
|
this.bucketRef = bucketRefArg;
|
||||||
@ -192,9 +192,22 @@ export class Directory {
|
|||||||
* gets a sub directory by name
|
* gets a sub directory by name
|
||||||
*/
|
*/
|
||||||
public async getSubDirectoryByName(dirNameArg: string, optionsArg: {
|
public async getSubDirectoryByName(dirNameArg: string, optionsArg: {
|
||||||
|
/**
|
||||||
|
* in s3 a directory does not exist if it is empty
|
||||||
|
* this option returns a directory even if it is empty
|
||||||
|
*/
|
||||||
getEmptyDirectory?: boolean;
|
getEmptyDirectory?: boolean;
|
||||||
|
/**
|
||||||
|
* in s3 a directory does not exist if it is empty
|
||||||
|
* this option creates a directory even if it is empty using a initializer file
|
||||||
|
*/
|
||||||
createWithInitializerFile?: boolean;
|
createWithInitializerFile?: boolean;
|
||||||
|
/**
|
||||||
|
* if the path is a file path, it will be treated as a file and the parent directory will be returned
|
||||||
|
*/
|
||||||
|
couldBeFilePath?: boolean;
|
||||||
} = {}): Promise<Directory | null> {
|
} = {}): Promise<Directory | null> {
|
||||||
|
|
||||||
const dirNameArray = dirNameArg.split('/').filter(str => str.trim() !== "");
|
const dirNameArray = dirNameArg.split('/').filter(str => str.trim() !== "");
|
||||||
|
|
||||||
optionsArg = {
|
optionsArg = {
|
||||||
@ -221,6 +234,17 @@ export class Directory {
|
|||||||
return returnDirectory || null;
|
return returnDirectory || null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (optionsArg.couldBeFilePath) {
|
||||||
|
const baseDirectory = await this.bucketRef.getBaseDirectory();
|
||||||
|
const existingFile = await baseDirectory.getFile({
|
||||||
|
path: dirNameArg,
|
||||||
|
});
|
||||||
|
if (existingFile) {
|
||||||
|
const adjustedPath = dirNameArg.substring(0, dirNameArg.lastIndexOf('/'));
|
||||||
|
return this.getSubDirectoryByName(adjustedPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let wantedDirectory: Directory | null = null;
|
let wantedDirectory: Directory | null = null;
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
for (const dirNameToSearch of dirNameArray) {
|
for (const dirNameToSearch of dirNameArray) {
|
||||||
@ -336,7 +360,7 @@ export class Directory {
|
|||||||
*/
|
*/
|
||||||
mode?: 'permanent' | 'trash';
|
mode?: 'permanent' | 'trash';
|
||||||
}) {
|
}) {
|
||||||
const file = await this.getFile({
|
const file = await this.getFileStrict({
|
||||||
path: optionsArg.path,
|
path: optionsArg.path,
|
||||||
});
|
});
|
||||||
await file.delete({
|
await file.delete({
|
||||||
|
@ -130,6 +130,29 @@ export class File {
|
|||||||
await this.parentDirectoryRef.listFiles();
|
await this.parentDirectoryRef.listFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* restores
|
||||||
|
*/
|
||||||
|
public async restore(optionsArg: {
|
||||||
|
useOriginalPath?: boolean;
|
||||||
|
toPath?: string;
|
||||||
|
overwrite?: boolean;
|
||||||
|
} = {}) {
|
||||||
|
optionsArg = {
|
||||||
|
useOriginalPath: (() => {
|
||||||
|
return optionsArg.toPath ? false : true;
|
||||||
|
})(),
|
||||||
|
overwrite: false,
|
||||||
|
...optionsArg,
|
||||||
|
};
|
||||||
|
const moveToPath = optionsArg.toPath || (await (await this.getMetaData()).getCustomMetaData({
|
||||||
|
key: 'recycle'
|
||||||
|
})).originalPath;
|
||||||
|
await this.move({
|
||||||
|
path: moveToPath,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* allows locking the file
|
* allows locking the file
|
||||||
* @param optionsArg
|
* @param optionsArg
|
||||||
@ -154,7 +177,7 @@ export class File {
|
|||||||
}) {
|
}) {
|
||||||
const metadata = await this.getMetaData();
|
const metadata = await this.getMetaData();
|
||||||
await metadata.removeLock({
|
await metadata.removeLock({
|
||||||
force: optionsArg?.force,
|
force: optionsArg?.force || false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +242,10 @@ export class File {
|
|||||||
// lets update references of this
|
// lets update references of this
|
||||||
const baseDirectory = await this.parentDirectoryRef.bucketRef.getBaseDirectory();
|
const baseDirectory = await this.parentDirectoryRef.bucketRef.getBaseDirectory();
|
||||||
this.parentDirectoryRef = await baseDirectory.getSubDirectoryByNameStrict(
|
this.parentDirectoryRef = await baseDirectory.getSubDirectoryByNameStrict(
|
||||||
pathDescriptorArg.directory?.getBasePath()!
|
await helpers.reducePathDescriptorToPath(pathDescriptorArg),
|
||||||
|
{
|
||||||
|
couldBeFilePath: true,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
this.name = pathDescriptorArg.path!;
|
this.name = pathDescriptorArg.path!;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user