feat(core): Enhanced directory handling and file restoration from trash
This commit is contained in:
		| @@ -1,5 +1,11 @@ | ||||
| # 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) | ||||
| 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 () => { | ||||
|   const path = 'trashtest/trashme.txt'; | ||||
|   const file = await myBucket.fastPut({ | ||||
|   const file = await myBucket.fastPutStrict({ | ||||
|     path, | ||||
|     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 () => { | ||||
|   const path = 'trashtest/trashme.txt'; | ||||
|   const file = await myBucket.fastPut({ | ||||
|   const file = await myBucket.fastPutStrict({ | ||||
|     path, | ||||
|     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(); | ||||
|   | ||||
| @@ -3,6 +3,6 @@ | ||||
|  */ | ||||
| export const commitinfo = { | ||||
|   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.' | ||||
| } | ||||
|   | ||||
| @@ -10,9 +10,9 @@ export class Directory { | ||||
|   public parentDirectoryRef: Directory; | ||||
|   public name: string; | ||||
|  | ||||
|   public tree: string[]; | ||||
|   public files: string[]; | ||||
|   public folders: string[]; | ||||
|   public tree!: string[]; | ||||
|   public files!: string[]; | ||||
|   public folders!: string[]; | ||||
|  | ||||
|   constructor(bucketRefArg: Bucket, parentDirectory: Directory, name: string) { | ||||
|     this.bucketRef = bucketRefArg; | ||||
| @@ -192,9 +192,22 @@ export class Directory { | ||||
|    * gets a sub directory by name | ||||
|    */ | ||||
|   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; | ||||
|     /** | ||||
|      * 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; | ||||
|     /** | ||||
|      * 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> { | ||||
|  | ||||
|     const dirNameArray = dirNameArg.split('/').filter(str => str.trim() !== ""); | ||||
|  | ||||
|     optionsArg = { | ||||
| @@ -221,8 +234,19 @@ export class Directory { | ||||
|       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 counter = 0;  | ||||
|     let counter = 0; | ||||
|     for (const dirNameToSearch of dirNameArray) { | ||||
|       counter++; | ||||
|       const directoryToSearchIn = wantedDirectory ? wantedDirectory : this; | ||||
| @@ -336,7 +360,7 @@ export class Directory { | ||||
|      */ | ||||
|     mode?: 'permanent' | 'trash'; | ||||
|   }) { | ||||
|     const file = await this.getFile({ | ||||
|     const file = await this.getFileStrict({ | ||||
|       path: optionsArg.path, | ||||
|     }); | ||||
|     await file.delete({ | ||||
|   | ||||
| @@ -130,6 +130,29 @@ export class File { | ||||
|     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 | ||||
|    * @param optionsArg | ||||
| @@ -154,7 +177,7 @@ export class File { | ||||
|   }) { | ||||
|     const metadata = await this.getMetaData(); | ||||
|     await metadata.removeLock({ | ||||
|       force: optionsArg?.force, | ||||
|       force: optionsArg?.force || false, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
| @@ -219,7 +242,10 @@ export class File { | ||||
|     // lets update references of this | ||||
|     const baseDirectory = await this.parentDirectoryRef.bucketRef.getBaseDirectory(); | ||||
|     this.parentDirectoryRef = await baseDirectory.getSubDirectoryByNameStrict( | ||||
|       pathDescriptorArg.directory?.getBasePath()! | ||||
|       await helpers.reducePathDescriptorToPath(pathDescriptorArg), | ||||
|       { | ||||
|         couldBeFilePath: true, | ||||
|       } | ||||
|     ); | ||||
|     this.name = pathDescriptorArg.path!; | ||||
|   } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user