fspath
Version:
Immutable Path combining path and fs operations for easy traversal and streaming
549 lines (495 loc) • 15 kB
JavaScript
// Generated by CoffeeScript 1.12.5
var Path, corepath, fs, isDir, isFile,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
fs = require('fs');
corepath = require('path');
isFile = function(path) {
return path.isFile();
};
isDir = function(path) {
return path.isDir();
};
Path = (function() {
function Path(path) {
this._the = {};
if (path != null) {
if ('string' === typeof path) {
this.path = path;
this.parts = path.split(corepath.sep);
} else if (Array.isArray(path)) {
this.path = path.join(corepath.sep);
this.parts = path.slice();
} else {
throw new Error('Path requires either string or array as `path` to constructor');
}
} else {
this.path = '.';
this.parts = ['.'];
}
this.isAbsolute = corepath.isAbsolute(this.path);
this.isRelative = !this.isAbsolute;
}
Path.prototype.reset = function() {
this._the = {};
return this._stats = null;
};
Path.prototype.stats = function(done) {
var error;
if (done != null) {
return fs.stat(this.path, (function(_this) {
return function(error, stats) {
_this._stats = stats;
if ((error != null ? error.code : void 0) === 'ENOENT') {
error = null;
}
return done(error, stats);
};
})(this));
} else {
try {
this._stats = null;
return this._stats = fs.statSync(this.path);
} catch (error1) {
error = error1;
/* istanbul ignore else */
if (error.code === 'ENOENT') {
} else {
throw error;
}
}
}
};
Path.prototype.refresh = function(done) {
this.reset();
return this.stats(done);
};
Path.prototype.toString = function() {
return this.path;
};
Path.prototype._fromStats = function(done, getter) {
if (done != null) {
return this.stats(function(error, stats) {
/* istanbul ignore if */
if (error != null) {
if (error.code === 'ENOENT') {
return done(null, getter(stats));
} else {
return done(error);
}
} else {
return done(null, getter(stats));
}
});
} else {
return getter(this.stats());
}
};
Path.prototype.isReal = function(done) {
return this._fromStats(done, function(stats) {
return stats != null;
});
};
Path.prototype.isFile = function(done) {
return this._fromStats(done, function(stats) {
var ref;
return (ref = stats != null ? stats.isFile() : void 0) != null ? ref : false;
});
};
Path.prototype.isDir = function(done) {
return this._fromStats(done, function(stats) {
var ref;
return (ref = stats != null ? stats.isDirectory() : void 0) != null ? ref : false;
});
};
Path.prototype.modified = function(done) {
return this._fromStats(done, function(stats) {
return stats != null ? stats.mtime : void 0;
});
};
Path.prototype.created = function(done) {
return this._fromStats(done, function(stats) {
return stats != null ? stats.ctime : void 0;
});
};
Path.prototype.accessed = function(done) {
return this._fromStats(done, function(stats) {
return stats != null ? stats.atime : void 0;
});
};
Path.prototype.isCanonical = function() {
var ref;
return (ref = this._the.canonical) != null ? ref : (this._the.canonical = !(indexOf.call(this.parts, '.') >= 0 || indexOf.call(this.parts, '..') >= 0));
};
Path.prototype.basename = function() {
var ref;
return (ref = this._the.basename) != null ? ref : (this._the.basename = corepath.basename(this.path));
};
Path.prototype.filename = function() {
var ref;
return (ref = this._the.filename) != null ? ref : (this._the.filename = corepath.basename(this.basename(), this.extname()));
};
Path.prototype.extname = function() {
var ref;
return (ref = this._the.extension) != null ? ref : (this._the.extension = corepath.extname(this.basename()));
};
Path.prototype.dirname = function() {
var ref;
return (ref = this._the.dirname) != null ? ref : (this._the.dirname = corepath.basename(corepath.dirname(this.path)));
};
Path.prototype.parent = function() {
var ref;
return (ref = this._the.parent) != null ? ref : (this._the.parent = this.to('..'));
};
Path.prototype.up = function(count) {
var add, i, j, ref;
if (count == null) {
count = 1;
}
count = Math.max(1, Math.min(20, count));
add = '..';
for (i = j = 1, ref = count; 1 <= ref ? j < ref : j > ref; i = 1 <= ref ? ++j : --j) {
add += corepath.sep + '..';
}
return this.to(add);
};
Path.prototype.startsWith = function(arg) {
var path;
path = typeof arg === 'string' ? arg : typeof (arg != null ? arg.path : void 0) === 'string' ? arg.path : void 0;
return (path != null) && path.length <= this.path.length && path.length > 0 && path === this.path.slice(0, path.length);
};
Path.prototype.endsWith = function(arg) {
var path;
path = typeof arg === 'string' ? arg : typeof (arg != null ? arg.path : void 0) === 'string' ? arg.path : void 0;
return (path != null) && path.length <= this.path.length && path.length > 0 && path === this.path.slice(-path.length);
};
Path.prototype.equals = function(value) {
if (value != null) {
if ('string' === typeof value) {
return this.path === value;
} else if ('function' === typeof value.test) {
return value.test(this.path);
} else if ('string' === typeof value.path) {
return this.path === value.path;
} else {
return {
error: 'equals() requires: string, regex, or Path'
};
}
} else {
return false;
}
};
Path.prototype._createStream = function(options, creator) {
var done, path;
if ((options != null ? options.done : void 0) != null) {
path = this.path;
done = options.done;
return process.nextTick(function() {
var error;
try {
return done(null, creator(path, options));
} catch (error1) {
error = error1;
/* istanbul ignore next */
return done(error);
}
});
} else {
return creator(this.path, options);
}
};
Path.prototype.reader = function(arg) {
var error, options;
options = typeof arg === 'function' ? {
done: arg
} : arg;
if (!this.isFile()) {
error = {
error: 'reader() requires file'
};
if ((options != null ? options.done : void 0) != null) {
return options.done(error);
} else {
return error;
}
}
return this._createStream(options, function(path, options) {
return fs.createReadStream(path, options != null ? options : {});
});
};
Path.prototype.writer = function(arg) {
var error, options;
options = typeof arg === 'function' ? {
done: arg
} : arg;
if (this.isDir()) {
error = {
error: 'writer() requires non-directory'
};
if ((options != null ? options.done : void 0) != null) {
return options.done(error);
} else {
return error;
}
}
return this._createStream(options, function(path, options) {
return fs.createWriteStream(path, options);
});
};
Path.prototype.read = function(arg) {
var error, options;
options = typeof arg === 'function' ? {
done: arg
} : arg;
if (!this.isFile()) {
error = {
error: 'read() requires file'
};
if ((options != null ? options.done : void 0) != null) {
return options.done(error);
} else {
return error;
}
}
if ((options != null ? options.done : void 0) != null) {
return fs.readFile(this.path, options, options.done);
} else {
return fs.readFileSync(this.path, options);
}
};
Path.prototype.write = function(data, arg) {
var error, options;
options = typeof arg === 'function' ? {
done: arg
} : arg;
if (this.isDir()) {
error = {
error: 'write() requires non-directory'
};
if ((options != null ? options.done : void 0) != null) {
return options.done(error);
} else {
return error;
}
}
if ((options != null ? options.done : void 0) != null) {
return fs.writeFile(this.path, data, options, options.done);
} else {
return fs.writeFileSync(this.path, data, options);
}
};
Path.prototype.append = function(data, arg) {
var error, options;
options = typeof arg === 'function' ? {
done: arg
} : arg;
if (this.isDir()) {
error = {
error: 'append() requires non-directory'
};
if ((options != null ? options.done : void 0) != null) {
return options.done(error);
} else {
return error;
}
}
if ((options != null ? options.done : void 0) != null) {
return fs.appendFile(this.path, data, options, options.done);
} else {
return fs.appendFileSync(this.path, data, options);
}
};
Path.prototype.pipe = function(pathOrStream, options) {
var event, listener, reader, ref, ref1, ref2, ref3, writer;
reader = this.reader(options != null ? options.reader : void 0);
if (reader.error != null) {
return reader;
}
if ((options != null ? (ref = options.events) != null ? ref.reader : void 0 : void 0) != null) {
ref1 = options.events.reader;
for (event in ref1) {
listener = ref1[event];
reader.on(event, listener);
}
}
writer = pathOrStream instanceof Path ? pathOrStream.writer(options != null ? options.writer : void 0) : pathOrStream;
if (writer.error != null) {
return writer;
}
if ((options != null ? (ref2 = options.events) != null ? ref2.writer : void 0 : void 0) != null) {
ref3 = options.events.writer;
for (event in ref3) {
listener = ref3[event];
writer.on(event, listener);
}
}
return reader.pipe(writer);
};
Path.prototype.list = function(arg) {
var done, error, options, path;
options = typeof arg === 'function' ? {
done: arg
} : arg;
if (!this.isDir()) {
error = {
error: 'list() requires directory'
};
if ((options != null ? options.done : void 0) != null) {
return options.done(error);
} else {
return error;
}
}
if ((options != null ? options.done : void 0) != null) {
done = options.done;
path = this;
return fs.readdir(this.path, function(error, array) {
/* istanbul ignore if */
if (error != null) {
return done(error);
} else {
return done(null, path._processList(options, array));
}
});
} else {
return this._processList(options, fs.readdirSync(this.path));
}
};
Path.prototype._processList = function(options, array) {
var acceptPath, acceptString, each, j, len, path, paths, rejectedPaths, rejectedStrings, string;
acceptString = options != null ? options.acceptString : void 0;
acceptPath = options != null ? options.acceptPath : void 0;
each = options != null ? options.each : void 0;
paths = [];
rejectedStrings = rejectedPaths = 0;
for (j = 0, len = array.length; j < len; j++) {
string = array[j];
if ((acceptString == null) || acceptString(string)) {
path = this.to(string);
if ((acceptPath == null) || acceptPath(path)) {
paths[paths.length] = path;
if (typeof each === "function") {
each({
path: path
});
}
} else {
rejectedPaths++;
}
} else {
rejectedStrings++;
}
}
return {
paths: paths,
rejected: {
strings: rejectedStrings,
paths: rejectedPaths
}
};
};
Path.prototype.files = function(arg) {
var options, theirFilter;
options = typeof arg === 'function' ? {
done: arg
} : arg;
if (options != null) {
options = Object.assign({}, options);
if (options.acceptPath != null) {
theirFilter = options.acceptPath;
options.acceptPath = function(path) {
return path.isFile() && theirFilter(path);
};
} else {
options.acceptPath = isFile;
}
} else {
options = {
acceptPath: isFile
};
}
return this.list(options);
};
Path.prototype.dirs = function(arg) {
var options, theirFilter;
options = typeof arg === 'function' ? {
done: arg
} : arg;
if (options != null) {
options = Object.assign({}, options);
if (options.acceptPath != null) {
theirFilter = options.acceptPath;
options.acceptPath = function(path) {
return path.isDir() && theirFilter(path);
};
} else {
options.acceptPath = isDir;
}
} else {
options = {
acceptPath: isDir
};
}
return this.list(options);
};
Path.prototype.to = function(path) {
var newPath;
if ('string' === typeof path) {
newPath = corepath.join(this.path, path);
if (newPath === this.path) {
return this;
} else {
return new Path(newPath);
}
} else if (Array.isArray(path)) {
return new Path(this.parts.concat(path));
} else {
return {
error: 'to(path) requires either a string or array of strings'
};
}
};
Path.prototype.resolve = function() {
var i, j, path, paths, ref;
paths = new Array(arguments.length + 1);
for (i = j = 0, ref = arguments.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
paths[i + 1] = arguments[i];
}
paths[0] = this.path;
path = corepath.resolve.apply(null, paths);
if (path === this.path) {
return this;
} else {
return new Path(path);
}
};
Path.prototype.relativeTo = function(path) {
path = corepath.relative(this.path, path);
if (path.length < 1) {
return this;
} else {
return new Path(path);
}
};
Path.prototype.normalize = function() {
var normalized;
normalized = corepath.normalize(this.path);
if (normalized === this.path) {
return this;
} else {
return new Path(normalized);
}
};
Path.prototype.subpath = function(start, end) {
return new Path((this.path === '/' ? '' : this.parts.slice(start, end)));
};
Path.prototype.part = function(index) {
return this.parts[index];
};
return Path;
})();
Path.prototype.extension = Path.prototype.extname;
module.exports = function(path) {
return new Path(path);
};
module.exports.Path = Path;