/* 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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