Skip to main content

@antithrow/node

Non-throwing wrappers around Node.js APIs. Each function mirrors its built-in counterpart but returns a ResultAsync instead of throwing or rejecting.

Errors are returned as NodeJS.ErrnoException from Node.js.

Installation

npm install @antithrow/node

fs/promises

Import from @antithrow/node/fs/promises for non-throwing wrappers around node:fs/promises.

File operations

readFile()

readFile(path: PathLike | FileHandle, options?: Options | null): ResultAsync<Buffer, NodeJS.ErrnoException>
readFile(path: PathLike | FileHandle, options: Options | BufferEncoding): ResultAsync<string, NodeJS.ErrnoException>

Reads the contents of a file. Returns a Buffer by default, or a string when an encoding is specified.

import { readFile } from "@antithrow/node/fs/promises";

const buf = await readFile("/tmp/data.bin");
// ok(Buffer) or err(NodeJS.ErrnoException)

const text = await readFile("/tmp/hello.txt", "utf-8");
// ok("Hello, world!") or err(NodeJS.ErrnoException)

writeFile()

writeFile(file: PathLike | FileHandle, data: string | ..., options?: Options | null): ResultAsync<void, NodeJS.ErrnoException>

Writes data to a file, replacing it if it already exists.

import { writeFile } from "@antithrow/node/fs/promises";

const result = await writeFile("/tmp/hello.txt", "Hello, world!");
// ok(undefined) or err(NodeJS.ErrnoException)

appendFile()

appendFile(path: PathLike | FileHandle, data: string | Uint8Array, options?: Options | null): ResultAsync<void, NodeJS.ErrnoException>

Appends data to a file.

import { appendFile } from "@antithrow/node/fs/promises";

const result = await appendFile("/tmp/log.txt", "new line\n");
// ok(undefined) or err(NodeJS.ErrnoException)

truncate()

truncate(path: PathLike, len?: number): ResultAsync<void, NodeJS.ErrnoException>

Truncates a file to a specified length.

import { truncate } from "@antithrow/node/fs/promises";

const result = await truncate("/tmp/data.bin", 100);
// ok(undefined) or err(NodeJS.ErrnoException)

open()

open(path: PathLike, flags?: string | number, mode?: Mode): ResultAsync<FileHandle, NodeJS.ErrnoException>

Opens a file and returns a FileHandle.

import { open } from "@antithrow/node/fs/promises";

const result = await open("/tmp/data.bin", "r");
// ok(FileHandle) or err(NodeJS.ErrnoException)

Directory operations

readdir()

readdir(path: PathLike, options?: Options | null): ResultAsync<string[], NodeJS.ErrnoException>
readdir(path: PathLike, options: { withFileTypes: true }): ResultAsync<Dirent[], NodeJS.ErrnoException>

Reads the contents of a directory.

import { readdir } from "@antithrow/node/fs/promises";

const result = await readdir("/tmp");
// ok(["file1.txt", "file2.txt"]) or err(NodeJS.ErrnoException)

const entries = await readdir("/tmp", { withFileTypes: true });
// ok(Dirent[]) or err(NodeJS.ErrnoException)

mkdir()

mkdir(path: PathLike, options: { recursive: true }): ResultAsync<string | undefined, NodeJS.ErrnoException>
mkdir(path: PathLike, options?: Mode | Options | null): ResultAsync<undefined, NodeJS.ErrnoException>

Creates a directory. When recursive is true, returns the first directory path created.

import { mkdir } from "@antithrow/node/fs/promises";

const result = await mkdir("/tmp/a/b/c", { recursive: true });
// ok("/tmp/a") or err(NodeJS.ErrnoException)

rmdir()

rmdir(path: PathLike): ResultAsync<void, NodeJS.ErrnoException>

Removes an empty directory.

import { rmdir } from "@antithrow/node/fs/promises";

const result = await rmdir("/tmp/mydir");
// ok(undefined) or err(NodeJS.ErrnoException)

rm()

rm(path: PathLike, options?: RmOptions): ResultAsync<void, NodeJS.ErrnoException>

Removes files and directories.

import { rm } from "@antithrow/node/fs/promises";

const result = await rm("/tmp/mydir", { recursive: true, force: true });
// ok(undefined) or err(NodeJS.ErrnoException)

mkdtemp()

mkdtemp(prefix: string, options?: Options | null): ResultAsync<string, NodeJS.ErrnoException>

Creates a unique temporary directory.

import { mkdtemp } from "@antithrow/node/fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";

const result = await mkdtemp(join(tmpdir(), "myapp-"));
// ok("/tmp/myapp-aBcDeF") or err(NodeJS.ErrnoException)

opendir()

opendir(path: PathLike, options?: OpenDirOptions): ResultAsync<Dir, NodeJS.ErrnoException>

Opens a directory for iterative reading.

import { opendir } from "@antithrow/node/fs/promises";

const result = await opendir("/tmp");
if (result.isOk()) {
for await (const dirent of result.value) {
console.log(dirent.name);
}
}

Copy & move

copyFile()

copyFile(src: PathLike, dest: PathLike, mode?: number): ResultAsync<void, NodeJS.ErrnoException>

Copies a file.

import { copyFile } from "@antithrow/node/fs/promises";

const result = await copyFile("/tmp/source.txt", "/tmp/dest.txt");
// ok(undefined) or err(NodeJS.ErrnoException)

cp()

cp(source: string | URL, destination: string | URL, opts?: CopyOptions): ResultAsync<void, NodeJS.ErrnoException>

Copies files and directories (supports recursive copy).

import { cp } from "@antithrow/node/fs/promises";

const result = await cp("/tmp/src-dir", "/tmp/dest-dir", { recursive: true });
// ok(undefined) or err(NodeJS.ErrnoException)

rename()

rename(oldPath: PathLike, newPath: PathLike): ResultAsync<void, NodeJS.ErrnoException>

Renames a file or directory.

import { rename } from "@antithrow/node/fs/promises";

const result = await rename("/tmp/old.txt", "/tmp/new.txt");
// ok(undefined) or err(NodeJS.ErrnoException)
link(existingPath: PathLike, newPath: PathLike): ResultAsync<void, NodeJS.ErrnoException>

Creates a hard link.

import { link } from "@antithrow/node/fs/promises";

const result = await link("/tmp/existing.txt", "/tmp/new-link.txt");
// ok(undefined) or err(NodeJS.ErrnoException)
symlink(target: PathLike, path: PathLike, type?: string | null): ResultAsync<void, NodeJS.ErrnoException>

Creates a symbolic link.

import { symlink } from "@antithrow/node/fs/promises";

const result = await symlink("/tmp/target", "/tmp/my-link");
// ok(undefined) or err(NodeJS.ErrnoException)
readlink(path: PathLike, options?: Options | null): ResultAsync<string, NodeJS.ErrnoException>

Reads the target of a symbolic link.

import { readlink } from "@antithrow/node/fs/promises";

const result = await readlink("/tmp/my-link");
// ok("/tmp/target") or err(NodeJS.ErrnoException)
unlink(path: PathLike): ResultAsync<void, NodeJS.ErrnoException>

Removes a file or symbolic link.

import { unlink } from "@antithrow/node/fs/promises";

const result = await unlink("/tmp/old-file.txt");
// ok(undefined) or err(NodeJS.ErrnoException)

realpath()

realpath(path: PathLike, options?: Options | null): ResultAsync<string, NodeJS.ErrnoException>

Resolves a path to its canonical absolute path.

import { realpath } from "@antithrow/node/fs/promises";

const result = await realpath("/tmp/../tmp/hello.txt");
// ok("/tmp/hello.txt") or err(NodeJS.ErrnoException)

Metadata

stat()

stat(path: PathLike, opts?: StatOptions): ResultAsync<Stats, NodeJS.ErrnoException>
stat(path: PathLike, opts: { bigint: true }): ResultAsync<BigIntStats, NodeJS.ErrnoException>

Returns file metadata.

import { stat } from "@antithrow/node/fs/promises";

const result = await stat("/tmp/hello.txt");
// ok(Stats) or err(NodeJS.ErrnoException)

lstat()

lstat(path: PathLike, opts?: StatOptions): ResultAsync<Stats, NodeJS.ErrnoException>

Like stat, but does not follow symbolic links.

import { lstat } from "@antithrow/node/fs/promises";

const result = await lstat("/tmp/my-link");
// ok(Stats) or err(NodeJS.ErrnoException)

statfs()

statfs(path: PathLike, opts?: StatFsOptions): ResultAsync<StatsFs, NodeJS.ErrnoException>

Returns filesystem statistics.

import { statfs } from "@antithrow/node/fs/promises";

const result = await statfs("/");
// ok(StatsFs) or err(NodeJS.ErrnoException)

access()

access(path: PathLike, mode?: number): ResultAsync<void, NodeJS.ErrnoException>

Tests whether a file is accessible.

import { access } from "@antithrow/node/fs/promises";
import { constants } from "node:fs";

const result = await access("/tmp/hello.txt", constants.R_OK);
// ok(undefined) or err(NodeJS.ErrnoException)

Permissions & ownership

chmod()

chmod(path: PathLike, mode: Mode): ResultAsync<void, NodeJS.ErrnoException>

Changes file permissions.

import { chmod } from "@antithrow/node/fs/promises";

const result = await chmod("/tmp/script.sh", 0o755);
// ok(undefined) or err(NodeJS.ErrnoException)

chown()

chown(path: PathLike, uid: number, gid: number): ResultAsync<void, NodeJS.ErrnoException>

Changes file ownership.

import { chown } from "@antithrow/node/fs/promises";

const result = await chown("/tmp/hello.txt", 1000, 1000);
// ok(undefined) or err(NodeJS.ErrnoException)

lchown()

lchown(path: PathLike, uid: number, gid: number): ResultAsync<void, NodeJS.ErrnoException>

Changes ownership on a symbolic link without dereferencing it.

import { lchown } from "@antithrow/node/fs/promises";

const result = await lchown("/tmp/my-link", 1000, 1000);
// ok(undefined) or err(NodeJS.ErrnoException)

Timestamps

utimes()

utimes(path: PathLike, atime: TimeLike, mtime: TimeLike): ResultAsync<void, NodeJS.ErrnoException>

Changes file access and modification times.

import { utimes } from "@antithrow/node/fs/promises";

const now = new Date();
const result = await utimes("/tmp/hello.txt", now, now);
// ok(undefined) or err(NodeJS.ErrnoException)

lutimes()

lutimes(path: PathLike, atime: TimeLike, mtime: TimeLike): ResultAsync<void, NodeJS.ErrnoException>

Like utimes, but does not follow symbolic links.

import { lutimes } from "@antithrow/node/fs/promises";

const now = new Date();
const result = await lutimes("/tmp/my-link", now, now);
// ok(undefined) or err(NodeJS.ErrnoException)

os

Import from @antithrow/node/os for non-throwing wrappers around node:os functions that can throw. These are synchronous and return Result (not ResultAsync).

Errors are returned as SystemError — a Node.js error class where code is "ERR_SYSTEM_ERROR" and the POSIX error code lives in error.info.code. The SystemError interface is exported from @antithrow/node/os.

System info

homedir()

homedir(): Result<string, SystemError>

Returns the current user's home directory path.

import { homedir } from "@antithrow/node/os";

const result = homedir();
// ok("/home/user") or err(SystemError)

hostname()

hostname(): Result<string, SystemError>

Returns the host name of the operating system.

import { hostname } from "@antithrow/node/os";

const result = hostname();
// ok("my-machine") or err(SystemError)

uptime()

uptime(): Result<number, SystemError>

Returns the system uptime in seconds.

import { uptime } from "@antithrow/node/os";

const result = uptime();
// ok(123456) or err(SystemError)

Network

networkInterfaces()

networkInterfaces(): Result<NodeJS.Dict<NetworkInterfaceInfo[]>, SystemError>

Returns an object containing network interfaces with assigned addresses.

import { networkInterfaces } from "@antithrow/node/os";

const result = networkInterfaces();
// ok({ lo: [...], eth0: [...] }) or err(SystemError)

User info

userInfo()

userInfo(options?: UserInfoOptionsWithStringEncoding): Result<UserInfo<string>, SystemError>
userInfo(options: UserInfoOptionsWithBufferEncoding): Result<UserInfo<Buffer>, SystemError>
userInfo(options: UserInfoOptions): Result<UserInfo<string | Buffer>, SystemError>

Returns information about the currently effective user.

import { userInfo } from "@antithrow/node/os";

const result = userInfo();
// ok({ username: "user", uid: 1000, ... }) or err(SystemError)

Process priority

getPriority()

getPriority(pid?: number): Result<number, SystemError>

Returns the scheduling priority for the process specified by pid. Defaults to the current process.

import { getPriority } from "@antithrow/node/os";

const result = getPriority();
// ok(0) or err(SystemError)

setPriority()

setPriority(priority: number): Result<void, SystemError | RangeError>
setPriority(pid: number, priority: number): Result<void, SystemError | RangeError>

Sets the scheduling priority for a process. Priority must be between -20 (high) and 19 (low). Throws a RangeError if the priority is outside the valid int32 range.

import { setPriority } from "@antithrow/node/os";

const result = setPriority(10);
// ok(undefined) or err(SystemError | RangeError)