fobject
Version:
A simple promise-based wrapper for file operations that treats files as objects.
221 lines (178 loc) • 5.36 kB
JavaScript
// Generated by CoffeeScript 1.10.0
var File, fs, nodefn, path, semver,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
fs = require('graceful-fs');
path = require('path');
nodefn = require('when/node');
semver = require('semver');
File = (function() {
/**
* @class
* @name File
* @param {String} path The path to the file. This will be resolved to an
absolute path, so even if you change your cwd you can still access the same
file.
* @param {String} [options.base=./] Used for relative pathing. This will not
be resolved to an absolute path. Typically where a glob starts.
*/
function File(path1, options) {
var ref;
this.path = path1;
if (options == null) {
options = {};
}
this._processOptionsObject = bind(this._processOptionsObject, this);
this.dirname = bind(this.dirname, this);
this.extname = bind(this.extname, this);
this.stat = bind(this.stat, this);
this.unlink = bind(this.unlink, this);
this.rename = bind(this.rename, this);
this.append = bind(this.append, this);
this.write = bind(this.write, this);
this.read = bind(this.read, this);
this._resolvePaths = bind(this._resolvePaths, this);
this.base = (ref = options.base) != null ? ref : './';
this._resolvePaths();
}
/**
* Normalize & resolve paths. Call if the File.path changes
* @function
* @name _resolvePaths
* @private
*/
File.prototype._resolvePaths = function() {
this.path = path.resolve(this.base, this.path);
return this.relative = path.relative(this.base, this.path);
};
/**
* Read from the file
* @function
* @name read
* @param {String|null} [options.encoding=null]
* @param {String} [options.flag='r']
* @return {Promise}
*/
File.prototype.read = function(options) {
if (options == null) {
options = {};
}
return nodefn.call(fs.readFile, this.path, this._processOptionsObject(options));
};
/**
* Write `data` to the file
* @function
* @name write
* @param {String|Buffer} data
* @param {String|null} [options.encoding='utf8'] ignored if data is a
buffer
* @param {Number} [options.mode=438] default is 0666 in Octal
* @param {String} [options.flag='w']
* @return {Promise}
*/
File.prototype.write = function(data, options) {
if (options == null) {
options = {};
}
return nodefn.call(fs.writeFile, this.path, data, this._processOptionsObject(options));
};
/**
* Append `data` to the file
* @function
* @name append
* @param {String|Buffer} data
* @param {String|null} [options.encoding='utf8'] ignored if data is a
buffer
* @param {Number} [options.mode=438] default is 0666 in Octal
* @param {String} [options.flag='w']
* @return {Promise}
*/
File.prototype.append = function(data, options) {
if (options == null) {
options = {};
}
return nodefn.call(fs.appendFile, this.path, data, this._processOptionsObject(options));
};
/**
* Rename the file
* @function
* @name rename
* @param {String} newPath The new path for the file. Will be resolved
relative to File.base.
* @return {Promise}
*/
File.prototype.rename = function(newPath) {
newPath = path.resolve(this.base, newPath);
return nodefn.call(fs.rename, this.path, newPath).then((function(_this) {
return function() {
_this.path = newPath;
return _this._resolvePaths();
};
})(this));
};
/**
* Delete the file
* @function
* @name unlink
* @return {Promise}
*/
File.prototype.unlink = function() {
return nodefn.call(fs.unlink, this.path);
};
/**
* Return a Stat object for the file
* @function
* @name stat
* @return {Promise}
*/
File.prototype.stat = function() {
return nodefn.call(fs.stat, this.path);
};
/**
* Get the extension of a file
* @function
* @name extname
* @return {String}
*/
File.prototype.extname = function() {
return path.extname(this.path);
};
/**
* Get the dirname of the file
* @function
* @name dirname
* @return {String}
*/
File.prototype.dirname = function() {
return path.dirname(this.path);
};
/**
* Determine if we're using the new version of the FS API that supports an
options object.
* @return {Boolean} True if the version is >= 0.10.0 (when the options object
was introduced).
*/
File.prototype._isOptionsObjectSupported = function() {
return semver.gte(process.version, '0.10.0');
};
/**
* The pre-v0.10.0 fs functions took a encoding parameter and no options
object. This function deals with that difference.
* @param {[type]} options [description]
*/
File.prototype._processOptionsObject = function(options) {
var length, optionNames;
if (this._isOptionsObjectSupported()) {
return options;
} else {
optionNames = Object.keys(options);
length = optionNames.length;
if (length === 0 || (length === 1 && optionNames[0] === 'encoding')) {
return options.encoding;
} else {
throw new Error("Node version <= 0.10.0 only supports an encoding option. Called with " + (optionNames.join()));
}
}
};
return File;
})();
module.exports = File;