Skip to content

Commit

Permalink
fix(ext/node): add fs.promises.fstat and FileHandle#stat (#26719)
Browse files Browse the repository at this point in the history
Co-authored-by: Yoshiya Hinosawa <[email protected]>
  • Loading branch information
2 people authored and bartlomieju committed Nov 28, 2024
1 parent 9fce244 commit 3f0e7c6
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 2 deletions.
21 changes: 21 additions & 0 deletions ext/node/polyfills/_fs/_fs_fstat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,24 @@ export function fstatSync(
const origin = new FsFile(fd, Symbol.for("Deno.internal.FsFile")).statSync();
return CFISBIS(origin, options?.bigint || false);
}

export function fstatPromise(fd: number): Promise<Stats>;
export function fstatPromise(
fd: number,
options: { bigint: false },
): Promise<Stats>;
export function fstatPromise(
fd: number,
options: { bigint: true },
): Promise<BigIntStats>;
export function fstatPromise(
fd: number,
options?: statOptions,
): Stats | BigIntStats {
return new Promise((resolve, reject) => {
fstat(fd, options, (err, stats) => {
if (err) reject(err);
else resolve(stats);
});
});
}
3 changes: 2 additions & 1 deletion ext/node/polyfills/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import Dir from "ext:deno_node/_fs/_fs_dir.ts";
import Dirent from "ext:deno_node/_fs/_fs_dirent.ts";
import { exists, existsSync } from "ext:deno_node/_fs/_fs_exists.ts";
import { fdatasync, fdatasyncSync } from "ext:deno_node/_fs/_fs_fdatasync.ts";
import { fstat, fstatSync } from "ext:deno_node/_fs/_fs_fstat.ts";
import { fstat, fstatPromise, fstatSync } from "ext:deno_node/_fs/_fs_fstat.ts";
import { fsync, fsyncSync } from "ext:deno_node/_fs/_fs_fsync.ts";
import { ftruncate, ftruncateSync } from "ext:deno_node/_fs/_fs_ftruncate.ts";
import { futimes, futimesSync } from "ext:deno_node/_fs/_fs_futimes.ts";
Expand Down Expand Up @@ -174,6 +174,7 @@ const promises = {
lstat: lstatPromise,
stat: statPromise,
statfs: statfsPromise,
fstat: fstatPromise,
link: linkPromise,
unlink: unlinkPromise,
chmod: chmodPromise,
Expand Down
1 change: 1 addition & 0 deletions ext/node/polyfills/fs/promises.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const readlink = fsPromises.readlink;
export const symlink = fsPromises.symlink;
export const lstat = fsPromises.lstat;
export const stat = fsPromises.stat;
export const fstat = fsPromises.fstat;
export const link = fsPromises.link;
export const unlink = fsPromises.unlink;
export const chmod = fsPromises.chmod;
Expand Down
10 changes: 9 additions & 1 deletion ext/node/polyfills/internal/fs/handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { EventEmitter } from "node:events";
import { Buffer } from "node:buffer";
import { promises, read, write } from "node:fs";
export type { BigIntStats, Stats } from "ext:deno_node/_fs/_fs_stat.ts";
import {
BinaryOptionsArgument,
FileOptionsArgument,
Expand Down Expand Up @@ -141,6 +142,13 @@ export class FileHandle extends EventEmitter {
// Note that Deno.close is not async
return Promise.resolve(core.close(this.fd));
}

stat(): Promise<Stats>;
stat(options: { bigint: false }): Promise<Stats>;
stat(options: { bigint: true }): Promise<BigIntStats>;
stat(options?: { bigint: boolean }): Promise<Stats | BigIntStats> {
return fsCall(promises.fstat, this, options);
}
}

function fsCall(fn, handle, ...args) {
Expand All @@ -152,7 +160,7 @@ function fsCall(fn, handle, ...args) {
});
}

return fn(handle, ...args);
return fn(handle.fd, ...args);
}

export default {
Expand Down
24 changes: 24 additions & 0 deletions tests/unit_node/_fs/_fs_handle_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,27 @@ Deno.test("[node/fs filehandle.write] Write from string", async function () {
assertEquals(res.bytesWritten, 11);
assertEquals(decoder.decode(data), "hello world");
});

Deno.test("[node/fs filehandle.stat] Get file status", async function () {
const fileHandle = await fs.open(testData);
const stat = await fileHandle.stat();

assertEquals(stat.isFile(), true);
assertEquals(stat.size, "hello world".length);

await fileHandle.close();
});

Deno.test("[node/fs filehandle.writeFile] Write to file", async function () {
const tempFile: string = await Deno.makeTempFile();
const fileHandle = await fs.open(tempFile, "w");

const str = "hello world";
await fileHandle.writeFile(str);

const data = Deno.readFileSync(tempFile);
await Deno.remove(tempFile);
await fileHandle.close();

assertEquals(decoder.decode(data), "hello world");
});

0 comments on commit 3f0e7c6

Please sign in to comment.