Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »

common-path

1.0.1 • Public • Published

common-path

MIT license npm version Build Status Coverage Status

Finds the longest common parent directory path in an array of file paths.

Also returns parsed paths with common, sub, base and other useful parts.

File paths can be:

  • Path strings.
  • Custom objects with a property whose value is path string.

Works well on POSIX and Windows, with absolute, relative, UNC, namespaced paths etc.

Also works well with third-party path libraries like upath (see API below).

Example with POSIX absolute paths:

/*
   If you want to run this example on Windows, use commonPath.posix(paths)
   If you use upath, then commonPath.custom(upath, paths)
*/
 
const commonPath = require('common-path');
 
const paths = [
  '/projects/myapp/src/util/one.js',
  '/projects/myapp/test/fixtures/two.js',
]
 
const common = commonPath(paths);
console.log(common);
/*
  {
    commonRoot: '/',
    commonDir: '/projects/myapp',
    parsedPaths: 
    [
      {
        original: '/projects/myapp/src/util/one.js',
        subdir: 'src/util',
        commonPart: '/projects/myapp/',
        subPart: 'src/util/',
        basePart: 'one.js',
        namePart: 'one',
        extPart: '.js',
      },
      {
        original: '/projects/myapp/test/fixtures/two.js',
        subdir: 'test/fixtures',
        commonPart: '/projects/myapp/',
        subPart: 'test/fixtures/',
        basePart: 'two.js',
        namePart: 'two',
        extPart: '.js',
      }
    ]
  }
*/

Some quick notes, see API for details:

  • commonPath() does not resolve paths and expects normalized paths. It's probably best to use this library on path strings generated by path.resolve(), which returns normalized absolute paths.
  • If you pass an array of objects, original will be a reference to the original object.
  • If there is no common path, commonRoot, commonDir and all subdir values will be null. For example, C:\a.js and D:\a.js don't have a common path. This will also happen if you pass an array with different kinds of paths, e.g. absolute and relative paths in the same array.
  • To clarify the above, commonDir can be an empty string, which represents the current directory. This can happen only if you pass an array of relative paths that don't have a longer common path.
  • commonPart, subPart, basePart, namePart and extPart are always string values (never null). These values are sliced from the original path string:
    • commonPart + subPart + basePart === original (or === original[pathKey] if you pass objects)
    • namePart + extPart === basePart

This library correctly recognizes different kinds of paths and is aware of their specific rules, for instance:

  • \ is not a common path for \\server\share\a.js and \b.js. The first one is a UNC path.
  • \\server is not a common path for \\server\share1\a.js and \\server\share2\b.js. UNC path without a shared folder is not actually a path.
  • C: is not a common path for C:a.js and C:\b.js. The first one is a relative path.
  • C: is a common path for C:a.js and C:b.js.
  • \\?\ is not a common path for \\?\C:\a.js and \\?\D:\b.js. It's just a namespace prefix.
  • On POSIX, \ is not a common path for \a.js and \b.js. It's a part of the filenames.

Installation

$ npm install common-path

Works on Node 6 and above.

API

Overview

commonPath(paths, [pathKey])

Cross-platform function.

Uses Node.js path module utilities, namely path.parse() and path.sep.

Depending on the local platform, commonPath() works like commonPath.posix() or commonPath.windows().

commonPath.posix(paths, [pathKey])

POSIX-specific function.

Calls parse() and sep via path.posix.

commonPath.windows(paths, [pathKey])

Windows-specific function.

Calls parse() and sep via path.win32.

commonPath.custom(Path, paths, [pathKey])

The custom function can be used if you generate paths via a third-party library, e.g. upath:

const common = commonPath.custom(upath, paths);

Path is a custom replacement for Node's path module and should provide parse() and sep.

Be aware that third-party libraries might not correctly parse certain kinds of paths (e.g. UNC paths). If your application supports just 'usual' absolute or relative paths, everything should work fine.

commonPath(paths, [pathKey])

Everything in this section applies to all four functions.

paths

Array of strings or objects, or even a mixed array of strings and objects.

If an element is a string, that element itself represents a file path.

If an element is an object, file path string will be read from its pathKey property.

Notes:

  • This library does not resolve paths. For example, D:\a\b.js, \a\b.js and a\b.js might all represent the same file, but they are seen as different kinds of paths, and different kinds of paths will always have null as the common path. If your array can contain different kinds of paths (e.g. both absolute and relative), use path.resolve() on all paths.
  • This library expects and works well with normalized paths. Use path.resolve() as it returns normalized paths, or just path.normalize() if your array contains only relative paths and you want to find the relative common path.
  • This library is designed to work with file paths. Directory paths will be treated as file paths. For example, common path for /projects/myapp and /projects/myapp/test will be /projects.

commonPath() will throw an exception if paths is not an array.

commonPath() will throw an exception if paths array contains elements that are not string or object.

pathKey

If you want to pass an array of custom objects that contain path strings, use pathKeyto specify the name of a property whose value represents the path string.

This optional parameter will be ignored if the paths array contains just strings.

Example with objects, this time on Windows and with one file in the common directory:

/*
   If you want to run this example on POSIX, use commonPath.windows(paths)
*/
 
const commonPath = require('common-path');
 
const obj1 = { filePath: 'C:\\lib\\hash.js' };
const obj2 = { filePath: 'C:\\lib\\encode\\url.js' };
 
const paths = [obj1, obj2];
 
const common = commonPath(paths, 'filePath');
/*
  {
    commonRoot: 'C:\\',
    commonDir: 'C:\\lib',
    parsedPaths: 
    [
      {
        original: obj1, // reference to the same object
        subdir: '',
        commonPart: 'C:\\lib\\',
        subPart: '',
        basePart: 'hash.js',
        namePart: 'hash',
        extPart: '.js',
      },
      {
        original: obj2, // reference to the same object
        subdir: 'encode',
        commonPart: 'C:\\lib\\',
        subPart: 'encode\\',
        basePart: 'url.js',
        namePart: 'url',
        extPart: '.js',
      }
    ]
  }
*/

commonPath() will throw an exception if pathKey is not a string or undefined.

commonPath() will throw an exception if the paths array contains object elements and pathKey is undefined. It will also throw an exception if at least one object[pathKey] is not a string.

returns

A structure as shown in the example.

Each element in the parsedPaths array represents an element from the original paths array, in the same order.

commonRoot

Root is the root value returned by path.parse().

If all paths have the same root, commonRoot will have that value.

Otherwise, commonRoot will be null. Consequently, commonDir and all subdir values will be null.

If the paths array contains only relative paths, commonRoot will be an empty string (it can also be C: on Windows, if all paths are in the form of C:a.js, C:b\c.js etc. these are also relative paths)

commonDir

Path to the longest common directory.

commonRoot is a substring of commonDir.

commonDir can have trailing separator only if it equals commonRoot, and commonRoot has trailing separator. For example: /, \, C:\, \\server\share\.

In all other cases, this string will not have trailing path separator.

original

Original path string, or a reference to the original object from the paths array.

subdir

subdir is a relative path from the commonDir to the directory in which the file is.

It will be null if the commonDir is null.

It will be an empty string if the file is in the commonDir.

This string will never have a trailing path separator, provided that you pass normalized paths.

This string will also never have a leading path separator.

commonPart, subPart, basePart

These strings are sliced directly from the original path string. They are never null.

commonPart is commonDir plus a trailing separator if there is one in the original path string and the commonDir itself doesn't have a trailing separator.

basePart is base returned by path.parse().

commonPart is sliced from the start, basePart from the end. subPart is anything left between.

commonPart + subPart + basePart always equals the original path string.

This holds even if the commonDir is null, in which case the commonPart will be an empty string:

/*
   If you want to run this example on POSIX, use commonPath.windows(paths)
*/
 
const commonPath = require('common-path');
 
const paths = [
  'C:\\a.js',
  'D:\\a.js',
]
 
const common = commonPath(paths);
console.log(common);
/*
  {
    commonRoot: null,
    commonDir: null,
    parsedPaths: 
    [
      {
        original: 'C:\\a.js',
        subdir: null,
        commonPart: '',
        subPart: 'C:\\',
        basePart: 'a.js',
        namePart: 'a',
        extPart: '.js',
      },
      {
        original: 'D:\\a.js',
        subdir: null,
        commonPart: '',
        subPart: 'D:\\',
        basePart: 'a.js',
        namePart: 'a',
        extPart: '.js',
      }
    ]
  }
*/
namePart, extPart

namePart and extPart are name and ext values returned by path.parse().

Related

cross-path-sort - Sort file paths

Author

Milos Djermanovic

License

MIT License

Install

npm i common-path

DownloadsWeekly Downloads

288

Version

1.0.1

License

MIT

Unpacked Size

20.8 kB

Total Files

5

Last publish

Collaborators

  • avatar