@@ -4,20 +4,21 @@ let path = require("node:path");
44
55exports . FileFinder = class FileFinder {
66 /**
7- * @param {string } directory
7+ * @param {string } root
88 * @param {FileFinderOptions } options?
99 */
10- constructor ( directory , { skipDotfiles, filter = ( ) => true } = { } ) {
11- this . directory = directory ;
10+ constructor ( root , { skipDotfiles, filter } ) {
11+ this . _root = root ;
12+
1213 /**
1314 * @param {string } filename
1415 * @return {boolean }
1516 */
16- this . filter = filename => {
17+ this . _filter = filename => {
1718 if ( skipDotfiles && isDotfile ( filename ) ) {
1819 return false ;
1920 }
20- return filter ( filename ) ;
21+ return filter ? filter ( filename ) : true ;
2122 } ;
2223 }
2324
@@ -26,9 +27,9 @@ exports.FileFinder = class FileFinder {
2627 *
2728 * @returns {Promise<string[]> }
2829 */
29- all ( ) {
30- return tree ( this . directory ) .
31- then ( filenames => filenames . filter ( this . filter ) ) ;
30+ async all ( ) {
31+ let filenames = await tree ( this . _root ) ;
32+ return filenames . filter ( this . _filter ) ;
3233 }
3334
3435 /**
@@ -37,64 +38,39 @@ exports.FileFinder = class FileFinder {
3738 * @param {string[] } filepaths
3839 * @returns {Promise<string[]> }
3940 */
40- match ( filepaths ) {
41- return filesWithinDirectory ( this . directory , filepaths ) .
42- then ( filepaths => filepaths . filter ( this . filter ) ) ;
41+ async match ( filepaths ) {
42+ return filepaths . map ( filepath => path . relative ( this . _root , filepath ) ) .
43+ filter ( filename => ! filename . startsWith ( ".." ) ) .
44+ filter ( this . _filter ) ;
4345 }
4446} ;
4547
4648/**
49+ * flat list of all files of a directory tree
50+ *
4751 * @param {string } filepath
4852 * @param {string } referenceDir
4953 * @returns {Promise<string[]> }
5054 */
51- function tree ( filepath , referenceDir = filepath ) {
52- return stat ( filepath ) .
53- then ( res => {
54- if ( ! res . isDirectory ( ) ) {
55- return [ path . relative ( referenceDir , filepath ) ] ;
56- }
55+ async function tree ( filepath , referenceDir = filepath ) {
56+ let stats = await stat ( filepath ) ;
5757
58- return readdir ( filepath ) .
59- then ( entries => {
60- let res = Promise . all ( entries . map ( entry => {
61- return tree ( path . join ( filepath , entry ) , referenceDir ) ;
62- } ) ) ;
63- return res . then ( flatten ) ;
64- } ) ;
65- } ) ;
66- }
58+ if ( ! stats . isDirectory ( ) ) {
59+ return [ path . relative ( referenceDir , filepath ) ] ;
60+ }
6761
68- /**
69- * @param {string } directory
70- * @param {string[] } files
71- * @returns {Promise<string[]> }
72- */
73- function filesWithinDirectory ( directory , files ) {
74- return new Promise ( resolve => {
75- resolve ( files .
76- map ( filepath => path . relative ( directory , filepath ) ) .
77- filter ( filename => ! filename . startsWith ( ".." ) ) ) ;
78- } ) ;
62+ let entries = await Promise . all ( ( await readdir ( filepath ) ) . map ( entry => {
63+ return tree ( path . join ( filepath , entry ) , referenceDir ) ;
64+ } ) ) ;
65+ return entries . flat ( ) ;
7966}
8067
8168/**
69+ * Does the filename start with a dot?
70+ *
8271 * @param {string } filename
8372 * @returns {boolean }
8473 */
8574function isDotfile ( filename ) {
8675 return path . basename ( filename ) . startsWith ( "." ) ;
8776}
88-
89- /**
90- * @param {string[][] } arr
91- * @returns {string[] }
92- */
93- function flatten ( arr ) {
94- /**
95- * I'm deeply sorry for this
96- * @type string[]
97- */
98- const akwardlyTypedStringArray = [ ] ;
99- return akwardlyTypedStringArray . concat . apply ( [ ] , arr ) ;
100- }
0 commit comments