* Recursively reads directory contents. * @param {MemoryEntry} dirEntry The directory entry * @param {string} dirPath The normalized directory path * @param {boolean} withFileTypes Whether to return Dirent objects * @returns {string[]|Dirent[]}
(dirEntry, dirPath, withFileTypes)
| 610 | * @returns {string[]|Dirent[]} |
| 611 | */ |
| 612 | #readdirRecursive(dirEntry, dirPath, withFileTypes) { |
| 613 | const results = []; |
| 614 | |
| 615 | const walk = (entry, currentPath, relativePath) => { |
| 616 | this.#ensurePopulated(entry, currentPath); |
| 617 | |
| 618 | for (const { 0: name, 1: childEntry } of entry.children) { |
| 619 | const childRelative = relativePath ? |
| 620 | relativePath + '/' + name : name; |
| 621 | |
| 622 | if (withFileTypes) { |
| 623 | let type; |
| 624 | if (childEntry.isSymbolicLink()) { |
| 625 | type = UV_DIRENT_LINK; |
| 626 | } else if (childEntry.isDirectory()) { |
| 627 | type = UV_DIRENT_DIR; |
| 628 | } else { |
| 629 | type = UV_DIRENT_FILE; |
| 630 | } |
| 631 | ArrayPrototypePush(results, |
| 632 | new Dirent(childRelative, type, dirPath)); |
| 633 | } else { |
| 634 | ArrayPrototypePush(results, childRelative); |
| 635 | } |
| 636 | |
| 637 | // Follow symlinks to directories for recursive traversal |
| 638 | let resolvedChild = childEntry; |
| 639 | if (childEntry.isSymbolicLink()) { |
| 640 | const targetPath = this.#resolveSymlinkTarget( |
| 641 | pathPosix.join(currentPath, name), childEntry.target, |
| 642 | ); |
| 643 | const result = this.#lookupEntry(targetPath, true, 0); |
| 644 | if (result.entry) { |
| 645 | resolvedChild = result.entry; |
| 646 | } |
| 647 | } |
| 648 | if (resolvedChild.isDirectory()) { |
| 649 | const childPath = pathPosix.join(currentPath, name); |
| 650 | walk(resolvedChild, childPath, childRelative); |
| 651 | } |
| 652 | } |
| 653 | }; |
| 654 | |
| 655 | walk(dirEntry, dirPath, ''); |
| 656 | return results; |
| 657 | } |
| 658 | |
| 659 | async readdir(path, options) { |
| 660 | return this.readdirSync(path, options); |