Skip to content

Commit

Permalink
fix: fs.readdir should support withFileTypes (#24108)
Browse files Browse the repository at this point in the history
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
  • Loading branch information
trop[bot] and codebytere committed Jun 12, 2020
1 parent bcf77df commit 0d80baf
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
35 changes: 33 additions & 2 deletions lib/common/asar.js
Expand Up @@ -572,7 +572,7 @@
};

const { readdir } = fs;
fs.readdir = function (pathArgument, options, callback) {
fs.readdir = function (pathArgument, options = {}, callback) {
const { isAsar, asarPath, filePath } = splitPath(pathArgument);
if (typeof options === 'function') {
callback = options;
Expand All @@ -594,13 +594,29 @@
return;
}

if (options.withFileTypes) {
const dirents = [];
for (const file of files) {
const stats = archive.stat(file);
if (stats.isFile) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
} else if (stats.isDirectory) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
} else if (stats.isLink) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
}
}
nextTick(callback, [null, dirents]);
return;
}

nextTick(callback, [null, files]);
};

fs.promises.readdir = util.promisify(fs.readdir);

const { readdirSync } = fs;
fs.readdirSync = function (pathArgument, options) {
fs.readdirSync = function (pathArgument, options = {}) {
const { isAsar, asarPath, filePath } = splitPath(pathArgument);
if (!isAsar) return readdirSync.apply(this, arguments);

Expand All @@ -614,6 +630,21 @@
throw createError(AsarError.NOT_FOUND, { asarPath, filePath });
}

if (options.withFileTypes) {
const dirents = [];
for (const file of files) {
const stats = archive.stat(file);
if (stats.isFile) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
} else if (stats.isDirectory) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
} else if (stats.isLink) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
}
}
return dirents;
}

return files;
};

Expand Down
36 changes: 36 additions & 0 deletions spec/asar-spec.js
Expand Up @@ -792,6 +792,16 @@ describe('asar package', function () {
expect(dirs).to.deep.equal(['file1', 'file2', 'file3', 'link1', 'link2']);
});

it('supports withFileTypes', function () {
const p = path.join(asarDir, 'a.asar');
const dirs = fs.readdirSync(p, { withFileTypes: true });
for (const dir of dirs) {
expect(dir instanceof fs.Dirent).to.be.true();
}
const names = dirs.map(a => a.name);
expect(names).to.deep.equal(['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']);
});

it('reads dirs from a linked dir', function () {
const p = path.join(asarDir, 'a.asar', 'link2', 'link2');
const dirs = fs.readdirSync(p);
Expand All @@ -816,6 +826,21 @@ describe('asar package', function () {
});
});

it('supports withFileTypes', function (done) {
const p = path.join(asarDir, 'a.asar');

fs.readdir(p, { withFileTypes: true }, (err, dirs) => {
expect(err).to.be.null();
for (const dir of dirs) {
expect(dir instanceof fs.Dirent).to.be.true();
}

const names = dirs.map(a => a.name);
expect(names).to.deep.equal(['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']);
done();
});
});

it('reads dirs from a normal dir', function (done) {
const p = path.join(asarDir, 'a.asar', 'dir1');
fs.readdir(p, function (err, dirs) {
Expand All @@ -824,6 +849,7 @@ describe('asar package', function () {
done();
});
});

it('reads dirs from a linked dir', function (done) {
const p = path.join(asarDir, 'a.asar', 'link2', 'link2');
fs.readdir(p, function (err, dirs) {
Expand All @@ -849,6 +875,16 @@ describe('asar package', function () {
expect(dirs).to.deep.equal(['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']);
});

it('supports withFileTypes', async function () {
const p = path.join(asarDir, 'a.asar');
const dirs = await fs.promises.readdir(p, { withFileTypes: true });
for (const dir of dirs) {
expect(dir instanceof fs.Dirent).to.be.true();
}
const names = dirs.map(a => a.name);
expect(names).to.deep.equal(['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']);
});

it('reads dirs from a normal dir', async function () {
const p = path.join(asarDir, 'a.asar', 'dir1');
const dirs = await fs.promises.readdir(p);
Expand Down

0 comments on commit 0d80baf

Please sign in to comment.