Cross-platform file path sorting. Sort an array of path strings or objects containing path strings.
npm install cross-path-sort   
Cross-platform non-destructive file path sorting function.
Pass in an array of path strings or objects with a property whose value is path string. Get a new array with
the same elements, sorted in a more intuitive way than with a simple sort:
* You can use shallowFirst/deepFirst options to separate the content of a directory from the content of its subdirectories.
``
simple sort vs this function with the shallowFirst option
one.js one.js
test/one_spec.js two.js
test/two_spec.js test/one_spec.js
two.js test/two_spec.js
`
* Different types of paths (relative, absolute, home, UNC, namespaced...) in the same array are always separated.
You can change the default order of types.
`
simple sort vs this function on Windows
api.js api.js
C:\util\hash.js engine.js
engine.js C:\util\hash.js
`
The sort function:
* Works well with all kinds of paths on all platforms on which Node.js can be installed.
* Parses and sorts paths based on the platform on which it is running. See the Platforms section below for details.
* Normalizes path strings, but it always returns same strings/objects from the original array.
* Does not access the file system, it just works with the strings.
* By design, does not throw any exceptions related to the content of the paths array.
``
$ npm install cross-path-sort
This particular example will produce the same results on all platforms since
the forward slash / is a valid separator on both Windows and POSIX (Linux, Unix, macOS...) systems:
`js
const crossPathSort = require('cross-path-sort');
const paths = [
'one.js',
'test/one_spec.js',
'/mylibs/hash.js',
'two.js',
'/mylibs/encode/url.js',
'/mylibs/assign.js',
'test/shared/init.js',
'test/two_spec.js',
'config/env.js'
];
const sortedPaths1 = crossPathSort.sort(paths, { shallowFirst: true });
/*
[
'one.js',
'two.js',
'config/env.js',
'test/one_spec.js',
'test/two_spec.js',
'test/shared/init.js',
'/mylibs/assign.js',
'/mylibs/hash.js',
'/mylibs/encode/url.js'
]
*/
const sortedPaths2 = crossPathSort.sort(paths, { deepFirst: true });
/*
[
'config/env.js',
'test/shared/init.js',
'test/one_spec.js',
'test/two_spec.js',
'one.js',
'two.js',
'/mylibs/encode/url.js',
'/mylibs/assign.js',
'/mylibs/hash.js'
]
*/
// if you just want to separate path types
const sortedPaths3 = crossPathSort.sort(paths);
/*
[
'config/env.js',
'one.js',
'test/one_spec.js',
'test/shared/init.js',
'test/two_spec.js',
'two.js',
'/mylibs/assign.js',
'/mylibs/encode/url.js',
'/mylibs/hash.js'
]
*/
`
Had we used the backslash \ instead, results would be different on different platforms.
The cross-platform sorting function assumes that the paths it works on are related to the operating system on which it is running.
In other words, it assumes that the paths are either locally generated by your application or specified by its user.
The paths are normalized, parsed and sorted accordingly.
This module exposes three functions:
* sort() is the cross-platform sorting function, which you should use.posix.sort()
* is POSIX-specific sorting function.windows.sort()
* is Windows-specific sorting function.
Depending on the local platform, sort() works like posix.sort() or windows.sort().
You should always use just sort() unless you have a specific application that doesn't work with local paths.
`js
const crossPathSort = require('cross-path-sort');
// escaped backslash
const paths = ['b\\a.js', 'c.js', 'a.js'];
// on windows: b\a.js = file a.js in subdirectory b
const sortedOnWindows = crossPathSort.windows.sort(paths, { shallowFirst: true });
/*
[
'a.js',
'c.js',
'b\\a.js'
]
*/
// on posix: b\a.js = file b\a.js
const sortedOnPosix = crossPathSort.posix.sort(paths, { shallowFirst: true });
/*
[
'a.js',
'b\\a.js',
'c.js'
]
*/
const sortedLocally = crossPathSort.sort(paths, { shallowFirst: true });
/*
same as sortedOnWindows or sortedOnPosix, depending on your platform
*/
`
All three functions have the same signature.
#### parameters
paths is an array of path strings or objects, see the _paths_ and _pathKey_ sections.
options is an options object. All options are optional, and the whole object is optional.
#### returns
The function returns a new, sorted array with the exact same elements from the paths array.
#### exceptions
Only if you specify invalid options. See the options below for details.
#### example
All options with their default values:
`js`
const sortedPaths = crossPathSort.sort(paths, {
pathKey: undefined,
shallowFirst: false,
deepFirst: false,
homePathsSupported: false,
posixOrder: ['rel', 'home', 'abs'],
windowsOrder: ['rel', 'home', 'abs', 'drel', 'dabs', 'unc', 'nms'],
segmentCompareFn: (a, b) => a.localeCompare(b)
});
Array of strings or objects, or even a mixed array of strings and objects.
By design, this array can contain anything:
* string elements and object elements whose object[pathKey] is string will be treated equally and sorted.
* All other elements will be treated as 'unreadable' and come after the sorted elements.
* Holes will be preserved and come at the very end of the resulting array.
If paths is not an array, sort() will simply return the same value.
If you want to sort an array of your custom objects that contain path strings, use the pathKey option
to specify the key of a property whose value represents the path string.
If specified, pathKey should be a string.
Path string of an object element from the paths array will be read from object[pathKey].
Notes:
* If your array has a mixed content, pathKey will be used only for object elements and ignored for string elementsstring
( element itself represents a path).object[pathKey]
* If is not a string, that object element will be treated as 'unreadable'.pathKey
* If you don't specify , all object elements will be treated as 'unreadable'.
Example:
`js
const crossPathSort = require('cross-path-sort');
const obj1 = { file: 'c.js' };
const obj2 = { file: 'b/a.js' };
const obj3 = {};
const obj4 = { file: 'a.js'};
const paths = [obj1, obj2, obj3, obj4];
const sortedPaths = crossPathSort.sort(paths, {
pathKey: 'file',
shallowFirst: true
});
/*
[obj4, obj1, obj2, obj3]
*/
`
If your array contains just string elements, you can leave this value undefined.
sort() will throw an exception if the pathKey argument itself is not a string or undefined.
sort() will __NOT__ throw an exception if object[pathKey] is not a string.
Default values are false. Only one can be set to true.
Sort has three modes:
* If shallowFirst is true, content of a directory will come _before_ the content of its subdirectories.deepFirst
* If is true, content of a directory will come _after_ the content of its subdirectories.false
* If both values are , file names will be compared with subdirectory names.
See the example in the Installation and Usage section above.
sort() will throw an exception if both shallowFirst and deepFirst have a truthy value.
Default value is false and paths starting with ~ are treated as _relative paths_, as the tilde is
a valid character for file names and directory names on all systems.
This is in line with how Node's modules such as fs or path treat these paths.
If your application explicitly supports shell-specific paths like ~/ or ~user/, and you want~
the paths starting with to appear in a different partition of the resulting array as _home paths_, settrue
this value to .
Regarding the next section:
* If homePathsSupported is false, paths starting with ~ will be 'rel' paths. home
There will be no paths.homePathsSupported
* If is true, paths starting with ~ will be 'home' paths.
These options specify the order of different path types in the resulting array.
sort() uses posixOrder on POSIX platforms, windowsOrder on Windows platforms.
#### POSIX path types
* 'rel' are relative paths, such as a.js and b/a.js.'home'
* are home paths, see the previous section.'abs'
* are absolute paths, such as /a.js and /b/a.js.
posixOrder default value is: ['rel', 'home', 'abs']
#### Windows path types
* 'rel' are relative paths, such as a.js and b\a.js'home'
* are home paths, see the previous section.'abs'
* are absolute paths, such as \a.js and \b\a.js.'drel'
* are relative paths with a specified drive, such as C:a.js and C:b\a.js.'dabs'
* are absolute paths with a specified drive, such as C:\a.js and C:\b\a.js.'unc'
* are UNC paths, such as \\server\share\a.js and \\server\share\b\a.js.'nms'
* are namespaced paths - paths starting with \\?\ or \\.\.
windowsOrder default value is: ['rel', 'home', 'abs', 'drel', 'dabs', 'unc', 'nms']
Since the forward slash / is a valid separator on Windows, paths like /a.js on Windows are also 'abs' type paths,C:/a.js
paths like on Windows are also 'dabs' type paths etc.
Example:
`js
const crossPathSort = require('cross-path-sort');
const paths = [
'one.js',
'test/one_spec.js',
'/mylibs/hash.js',
'two.js',
'/mylibs/encode/url.js',
'/mylibs/assign.js',
'test/shared/init.js',
'test/two_spec.js',
'config/env.js'
];
// position of the 'home' type is irrelevant if homePathsSupported is not true
const sortedPaths1 = crossPathSort.sort(paths, {
shallowFirst: true,
posixOrder: ['abs', 'home', 'rel'],
windowsOrder: ['abs', 'dabs', 'unc', 'nms', 'drel', 'home', 'rel']
});
/*
[
'/mylibs/assign.js',
'/mylibs/hash.js',
'/mylibs/encode/url.js',
'one.js',
'two.js',
'config/env.js',
'test/one_spec.js',
'test/two_spec.js',
'test/shared/init.js'
]
*/
`
sort() will throw an exception if the posixOrder argument is not an array or undefined.array
An must be a permutation of the default array. The same applies to the windowsOrder argument.
Function used to compare path segments such as file names, directory names, drive letters etc.
Default function is: (a, b) => a.localeCompare(b)
If you don't specify this option, the default function will be used.
Your custom function should work like a function you would use with Array.prototype.sort().
The function will always get two string values, and should return a number that is < 0, 0 or > 0.
sort() will throw an exception if segmentCompareFn is not a function or undefined.sort()
Also, does not catch exceptions thrown by your function.sort()` will throw that exception.
If your function throws an exception, the whole