streamich/memfs

readdir does not support "recursive" option

nerilea opened this issue · 2 comments

memfs does not support the "recursive" option on readdir. As a result it is unable to reproduce the correct result when using a volume with a nested tree.

Another related issue, when using the withFileTypes: true option the Dirent[] object returned by memfs does not contain the base path prop. I suspect this will be needed to properly implement the "recursive" option.

I am am testing code similar to the following, using memfs v4.6.0.

import { readdir } from "node:fs/promises";
import { relative } from "node:path";

export async function getFilePaths({ basepath }) {
  const entries = await readdir(resolve(basepath), {
    recursive: true,
    withFileTypes: true,
  });
  return entries
    .filter((entry) => entry.isFile())
    .map((file) => relative(basepath, resolve(file.path, file.name)));
}

The test implemented with vitest.

import { getFilePaths } from "./fileUtils.js";
import { vol } from "memfs";
import { afterEach, describe, test, expect, vi } from "vitest";

vi.mock("node:fs/promises", async () => {
  const memfs = await vi.importActual("memfs");
  return memfs.fs.promises;
});

describe("test", () => {
  afterEach(() => {
    vol.reset();
  });

  test('should return only files', async () => {
    // arrange
    const expected = "/r/37/oj33b0leub.md";
    vol.fromJSON({
      [expected]: "# kn7ay6b7hj\n1. isin7s29f6\n"
    }, "/");

    // act
    const actual = await getFilePaths({ basepath: "/r" });

    // assert
    expect(actual).toHaveLength(1);
    expect(actual[0]).toStrictEqual(expected);
  });
});

Thanks, if anyone wants to pick this up, please do! It is a good self-contained issue for new contributors.

Hi @streamich I made an attempt at this here: #972 It passes the tests. See PR notes for changes.