Capabilities
What a driver supports — declared where it cannot be guessed, inferred from the methods where it can, and never faked.
import { resolveCapabilities } from "mountx";
import type { FsCapabilities, MountxExtensions, ResolvedCapabilities } from "mountx";#FsCapabilities
interface FsCapabilities {
handles?: boolean; // open() returns real per-open state that survives unlink
hardlinks?: boolean; // link() works and nlink is counted
symlinks?: boolean; // symlink()/readlink() work; lstat differs from stat
permissions?: boolean; // mode and ownership bits are stored and returned
times?: boolean; // utimes() is stored and returned
truncate?: boolean; // truncate() and FileHandle.truncate() work
atomicRename?: boolean; // rename() replaces the destination atomically
caseSensitive?: boolean; // names differing only in case are distinct
statfs?: boolean; // statfs() returns meaningful numbers
readOnly?: boolean; // every mutating operation answers EROFS
extensions?: readonly (keyof MountxExtensions)[];
}Unset means infer it, never false. The inference rules, member by member, are in Writing a driver; handles and atomicRename are the two that cannot be inferred and default to false.
An unmet capability answers ENOSYS/ENOTSUP. It is never silently pretended — that is an invariant of the project, not a default.
#resolveCapabilities(driver)
function resolveCapabilities(driver: FsDriver): ResolvedCapabilities;Declarations win; the presence of a method is the fallback. ResolvedCapabilities has every member decided, and it is what createLoopback() exposes as fs.capabilities.
#MountxExtensions
The optional driver.mountx namespace, for what node:fs genuinely does not cover: utimens, mknod, getxattr, setxattr, listxattr, removexattr.
Types only for now — no transport implements them yet, and transports probe for each member and degrade without it. Deliberately just the path-shaped gaps: locks, fallocate, lseek and cache-invalidation notifies are per-open-file or session-scoped, so they get designed with the session layer rather than guessed at here.
#Next
- Loopback harness — where you check what got resolved.
- Driver interface — the methods the inference reads.