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 { denoErrorToNodeError } from "ext:deno_node/internal/errors.ts";
|
||||||
import { promisify } from "ext:deno_node/internal/util.mjs";
|
import { promisify } from "ext:deno_node/internal/util.mjs";
|
||||||
|
import { primordials } from "ext:core/mod.js";
|
||||||
|
|
||||||
|
const { ObjectCreate, ObjectAssign } = primordials;
|
||||||
|
|
||||||
export type statOptions = {
|
export type statOptions = {
|
||||||
bigint: boolean;
|
bigint: boolean;
|
||||||
throwIfNoEntry?: boolean;
|
throwIfNoEntry?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Stats = {
|
interface IStats {
|
||||||
/** ID of the device containing the file.
|
/** ID of the device containing the file.
|
||||||
*
|
*
|
||||||
* _Linux/Mac OS only._ */
|
* _Linux/Mac OS only._ */
|
||||||
|
@ -80,9 +83,84 @@ export type Stats = {
|
||||||
isFile: () => boolean;
|
isFile: () => boolean;
|
||||||
isSocket: () => boolean;
|
isSocket: () => boolean;
|
||||||
isSymbolicLink: () => 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.
|
/** ID of the device containing the file.
|
||||||
*
|
*
|
||||||
* _Linux/Mac OS only._ */
|
* _Linux/Mac OS only._ */
|
||||||
|
@ -159,10 +237,13 @@ export type BigIntStats = {
|
||||||
isFile: () => boolean;
|
isFile: () => boolean;
|
||||||
isSocket: () => boolean;
|
isSocket: () => boolean;
|
||||||
isSymbolicLink: () => boolean;
|
isSymbolicLink: () => boolean;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
export class BigIntStats {}
|
||||||
|
|
||||||
export function convertFileInfoToStats(origin: Deno.FileInfo): Stats {
|
export function convertFileInfoToStats(origin: Deno.FileInfo): Stats {
|
||||||
return {
|
const stats = ObjectCreate(Stats.prototype);
|
||||||
|
ObjectAssign(stats, {
|
||||||
dev: origin.dev,
|
dev: origin.dev,
|
||||||
ino: origin.ino,
|
ino: origin.ino,
|
||||||
mode: origin.mode,
|
mode: origin.mode,
|
||||||
|
@ -189,7 +270,9 @@ export function convertFileInfoToStats(origin: Deno.FileInfo): Stats {
|
||||||
isSocket: () => false,
|
isSocket: () => false,
|
||||||
ctime: origin.mtime,
|
ctime: origin.mtime,
|
||||||
ctimeMs: origin.mtime?.getTime() || null,
|
ctimeMs: origin.mtime?.getTime() || null,
|
||||||
};
|
});
|
||||||
|
|
||||||
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toBigInt(number?: number | null) {
|
function toBigInt(number?: number | null) {
|
||||||
|
@ -200,7 +283,8 @@ function toBigInt(number?: number | null) {
|
||||||
export function convertFileInfoToBigIntStats(
|
export function convertFileInfoToBigIntStats(
|
||||||
origin: Deno.FileInfo,
|
origin: Deno.FileInfo,
|
||||||
): BigIntStats {
|
): BigIntStats {
|
||||||
return {
|
const stats = ObjectCreate(BigIntStats.prototype);
|
||||||
|
ObjectAssign(stats, {
|
||||||
dev: toBigInt(origin.dev),
|
dev: toBigInt(origin.dev),
|
||||||
ino: toBigInt(origin.ino),
|
ino: toBigInt(origin.ino),
|
||||||
mode: toBigInt(origin.mode),
|
mode: toBigInt(origin.mode),
|
||||||
|
@ -233,7 +317,8 @@ export function convertFileInfoToBigIntStats(
|
||||||
ctime: origin.mtime,
|
ctime: origin.mtime,
|
||||||
ctimeMs: origin.mtime ? BigInt(origin.mtime.getTime()) : null,
|
ctimeMs: origin.mtime ? BigInt(origin.mtime.getTime()) : null,
|
||||||
ctimeNs: origin.mtime ? BigInt(origin.mtime.getTime()) * 1000000n : null,
|
ctimeNs: origin.mtime ? BigInt(origin.mtime.getTime()) * 1000000n : null,
|
||||||
};
|
});
|
||||||
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
// shortcut for Convert File Info to Stats or BigIntStats
|
// 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 { getValidatedPath } from "ext:deno_node/internal/fs/utils.mjs";
|
||||||
import { validateFunction } from "ext:deno_node/internal/validators.mjs";
|
import { validateFunction } from "ext:deno_node/internal/validators.mjs";
|
||||||
import { stat, Stats } from "ext:deno_node/_fs/_fs_stat.ts";
|
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 { Buffer } from "node:buffer";
|
||||||
import { delay } from "ext:deno_node/_util/async.ts";
|
import { delay } from "ext:deno_node/_util/async.ts";
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ const statAsync = async (filename: string): Promise<Stats | null> => {
|
||||||
return emptyStats;
|
return emptyStats;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const emptyStats = new StatsClass(
|
const emptyStats = new Stats(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -69,7 +69,12 @@ import {
|
||||||
} from "ext:deno_node/_fs/_fs_rename.ts";
|
} from "ext:deno_node/_fs/_fs_rename.ts";
|
||||||
import { rmdir, rmdirPromise, rmdirSync } from "ext:deno_node/_fs/_fs_rmdir.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 { 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 {
|
import {
|
||||||
symlink,
|
symlink,
|
||||||
symlinkPromise,
|
symlinkPromise,
|
||||||
|
@ -105,7 +110,6 @@ import {
|
||||||
writeFilePromise,
|
writeFilePromise,
|
||||||
writeFileSync,
|
writeFileSync,
|
||||||
} from "ext:deno_node/_fs/_fs_writeFile.ts";
|
} 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"
|
// @deno-types="./internal/fs/streams.d.ts"
|
||||||
import {
|
import {
|
||||||
createReadStream,
|
createReadStream,
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {
|
||||||
mkdtempSync,
|
mkdtempSync,
|
||||||
promises,
|
promises,
|
||||||
readFileSync,
|
readFileSync,
|
||||||
|
Stats,
|
||||||
|
statSync,
|
||||||
writeFileSync,
|
writeFileSync,
|
||||||
} from "node:fs";
|
} from "node:fs";
|
||||||
import { constants as fsPromiseConstants, cp } from "node:fs/promises";
|
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(
|
Deno.test(
|
||||||
"[node/fs/promises cp] copy file",
|
"[node/fs/promises cp] copy file",
|
||||||
async () => {
|
async () => {
|
||||||
|
|
Loading…
Reference in a new issue