Firebase Update

This commit is contained in:
Lukas Nowy
2018-12-22 23:30:39 +01:00
parent befb44764d
commit acffe619b3
11523 changed files with 1614327 additions and 930246 deletions

3
express-server/node_modules/walkdir/.jshintignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
node_modules
test/dir
test/comparison

2
express-server/node_modules/walkdir/.npmignore generated vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
*~

7
express-server/node_modules/walkdir/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,7 @@
language: node_js
sudo: false
node_js:
- "0.10"
- "0.12"
- "4"
- "5"

32
express-server/node_modules/walkdir/CONTRIBUTING.md generated vendored Normal file
View File

@ -0,0 +1,32 @@
# walkdir Contributing Guidelines
- Always search for a related issue before starting a new issue.
- Always choose a concise, helpful issue name.
- Always stay on-topic. If you've got a new bug report or feature request, put it in its own issue.
- Always be polite to other people.
- Never post private information, such as torrent or tracker names, IP addresses, etc.
Issues that break the rules may be deleted and locked without warning.
## walkdir is an OPEN Open Source Project
Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.
## Rules
There are a few basic ground-rules for contributors:
1. **No `--force` pushes** or modifying the Git history in any way.
1. **External API changes and significant modifications** should be subject to a **pull request** to solicit feedback from other contributors.
1. Pull requests to solicit feedback are *encouraged* for any other non-trivial contribution but left to the discretion of the contributor.
1. Use a non-`master` branch for ongoing work.
1. Contributors should attempt to adhere to the prevailing code style.
1. Run `npm test` locally before submitting your PR to catch easy-to-miss style & testing issues
## Releases
Declaring formal releases remains the prerogative of the project maintainer.
## Changes to this arrangement
*Thanks to [Rod Vagg](https://github.com/rvagg) and the [LevelUP](https://github.com/rvagg/node-levelup) project for coming up with this model of open source contribution.*

10
express-server/node_modules/walkdir/license generated vendored Normal file
View File

@ -0,0 +1,10 @@
The MIT License (MIT)
Copyright (c) 2012 Ryan Day
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

66
express-server/node_modules/walkdir/package.json generated vendored Normal file
View File

@ -0,0 +1,66 @@
{
"_from": "walkdir@0.0.12",
"_id": "walkdir@0.0.12",
"_inBundle": false,
"_integrity": "sha512-HFhaD4mMWPzFSqhpyDG48KDdrjfn409YQuVW7ckZYhW4sE87mYtWifdB/+73RA7+p4s4K18n5Jfx1kHthE1gBw==",
"_location": "/walkdir",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "walkdir@0.0.12",
"name": "walkdir",
"escapedName": "walkdir",
"rawSpec": "0.0.12",
"saveSpec": null,
"fetchSpec": "0.0.12"
},
"_requiredBy": [
"/google-gax",
"/google-proto-files"
],
"_resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.12.tgz",
"_shasum": "2f24f1ade64aab1e458591d4442c8868356e9281",
"_spec": "walkdir@0.0.12",
"_where": "D:\\Desktop\\Git\\Firebase\\SmartShopperFirebase\\node_modules\\google-gax",
"author": {
"name": "Ryan Day",
"email": "soldair@gmail.com"
},
"bugs": {
"url": "https://github.com/soldair/node-walkdir/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "tjfontaine"
}
],
"deprecated": false,
"description": "Find files simply. Walks a directory tree emitting events based on what it finds. Presents a familiar callback/emitter/a+sync interface. Walk a tree of any depth.",
"devDependencies": {
"tape": "^4.0.0"
},
"engines": {
"node": ">=0.6.0"
},
"homepage": "http://github.com/soldair/node-walkdir",
"keywords": [
"find",
"walk",
"tree",
"files",
"fs"
],
"license": "MIT",
"main": "./walkdir.js",
"name": "walkdir",
"repository": {
"type": "git",
"url": "git://github.com/soldair/node-walkdir.git"
},
"scripts": {
"test": "tape test/*.js"
},
"version": "0.0.12"
}

178
express-server/node_modules/walkdir/readme.md generated vendored Normal file
View File

@ -0,0 +1,178 @@
[![Build Status](https://secure.travis-ci.org/soldair/node-walkdir.png)](http://travis-ci.org/soldair/node-walkdir)
## walkdir
Find files. Walks a directory tree emitting events based on what it finds. Presents a familliar callback/emitter/sync interface. Walk a tree of any depth. This is a performant option any pull requests to make it more so will be taken into consderation..
## Example
```js
var walk = require('walkdir');
//async with path callback
walk('../', function(path, stat) {
console.log('found: ', path);
});
//use async emitter to capture more events
var emitter = walk('../');
emitter.on('file', function(filename, stat) {
console.log('file from emitter: ', filename);
});
//sync with callback
walk.sync('../', function(path, stat) {
console.log('found sync:', path);
});
//sync just need paths
var paths = walk.sync('../');
console.log('found paths sync: ', paths);
```
## install
npm install walkdir
## arguments
walkdir(path, [options], [callback])
walkdir.sync(path, [options], [callback]);
- path
- the starting point of your directory walk
- options. supported options are
- general
```js
{
"follow_symlinks": false, // default is off
"no_recurse": false, // only recurse one level deep
"max_depth": undefined // only recurse down to max_depth. if you need more than no_recurse
"track_inodes": true // on windows or with hardlinks some files are not emitted due to inode collision.
// ^ should be used with max_depth to prevent infinite loop
}
```
- sync only
```js
{
"return_object": false, // if true the sync return will be in {path:stat} format instead of [path,path,...]
"no_return": false, // if true null will be returned and no array or object will be created with found paths. useful for large listings
}
```
- callback
- this is bound to the path event of the emitter. its optional in all cases.
```js
callback(path, stat)
```
## events
non error type events are emitted with (path,stat). stat is an instanceof fs.Stats
###path
fired for everything
###file
fired only for regular files
###directory
fired only for directories
###link
fired when a symbolic link is found
###end
fired when the entire tree has been read and emitted.
###socket
fired when a socket descriptor is found
###fifo
fired when a fifo is found
###characterdevice
fired when a character device is found
###blockdevice
fired when a block device is found
###targetdirectory
fired for the stat of the path you provided as the first argument. is is only fired if it is a directory.
###empty
fired for empty directory
## error events
error type events are emitted with (path,error). error being the error object returned from an fs call or other opperation.
###error
if the target path cannot be read an error event is emitted. this is the only failure case.
###fail
when stat or read fails on a path somewhere in the walk and it is not your target path you get a fail event instead of error.
This is handy if you want to find places you dont have access too.
## notes
the async emitter returned supports 3 methods
###end
stop a walk in progress
###pause
pause the walk. no more events will be emitted until resume
###resume
resume the walk
### ignore(path or array of paths)
will not traverse these directories. may be called in the path event handler to ignore dynamically.
```js
var walk = require('walkdir');
var p = require('path');
walk('/', function(path, stat) {
// ignore all .git directories.
if (p.basename(path) === '.git') {
this.ignore(path)
}
})
```
### cancel a walk in progress
```js
//cancel a walk in progress within callback.
var walk = require('walkdir');
walk('../', function(path, stat) {
this.end();
});
//cancel a walk in progress with emitter handle
var walk = require('walkdir');
var emitter = walk('../');
doSomethingAsync(function() {
emitter.end();
})
```
## thanks
thanks to substack. the interface for this module is based off of node-findit
## contributing
see `CONTRIBUTING.md` for guidelines. this is an open opensource project.

66
express-server/node_modules/walkdir/test/async.js generated vendored Normal file
View File

@ -0,0 +1,66 @@
var test = require('tape'),
walkdir = require('../walkdir.js');
var expectedPaths = {
'dir/foo/x':'file',
'dir/foo/a':'dir',
'dir/foo/a/y':'file',
'dir/foo/a/b':'dir',
'dir/foo/a/b/z':'file',
'dir/foo/a/b/c':'dir',
'dir/foo/a/b/c/w':'file'
};
test('async events',function(t){
var paths = [],
files = [],
dirs = [];
var emitter = walkdir(__dirname+'/dir/foo',function(path){
//console.log('path: ',path);
paths.push(path.replace(__dirname+'/',''));
});
emitter.on('directory',function(path,stat){
dirs.push(path.replace(__dirname+'/',''));
});
emitter.on('file',function(path,stat){
//console.log('file: ',path);
files.push(path.replace(__dirname+'/',''));
});
emitter.on('end',function(){
files.forEach(function(v,k){
t.equals(expectedPaths[v],'file','path from file event should be file');
});
var expected = Object.keys(expectedPaths);
t.ok(expected.length == paths.length, 'expected and emitted paths should have the same length');
expected.forEach(function(v,k){
if(expectedPaths[v] == 'file') {
t.ok(files.indexOf(v) > -1,'should have file in files array');
}
});
dirs.forEach(function(v,k){
t.equals(expectedPaths[v],'dir','path from dir event should be dir '+v);
});
expected.forEach(function(v,k){
if(expectedPaths[v] == 'dir') {
t.ok(dirs.indexOf(v) > -1,'should have dir in dirs array');
}
});
expected.forEach(function(v,k){
t.ok(paths.indexOf(v) !== -1,'should have found all expected paths '+v);
});
t.end();
});
});

View File

@ -0,0 +1,33 @@
var spawn = require('child_process').spawn;
var find = spawn('find',[process.argv[2]||'./']);
var fs = require('fs');
var buf = '',count = 0;
handleBuf = function(data){
buf += data;
if(buf.length >= 1024) {
var lines = buf.split("\n");
buf = lines.pop();//last line my not be complete
count += lines.length;
process.stdout.write(lines.join("\n")+"\n");
}
};
find.stdout.on('data',function(data){
//buf += data.toString();
handleBuf(data)
//process.stdout.write(data.toString());
});
find.on('end',function(){
handleBuf("\n");
console.log('found '+count+' files');
console.log('ended');
});
find.stdin.end();

View File

@ -0,0 +1,26 @@
import os
import sys
rootdir = sys.argv[1]
ino = {}
buf = []
for root, subFolders, files in os.walk(rootdir):
for filename in files:
filePath = os.path.join(root, filename)
try:
stat = os.lstat(filePath)
except OSError:
pass
inostr = stat.st_ino
if inostr not in ino:
ino[stat.st_ino] = 1
buf.append(filePath);
buf.append("\n");
if len(buf) >= 1024:
sys.stdout.write(''.join(buf))
buf = []
sys.stdout.write(''.join(buf));

View File

@ -0,0 +1,15 @@
var findit = require('findit');
var files = findit.findSync(process.argv[2]||'./');
var count = files.length;
console.log(files);
files = files.join("\n");
process.stdout.write(files+"\n");
console.log('found '+count+' files');

View File

@ -0,0 +1,14 @@
var findit = require('findit');
var find = findit.find(process.argv[2]||'./');
var count = 0;
find.on('file',function(path,stat){
count++;
process.stdout.write(path+"\n");
});
find.on('end',function(){
console.log('found '+count+' regular files');
});

View File

@ -0,0 +1,24 @@
var fstream = require('fstream');
var pipe = fstream.Reader(process.argv[2]||"../");
var count = 0,errorHandler;
pipe.on('entry',function fn(entry){
if(entry.type == "Directory"){
entry.on('entry',fn);
} else if(entry.type == "File") {
count++;
}
entry.on('error',errorHandler);
});
pipe.on('error',(errorHandler = function(error){
console.log('error event ',error);
}));
pipe.on('end',function(){
console.log('end! '+count);
});
//this is pretty slow

View File

@ -0,0 +1 @@
npm install

View File

@ -0,0 +1,18 @@
var lsr = require('ls-r');
lsr(process.argv[2]||'./',{maxDepth:500000,recursive:true},function(err,origPath,args){
if(err) {
console.log('eww an error! ',err);
return;
}
//console.log('hit');
var c = 0;
args.forEach(function(stat){
if(stat.isFile()){
console.log(stat.path);
c++;
}
});
console.log('found '+args.length+" regular files");
});

View File

@ -0,0 +1,10 @@
{
"name":"recursedir-comparisons",
"version": "0.0.0",
"author": "Ryan Day <soldair@gmail.com>",
"devDependencies": {
"findit": "*",
"ls-r":"*",
"fstream":"*"
}
}

34
express-server/node_modules/walkdir/test/custom_fs.js generated vendored Normal file
View File

@ -0,0 +1,34 @@
var test = require('tape'),
_fs = require('fs'),
walkdir = require('../walkdir.js');
var expectedPaths = {};
test('fs option',function(t){
var paths = [];
var emitter = walkdir(__dirname+'/dir/foo',{fs:
{
readdir: function () {
var cb = arguments[arguments.length - 1];
cb(null, []);
},
lstat: function (file) {
var cb = arguments[arguments.length - 1];
return _fs.lstat(__dirname, cb);
}
}
},function(path,stat,depth){
t.fail('there should be no files emitted');
});
emitter.on('end',function(){
var expected = Object.keys(expectedPaths);
t.ok(expected.length == paths.length, 'expected and emitted paths should have the same length');
paths.forEach(function(v){
t.ok(expected.indexOf(v) > -1,'all expected files should be in paths');
});
t.end();
});
});

View File

View File

0
express-server/node_modules/walkdir/test/dir/foo/a/y generated vendored Normal file
View File

0
express-server/node_modules/walkdir/test/dir/foo/x generated vendored Normal file
View File

View File

@ -0,0 +1 @@
found me!

View File

View File

View File

19
express-server/node_modules/walkdir/test/endearly.js generated vendored Normal file
View File

@ -0,0 +1,19 @@
var test = require('tape'),
walk = require('../walkdir.js');
test('should be able to end walk after first path',function(t){
var paths = [];
var em = walk('../',function(path){
paths.push(path);
this.end();
});
em.on('end',function(){
t.equals(paths.length,1,'should have only found one path');
t.end();
});
});

View File

@ -0,0 +1,19 @@
var test = require('tape')
var walkdir = require('../')
test('async events',function(t){
var paths = [],
files = [],
dirs = [];
var emitter = walkdir(__dirname+'/dir/foo',function(path){
paths.push(path.replace(__dirname+'/',''));
if(path === __dirname+'/dir/foo/a') this.ignore(__dirname+'/dir/foo/a');
})
emitter.on('end',function(){
t.equals(paths.sort().join('|'),'dir/foo/a|dir/foo/x','should have ignored under a');
t.end();
})
})

View File

@ -0,0 +1,18 @@
var test = require('tape')
var walkdir = require('../')
test('async events',function(t){
var paths = [],
files = [],
dirs = [];
var emitter = walkdir(__dirname+'/dir/foo',function(path){
paths.push(path.replace(__dirname+'/',''));
}).ignore(__dirname+'/dir/foo');
emitter.on('end',function(){
t.equals(paths.length,0,'should have no paths')
t.end();
})
})

18
express-server/node_modules/walkdir/test/ignore.js generated vendored Normal file
View File

@ -0,0 +1,18 @@
var test = require('tape')
var walkdir = require('../')
test('async events',function(t){
var paths = [],
files = [],
dirs = [];
var emitter = walkdir(__dirname+'/dir/foo',function(path){
paths.push(path.replace(__dirname+'/',''));
}).ignore(__dirname+'/dir/foo/a');
emitter.on('end',function(){
t.equals(paths.sort().join('|'),'dir/foo/a|dir/foo/x','should have ignored under a');
t.end();
})
})

30
express-server/node_modules/walkdir/test/max_depth.js generated vendored Normal file
View File

@ -0,0 +1,30 @@
var test = require('tape'),
walkdir = require('../walkdir.js');
var expectedPaths = {
'dir/foo/x':'file',
'dir/foo/a':'dir',
'dir/foo/a/y':'file',
'dir/foo/a/b':'dir'
};
test('no_recurse option',function(t){
var paths = [];
var emitter = walkdir(__dirname+'/dir/foo',{max_depth:2},function(path,stat,depth){
paths.push(path.replace(__dirname+'/',''));
t.ok(depth < 3,' all paths emitted should have a depth less than 3');
});
emitter.on('end',function(){
var expected = Object.keys(expectedPaths);
t.ok(expected.length == paths.length, 'expected and emitted paths should have the same length');
paths.forEach(function(v){
t.ok(expected.indexOf(v) > -1,'paths should not have any unexpected files');
});
t.end();
});
});

View File

@ -0,0 +1,43 @@
var test = require('tape')
var walkdir = require('../walkdir.js')
var basename = require('path').basename
test('follow symlinks',function(t){
var links = [],paths = [],failures = [],errors = [], files = [];
var emitter = walkdir(__dirname+'/dir/nested-symlink',{follow_symlinks:true});
emitter.on('path',function(path,stat){
paths.push(path);
});
emitter.on('file',function(path,stat){
files.push(path);
});
emitter.on('link',function(path,stat){
links.push(path);
});
emitter.on('error',function(path,err){
console.log('error!!', arguments);
errors.push(arguments);
});
emitter.on('fail',function(path,err){
failures.push(path);
});
emitter.on('end',function(){
t.equal(files.length,1)
t.equal(basename(files[0]),'found-me','found the nested symlink')
t.equal(paths.length,3,'should find 3 things')
t.ok(!failures.length,'no failures')
t.end();
});
})

28
express-server/node_modules/walkdir/test/no_recurse.js generated vendored Normal file
View File

@ -0,0 +1,28 @@
var test = require('tape'),
walkdir = require('../walkdir.js');
var expectedPaths = {
'dir/foo/x':'file',
'dir/foo/a':'dir'
};
test('no_recurse option',function(t){
var paths = [];
var emitter = walkdir(__dirname+'/dir/foo',{no_recurse:true},function(path,stat,depth){
paths.push(path.replace(__dirname+'/',''));
t.ok(depth === 1,' all paths emitted should have a depth of 1');
});
emitter.on('end',function(){
var expected = Object.keys(expectedPaths);
t.ok(expected.length == paths.length, 'expected and emitted paths should have the same length');
paths.forEach(function(v){
t.ok(expected.indexOf(v) > -1,'all expected files should be in paths');
});
t.end();
});
});

View File

@ -0,0 +1,34 @@
var test = require('tape'),
fs = require('fs'),
path = require('path'),
walk = require('../walkdir.js');
test('should not emit fail events for empty dirs',function(t){
fs.mkdir('./empty',function(err,data){
if(err) {
t.equals(err.code,'EEXIST','if error code on mkdir for fixture it should only be because it exists already');
}
var paths = [];
var dirs = [];
var emptys = [];
var fails = [];
var em = walk('./');
em.on('fail',function(path,err){
fails.push(path);
});
em.on('empty',function(path,err){
emptys.push(path);
});
em.on('end',function(){
t.equals(fails.length,0,'should not have any fails');
t.equals(path.basename(emptys[0]),'empty','should find empty dir');
t.end();
});
});
});

View File

@ -0,0 +1,36 @@
var test = require('tape'),
walk = require('../walkdir.js');
test('should be able to pause walk',function(t){
var paths = [];
var paused = false;
var em = walk('./',function(path){
if(!paused){
em.pause();
paused = 1;
setTimeout(function(){
t.equals(paths.length,1,'while paused should not emit any more paths');
em.resume();
},300);
} else if(paused == 1){
em.pause();
paused = 2;
setTimeout(function(){
t.equals(paths.length,2,'while paused should not emit any more paths');
em.resume();
},300);
}
paths.push(path);
});
em.on('end',function(){
console.log('end, and i found ',paths.length,'paths');
t.ok(paths.length > 1,'should have more paths before end');
t.end();
});
});

37
express-server/node_modules/walkdir/test/symlink.js generated vendored Normal file
View File

@ -0,0 +1,37 @@
var test = require('tape'),
walkdir = require('../walkdir.js');
test('follow symlinks',function(t){
var links = [],paths = [],failures = [],errors = [];
var emitter = walkdir(__dirname+'/dir/symlinks/dir2',{follow_symlinks:true});
emitter.on('path',function(path,stat){
paths.push(path);
});
emitter.on('link',function(path,stat){
links.push(path);
});
emitter.on('error',function(path,err){
console.log('error!!', arguments);
errors.push(arguments);
});
emitter.on('fail',function(path,err){
failures.push(path);
});
emitter.on('end',function(){
t.equal(errors.length,0,'should have no errors');
t.equal(failures.length,1,'should have a failure');
t.ok(paths.indexOf(__dirname+'/dir/symlinks/dir1/file1') !== -1,'if follow symlinks works i would have found dir1 file1');
t.equal(require('path').basename(failures[0]),'does-not-exist','should have fail resolviong does-not-exist which dangling-symlink points to');
t.end();
});
});

52
express-server/node_modules/walkdir/test/sync.js generated vendored Normal file
View File

@ -0,0 +1,52 @@
var test = require('tape'),
walkdir = require('../walkdir.js');
var expectedPaths = {
'dir/foo/x':'file',
'dir/foo/a':'dir',
'dir/foo/a/y':'file',
'dir/foo/a/b':'dir',
'dir/foo/a/b/z':'file',
'dir/foo/a/b/c':'dir',
'dir/foo/a/b/c/w':'file'
};
test('sync',function(t){
var paths = [],
files = [],
dirs = [];
var pathResult = walkdir.sync(__dirname+'/dir/foo',function(path){
console.log('path: ',path);
paths.push(path);
});
t.ok(pathResult instanceof Array,'if return object is not specified should be an array');
t.equals(Object.keys(expectedPaths).length,paths.length,'should have found the same number of paths as expected');
Object.keys(expectedPaths).forEach(function(v,k){
t.ok(paths.indexOf(__dirname+'/'+v) > -1,v+' should be found');
});
t.deepEquals(paths,pathResult,'paths should be equal to pathResult');
t.end();
});
test('sync return object',function(t){
var pathResult = walkdir.sync(__dirname+'/dir/foo',{return_object:true});
t.ok(!(pathResult instanceof Array),'if return object is not specified should be an array');
t.equals(Object.keys(expectedPaths).length,Object.keys(pathResult).length,'should find the same number of paths as expected');
Object.keys(expectedPaths).forEach(function(v,k){
t.ok(pathResult[__dirname+'/'+v],'should find path in result object');
});
t.end();
});

256
express-server/node_modules/walkdir/walkdir.js generated vendored Normal file
View 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;
}
}