Firebase Update
This commit is contained in:
256
express-server/node_modules/walkdir/walkdir.js
generated
vendored
Normal file
256
express-server/node_modules/walkdir/walkdir.js
generated
vendored
Normal file
@ -0,0 +1,256 @@
|
||||
var EventEmitter = require('events').EventEmitter,
|
||||
_fs = require('fs'),
|
||||
_path = require('path'),
|
||||
sep = _path.sep||'/';// 0.6.x
|
||||
|
||||
|
||||
module.exports = walkdir;
|
||||
|
||||
walkdir.find = walkdir.walk = walkdir;
|
||||
|
||||
walkdir.sync = function(path,options,cb){
|
||||
if(typeof options == 'function') cb = options;
|
||||
options = options || {};
|
||||
options.sync = true;
|
||||
return walkdir(path,options,cb);
|
||||
|
||||
};
|
||||
|
||||
function walkdir(path,options,cb){
|
||||
|
||||
if(typeof options == 'function') cb = options;
|
||||
|
||||
options = options || {};
|
||||
|
||||
var fs = options.fs || _fs;
|
||||
|
||||
var emitter = new EventEmitter(),
|
||||
dontTraverse = [],
|
||||
allPaths = (options.return_object?{}:[]),
|
||||
resolved = false,
|
||||
inos = {},
|
||||
stop = 0,
|
||||
pause = null,
|
||||
ended = 0,
|
||||
jobs=0,
|
||||
job = function(value) {
|
||||
jobs += value;
|
||||
if(value < 1 && !tick) {
|
||||
tick = 1;
|
||||
process.nextTick(function(){
|
||||
tick = 0;
|
||||
if(jobs <= 0 && !ended) {
|
||||
ended = 1;
|
||||
emitter.emit('end');
|
||||
}
|
||||
});
|
||||
}
|
||||
}, tick = 0;
|
||||
|
||||
emitter.ignore = function(path){
|
||||
if(Array.isArray(path)) dontTraverse.push.apply(dontTraverse,path)
|
||||
else dontTraverse.push(path)
|
||||
return this
|
||||
}
|
||||
|
||||
//mapping is stat functions to event names.
|
||||
var statIs = [['isFile','file'],['isDirectory','directory'],['isSymbolicLink','link'],['isSocket','socket'],['isFIFO','fifo'],['isBlockDevice','blockdevice'],['isCharacterDevice','characterdevice']];
|
||||
|
||||
var statter = function (path,first,depth) {
|
||||
job(1);
|
||||
var statAction = function fn(err,stat,data) {
|
||||
|
||||
job(-1);
|
||||
if(stop) return;
|
||||
|
||||
// in sync mode i found that node will sometimes return a null stat and no error =(
|
||||
// this is reproduceable in file descriptors that no longer exist from this process
|
||||
// after a readdir on /proc/3321/task/3321/ for example. Where 3321 is this pid
|
||||
// node @ v0.6.10
|
||||
if(err || !stat) {
|
||||
emitter.emit('fail',path,err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//if i have evented this inode already dont again.
|
||||
var fileName = _path.basename(path);
|
||||
var fileKey = stat.dev + '-' + stat.ino + '-' + fileName;
|
||||
if(options.track_inodes !== false) {
|
||||
if(inos[fileKey] && stat.ino) return;
|
||||
inos[fileKey] = 1;
|
||||
}
|
||||
|
||||
if (first && stat.isDirectory()) {
|
||||
emitter.emit('targetdirectory',path,stat,depth);
|
||||
return;
|
||||
}
|
||||
|
||||
emitter.emit('path', path, stat,depth);
|
||||
|
||||
var i,name;
|
||||
|
||||
for(var j=0,k=statIs.length;j<k;j++) {
|
||||
if(stat[statIs[j][0]]()) {
|
||||
emitter.emit(statIs[j][1],path,stat,depth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(options.sync) {
|
||||
var stat,ex;
|
||||
try{
|
||||
stat = fs.lstatSync(path);
|
||||
} catch (e) {
|
||||
ex = e;
|
||||
}
|
||||
|
||||
statAction(ex,stat);
|
||||
} else {
|
||||
fs.lstat(path,statAction);
|
||||
}
|
||||
},readdir = function(path,stat,depth){
|
||||
if(!resolved) {
|
||||
path = _path.resolve(path);
|
||||
resolved = 1;
|
||||
}
|
||||
|
||||
if(options.max_depth && depth >= options.max_depth){
|
||||
emitter.emit('maxdepth',path,stat,depth);
|
||||
return;
|
||||
}
|
||||
|
||||
if(dontTraverse.length){
|
||||
for(var i=0;i<dontTraverse.length;++i){
|
||||
if(dontTraverse[i] == path) {
|
||||
dontTraverse.splice(i,1)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
job(1);
|
||||
var readdirAction = function(err,files) {
|
||||
job(-1);
|
||||
if (err || !files) {
|
||||
//permissions error or invalid files
|
||||
emitter.emit('fail',path,err);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!files.length) {
|
||||
// empty directory event.
|
||||
emitter.emit('empty',path,stat,depth);
|
||||
return;
|
||||
}
|
||||
|
||||
if(path == sep) path='';
|
||||
for(var i=0,j=files.length;i<j;i++){
|
||||
statter(path+sep+files[i],false,(depth||0)+1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//use same pattern for sync as async api
|
||||
if(options.sync) {
|
||||
var e,files;
|
||||
try {
|
||||
files = fs.readdirSync(path);
|
||||
} catch (e) { }
|
||||
|
||||
readdirAction(e,files);
|
||||
} else {
|
||||
fs.readdir(path,readdirAction);
|
||||
}
|
||||
};
|
||||
|
||||
if (options.follow_symlinks) {
|
||||
var linkAction = function(err,path,depth){
|
||||
job(-1);
|
||||
//TODO should fail event here on error?
|
||||
statter(path,false,depth);
|
||||
};
|
||||
|
||||
emitter.on('link',function(path,stat,depth){
|
||||
job(1);
|
||||
if(options.sync) {
|
||||
var lpath,ex;
|
||||
try {
|
||||
lpath = fs.readlinkSync(path);
|
||||
} catch(e) {
|
||||
ex = e;
|
||||
}
|
||||
linkAction(ex,_path.resolve(_path.dirname(path),lpath),depth);
|
||||
|
||||
} else {
|
||||
fs.readlink(path,function(err,lpath){
|
||||
linkAction(err,_path.resolve(_path.dirname(path),lpath),depth);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
emitter.on('path',cb);
|
||||
}
|
||||
|
||||
if (options.sync) {
|
||||
if(!options.no_return){
|
||||
emitter.on('path',function(path,stat){
|
||||
if(options.return_object) allPaths[path] = stat;
|
||||
else allPaths.push(path);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.no_recurse) {
|
||||
emitter.on('directory',readdir);
|
||||
}
|
||||
//directory that was specified by argument.
|
||||
emitter.once('targetdirectory',readdir);
|
||||
//only a fail on the path specified by argument is fatal
|
||||
emitter.once('fail',function(_path,err){
|
||||
//if the first dir fails its a real error
|
||||
if(path == _path) {
|
||||
emitter.emit('error',path,err);
|
||||
}
|
||||
});
|
||||
|
||||
statter(path,1);
|
||||
if (options.sync) {
|
||||
return allPaths;
|
||||
} else {
|
||||
//support stopping everything.
|
||||
emitter.end = emitter.stop = function(){stop = 1;};
|
||||
//support pausing everything
|
||||
var emitQ = [];
|
||||
emitter.pause = function(){
|
||||
job(1);
|
||||
pause = true;
|
||||
emitter.emit = function(){
|
||||
emitQ.push(arguments);
|
||||
};
|
||||
};
|
||||
// support getting the show going again
|
||||
emitter.resume = function(){
|
||||
if(!pause) return;
|
||||
pause = false;
|
||||
// not pending
|
||||
job(-1);
|
||||
//replace emit
|
||||
emitter.emit = EventEmitter.prototype.emit;
|
||||
// local ref
|
||||
var q = emitQ;
|
||||
// clear ref to prevent infinite loops
|
||||
emitQ = [];
|
||||
while(q.length) {
|
||||
emitter.emit.apply(emitter,q.shift());
|
||||
}
|
||||
};
|
||||
|
||||
return emitter;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user