node-readfiles
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -1,167 +0,801 @@ | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var Promise = require('es6-promise').Promise; | ||
function buildFilter(filters) { | ||
var filters = (filters instanceof Array) ? filters.slice() : [filters]; | ||
var filterArray = []; | ||
if (filters.length === 0) return null; | ||
while(filters.length > 0) { | ||
var filter = filters.shift(); | ||
filterArray.push('\\/?' + filter.replace(/\./g, '\\.') | ||
.replace(/(\*?)(\*)(?!\*)/g, function(match, prefix) { | ||
if(prefix == '*') { | ||
return match; | ||
} | ||
return '[^\\/]*'; | ||
}) | ||
.replace(/\?/g, '[^\\/]?') | ||
.replace(/\*\*/g, '\.*') | ||
.replace(/([\-\+\|])/g, '\\$1') | ||
); | ||
} | ||
return new RegExp('^' + filterArray.join('|') + '$', 'i'); | ||
} | ||
function readfiles(dir, options, callback) { | ||
if (typeof options === 'function' || options === null) { | ||
callback = options; | ||
options = {}; | ||
} | ||
options = options || {}; | ||
callback = typeof callback === 'function' ? callback : function () {}; | ||
return new Promise(function (resolve, reject) { | ||
var files = []; | ||
var subdirs = []; | ||
var filterRegExp = options.filter && buildFilter(options.filter); | ||
(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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
define("src/build-filter", ["require", "exports"], function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.buildFilter = void 0; | ||
const buildFilter = (filtersParam) => { | ||
const filters = filtersParam instanceof Array ? filtersParam.slice() : [filtersParam]; | ||
const filterArray = []; | ||
if (filters.length === 0) | ||
return null; | ||
while (filters.length > 0) { | ||
const filter = filters.shift(); | ||
filterArray.push('\\/?' + | ||
filter | ||
.replace(/\./g, '\\.') | ||
.replace(/(\*?)(\*)(?!\*)/g, function (match, prefix) { | ||
if (prefix == '*') { | ||
return match; | ||
} | ||
return '[^\\/]*'; | ||
}) | ||
.replace(/\?/g, '[^\\/]?') | ||
.replace(/\*\*/g, '.*') | ||
.replace(/([\-\+\|])/g, '\\$1')); | ||
} | ||
// reverse the order of the files if the reverse option is true | ||
if (options.reverse === true) { | ||
fileList = fileList.reverse(); | ||
return new RegExp('^' + filterArray.join('|') + '$', 'i'); | ||
}; | ||
exports.buildFilter = buildFilter; | ||
}); | ||
define("src/build-filters.spec", ["require", "exports", "src/build-filter"], function (require, exports, build_filter_1) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
describe('buildFilter', () => { | ||
it('creates a filter RegExp given a wildcard filter string', () => { | ||
const result = (0, build_filter_1.buildFilter)('*'); | ||
expect(result).toEqual(/^\/?[^\/]*$/i); | ||
}); | ||
it('creates a filter RegExp given a wildcard filter string', () => { | ||
const result = (0, build_filter_1.buildFilter)('**'); | ||
expect(result).toEqual(/^\/?.*$/i); | ||
}); | ||
it('creates a filter RegExp given an array of filters', () => { | ||
const result = (0, build_filter_1.buildFilter)(['**/*123*', '**/abc.*']); | ||
expect(result).toEqual(/^\/?.*\/[^\/]*123[^\/]*|\/?.*\/abc\.[^\/]*$/i); | ||
}); | ||
}); | ||
}); | ||
define("src/consts", ["require", "exports"], function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.FilenameFormat = void 0; | ||
var FilenameFormat; | ||
(function (FilenameFormat) { | ||
FilenameFormat[FilenameFormat["RELATIVE"] = 0] = "RELATIVE"; | ||
FilenameFormat[FilenameFormat["FULL_PATH"] = 1] = "FULL_PATH"; | ||
FilenameFormat[FilenameFormat["FILENAME"] = 2] = "FILENAME"; | ||
})(FilenameFormat = exports.FilenameFormat || (exports.FilenameFormat = {})); | ||
}); | ||
define("src/readfiles", ["require", "exports", "fs", "path", "src/build-filter", "src/consts"], function (require, exports, fs, path, build_filter_2, consts_1) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.readfiles = void 0; | ||
function readfiles(dir, optionsProp, callbackProp) { | ||
let callback = callbackProp; | ||
let options = optionsProp; | ||
if (typeof optionsProp === 'function') { | ||
callback = optionsProp; | ||
options = {}; | ||
} | ||
(function 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(); | ||
} | ||
// stat the full path | ||
fs.stat(fullpath, function (err, stat) { | ||
if (err) { | ||
// call callback with the error | ||
var result = callback(err, relFilename, null, stat); | ||
// if callback result is a function then call the result with next as a parameter | ||
if (typeof result === 'function' && !err) { | ||
return result(next); | ||
} | ||
// if rejectOnError is not false, reject the promise | ||
if (options.rejectOnError !== false) { | ||
return reject(err); | ||
} | ||
return next(); | ||
options = options || {}; | ||
callback = typeof callback === 'function' ? callback : () => { }; | ||
return new Promise((resolve, reject) => { | ||
const files = []; | ||
const subDirs = []; | ||
const filterRegExp = options.filter && (0, build_filter_2.buildFilter)(options.filter); | ||
const traverseDir = (dirPath, done) => { | ||
fs.readdir(dirPath, (err, fileList) => { | ||
if (err) { | ||
if (options.rejectOnError !== false) { | ||
return reject(err); | ||
} | ||
return done(files); | ||
} | ||
if (options.reverse === true) { | ||
fileList = fileList.reverse(); | ||
} | ||
const next = () => { | ||
if (fileList.length === 0) { | ||
done(files); | ||
return; | ||
} | ||
const filename = fileList.shift(); | ||
const relFilename = path.join(subDirs.join('/'), filename); | ||
const fullPath = path.join(dirPath, filename); | ||
if (options.hidden !== true && /^\./.test(filename)) { | ||
return next(); | ||
} | ||
fs.stat(fullPath, (err, stat) => { | ||
if (err) { | ||
const result = callback(err, relFilename, null, stat); | ||
if (typeof result === 'function' && !err) { | ||
return result(next); | ||
} | ||
if (options.rejectOnError !== false) { | ||
return reject(err); | ||
} | ||
return next(); | ||
} | ||
if (stat.isDirectory()) { | ||
if (!isNaN(options.depth) && options.depth >= 0 && subDirs.length + 1 > options.depth) { | ||
return next(); | ||
} | ||
subDirs.push(filename); | ||
traverseDir(fullPath, () => { | ||
subDirs.pop(); | ||
next(); | ||
}); | ||
} | ||
else if (stat.isFile()) { | ||
if (filterRegExp && !filterRegExp.test('/' + relFilename)) { | ||
return next(); | ||
} | ||
let outputName = relFilename; | ||
if (options.filenameFormat === consts_1.FilenameFormat.FULL_PATH) { | ||
outputName = fullPath; | ||
} | ||
else if (options.filenameFormat === consts_1.FilenameFormat.FILENAME) { | ||
outputName = filename; | ||
} | ||
files.push(outputName); | ||
new Promise(resolve => { | ||
var _a; | ||
if (options.readContents === false) { | ||
return resolve(null); | ||
} | ||
fs.readFile(fullPath, (_a = options === null || options === void 0 ? void 0 : options.encoding) !== null && _a !== void 0 ? _a : 'utf8', (err, content) => { | ||
if (err) | ||
throw err; | ||
resolve(content); | ||
}); | ||
}) | ||
.then(content => { | ||
const result = callback(err, outputName, content, stat); | ||
if (typeof result === 'function' && !err) { | ||
return result(next); | ||
} | ||
options.async !== true && next(); | ||
}) | ||
.catch(err => { | ||
if (options.rejectOnError !== false) { | ||
return reject(err); | ||
} | ||
next(); | ||
}); | ||
} | ||
else { | ||
next(); | ||
} | ||
}); | ||
}; | ||
next(); | ||
}); | ||
}; | ||
traverseDir(dir, resolve); | ||
}); | ||
} | ||
exports.readfiles = readfiles; | ||
}); | ||
define("src/index", ["require", "exports", "src/consts", "src/readfiles", "src/readfiles"], function (require, exports, consts_2, readfiles_1, readfiles_2) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = void 0; | ||
__exportStar(consts_2, exports); | ||
__exportStar(readfiles_1, exports); | ||
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return readfiles_2.readfiles; } }); | ||
}); | ||
define("test/fixtures", ["require", "exports"], function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.badDeepPathFixture = exports.deepPathFixture = exports.flatPathFixture = void 0; | ||
exports.flatPathFixture = { | ||
'/path/to/dir': { | ||
'abc.txt': 'ABC', | ||
'def.dat': 'DEF', | ||
'test123.txt': '123', | ||
'test456.dat': '456', | ||
}, | ||
}; | ||
exports.deepPathFixture = { | ||
'/path/to/dir': { | ||
'.system': 'SYSTEM', | ||
'def.dat': 'DEF', | ||
'abc.txt': 'ABC', | ||
'abc123.txt': 'ABC123', | ||
subdir: { | ||
'.dot': 'DOT', | ||
'test456.dat': '456', | ||
'test789.txt': '789', | ||
'test123.txt': '123', | ||
'abc123.txt': 'ABC123', | ||
subsubdir: { | ||
'.hidden': 'HIDDEN', | ||
'abc123.dat': 'ABC123', | ||
'def456.dat': '456', | ||
}, | ||
}, | ||
otherdir: { | ||
'.other': 'DOT', | ||
'test789.txt': '789', | ||
'test123.txt': '123', | ||
subsubdir: { | ||
'.hidden': 'HIDDEN', | ||
'abc123.txt': 'ABC123', | ||
'def456.txt': '456', | ||
}, | ||
}, | ||
}, | ||
}; | ||
exports.badDeepPathFixture = { | ||
'/path/to/dir': { | ||
'.system': 'SYSTEM', | ||
'def.dat': 'DEF', | ||
'abc.txt': 'ABC', | ||
'abc123.txt': 'ABC123', | ||
subdir: { | ||
'.dot': 'DOT', | ||
'error-file.dat': false, | ||
'test456.dat': '456', | ||
'test789.txt': '789', | ||
'test123.txt': '123', | ||
'abc123.txt': 'ABC123', | ||
subsubdir: { | ||
'.hidden': 'HIDDEN', | ||
'abc123.dat': 'ABC123', | ||
'def456.dat': '456', | ||
}, | ||
}, | ||
otherdir: { | ||
'.other': 'DOT', | ||
'error-file.dat': false, | ||
'test789.txt': '789', | ||
'test123.txt': '123', | ||
subsubdir: { | ||
'.hidden': 'HIDDEN', | ||
'abc123.txt': 'ABC123', | ||
'def456.txt': '456', | ||
}, | ||
}, | ||
}, | ||
}; | ||
}); | ||
define("test/fs-helper", ["require", "exports", "fs"], function (require, exports, fs) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.mockFs = void 0; | ||
const fattenFixtures = (fixtureMap, rootPath = '') => { | ||
let flatMap = {}; | ||
if (rootPath) { | ||
flatMap[rootPath] = fixtureMap; | ||
} | ||
for (const path of Object.keys(fixtureMap).sort()) { | ||
if (typeof fixtureMap[path] !== 'object') { | ||
flatMap[`${rootPath}${path}`] = fixtureMap[path]; | ||
} | ||
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(); | ||
} | ||
// traverse the sub-directory | ||
subdirs.push(filename); | ||
traverseDir(fullpath, function () { | ||
subdirs.pop(); | ||
next(); | ||
}); | ||
} else if (stat.isFile()) { | ||
// test filters, if it does not match move to next file | ||
if (filterRegExp && !filterRegExp.test('/' + relFilename)) { | ||
return next(); | ||
} | ||
// 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) { | ||
if (options.readContents === false) { | ||
return resolve(null); | ||
else { | ||
flatMap = Object.assign({}, flatMap, fattenFixtures(fixtureMap[path], `${rootPath}${path}/`)); | ||
} | ||
} | ||
return flatMap; | ||
}; | ||
const mockFs = (fixture) => { | ||
jest.spyOn(fs, 'readdir').mockRestore(); | ||
jest.spyOn(fs, 'stat').mockRestore(); | ||
jest.spyOn(fs, 'readFile').mockRestore(); | ||
const pathsMap = fattenFixtures(fixture); | ||
jest.spyOn(fs, 'readdir').mockImplementation((readdirPath, readdirCb) => { | ||
if (!pathsMap[`${readdirPath}/`]) { | ||
return readdirCb(new Error(`ENOENT, no such file or directory '${readdirPath}'`), null); | ||
} | ||
jest.spyOn(fs, 'stat').mockImplementation((statPath, statCb) => { | ||
if (!pathsMap[statPath] && !pathsMap[`${statPath}/`]) { | ||
return statCb(new Error(`ENOENT, no such file or directory, stat '${statPath}'`), null); | ||
} | ||
// read the file | ||
fs.readFile(fullpath, options.encoding || 'utf8', function (err, content) { | ||
if (err) throw err; | ||
resolve(content); | ||
statCb(null, { | ||
isDirectory: () => typeof pathsMap[`${statPath}/`] === 'object', | ||
isFile: () => typeof pathsMap[statPath] === 'string', | ||
}); | ||
}).then(function (content) { | ||
// call the callback with the content | ||
var result = callback(err, outputName, content, stat); | ||
// if callback result is a function then call the result with next as a parameter | ||
if (typeof result === 'function' && !err) { | ||
return result(next); | ||
}); | ||
jest.spyOn(fs, 'readFile').mockImplementation(((readFilePath, encoding, readFileCb) => { | ||
if (!pathsMap[readFilePath]) { | ||
return readFileCb(new Error(`ENOENT, no such file or directory '${readFilePath}'`), null); | ||
} | ||
// call the next if async is not true | ||
options.async !== true && next(); | ||
}).catch(function (err) { | ||
if (options.rejectOnError !== false) { | ||
return reject(err); | ||
} | ||
next(); | ||
}); | ||
} else { | ||
next(); | ||
} | ||
}); | ||
})(); | ||
}); | ||
})(dir, resolve); | ||
}); | ||
} | ||
readfiles.RELATIVE = 0; | ||
readfiles.FULL_PATH = 1; | ||
readfiles.FILENAME = 2; | ||
module.exports = readfiles; | ||
readFileCb(null, pathsMap[readFilePath]); | ||
})); | ||
readdirCb(null, Object.keys(pathsMap[`${readdirPath}/`]).sort()); | ||
}); | ||
}; | ||
exports.mockFs = mockFs; | ||
}); | ||
define("src/readfiles.spec", ["require", "exports", "src/index", "test/fixtures", "test/fs-helper", "src/consts"], function (require, exports, index_1, fixtures_1, fs_helper_1, consts_3) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
describe('readfiles', () => { | ||
describe('defaults', () => { | ||
let clock; | ||
beforeEach(() => { | ||
jest.useFakeTimers(); | ||
(0, fs_helper_1.mockFs)(fixtures_1.flatPathFixture); | ||
}); | ||
it('should return the list of files and their contents', done => { | ||
const files = ['abc.txt', 'def.dat', 'test123.txt', 'test456.dat']; | ||
const contents = ['ABC', 'DEF', '123', '456']; | ||
(0, index_1.default)('/path/to/dir', (err, filename, content) => { | ||
expect(filename).toEqual(files.shift()); | ||
expect(content).toEqual(contents.shift()); | ||
if (files.length === 0) | ||
done(); | ||
}).catch(err => { | ||
done(err); | ||
}); | ||
}); | ||
it('should throw an error on a file', done => { | ||
(0, fs_helper_1.mockFs)({ | ||
'/path/to/dir': { | ||
'badfile.txt': false, | ||
}, | ||
}); | ||
(0, index_1.default)('/path/to/dir', (err, filename, content) => { | ||
expect(content).toBeNull(); | ||
expect(err.message).toEqual("ENOENT, no such file or directory, stat '/path/to/dir/badfile.txt'"); | ||
}).catch(err => { | ||
expect(err.message).toEqual("ENOENT, no such file or directory, stat '/path/to/dir/badfile.txt'"); | ||
done(); | ||
}); | ||
}); | ||
it('should resolve the promise when finished traversing all files', done => { | ||
(0, index_1.default)('/path/to/dir') | ||
.then(files => { | ||
expect(files).toHaveLength(4); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it('should call the done callback with an error on a path', function (done) { | ||
(0, fs_helper_1.mockFs)({}); | ||
(0, index_1.default)('/fake/invalid/dir').catch(function (err) { | ||
expect(err.message).toEqual("ENOENT, no such file or directory '/fake/invalid/dir'"); | ||
done(); | ||
}); | ||
}); | ||
it('should wait for an asynchronous callback when returning a function', function (done) { | ||
let count = 0; | ||
const expectFiles = ['abc.txt', 'def.dat', 'test123.txt', 'test456.dat']; | ||
(0, index_1.default)('/path/to/dir', function (err, filename) { | ||
return function (next) { | ||
expect(filename).toEqual(expectFiles[count++]); | ||
setTimeout(function () { | ||
next(); | ||
}, 1000); | ||
jest.advanceTimersToNextTimer(); | ||
}; | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
}); | ||
describe('options', () => { | ||
beforeEach(() => { | ||
(0, fs_helper_1.mockFs)(fixtures_1.deepPathFixture); | ||
}); | ||
it("callback returns the list of files in reverse order when 'reverse' is true", done => { | ||
(0, index_1.default)('/path/to/dir', { reverse: true }) | ||
.then(files => { | ||
expect(files).toEqual([ | ||
'subdir/test789.txt', | ||
'subdir/test456.dat', | ||
'subdir/test123.txt', | ||
'subdir/subsubdir/def456.dat', | ||
'subdir/subsubdir/abc123.dat', | ||
'subdir/abc123.txt', | ||
'otherdir/test789.txt', | ||
'otherdir/test123.txt', | ||
'otherdir/subsubdir/def456.txt', | ||
'otherdir/subsubdir/abc123.txt', | ||
'def.dat', | ||
'abc123.txt', | ||
'abc.txt', | ||
]); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns the full path of the files when 'filenameFormat' is 'readfiles.FULL_PATH'", done => { | ||
let count = 0; | ||
const expectFiles = [ | ||
'/path/to/dir/abc.txt', | ||
'/path/to/dir/abc123.txt', | ||
'/path/to/dir/def.dat', | ||
'/path/to/dir/otherdir/subsubdir/abc123.txt', | ||
'/path/to/dir/otherdir/subsubdir/def456.txt', | ||
'/path/to/dir/otherdir/test123.txt', | ||
'/path/to/dir/otherdir/test789.txt', | ||
'/path/to/dir/subdir/abc123.txt', | ||
'/path/to/dir/subdir/subsubdir/abc123.dat', | ||
'/path/to/dir/subdir/subsubdir/def456.dat', | ||
'/path/to/dir/subdir/test123.txt', | ||
'/path/to/dir/subdir/test456.dat', | ||
'/path/to/dir/subdir/test789.txt', | ||
]; | ||
(0, index_1.default)('/path/to/dir', { filenameFormat: consts_3.FilenameFormat.FULL_PATH }, (err, filename) => { | ||
expect(filename).toEqual(expectFiles[count++]); | ||
}) | ||
.then(files => { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(err => { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns the relative path of the files when 'filenameFormat' is 'readfiles.RELATIVE'", done => { | ||
let count = 0; | ||
const expectFiles = [ | ||
'abc.txt', | ||
'abc123.txt', | ||
'def.dat', | ||
'otherdir/subsubdir/abc123.txt', | ||
'otherdir/subsubdir/def456.txt', | ||
'otherdir/test123.txt', | ||
'otherdir/test789.txt', | ||
'subdir/abc123.txt', | ||
'subdir/subsubdir/abc123.dat', | ||
'subdir/subsubdir/def456.dat', | ||
'subdir/test123.txt', | ||
'subdir/test456.dat', | ||
'subdir/test789.txt', | ||
]; | ||
(0, index_1.default)('/path/to/dir', { filenameFormat: consts_3.FilenameFormat.RELATIVE }, (err, filename) => { | ||
expect(expectFiles).toContain(filename); | ||
}) | ||
.then(files => { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(err => { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns only the filename of the file when 'filenameFormat' is 'readfiles.FILENAME'", done => { | ||
let count = 0; | ||
const expectFiles = [ | ||
'abc.txt', | ||
'abc123.txt', | ||
'def.dat', | ||
'abc123.txt', | ||
'def456.txt', | ||
'test123.txt', | ||
'test789.txt', | ||
'abc123.txt', | ||
'abc123.dat', | ||
'def456.dat', | ||
'test123.txt', | ||
'test456.dat', | ||
'test789.txt', | ||
]; | ||
(0, index_1.default)('/path/to/dir', { filenameFormat: consts_3.FilenameFormat.FILENAME }, (err, filename) => { | ||
expect(expectFiles).toContain(filename); | ||
}) | ||
.then(files => { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(err => { | ||
done(err); | ||
}); | ||
}); | ||
it("does not stop reading files when one file throws an error and 'rejectOnError' is false", done => { | ||
let fileCount = 0; | ||
(0, fs_helper_1.mockFs)(fixtures_1.badDeepPathFixture); | ||
(0, index_1.default)('/path/to/dir', { rejectOnError: false }, err => { | ||
fileCount++; | ||
}) | ||
.then(files => { | ||
expect(fileCount).toEqual(15); | ||
expect(files.length).toEqual(13); | ||
done(); | ||
}) | ||
.catch(err => { | ||
done(err); | ||
}); | ||
}); | ||
it("callback does not return the file contents when 'readContents' is false", done => { | ||
let fileCount = 0; | ||
(0, index_1.default)('/path/to/dir', { readContents: false }, (err, filename, contents) => { | ||
expect(contents).toBeNull(); | ||
fileCount++; | ||
}) | ||
.then(files => { | ||
expect(fileCount).toEqual(13); | ||
expect(files.length).toEqual(13); | ||
done(); | ||
}) | ||
.catch(err => { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns file contents encoded in the specified 'encoding' type", done => { | ||
const expectFiles = { | ||
'abc.txt': 'ABC', | ||
'abc123.txt': 'ABC123', | ||
'def.dat': 'DEF', | ||
'otherdir/subsubdir/abc123.txt': 'ABC123', | ||
'otherdir/subsubdir/def456.txt': '456', | ||
'otherdir/symlink.dat': '123', | ||
'otherdir/test123.txt': '123', | ||
'otherdir/test789.txt': '789', | ||
'subdir/abc123.txt': 'ABC123', | ||
'subdir/subsubdir/abc123.dat': 'ABC123', | ||
'subdir/subsubdir/def456.dat': '456', | ||
'subdir/test123.txt': '123', | ||
'subdir/test456.dat': '456', | ||
'subdir/test789.txt': '789', | ||
}; | ||
(0, index_1.default)('/path/to/dir', { encoding: null }, (err, filename, contents) => { | ||
expect(contents).toEqual(expectFiles[filename]); | ||
}) | ||
.then(files => { | ||
expect(files.length).toEqual(13); | ||
done(); | ||
}) | ||
.catch(err => { | ||
done(err); | ||
}); | ||
}); | ||
it("traverses the directory tree limiting to specified 'depth'", done => { | ||
let count = 0; | ||
const expectFiles = [ | ||
'abc.txt', | ||
'abc123.txt', | ||
'def.dat', | ||
'otherdir/test123.txt', | ||
'otherdir/test789.txt', | ||
'subdir/abc123.txt', | ||
'subdir/test123.txt', | ||
'subdir/test456.dat', | ||
'subdir/test789.txt', | ||
]; | ||
(0, index_1.default)('/path/to/dir', { depth: 1 }, (err, filename) => { | ||
expect(filename).toEqual(expectFiles[count++]); | ||
}) | ||
.then(files => { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(err => { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns all files including hidden files when 'hidden' is true", done => { | ||
let count = 0; | ||
const expectFiles = [ | ||
'.system', | ||
'abc.txt', | ||
'abc123.txt', | ||
'def.dat', | ||
'otherdir/.other', | ||
'otherdir/subsubdir/.hidden', | ||
'otherdir/subsubdir/abc123.txt', | ||
'otherdir/subsubdir/def456.txt', | ||
'otherdir/test123.txt', | ||
'otherdir/test789.txt', | ||
'subdir/.dot', | ||
'subdir/abc123.txt', | ||
'subdir/subsubdir/.hidden', | ||
'subdir/subsubdir/abc123.dat', | ||
'subdir/subsubdir/def456.dat', | ||
'subdir/test123.txt', | ||
'subdir/test456.dat', | ||
'subdir/test789.txt', | ||
]; | ||
(0, index_1.default)('/path/to/dir', { hidden: true }, (err, filename) => { | ||
expect(filename).toEqual(expectFiles[count++]); | ||
}) | ||
.then(files => { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(err => { | ||
done(err); | ||
}); | ||
}); | ||
}); | ||
describe('filters', function () { | ||
it("callback returns all files in the given directory when the 'filter' option is equal '*'", function (done) { | ||
const expectFiles = ['abc.txt', 'abc123.txt', 'def.dat']; | ||
(0, index_1.default)('/path/to/dir', { | ||
filter: '*', | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns all files in the given directory recursively when the 'filter' option is equal '**'", function (done) { | ||
const expectFiles = [ | ||
'abc.txt', | ||
'abc123.txt', | ||
'def.dat', | ||
'otherdir/subsubdir/abc123.txt', | ||
'otherdir/subsubdir/def456.txt', | ||
'otherdir/test123.txt', | ||
'otherdir/test789.txt', | ||
'subdir/abc123.txt', | ||
'subdir/subsubdir/abc123.dat', | ||
'subdir/subsubdir/def456.dat', | ||
'subdir/test123.txt', | ||
'subdir/test456.dat', | ||
'subdir/test789.txt', | ||
]; | ||
(0, index_1.default)('/path/to/dir', { | ||
filter: '**', | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns all \"txt\" files in the given directory when the 'filter' option is equal '*.txt'", function (done) { | ||
const expectFiles = ['abc.txt', 'abc123.txt']; | ||
(0, index_1.default)('/path/to/dir', { | ||
filter: '*.txt', | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns all \"txt\" files in the given directory recursively when the 'filter' option is equal '**/*.txt'", function (done) { | ||
const expectFiles = [ | ||
'abc.txt', | ||
'abc123.txt', | ||
'otherdir/subsubdir/abc123.txt', | ||
'otherdir/subsubdir/def456.txt', | ||
'otherdir/test123.txt', | ||
'otherdir/test789.txt', | ||
'subdir/abc123.txt', | ||
'subdir/test123.txt', | ||
'subdir/test789.txt', | ||
]; | ||
(0, index_1.default)('/path/to/dir', { | ||
filter: '**/*.txt', | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns all files that match \"abc.txt\" in the given directory recursively when the 'filter' option is equal '**/abc123.txt'", function (done) { | ||
const expectFiles = ['abc123.txt', 'otherdir/subsubdir/abc123.txt', 'subdir/abc123.txt']; | ||
(0, index_1.default)('/path/to/dir', { | ||
filter: '**/abc123.txt', | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns all files that match \"abc123.txt\" in the given directory when the 'filter' option is equal 'abc123.txt'", function (done) { | ||
const expectFiles = ['abc123.txt']; | ||
(0, index_1.default)('/path/to/dir', { | ||
filter: 'abc123.txt', | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns all files in all sub-directory of the given directory when the 'filter' option is equal '*/*'", function (done) { | ||
const expectFiles = [ | ||
'abc.txt', | ||
'abc123.txt', | ||
'def.dat', | ||
'otherdir/test123.txt', | ||
'otherdir/test789.txt', | ||
'subdir/abc123.txt', | ||
'subdir/test123.txt', | ||
'subdir/test456.dat', | ||
'subdir/test789.txt', | ||
]; | ||
(0, index_1.default)('/path/to/dir', { | ||
filter: '*/*', | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns all files where the extension matches \"t?t\" in the given directory when the 'filter' option is equal '*.??t'", function (done) { | ||
const expectFiles = ['abc.txt', 'abc123.txt']; | ||
(0, index_1.default)('/path/to/dir', { | ||
filter: '*.t?t', | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns all files where the extension matches \"t?t\" in the given directory recursively when the 'filter' option is equal '**/*.??t'", function (done) { | ||
const expectFiles = [ | ||
'abc.txt', | ||
'abc123.txt', | ||
'otherdir/subsubdir/abc123.txt', | ||
'otherdir/subsubdir/def456.txt', | ||
'otherdir/test123.txt', | ||
'otherdir/test789.txt', | ||
'subdir/abc123.txt', | ||
'subdir/test123.txt', | ||
'subdir/test789.txt', | ||
]; | ||
(0, index_1.default)('/path/to/dir', { | ||
filter: '**/*.t??', | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it("callback returns all files that match the array of filters in the given directory when the 'filter' option is equal ['*123*', 'abc.*'] ", function (done) { | ||
const expectFiles = [ | ||
'abc.txt', | ||
'abc123.txt', | ||
'otherdir/subsubdir/abc123.txt', | ||
'otherdir/test123.txt', | ||
'subdir/abc123.txt', | ||
'subdir/subsubdir/abc123.dat', | ||
'subdir/test123.txt', | ||
]; | ||
(0, index_1.default)('/path/to/dir', { | ||
filter: ['**/*123*', '**/abc.*'], | ||
}) | ||
.then(function (files) { | ||
expect(files).toEqual(expectFiles); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
//# sourceMappingURL=readfiles.js.map |
{ | ||
"name": "node-readfiles", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "A lightweight Node.js module to recursively read files in a directory using ES6 Promises", | ||
"main": "index.js", | ||
"main": "lib/readfiles.js", | ||
"scripts": { | ||
"start": "echo 'Not a runnable module' && exit 1", | ||
"test": "mocha", | ||
"lint": "eslint lib test", | ||
"test": "jest", | ||
"build": "tsc", | ||
"lint": "eslint src test", | ||
"preversion": "npm run lint && npm test" | ||
@@ -29,11 +30,15 @@ }, | ||
"devDependencies": { | ||
"chai": "^3.5.0", | ||
"eslint": "^2.10.2", | ||
"mocha": "^2.4.5", | ||
"mock-fs": "^3.9.0", | ||
"sinon": "^1.17.4" | ||
"@types/jest": "^27.5.1", | ||
"@typescript-eslint/eslint-plugin": "^5.27.0", | ||
"@typescript-eslint/parser": "^5.27.0", | ||
"eslint": "^8.16.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint-plugin-prettier": "^4.0.0", | ||
"jest": "^28.1.0", | ||
"prettier": "^2.6.2", | ||
"ts-jest": "^28.0.3", | ||
"ts-node": "^10.8.0", | ||
"typescript": "^4.7.2" | ||
}, | ||
"dependencies": { | ||
"es6-promise": "^3.2.1" | ||
} | ||
"dependencies": {} | ||
} |
@@ -26,5 +26,5 @@ # node-readfiles | ||
* **reverse**: a bollean value that reverses the order of the list of files before traversing them (defaults to false) | ||
* **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`) | ||
* **rejectOnError**: a bollean value wether to stop and trigger the "doneCallback" when an error occurs (defaults to true) | ||
* **reverse**: a boolean value that reverses the order of the list of files before traversing them (defaults to false) | ||
* **filenameFormat**: one of `readfiles.FULL_PATH`, `readfiles.RELATIVE`, or `readfiles.FILENAME`, whether the callback's returns the full-path, relative-path or only the filenames of the traversed files. (default is `readfiles.RELATIVE`) | ||
* **rejectOnError**: a boolean value whether 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 '**') | ||
@@ -34,6 +34,6 @@ * `?` matches one character | ||
* `**` matches zero or more 'directories' in a path | ||
* **readContents**: a boolean value wether to read the file contents when traversing the files <sup>[\[1\]](#read-files)</sup> (defaults to true) | ||
* **readContents**: a boolean value whether to read the file contents when traversing the files <sup>[\[1\]](#read-files)</sup> (defaults to true) | ||
* **encoding**: a string with the encoding used when reading a file (defaults to 'utf8') | ||
* **depth**: an integer value which limits the number sub-directories levels to traverse for the given path where `-1` is infinte, and `0` is none (defaults to -1) | ||
* **hidden**: a boolean value wether to exclude hidden files prefixed with a `.` (defaults to true) | ||
* **hidden**: a boolean value whether to include hidden files prefixed with a `.` (defaults to false) | ||
@@ -52,3 +52,3 @@ | ||
```javascript | ||
readfiles('/path/to/dir/', function (err, content, filename, stat) { | ||
readfiles('/path/to/dir/', function (err, filename, content, stat) { | ||
if (err) throw err; | ||
@@ -72,3 +72,3 @@ return function (next) { | ||
readfiles('/path/to/dir/', function (err, filename, contents) { | ||
readfiles('/path/to/dir/', function (err, filename, content) { | ||
if (err) throw err; | ||
@@ -89,3 +89,3 @@ console.log('File ' + filename + ':'); | ||
```javascript | ||
readfiles('/path/to/dir/', function (err, filename, contents) { | ||
readfiles('/path/to/dir/', function (err, filename, content) { | ||
if (err) throw err; | ||
@@ -105,3 +105,3 @@ console.log('File ' + filename + ':'); | ||
depth: 0 | ||
}, function (err, content, filename) { | ||
}, function (err, filename, content) { | ||
if (err) throw err; | ||
@@ -121,3 +121,3 @@ console.log('File ' + filename + ':'); | ||
filter: '*' // instead of the default '**' | ||
}, function (err, content, filename) { | ||
}, function (err, filename, content) { | ||
if (err) throw err; | ||
@@ -137,3 +137,3 @@ console.log('File ' + filename + ':'); | ||
filter: '*.txt' | ||
}, function (err, content, filename) { | ||
}, function (err, filename, content) { | ||
if (err) throw err; | ||
@@ -153,3 +153,3 @@ console.log('File ' + filename + ':'); | ||
filter: '*.t?t' | ||
}, function (err, content, filename) { | ||
}, function (err, filename, content) { | ||
if (err) throw err; | ||
@@ -170,3 +170,3 @@ console.log('File ' + filename + ':'); | ||
readContents: false | ||
}, function (err, content, filename) { | ||
}, function (err, filename, content) { | ||
if (err) throw err; | ||
@@ -173,0 +173,0 @@ console.log('File ' + filename); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
73047
0
16
1703
0
11
1
- Removedes6-promise@^3.2.1
- Removedes6-promise@3.3.1(transitive)