|
4 | 4 | MathRandom, |
5 | 5 | ObjectFreeze, |
6 | 6 | StringPrototypeIncludes, |
| 7 | + StringPrototypeLastIndexOf, |
| 8 | + StringPrototypeSlice, |
7 | 9 | StringPrototypeStartsWith, |
8 | 10 | Symbol, |
9 | 11 | SymbolDispose, |
@@ -379,28 +381,36 @@ class VirtualFileSystem { |
379 | 381 | readdirSync(dirPath, options) { |
380 | 382 | const providerPath = this.#toProviderPath(dirPath); |
381 | 383 | const result = this[kProvider].readdirSync(providerPath, options); |
| 384 | + return this.#toMountedDirents(dirPath, result, options); |
| 385 | + } |
382 | 386 |
|
383 | | - // Rewrite Dirent parentPath from provider-relative to VFS path. |
384 | | - if (options?.withFileTypes === true) { |
385 | | - const recursive = options?.recursive === true; |
386 | | - for (let i = 0; i < result.length; i++) { |
387 | | - const dirent = result[i]; |
388 | | - if (recursive) { |
389 | | - // In recursive mode, name may contain slashes (e.g. 'a/b.txt'). |
390 | | - const slashIdx = dirent.name.lastIndexOf('/'); |
391 | | - if (slashIdx !== -1) { |
392 | | - const subdir = dirent.name.slice(0, slashIdx); |
393 | | - dirent.parentPath = joinPath(dirPath, subdir); |
394 | | - dirent.name = dirent.name.slice(slashIdx + 1); |
395 | | - } else { |
396 | | - dirent.parentPath = dirPath; |
397 | | - } |
398 | | - } else { |
399 | | - dirent.parentPath = dirPath; |
| 387 | + /** |
| 388 | + * Rewrites the Dirents of a listing of `dirPath` from provider-relative to |
| 389 | + * VFS paths, so that each `parentPath` is the directory the entry is in. |
| 390 | + * @param {string} dirPath The listed directory, as given by the caller |
| 391 | + * @param {string[]|Dirent[]} result The provider's listing |
| 392 | + * @param {object} [options] The readdir options |
| 393 | + * @returns {string[]|Dirent[]} |
| 394 | + */ |
| 395 | + #toMountedDirents(dirPath, result, options) { |
| 396 | + if (options?.withFileTypes !== true) return result; |
| 397 | + const recursive = options?.recursive === true; |
| 398 | + // A mounted VFS is addressed by host paths, so, like fs, join with the |
| 399 | + // host's separator; an unmounted one uses POSIX paths throughout. |
| 400 | + const join = this[kMounted] ? path.join : joinPath; |
| 401 | + for (let i = 0; i < result.length; i++) { |
| 402 | + const dirent = result[i]; |
| 403 | + dirent.parentPath = dirPath; |
| 404 | + if (recursive) { |
| 405 | + // In recursive mode, name may contain slashes (e.g. 'a/b.txt'). |
| 406 | + const slashIdx = StringPrototypeLastIndexOf(dirent.name, '/'); |
| 407 | + if (slashIdx !== -1) { |
| 408 | + const subdir = StringPrototypeSlice(dirent.name, 0, slashIdx); |
| 409 | + dirent.parentPath = join(dirPath, subdir); |
| 410 | + dirent.name = StringPrototypeSlice(dirent.name, slashIdx + 1); |
400 | 411 | } |
401 | 412 | } |
402 | 413 | } |
403 | | - |
404 | 414 | return result; |
405 | 415 | } |
406 | 416 |
|
@@ -813,7 +823,8 @@ class VirtualFileSystem { |
813 | 823 | } |
814 | 824 |
|
815 | 825 | this[kProvider].readdir(this.#toProviderPath(dirPath), options) |
816 | | - .then((entries) => callback(null, entries), (err) => callback(err)); |
| 826 | + .then((entries) => callback(null, this.#toMountedDirents(dirPath, entries, options)), |
| 827 | + (err) => callback(err)); |
817 | 828 | } |
818 | 829 |
|
819 | 830 | /** |
@@ -1173,6 +1184,8 @@ class VirtualFileSystem { |
1173 | 1184 | const toProviderPath = (p) => this.#toProviderPath(p); |
1174 | 1185 | const toProviderPrefix = (p) => this.#toProviderPrefix(p); |
1175 | 1186 | const toMountedPath = (p) => this.#toMountedPath(p); |
| 1187 | + const toMountedDirents = (p, result, options) => |
| 1188 | + this.#toMountedDirents(p, result, options); |
1176 | 1189 |
|
1177 | 1190 | return ObjectFreeze({ |
1178 | 1191 | async readFile(filePath, options) { |
@@ -1202,7 +1215,8 @@ class VirtualFileSystem { |
1202 | 1215 |
|
1203 | 1216 | async readdir(dirPath, options) { |
1204 | 1217 | const providerPath = toProviderPath(dirPath); |
1205 | | - return provider.readdir(providerPath, options); |
| 1218 | + const result = await provider.readdir(providerPath, options); |
| 1219 | + return toMountedDirents(dirPath, result, options); |
1206 | 1220 | }, |
1207 | 1221 |
|
1208 | 1222 | async mkdir(dirPath, options) { |
|
0 commit comments