watcher/dist_ts/tiny-readdir/index.js
2024-04-18 21:12:37 +02:00

179 lines
17 KiB
JavaScript

/* IMPORT */
import fs from 'node:fs';
import path from 'node:path';
import { isFunction, makeCounterPromise } from './utils.js';
/* MAIN */
//TODO: Streamline the type of dirnmaps
const readdir = (rootPath, options) => {
const followSymlinks = options?.followSymlinks ?? false;
const maxDepth = options?.depth ?? Infinity;
const maxPaths = options?.limit ?? Infinity;
const ignore = options?.ignore ?? (() => false);
const isIgnored = isFunction(ignore) ? ignore : (targetPath) => ignore.test(targetPath);
const signal = options?.signal ?? { aborted: false };
const directories = [];
const directoriesNames = new Set();
const directoriesNamesToPaths = {};
const files = [];
const filesNames = new Set();
const filesNamesToPaths = {};
const symlinks = [];
const symlinksNames = new Set();
const symlinksNamesToPaths = {};
const map = {};
const visited = new Set();
const resultEmpty = { directories: [], directoriesNames: new Set(), directoriesNamesToPaths: {}, files: [], filesNames: new Set(), filesNamesToPaths: {}, symlinks: [], symlinksNames: new Set(), symlinksNamesToPaths: {}, map: {} };
const result = { directories, directoriesNames, directoriesNamesToPaths, files, filesNames, filesNamesToPaths, symlinks, symlinksNames, symlinksNamesToPaths, map };
const { promise, increment, decrement } = makeCounterPromise();
let foundPaths = 0;
const handleDirectory = (dirmap, subPath, name, depth) => {
if (visited.has(subPath))
return;
if (foundPaths >= maxPaths)
return;
foundPaths += 1;
dirmap.directories.push(subPath);
dirmap.directoriesNames.add(name);
// dirmap.directoriesNamesToPaths.propertyIsEnumerable(name) || ( dirmap.directoriesNamesToPaths[name] = [] );
// dirmap.directoriesNamesToPaths[name].push ( subPath );
directories.push(subPath);
directoriesNames.add(name);
directoriesNamesToPaths.propertyIsEnumerable(name) || (directoriesNamesToPaths[name] = []);
directoriesNamesToPaths[name].push(subPath);
visited.add(subPath);
if (depth >= maxDepth)
return;
if (foundPaths >= maxPaths)
return;
populateResultFromPath(subPath, depth + 1);
};
const handleFile = (dirmap, subPath, name) => {
if (visited.has(subPath))
return;
if (foundPaths >= maxPaths)
return;
foundPaths += 1;
dirmap.files.push(subPath);
dirmap.filesNames.add(name);
// dirmap.filesNamesToPaths.propertyIsEnumerable(name) || ( dirmap.filesNamesToPaths[name] = [] );
// dirmap.filesNamesToPaths[name].push ( subPath );
files.push(subPath);
filesNames.add(name);
filesNamesToPaths.propertyIsEnumerable(name) || (filesNamesToPaths[name] = []);
filesNamesToPaths[name].push(subPath);
visited.add(subPath);
};
const handleSymlink = (dirmap, subPath, name, depth) => {
if (visited.has(subPath))
return;
if (foundPaths >= maxPaths)
return;
foundPaths += 1;
dirmap.symlinks.push(subPath);
dirmap.symlinksNames.add(name);
// dirmap.symlinksNamesToPaths.propertyIsEnumerable(name) || ( dirmap.symlinksNamesToPaths[name] = [] );
// dirmap.symlinksNamesToPaths[name].push ( subPath );
symlinks.push(subPath);
symlinksNames.add(name);
symlinksNamesToPaths.propertyIsEnumerable(name) || (symlinksNamesToPaths[name] = []);
symlinksNamesToPaths[name].push(subPath);
visited.add(subPath);
if (!followSymlinks)
return;
if (depth >= maxDepth)
return;
if (foundPaths >= maxPaths)
return;
populateResultFromSymlink(subPath, depth + 1);
};
const handleStat = (dirmap, rootPath, name, stat, depth) => {
if (signal.aborted)
return;
if (isIgnored(rootPath))
return;
if (stat.isDirectory()) {
handleDirectory(dirmap, rootPath, name, depth);
}
else if (stat.isFile()) {
handleFile(dirmap, rootPath, name);
}
else if (stat.isSymbolicLink()) {
handleSymlink(dirmap, rootPath, name, depth);
}
};
const handleDirent = (dirmap, rootPath, dirent, depth) => {
if (signal.aborted)
return;
const separator = (rootPath === path.sep) ? '' : path.sep;
const name = dirent.name;
const subPath = `${rootPath}${separator}${name}`;
if (isIgnored(subPath))
return;
if (dirent.isDirectory()) {
handleDirectory(dirmap, subPath, name, depth);
}
else if (dirent.isFile()) {
handleFile(dirmap, subPath, name);
}
else if (dirent.isSymbolicLink()) {
handleSymlink(dirmap, subPath, name, depth);
}
};
const handleDirents = (dirmap, rootPath, dirents, depth) => {
for (let i = 0, l = dirents.length; i < l; i++) {
handleDirent(dirmap, rootPath, dirents[i], depth);
}
};
const populateResultFromPath = (rootPath, depth) => {
if (signal.aborted)
return;
if (depth > maxDepth)
return;
if (foundPaths >= maxPaths)
return;
increment();
fs.readdir(rootPath, { withFileTypes: true }, (error, dirents) => {
if (error)
return decrement();
if (signal.aborted)
return decrement();
if (!dirents.length)
return decrement();
const dirmap = map[rootPath] = { directories: [], directoriesNames: new Set(), directoriesNamesToPaths: {}, files: [], filesNames: new Set(), filesNamesToPaths: {}, symlinks: [], symlinksNames: new Set(), symlinksNamesToPaths: {} };
handleDirents(dirmap, rootPath, dirents, depth);
decrement();
});
};
const populateResultFromSymlink = async (rootPath, depth) => {
increment();
fs.realpath(rootPath, (error, realPath) => {
if (error)
return decrement();
if (signal.aborted)
return decrement();
fs.stat(realPath, async (error, stat) => {
if (error)
return decrement();
if (signal.aborted)
return decrement();
const name = path.basename(realPath);
const dirmap = map[rootPath] = { directories: [], directoriesNames: new Set(), directoriesNamesToPaths: {}, files: [], filesNames: new Set(), filesNamesToPaths: {}, symlinks: [], symlinksNames: new Set(), symlinksNamesToPaths: {} };
handleStat(dirmap, realPath, name, stat, depth);
decrement();
});
});
};
const getResult = async (rootPath, depth = 1) => {
rootPath = path.normalize(rootPath);
visited.add(rootPath);
populateResultFromPath(rootPath, depth);
await promise;
if (signal.aborted)
return resultEmpty;
return result;
};
return getResult(rootPath);
};
/* EXPORT */
export default readdir;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy90aW55LXJlYWRkaXIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsWUFBWTtBQUVaLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFDLFVBQVUsRUFBRSxrQkFBa0IsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUcxRCxVQUFVO0FBRVYsdUNBQXVDO0FBRXZDLE1BQU0sT0FBTyxHQUFHLENBQUUsUUFBZ0IsRUFBRSxPQUFpQixFQUFvQixFQUFFO0lBRXpFLE1BQU0sY0FBYyxHQUFHLE9BQU8sRUFBRSxjQUFjLElBQUksS0FBSyxDQUFDO0lBQ3hELE1BQU0sUUFBUSxHQUFHLE9BQU8sRUFBRSxLQUFLLElBQUksUUFBUSxDQUFDO0lBQzVDLE1BQU0sUUFBUSxHQUFHLE9BQU8sRUFBRSxLQUFLLElBQUksUUFBUSxDQUFDO0lBQzVDLE1BQU0sTUFBTSxHQUFHLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoRCxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUcsTUFBTSxDQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBRSxVQUFrQixFQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFHLFVBQVUsQ0FBRSxDQUFDO0lBQ3hHLE1BQU0sTUFBTSxHQUFHLE9BQU8sRUFBRSxNQUFNLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDckQsTUFBTSxXQUFXLEdBQWEsRUFBRSxDQUFDO0lBQ2pDLE1BQU0sZ0JBQWdCLEdBQWdCLElBQUksR0FBRyxFQUFHLENBQUM7SUFDakQsTUFBTSx1QkFBdUIsR0FBNkIsRUFBRSxDQUFDO0lBQzdELE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztJQUMzQixN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