UNPKG

q-fs

Version:

Q Promise wrappers for Node's file system.

267 lines (247 loc) 7.5 kB
/** * An asynchronous local file system API, based on a subset * of the `narwhal/fs` API and the `narwhal/promise` API, * such that the method names are the same but some return * values are promises instead of fully resolved values. * @module */ /*whatsupdoc*/ var FS = require("fs"); // node var SYS = require("sys"); // node var Q = require("qq"); var IO = require("q-io"); var COMMON = require("./lib/common"); var MOCK = require("./lib/mock"); var ROOT = require("./lib/root"); COMMON.update(exports, process.cwd); exports.Mock = MOCK.Fs; exports.mock = MOCK.mock; exports.Root = ROOT.Fs; /** * @param {String} path * @returns {Promise * Stream} a stream from the * `narwhal/q-io` module. */ exports.open = function (path, flags, charset) { flags = flags || "r"; var options = {"flags": flags.replace(/b/g, "")}; if (flags.indexOf("b") >= 0) { if (charset) { throw new Error("Can't open a binary file with a charset: " + charset); } } else { charset = charset || "binary"; } if (flags.indexOf("w") >= 0) { var stream = FS.createWriteStream(String(path), options); return IO.Writer(stream, charset); } else { var stream = FS.createReadStream(String(path), options); return IO.Reader(stream, charset); } }; exports.remove = function (path) { path = String(path); var done = Q.defer(); FS.unlink(path, function (error) { if (error) { error.message = "Can't remove " + JSON.stringify(path) + ": " + error.message; done.reject(error); } else { done.resolve(); } }); return done.promise; }; exports.makeDirectory = function (path, mode) { path = String(path); var done = Q.defer(); mode = mode === undefined ? parseInt('755', 8) : mode; FS.mkdir(path, mode, function (error) { if (error) { error.message = "Can't makeDirectory " + JSON.stringify(path) + " with mode " + mode + ": " + error.message; done.reject(error); } else { done.resolve(); } }); return done.promise; }; exports.removeDirectory = function (path) { path = String(path); var done = Q.defer(); FS.rmdir(path, function (error) { if (error) { error.message = "Can't removeDirectory " + JSON.stringify(path) + ": " + error.message; done.reject(error); } else { done.resolve(); } }); return done.promise; }; /** */ exports.list = function (path) { path = String(path); var result = Q.defer(); FS.readdir(path, function (error, list) { if (error) { error.message = "Can't list " + JSON.stringify(path) + ": " + error.message; return result.reject(error); } else { result.resolve(list); } }); return Q.Lazy(Array, result.promise); }; /** * @param {String} path * @returns {Promise * Stat} */ exports.stat = function (path) { path = String(path); var done = Q.defer(); try { FS.stat(path, function (error, stat) { if (error) { error.message = "Can't stat " + JSON.stringify(path) + ": " + error; done.reject(error); } else { done.resolve(new exports.Stats(stat)); } }); } catch (error) { done.reject(error); } return Q.Lazy(exports.Stats, done.promise); }; exports.statLink = function (path) { path = String(path); var done = Q.defer(); try { FS.lstat(path, function (error, stat) { if (error) { error.message = "Can't statLink " + JSON.stringify(path) + ": " + error.message; done.reject(error); } else { done.resolve(stat); } }); } catch (error) { done.reject(error); } return done.promise; }; exports.statFd = function (fd) { fd = Number(fd); var done = Q.defer(); try { FS.fstat(fd, function (error, stat) { if (error) { error.message = "Can't statFd file descriptor " + JSON.stringify(fd) + ": " + error.message; done.reject(error); } else { done.resolve(stat); } }); } catch (error) { done.reject(error); } return done.promise; }; exports.link = function (source, target) { source = String(source); target = String(target); var done = Q.defer(); try { FS.link(source, target, function (error) { if (error) { error.message = "Can't link " + JSON.stringify(source) + " to " + JSON.stringify(target) + ": " + error.message; done.reject(error); } else { done.resolve(); } }); } catch (error) { done.reject(error); } return done.promise; }; exports.symbolicLink = function (target, relative) { target = String(target); relative = String(relative); var done = Q.defer(); try { FS.symlink(relative, target, function (error) { if (error) { error.message = "Can't create symbolicLink " + JSON.stringify(target) + " to relative location " + JSON.stringify(relative) + ": " + error.message; done.reject(error); } else { done.resolve(); } }); } catch (error) { done.reject(error); } return done.promise; }; exports.symbolicCopy = function (source, target) { return Q.when(exports.relative(target, source), function (relative) { return exports.symbolicLink(target, relative); }); }; exports.chown = function (path, uid, gid) { path = String(path); var done = Q.defer(); try { FS.chown(path, uid, gid, function (error) { if (error) { error.message = "Can't chown (change owner) of " + JSON.stringify(path) + " to user " + JSON.stringify(uid) + " and group " + JSON.stringify(gid) + ": " + error.message; done.reject(error); } else { done.resolve(); } }); } catch (error) { done.reject(error); } return done.promise; }; exports.chmod = function (path, mode) { path = String(path); mode = String(mode); var done = Q.defer(); try { FS.chmod(path, mode, function (error) { if (error) { error.message = "Can't chmod (change permissions mode) of " + JSON.stringify(path) + " to (octal number) " + mode.toString(8) + ": " + error.message; done.reject(error); } else { done.resolve(); } }); } catch (error) { done.reject(error); } return done.promise; }; exports.lastModified = function (path) { var stat = exports.stat(path); var mtime = Q.get(stat, 'mtime'); return Q.when(mtime, function (mtime) { return Date.parse(mtime); }); }; exports.canonical = function (path) { var result = Q.defer(); FS.realpath(path, function (error, path) { if (error) { error.message = "Can't get canonical path of " + JSON.stringify(path) + " by way of C realpath: " + error.message; result.reject(error); } else { result.resolve(path); } }); return result.promise; };