node package manager

filepath

A cross platform utility interface for working with filesystems in Node.js.

Filepath

A cross platform interface for working with the file system in Node.js programs. Yes, it works with both posix and win32. So there.

Built by @kixxauth

The most common use of Filepath is to use it as a library. In that case, just include it in your Node.js project by adding a line for "filepath" in your pacakge.json dependencies. For more information about your package.json file, you should check out the npm documentation by running npm help json.

Alternatively, you can quickly install Filepath for use in a project by running

npm install filepath

which will install filepath in your node_modules/ folder.

var filepath = require('filepath');

FilePath.create just takes a string to create a new path object:

var path = filepath.create(__filname);

It's important to remember that a FilePath instance is not a String. The 'path' property of a FilePath instance is the string representation of the FilePath instance, which is the same thing as calling .toString().

console.log(path);
// "{ [String: '/Users/kris/filepath/README.md'] path: '/Users/kris/filepath/README.md' }"
 
path.path; // "/Users/kris/filepath/README.md"
path.valueOf(); // "/Users/kris/filepath/README.md"
path.toString(); // "/Users/kris/filepath/README.md"
path + ''; // "/Users/kris/filepath/README.md"
 
assert(path.path === path.toString())

About Promises

About Error Handling

Returns a new FilePath instance. Defaults to the current working directory if you don't pass any arguments.

var path = filepath.create();
assert(path.toString() === process.cwd());
path.toString();
// "/Users/kris/projects/filepath"

Joins multiple arguments into a single path object.

var path = filepath.create(__dirname, 'foo', 'bar');
assert(path.toString() === __dirname + '/foo/bar');
path.path; // "/Users/kris/projects/filepath/foo/bar"

Returns a FilePath instance representing the root system path.

// On a posix system:
assert(filepath.root().toString() === '/');

Returns a FilePath instance representing the users's home directory. This is achieved using environment variables process.env.HOME on posix and process.env.USERPROFILE on win32.

assert(filepath.home().toString() === '/home/kris');

Joins an arbitrary number of arguments and appends them onto the path. Returns a new FilePath instance, leaving the original intact.

var path1 = filepath.create(__dirname);
var path2 = path1.append('foo', 'bar');
var path3 = path1.append('baz');
 
assert(path1.toString() === __dirname);
assert(path2.toString() === __dirname + '/foo/bar');
assert(path3.toString() === __dirname + '/baz');

Resolves a relative path with this one. Returns a new FilePath instance, leaving the original intact.

var path = filepath
  .create('/home/kris/filepath/lib')
  .resolve('../README.md');
 
assert(path.toString() === '/home/kris/filepath/README.md');

Pops off the file or directory basename. The same as doing ../ on a posix system. Returns a new FilePath instance.

var path = filepath.create('/home/kris/filepath').dir();
 
assert(path.toString() === '/home/kris');

Copies the current path to the given path. Resolves with a new FilePath instance representing the new location. Also can be invoked synchronously.

See also: Promises and Error Handling

filepath
  .create(__filename)
  .copy('/tmp/README.md')
  .then(function (target) {
    // The callback value `target` is a new FilePath instance.
    assert(target.toString() === '/tmp/README.md');
  })
  .catch(console.error);

Pass in mixed parts as the target.

var targetDir = filepath.root().append('tmp');
filepath
  .create(__filename)
  .copy(targetDir, 'README.md');

Or you can copy a file synchronously:

var target = filepath
  .create(__filename)
  .copy('/tmp/README.md', {sync: true});
assert(target.toString() === '/tmp/README.md');

Removes a FilePath. This is done by calling native Node.js fs.unlinkSync. There is no asynchronous pattern for #remove(). Returns the FilePath instance.

var path = filepath.create(__filename);
assert(path.exists());
path.remove();
assert(!path.exists());

Returns the stringified version of a FilePath. This is the same thing as the .path attribute, and doing path + ''.

path.toString(); // "/Users/kris/filepath/README.md"
path.path; // "/Users/kris/filepath/README.md"
path.valueOf(); // "/Users/kris/filepath/README.md"
path + ''; // "/Users/kris/filepath/README.md"

Same as #toString().

Returns the last part of the path only. If you pass in the extension string, it will not be included in the returned part. Note that #basename() returns a String and not a FilePath instance.

var path = filepath.create('/home/kris/projects/filepath/README.md');
assert(path.basename() === 'README.md');
assert(path.basename('.md') === 'README');

Returns the extension of the last part of the path. Note that #extname() returns a String and not a FilePath instance.

var ext = filepath.create('/home/kris/projects/filepath/README.md').extname();
assert(ext === '.md');

Splits a FilePath into an Array of parts. Each element in the Array is a String.

var parts = filepath.create('/home/kris/projects/filepath/README.md').split();
assert(Array.isArray(parts));
assert(parts[0] === 'home');
assert(parts.pop() === 'README.md');

Returns the relative String required to reach the passed in path. Note that #relative() returns a String and not a FilePath instance.

var rel = filepath
  .create('/home/kris/projects/filepath/lib')
  .relative('/home/kris/projects/filepath/test');
 
assert(rel === '../test');

Check to see if a FilePath is present on the filesystem. Returns a Boolean.

var path = filepath.create(__dirname);
assert(path.exists());
assert(!path.append('foo').exists());

Check to see if a FilePath is a file type on the filesystem. This is accomplished using stats.isFile(). If the FilePath does not exist, #isFile() will return false rather than throwing an Error. Returns a Boolean.

var path = filepath.create(__filename);
assert(path.isFile());

Check to see if a FilePath is a directory type on the filesystem. This is accomplished using stats.isDirectory(). If the FilePath does not exist, #isFile() will return false rather than throwing an Error. Returns a Boolean.

var path = filepath.create(__dirname)
assert(path.isDirectory())

Reads the contents of a file. This can be called asynchronously (by default) or synchronously. If the path is not a file type, it will throw an ExpectFileError. The default encoding is 'utf8', which means you will get a String back. Set the encoding to null to get a Buffer instead. Any options passed in (including 'encoding') will be passed to Node.js native fs.readFile().

read() returns a Promise for the file contents unless you run it synchronously. If the file does not exist, it will return null. See also: Promises and Error Handling

var path = filepath.create(__filename);
 
// #read() returns a promise object with #then() and #catch() methods.
path.read()
  .then(function assertResult(contents) {
    assert(typeof contents === 'string');
  }).catch(console.error);
 
// Or you can read a file *synchronously*:
var readmeContents = path.read({sync: true, encoding: null});
assert(readmeContents instanceof Buffer);

Writes a file with the given content. This can be called asynchronously (by default) or synchronously. If the path is not a file type, it will throw an ExpectFileError. If the file does not exist, it will be created. The default encoding is 'utf8' which means you are passing #write() a String. Set the encoding to null to pass a Buffer instead. Any options passed in (including 'encoding') will be passed to Node.js native fs.writeFile().

write() returns a Promise for the FilePath instance unless you run it synchronously. See also: Promises and Error Handling

var path = filepath.create('/tmp/new_file.txt')
 
path.write('Hello world!\n')
  .then(function assertResult(returnedPath) {
    assert(returnedPath === path);
    assert(path.read({sync: true}) === 'Hello world!\n');
  })
  .catch(console.error);
 
// Or you can write a file *synchronously*:
var syncPath = filepath.create('/tmp/new_file_sync.txt');
syncPath.write('Overwrite with this text', {sync: true});
assert(syncPath.read({sync: true}) === 'Hello world!\n');

Require a module using Node.js native require(). You'll need to pass in the current require function to have the correct context for requiring a module.

var path = filepath.create(__dirname, 'index.js');
var filepath = path.require(require);
assert(filepath === filepath);

Creates a new Read Stream from the FilePath. This can be used in streaming APIs.

var FS = require('fs');
var stream = filepath.create(__filename).newReadStream();
assert(stream instanceof FS.ReadStream);

Creates a new Write Stream from the FilePath. This can be used in streaming APIs.

var FS = require('fs');
var stream = filepath.create('/tmp/new_file.txt').newWriteStream();
assert(stream instanceof FS.WriteStream);

Create a directory, unless it already exists. Will create any parent directories which do not already exist. Works kinda like 'mkdir -P'. Returns the FilePath instance.

var path = filepath.create('/tmp/some/new/deep/dir').mkdir();
assert(path instanceof filepath.FilePath);
assert(path.isDirectory());

List paths in a directory. Listing a directory returns an Array of fully resolved FilePath instances.

var li = filepath.create(__dirname).list();
assert(li[4] instanceof filepath.FilePath);
assert(li[4].toString() === '/home/kris/projects/filepath/README.md');

Recursively walk a directory tree. The given callbak with be called with fully resolved FilePath instances. Returns the FilePath instance.

filepath.create(__dirname).recurse(function (path) {
  assert(path instanceof filepath.FilePath);
  assert(path.toString().indexOf(__dirname) === 0);
});

FilePath uses Bluebird promises from end to end. This provides a full featured and consistent API for some of the most common asynchronous flows in your program.

Bluebird also has a unique and very useful error handling mechanism (see below).

FilePath defines 4 Error types:

  • FilePathError
  • NotFoundError
  • ExpectDirectoryError
  • ExpectFileError

NotFoundError, ExpectDirectoryError, and ExpectFileError are subtypes of FilePathError. This allows you to use Bluebirds error handling in .catch() handlers:

// Catch only an ExpectFileError
filepath.create(__dirname)
  .read()
  .then(function () { /* This will not be called */ })
  .catch(filepath.ExpectFileError, function (err) {
    // handle the ExpectFileError
  })
  .catch(function (err) {
    // handle the unexpected Error
  });

To run the tests, just do

npm test

You should see the test results output.

Copyright (c) 2013-2015 by Kris Walker kris@kixx.name (http://www.kixx.name).

Unless otherwise indicated, all source code is licensed under the MIT license. See LICENSE for details.