Skip to content

Instantly share code, notes, and snippets.

@Phoenix35
Last active September 25, 2019 15:53
Show Gist options
  • Save Phoenix35/94171146f85bce863d53bde82d250037 to your computer and use it in GitHub Desktop.
Save Phoenix35/94171146f85bce863d53bde82d250037 to your computer and use it in GitHub Desktop.
"use strict";
const fsP = require("fs").promises;
const path = require("path");
const { cwd, chdir } = process;
/*
Breadth-first
*/
/**
* getMatchingExt - Lazily generates paths in a given `targetDir` directory matching the given `extensions` set
* @param {Path} targetDir -
* @param {Object} options -
* @param {Set} options.extensions -
* @param {?string} options.encoding -
* @param {?number} options.depth -
* @return {AsyncIterableIterator<string>} -
*/
async function *getMatchingExt ( // eslint-disable-line complexity
targetDir,
{
extensions = new Set,
encoding = "utf8",
depth = 0,
} = {},
) {
if (depth < 1) {
for (const file of await fsP.readdir(
targetDir,
{ encoding,
withFileTypes: true },
)) {
if (file.isFile() && extensions.has(path.extname(file.name)))
yield file.name;
}
return;
}
const oldDir = cwd();
chdir(targetDir);
const pathsQueue = [["."]];
try {
while (pathsQueue.length) {
// Queue in breadth-first traversal implemented via push - shift.
const currentSegments = pathsQueue.shift(),
currentDepth = currentSegments.length,
currentPath = path.join(...currentSegments);
const files = await fsP.readdir( // eslint-disable-line no-await-in-loop
currentPath,
{ encoding,
withFileTypes: true },
);
for (const file of files) {
const name = file.name;
if (file.isFile() && extensions.has(path.extname(name)))
yield path.join(currentPath, name);
else if (file.isDirectory() && currentDepth <= depth)
pathsQueue.push(currentSegments.concat(name));
}
}
} finally {
chdir(oldDir);
}
}
module.exports = getMatchingExt;
// Use
(async function main () {
for await (
const file of getMatchingExt(__dirname, { extensions: new Set([ ".jpg", ".jpeg" ]),
depth: Number.MAX_SAFE_INTEGER })
)
console.log(file);
})().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment