From 06ffac67c2eb430842124cc778b010840bd02f33 Mon Sep 17 00:00:00 2001 From: James Bronder <36022278+jbronder@users.noreply.github.com> Date: Tue, 7 Jan 2025 20:11:38 -0800 Subject: [PATCH] feat(fs/unstable): added readDir function and test #6255 --- fs/unstable_read_dir.ts | 50 ++++++++++++++++++++++++++++++++++++ fs/unstable_read_dir_test.ts | 41 +++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 fs/unstable_read_dir.ts create mode 100644 fs/unstable_read_dir_test.ts diff --git a/fs/unstable_read_dir.ts b/fs/unstable_read_dir.ts new file mode 100644 index 000000000000..55992e2d5b6f --- /dev/null +++ b/fs/unstable_read_dir.ts @@ -0,0 +1,50 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +import { getNodeFsPromises, isDeno } from "./_utils.ts"; +import { mapError } from "./_map_error.ts"; +import { toDirEntry } from "./_to_dir_entry.ts"; +import type { DirEntry } from "./unstable_types.ts"; + +async function* getDirEntries(path: string | URL): AsyncIterable { + const fsPromises = getNodeFsPromises(); + try { + const dir = await fsPromises.opendir(path); + for await (const entry of dir) { + const dirEntry = toDirEntry(entry); + yield dirEntry; + } + } catch (error) { + throw error; + } +} + +/** Reads the directory given by `path` and returns an async iterable of + * {@linkcode DirEntry}. The order of entries is not guaranteed. + * + * ```ts + * import { readDir } from "@std/fs/unstable-read-dir"; + * + * for await (const dirEntry of readDir("/")) { + * console.log(dirEntry.name); + * } + * ``` + * + * Throws error if `path` is not a directory. + * + * Requires `allow-read` permission. + * + * @tags allow-read + * @category File System + */ +export function readDir(path: string | URL): AsyncIterable { + if (isDeno) { + return Deno.readDir(path); + } else { + try { + const dirEntries = getDirEntries(path); + return dirEntries; + } catch (error) { + throw mapError(error); + } + } +} diff --git a/fs/unstable_read_dir_test.ts b/fs/unstable_read_dir_test.ts new file mode 100644 index 000000000000..248f2772e327 --- /dev/null +++ b/fs/unstable_read_dir_test.ts @@ -0,0 +1,41 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +import { assert, assertEquals, assertRejects } from "@std/assert"; +import { fromFileUrl, join, resolve } from "@std/path"; +import { readDir } from "./unstable_read_dir.ts"; +import { NotFound } from "./unstable_errors.js"; + +const testdataDir = resolve(fromFileUrl(import.meta.url), "../testdata"); + +Deno.test("readDir() reads from the directory and its subdirectories", async () => { + const files = []; + for await (const e of readDir(testdataDir)) { + files.push(e); + } + + let counter = 0; + for (const f of files) { + if (f.name === "walk") { + assert(f.isDirectory); + counter++; + } + } + + assertEquals(counter, 1); +}); + +Deno.test("readDir() rejects when the path is not a directory", async () => { + await assertRejects(async () => { + const testFile = join(testdataDir, "0.txt"); + await readDir(testFile)[Symbol.asyncIterator]().next(); + }, Error); +}); + +Deno.test("readDir() rejects when the directory does not exist", async () => { + await assertRejects( + async () => { + await readDir("non_existent_dir")[Symbol.asyncIterator]().next(); + }, + NotFound, + ); +});