Comparing version 5.1.0 to 5.2.0
@@ -6,11 +6,11 @@ declare module "fdir" { | ||
type FilterFn = (path: string, isDirectory: boolean) => boolean; | ||
type ExcludeFn = (dirName: string, dirPath: string) => boolean; | ||
type Callback = (error: Error, output: Output) => void; | ||
export type FilterFn = (path: string, isDirectory: boolean) => boolean; | ||
export type ExcludeFn = (dirName: string, dirPath: string) => boolean; | ||
export type Callback = (error: Error, output: Output) => void; | ||
type Group = { dir: string; files: string[] }; | ||
export type Group = { dir: string; files: string[] }; | ||
type Output = GroupOutput | OnlyCountsOutput | PathsOutput; | ||
export type Output = GroupOutput | OnlyCountsOutput | PathsOutput; | ||
type Options = { | ||
export type Options = { | ||
includeBasePath?: boolean; | ||
@@ -28,2 +28,3 @@ includeDirs?: boolean; | ||
exclude?: ExcludeFn; | ||
relativePaths?: boolean; | ||
}; | ||
@@ -63,5 +64,10 @@ | ||
*/ | ||
withSymlinks(): Builder; | ||
withSymlinks(): Builder; | ||
/** | ||
* Return paths relative to the root directory | ||
*/ | ||
withRelativePaths(): Builder; | ||
/** | ||
* The depth to crawl to before stopping | ||
@@ -68,0 +74,0 @@ * @param depth The depth |
{ | ||
"name": "fdir", | ||
"version": "5.1.0", | ||
"version": "5.2.0", | ||
"description": "The fastest directory crawler & globbing alternative to glob, fast-glob, & tiny-glob. Crawls 1m files in < 1s", | ||
@@ -55,3 +55,3 @@ "main": "index.js", | ||
"klaw-sync": "^6.0.0", | ||
"mock-fs": "^4.11.0", | ||
"mock-fs": "^5.0.0", | ||
"picomatch": "^2.2.2", | ||
@@ -58,0 +58,0 @@ "recur-readdir": "0.0.1", |
@@ -28,8 +28,7 @@ const { readdir } = require("../compat/fs"); | ||
function callback(directoryPath, options, callback) { | ||
let walker = new Walker(options, callback); | ||
walker.registerWalker(walkDirectory); | ||
let walker = new Walker(options, walkDirectory, callback); | ||
walker.state.queue = new Queue(walker.callbackInvoker); | ||
const root = walker.normalizePath(directoryPath); | ||
walker.walk(walker, root, options.maxDepth); | ||
walker.walkDir(walker, root, options.maxDepth); | ||
} | ||
@@ -58,14 +57,12 @@ | ||
state.counts.dirs++; | ||
// Perf: Node >= 10 introduced withFileTypes that helps us | ||
// skip an extra fs.stat call. | ||
// Howver, since this API is not availble in Node < 10, I had to create | ||
// However, since this API is not availble in Node < 10, I had to create | ||
// a compatibility layer to support both variants. | ||
readdir(directoryPath, readdirOpts, function(error, dirents) { | ||
if (error) { | ||
state.queue.dequeue(error, state); | ||
return; | ||
} | ||
readdir(directoryPath, readdirOpts, function process(error, dirents = []) { | ||
walker.processDirents(dirents, directoryPath, currentDepth); | ||
walker.processDirents(dirents, directoryPath, currentDepth); | ||
state.queue.dequeue(null, state); | ||
state.queue.dequeue(walker.options.suppressErrors ? null : error, state); | ||
}); | ||
@@ -72,0 +69,0 @@ } |
@@ -1,6 +0,6 @@ | ||
const { sep } = require("path"); | ||
const { sep } = require("../compat/fs"); | ||
const fs = require("fs"); | ||
module.exports.getArray = function(state) { | ||
return state.paths; | ||
module.exports.getArray = function(paths) { | ||
return paths; | ||
}; | ||
@@ -12,25 +12,29 @@ | ||
module.exports.pushFileFilterAndCount = function(walker, filename) { | ||
if (walker.options.filters.every((filter) => filter(filename, false))) | ||
module.exports.pushFileCount(walker); | ||
module.exports.pushFileFilterAndCount = function( | ||
filename, | ||
_paths, | ||
filters, | ||
counts | ||
) { | ||
if (filters.every((filter) => filter(filename, false))) counts.files++; | ||
}; | ||
module.exports.pushFileFilter = function(walker, filename, files) { | ||
if (walker.options.filters.every((filter) => filter(filename, false))) | ||
files.push(filename); | ||
module.exports.pushFileFilter = function(filename, paths, filters) { | ||
if (filters.every((filter) => filter(filename, false))) paths.push(filename); | ||
}; | ||
module.exports.pushFileCount = function(walker) { | ||
walker.state.counts.files++; | ||
module.exports.pushFileCount = function(_filename, _paths, _filters, counts) { | ||
counts.files++; | ||
}; | ||
module.exports.pushFile = function(_walker, filename, files) { | ||
files.push(filename); | ||
module.exports.pushFile = function(filename, paths) { | ||
paths.push(filename); | ||
}; | ||
module.exports.pushDir = function(_walker, dirPath, paths) { | ||
module.exports.pushDir = function(dirPath, paths) { | ||
paths.push(dirPath); | ||
}; | ||
module.exports.pushDirFilter = function(walker, dirPath, paths) { | ||
if (walker.options.filters.every((filter) => filter(dirPath, true))) { | ||
module.exports.pushDirFilter = function(dirPath, paths, filters) { | ||
if (filters.every((filter) => filter(dirPath, true))) { | ||
paths.push(dirPath); | ||
@@ -41,4 +45,12 @@ } | ||
module.exports.joinPathWithBasePath = function(filename, dir) { | ||
return `${dir}${dir.endsWith(sep) ? "" : sep}${filename}`; | ||
return dir + filename; | ||
}; | ||
module.exports.joinPathWithRelativePath = function(relativePath) { | ||
relativePath += relativePath[relativePath.length - 1] === sep ? "" : sep; | ||
return function(filename, dir) { | ||
return dir.substring(relativePath.length) + filename; | ||
}; | ||
}; | ||
module.exports.joinPath = function(filename) { | ||
@@ -48,22 +60,9 @@ return filename; | ||
module.exports.walkDirExclude = function( | ||
walker, | ||
path, | ||
directoryName, | ||
currentDepth | ||
) { | ||
if (!walker.options.excludeFn(directoryName, path)) { | ||
module.exports.walkDir(walker, path, directoryName, currentDepth); | ||
} | ||
module.exports.joinDirPath = function(filename, dir) { | ||
return dir + filename + sep; | ||
}; | ||
module.exports.walkDir = function(walker, path, _directoryName, currentDepth) { | ||
walker.state.counts.dirs++; | ||
walker.walk(walker, path, currentDepth); | ||
module.exports.groupFiles = function(state, dir, files) { | ||
state.paths[dir] = files; | ||
}; | ||
module.exports.groupFiles = function(dir, files, state) { | ||
state.counts.files += files.length; | ||
state.paths.push({ dir, files }); | ||
}; | ||
module.exports.empty = function() {}; | ||
@@ -99,3 +98,3 @@ | ||
if (error) { | ||
state.queue.dequeue(error, state); | ||
state.queue.dequeue(state.options.suppressErrors ? null : error, state); | ||
return; | ||
@@ -106,3 +105,3 @@ } | ||
if (error) { | ||
state.queue.dequeue(error, state); | ||
state.queue.dequeue(state.options.suppressErrors ? null : error, state); | ||
return; | ||
@@ -109,0 +108,0 @@ } |
@@ -14,7 +14,6 @@ const { readdirSync } = require("../compat/fs"); | ||
let walker = new Walker(options); | ||
walker.registerWalker(walkDirectory); | ||
let walker = new Walker(options, walkDirectory); | ||
const root = walker.normalizePath(directoryPath); | ||
walker.walk(walker, root, options.maxDepth); | ||
walker.walkDir(walker, root, options.maxDepth); | ||
@@ -37,10 +36,13 @@ return walker.callbackInvoker(walker.state); | ||
const { state } = walker; | ||
state.counts.dirs++; | ||
let dirents = []; | ||
try { | ||
const dirents = readdirSync(directoryPath, readdirOpts); | ||
walker.processDirents(dirents, directoryPath, currentDepth); | ||
dirents = readdirSync(directoryPath, readdirOpts); | ||
} catch (e) { | ||
if (!state.options.suppressErrors) throw e; | ||
} | ||
walker.processDirents(dirents, directoryPath, currentDepth); | ||
} | ||
module.exports = sync; |
const { Dirent } = require("fs"); | ||
const { sep, resolve: pathResolve } = require("path"); | ||
const { sep } = require("../compat/fs"); | ||
const { resolve: pathResolve } = require("path"); | ||
const { cleanPath } = require("../utils"); | ||
@@ -7,7 +8,7 @@ const fns = require("./fns"); | ||
function Walker(options, callback) { | ||
function Walker(options, walkerFunction, callback) { | ||
/* Dummy functions that will be filled later conditionally based on options */ | ||
this.pushFile = fns.empty; | ||
this.pushDir = fns.empty; | ||
this.walkDir = fns.empty; | ||
this.walkDir = walkerFunction; | ||
this.joinPath = fns.empty; | ||
@@ -48,15 +49,7 @@ this.groupFiles = fns.empty; | ||
if (this.options.normalizePath) path = cleanPath(path); | ||
return path; | ||
const needsSeperator = path[path.length - 1] !== sep; | ||
return needsSeperator ? path + sep : path; | ||
}; | ||
/** | ||
* Register the core directory walker function. | ||
* This is used to by the sync/async walkers depending on usage. | ||
* @param {(walker: Walker, directoryPath: string, currentDepth: number) => {}} walkerFunction | ||
*/ | ||
Walker.prototype.registerWalker = function registerWalker(walkerFunction) { | ||
this.walk = walkerFunction; | ||
}; | ||
/** | ||
* Process dirents recursively (and also resolve symlinks if needed) | ||
@@ -72,6 +65,5 @@ * @param {Dirent[]} dirents | ||
) { | ||
this.pushDir(this, directoryPath, this.state.paths); | ||
this.pushDir(directoryPath, this.state.paths, this.options.filters); | ||
const files = this.getArray(this.state); | ||
const files = this.getArray(this.state.paths); | ||
for (var i = 0; i < dirents.length; ++i) { | ||
@@ -82,6 +74,10 @@ const dirent = dirents[i]; | ||
const filename = this.joinPath(dirent.name, directoryPath); | ||
this.pushFile(this, filename, files); | ||
this.pushFile(filename, files, this.options.filters, this.state.counts); | ||
} else if (dirent.isDirectory()) { | ||
let path = fns.joinPathWithBasePath(dirent.name, directoryPath); | ||
this.walkDir(this, path, dirent.name, currentDepth - 1); | ||
let path = fns.joinDirPath(dirent.name, directoryPath); | ||
if (this.options.excludeFn && this.options.excludeFn(dirent.name, path)) | ||
continue; | ||
this.walkDir(this, path, currentDepth - 1, dirent.name); | ||
} | ||
@@ -92,8 +88,20 @@ // perf: we can avoid entering the condition block if .withSymlinks is not set | ||
else if (dirent.isSymbolicLink() && this.symlinkResolver !== fns.empty) { | ||
let path = fns.joinPathWithBasePath(dirent.name, directoryPath); | ||
let path = fns.joinDirPath(dirent.name, directoryPath); | ||
this.symlinkResolver(path, this.state, (stat, resolvedPath) => { | ||
if (stat.isFile()) { | ||
this.pushFile(this, resolvedPath, files); | ||
this.pushFile( | ||
resolvedPath, | ||
files, | ||
this.options.filters, | ||
this.state.counts | ||
); | ||
} else if (stat.isDirectory()) { | ||
this.walkDir(this, resolvedPath, dirent.name, currentDepth - 1); | ||
resolvedPath = this.normalizePath(resolvedPath); | ||
if ( | ||
this.options.excludeFn && | ||
this.options.excludeFn(dirent.name, resolvedPath) | ||
) | ||
return; | ||
this.walkDir(this, resolvedPath, currentDepth - 1, dirent.name); | ||
} | ||
@@ -104,3 +112,3 @@ }); | ||
this.groupFiles(directoryPath, files, this.state); | ||
this.groupFiles(this.state, directoryPath, files); | ||
}; | ||
@@ -116,5 +124,5 @@ | ||
includeBasePath, | ||
relativePath, | ||
includeDirs, | ||
groupVar, | ||
excludeFn, | ||
excludeFiles, | ||
@@ -126,7 +134,8 @@ resolveSymlinks, | ||
// build function for joining paths | ||
this.joinPath = includeBasePath ? fns.joinPathWithBasePath : fns.joinPath; | ||
this.joinPath = relativePath | ||
? fns.joinPathWithRelativePath(relativePath) | ||
: includeBasePath | ||
? fns.joinPathWithBasePath | ||
: fns.joinPath; | ||
// build recursive walk directory function | ||
this.walkDir = excludeFn ? fns.walkDirExclude : fns.walkDir; | ||
// build groupFiles function for grouping files | ||
@@ -133,0 +142,0 @@ this.groupFiles = groupVar ? fns.groupFiles : fns.empty; |
@@ -9,11 +9,11 @@ const { promise, callback } = require("../api/async.js"); | ||
APIBuilder.prototype.withPromise = function() { | ||
APIBuilder.prototype.withPromise = function () { | ||
return promise(this.dir, this.options); | ||
}; | ||
APIBuilder.prototype.withCallback = function(cb) { | ||
APIBuilder.prototype.withCallback = function (cb) { | ||
callback(this.dir, this.options, cb); | ||
}; | ||
APIBuilder.prototype.sync = function() { | ||
APIBuilder.prototype.sync = function () { | ||
return sync(this.dir, this.options); | ||
@@ -20,0 +20,0 @@ }; |
@@ -20,2 +20,3 @@ const APIBuilder = require("./apiBuilder"); | ||
Builder.prototype.crawl = function(path) { | ||
this.relativePath = this.relativePath === true ? path : undefined; | ||
return new APIBuilder(path, this); | ||
@@ -30,2 +31,3 @@ }; | ||
options.filters = options.filters || []; | ||
options.relativePath = options.relativePaths ? path : undefined; | ||
@@ -44,2 +46,7 @@ if (options.excludeFiles) { | ||
Builder.prototype.withRelativePaths = function() { | ||
this.relativePath = true; | ||
return this; | ||
}; | ||
Builder.prototype.withDirs = function() { | ||
@@ -46,0 +53,0 @@ this.includeDirs = true; |
@@ -6,5 +6,5 @@ const { lstat, lstatSync, readdir, readdirSync, Dirent } = require("fs"); | ||
if (!Dirent) { | ||
module.exports.readdir = function(dir, _, callback) { | ||
module.exports.readdir = function (dir, _, callback) { | ||
readdir(dir, (err, files) => { | ||
if (err) return process.nextTick(callback, err, null); | ||
if (err) return process.nextTick(callback, err, []); | ||
if (!files.length) return process.nextTick(callback, null, []); | ||
@@ -19,3 +19,3 @@ | ||
if (err) return process.nextTick(callback, err, null); | ||
dirents[dirents.length] = getDirent(name, stat); | ||
dirents.push(getDirent(name, stat)); | ||
if (dirents.length === files.length) { | ||
@@ -29,3 +29,3 @@ process.nextTick(callback, null, dirents); | ||
module.exports.readdirSync = function(dir) { | ||
module.exports.readdirSync = function (dir) { | ||
const files = readdirSync(dir); | ||
@@ -50,4 +50,5 @@ let dirents = []; | ||
} | ||
module.exports.sep = sep; | ||
} else { | ||
module.exports = { readdirSync, readdir }; | ||
module.exports = { sep, readdirSync, readdir }; | ||
} |
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
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
30677
670