123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- var fs = require('fs'),
- path = require('path');
- exports.promiseFiles = function promiseFiles(dir, type, options){
- type = type || 'file'
- var processor = function(res,rej){
- var cb = function(err,data){
- if(err)return rej(err)
- res(data)
- }
- exports.files(dir,type,cb,options)
- }
- return new Promise(processor)
- }
- /**
- * find all files or subdirs (recursive) and pass to callback fn
- *
- * @param {string} dir directory in which to recurse files or subdirs
- * @param {string} type type of dir entry to recurse ('file', 'dir', or 'all', defaults to 'file')
- * @param {function(error, <Array.<string>)} callback fn to call when done
- * @example
- * dir.files(__dirname, function(err, files) {
- * if (err) throw err;
- * console.log('files:', files);
- * });
- */
- exports.files = function files(dir, type, callback, options) {
- var ofType = typeof type
- if(ofType == 'object'){
- options = options || type
- type = 'file'
- callback = function(){}
- }else if (ofType !== 'string') {
- //ignoreType = callback;
- callback = type;
- type = 'file';
- }
-
- options = options || {}
- var pending,
- results = {
- files: [],
- dirs: []
- };
- var done = function() {
- if(type==='combine'){
- results = results.files.concat(results.dirs)
- } else if (!type || options.ignoreType || ['all','combine'].indexOf(type)>=0) {
- results = results
- } else {
- results = results[type + 's']
- }
- if(options.sync)return;
- callback(null, results);
- };
- var getStatHandler = function(statPath, name, lstatCalled) {
- return function(err, stat) {
- if (err) {
- if (!lstatCalled) {
- return fs.lstat(statPath, getStatHandler(statPath, name, true));
- }
- return callback(err);
- }
- var pushVal = options.shortName ? name : statPath
- if (stat && stat.isDirectory() && stat.mode !== 17115) {
- if (type !== 'file') {
- results.dirs.push(pushVal);
- }
- if (options.recursive==null || options.recursive) {
- var subloop = function(err, res) {
- if (err){
- return callback(err)
- }
-
- if(type === 'combine'){
- results.files = results.files.concat(res);
- }else if (type === 'all') {
- results.files = results.files.concat(res.files);
- results.dirs = results.dirs.concat(res.dirs);
- } else if (type === 'file') {
- results.files = results.files.concat(res.files);
- } else {
- results.dirs = results.dirs.concat(res.dirs);
- }
- if (!--pending){
- done();
- }
- }
- var newOptions = Object.assign({}, options)
- newOptions.ignoreType = true
- var moreResults = files(statPath, type, subloop, newOptions);
- if(options.sync){
- subloop(null, moreResults)
- }
- }else if (!--pending){
- done()
- }
- } else {
- if (type !== 'dir') {
- results.files.push(pushVal);
- }
- // should be the last statement in statHandler
- if (!--pending){
- done()
- }
- }
- }
- }
- var bufdir = Buffer.from(dir);
- const onDirRead = function(err, list) {
- if (err) return callback(err);
-
- pending = list.length;
- if (!pending) return done();
-
- for (var file, i = 0, l = list.length; i < l; i++) {
- var fname = list[i].toString();
- file = path.join(dir, fname);
- var buffile = Buffer.concat([bufdir, Buffer.from(path.sep), list[i]]);
- if(options.sync){
- var res = fs.statSync(buffile);
- getStatHandler(file,fname)(null, res)
- }else{
- fs.stat(buffile, getStatHandler(file,fname));
- }
- }
- return results
- }
- const onStat = function(err, stat) {
- if (err) return callback(err);
- if (stat && stat.mode === 17115) return done();
- if(options.sync){
- const list = fs.readdirSync(bufdir, {encoding: 'buffer'})
- return onDirRead(null, list)
- }else{
- fs.readdir(bufdir, {encoding: 'buffer'}, onDirRead)
- }
- }
- if(options.sync){
- const stat = fs.statSync(bufdir);
- return onStat(null, stat)
- }else{
- fs.stat(bufdir, onStat);
- }
- };
- /**
- * find all files and subdirs in a directory (recursive) and pass them to callback fn
- *
- * @param {string} dir directory in which to recurse files or subdirs
- * @param {boolean} combine whether to combine both subdirs and filepaths into one array (default false)
- * @param {function(error, Object.<<Array.<string>, Array.<string>>)} callback fn to call when done
- * @example
- * dir.paths(__dirname, function (err, paths) {
- * if (err) throw err;
- * console.log('files:', paths.files);
- * console.log('subdirs:', paths.dirs);
- * });
- * dir.paths(__dirname, true, function (err, paths) {
- * if (err) throw err;
- * console.log('paths:', paths);
- * });
- */
- exports.paths = function paths(dir, combine, callback) {
- var type;
- if (typeof combine === 'function') {
- callback = combine;
- combine = false;
- }
- exports.files(dir, 'all', function(err, results) {
- if (err) return callback(err);
- if (combine) {
- callback(null, results.files.concat(results.dirs));
- } else {
- callback(null, results);
- }
- });
- };
- /**
- * find all subdirs (recursive) of a directory and pass them to callback fn
- *
- * @param {string} dir directory in which to find subdirs
- * @param {string} type type of dir entry to recurse ('file' or 'dir', defaults to 'file')
- * @param {function(error, <Array.<string>)} callback fn to call when done
- * @example
- * dir.subdirs(__dirname, function (err, paths) {
- * if (err) throw err;
- * console.log('files:', paths.files);
- * console.log('subdirs:', paths.dirs);
- * });
- */
- exports.subdirs = function subdirs(dir, callback, type, options) {
- options = options || {}
- const iCallback = function(err, subdirs) {
- if (err) return callback(err);
- if(type=='combine'){
- subdirs = subdirs.files.concat(subdirs.dirs)
- }
-
- if(options.sync)return subdirs
- callback(null, subdirs);
- }
- const res = exports.files(dir, 'dir', iCallback, options)
- if(options && options.sync){
- return iCallback(null,res)
- }
- };
|