Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

findit

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

findit - npm Package Compare versions

Comparing version 0.1.2 to 1.0.0

.travis.yml

229

index.js

@@ -0,142 +1,123 @@

var EventEmitter = require('events').EventEmitter;
var fs = require('fs');
var path = require('path');
var EventEmitter = require('events').EventEmitter;
var Seq = require('seq');
function createInodeChecker() {
var inodes = {};
return function inodeSeen(inode) {
if (inodes[inode]) {
return true;
} else {
inodes[inode] = true;
return false;
}
module.exports = function walk (dir, opts, emitter, dstat) {
if (!opts) opts = {};
var fdir = opts._original || dir;
opts._original = undefined;
if (!emitter) {
emitter = new EventEmitter;
emitter._pending = 0;
emitter._seen = {};
}
}
exports = module.exports = find;
exports.find = find;
function find (base, options, cb) {
cb = arguments[arguments.length - 1];
if (typeof(cb) !== 'function') {
cb = undefined;
}
var em = new EventEmitter;
var inodeSeen = createInodeChecker();
emitter._pending ++;
function finder (dir, f) {
Seq()
.seq(fs.readdir, dir, Seq)
.flatten()
.seqEach(function (file) {
var p = dir + '/' + file;
fs.lstat(p, this.into(p));
})
.seq(function () {
this(null, Object.keys(this.vars));
})
.flatten()
.seqEach(function (file) {
var stat = this.vars[file];
if (cb) cb(file, stat);
if (inodeSeen(stat.ino)) {
// already seen this inode, probably a recursive symlink
this(null);
}
else {
em.emit('path', file, stat);
if (stat.isSymbolicLink()) {
em.emit('link', file, stat);
if (options && options.follow_symlinks) {
path.exists(file, function(exists) {
if (exists) {
fs.readlink(file, function(err, resolvedPath) {
if (err) {
em.emit('error', err);
} else {
finder(path.resolve(path.dir(file), resolvedPath));
}
});
}
});
} else {
this(null);
}
}
else if (stat.isDirectory()) {
em.emit('directory', file, stat);
finder(file, this);
}
else {
em.emit('file', file, stat);
this(null);
}
}
})
.seq(f.bind({}, null))
.catch(em.emit.bind(em, 'error'))
;
if (dstat) {
var stopped = false;
emitter.emit('directory', fdir, dstat, function stop () {
stopped = true;
});
emitter.emit('path', fdir, dstat);
if (!stopped) fs.readdir(dir, onreaddir);
else check()
}
fs.lstat(base, function (err, s) {
if (err) {
em.emit('error', err);
else fs.lstat(dir, function onstat (err, stat) {
if (err) return finish();
emitter._seen[stat.ino] = true;
if (stat.isSymbolicLink() && opts.followSymlinks) {
emitter.emit('link', fdir, stat);
fs.readlink(dir, function (err, rfile) {
if (err) return finish();
var file_ = path.resolve(dir, rfile);
emitter.emit('readlink', fdir, file_);
fs.lstat(file_, onstat);
});
}
if (s.isDirectory()) {
finder(base, em.emit.bind(em, 'end'));
else if (stat.isSymbolicLink()) {
emitter.emit('link', fdir, stat);
emitter.emit('path', fdir, stat);
finish();
}
else if (s.isSymbolicLink()) {
if (cb) cb(base, s);
em.emit('link', base, s);
em.emit('end');
else if (stat.isDirectory()) {
var stopped = false;
emitter.emit('directory', fdir, stat, function stop () {
stopped = true;
});
emitter.emit('path', fdir, stat);
if (!stopped) fs.readdir(dir, onreaddir);
else check()
}
else {
if (cb) cb(base, s);
em.emit('file', base, s);
em.emit('end');
emitter.emit('file', fdir, stat);
emitter.emit('path', fdir, stat);
finish();
}
});
return em;
};
exports.findSync = function findSync(dir, options, callback) {
cb = arguments[arguments.length - 1];
if (typeof(cb) !== 'function') {
cb = undefined;
return emitter;
function check () {
if (-- emitter._pending === 0) finish();
}
var inodeSeen = createInodeChecker();
var files = [];
var fileQueue = [];
var processFile = function processFile(file) {
var stat = fs.lstatSync(file);
if (inodeSeen(stat.ino)) {
return;
}
files.push(file);
cb && cb(file, stat)
function finish () {
emitter.emit('end');
emitter._seen = null;
}
function onreaddir (err, files) {
emitter._pending --;
if (err) return check();
files.forEach(function (rfile) {
emitter._pending ++;
var file = path.join(fdir, rfile);
fs.lstat(file, function (err, stat) {
if (err) check()
else onstat(file, stat)
});
});
}
function onstat (file, stat, original) {
if (emitter._seen[stat.ino]) return check();
emitter._seen[stat.ino] = true;
if (stat.isDirectory()) {
fs.readdirSync(file).forEach(function(f) { fileQueue.push(path.join(file, f)); });
} else if (stat.isSymbolicLink()) {
if (options && options.follow_symlinks && path.existsSync(file)) {
fileQueue.push(fs.realpathSync(file));
}
if (original) opts._original = original;
walk(file, opts, emitter, stat);
check();
}
};
/* we don't include the starting directory unless it is a file */
var stat = fs.lstatSync(dir);
if (stat.isDirectory()) {
fs.readdirSync(dir).forEach(function(f) { fileQueue.push(path.join(dir, f)); });
} else {
fileQueue.push(dir);
else if (stat.isSymbolicLink() && opts.followSymlinks) {
emitter.emit('link', file, stat);
fs.readlink(file, function (err, rfile) {
if (err) return check();
var file_ = path.resolve(path.dirname(file), rfile);
emitter.emit('readlink', file, file_);
fs.lstat(file_, function (err, stat_) {
if (err) return check();
emitter._pending ++;
onstat(file_, stat_, file);
check();
});
});
}
else if (stat.isSymbolicLink()) {
emitter.emit('link', file, stat);
emitter.emit('path', file, stat);
check();
}
else {
emitter.emit('file', file, stat);
emitter.emit('path', file, stat);
check();
}
}
while (fileQueue.length > 0) {
processFile(fileQueue.shift());
}
return files;
};
exports.find.sync = exports.findSync;
{
"name" : "findit",
"version" : "0.1.2",
"description" : "Walk a directory tree.",
"main" : "./index.js",
"dependencies" : {
"seq" : ">=0.1.7"
},
"devDependencies" : {
"hashish" : ">=0.0.2 <0.1",
"expresso" : "0.7.x"
},
"scripts" : {
"test" : "expresso"
},
"repository" : {
"type" : "git",
"url" : "http://github.com/substack/node-findit.git"
},
"keywords" : [
"find",
"walk",
"directory",
"recursive",
"tree"
],
"author" : {
"name" : "James Halliday",
"email" : "mail@substack.net",
"url" : "http://substack.net"
},
"license" : "MIT/X11",
"engine" : ["node >=0.2.0"]
"name": "findit",
"version": "1.0.0",
"description": "walk a directory tree recursively with events",
"main": "index.js",
"devDependencies": {
"tap": "~0.4.4"
},
"scripts": {
"test": "tap test/*.js"
},
"repository": {
"type": "git",
"url": "http://github.com/substack/node-findit.git"
},
"keywords": [
"find",
"walk",
"directory",
"recursive",
"tree",
"traversal"
],
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"license": "MIT"
}

@@ -1,18 +0,12 @@

var assert = require('assert');
var find = require('../').find;
var findSync = require('../').findSync;
var find = require('../');
var test = require('tap').test;
exports.foo = function () {
var to = setTimeout(function () {
assert.fail('Never caught "end"');
}, 5000);
test('foo', function (t) {
var finder = find(__dirname + '/foo');
var ps = {};
var finder = find(__dirname + '/foo', function (file, stat) {
ps[file] = stat.isDirectory();
});
var paths = []
finder.on('path', function (p) {
finder.on('path', function (p, stat) {
paths.push(p);
ps[p] = stat.isDirectory();
});

@@ -31,4 +25,4 @@

finder.on('end', function () {
clearTimeout(to);
var ref = {
'' : true,
'a' : true,

@@ -43,14 +37,14 @@ 'a/b' : true,

assert.eql(Object.keys(ref).length, Object.keys(ps).length);
t.equal(Object.keys(ref).length, Object.keys(ps).length);
var count = { dirs : 0, files : 0, paths : 0 };
Object.keys(ref).forEach(function (key) {
var file = __dirname + '/foo/' + key;
assert.eql(ref[key], ps[file]);
var file = (__dirname + '/foo/' + key).replace(/\/$/, '');
t.equal(ref[key], ps[file]);
if (ref[key]) {
assert.ok(dirs.indexOf(file) >= 0);
t.ok(dirs.indexOf(file) >= 0);
count.dirs ++;
}
else {
assert.ok(files.indexOf(file) >= 0);
t.ok(files.indexOf(file) >= 0);
count.files ++;

@@ -60,23 +54,7 @@ }

assert.eql(count.dirs, dirs.length);
assert.eql(count.files, files.length);
assert.eql(paths.sort(), Object.keys(ps).sort());
t.deepEqual(count.dirs, dirs.length);
t.deepEqual(count.files, files.length);
t.deepEqual(paths.sort(), Object.keys(ps).sort());
t.end();
});
};
exports.fooSync = function () {
assert.eql(
findSync(__dirname + '/foo')
.reduce(function (files, file) {
files[file] = true;
return files;
}, {}),
[ 'a', 'a/b', 'a/b/c', 'x', 'a/y', 'a/b/z', 'a/b/c/w' ]
.reduce(function (files, file) {
files[__dirname + '/foo/' + file] = true;
return files;
}, {})
);
assert.eql(findSync(__dirname + '/foo/x'), [ __dirname + '/foo/x' ]);
};
});

@@ -1,13 +0,6 @@

var assert = require('assert');
var find = require('../');
var test = require('tap').test;
exports.module = function () {
assert.eql(find.findSync, find.find.sync);
assert.eql(find, find.find);
};
exports.file = function () {
var to = setTimeout(function () {
assert.fail('never ended');
}, 5000);
test('single file', function (t) {
t.plan(2);

@@ -17,3 +10,3 @@ var finder = find(__filename);

finder.on('file', function (file) {
assert.equal(file, __filename);
t.equal(file, __filename);
files.push(file);

@@ -23,9 +16,8 @@ });

finder.on('directory', function (dir) {
assert.fail(dir);
t.fail(dir);
});
finder.on('end', function () {
clearTimeout(to);
assert.deepEqual(files, [ __filename ]);
t.deepEqual(files, [ __filename ]);
});
};
});

@@ -1,42 +0,36 @@

var assert = require('assert');
var test = require('tap').test;
var path = require('path');
var findit = require('../');
var to = setTimeout(function () {
assert.fail('never ended');
}, 5000);
function find_helper(dir, options, callback) {
function helper(t, dir, options, callback) {
var symlinks = [];
var files = [];
var dirs = [];
var finder = findit.find(dir, options);
var finder = findit(dir, options);
finder.on('link', function (link, stat) {
assert.ok(stat.isSymbolicLink());
t.ok(stat.isSymbolicLink());
symlinks.push(path.basename(link));
});
finder.on('file', function (file, stat) {
assert.ok(stat.isFile());
t.ok(stat.isFile());
files.push(path.basename(file));
});
finder.on('directory', function (dir, stat) {
assert.ok(stat.isDirectory());
t.ok(stat.isDirectory());
dirs.push(path.basename(dir));
});
finder.on('error', function (err) {
assert.fail(err);
t.fail(err);
});
finder.on('end', function () {
clearTimeout(to);
symlinks.sort();
files.sort();
dirs.sort();
callback({ symlinks: symlinks, files: files, dirs: dirs });

@@ -46,29 +40,40 @@ });

exports.links = function() {
find_helper(__dirname + '/symlinks/dir1', { follow_symlinks: false }, function(data) {
assert.eql(['dangling-symlink', 'link-to-dir2', 'link-to-file'], data.symlinks);
assert.eql(['file1'], data.files);
assert.eql([], data.dirs);
});
};
test('links', function (t) {
helper(t, __dirname + '/symlinks/dir1', { followSymlinks: false }, done);
function done (data) {
t.deepEqual(data.symlinks, [
'dangling-symlink', 'link-to-dir2', 'link-to-file'
]);
t.deepEqual(data.files, [ 'file1' ]);
t.deepEqual(data.dirs, [ 'dir1' ]);
t.end();
}
});
exports.follow_links = function() {
find_helper(__dirname + '/symlinks/dir1', { follow_symlinks: true }, function(data) {
assert.eql(['cyclic-link-to-dir1', 'dangling-symlink', 'link-to-dir2', 'link-to-file'], data.symlinks);
assert.eql(['file', 'file1', 'file2'], data.files);
assert.eql(['dir1', 'dir2'], data.dirs);
});
};
test('follow links', function (t) {
helper(t, __dirname + '/symlinks/dir1', { followSymlinks: true }, done);
function done (data) {
t.deepEqual(data.symlinks, [
'cyclic-link-to-dir1', 'dangling-symlink', 'link-to-dir2',
'link-to-file'
]);
t.deepEqual(data.files, ['file', 'file1', 'file2']);
t.deepEqual(data.dirs, [ 'dir1', 'link-to-dir2' ]);
t.end();
}
});
exports.links_sync = function() {
var files = findit.findSync(__dirname + '/symlinks/dir1', { follow_symlinks: false }).map(path.basename);
files.sort();
assert.eql(['dangling-symlink', 'file1', 'link-to-dir2', 'link-to-file'], files);
};
exports.follow_links_sync = function() {
var files = findit.findSync(__dirname + '/symlinks/dir1', { follow_symlinks: true }).map(path.basename);
files.sort();
assert.eql(['cyclic-link-to-dir1', 'dangling-symlink', 'dir1', 'dir2', 'file', 'file1', 'file2', 'link-to-dir2', 'link-to-file'], files);
};
test('parent links', function (t) {
helper(t, __dirname + '/symlinks', { followSymlinks: true }, done);
function done (data) {
t.deepEqual(data.symlinks, [
'cyclic-link-to-dir1', 'dangling-symlink', 'link-to-dir2',
'link-to-file'
]);
t.deepEqual(data.files, ['file', 'file1', 'file2']);
t.deepEqual(data.dirs, [ 'dir1', 'dir2', 'symlinks' ]);
t.end();
}
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc