import type { UUID } from 'node:crypto'; import type { ConstMap } from 'utilium'; import type { InodeLike } from './inode.js'; /** * Usage information about a file system * @category Internals * @internal */ export interface UsageInfo { /** * The total space */ totalSpace: number; /** * The available space */ freeSpace: number; /** * The optimal block size to use with the file system * @default 4096 */ blockSize?: number; /** * Total number of nodes available */ totalNodes?: number; /** * Number of free nodes available */ freeNodes?: number; } export type CaseFold = 'upper' | 'lower'; /** * Attributes that control how the file system interacts with the VFS. * No options are set by default. * @category Internals * @internal */ export interface FileSystemAttributes { /** * If set disables async file systems from preloading their contents. * This means *sync operations will not work* (unless the contents are cached) * It has no affect on sync file systems. */ no_async_preload: void; /** * Currently unused. In the future, this will disable caching. * Analogous to `S_DAX` on every file. */ no_cache: void; /** * If set, the file system should not be written to. * This should be set for read-only file systems. * Note this does NOT trigger EROFS errors; * writes will silently be dropped. */ no_write: void; /** * The FS is using the default implementation for `streamRead` * @internal */ default_stream_read: void; /** * The FS is using the default implementation for `streamWrite` * @internal */ default_stream_write: void; /** * Do not update access times. */ no_atime: void; /** * Ignore suid and sgid bits. * @todo Implement * @experimental */ no_suid: void; /** * Writes are synced at once * @experimental */ sync: void; /** * If set, the VFS layer will convert paths to lower/upper case. */ case_fold?: CaseFold; } /** * Options used when creating files and directories. * This weird naming and such is to preserve backward compatibility. * @category Internals * @internal */ export interface CreationOptions extends Partial { /** * The uid to create the file. * This is ignored if the FS supports setuid and the setuid bit is set */ uid: number; /** * The gid to create the file. * This is ignored if the FS supports setgid and the setgid bit is set */ gid: number; /** * The mode to create the file with. */ mode: number; } /** * Options for streaming operations * @category Internals * @internal */ export interface StreamOptions { start?: number; end?: number; autoClose?: boolean; } /** * Provides a consistent and easy to use internal API. * Default implementations for `exists` and `existsSync` are included. * If you are extending this class, note that every path is an absolute path and all arguments are present. * @category Internals * @internal */ export declare abstract class FileSystem { /** * A unique ID for this kind of file system. * Currently unused internally, but could be used for partition tables or something */ readonly type: number; /** * The name for this file system. * For example, tmpfs for an in memory one */ readonly name: string; label?: string; /** * The last place this file system was mounted * @internal @protected */ _mountPoint?: string; /** * The UUID of the file system. * @privateRemarks This is only used by `ioctl` * @internal @protected */ _uuid: UUID; get uuid(): UUID; /** * @see FileSystemAttributes */ readonly attributes: ConstMap & Map; constructor( /** * A unique ID for this kind of file system. * Currently unused internally, but could be used for partition tables or something */ type: number, /** * The name for this file system. * For example, tmpfs for an in memory one */ name: string); toString(): string; /** * Default implementation. * @todo Implement * @experimental */ usage(): UsageInfo; ready(): Promise; readySync(): void; abstract rename(oldPath: string, newPath: string): Promise; abstract renameSync(oldPath: string, newPath: string): void; abstract stat(path: string): Promise; abstract statSync(path: string): InodeLike; /** Modify metadata. */ abstract touch(path: string, metadata: Partial): Promise; /** Modify metadata. */ abstract touchSync(path: string, metadata: Partial): void; /** * Create the file at `path` with the given options. */ abstract createFile(path: string, options: CreationOptions): Promise; /** * Create the file at `path` with the given options. */ abstract createFileSync(path: string, options: CreationOptions): InodeLike; abstract unlink(path: string): Promise; abstract unlinkSync(path: string): void; abstract rmdir(path: string): Promise; abstract rmdirSync(path: string): void; abstract mkdir(path: string, options: CreationOptions): Promise; abstract mkdirSync(path: string, options: CreationOptions): InodeLike; abstract readdir(path: string): Promise; abstract readdirSync(path: string): string[]; /** * Test whether or not `path` exists. */ exists(path: string): Promise; /** * Test whether or not `path` exists. */ existsSync(path: string): boolean; abstract link(target: string, link: string): Promise; abstract linkSync(target: string, link: string): void; abstract sync(): Promise; abstract syncSync(): void; /** * Reads into a buffer * @param buffer The buffer to read into. You must set the `byteOffset` and `byteLength` appropriately! * @param start The offset into the file to start reading from * @param end The position in the file to stop reading */ abstract read(path: string, buffer: Uint8Array, start: number, end: number): Promise; /** * Reads into a buffer * @param buffer The buffer to read into. You must set the `byteOffset` and `byteLength` appropriately! * @param start The offset into the file to start reading from * @param end The position in the file to stop reading */ abstract readSync(path: string, buffer: Uint8Array, start: number, end: number): void; /** * Writes a buffer to a file * @param buffer The buffer to write. You must set the `byteOffset` and `byteLength` appropriately! * @param offset The offset in the file to start writing */ abstract write(path: string, buffer: Uint8Array, offset: number): Promise; /** * Writes a buffer to a file * @param buffer The buffer to write. You must set the `byteOffset` and `byteLength` appropriately! * @param offset The offset in the file to start writing */ abstract writeSync(path: string, buffer: Uint8Array, offset: number): void; /** * Read a file using a stream. * @privateRemarks The default implementation of `streamRead` uses "chunked" `read`s */ streamRead(path: string, options: StreamOptions): ReadableStream; /** * Write a file using stream. * @privateRemarks The default implementation of `streamWrite` uses "chunked" `write`s */ streamWrite(path: string, options: StreamOptions): WritableStream; }