class FakeFileSystem { constructor() { this.currentPath='/' this.path2dir = {} } /* loadStructure : loads an object like dirname: [ subojbects ] */ loadStructure(struct, files) { this._scanStruct('/', struct, files || []); } _scanStruct(locPath, struct, files){ this.path2dir[locPath]={ /* assign local files & local folers*/ files: [...files.filter(item=>{ let filePath = (item.fullPath.split('/').length>2) ? item.fullPath.substr(0,item.fullPath.lastIndexOf('/')) : '/' return(filePath==locPath) })], folders: [...Object.keys(struct).map(item=> { let folderPath = (locPath=='/') ? '/'+item: locPath+'/'+item let childrenFiles = files.filter(item=>(item.object.path==folderPath)) return({ name:item, path: folderPath, isEmpty:( (Object.keys(struct[item]).length==0) && (childrenFiles.length==0) ) }) })] } if(locPath!='/') this.path2dir[locPath].folders.unshift({name:'..', path:'..'}) this.path2dir[locPath].files.sort((a,b)=>((a.object.name((a.name(item.fullPath.length>subPath.length)) this._scanStruct( subPath, struct[folderName], childrenFiles ) } } /* getFolder : returns an alphabetically sorted array of folders at the current path */ getFolders(){ return(this.path2dir[this.currentPath].folders) } /* getFiles : returns an alphabetically sorted array of files at the current path */ getFiles(){ return(this.path2dir[this.currentPath].files) } /* findFile : returns the path of the first file than validates the comparison function. The comparison function is given the file object as parameter, and should return a boolean. */ findFile(fn){ for(let path of Object.keys(this.path2dir)){ for(let file of this.path2dir[path].files){ if(fn(file.object)) return(path) } } return(false) } /* changeDir : changes the current path, relatively or absolutely */ changeDir(path){ if(path.startsWith('/')){ //Absolute if(this.pathExists(path)) this.currentPath = path } else { //relative let newPath = this.normalizePath(this.currentPath+'/'+path) if(newPath=='') newPath='/' if(this.pathExists(newPath)) this.currentPath = newPath } } /* pathExists : Check if path (file excluded) exists in the structure */ pathExists(path){ return(Object.keys(this.path2dir).includes(path)) } /* normalizePath : cleans up and normalizes (executes all /../) */ normalizePath(path) { path = path.replace(/\/+/g, '/') if (path.startsWith("/")) path = path.substring(1) if (path.endsWith("/")) path = path.slice(0, -1) let segments = path.split("/") let normalizedPath = "/" for(let segment of segments) { if (segment === "." || segment === "") continue if (segment === "..") { normalizedPath = normalizedPath.substring(0, normalizedPath.lastIndexOf("/") ) continue } if (!normalizedPath.endsWith("/")) normalizedPath = normalizedPath + "/" normalizedPath = normalizedPath + segment } return(normalizedPath) } } app.registerClass('FakeFileSystem', FakeFileSystem)