SOLVED: Check if path is subdirectory of another in Node.JS

Introduction

This article discusses how you can determine if a path is a subdirectory of another in NodeJS. If you would like to follow along with this tutorial make sure you have NodeJS installed and if not go ahead and follow this installation tutorial to set it up.

 

The Problem

We want to determine if a path is subdirectory of another directory. For example, if you have two paths, /blog/category and /blog/category/node, you should return true as  /blog/category/node is a subdirectory of /blog/category. On the other hand, /blog/category and /news/category/node should not return true. Essentially, we want to check whether a path is a child of a parent path.

Advertisement

Before discussing how to go about the solution, let us first see how the NodeJS path module works.

 

NodeJS Path Module

The NodeJS path module provides utilities for working with paths in NodeJS. It provides different methods you can use to easily manipulate and analyze file paths. Since it is included in the standard library, you can use it without installation.

const path = require('path')

The following section covers some of the common path methods.

 

path.relative()

This method is used to find the relative path from one given path to another. It accepts two paths; the path `from` which is the base path and the path `to` which is used to find the relative path. If the paths are the same, path.relative() returns a zero-length string.

path.relative( from, to )

Consider the following code that uses path.relative()

const relPath1 = path.relative("blog/category", "blog/write");
console.log(relPath1)// output: ../write
const relPath2 = path.relative("blog/category", "post/node-path-module");
console.log(relPath2)// output: ../../post/node-path-module
// When both the paths are same
// It returns blank string
const relPath3 = path.relative("blog/category", "blog/category");
console.log(relPath3) // output: returns a zero length string as paths are the same

 

path.isAbsolute()

path.isAbsolute() is used to check whether or not a particular path is an absolute one or not. An absolute path refers to a path that contains all the details required to locate a file in a file system starting from the root element and ending with the other subdirectories. This method accepts one parameter that accepts the path to the file being checked if it's absolute. If the path is absolute, it returns true, if not it returns false.

Advertisement
path.isAbsolute( path )

Below is an example of path.isAbsolute() in use.

const absPath1 = path.isAbsolute('/foo/bar');
console.log(absPath1) // Output: true
const absPath2 = path.isAbsolute('/baz/..'); 
console.log(absPath2) // Output: true
const absPath3 = path.isAbsolute('qux/');    
console.log(absPath3) // Output: false
const absPath4 = path.isAbsolute('.');
console.log(absPath4) // Output: false

As illustrated, the path.isAbsolute() method returns a boolean that indicates whether the path is absolute or not.

 

path.Normalize()

Sometimes paths are written in shortcuts that include .. and . to make navigation easier. However, writing a long path like this can lead to readability issues which can then lead to human error. path.Normalize() is used to convert the paths with these shortcuts to actual paths with all the details included. This method accepts a string representing the path to be normalized as a parameter. The return value is a string of the normalized path.

path.normalize( path )

Below is an example of how to use path.Nomalize()

const normPath1 = path.normalize("/blog/category/.");
console.log(normPath1)// output: /blog/category
const normPath2 = path.normalize("/blog/../node");
console.log(normPath2) //output: /node
const normPath3 = path.normalize("/blog///admin///comments")
console.log(normPath3); // output: /blog/admin/comments

That's it! Those are some of the methods available on the path module. There are more methods than this and you should look at the documentation to learn more about them. This article only covered the methods that will be used in the solution below when determining if a subdirectory is a child of another directory.

 

Set Up NodeJS

Now that you know how to work with the path module, you can now proceed to the solution. In your preferred working directory, create a new file and name it ‘node-path.js’. Now you will need to set up a simple server to help you in your functions. Open the file you just created in your text editor and add the following code.

Advertisement
const http = require("http");
const requestListener = function (req, res) {
 res.end("Hello, World!");
};
const server = http.createServer(requestListener);
server.listen(3000);

To run your application, use the following command

node node-path.js

 

Using NodeJS Path

The NodeJS path is a module that provides the necessary utilities for working with files in NodeJS. To add it to your application, you do not need to import it since it comes with the standard library. Simply add it to your file using the following line of code.

const path = require('path');

Consider the following solution.

const http = require("http");
const path = require('path');
function checkIfSubDir (parent, dir) {
 const relative = path.relative(parent, dir);
 return relative && !relative.startsWith('..') && !path.isAbsolute(relative);
}
pathsToTest.forEach((paths) => {
   console.log(checkIfSubDir(paths[0], paths[1]))
 })
const requestListener = function (req, res) {
    res.end("Hello, World!");
};
const server = http.createServer(requestListener);
server.listen(3000);

Let’s understand the above code. In the first line, you are importing the path module. This provides the methods that will be used to analyze the directory paths. 

Next, you are declaring a function that accepts the parent directory path and the path to be evaluated.

The function works on the premise that if the child is a subdirectory of the parent, the relative path from the parent to the child will always start with '..'. The path.relative() method accepts two paths and returns the relative path from the ‘from’ directory to the ‘to’ directory. If the child is inside the parent, the relative path from the former to the latter will always start with '..'. 

Advertisement

To test this solution, try passing the following paths to your function.

[
 ['/foo', '/foo'],
 ['/foo', '/bar'],
 ['/foo', '/foobar'],
 ['/foo', '/foo/bar'],
 ['/foo', '/foo/../bar'],
 ['/foo', '/foo/./bar'],
 ['/bar/../foo', '/foo/bar'],
 ['/foo', './bar'],
 ['C:\\Foo', 'C:\\Foo\\Bar'],
 ['C:\\Foo', 'C:\\Bar'],
 ['C:\\Foo', 'D:\\Foo\\Bar']
 ];

You should expect the following solution.

false
false
true
false
true
true
false
false
false
false

The above solution will help you check whether a directory is a child of another directory. It is the perfect solution if you also want it to work on Windows.

 

Recap

In this article, you learned how to use the NodeJS path module to determine whether a NodeJS path is a subdirectory of another. The article started by first defining the problem that needed to be solved then gave a brief overview of the NodeJS path module. Finally, the article discussed the solution which checked to see if the relative path from the parent to the child started with '..'.

The solution to this problem is inspired by a StackOverflow solution to the same problem. If you want to learn more about the path module, do so by reviewing the NodeJS path documentation.

 

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X