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

node-readfiles

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-readfiles - npm Package Compare versions

Comparing version 0.0.9 to 0.1.0

183

lib/readfiles.js
var fs = require('fs');
var path = require('path');
var Promise = require('es6-promise').Promise;

@@ -27,5 +28,4 @@ function buildFilter(filters) {

function readfiles(dir, options, callback, doneCallback) {
function readfiles(dir, options, callback) {
if (typeof options === 'function' || options === null) {
doneCallback = callback;
callback = options;

@@ -35,104 +35,123 @@ options = {};

options = options || {};
callback = typeof callback === 'function' ? callback : null;
doneCallback = doneCallback || function () {};
callback = typeof callback === 'function' ? callback : function () {};
return new Promise(function (resolve, reject) {
var files = [];
var subdirs = [];
var filterRegExp = options.filter && buildFilter(options.filter);
var files = [];
var subdirs = [];
var filterRegExp = options.filter && buildFilter(options.filter);
(function traverseDir(dirpath, done) {
fs.readdir(dirpath, function (err, fileList) {
if (err) {
done(err, files.length, files);
return;
}
// reverse the order of the files if the reverse option is true
if (options.reverse === true) {
fileList = fileList.reverse();
}
(function next() {
if (fileList.length === 0) {
done(null, files, files.length);
return;
(function traverseDir(dirpath, done) {
fs.readdir(dirpath, function (err, fileList) {
if (err) {
// if rejectOnError is not false, reject the promise
if (options.rejectOnError !== false) {
return reject(err);
}
return done(files);
}
var filename = fileList.shift();
var relFilename = path.join(subdirs.join('/'), filename);
var fullpath = path.join(dirpath, filename);
// skip file if it's a hidden file and the hidden option is not set
if (options.hidden !== true && /^\./.test(filename)) {
return next();
// reverse the order of the files if the reverse option is true
if (options.reverse === true) {
fileList = fileList.reverse();
}
// stat the full path
fs.stat(fullpath, function (err, stat) {
if (err) {
if (callback && callback(err, relFilename, null, stat, next) === false && !err) {
return;
}
if (options.doneOnError !== false) {
return doneCallback(err, files, files.length);
}
(function next() {
var cbNext = null;
if (options.async === true) cbNext = next;
// if the file list is empty then call done
if (fileList.length === 0) {
done(files);
return;
}
var filename = fileList.shift();
var relFilename = path.join(subdirs.join('/'), filename);
var fullpath = path.join(dirpath, filename);
// skip file if it's a hidden file and the hidden option is not set
if (options.hidden !== true && /^\./.test(filename)) {
return next();
}
if (stat.isDirectory()) {
// limit the depth of the traversal if depth is defined
if (!isNaN(options.depth) && options.depth >= 0 && (subdirs.length + 1) > options.depth) {
return next();
}
// stat the full path
fs.stat(fullpath, function (err, stat) {
// traverse the sub-directory
subdirs.push(filename);
traverseDir(fullpath, function (err, count, files) {
subdirs.pop();
next();
});
} else if (stat.isFile()) {
if (err) {
// call callback with the error
callback(err, relFilename, null, stat, cbNext);
// test filters, if it does not match move to next file
if (filterRegExp && !filterRegExp.test('/' + relFilename)) {
return next();
}
// if rejectOnError is not false, reject the promise
if (options.rejectOnError !== false) {
return reject(err);
}
// set the format of the output filename
var outputName = relFilename;
if (options.filenameFormat === readfiles.FULL_PATH) {
outputName = fullpath;
}else if (options.filenameFormat === readfiles.FILENAME) {
outputName = filename;
//if async is true then don't call next
return options.async !== true && next();
}
files.push(outputName);
// skip reading the file if readContents is false
if (options.readContents === false) {
if (callback && callback(null, outputName, null, stat, next) === false) {
return;
if (stat.isDirectory()) {
// limit the depth of the traversal if depth is defined
if (!isNaN(options.depth) && options.depth >= 0 && (subdirs.length + 1) > options.depth) {
return next();
}
return next();
}
// read the file
fs.readFile(fullpath, options.encoding || 'utf8', function (err, content) {
// traverse the sub-directory
subdirs.push(filename);
traverseDir(fullpath, function (err, count, files) {
subdirs.pop();
next();
});
// call "callback"
if (callback && callback(err, outputName, content, stat, next) === false && !err) {
return;
} else if (stat.isFile()) {
// test filters, if it does not match move to next file
if (filterRegExp && !filterRegExp.test('/' + relFilename)) {
return next();
}
if (err && options.doneOnError !== false) {
return doneCallback(err, files, files.length);
// set the format of the output filename
var outputName = relFilename;
if (options.filenameFormat === readfiles.FULL_PATH) {
outputName = fullpath;
}else if (options.filenameFormat === readfiles.FILENAME) {
outputName = filename;
}
files.push(outputName);
// promise to handle file reading (if not disabled)
new Promise(function (resolve, reject) {
if (options.readContents === false) {
return resolve(null);
}
// read the file
fs.readFile(fullpath, options.encoding || 'utf8', function (err, content) {
if (err) throw err;
resolve(content);
});
}).then(function (content) {
// call the callback with the content
callback(err, outputName, content, stat, cbNext);
// call the next if async is not true
options.async !== true && next();
}).catch(function (err) {
if (options.rejectOnError !== false) {
return reject(err);
}
//if async is true then don't call next
options.async !== true && next();
});
} else {
next();
});
} else {
next();
}
}
});
})();
});
})(dir, doneCallback);
});
})();
});
})(dir, resolve);
});
}

@@ -139,0 +158,0 @@

{
"name": "node-readfiles",
"version": "0.0.9",
"description": "A lightweight Node.js module to recursively read files in a directory",
"version": "0.1.0",
"description": "A lightweight Node.js module to recursively read files in a directory using ES6 Promises",
"main": "index.js",

@@ -29,3 +29,6 @@ "scripts": {

"mock-fs": "^3.9.0"
},
"dependencies": {
"es6-promise": "^3.2.1"
}
}
# node-readfiles
A lightweight node.js module to recursively read files in a directory.
A lightweight node.js module to recursively read files in a directory using ES6 Promises.

@@ -16,4 +16,4 @@ ## Installation

### readfiles(dir, [options], callback, [doneCallback])
Asynchronusly read the files in a directory
### _Promise(files):_ readfiles(dir, [options], [callback])
Asynchronusly read the files in a directory returning a **Promise**.

@@ -29,3 +29,3 @@ #### dir

* **filenameFormat**: one of `readfiles.FULL_PATH`, `readfiles.RELATIVE`, or `readfiles.FILENAME`, wether the callback's returns the full-path, relative-path or only the filenames of the traversed files. (default is `readfiles.RELATIVE`)
* **doneOnError**: a bollean value wether to stop and trigger the "doneCallback" when an error occurs (defaults to true)
* **rejectOnError**: a bollean value wether to stop and trigger the "doneCallback" when an error occurs (defaults to true)
* **filter**: a string, or an array of strings of path expression that match the files being read (defaults to '**')

@@ -39,2 +39,3 @@ * `?` matches one character

* **hidden**: a boolean value wether to exclude hidden files prefixed with a `.` (defaults to true)
* **async**: a boolean value which enables/disables asynchronous traversal of the tree. When set to `true`, the `next()` in the `callback` must be called. (defaults to false)

@@ -46,3 +47,3 @@

If you're doing a long operation and want to pause on every file, have the callback return `false`, will cause `readfiles` to pause until you call `next`. See bellow for an example.
When working with asynchronous operations, you can set the `async` to `true`. This will enabled you to continue traversal of the directory when you call `next()`. See bellow for an example.

@@ -52,6 +53,20 @@

### doneCallback(err, files, count)
### _Promise(files)_
The callback function that is triggered once all the files have been read, passing the number of files read and an array with the full path of all files.
When calling `readfiles`, an ES6 Promise is returned with an array of all the files that were found. You can then call `then` or `catch` to see if `readfiles` encountered an error.
```javascript
var readfiles = require('node-readfiles');
readfiles('/path/to/dir/', function (err, filename, contents) {
if (err) throw err;
console.log('File ' + filename + ':');
console.log(content);
}).then(function (files) {
console.log('Read ' + files.length + ' file(s)');
}).catch(function (err) {
console.log('Error reading files:', err.message);
});
```
## Examples

@@ -62,4 +77,2 @@

```javascript
var readfiles = require('readfiles');
readfiles('/path/to/dir/', function (err, filename, contents) {

@@ -69,4 +82,4 @@ if (err) throw err;

console.log(content);
}, function (err, count, files) {
console.log('Read ' + count + ' file(s)');
}).then(function (files) {
console.log('Read ' + files.length + ' file(s)');
console.log(files.join('\n'));

@@ -79,4 +92,2 @@ });

```javascript
var readfiles = require('readfiles');
readfiles('/path/to/dir/', {

@@ -88,4 +99,4 @@ depth: 0

console.log(content);
}, function (err, count, files) {
console.log('Read ' + count + ' file(s)');
}).then(function (files) {
console.log('Read ' + files.length + ' file(s)');
console.log(files.join('\n'));

@@ -95,7 +106,5 @@ });

The above can also be accomplished using `filter`.
The above can also be accomplished using the `filter` option.
```javascript
var readfiles = require('readfiles');
readfiles('/path/to/dir/', {

@@ -107,4 +116,4 @@ filter: '*' // instead of the default '**'

console.log(content);
}, function (err, count, files) {
console.log('Read ' + count + ' file(s)');
}).then(function (files) {
console.log('Read ' + files.length + ' file(s)');
console.log(files.join('\n'));

@@ -117,4 +126,2 @@ });

```javascript
var readfiles = require('readfiles');
readfiles('/path/to/dir/', {

@@ -126,4 +133,4 @@ filter: '*.txt'

console.log(content);
}, function (err, count, files) {
console.log('Read ' + count + ' text file(s)');
}).then(function (files) {
console.log('Read ' + files.length + ' file(s)');
});

@@ -136,4 +143,2 @@

```javascript
var readfiles = require('readfiles');
readfiles('/path/to/dir/', {

@@ -145,4 +150,4 @@ filter: '*.t?t'

console.log(content);
}, function (err, count, files) {
console.log('Read ' + count + ' text file(s)');
}).then(function (files) {
console.log('Read ' + files.length + ' file(s)');
});

@@ -155,4 +160,2 @@

```javascript
var readfiles = require('readfiles');
readfiles('/path/to/dir/', {

@@ -168,8 +171,8 @@ filter: '*.json',

This example waits for async calls to occur on every file.
When making asynchronous calls on files, you can enable asynchronous support by setting the `async` to `true`.
```javascript
var readfiles = require('readfiles');
readfiles('/path/to/dir/', function (err, content, filename, stat, next) {
readfiles('/path/to/dir/', {
async: true
}, function (err, content, filename, stat, next) {
if (err) throw err;

@@ -185,35 +188,3 @@ setTimeout(function () {

A simple example that works like `find`
```javascript
var readfiles = require('node-readfiles');
var path = require('path');
function fileSize(size) {
var unit = 'B';
if (size > 1000000000) {
unit = 'T';
size /= 1000000000;
}else if (size > 1000000) {
unit = 'M';
size /= 1000000;
}else if (size > 1000) {
unit = 'K';
size /= 1000;
}
return (Math.round(size * 10) / 10) + unit;
}
var basepath = path.resolve(process.cwd(), process.argv.pop());
readfiles(basepath, {
readContents: false
}, function (err, filename, content, stat) {
console.log(filename, fileSize(stat.size), (stat.mode & 0777).toString(8));
}, function (err, files, count) {
console.log('\nTotal of', count, 'file(s) found\n');
});
```
## License
MIT licensed (See LICENSE.txt)

@@ -10,3 +10,3 @@ var expect = require('chai').expect;

describe('readfiles method', function() {
describe('readfiles', function() {
after(function () {

@@ -16,3 +16,3 @@ mock.restore();

describe('callbacks', function () {
describe('defaults', function () {
beforeEach(function () {

@@ -44,5 +44,5 @@ mock(fixtures.flat);

it('calls the done callback when finished traversing all files', function (done) {
readfiles('/path/to/dir', null, function (err, files, count) {
expect(count).to.equal(4);
it('resolves the promise when finished traversing all files', function (done) {
readfiles('/path/to/dir').then(function (files) {
expect(files.length).to.equal(4);
done();

@@ -53,3 +53,3 @@ });

it('calls the done callback with an error on a path', function(done) {
readfiles('/fake/invalid/dir', null, function (err, files, count) {
readfiles('/fake/invalid/dir').catch(function (err) {
expect(err.message).to.equal('ENOENT, no such file or directory \'/fake/invalid/dir\'');

@@ -70,3 +70,3 @@ done();

reverse: true
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal([

@@ -114,3 +114,3 @@ 'subdir/test789.txt',

expect(filename).to.equal(expectFiles[count++]);
}, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -143,3 +143,3 @@ done();

expect(filename).to.equal(expectFiles[count++]);
}, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -172,3 +172,3 @@ done();

expect(filename).to.equal(expectFiles[count++]);
}, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -179,3 +179,3 @@ done();

it('does not call done when one file throws an error and \'doneOnError\' is false', function(done) {
it('does not call done when one file throws an error and \'rejectOnError\' is false', function(done) {
mock(fixtures.deepError);

@@ -185,7 +185,7 @@

readfiles('/path/to/dir', {
doneOnError: false
rejectOnError: false
}, function (err, filename) {
fileCount++;
}, function (err, files, count) {
expect(count).to.equal(11);
}).then(function (files) {
expect(files.length).to.equal(11);
done();

@@ -200,3 +200,3 @@ });

expect(contents).to.be.null;
}, function (err, files, count) {
}).then(function (files) {
done();

@@ -229,3 +229,3 @@ });

expect(contents).to.equal(expectFiles[filename]);
}, function (err, files, count) {
}).then(function (files) {
done();

@@ -253,3 +253,3 @@ });

expect(filename).to.equal(expectFiles[count++]);
}, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -287,3 +287,3 @@ done();

expect(filename).to.equal(expectFiles[count++]);
}, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -306,3 +306,3 @@ done();

filter: '*'
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -332,3 +332,3 @@ done();

filter: '**'
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -346,3 +346,3 @@ done();

filter: '*.txt'
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -367,3 +367,3 @@ done();

filter: '**/*.txt'
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -382,3 +382,3 @@ done();

filter: '**/abc123.txt'
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -395,3 +395,3 @@ done();

filter: 'abc123.txt'
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -417,3 +417,3 @@ done();

filter: '*/*'
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -431,3 +431,3 @@ done();

filter: '*.t?t'
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -452,3 +452,3 @@ done();

filter: '**/*.t??'
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -471,3 +471,3 @@ done();

filter: ['**/*123*', '**/abc.*']
}, null, function (err, files, count) {
}).then(function (files) {
expect(files).to.deep.equal(expectFiles);

@@ -474,0 +474,0 @@ done();

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