summaryrefslogtreecommitdiff
path: root/ext/node/polyfills/_fs/_fs_stat.ts
diff options
context:
space:
mode:
Diffstat (limited to 'ext/node/polyfills/_fs/_fs_stat.ts')
-rw-r--r--ext/node/polyfills/_fs/_fs_stat.ts314
1 files changed, 314 insertions, 0 deletions
diff --git a/ext/node/polyfills/_fs/_fs_stat.ts b/ext/node/polyfills/_fs/_fs_stat.ts
new file mode 100644
index 000000000..3a006084d
--- /dev/null
+++ b/ext/node/polyfills/_fs/_fs_stat.ts
@@ -0,0 +1,314 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+import { denoErrorToNodeError } from "internal:deno_node/polyfills/internal/errors.ts";
+import { promisify } from "internal:deno_node/polyfills/internal/util.mjs";
+
+export type statOptions = {
+ bigint: boolean;
+ throwIfNoEntry?: boolean;
+};
+
+export type Stats = {
+ /** ID of the device containing the file.
+ *
+ * _Linux/Mac OS only._ */
+ dev: number | null;
+ /** Inode number.
+ *
+ * _Linux/Mac OS only._ */
+ ino: number | null;
+ /** **UNSTABLE**: Match behavior with Go on Windows for `mode`.
+ *
+ * The underlying raw `st_mode` bits that contain the standard Unix
+ * permissions for this file/directory. */
+ mode: number | null;
+ /** Number of hard links pointing to this file.
+ *
+ * _Linux/Mac OS only._ */
+ nlink: number | null;
+ /** User ID of the owner of this file.
+ *
+ * _Linux/Mac OS only._ */
+ uid: number | null;
+ /** Group ID of the owner of this file.
+ *
+ * _Linux/Mac OS only._ */
+ gid: number | null;
+ /** Device ID of this file.
+ *
+ * _Linux/Mac OS only._ */
+ rdev: number | null;
+ /** The size of the file, in bytes. */
+ size: number;
+ /** Blocksize for filesystem I/O.
+ *
+ * _Linux/Mac OS only._ */
+ blksize: number | null;
+ /** Number of blocks allocated to the file, in 512-byte units.
+ *
+ * _Linux/Mac OS only._ */
+ blocks: number | null;
+ /** The last modification time of the file. This corresponds to the `mtime`
+ * field from `stat` on Linux/Mac OS and `ftLastWriteTime` on Windows. This
+ * may not be available on all platforms. */
+ mtime: Date | null;
+ /** The last access time of the file. This corresponds to the `atime`
+ * field from `stat` on Unix and `ftLastAccessTime` on Windows. This may not
+ * be available on all platforms. */
+ atime: Date | null;
+ /** The creation time of the file. This corresponds to the `birthtime`
+ * field from `stat` on Mac/BSD and `ftCreationTime` on Windows. This may
+ * not be available on all platforms. */
+ birthtime: Date | null;
+ /** change time */
+ ctime: Date | null;
+ /** atime in milliseconds */
+ atimeMs: number | null;
+ /** atime in milliseconds */
+ mtimeMs: number | null;
+ /** atime in milliseconds */
+ ctimeMs: number | null;
+ /** atime in milliseconds */
+ birthtimeMs: number | null;
+ isBlockDevice: () => boolean;
+ isCharacterDevice: () => boolean;
+ isDirectory: () => boolean;
+ isFIFO: () => boolean;
+ isFile: () => boolean;
+ isSocket: () => boolean;
+ isSymbolicLink: () => boolean;
+};
+
+export type BigIntStats = {
+ /** ID of the device containing the file.
+ *
+ * _Linux/Mac OS only._ */
+ dev: bigint | null;
+ /** Inode number.
+ *
+ * _Linux/Mac OS only._ */
+ ino: bigint | null;
+ /** **UNSTABLE**: Match behavior with Go on Windows for `mode`.
+ *
+ * The underlying raw `st_mode` bits that contain the standard Unix
+ * permissions for this file/directory. */
+ mode: bigint | null;
+ /** Number of hard links pointing to this file.
+ *
+ * _Linux/Mac OS only._ */
+ nlink: bigint | null;
+ /** User ID of the owner of this file.
+ *
+ * _Linux/Mac OS only._ */
+ uid: bigint | null;
+ /** Group ID of the owner of this file.
+ *
+ * _Linux/Mac OS only._ */
+ gid: bigint | null;
+ /** Device ID of this file.
+ *
+ * _Linux/Mac OS only._ */
+ rdev: bigint | null;
+ /** The size of the file, in bytes. */
+ size: bigint;
+ /** Blocksize for filesystem I/O.
+ *
+ * _Linux/Mac OS only._ */
+ blksize: bigint | null;
+ /** Number of blocks allocated to the file, in 512-byte units.
+ *
+ * _Linux/Mac OS only._ */
+ blocks: bigint | null;
+ /** The last modification time of the file. This corresponds to the `mtime`
+ * field from `stat` on Linux/Mac OS and `ftLastWriteTime` on Windows. This
+ * may not be available on all platforms. */
+ mtime: Date | null;
+ /** The last access time of the file. This corresponds to the `atime`
+ * field from `stat` on Unix and `ftLastAccessTime` on Windows. This may not
+ * be available on all platforms. */
+ atime: Date | null;
+ /** The creation time of the file. This corresponds to the `birthtime`
+ * field from `stat` on Mac/BSD and `ftCreationTime` on Windows. This may
+ * not be available on all platforms. */
+ birthtime: Date | null;
+ /** change time */
+ ctime: Date | null;
+ /** atime in milliseconds */
+ atimeMs: bigint | null;
+ /** atime in milliseconds */
+ mtimeMs: bigint | null;
+ /** atime in milliseconds */
+ ctimeMs: bigint | null;
+ /** atime in nanoseconds */
+ birthtimeMs: bigint | null;
+ /** atime in nanoseconds */
+ atimeNs: bigint | null;
+ /** atime in nanoseconds */
+ mtimeNs: bigint | null;
+ /** atime in nanoseconds */
+ ctimeNs: bigint | null;
+ /** atime in nanoseconds */
+ birthtimeNs: bigint | null;
+ isBlockDevice: () => boolean;
+ isCharacterDevice: () => boolean;
+ isDirectory: () => boolean;
+ isFIFO: () => boolean;
+ isFile: () => boolean;
+ isSocket: () => boolean;
+ isSymbolicLink: () => boolean;
+};
+
+export function convertFileInfoToStats(origin: Deno.FileInfo): Stats {
+ return {
+ dev: origin.dev,
+ ino: origin.ino,
+ mode: origin.mode,
+ nlink: origin.nlink,
+ uid: origin.uid,
+ gid: origin.gid,
+ rdev: origin.rdev,
+ size: origin.size,
+ blksize: origin.blksize,
+ blocks: origin.blocks,
+ mtime: origin.mtime,
+ atime: origin.atime,
+ birthtime: origin.birthtime,
+ mtimeMs: origin.mtime?.getTime() || null,
+ atimeMs: origin.atime?.getTime() || null,
+ birthtimeMs: origin.birthtime?.getTime() || null,
+ isFile: () => origin.isFile,
+ isDirectory: () => origin.isDirectory,
+ isSymbolicLink: () => origin.isSymlink,
+ // not sure about those
+ isBlockDevice: () => false,
+ isFIFO: () => false,
+ isCharacterDevice: () => false,
+ isSocket: () => false,
+ ctime: origin.mtime,
+ ctimeMs: origin.mtime?.getTime() || null,
+ };
+}
+
+function toBigInt(number?: number | null) {
+ if (number === null || number === undefined) return null;
+ return BigInt(number);
+}
+
+export function convertFileInfoToBigIntStats(
+ origin: Deno.FileInfo,
+): BigIntStats {
+ return {
+ dev: toBigInt(origin.dev),
+ ino: toBigInt(origin.ino),
+ mode: toBigInt(origin.mode),
+ nlink: toBigInt(origin.nlink),
+ uid: toBigInt(origin.uid),
+ gid: toBigInt(origin.gid),
+ rdev: toBigInt(origin.rdev),
+ size: toBigInt(origin.size) || 0n,
+ blksize: toBigInt(origin.blksize),
+ blocks: toBigInt(origin.blocks),
+ mtime: origin.mtime,
+ atime: origin.atime,
+ birthtime: origin.birthtime,
+ mtimeMs: origin.mtime ? BigInt(origin.mtime.getTime()) : null,
+ atimeMs: origin.atime ? BigInt(origin.atime.getTime()) : null,
+ birthtimeMs: origin.birthtime ? BigInt(origin.birthtime.getTime()) : null,
+ mtimeNs: origin.mtime ? BigInt(origin.mtime.getTime()) * 1000000n : null,
+ atimeNs: origin.atime ? BigInt(origin.atime.getTime()) * 1000000n : null,
+ birthtimeNs: origin.birthtime
+ ? BigInt(origin.birthtime.getTime()) * 1000000n
+ : null,
+ isFile: () => origin.isFile,
+ isDirectory: () => origin.isDirectory,
+ isSymbolicLink: () => origin.isSymlink,
+ // not sure about those
+ isBlockDevice: () => false,
+ isFIFO: () => false,
+ isCharacterDevice: () => false,
+ isSocket: () => false,
+ ctime: origin.mtime,
+ ctimeMs: origin.mtime ? BigInt(origin.mtime.getTime()) : null,
+ ctimeNs: origin.mtime ? BigInt(origin.mtime.getTime()) * 1000000n : null,
+ };
+}
+
+// shortcut for Convert File Info to Stats or BigIntStats
+export function CFISBIS(fileInfo: Deno.FileInfo, bigInt: boolean) {
+ if (bigInt) return convertFileInfoToBigIntStats(fileInfo);
+ return convertFileInfoToStats(fileInfo);
+}
+
+export type statCallbackBigInt = (err: Error | null, stat: BigIntStats) => void;
+
+export type statCallback = (err: Error | null, stat: Stats) => void;
+
+export function stat(path: string | URL, callback: statCallback): void;
+export function stat(
+ path: string | URL,
+ options: { bigint: false },
+ callback: statCallback,
+): void;
+export function stat(
+ path: string | URL,
+ options: { bigint: true },
+ callback: statCallbackBigInt,
+): void;
+export function stat(
+ path: string | URL,
+ optionsOrCallback: statCallback | statCallbackBigInt | statOptions,
+ maybeCallback?: statCallback | statCallbackBigInt,
+) {
+ const callback =
+ (typeof optionsOrCallback === "function"
+ ? optionsOrCallback
+ : maybeCallback) as (
+ ...args: [Error] | [null, BigIntStats | Stats]
+ ) => void;
+ const options = typeof optionsOrCallback === "object"
+ ? optionsOrCallback
+ : { bigint: false };
+
+ if (!callback) throw new Error("No callback function supplied");
+
+ Deno.stat(path).then(
+ (stat) => callback(null, CFISBIS(stat, options.bigint)),
+ (err) => callback(denoErrorToNodeError(err, { syscall: "stat" })),
+ );
+}
+
+export const statPromise = promisify(stat) as (
+ & ((path: string | URL) => Promise<Stats>)
+ & ((path: string | URL, options: { bigint: false }) => Promise<Stats>)
+ & ((path: string | URL, options: { bigint: true }) => Promise<BigIntStats>)
+);
+
+export function statSync(path: string | URL): Stats;
+export function statSync(
+ path: string | URL,
+ options: { bigint: false; throwIfNoEntry?: boolean },
+): Stats;
+export function statSync(
+ path: string | URL,
+ options: { bigint: true; throwIfNoEntry?: boolean },
+): BigIntStats;
+export function statSync(
+ path: string | URL,
+ options: statOptions = { bigint: false, throwIfNoEntry: true },
+): Stats | BigIntStats | undefined {
+ try {
+ const origin = Deno.statSync(path);
+ return CFISBIS(origin, options.bigint);
+ } catch (err) {
+ if (
+ options?.throwIfNoEntry === false &&
+ err instanceof Deno.errors.NotFound
+ ) {
+ return;
+ }
+ if (err instanceof Error) {
+ throw denoErrorToNodeError(err, { syscall: "stat" });
+ } else {
+ throw err;
+ }
+ }
+}