UNPKG

fs-finder-updated

Version:
383 lines (345 loc) 12.3 kB
// Generated by CoffeeScript 2.7.0 (function() { var Base, Helpers, Q, async, fs, path; Helpers = require('./Helpers'); path = require('path'); fs = require('fs'); Q = require('q'); async = require('async'); Base = (function() { class Base { constructor(directory) { directory = path.resolve(directory); if (!fs.statSync(directory).isDirectory()) { throw new Error(`Path ${directory} is not directory`); } this.directory = directory; this.excludes = []; this.filters = []; } //******************************************************************************************************************* // TESTING //******************************************************************************************************************* static mock(tree = {}, info = {}) { var FS; FS = require('fs-mock'); fs = new FS(tree, info); return fs; } static restore() { return fs = require('fs'); } //******************************************************************************************************************* // SETUP //******************************************************************************************************************* recursively(recursive = true) { this.recursive = recursive; return this; } exclude(excludes, exactly = false) { var exclude, j, len, result; if (typeof excludes === 'string') { excludes = [excludes]; } result = []; for (j = 0, len = excludes.length; j < len; j++) { exclude = excludes[j]; if (exactly) { exclude = `<^>${exclude}<$>`; } result.push(Helpers.normalizePattern(exclude)); } this.excludes = this.excludes.concat(result); return this; } showSystemFiles(systemFiles = true) { this.systemFiles = systemFiles; return this; } lookUp(up = true) { this.up = up; return this; } findFirst(_findFirst = true) { this._findFirst = _findFirst; return this; } filter(fn) { this.filters.push(fn); return this; } //******************************************************************************************************************* // SEARCHING //******************************************************************************************************************* getPathsSync(type = 'all', mask = null, dir = this.directory) { var _path, err, j, len, paths, read, result, stats; paths = []; try { read = fs.readdirSync(dir); } catch (error) { err = error; if (this._findFirst === true) { return null; } return paths; } for (j = 0, len = read.length; j < len; j++) { _path = read[j]; _path = path.join(dir, _path); if (!this.checkExcludes(_path) || !this.checkSystemFiles(_path)) { continue; } try { stats = fs.statSync(_path); } catch (error) { err = error; continue; } switch (this.checkFile(_path, stats, mask, type)) { case 0: continue; case 1: if (this._findFirst === true) { return _path; } paths.push(_path); } if (stats.isDirectory() && this.recursive === true) { result = this.getPathsSync(type, mask, _path); if (this._findFirst === true && typeof result === 'string') { return result; } else if (this._findFirst === true && result === null) { continue; } else { paths = paths.concat(result); } } } if (this._findFirst === true) { return null; } else { return paths; } } getPathsAsync(fn, type = 'all', mask = null, dir = this.directory) { var paths; paths = []; return fs.readdir(dir, (err, read) => { var _path, files, j, len, nextPaths; if (err) { return fn(this._findFirst === true ? null : paths); } else { nextPaths = []; for (j = 0, len = read.length; j < len; j++) { _path = read[j]; _path = path.join(dir, _path); if (!this.checkExcludes(_path) || !this.checkSystemFiles(_path)) { continue; } nextPaths.push(_path); } files = {}; return async.eachSeries(nextPaths, function(item, cb) { return fs.stat(item, function(err, stats) { if (!err) { files[item] = stats; } return cb(); }); }, () => { var file, stats, subDirectories; subDirectories = []; for (file in files) { stats = files[file]; switch (this.checkFile(file, stats, mask, type)) { case 0: continue; case 1: if (this._findFirst === true) { fn(file); return null; } paths.push(file); } if (stats.isDirectory() && this.recursive === true) { subDirectories.push(file); } } if (subDirectories.length === 0) { return fn(this._findFirst === true ? null : paths); } else { return async.eachSeries(subDirectories, (item, cb) => { return this.getPathsAsync((result) => { if (this._findFirst === true && typeof result === 'string') { fn(result); return cb(new Error('Fake error')); } else if (this._findFirst === true && result === null) { return cb(); } else { paths = paths.concat(result); return cb(); } }, type, mask, item); }, function(err) { if (!err) { return fn(paths); } }); } }); } }); } //******************************************************************************************************************* // CHECKS //******************************************************************************************************************* checkExcludes(_path) { var exclude, j, len, ref; ref = this.excludes; for (j = 0, len = ref.length; j < len; j++) { exclude = ref[j]; if ((new RegExp(exclude)).test(_path)) { return false; } } return true; } checkSystemFiles(_path) { if (this.systemFiles === false) { if (path.basename(_path)[0] === '.' || _path.match(/~$/) !== null) { return false; } } return true; } checkFilters(_path, stats) { var filter, j, len, ref; ref = this.filters; for (j = 0, len = ref.length; j < len; j++) { filter = ref[j]; if (!filter(stats, _path)) { return false; } } return true; } checkFile(_path, stats, mask, type) { if (type === 'all' || (type === 'files' && stats.isFile()) || (type === 'directories' && stats.isDirectory())) { if (mask === null || (mask !== null && (new RegExp(mask, 'g')).test(_path))) { if (!this.checkFilters(_path, stats)) { return 0; } return 1; } } return 2; } //******************************************************************************************************************* // PARENTS //******************************************************************************************************************* getPathsFromParentsSync(mask = null, type = 'all') { var Finder, breakAtEnd, finder, found, i, j, len, parentPath, parentPaths, previous, result; Finder = require('./Finder'); parentPaths = Helpers.expandPath(this.directory); result = []; previous = null; breakAtEnd = false; for (i = j = 0, len = parentPaths.length; j < len; i = ++j) { parentPath = parentPaths[i]; if (this.up === true) { // continue } else if (typeof this.up === 'string' && this.up === parentPath) { breakAtEnd = true; } else if (typeof this.up === 'number' && this.up <= i) { break; } finder = new Finder(parentPath); finder.recursive = this.recursive; finder.excludes = this.excludes; finder.filters = this.filters; finder.systemFiles = this.systemFiles; finder._findFirst = this._findFirst === true; if (previous !== null) { finder.exclude(previous, true); } found = finder.getPathsSync(type, mask); if (this._findFirst === true && typeof found === 'string') { return found; } else if (this._findFirst === true && found === null) { // continue } else if (found.length > 0) { result = result.concat(found); } if (breakAtEnd) { break; } previous = parentPath; } if (this._findFirst === true) { return null; } else { return result; } } getPathsFromParentsAsync(fn, mask = null, type = 'all') { var Finder, breakAtEnd, finder, finders, i, j, len, parentPath, parentPaths, previous, result; Finder = require('./Finder'); parentPaths = Helpers.expandPath(this.directory); result = []; previous = null; breakAtEnd = false; finders = []; for (i = j = 0, len = parentPaths.length; j < len; i = ++j) { parentPath = parentPaths[i]; if (this.up === true) { // continue } else if (typeof this.up === 'string' && this.up === parentPath) { breakAtEnd = true; } else if (typeof this.up === 'number' && this.up <= i) { break; } finder = new Finder(parentPath); finder.recursive = this.recursive; finder.excludes = this.excludes; finder.filters = this.filters; finder.systemFiles = this.systemFiles; finder._findFirst = this._findFirst === true; if (previous !== null) { finder.exclude(previous, true); } finders.push(finder); if (breakAtEnd) { break; } previous = parentPath; } return async.eachSeries(finders, (finder, cb) => { return finder.getPathsAsync((found) => { if (this._findFirst === true && typeof found === 'string') { fn(found); return cb(new Error('Fake error')); } else if (this._findFirst === true && found === null) { return cb(); } else { result = result.concat(found); return cb(); } }, type, mask); }, (err) => { if (!err) { return fn(this._findFirst === true ? null : result); } }); } }; Base.prototype.directory = null; Base.prototype.recursive = false; Base.prototype.excludes = null; Base.prototype.filters = null; Base.prototype.systemFiles = false; Base.prototype.up = false; Base.prototype._findFirst = false; return Base; }).call(this); module.exports = Base; }).call(this);