Skip to content

Commit

Permalink
feat: Implementing "withFileTypes" option for fs.readdir method
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmlnc committed Jan 3, 2020
1 parent ad93ac5 commit d899b03
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 3 deletions.
33 changes: 30 additions & 3 deletions lib/binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ const getPathParts = require('./filesystem').getPathParts;
const bufferFrom = require('./buffer').from;
const bufferAlloc = require('./buffer').alloc;

const MODE_TO_K_TYPE = {
[constants.S_IFREG]: constants.UV_DIRENT_FILE,
[constants.S_IFDIR]: constants.UV_DIRENT_DIR,
[constants.S_IFBLK]: constants.UV_DIRENT_BLOCK,
[constants.S_IFCHR]: constants.UV_DIRENT_CHAR,
[constants.S_IFLNK]: constants.UV_DIRENT_LINK,
[constants.S_IFIFO]: constants.UV_DIRENT_FIFO,
[constants.S_IFSOCK]: constants.UV_DIRENT_SOCKET
};

/** Workaround for optimizations in node 8+ */
const fsBinding = process.binding('fs');
const kUsePromises = fsBinding.kUsePromises;
Expand Down Expand Up @@ -140,6 +150,16 @@ function wrapStatsCallback(callback) {
}
}

function getDirentType(mode) {
const ktype = MODE_TO_K_TYPE[mode & constants.S_IFMT];

if (ktype === undefined) {
return constants.UV_DIRENT_UNKNOWN;
}

return ktype;
}

function notImplemented() {
throw new Error('Method not implemented');
}
Expand Down Expand Up @@ -914,9 +934,6 @@ Binding.prototype.readdir = function(
} else if (arguments.length === 3) {
callback = withFileTypes;
}
if (withFileTypes === true) {
notImplemented();
}

markSyscall(ctx, 'scandir');

Expand All @@ -933,7 +950,17 @@ Binding.prototype.readdir = function(
if (!(dir instanceof Directory)) {
throw new FSError('ENOTDIR', dirpath);
}

let list = dir.list();
if (withFileTypes === true) {
const types = list.map(function(name) {
const stats = dir.getItem(name).getStats();

return getDirentType(stats.mode);
});
list = [list, types];
}

if (encoding === 'buffer') {
list = list.map(function(item) {
return bufferFrom(item);
Expand Down
40 changes: 40 additions & 0 deletions test/lib/fs.readdir.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const path = require('path');

const assert = helper.assert;
const withPromise = helper.withPromise;
const inVersion = helper.inVersion;

describe('fs.readdir(path, callback)', function() {
beforeEach(function() {
Expand Down Expand Up @@ -81,6 +82,45 @@ describe('fs.readdir(path, callback)', function() {
}
);
});

inVersion('>=10.10').it('should support withFileTypes option', function(
done
) {
fs.readdir(
path.join('nested', 'sub', 'dir'),
{withFileTypes: true},
function(err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(items, [
{name: 'empty'},
{name: 'one.txt'},
{name: 'two.txt'}
]);
assert.ok(items[0].isDirectory());
assert.ok(items[1].isFile());
assert.ok(items[2].isFile());
done();
}
);
});

withPromise.it('should support withFileTypes option', function(done) {
fs.promises
.readdir(path.join('nested', 'sub', 'dir'), {withFileTypes: true})
.then(function(items) {
assert.isArray(items);
assert.deepEqual(items, [
{name: 'empty'},
{name: 'one.txt'},
{name: 'two.txt'}
]);
assert.ok(items[0].isDirectory());
assert.ok(items[1].isFile());
assert.ok(items[2].isFile());
done();
}, done);
});
});

describe('fs.readdirSync(path)', function() {
Expand Down

0 comments on commit d899b03

Please # to comment.