In-memory filesystem library in JavaScript

Implement a simple in-memory filesystem library in JavaScript that supports the following functionalities.

  • createDirectory(name) – Creates a new directory at the current path.
  • changeDirectory(path) – Changes the directory path.
  • addFile(name) – Adds a new file at the current path.
  • deleteFile(name) – Deletes the file with given name at the current path.
  • deleteDirectory(name) – Deletes the directory with given name at the given path.
  • getRootDirectory – Returns the root directory and all its nested childs.
  • getCurDirectory – Returns the items of current directory.
  • getCurDirectoryPath – Returns the path of the current directory.

To implement this function we will be extensively using Objects, working with objects is a complex task especially if you are not thoroughly aware of how objects as a reference can be used effectively.

Boilerplate.

const FileSystem = function(){
  this.directory = {"root": {}};
  this.currentDir = this.directory["root"];
  this.currentDirPath = "root";
};

Here we have defined 3 variables,

  1. directory – Holds the root directory.
  2. currentDir – Holds the reference to the root directory.
  3. currentDirPath – Holds the path of the current directory.

Create a new directory

A new directory is just a new object added to the given path.

this.createDirectory = function(name){
    this.currentDir[name] = {};
}

Change path of the directory

We accept the directory path as an absolute value separated by hyphen path-subpath-subpath. Once the directory changes, we also update the currentDir object reference. This way when you create a new directory or add a new file it will be added to the currentDir only.

Note – we are not checking if the directory exists or not.

  this.changeDirectory = function(path) {
    this.currentDir = this._changeDirectoryHelper(path);
    this.currentDirPath = path;
  }
  
  this._changeDirectoryHelper = function(path) {
    const paths = path.split("-");
    let current = this.directory;
    for(let key of paths){
      current = current[key];
    }
    
    return current;
  }

Get current directory.

Returns the current directory object.

this.getCurDirectoryPath = function(){
  return this.currentDirPath;
}

Get current directory path.

this.getCurDirectory = function(){
  return this.currentDir;
}

Add file

At the current path the files will be added to the key β€œfiles” as an array making it easy to add and remove them.

  this.addFile = function(fileName){
    if(this.currentDir.files){
      this.currentDir.files.push(fileName);
    }else{
      this.currentDir["files"] = [fileName];
    }
    return true;
  }

Remove file

To remove files simply filter the files array at the current directory.

  this.deleteFile = function(fileName){
    this.currentDir.files = this.currentDir.files.filter((e) => e !== fileName);
    return true;
  }

Delete the directory

To delete the directory, change to the current path and delete any of the sub-directory.

 this.deleteDirectory = function(name){
    delete this.currentDir[name];
  }

Get the root directory

Returns the root object.

this.getRootDirectory = function(){
    return this.directory;
}

Complete code

const FileSystem = function(){
  this.directory = {"root": {}};
  this.currentDir = this.directory["root"];
  this.currentDirPath = "root";
  
  this.createDirectory = function(name){
    this.currentDir[name] = {};
  }
  
  this.changeDirectory = function(path) {
    this.currentDir = this._changeDirectoryHelper(path);
    this.currentDirPath = path;
  }
  
  this._changeDirectoryHelper = function(path) {
    const paths = path.split("-");
    let current = this.directory;
    for(let key of paths){
      current = current[key];
    }
    
    return current;
  }
  
  this.getCurDirectoryPath = function(){
    return this.currentDirPath;
  }
  
  this.getCurDirectory = function(){
    return this.currentDir;
  }
  
  this.addFile = function(fileName){
    if(this.currentDir.files){
      this.currentDir.files.push(fileName);
    }else{
      this.currentDir["files"] = [fileName];
    }
    return true;
  }
  
  this.deleteFile = function(fileName){
    this.currentDir.files = this.currentDir.files.filter((e) => e !== fileName);
    return true;
  }
  
  this.deleteDirectory = function(name){
    delete this.currentDir[name];
  }
  
  this.getRootDirectory = function(){
    return this.directory;
  } 
}
Input:
const dir = new FileSystem();
dir.createDirectory('prashant');
dir.changeDirectory('root-prashant');
dir.addFile('index.html');
dir.addFile('app.js');
dir.changeDirectory('root');
dir.createDirectory('practice');
dir.changeDirectory('root-practice');
dir.addFile('index.html');
dir.addFile('app.js');
dir.createDirectory('build');
dir.changeDirectory('root-practice-build');
dir.addFile('a.png');
dir.addFile('b.jpg');
dir.deleteFile('a.png');
dir.changeDirectory('root');
dir.deleteDirectory('prashant');
console.log(dir.getRootDirectory());

Output:
{
  "root": {
    "practice": {
      "files": [
        "index.html",
        "app.js"
      ],
      "build": {
        "files": [
          "b.jpg"
        ]
      }
    }
  }
}

Not as we are using the object as a reference and making the updates on it, printing the directory and performing action after that will still show the updated object.