Skip to content

Commit 3f0e7c6

Browse files
manztkt3k
authored andcommitted
fix(ext/node): add fs.promises.fstat and FileHandle#stat (#26719)
Co-authored-by: Yoshiya Hinosawa <[email protected]>
1 parent 9fce244 commit 3f0e7c6

File tree

5 files changed

+57
-2
lines changed

5 files changed

+57
-2
lines changed

ext/node/polyfills/_fs/_fs_fstat.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,24 @@ export function fstatSync(
6363
const origin = new FsFile(fd, Symbol.for("Deno.internal.FsFile")).statSync();
6464
return CFISBIS(origin, options?.bigint || false);
6565
}
66+
67+
export function fstatPromise(fd: number): Promise<Stats>;
68+
export function fstatPromise(
69+
fd: number,
70+
options: { bigint: false },
71+
): Promise<Stats>;
72+
export function fstatPromise(
73+
fd: number,
74+
options: { bigint: true },
75+
): Promise<BigIntStats>;
76+
export function fstatPromise(
77+
fd: number,
78+
options?: statOptions,
79+
): Stats | BigIntStats {
80+
return new Promise((resolve, reject) => {
81+
fstat(fd, options, (err, stats) => {
82+
if (err) reject(err);
83+
else resolve(stats);
84+
});
85+
});
86+
}

ext/node/polyfills/fs.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Dir from "ext:deno_node/_fs/_fs_dir.ts";
2323
import Dirent from "ext:deno_node/_fs/_fs_dirent.ts";
2424
import { exists, existsSync } from "ext:deno_node/_fs/_fs_exists.ts";
2525
import { fdatasync, fdatasyncSync } from "ext:deno_node/_fs/_fs_fdatasync.ts";
26-
import { fstat, fstatSync } from "ext:deno_node/_fs/_fs_fstat.ts";
26+
import { fstat, fstatPromise, fstatSync } from "ext:deno_node/_fs/_fs_fstat.ts";
2727
import { fsync, fsyncSync } from "ext:deno_node/_fs/_fs_fsync.ts";
2828
import { ftruncate, ftruncateSync } from "ext:deno_node/_fs/_fs_ftruncate.ts";
2929
import { futimes, futimesSync } from "ext:deno_node/_fs/_fs_futimes.ts";
@@ -174,6 +174,7 @@ const promises = {
174174
lstat: lstatPromise,
175175
stat: statPromise,
176176
statfs: statfsPromise,
177+
fstat: fstatPromise,
177178
link: linkPromise,
178179
unlink: unlinkPromise,
179180
chmod: chmodPromise,

ext/node/polyfills/fs/promises.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const readlink = fsPromises.readlink;
1616
export const symlink = fsPromises.symlink;
1717
export const lstat = fsPromises.lstat;
1818
export const stat = fsPromises.stat;
19+
export const fstat = fsPromises.fstat;
1920
export const link = fsPromises.link;
2021
export const unlink = fsPromises.unlink;
2122
export const chmod = fsPromises.chmod;

ext/node/polyfills/internal/fs/handle.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { EventEmitter } from "node:events";
77
import { Buffer } from "node:buffer";
88
import { promises, read, write } from "node:fs";
9+
export type { BigIntStats, Stats } from "ext:deno_node/_fs/_fs_stat.ts";
910
import {
1011
BinaryOptionsArgument,
1112
FileOptionsArgument,
@@ -141,6 +142,13 @@ export class FileHandle extends EventEmitter {
141142
// Note that Deno.close is not async
142143
return Promise.resolve(core.close(this.fd));
143144
}
145+
146+
stat(): Promise<Stats>;
147+
stat(options: { bigint: false }): Promise<Stats>;
148+
stat(options: { bigint: true }): Promise<BigIntStats>;
149+
stat(options?: { bigint: boolean }): Promise<Stats | BigIntStats> {
150+
return fsCall(promises.fstat, this, options);
151+
}
144152
}
145153

146154
function fsCall(fn, handle, ...args) {
@@ -152,7 +160,7 @@ function fsCall(fn, handle, ...args) {
152160
});
153161
}
154162

155-
return fn(handle, ...args);
163+
return fn(handle.fd, ...args);
156164
}
157165

158166
export default {

tests/unit_node/_fs/_fs_handle_test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,27 @@ Deno.test("[node/fs filehandle.write] Write from string", async function () {
9393
assertEquals(res.bytesWritten, 11);
9494
assertEquals(decoder.decode(data), "hello world");
9595
});
96+
97+
Deno.test("[node/fs filehandle.stat] Get file status", async function () {
98+
const fileHandle = await fs.open(testData);
99+
const stat = await fileHandle.stat();
100+
101+
assertEquals(stat.isFile(), true);
102+
assertEquals(stat.size, "hello world".length);
103+
104+
await fileHandle.close();
105+
});
106+
107+
Deno.test("[node/fs filehandle.writeFile] Write to file", async function () {
108+
const tempFile: string = await Deno.makeTempFile();
109+
const fileHandle = await fs.open(tempFile, "w");
110+
111+
const str = "hello world";
112+
await fileHandle.writeFile(str);
113+
114+
const data = Deno.readFileSync(tempFile);
115+
await Deno.remove(tempFile);
116+
await fileHandle.close();
117+
118+
assertEquals(decoder.decode(data), "hello world");
119+
});

0 commit comments

Comments
 (0)