@ayonli/jsext
Version:
A JavaScript extension package for building strong and modern applications.
920 lines (919 loc) • 28.4 kB
TypeScript
/**
* Universal file system APIs for both server and browser applications.
*
* This module is guaranteed to work in the following environments:
*
* - Node.js
* - Deno
* - Bun
* - Modern browsers
* - Cloudflare Workers (limited support and experimental)
*
* We can also use the {@link runtime} function to check whether the runtime
* has file system support. When `runtime().fsSupport` is `true`, this module
* should work properly.
*
* In most browsers, this module uses the
* [Origin Private File System](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system).
* In Chromium browsers, this module can also access the device's local file
* system via `window.showOpenFilePicker()` and `window.showDirectoryPicker()`.
*
* This module also provides limited support for Cloudflare Workers, however it
* requires setting the `[site].bucket` option in the `wrangler.toml` file. Only
* the reading functions are supported, such as {@link readFile} and
* {@link readDir}, these functions allow us reading static files in the workers,
* writing functions is not implemented at the moment. More details about
* serving static assets in Cloudflare Workers can be found here:
* [Add static assets to an existing Workers project](https://developers.cloudflare.com/workers/configuration/sites/start-from-worker/).
*
* **Errors:**
*
* When a file system operation fails, this module throws an {@link Exception}
* with one of the following names:
*
* - `NotFoundError`: The file or directory does not exist.
* - `NotAllowedError`: The operation is not allowed, such as being blocked by
* the permission system.
* - `AlreadyExistsError`: The file or directory already exists.
* - `IsDirectoryError`: The path is a directory, not a file.
* - `NotDirectoryError`: The path is a file, not a directory.
* - `InvalidOperationError`: The operation is not supported, such as trying to
* copy a directory without the `recursive` option.
* - `BusyError`: The file is busy, such as being locked by another program.
* - `InterruptedError`: The operation is interrupted by the underlying file
* system.
* - `FileTooLargeError`: The file is too large, or the file system doesn't have
* enough space to store the new content.
* - `FilesystemLoopError`: Too many symbolic links were encountered when
* resolving the filename.
*
* Other errors may also be thrown by the runtime, such as `TypeError`.
*
* @experimental
* @module
*/
import type { FileInfo, DirEntry, FileSystemOptions, DirTree } from "./fs/types.ts";
export type { FileSystemOptions, FileInfo, DirEntry, DirTree };
/**
* @deprecated Use {@link FileSystemOptions} instead.
*/
export type CommonOptions = FileSystemOptions;
/**
* Platform-specific end-of-line marker. The value is `\r\n` in Windows
* server-side environments, and `\n` elsewhere.
*/
export declare const EOL: "\n" | "\r\n";
/**
* Options for the {@link getDirHandle} function.
*/
export interface GetDirOptions extends FileSystemOptions {
/**
* Create the directory if not exist.
*/
create?: boolean;
/**
* Used when `create` is `true`, recursively create the directory and its
* parent directories.
*/
recursive?: boolean;
}
/**
* Obtains the directory handle of the given path.
*
* NOTE: This function is only available in the browser.
*
* NOTE: If the `path` is not provided or is empty, the root directory handle
* will be returned.
*
* @example
* ```ts
* // with the default storage
* import { getDirHandle } from "@ayonli/jsext/fs";
*
* const dir = await getDirHandle("/path/to/dir");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { getDirHandle } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* const dir = await getDirHandle("/path/to/dir", { root });
* ```
*
* @example
* ```ts
* // create the directory if not exist
* import { getDirHandle } from "@ayonli/jsext/fs";
*
* const dir = await getDirHandle("/path/to/dir", { create: true, recursive: true });
* ```
*
* @example
* ```ts
* // return the root directory handle
* import { getDirHandle } from "@ayonli/jsext/fs";
*
* const root = await getDirHandle();
* ```
*/
export declare function getDirHandle(path?: string, options?: GetDirOptions): Promise<FileSystemDirectoryHandle>;
/**
* Options for the {@link getFileHandle} function.
*/
export interface GetFileOptions extends FileSystemOptions {
/**
* Create the file if not exist.
*/
create?: boolean;
}
/**
* Obtains the file handle of the given path.
*
* NOTE: This function is only available in the browser.
*
* @example
* ```ts
* // with the default storage
* import { getFileHandle } from "@ayonli/jsext/fs";
*
* const file = await getFileHandle("/path/to/file.txt");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { getFileHandle } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* const file = await getFileHandle("/path/to/file.txt", { root });
* ```
*
* @example
* ```ts
* // create the file if not exist
* import { getFileHandle } from "@ayonli/jsext/fs";
*
* const file = await getFileHandle("/path/to/file.txt", { create: true });
* ```
*/
export declare function getFileHandle(path: string, options?: GetFileOptions): Promise<FileSystemFileHandle>;
/**
* Checks if the given path exists.
*
* This function may throw an error if the path is invalid or the operation is
* not allowed.
*
* NOTE: This function can also be used in Cloudflare Workers.
*
* @example
* ```ts
* // with the default storage
* import { exists } from "@ayonli/jsext/fs";
*
* if (await exists("/path/to/file.txt")) {
* console.log("The file exists.");
* } else {
* console.log("The file does not exist.");
* }
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { exists } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
*
* if (await exists("/path/to/file.txt", { root })) {
* console.log("The file exists.");
* } else {
* console.log("The file does not exist.");
* }
* ```
*/
export declare function exists(path: string, options?: FileSystemOptions): Promise<boolean>;
/**
* Options for the {@link stat} function.
*/
export interface StatOptions extends FileSystemOptions {
/**
* Whether to follow the symbolic link.
* @default false
*/
followSymlink?: boolean;
}
/**
* Returns the information of the given file or directory.
*
* NOTE: This function can also be used in Cloudflare Workers.
*
* @example
* ```ts
* // with the default storage
* import { stat } from "@ayonli/jsext/fs";
*
* const info = await stat("/path/to/file.txt");
* console.log(`${info.name} is a ${info.kind}, its size is ${info.size} bytes, with MIME type ${info.type}.`);
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { stat } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* const info = await stat("/path/to/file.txt", { root });
* console.log(`${info.name} is a ${info.kind}, its size is ${info.size} bytes, with MIME type ${info.type}.`);
* ```
*/
export declare function stat(target: string | FileSystemFileHandle | FileSystemDirectoryHandle, options?: StatOptions): Promise<FileInfo>;
/**
* Options for the {@link mkdir} function.
*/
export interface MkdirOptions extends FileSystemOptions {
/**
* Whether to create parent directories if they do not exist.
*/
recursive?: boolean;
/**
* The permission mode of the directory.
*
* NOTE: This option is ignored in the browser and in Windows.
* @default 0o777
*/
mode?: number;
}
/**
* Creates a new directory with the given path.
*
* @example
* ```ts
* // with the default storage
* import { mkdir } from "@ayonli/jsext/fs";
*
* await mkdir("/path/to/dir");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { mkdir } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* await mkdir("/path/to/dir", { root });
* ```
*
* @example
* ```ts
* // create the directory and its parent directories if not exist
* import { mkdir } from "@ayonli/jsext/fs";
*
* await mkdir("/path/to/dir", { recursive: true });
* ```
*/
export declare function mkdir(path: string, options?: MkdirOptions): Promise<void>;
/**
* Ensures the directory exists, creating it (and any parent directory) if not.
*
* @example
* ```ts
* // with the default storage
* import { ensureDir } from "@ayonli/jsext/fs";
*
* await ensureDir("/path/to/dir");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { ensureDir } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* await ensureDir("/path/to/dir", { root });
* ```
*/
export declare function ensureDir(path: string, options?: Omit<MkdirOptions, "recursive">): Promise<void>;
/**
* Options for the {@link readDir} function.
*/
export interface ReadDirOptions extends FileSystemOptions {
/**
* Whether to read the sub-directories recursively.
*/
recursive?: boolean;
}
/**
* Reads the directory of the given path and iterates its entries.
*
* NOTE: The order of the entries is not guaranteed.
*
* NOTE: This function can also be used in Cloudflare Workers.
*
* @example
* ```ts
* // with the default storage
* import { readDir } from "@ayonli/jsext/fs";
*
* for await (const entry of readDir("/path/to/dir")) {
* console.log(`${entry.name} is a ${entry.kind}, its relative path is '${entry.relativePath}'.`);
* }
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { readDir } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* for await (const entry of readDir("/path/to/dir", { root })) {
* console.log(`${entry.name} is a ${entry.kind}, its relative path is '${entry.relativePath}'.`);
* }
* ```
*
* @example
* ```ts
* // read the sub-directories recursively
* import { readDir } from "@ayonli/jsext/fs";
*
* for await (const entry of readDir("/path/to/dir", { recursive: true })) {
* console.log(`${entry.name} is a ${entry.kind}, its relative path is '${entry.relativePath}'.`);
* }
* ```
*/
export declare function readDir(target: string | FileSystemDirectoryHandle, options?: ReadDirOptions): AsyncIterableIterator<DirEntry>;
/**
* Recursively reads the contents of the directory and transform them into a
* tree structure.
*
* NOTE: Unlike {@link readDir}, the order of the entries returned by this
* function is guaranteed, they are ordered first by kind (directories before
* files), then by names alphabetically.
*
* NOTE: This function can also be used in Cloudflare Workers.
*
* @example
* ```ts
* // with the default storage
* import { readTree } from "@ayonli/jsext/fs";
*
* const tree = await readTree("/path/to/dir");
* console.log(tree);
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { readTree } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* const tree = await readTree("/path/to/dir", { root });
* console.log(tree);
* ```
*/
export declare function readTree(target: string | FileSystemDirectoryHandle, options?: FileSystemOptions): Promise<DirTree>;
/**
* Options for file reading functions, such as {@link readFile},
* {@link readFileAsText} and {@link readFileAsFile}.
*/
export interface ReadFileOptions extends FileSystemOptions {
signal?: AbortSignal;
}
/**
* Reads the content of the given file in bytes.
*
* NOTE: This function can also be used in Cloudflare Workers.
*
* @example
* ```ts
* // with the default storage
* import { readFile } from "@ayonli/jsext/fs";
*
* const bytes = await readFile("/path/to/file.txt");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { readFile } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* const bytes = await readFile("/path/to/file.txt", { root });
* ```
*/
export declare function readFile(target: string | FileSystemFileHandle, options?: ReadFileOptions): Promise<Uint8Array>;
/**
* Reads the content of the given file as text with `utf-8` encoding.
*
* NOTE: This function can also be used in Cloudflare Workers.
*
* @example
* ```ts
* // with the default storage
* import { readFileAsText } from "@ayonli/jsext/fs";
*
* const text = await readFileAsText("/path/to/file.txt");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { readFileAsText } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* const text = await readFileAsText("/path/to/file.txt", { root });
* ```
*/
export declare function readFileAsText(target: string | FileSystemFileHandle, options?: ReadFileOptions): Promise<string>;
/**
* Reads the file as a `File` object.
*
* NOTE: This function can also be used in Cloudflare Workers.
*
* @example
* ```ts
* // with the default storage
* import { readFileAsFile } from "@ayonli/jsext/fs";
*
* const file = await readFileAsFile("/path/to/file.txt");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { readFileAsFile } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* const file = await readFileAsFile("/path/to/file.txt", { root });
* ```
*/
export declare function readFileAsFile(target: string | FileSystemFileHandle, options?: ReadFileOptions): Promise<File>;
/**
* Options for file writing functions, such as {@link writeFile} and {@link writeLines}.
*/
export interface WriteFileOptions extends FileSystemOptions {
/**
* Append the data to the file instead of overwriting it.
*/
append?: boolean;
/**
* Permissions always applied to file.
*
* NOTE: This option is ignored in the browser.
* @default 0o666
*/
mode?: number;
signal?: AbortSignal;
}
/**
* Writes the given data to the file.
*
* @example
* ```ts
* // with the default storage
* import { writeFile } from "@ayonli/jsext/fs";
*
* await writeFile("/path/to/file.txt", "Hello, world!");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { writeFile } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* await writeFile("/path/to/file.txt", "Hello, world!", { root });
* ```
*
* @example
* ```ts
* // append the data to the file
* import { writeFile } from "@ayonli/jsext/fs";
*
* await writeFile("/path/to/file.txt", "Hello, world!", { append: true });
* ```
*
* @example
* ```ts
* // write binary data to the file
* import { writeFile } from "@ayonli/jsext/fs";
* import bytes from "@ayonli/jsext/bytes";
*
* const data = bytes("Hello, world!");
* await writeFile("/path/to/file.txt", data)
* ```
*
* @example
* ```ts
* // write a blob to the file
* import { writeFile } from "@ayonli/jsext/fs";
*
* const blob = new Blob(["Hello, world!"], { type: "text/plain" });
* await writeFile("/path/to/file.txt", blob);
* ```
*
* @example
* ```ts
* // write a readable stream to the file
* import { writeFile } from "@ayonli/jsext/fs";
*
* const res = await fetch("https://example.com/file.txt");
* await writeFile("/path/to/file.txt", res.body!);
* ```
*/
export declare function writeFile(target: string | FileSystemFileHandle, data: string | ArrayBuffer | ArrayBufferView | ReadableStream<Uint8Array> | Blob, options?: WriteFileOptions): Promise<void>;
/**
* Writes multiple lines of content to the file.
*
* This function will automatically detect the line ending of the current
* content and use it to write the new lines. If the file is empty or does not
* exists (will be created automatically), it will use the system's default line
* ending to separate lines.
*
* This function will append a new line at the end of the final content, in
* appending mode, it will also prepend a line ending before the input lines if
* the current content doesn't ends with one.
*
* @example
* ```ts
* // with the default storage
* import { writeLines } from "@ayonli/jsext/fs";
*
* await writeLines("/path/to/file.txt", ["Hello", "World"]);
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { writeLines } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* await writeLines("/path/to/file.txt", ["Hello", "World"], { root });
* ```
*
* @example
* ```ts
* // append the lines to the file
* import { writeLines } from "@ayonli/jsext/fs";
*
* await writeLines("/path/to/file.txt", ["Hello", "World"], { append: true });
* ```
*/
export declare function writeLines(target: string | FileSystemFileHandle, lines: string[], options?: WriteFileOptions): Promise<void>;
/**
* Truncates (or extends) the file to reach the specified `size`. If `size` is
* not specified then the entire file contents are truncated.
*
* @example
* ```ts
* // with the default storage
* import { stat, truncate } from "@ayonli/jsext/fs";
*
* await truncate("/path/to/file.txt", 1024);
* const info = await stat("/path/to/file.txt");
* console.assert(info.size === 1024);
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { stat, truncate } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* await truncate("/path/to/file.txt", 1024, { root });
* const info = await stat("/path/to/file.txt", { root });
* console.assert(info.size === 1024);
* ```
*
* @example
* ```ts
* // truncate the file to zero size
* import { stat, truncate } from "@ayonli/jsext/fs";
*
* await truncate("/path/to/file.txt");
* const info = await stat("/path/to/file.txt");
* console.assert(info.size === 0);
* ```
*/
export declare function truncate(target: string | FileSystemFileHandle, size?: number, options?: FileSystemOptions): Promise<void>;
/**
* Options for the {@link remove} function.
*/
export interface RemoveOptions extends FileSystemOptions {
/**
* Whether to delete the sub-directories and files recursively. This option
* is required in order to remove a non-empty directory.
*/
recursive?: boolean;
}
/**
* Removes the file or directory of the given path from the file system.
*
* @example
* ```ts
* // with the default storage
* import { remove } from "@ayonli/jsext/fs";
*
* await remove("/path/to/file.txt");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { remove } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* await remove("/path/to/file.txt", { root });
* ```
*
* @example
* ```ts
* // remove the directory and its contents recursively
* import { remove } from "@ayonli/jsext/fs";
*
* await remove("/path/to/dir", { recursive: true });
* ```
*/
export declare function remove(path: string, options?: RemoveOptions): Promise<void>;
/**
* Renames the file or directory from the old path to the new path.
*
* @example
* ```ts
* // with the default storage
* import { rename } from "@ayonli/jsext/fs";
*
* await rename("/path/to/old.txt", "/path/to/new.txt");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { rename } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* await rename("/path/to/old.txt", "/path/to/new.txt", { root });
* ```
*/
export declare function rename(oldPath: string, newPath: string, options?: FileSystemOptions): Promise<void>;
/**
* Options for the {@link copy} function.
*/
export interface CopyOptions extends FileSystemOptions {
/**
* Whether to copy the directory recursively, which means to copy the
* directory and all its contents.
*/
recursive?: boolean;
}
/**
* Copies the file or directory (and its contents) from the old location to the
* new location.
*
* NOTE: If the old location is a file and the new location is a directory, the
* file will be copied into the new directory with the old name.
*
* NOTE: In Unix/Linux systems, when using the `cp -R` command to copy a path
* without an ending slash, the command will copy the directory itself into the
* new path if the new path already exists. This function does not have this
* behavior, it does not distinguish between a path with a trailing slash and a
* path without it. So when copying a directory, this function always copy its
* contents to the new path, whether the new path already exists or not.
*
* @example
* ```ts
* // with the default storage
* import { copy } from "@ayonli/jsext/fs";
*
* await copy("/path/to/old.txt", "/path/to/new.txt");
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { copy } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* await copy("/path/to/old.txt", "/path/to/new.txt", { root });
* ```
*
* @example
* ```ts
* // copy a directory and its contents recursively
* import { copy } from "@ayonli/jsext/fs";
*
* await copy("/path/to/dir", "/path/to/new", { recursive: true });
* ```
*
* @example
* ```ts
* // copy a file to a directory
* import { copy, exists } from "@ayonli/jsext/fs";
*
* await copy("/path/to/file.txt", "/path/to/dir");
* console.assert(await exists("/path/to/dir/file.txt"));
* ```
*/
export declare function copy(src: string, dest: string, options?: CopyOptions): Promise<void>;
/**
* @example
* ```ts
* // copy a file from the device's file system to the browser's file system (Chromium only)
* import { copy, getFileHandle } from "@ayonli/jsext/fs";
*
* const file1 = await window.showOpenFilePicker();
* const file2 = await getFileHandle("/path/to/file.txt");
*
* await copy(file1[0], file2);
* ```
*/
export declare function copy(src: FileSystemFileHandle, dest: FileSystemFileHandle | FileSystemDirectoryHandle): Promise<void>;
/**
* @example
* ```ts
* // copy a directory from the device's file system to the browser's file system (Chromium only)
* import { copy, getDirHandle } from "@ayonli/jsext/fs";
*
* const dir1 = await window.showDirectoryPicker();
* const dir2 = await getDirHandle("/path/to/dir");
*
* await copy(dir1, dir2, { recursive: true });
* ```
*/
export declare function copy(src: FileSystemDirectoryHandle, dest: FileSystemDirectoryHandle, options?: Pick<CopyOptions, "recursive">): Promise<void>;
/**
* Options for the {@link link} function.
*/
export interface LinkOptions {
/**
* Create a symbolic link instead of a hard link.
*/
symbolic?: boolean;
}
/**
* Creates a hard link (or symbolic link) from the source path to the destination
* path.
*
* NOTE: This function is only available in Node.js, Deno and Bun.
*
* @example
* ```ts
* // create a hard link
* import { link } from "@ayonli/jsext/fs";
*
* await link("/path/to/file.txt", "/path/to/link.txt");
* ```
*
* @example
* ```ts
* // create a symbolic link
* import { link } from "@ayonli/jsext/fs";
*
* await link("/path/to/file.txt", "/path/to/link.txt", { symbolic: true });
* ```
*/
export declare function link(src: string, dest: string, options?: LinkOptions): Promise<void>;
/**
* Returns the destination path of a symbolic link.
*
* NOTE: This function is only available in Node.js, Deno and Bun.
*
* @example
* ```ts
* import { readLink } from "@ayonli/jsext/fs";
*
* const dest = await readLink("/path/to/link.txt");
* console.log(dest);
* ```
*/
export declare function readLink(path: string): Promise<string>;
/**
* Changes the permission of the specified file or directory.
*
* The mode is a sequence of 3 octal numbers. The first/left-most number
* specifies the permissions for the owner. The second number specifies the
* permissions for the group. The last/right-most number specifies the
* permissions for others. For example, with a mode of 0o764, the owner (7) can
* read/write/execute, the group (6) can read/write and everyone else (4) can
* read only.
*
* | Number | Description |
* | ------ | ----------- |
* | 7 | read, write, and execute |
* | 6 | read and write |
* | 5 | read and execute |
* | 4 | read only |
* | 3 | write and execute |
* | 2 | write only |
* | 1 | execute only |
* | 0 | no permission |
*
* NOTE: This function is only available in Node.js, Deno and Bun, and only
* works in Unix/Linux systems, in other environments, it's a no-op.
*
* @example
* ```ts
* import { chmod } from "@ayonli/jsext/fs";
*
* // Change the file's permission to read/write for owner, read for group and others.
* await chmod("/path/to/file.txt", 0o644);
* ```
*/
export declare function chmod(path: string, mode: number): Promise<void>;
/**
* Changes the owner and group of the specified file or directory.
*
* NOTE: This function is only available in Node.js, Deno and Bun, and only
* works in Unix/Linux systems, in other environments, it's a no-op.
*
* @example
* ```ts
* import { chown } from "@ayonli/jsext/fs";
*
* // Change the owner and group of the file to root.
* await chown("/path/to/file.txt", 0, 0);
* ```
*/
export declare function chown(path: string, uid: number, gid: number): Promise<void>;
/**
* Changes the access (`atime`) and modification (`mtime`) times of the file
* or directory. Given times are either in seconds (UNIX epoch time) or as `Date`
* objects.
*
* NOTE: This function only works in Node.js, Deno and Bun, in other
* environments, it's a no-op.
*
* @example
* ```ts
* import { utimes } from "@ayonli/jsext/fs";
*
* // Set the access and modification times to the current time.
* await utimes("/path/to/file.txt", Date.now(), Date.now());
* ```
*/
export declare function utimes(path: string, atime: number | Date, mtime: number | Date): Promise<void>;
/**
* Creates a readable stream for the target file.
*
* NOTE: In Node.js, this function requires Node.js v18.0 or above.
*
* @example
* ```ts
* // with the default storage
* import { createReadableStream } from "@ayonli/jsext/fs";
* import { readAsText } from "@ayonli/jsext/reader";
*
* const input = createReadableStream("/path/to/file.txt");
*
* const text = await readAsText(input);
* console.log(text);
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { createReadableStream } from "@ayonli/jsext/fs";
* import { readAsText } from "@ayonli/jsext/reader";
*
* const root = await window.showDirectoryPicker();
* const input = createReadableStream("/path/to/file.txt", { root });
*
* const text = await readAsText(input);
* console.log(text);
* ```
*/
export declare function createReadableStream(target: string | FileSystemFileHandle, options?: FileSystemOptions): ReadableStream<Uint8Array>;
/**
* @deprecated use `createReadableStream` instead.
*/
export declare const readFileAsStream: typeof createReadableStream;
/**
* Creates a writable stream for the target file.
*
* NOTE: In Node.js, this function requires Node.js v18.0 or above.
*
* @example
* ```ts
* // with the default storage
* import { createWritableStream } from "@ayonli/jsext/fs";
*
* const output = createWritableStream("/path/to/file.txt");
* const res = await fetch("https://example.com/file.txt");
*
* await res.body!.pipeTo(output);
* ```
*
* @example
* ```ts
* // with a user-selected directory as root (Chromium only)
* import { createWritableStream } from "@ayonli/jsext/fs";
*
* const root = await window.showDirectoryPicker();
* const output = createWritableStream("/path/to/file.txt", { root });
* const res = await fetch("https://example.com/file.txt");
*
* await res.body!.pipeTo(output);
* ```
*/
export declare function createWritableStream(target: string | FileSystemFileHandle, options?: Omit<WriteFileOptions, "signal">): WritableStream<Uint8Array>;