Made a few FilePath-like utility types

This commit is contained in:
Kir_Antipov 2023-01-25 17:15:33 +00:00
parent 3367d6a02d
commit 49ccf5b5a2
2 changed files with 153 additions and 0 deletions

67
src/utils/io/file-path.ts Normal file
View file

@ -0,0 +1,67 @@
import { PathLike } from "node:fs";
import { FileHandle } from "node:fs/promises";
/**
* Represents a file path for asynchronous (non-blocking) operations.
*/
export type AsyncFilePath = PathLike | FileHandle;
/**
* Represents a file path for synchronous (blocking) operations.
*/
export type SyncFilePath = PathLike | number;
/**
* Represents a file path.
*/
export type FilePath = AsyncFilePath | SyncFilePath;
/**
* Determines if the provided value is a valid {@link FilePath}.
*
* @param path - The value to check.
*
* @returns `true` if the value is a valid {@link FilePath}; otherwise, `false`.
*/
export function isFilePath(path: unknown): path is FilePath {
return (
typeof path === "string" ||
typeof path === "number" ||
typeof (path as URL)?.pathname === "string" ||
Buffer.isBuffer(path) ||
isFileHandle(path)
);
}
/**
* Determines if the provided value is a valid {@link AsyncFilePath}.
*
* @param path - The value to check.
*
* @returns `true` if the value is a valid {@link AsyncFilePath}; otherwise, `false`.
*/
export function isAsyncFilePath(path: unknown): path is AsyncFilePath {
return isFilePath(path) && typeof path !== "number";
}
/**
* Determines if the provided value is a valid {@link SyncFilePath}.
*
* @param path - The value to check.
*
* @returns `true` if the value is a valid {@link SyncFilePath}; otherwise, `false`.
*/
export function isSyncFilePath(path: unknown): path is SyncFilePath {
return isFilePath(path) && !isFileHandle(path);
}
/**
* Determines if the provided value is a valid {@link FileHandle}.
*
* @param path - The value to check.
*
* @returns `true` if the value is a valid {@link FileHandle}; otherwise, `false`.
*/
function isFileHandle(handle: unknown): handle is FileHandle {
return typeof (handle as FileHandle)?.fd === "number";
}

View file

@ -0,0 +1,86 @@
import { isAsyncFilePath, isFilePath, isSyncFilePath } from "@/utils/io/file-path";
import { FileHandle } from "node:fs/promises";
describe("isFilePath", () => {
test("returns true for string file paths", () => {
expect(isFilePath("path/to/file.txt")).toBe(true);
});
test("returns true for file descriptors", () => {
expect(isFilePath(123)).toBe(true);
});
test("returns true for URL file paths", () => {
expect(isFilePath(new URL("file:///path/to/file.txt"))).toBe(true);
});
test("returns true for Buffer file paths", () => {
expect(isFilePath(Buffer.from("path/to/file.txt"))).toBe(true);
});
test("returns true for file handles", () => {
expect(isFilePath({ fd: 1 } as FileHandle)).toBe(true);
});
test("returns false for invalid file paths", () => {
expect(isFilePath(null)).toBe(false);
expect(isFilePath(undefined)).toBe(false);
expect(isFilePath({})).toBe(false);
expect(isFilePath([])).toBe(false);
});
});
describe("isAsyncFilePath", () => {
test("returns true for string file paths", () => {
expect(isAsyncFilePath("path/to/file.txt")).toBe(true);
});
test("returns true for URL file paths", () => {
expect(isAsyncFilePath(new URL("file:///path/to/file.txt"))).toBe(true);
});
test("returns true for Buffer file paths", () => {
expect(isAsyncFilePath(Buffer.from("path/to/file.txt"))).toBe(true);
});
test("returns true for file handles", () => {
expect(isAsyncFilePath({ fd: 1 } as FileHandle)).toBe(true);
});
test("returns false for invalid file paths", () => {
expect(isAsyncFilePath(null)).toBe(false);
expect(isAsyncFilePath(undefined)).toBe(false);
expect(isAsyncFilePath({})).toBe(false);
expect(isAsyncFilePath([])).toBe(false);
expect(isAsyncFilePath(1)).toBe(false);
});
});
describe("isSyncFilePath", () => {
test("returns true for string file paths", () => {
expect(isSyncFilePath("path/to/file.txt")).toBe(true);
});
test("returns true for file descriptors", () => {
expect(isSyncFilePath(123)).toBe(true);
});
test("returns true for URL file paths", () => {
expect(isSyncFilePath(new URL("file:///path/to/file.txt"))).toBe(true);
});
test("returns true for Buffer file paths", () => {
expect(isSyncFilePath(Buffer.from("path/to/file.txt"))).toBe(true);
});
test("returns false for file handles", () => {
expect(isSyncFilePath({ fd: 1 } as FileHandle)).toBe(false);
});
test("returns false for invalid file paths", () => {
expect(isSyncFilePath(null)).toBe(false);
expect(isSyncFilePath(undefined)).toBe(false);
expect(isSyncFilePath({})).toBe(false);
expect(isSyncFilePath([])).toBe(false);
});
});