Skip to content

Commit a121634

Browse files
authored
fix(node/fs/exists): fix promisified exists (#2409)
1 parent 583554d commit a121634

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

node/_fs/_fs_exists.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
11
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
22
import { fromFileUrl } from "../path.ts";
33

4-
type ExitsCallback = (exists: boolean) => void;
4+
type ExistsCallback = (exists: boolean) => void;
55

66
/**
77
* TODO: Also accept 'path' parameter as a Node polyfill Buffer type once these
88
* are implemented. See https://github.com/denoland/deno/issues/3403
99
* Deprecated in node api
1010
*/
11-
export function exists(path: string | URL, callback: ExitsCallback): void {
11+
export function exists(path: string | URL, callback: ExistsCallback): void {
1212
path = path instanceof URL ? fromFileUrl(path) : path;
1313
Deno.lstat(path).then(() => callback(true), () => callback(false));
1414
}
1515

16+
// The callback of fs.exists doesn't have standard callback signature.
17+
// We need to provide special implementation for promisify.
18+
// See https://github.com/nodejs/node/pull/13316
19+
const kCustomPromisifiedSymbol = Symbol.for("nodejs.util.promisify.custom");
20+
Object.defineProperty(exists, kCustomPromisifiedSymbol, {
21+
value: (path: string | URL) => {
22+
return new Promise((resolve) => {
23+
exists(path, (exists) => resolve(exists));
24+
});
25+
},
26+
});
27+
1628
/**
1729
* TODO: Also accept 'path' parameter as a Node polyfill Buffer or URL type once these
1830
* are implemented. See https://github.com/denoland/deno/issues/3403

node/_fs/_fs_exists_test.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import {
55
assertStringIncludes,
66
} from "../../testing/asserts.ts";
77
import { exists, existsSync } from "./_fs_exists.ts";
8+
import { promisify } from "../util.ts";
89

9-
Deno.test("existsFile", async function () {
10+
Deno.test("[std/node/fs] exists", async function () {
1011
const availableFile = await new Promise((resolve) => {
1112
const tmpFilePath = Deno.makeTempFileSync();
1213
exists(tmpFilePath, (exists: boolean) => {
@@ -21,13 +22,24 @@ Deno.test("existsFile", async function () {
2122
assertEquals(notAvailableFile, false);
2223
});
2324

24-
Deno.test("existsSyncFile", function () {
25+
Deno.test("[std/node/fs] existsSync", function () {
2526
const tmpFilePath = Deno.makeTempFileSync();
2627
assertEquals(existsSync(tmpFilePath), true);
2728
Deno.removeSync(tmpFilePath);
2829
assertEquals(existsSync("./notAvailable.txt"), false);
2930
});
3031

32+
Deno.test("[std/node/fs] promisify(exists)", async () => {
33+
const tmpFilePath = await Deno.makeTempFile();
34+
try {
35+
const existsPromisified = promisify(exists);
36+
assert(await existsPromisified(tmpFilePath));
37+
assert(!await existsPromisified("./notAvailable.txt"));
38+
} finally {
39+
await Deno.remove(tmpFilePath);
40+
}
41+
});
42+
3143
Deno.test("[std/node/fs] exists callback isn't called twice if error is thrown", async () => {
3244
// This doesn't use `assertCallbackErrorUncaught()` because `exists()` doesn't return a standard node callback, which is what it expects.
3345
const tempFile = await Deno.makeTempFile();

0 commit comments

Comments
 (0)