26
26
27
27
const {
28
28
ArrayPrototypePush,
29
+ ArrayPrototypeShift,
29
30
BigIntPrototypeToString,
30
31
MathMax,
31
32
Number,
@@ -140,7 +141,6 @@ const {
140
141
validateObject,
141
142
validateString,
142
143
} = require ( 'internal/validators' ) ;
143
-
144
144
let truncateWarn = true ;
145
145
let fs ;
146
146
@@ -1404,34 +1404,64 @@ function mkdirSync(path, options) {
1404
1404
}
1405
1405
}
1406
1406
1407
- // TODO(Ethan-Arrowood): Make this iterative too
1408
- function readdirSyncRecursive ( path , origPath , options ) {
1409
- nullCheck ( path , 'path' , true ) ;
1410
- const ctx = { path } ;
1411
- const result = binding . readdir ( pathModule . toNamespacedPath ( path ) ,
1412
- options . encoding , ! ! options . withFileTypes , undefined , ctx ) ;
1413
- handleErrorFromBinding ( ctx ) ;
1414
- return options . withFileTypes ?
1415
- getDirents ( path , result ) . flatMap ( ( dirent ) => {
1416
- return [
1417
- dirent ,
1418
- ...( dirent . isDirectory ( ) ?
1419
- readdirSyncRecursive (
1420
- pathModule . join ( path , dirent . name ) ,
1421
- origPath ,
1422
- options ,
1423
- ) : [ ] ) ,
1424
- ] ;
1425
- } ) :
1426
- result . flatMap ( ( ent ) => {
1427
- const innerPath = pathModule . join ( path , ent ) ;
1428
- const relativePath = pathModule . relative ( origPath , innerPath ) ;
1429
- const stat = binding . internalModuleStat ( innerPath ) ;
1430
- return [
1431
- relativePath ,
1432
- ...( stat === 1 ? readdirSyncRecursive ( innerPath , origPath , options ) : [ ] ) ,
1433
- ] ;
1434
- } ) ;
1407
+ /**
1408
+ * An iterative algorithm for reading the entire contents of the `basePath` directory.
1409
+ * This function does not validate `basePath` as a directory. It is passed directly to
1410
+ * `binding.readdir` after a `nullCheck`.
1411
+ * @param {string } basePath
1412
+ * @param {{ encoding: string, withFileTypes: boolean } } options
1413
+ * @returns {Array<string> | Array<Dirent> }
1414
+ */
1415
+ function readdirSyncRecursive ( basePath , options ) {
1416
+ nullCheck ( basePath , 'path' , true ) ;
1417
+
1418
+ const results = [ ] ;
1419
+ const opsQueue = [ ] ;
1420
+
1421
+ function _read ( _path ) {
1422
+ const ctx = { _path } ;
1423
+ const result = binding . readdir (
1424
+ pathModule . toNamespacedPath ( _path ) ,
1425
+ options . encoding ,
1426
+ ! ! options . withFileTypes ,
1427
+ undefined ,
1428
+ ctx ,
1429
+ ) ;
1430
+ handleErrorFromBinding ( ctx ) ;
1431
+
1432
+ if ( options . withFileTypes ) {
1433
+ const dirents = getDirents ( _path , result ) ;
1434
+ for ( let i = 0 ; i < dirents . length ; i ++ ) {
1435
+ const dirent = dirents [ i ] ;
1436
+ ArrayPrototypePush ( results , dirent ) ;
1437
+ if ( dirent . isDirectory ( ) ) {
1438
+ ArrayPrototypePush ( opsQueue , curryRead ( pathModule . join ( dirent . path , dirent . name ) ) ) ;
1439
+ }
1440
+ }
1441
+ } else {
1442
+ for ( let i = 0 ; i < result . length ; i ++ ) {
1443
+ const ent = result [ i ] ;
1444
+ const innerPath = pathModule . join ( _path , ent ) ;
1445
+ const relativePath = pathModule . relative ( basePath , innerPath ) ;
1446
+ const stat = binding . internalModuleStat ( innerPath ) ;
1447
+ ArrayPrototypePush ( results , relativePath ) ;
1448
+ if ( stat === 1 ) {
1449
+ ArrayPrototypePush ( opsQueue , curryRead ( innerPath ) ) ;
1450
+ }
1451
+ }
1452
+ }
1453
+ }
1454
+
1455
+ const curryRead = ( p ) => ( ) => _read ( p ) ;
1456
+
1457
+ ArrayPrototypePush ( opsQueue , curryRead ( basePath ) ) ;
1458
+
1459
+ while ( opsQueue . length !== 0 ) {
1460
+ const op = ArrayPrototypeShift ( opsQueue ) ;
1461
+ op ( ) ;
1462
+ }
1463
+
1464
+ return results ;
1435
1465
}
1436
1466
1437
1467
/**
@@ -1456,7 +1486,7 @@ function readdir(path, options, callback) {
1456
1486
}
1457
1487
1458
1488
if ( options . recursive ) {
1459
- callback ( null , readdirSyncRecursive ( path , path , options ) ) ;
1489
+ callback ( null , readdirSyncRecursive ( path , options ) ) ;
1460
1490
return ;
1461
1491
}
1462
1492
@@ -1494,7 +1524,7 @@ function readdirSync(path, options) {
1494
1524
}
1495
1525
1496
1526
if ( options . recursive ) {
1497
- return readdirSyncRecursive ( path , path , options ) ;
1527
+ return readdirSyncRecursive ( path , options ) ;
1498
1528
}
1499
1529
1500
1530
const ctx = { path } ;
0 commit comments