walk-asyncgen
Version:
Recursively walk a directory using an async generator.
67 lines (60 loc) • 2.03 kB
JavaScript
import path from 'path';
import fs from 'fs-extra';
const defaultOpts = {
excludeDirs: false,
excludeFiles: false,
excludeExt: false,
includeDirs: false,
includeFiles: false,
includeExt: false,
printDirs: true,
};
// option types : excludeDirs: RegExp, excludeFiles: RegExp, excludeExt: string (including leading period, ex: '.html')
export default async function* pathsGenerator(dir = process.cwd(), options = defaultOpts) {
const {
excludeDirs,
excludeFiles,
excludeExt,
includeDirs,
includeFiles,
includeExt,
printDirs,
} = options;
if (printDirs) console.log('dir: ' + dir);
if (!(await fs.pathExists(dir))) throw new Error('Path does not exist');
let currentDir = await fs.readdir(dir);
// filter array using options
if (includeDirs || includeExt || includeFiles || excludeFiles || excludeExt || excludeDirs) {
currentDir = currentDir.filter((item) => {
const itemPath = path.join(dir, item);
const itemStats = fs.statSync(itemPath);
if (itemStats.isFile()) {
if (includeFiles && !includeFiles.test(item)) return false;
if (includeExt && !includeExt.test(path.extname(item).slice(1))) return false;
if (excludeFiles && excludeFiles.test(item)) return false;
if (excludeExt && excludeExt.test(path.extname(item).slice(1))) return false;
} else if (itemStats.isDirectory()) {
if (includeDirs) return includeDirs.test(item);
if (excludeDirs) return !excludeDirs.test(item);
}
return true;
});
}
const files = [];
const folders = [];
for (const item of currentDir) {
const itemPath = path.join(dir, item);
const itemStats = await fs.stat(itemPath);
if (itemStats.isDirectory()) {
folders.push(itemPath);
} else if (itemStats.isFile()) {
files.push(itemPath);
} else throw new Error(`${itemPath} is neither a file nor a folder?`);
}
for (const file of files) {
yield file;
}
for (const folder of folders) {
yield* pathsGenerator(folder, options);
}
}