| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 872e670 commit 439ea47
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1220,6 +1220,9 @@ a colon, Node.js will open a file system stream, as described by | |||
| 1220 | 1220 | <!-- YAML | |
| 1221 | 1221 | added: v12.12.0 | |
| 1222 | 1222 | changes: | |
| 1223 | + - version: REPLACEME | ||
| 1224 | + pr-url: https://github.com/nodejs/node/pull/41439 | ||
| 1225 | + description: Added `recursive` option. | ||
| 1223 | 1226 | - version: | |
| 1224 | 1227 | - v13.1.0 | |
| 1225 | 1228 | - v12.16.0 | |
@@ -1233,6 +1236,8 @@ changes: | |||
| 1233 | 1236 | * `bufferSize` {number} Number of directory entries that are buffered | |
| 1234 | 1237 | internally when reading from the directory. Higher values lead to better | |
| 1235 | 1238 | performance but higher memory usage. **Default:** `32` | |
| 1239 | + * `recursive` {boolean} Resolved `Dir` will be an {AsyncIterable} | ||
| 1240 | + containing all sub files and directories. **Default:** `false` | ||
| 1236 | 1241 | * Returns: {Promise} Fulfills with an {fs.Dir}. | |
| 1237 | 1242 | ||
| 1238 | 1243 | Asynchronously open a directory for iterative scanning. See the POSIX | |
@@ -1266,6 +1271,9 @@ closed after the iterator exits. | |||
| 1266 | 1271 | <!-- YAML | |
| 1267 | 1272 | added: v10.0.0 | |
| 1268 | 1273 | changes: | |
| 1274 | + - version: REPLACEME | ||
| 1275 | + pr-url: https://github.com/nodejs/node/pull/41439 | ||
| 1276 | + description: Added `recursive` option. | ||
| 1269 | 1277 | - version: v10.11.0 | |
| 1270 | 1278 | pr-url: https://github.com/nodejs/node/pull/22020 | |
| 1271 | 1279 | description: New option `withFileTypes` was added. | |
@@ -1275,6 +1283,7 @@ changes: | |||
| 1275 | 1283 | * `options` {string|Object} | |
| 1276 | 1284 | * `encoding` {string} **Default:** `'utf8'` | |
| 1277 | 1285 | * `withFileTypes` {boolean} **Default:** `false` | |
| 1286 | + * `recursive` {boolean} **Default:** `false` | ||
| 1278 | 1287 | * Returns: {Promise} Fulfills with an array of the names of the files in | |
| 1279 | 1288 | the directory excluding `'.'` and `'..'`. | |
| 1280 | 1289 | ||
@@ -3402,6 +3411,9 @@ const { openAsBlob } = require('node:fs'); | |||
| 3402 | 3411 | <!-- YAML | |
| 3403 | 3412 | added: v12.12.0 | |
| 3404 | 3413 | changes: | |
| 3414 | + - version: REPLACEME | ||
| 3415 | + pr-url: https://github.com/nodejs/node/pull/41439 | ||
| 3416 | + description: Added `recursive` option. | ||
| 3405 | 3417 | - version: v18.0.0 | |
| 3406 | 3418 | pr-url: https://github.com/nodejs/node/pull/41678 | |
| 3407 | 3419 | description: Passing an invalid callback to the `callback` argument | |
@@ -3420,6 +3432,7 @@ changes: | |||
| 3420 | 3432 | * `bufferSize` {number} Number of directory entries that are buffered | |
| 3421 | 3433 | internally when reading from the directory. Higher values lead to better | |
| 3422 | 3434 | performance but higher memory usage. **Default:** `32` | |
| 3435 | + * `recursive` {boolean} **Default:** `false` | ||
| 3423 | 3436 | * `callback` {Function} | |
| 3424 | 3437 | * `err` {Error} | |
| 3425 | 3438 | * `dir` {fs.Dir} | |
@@ -3538,6 +3551,9 @@ above values. | |||
| 3538 | 3551 | <!-- YAML | |
| 3539 | 3552 | added: v0.1.8 | |
| 3540 | 3553 | changes: | |
| 3554 | + - version: REPLACEME | ||
| 3555 | + pr-url: https://github.com/nodejs/node/pull/41439 | ||
| 3556 | + description: Added `recursive` option. | ||
| 3541 | 3557 | - version: v18.0.0 | |
| 3542 | 3558 | pr-url: https://github.com/nodejs/node/pull/41678 | |
| 3543 | 3559 | description: Passing an invalid callback to the `callback` argument | |
@@ -3567,6 +3583,7 @@ changes: | |||
| 3567 | 3583 | * `options` {string|Object} | |
| 3568 | 3584 | * `encoding` {string} **Default:** `'utf8'` | |
| 3569 | 3585 | * `withFileTypes` {boolean} **Default:** `false` | |
| 3586 | + * `recursive` {boolean} **Default:** `false` | ||
| 3570 | 3587 | * `callback` {Function} | |
| 3571 | 3588 | * `err` {Error} | |
| 3572 | 3589 | * `files` {string\[]|Buffer\[]|fs.Dirent\[]} | |
@@ -5543,6 +5560,9 @@ object with an `encoding` property specifying the character encoding to use. | |||
| 5543 | 5560 | <!-- YAML | |
| 5544 | 5561 | added: v12.12.0 | |
| 5545 | 5562 | changes: | |
| 5563 | + - version: REPLACEME | ||
| 5564 | + pr-url: https://github.com/nodejs/node/pull/41439 | ||
| 5565 | + description: Added `recursive` option. | ||
| 5546 | 5566 | - version: | |
| 5547 | 5567 | - v13.1.0 | |
| 5548 | 5568 | - v12.16.0 | |
@@ -5556,6 +5576,7 @@ changes: | |||
| 5556 | 5576 | * `bufferSize` {number} Number of directory entries that are buffered | |
| 5557 | 5577 | internally when reading from the directory. Higher values lead to better | |
| 5558 | 5578 | performance but higher memory usage. **Default:** `32` | |
| 5579 | + * `recursive` {boolean} **Default:** `false` | ||
| 5559 | 5580 | * Returns: {fs.Dir} | |
| 5560 | 5581 | ||
| 5561 | 5582 | Synchronously open a directory. See opendir(3). | |
@@ -5599,6 +5620,9 @@ this API: [`fs.open()`][]. | |||
| 5599 | 5620 | <!-- YAML | |
| 5600 | 5621 | added: v0.1.21 | |
| 5601 | 5622 | changes: | |
| 5623 | + - version: REPLACEME | ||
| 5624 | + pr-url: https://github.com/nodejs/node/pull/41439 | ||
| 5625 | + description: Added `recursive` option. | ||
| 5602 | 5626 | - version: v10.10.0 | |
| 5603 | 5627 | pr-url: https://github.com/nodejs/node/pull/22020 | |
| 5604 | 5628 | description: New option `withFileTypes` was added. | |
@@ -5612,6 +5636,7 @@ changes: | |||
| 5612 | 5636 | * `options` {string|Object} | |
| 5613 | 5637 | * `encoding` {string} **Default:** `'utf8'` | |
| 5614 | 5638 | * `withFileTypes` {boolean} **Default:** `false` | |
| 5639 | + * `recursive` {boolean} **Default:** `false` | ||
| 5615 | 5640 | * Returns: {string\[]|Buffer\[]|fs.Dirent\[]} | |
| 5616 | 5641 | ||
| 5617 | 5642 | Reads the contents of the directory. | |
@@ -6465,6 +6490,16 @@ The file name that this {fs.Dirent} object refers to. The type of this | |||
| 6465 | 6490 | value is determined by the `options.encoding` passed to [`fs.readdir()`][] or | |
| 6466 | 6491 | [`fs.readdirSync()`][]. | |
| 6467 | 6492 | ||
| 6493 | + #### `dirent.path` | ||
| 6494 | + | ||
| 6495 | + <!-- YAML | ||
| 6496 | + added: REPLACEME | ||
| 6497 | + --> | ||
| 6498 | + | ||
| 6499 | + * {string} | ||
| 6500 | + | ||
| 6501 | + The base path that this {fs.Dirent} object refers to. | ||
| 6502 | + | ||
| 6468 | 6503 | ### Class: `fs.FSWatcher` | |
| 6469 | 6504 | ||
| 6470 | 6505 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1404,6 +1404,36 @@ 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 | + }); | ||
| 1435 | + } | ||
| 1436 | + | ||
| 1407 | 1437 | /** | |
| 1408 | 1438 | * Reads the contents of a directory. | |
| 1409 | 1439 | * @param {string | Buffer | URL} path | |
@@ -1421,6 +1451,14 @@ function readdir(path, options, callback) { | |||
| 1421 | 1451 | callback = makeCallback(typeof options === 'function' ? options : callback); | |
| 1422 | 1452 | options = getOptions(options); | |
| 1423 | 1453 | path = getValidatedPath(path); | |
| 1454 | + if (options.recursive != null) { | ||
| 1455 | + validateBoolean(options.recursive, 'options.recursive'); | ||
| 1456 | + } | ||
| 1457 | + | ||
| 1458 | + if (options.recursive) { | ||
| 1459 | + callback(null, readdirSyncRecursive(path, path, options)); | ||
| 1460 | + return; | ||
| 1461 | + } | ||
| 1424 | 1462 | ||
| 1425 | 1463 | const req = new FSReqCallback(); | |
| 1426 | 1464 | if (!options.withFileTypes) { | |
@@ -1444,12 +1482,21 @@ function readdir(path, options, callback) { | |||
| 1444 | 1482 | * @param {string | { | |
| 1445 | 1483 | * encoding?: string; | |
| 1446 | 1484 | * withFileTypes?: boolean; | |
| 1485 | + * recursive?: boolean; | ||
| 1447 | 1486 | * }} [options] | |
| 1448 | 1487 | * @returns {string | Buffer[] | Dirent[]} | |
| 1449 | 1488 | */ | |
| 1450 | 1489 | function readdirSync(path, options) { | |
| 1451 | 1490 | options = getOptions(options); | |
| 1452 | 1491 | path = getValidatedPath(path); | |
| 1492 | + if (options.recursive != null) { | ||
| 1493 | + validateBoolean(options.recursive, 'options.recursive'); | ||
| 1494 | + } | ||
| 1495 | + | ||
| 1496 | + if (options.recursive) { | ||
| 1497 | + return readdirSyncRecursive(path, path, options); | ||
| 1498 | + } | ||
| 1499 | + | ||
| 1453 | 1500 | const ctx = { path }; | |
| 1454 | 1501 | const result = binding.readdir(pathModule.toNamespacedPath(path), | |
| 1455 | 1502 | options.encoding, !!options.withFileTypes, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,8 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | 3 | const { | |
| 4 | 4 | ArrayPrototypePush, | |
| 5 | - ArrayPrototypeSlice, | ||
| 6 | - ArrayPrototypeSplice, | ||
| 5 | + ArrayPrototypeShift, | ||
| 7 | 6 | FunctionPrototypeBind, | |
| 8 | 7 | ObjectDefineProperty, | |
| 9 | 8 | PromiseReject, | |
@@ -99,13 +98,21 @@ class Dir { | |||
| 99 | 98 | } | |
| 100 | 99 | ||
| 101 | 100 | if (this[kDirBufferedEntries].length > 0) { | |
| 102 | - const { 0: name, 1: type } = | ||
| 103 | - ArrayPrototypeSplice(this[kDirBufferedEntries], 0, 2); | ||
| 104 | - if (maybeSync) | ||
| 105 | - process.nextTick(getDirent, this[kDirPath], name, type, callback); | ||
| 106 | - else | ||
| 107 | - getDirent(this[kDirPath], name, type, callback); | ||
| 108 | - return; | ||
| 101 | + try { | ||
| 102 | + const dirent = ArrayPrototypeShift(this[kDirBufferedEntries]); | ||
| 103 | + | ||
| 104 | + if (this[kDirOptions].recursive && dirent.isDirectory()) { | ||
| 105 | + this.readSyncRecursive(dirent); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + if (maybeSync) | ||
| 109 | + process.nextTick(callback, null, dirent); | ||
| 110 | + else | ||
| 111 | + callback(null, dirent); | ||
| 112 | + return; | ||
| 113 | + } catch (error) { | ||
| 114 | + return callback(error); | ||
| 115 | + } | ||
| 109 | 116 | } | |
| 110 | 117 | ||
| 111 | 118 | const req = new FSReqCallback(); | |
@@ -120,8 +127,16 @@ class Dir { | |||
| 120 | 127 | return callback(err, result); | |
| 121 | 128 | } | |
| 122 | 129 | ||
| 123 | - this[kDirBufferedEntries] = ArrayPrototypeSlice(result, 2); | ||
| 124 | - getDirent(this[kDirPath], result[0], result[1], callback); | ||
| 130 | + try { | ||
| 131 | + this.processReadResult(this[kDirPath], result); | ||
| 132 | + const dirent = ArrayPrototypeShift(this[kDirBufferedEntries]); | ||
| 133 | + if (this[kDirOptions].recursive && dirent.isDirectory()) { | ||
| 134 | + this.readSyncRecursive(dirent); | ||
| 135 | + } | ||
| 136 | + callback(null, dirent); | ||
| 137 | + } catch (error) { | ||
| 138 | + callback(error); | ||
| 139 | + } | ||
| 125 | 140 | }; | |
| 126 | 141 | ||
| 127 | 142 | this[kDirOperationQueue] = []; | |
@@ -132,6 +147,45 @@ class Dir { | |||
| 132 | 147 | ); | |
| 133 | 148 | } | |
| 134 | 149 | ||
| 150 | + processReadResult(path, result) { | ||
| 151 | + for (let i = 0; i < result.length; i += 2) { | ||
| 152 | + ArrayPrototypePush( | ||
| 153 | + this[kDirBufferedEntries], | ||
| 154 | + getDirent( | ||
| 155 | + pathModule.join(path, result[i]), | ||
| 156 | + result[i], | ||
| 157 | + result[i + 1], | ||
| 158 | + ), | ||
| 159 | + ); | ||
| 160 | + } | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + // TODO(Ethan-Arrowood): Review this implementation. Make it iterative. | ||
| 164 | + // Can we better leverage the `kDirOperationQueue`? | ||
| 165 | + readSyncRecursive(dirent) { | ||
| 166 | + const ctx = { path: dirent.path }; | ||
| 167 | + const handle = dirBinding.opendir( | ||
| 168 | + pathModule.toNamespacedPath(dirent.path), | ||
| 169 | + this[kDirOptions].encoding, | ||
| 170 | + undefined, | ||
| 171 | + ctx, | ||
| 172 | + ); | ||
| 173 | + handleErrorFromBinding(ctx); | ||
| 174 | + const result = handle.read( | ||
| 175 | + this[kDirOptions].encoding, | ||
| 176 | + this[kDirOptions].bufferSize, | ||
| 177 | + undefined, | ||
| 178 | + ctx, | ||
| 179 | + ); | ||
| 180 | + | ||
| 181 | + if (result) { | ||
| 182 | + this.processReadResult(dirent.path, result); | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + handle.close(undefined, ctx); | ||
| 186 | + handleErrorFromBinding(ctx); | ||
| 187 | + } | ||
| 188 | + | ||
| 135 | 189 | readSync() { | |
| 136 | 190 | if (this[kDirClosed] === true) { | |
| 137 | 191 | throw new ERR_DIR_CLOSED(); | |
@@ -142,9 +196,11 @@ class Dir { | |||
| 142 | 196 | } | |
| 143 | 197 | ||
| 144 | 198 | if (this[kDirBufferedEntries].length > 0) { | |
| 145 | - const { 0: name, 1: type } = | ||
| 146 | - ArrayPrototypeSplice(this[kDirBufferedEntries], 0, 2); | ||
| 147 | - return getDirent(this[kDirPath], name, type); | ||
| 199 | + const dirent = ArrayPrototypeShift(this[kDirBufferedEntries]); | ||
| 200 | + if (this[kDirOptions].recursive && dirent.isDirectory()) { | ||
| 201 | + this.readSyncRecursive(dirent); | ||
| 202 | + } | ||
| 203 | + return dirent; | ||
| 148 | 204 | } | |
| 149 | 205 | ||
| 150 | 206 | const ctx = { path: this[kDirPath] }; | |
@@ -160,8 +216,13 @@ class Dir { | |||
| 160 | 216 | return result; | |
| 161 | 217 | } | |
| 162 | 218 | ||
| 163 | - this[kDirBufferedEntries] = ArrayPrototypeSlice(result, 2); | ||
| 164 | - return getDirent(this[kDirPath], result[0], result[1]); | ||
| 219 | + this.processReadResult(this[kDirPath], result); | ||
| 220 | + | ||
| 221 | + const dirent = ArrayPrototypeShift(this[kDirBufferedEntries]); | ||
| 222 | + if (this[kDirOptions].recursive && dirent.isDirectory()) { | ||
| 223 | + this.readSyncRecursive(dirent); | ||
| 224 | + } | ||
| 225 | + return dirent; | ||
| 165 | 226 | } | |
| 166 | 227 | ||
| 167 | 228 | close(callback) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments