flavored-path
=============

_Node.js project_

#### "path" module revisited with backward compatibility and additional features ####

Version: 0.0.8

The goal of this module is to fix the current working directory issue, provide backward compatibility to the `path.normalize()` function (it's terribly bugged on Windows), provide forward compatibility with the `path.sep`, `path.delimiter` aliases and all future aditions and add additional useful methods.

This module uses [meta-path](https://github.com/Gagle/Node-MetaPath) to guarantee the backward compatibility. See its documentation to understand the problems and the fixes.

The primary intention is to use `flavored-path` as a complete replacement of the `path` built-in module.

Every time you call a fs built-in function I recommend to call to the [get()](#get) function:

```javascript
var fs = require ("fs");
var path = require ("flavored-path");
fs.exists (path.get ("my/path"), cb);
```

The [get()](#get) function will take care all the possible types of path (relative, absolute, network shared resource and relative from the home directory on Linux) and fix, resolve or whatever they need in order to work as expected.

#### Installation ####

```
npm install flavored-path
```

#### Example ####

```javascript
var fs = require ("fs");
var path = require ("flavored-path");

/*
path.get (".") is equivalent to __dirname but get() can be used with any type
of path, e.g.: Linux home paths (~/a/b).

On Linux, home paths are resolved to absolute files, so this snippet prints
all the entries in the user's home path.

On Windows, home paths are processed like regular relative paths, that is,
get() will return something like this: <cwd>/~/, so don't use ~ on Windows.

The Node.js built-in functions work the same way, for them ~ is processed
like a relative home path.
*/

fs.readdir (path.get ("~"), function (error, files){
	if (error) return console.log (error);
	console.log (files);
});
```

#### Methods and Properties ####

- [path.basename(p[, ext])](#basename)
- [path.delimiter](#delimiter)
- [path.dirname(p)](#dirname)
- [path.extname(p)](#extname)
- [path.get(p)](#get)
- [path.isAbsolute(p)](#isAbsolute)
- [path.isHome(p)](#isHome)
- [path.isNetwork(p)](#isNetwork)
- [path.isRelative(p)](#isRelative)
- [path.isRoot(p)](#isRoot)
- [path.join(path1, path2[, ...])](#join)
- [path.normalize(p)](#normalize)
- [path.prefix(p)](#prefix)
- [path.realpath(p)](#realpath)
- [path.relative(from, to)](#relative)
- [path.removePrefix(p)](#removePrefix)
- [path.resolve([from, [...]], to)](#resolve)
- [path.sep](#sep)

<a name="basename"></a>
__path.basename(p[, ext])__  
Same Node.js built-in function ([path.basename()](https://github.com/joyent/node/blob/master/doc/api/path.markdown#pathbasenamep-ext)).

<a name="delimiter"></a>
__path.delimiter__  
Same Node.js built-in function ([path.delimiter](https://github.com/joyent/node/blob/master/doc/api/path.markdown#pathdelimiter)).

<a name="dirname"></a>
__path.dirname(p)__  
Same Node.js built-in function ([path.dirname()](https://github.com/joyent/node/blob/master/doc/api/path.markdown#pathdirnamep)).

<a name="extname"></a>
__path.extname(p)__  
Same Node.js built-in function ([path.extname()](https://github.com/joyent/node/blob/master/doc/api/path.markdown#pathextnamep)).

<a name="get"></a>
__path.get(p)__  
Returns a path suitable for using with a `fs` built-in function. Every time you need to call to a `fs` function you can call to this function:

```javascript
fs.exists (path.get ("a"), cb);
```

You can pass any type of path. It will be normalized, fixed, resolved, whatever modification to convert the given path to a valid path for using with any `fs` built-in function.

The path is normalized and if the script is executed from a different directory from where the main script it's executed, e.g. `node a/app.js` instead of `node app.js`, the path is also be fixed. Example:

```javascript
//app.js
var path = require ("flavored-path");
console.log (path.get ("app.js"));
```

```
$ pwd
/home/gll
$ node a/app.js
a/app.js
```

If `flavored-path` it's used within a global module it makes no sense to try to fix a relative path because it's not needed. In this case the function only normalizes the path and returns it.

In fact, this function provides the same funcionality as the `__dirname` approach but also works in third-party modules whereas `__dirname` cannot be used in them.

<a name="isAbsolute"></a>
__path.isAbsolute(p)__  
Checks whether the path is absolute. An absolute path begins with `/` or `\` (the prefix is skipped, e.g.: `D:`), this means that network paths are also absolute. The given path doesn't need to be normalized. Returns true if is absolute, false otherwise.

<a name="isHome"></a>
__path.isHome(p)__  
Checks whether the path is relative from the user's home directory. A home path path begins with `~` (cannot contain a prefix), this means that home paths are also relative. The given path doesn't need to be normalized. Returns true if is a home path, false otherwise.

<a name="isNetwork"></a>
__path.isNetwork(p)__  
Checks whether the path is a network resource (on Windows world this is called a UNC path). A network path begins with `//` or `\\\\` (the prefix is skipped, e.g.: `smb:`). The given path doesn't need to be normalized. Returns true if is a network resource, false otherwise.

<a name="isRelative"></a>
__path.isRelative(p)__  
Checks whether the path is relative. A relative path begins with any character different from `/` or `\` (the prefix is skipped, e.g.: `D:`). The given path doesn't need to be normalized. Returns true if is relative, false otherwise.

<a name="isRoot"></a>
__path.isRoot(p)__  
Checks whether the path is a root. A root path is equal to `/`, `\`, `//` or `\\` (the prefix is skipped, e.g.: `D:`). The given path doesn't need to be normalized. Returns true if is a root path, false otherwise.

<a name="join"></a>
__path.join(path1, path2[, ...])__  
Same Node.js built-in function ([path.join()](https://github.com/joyent/node/blob/master/doc/api/path.markdown#pathjoinpath1-path2-)).

The joined path is correctly normalized.

```javascript
console.log (path.join ("smb://a//b", "c/")); //Prints: smb://a/b/c/
```

<a name="normalize"></a>
__path.normalize(p)__  
Same Node.js built-in function ([path.normalize()](https://github.com/joyent/node/blob/master/doc/api/path.markdown#pathnormalizep)).

Takes care all of the bugs found in the built-in normalize function explained in the [meta-path](https://github.com/Gagle/Node-MetaPath) module.

<a name="prefix"></a>
__path.prefix(p)__  
Returns the prefix. The prefix is the string before `:` (included).

<a name="realpath"></a>
__path.realpath(p)__  
An alias for the `resolve()` function. The real path of `.` it's the real current working directory with the relative fix applied.

```javascript
/*
You can overwrite the built-in cwd function and cache the result.
Now, the process.cwd() function will always return the same path if
you move across the directories and execute a script from outside of its
directory, so you don't need to call to get():

$ node app.js
$ node dir/app.js
$ node ../app.js
*/

process.cwd = (function (){
	var cwd = path.realpath (".");
	return function (){
		return cwd;
	};
})();
```

This is an error prone solution because you're overwritting a built-in Node.js function, and you may have other modules that may stop working properly. Use with caution.

<a name="relative"></a>
__path.relative(from, to)__  
Same Node.js built-in function ([path.relative()](https://github.com/joyent/node/blob/master/doc/api/path.markdown#pathrelativefrom-to)).

<a name="removePrefix"></a>
__path.removePrefix(p)__  
Returns the path without the prefix.

<a name="resolve"></a>
__path.resolve([from, [...]], to)__  
Same Node.js built-in function ([path.resolve()](https://github.com/joyent/node/blob/master/doc/api/path.markdown#pathresolvefrom--to)).

The absolute path that is returned fixes the current working directory issue.

The Linux relative home paths are resolved to its absolute path (only on Linux). The resolve built-in function doesn't provide this functionality. The `fs` built-in functions don't expand `~` to the user's home path, so when you deal with home paths you must convert it first to an absolute path:

```javascript
fs.exists (path.resolve ("~/a"), cb);
//Or simply:
//fs.exists (path.get ("~/a"), cb);
```

Network resource paths (paths that begin with `//`) are also resolved correctly.

Some examples:


```javascript
//app.js
console.log (path.resolve ("b", "c")); //Prints: /home/gll/a/b/c
console.log (path.resolve ("s", "~/a")); //Prints: /home/gll/a
console.log (path.resolve ("s", "/a", "b")); //Prints: /a/b
console.log (path.resolve ("s", "//a", "b")); //Prints: //a/b
```

```
$ pwd
/home/gll
$ node a/app.js
```

<a name="sep"></a>
__path.sep__  
Same Node.js built-in property ([path.sep](https://github.com/joyent/node/blob/master/doc/api/path.markdown#pathsep)).