# common-path

> Finds the longest common parent directory path in an array of file path strings or custom objects. Also returns sub and base parts for each path.

Latest version **1.0.1** (published 2020-02-17) · MIT license · 0 weekly downloads

## Install

```sh
npm install common-path
pnpm add common-path
yarn add common-path
bun add common-path
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.1 |
| Published | 2020-02-17 |
| First published | 2018-12-09 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Node | >=6 |
| Dependencies | 0 |
| Unpacked size | 20.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 2 |
| Author | Milos Djermanovic |
| Maintainers | mdjermanovic |
| Keywords | path, paths, common, shared, parent, prefix, same, longest, max, deepest, dir, directory, folder, absolute, relative, unc, find, array, file, files, root, cross-platform, windows, posix |

## Links

- npm: https://www.npmjs.com/package/common-path
- Repository: https://github.com/mdjermanovic/common-path
- Homepage: https://github.com/mdjermanovic/common-path#readme
- Issues: https://github.com/mdjermanovic/common-path/issues
- npm.io page: https://npm.io/package/common-path

## Alternatives

- [base64url](https://npm.io/package/base64url.md) — 6.1M weekly downloads
- [get-installed-path](https://npm.io/package/get-installed-path.md) — 502.9K weekly downloads
- [@uppy/url](https://npm.io/package/@uppy/url.md) — 185.8K weekly downloads
- [@d3fc/d3fc-shape](https://npm.io/package/@d3fc/d3fc-shape.md) — 16.2K weekly downloads
- [localizer](https://npm.io/package/localizer.md) — 226 weekly downloads

## Recent versions

- 1.0.1 (latest) — 2020-02-17
- 1.0.0 — 2018-12-09

## README

# common-path

[![MIT license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/mdjermanovic/common-path/blob/master/LICENSE) [![npm version](https://img.shields.io/npm/v/common-path.svg?style=flat)](https://www.npmjs.com/package/common-path) [![Build Status](https://travis-ci.org/mdjermanovic/common-path.svg?branch=master)](https://travis-ci.org/mdjermanovic/common-path) [![Coverage Status](https://coveralls.io/repos/github/mdjermanovic/common-path/badge.svg?branch=master)](https://coveralls.io/github/mdjermanovic/common-path?branch=master)

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](https://www.npmjs.com/package/upath) (see API below).

Example with POSIX absolute paths:

```js
/*
   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()](https://nodejs.org/api/path.html#path_path_resolve_paths),
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

```console
$ npm install common-path
```

Works on Node 6 and above.

## API

### Overview

#### commonPath(paths, [pathKey])

Cross-platform function. 

Uses [Node.js path module](https://nodejs.org/api/path.html) utilities, namely 
[path.parse()](https://nodejs.org/api/path.html#path_path_parse_path) and [path.sep](https://nodejs.org/api/path.html#path_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](https://nodejs.org/api/path.html#path_path_posix).

#### commonPath.windows(paths, [pathKey])

Windows-specific function.

Calls `parse()` and `sep` via [path.win32](https://nodejs.org/api/path.html#path_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:

```js
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()](https://nodejs.org/api/path.html#path_path_resolve_paths) on all paths.
* This library expects and works well with __normalized__ paths. 
Use [path.resolve()](https://nodejs.org/api/path.html#path_path_resolve_paths) as it returns normalized paths,
or just [path.normalize()](https://nodejs.org/api/path.html#path_path_normalize_path) 
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 `pathKey `to 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:

```js
/*
   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()](https://nodejs.org/api/path.html#path_path_parse_path).

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()](https://nodejs.org/api/path.html#path_path_parse_path).

`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:

```js
/*
   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()](https://nodejs.org/api/path.html#path_path_parse_path).

## Related

[cross-path-sort](https://github.com/mdjermanovic/cross-path-sort) - Sort file paths

## Author

[Milos Djermanovic](https://github.com/mdjermanovic)

## License

[MIT License](https://github.com/mdjermanovic/common-path/blob/master/LICENSE)

---
_Source: https://npm.io/package/common-path · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
