mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
fix(node): stat/statSync returns instance of fs.Stats (#22294)
Fixes https://github.com/denoland/deno/issues/22291 --------- Signed-off-by: Divy Srivastava <dj.srivastava23@gmail.com>
This commit is contained in:
parent
156950828e
commit
6ba0b7952d
4 changed files with 111 additions and 12 deletions
|
@ -5,13 +5,16 @@
|
|||
|
||||
import { denoErrorToNodeError } from "ext:deno_node/internal/errors.ts";
|
||||
import { promisify } from "ext:deno_node/internal/util.mjs";
|
||||
import { primordials } from "ext:core/mod.js";
|
||||
|
||||
const { ObjectCreate, ObjectAssign } = primordials;
|
||||
|
||||
export type statOptions = {
|
||||
bigint: boolean;
|
||||
throwIfNoEntry?: boolean;
|
||||
};
|
||||
|
||||
export type Stats = {
|
||||
interface IStats {
|
||||
/** ID of the device containing the file.
|
||||
*
|
||||
* _Linux/Mac OS only._ */
|
||||
|
@ -80,9 +83,84 @@ export type Stats = {
|
|||
isFile: () => boolean;
|
||||
isSocket: () => boolean;
|
||||
isSymbolicLink: () => boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export type BigIntStats = {
|
||||
class StatsBase {
|
||||
constructor(
|
||||
dev,
|
||||
mode,
|
||||
nlink,
|
||||
uid,
|
||||
gid,
|
||||
rdev,
|
||||
blksize,
|
||||
ino,
|
||||
size,
|
||||
blocks,
|
||||
) {
|
||||
this.dev = dev;
|
||||
this.mode = mode;
|
||||
this.nlink = nlink;
|
||||
this.uid = uid;
|
||||
this.gid = gid;
|
||||
this.rdev = rdev;
|
||||
this.blksize = blksize;
|
||||
this.ino = ino;
|
||||
this.size = size;
|
||||
this.blocks = blocks;
|
||||
}
|
||||
}
|
||||
|
||||
// The Date constructor performs Math.floor() to the timestamp.
|
||||
// https://www.ecma-international.org/ecma-262/#sec-timeclip
|
||||
// Since there may be a precision loss when the timestamp is
|
||||
// converted to a floating point number, we manually round
|
||||
// the timestamp here before passing it to Date().
|
||||
function dateFromMs(ms) {
|
||||
return new Date(Number(ms) + 0.5);
|
||||
}
|
||||
|
||||
export class Stats extends StatsBase {
|
||||
constructor(
|
||||
dev,
|
||||
mode,
|
||||
nlink,
|
||||
uid,
|
||||
gid,
|
||||
rdev,
|
||||
blksize,
|
||||
ino,
|
||||
size,
|
||||
blocks,
|
||||
atimeMs,
|
||||
mtimeMs,
|
||||
ctimeMs,
|
||||
birthtimeMs,
|
||||
) {
|
||||
super(
|
||||
dev,
|
||||
mode,
|
||||
nlink,
|
||||
uid,
|
||||
gid,
|
||||
rdev,
|
||||
blksize,
|
||||
ino,
|
||||
size,
|
||||
blocks,
|
||||
);
|
||||
this.atimeMs = atimeMs;
|
||||
this.mtimeMs = mtimeMs;
|
||||
this.ctimeMs = ctimeMs;
|
||||
this.birthtimeMs = birthtimeMs;
|
||||
this.atime = dateFromMs(atimeMs);
|
||||
this.mtime = dateFromMs(mtimeMs);
|
||||
this.ctime = dateFromMs(ctimeMs);
|
||||
this.birthtime = dateFromMs(birthtimeMs);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IBigIntStats {
|
||||
/** ID of the device containing the file.
|
||||
*
|
||||
* _Linux/Mac OS only._ */
|
||||
|
@ -159,10 +237,13 @@ export type BigIntStats = {
|
|||
isFile: () => boolean;
|
||||
isSocket: () => boolean;
|
||||
isSymbolicLink: () => boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export class BigIntStats {}
|
||||
|
||||
export function convertFileInfoToStats(origin: Deno.FileInfo): Stats {
|
||||
return {
|
||||
const stats = ObjectCreate(Stats.prototype);
|
||||
ObjectAssign(stats, {
|
||||
dev: origin.dev,
|
||||
ino: origin.ino,
|
||||
mode: origin.mode,
|
||||
|
@ -189,7 +270,9 @@ export function convertFileInfoToStats(origin: Deno.FileInfo): Stats {
|
|||
isSocket: () => false,
|
||||
ctime: origin.mtime,
|
||||
ctimeMs: origin.mtime?.getTime() || null,
|
||||
};
|
||||
});
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
function toBigInt(number?: number | null) {
|
||||
|
@ -200,7 +283,8 @@ function toBigInt(number?: number | null) {
|
|||
export function convertFileInfoToBigIntStats(
|
||||
origin: Deno.FileInfo,
|
||||
): BigIntStats {
|
||||
return {
|
||||
const stats = ObjectCreate(BigIntStats.prototype);
|
||||
ObjectAssign(stats, {
|
||||
dev: toBigInt(origin.dev),
|
||||
ino: toBigInt(origin.ino),
|
||||
mode: toBigInt(origin.mode),
|
||||
|
@ -233,7 +317,8 @@ export function convertFileInfoToBigIntStats(
|
|||
ctime: origin.mtime,
|
||||
ctimeMs: origin.mtime ? BigInt(origin.mtime.getTime()) : null,
|
||||
ctimeNs: origin.mtime ? BigInt(origin.mtime.getTime()) * 1000000n : null,
|
||||
};
|
||||
});
|
||||
return stats;
|
||||
}
|
||||
|
||||
// shortcut for Convert File Info to Stats or BigIntStats
|
||||
|
|
|
@ -10,7 +10,6 @@ import { promisify } from "node:util";
|
|||
import { getValidatedPath } from "ext:deno_node/internal/fs/utils.mjs";
|
||||
import { validateFunction } from "ext:deno_node/internal/validators.mjs";
|
||||
import { stat, Stats } from "ext:deno_node/_fs/_fs_stat.ts";
|
||||
import { Stats as StatsClass } from "ext:deno_node/internal/fs/utils.mjs";
|
||||
import { Buffer } from "node:buffer";
|
||||
import { delay } from "ext:deno_node/_util/async.ts";
|
||||
|
||||
|
@ -22,7 +21,7 @@ const statAsync = async (filename: string): Promise<Stats | null> => {
|
|||
return emptyStats;
|
||||
}
|
||||
};
|
||||
const emptyStats = new StatsClass(
|
||||
const emptyStats = new Stats(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
|
|
@ -69,7 +69,12 @@ import {
|
|||
} from "ext:deno_node/_fs/_fs_rename.ts";
|
||||
import { rmdir, rmdirPromise, rmdirSync } from "ext:deno_node/_fs/_fs_rmdir.ts";
|
||||
import { rm, rmPromise, rmSync } from "ext:deno_node/_fs/_fs_rm.ts";
|
||||
import { stat, statPromise, statSync } from "ext:deno_node/_fs/_fs_stat.ts";
|
||||
import {
|
||||
stat,
|
||||
statPromise,
|
||||
Stats,
|
||||
statSync,
|
||||
} from "ext:deno_node/_fs/_fs_stat.ts";
|
||||
import {
|
||||
symlink,
|
||||
symlinkPromise,
|
||||
|
@ -105,7 +110,6 @@ import {
|
|||
writeFilePromise,
|
||||
writeFileSync,
|
||||
} from "ext:deno_node/_fs/_fs_writeFile.ts";
|
||||
import { Stats } from "ext:deno_node/internal/fs/utils.mjs";
|
||||
// @deno-types="./internal/fs/streams.d.ts"
|
||||
import {
|
||||
createReadStream,
|
||||
|
|
|
@ -9,6 +9,8 @@ import {
|
|||
mkdtempSync,
|
||||
promises,
|
||||
readFileSync,
|
||||
Stats,
|
||||
statSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { constants as fsPromiseConstants, cp } from "node:fs/promises";
|
||||
|
@ -97,6 +99,15 @@ Deno.test(
|
|||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
"[node/fs statSync] instanceof fs.Stats",
|
||||
() => {
|
||||
const stat = statSync("tests/testdata/assets/fixture.json");
|
||||
assert(stat);
|
||||
assert(stat instanceof Stats);
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
"[node/fs/promises cp] copy file",
|
||||
async () => {
|
||||
|
|
Loading…
Reference in a new issue