Skip to content

Commit 450bdfb

Browse files
authored
feat(fs/unstable): add fs.lstat (#6276)
1 parent 093fceb commit 450bdfb

File tree

4 files changed

+66
-0
lines changed

4 files changed

+66
-0
lines changed

_tools/node_test_runner/run_test.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import "../../collections/unzip_test.ts";
5050
import "../../collections/without_all_test.ts";
5151
import "../../collections/zip_test.ts";
5252
import "../../fs/unstable_stat_test.ts";
53+
import "../../fs/unstable_lstat_test.ts";
5354

5455
for (const testDef of testDefinitions) {
5556
test(testDef.name, testDef.fn);

fs/deno.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"./expand-glob": "./expand_glob.ts",
1515
"./move": "./move.ts",
1616
"./unstable-stat": "./unstable_stat.ts",
17+
"./unstable-lstat": "./unstable_lstat.ts",
1718
"./walk": "./walk.ts"
1819
}
1920
}

fs/unstable_lstat.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2+
3+
import { getNodeFsPromises, isDeno } from "./_utils.ts";
4+
import { mapError } from "./_map_error.ts";
5+
import { toFileInfo } from "./_to_file_info.ts";
6+
import type { FileInfo } from "./unstable_types.ts";
7+
8+
/** Resolves to a {@linkcode FileInfo} for the specified `path`. If `path` is a symlink, information for the symlink will be returned instead of what it points to.
9+
*
10+
* ```ts
11+
* import { assert } from "@std/assert";
12+
* import { lstat } from "@std/fs/unstable-lstat";
13+
* const fileInfo = await lstat("README.md");
14+
* assert(fileInfo.isFile);
15+
* ```
16+
*
17+
* Requires `allow-read` permission.
18+
*
19+
* @tags allow-read
20+
* @category File System
21+
*/
22+
export async function lstat(path: string | URL): Promise<FileInfo> {
23+
if (isDeno) {
24+
return Deno.lstat(path);
25+
} else {
26+
const fsPromises = getNodeFsPromises();
27+
try {
28+
const stat = await fsPromises.lstat(path);
29+
return toFileInfo(stat);
30+
} catch (error) {
31+
throw mapError(error);
32+
}
33+
}
34+
}

fs/unstable_lstat_test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2+
3+
import { assert, assertRejects } from "@std/assert";
4+
import { lstat } from "./unstable_lstat.ts";
5+
import { NotFound } from "./unstable_errors.js";
6+
7+
Deno.test("lstat() returns FileInfo for a file", async () => {
8+
const fileInfo = await lstat("README.md");
9+
10+
assert(fileInfo.isFile);
11+
});
12+
13+
Deno.test("lstat() does not follow symlinks", async () => {
14+
const linkFile = `${import.meta.dirname}/testdata/0-link`;
15+
const fileInfo = await lstat(linkFile);
16+
17+
assert(fileInfo.isSymlink);
18+
});
19+
20+
Deno.test("lstat() returns FileInfo for a directory", async () => {
21+
const fileInfo = await lstat("fs");
22+
23+
assert(fileInfo.isDirectory);
24+
});
25+
26+
Deno.test("lstat() rejects with NotFound for a non-existent file", async () => {
27+
await assertRejects(async () => {
28+
await lstat("non_existent_file");
29+
}, NotFound);
30+
});

0 commit comments

Comments
 (0)