Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if a path is subdirectory of another in Node.js

I am working on a MQTT handler for which I want to emit an event for each parent directory where there is a event listener. For example:

If there are the following MQTT paths available, where there are subscriptors –there are event listeners for these paths–

  • test
  • replyer/request
  • test/replyer/request

And someone publishes on topic test/replyer/request/@issuer, there should be 2 events emmited: test, test/replyer/request.

Given than any path is possible and there is no list of available valid events, we must check only if a path is a parent of another. Can we do this with regex? If so, how would it look like? Is there a simpler/more efficient solution?

like image 976
jsdario Avatar asked May 30 '16 09:05

jsdario


People also ask

How do you check if a path is a directory in node JS?

js? To check if a path is a directory in Node. js, we can use the stat() (asynchronous execution) function or the statSync() (synchronous execution) function from the fs (filesystem) module and then use the isDirectory() method returned from the stats object.

How do I find the relative path in node JS?

The path. relative() method is used to find the relative path from a given path to another path based on the current working directory. If both the given paths are the same, it would resolve to a zero-length string.

What is a relative path?

A relative path refers to a location that is relative to a current directory. Relative paths make use of two special symbols, a dot (.) and a double-dot (..), which translate into the current directory and the parent directory. Double dots are used for moving up in the hierarchy.

What is absolute path and relative path in NodeJS?

The difference between relative and absolute paths is that when using relative paths you take as reference the current working directory while with absolute paths you refer to a certain, well known directory.


1 Answers

Let Node itself do the work.

const path = require('path'); const relative = path.relative(parent, dir); return relative && !relative.startsWith('..') && !path.isAbsolute(relative); 

It does normalisation for you as well.

const path = require('path');  const tests = [   ['/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'], ];  tests.forEach(([parent, dir]) => {     const relative = path.relative(parent, dir);     const isSubdir = relative && !relative.startsWith('..') && !path.isAbsolute(relative);     console.log(`[${parent}, ${dir}] => ${isSubdir} (${relative})`); }); 

Works on Windows across drives too.

[/foo, /foo] => false () [/foo, /bar] => false (..\bar) [/foo, /foobar] => false (..\foobar) [/foo, /foo/bar] => true (bar) [/foo, /foo/../bar] => false (..\bar) [/foo, /foo/./bar] => true (bar) [/bar/../foo, /foo/bar] => true (bar) [/foo, ./bar] => false (..\Users\kozhevnikov\Desktop\bar) [C:\Foo, C:\Foo\Bar] => true (Bar) [C:\Foo, C:\Bar] => false (..\Bar) [C:\Foo, D:\Foo\Bar] => false (D:\Foo\Bar) 
like image 115
Ilya Kozhevnikov Avatar answered Oct 19 '22 11:10

Ilya Kozhevnikov