API reference

files

Every export of @kitr/files, @kitr/files/react, @kitr/files/provider, @kitr/files/driver, @kitr/files/drivers/web, @kitr/files/drivers/electron, @kitr/files/drivers/tauri, @kitr/files/drivers/capacitor, read from the published type definitions. The guide shows them in use.

@kitr/files

acceptFor

function acceptFor(filters?: FileFilter[]): string;

The accept string an <input type="file"> needs for a set of filters.

capacitorFileStore

function capacitorFileStore(options?: {
  directory?: CapacitorDirectory;
}): CapacitorFileStore;

@capacitor/filesystem under one of the app's directories (data by default, which no other app can see). Paths are relative to that directory. For files the person chooses, use the files service's dialogs instead.

createCapacitorFilesDriver

function createCapacitorFilesDriver(_options?: DriverOptions): Driver;

Files driver for the Capacitor shell. open() shows the system document picker (@capawesome/capacitor-file-picker). Mobile has no "save as" dialog, so save() writes the file to the app's cache (@capacitor/filesystem) and opens the share sheet (@capacitor/share), where the person picks Save to Files, Drive, Mail and so on; it resolves to the file's URI, or null when the sheet is dismissed. reveal() hands a path to the share sheet.

createElectronFilesDriver

function createElectronFilesDriver(_options?: DriverOptions): ElectronFilesDriver;

The files driver for the Electron shell. Dialogs are Electron's dialog.showOpenDialog and showSaveDialog, run in the main process; the chosen files are read and written there with fs/promises. The window can only reach paths the person picked in a dialog this session (and anything inside a picked folder): main refuses every other path, so a compromised page cannot read your disk. Served over the kitr:files:* channels of handleKitrIpc().

Throws E_DRIVER_UNAVAILABLE when the preload bridge is missing (no exposeIpc() call).

createFiles

function createFiles(config?: FilesConfig, app?: KitrApp): Files;

Build the files service: the given driver, else the platform's, else selectDriver() for the runtime (the web driver in a browser, memory on the server, E_DRIVER_UNAVAILABLE in a native shell unless fallbackToWeb is set).

createMemoryFilesDriver

function createMemoryFilesDriver(queue?: PickedFile[]): FilesDriver & {
  queue: PickedFile[];
  saved: Array<{
    name: string;
    data: FileData;
  }>;
};

A driver for tests and the server: open returns what you queue, save records what was written.

createTauriFilesDriver

function createTauriFilesDriver(_options?: DriverOptions): Driver;

The files driver for the Tauri shell, on @tauri-apps/plugin-dialog (the dialogs) and @tauri-apps/plugin-fs (reading and writing what was chosen), with @tauri-apps/plugin-opener for reveal(). The plugins are imported on first use and are optional peers; a missing one makes the method that needs it reject with E_DRIVER_UNAVAILABLE. The dialog plugin adds each chosen path to the fs scope for the session, so the window reaches only what the person picked unless your capability file grants more.

createWebFilesDriver

function createWebFilesDriver(): FilesDriver;

File System Access API when available, <input type="file"> and a download link otherwise.

fromFile

function fromFile(file: File, path?: string): PickedFile;

Wrap a browser File (or any Blob with a name) as a PickedFile.

mimeFor

function mimeFor(name: string, fallback?: string): string;

The MIME type for a file name's extension, e.g. invoice.pdf → application/pdf. Unknown → fallback.

selectDriver

function selectDriver(runtime: Runtime, options?: DriverOptions): Driver;

The files driver for a runtime: the File System Access API (or <input type="file">) on web, a memory driver on the server, and each native shell's own dialogs. A shell with no driver yet throws E_DRIVER_UNAVAILABLE rather than falling back to the web one, unless fallbackToWeb is set.

toBlob

function toBlob(data: FileData, type: string): Blob;

Turn any FileData into a Blob of the given type. A Blob passes through unchanged.

useFiles

function useFiles(app: KitrApp): Files;

The files service from an app's container, for code outside React.

defineConfig

const defineConfig: <const C extends FilesConfig>(config: C) => C;

Type-checks config/files.ts. Returns the object unchanged.

CapacitorFileStore

interface CapacitorFileStore {
  /** Read a file as UTF-8 text. */
  readText(path: string): Promise<string>;
  /** Read a file as bytes. */
  readBytes(path: string): Promise<Uint8Array>;
  /** Write (and replace) a file, creating parent folders. Resolves to its URI. */
  write(path: string, data: FileData): Promise<string>;
  /** Delete a file. */
  remove(path: string): Promise<void>;
  /** The entries of a folder (the directory's root by default). */
  list(path?: string): Promise<FileEntry[]>;
  /** Size, type and modification time of a file or folder. */
  stat(path: string): Promise<FileEntry>;
  /** Whether the path exists. */
  exists(path: string): Promise<boolean>;
}

Read, write, delete, list and stat under the app's own directories (no dialogs).

ElectronFilesDriver

interface ElectronFilesDriver extends Driver {
  /** Show the folder dialog. Resolves to the chosen folder, or null when cancelled. */
  openDirectory(options?: {
    title?: string;
  }): Promise<PickedFolder | null>;
}

The Electron driver, with the folder dialog and directory calls only a desktop shell has.

FileEntry

interface FileEntry {
  name: string;
  type: 'file' | 'directory';
  /** Size in bytes. */
  size: number;
  /** Last change, in milliseconds since the epoch. */
  modifiedAt: number;
  /** A `file://` URI the system and other apps understand. */
  uri: string;
}

A file or folder in the app's storage, as list() and stat() report it.

FileFilter

/** A named group of extensions shown in a dialog's file-type menu, e.g. `Invoices (*.pdf)`. */
interface FileFilter {
  /** Shown in the dialog, e.g. `Images`. */
  name: string;
  /** Extensions without the dot, e.g. `['png', 'jpg']`. */
  extensions: string[];
}

A named group of extensions shown in a dialog's file-type menu, e.g. Invoices (*.pdf).

Files

interface Files {
  /** The driver in use. */
  readonly driver: FilesDriver;
  /** Show the open dialog. Resolves to [] when cancelled. */
  open(options?: OpenOptions): Promise<PickedFile[]>;
  /** Open exactly one file, or null when cancelled. */
  pick(options?: Omit<OpenOptions, 'multiple'>): Promise<PickedFile | null>;
  /** Save data where the person chooses. Resolves to the chosen name or path, or null when cancelled. */
  save(data: FileData, options: SaveOptions): Promise<string | null>;
  /** Open a path with the system's default app. Resolves without doing anything when the driver can't. */
  reveal(path: string): Promise<void>;
}

The files service bound in the container: open, pick and save through the active driver.

FilesConfig

interface FilesConfig {
  /** Use this driver instead of the platform's or the web one. Mostly for tests. */
  driver?: FilesDriver;
  /** Filters added to every dialog, e.g. the app's own document type. */
  filters?: FileFilter[];
  /**
   * In a native shell (Electron, Tauri, Capacitor) with no files driver, use the web driver inside
   * the WebView instead of throwing `E_DRIVER_UNAVAILABLE`. Default false.
   */
  fallbackToWeb?: boolean;
}

Options for config/files.ts.

FilesDriver

interface FilesDriver {
  /** Shown in devtools and on `files.driver.name`, e.g. `web` or `memory`. */
  name: string;
  /** Show the open dialog. Resolves to [] when cancelled. */
  open(options: OpenOptions): Promise<PickedFile[]>;
  /** Write data where the person chooses. Resolves to the chosen path/name, or null when cancelled. */
  save(data: FileData, options: SaveOptions): Promise<string | null>;
  /** Open a file with the system's default app, when the platform allows it. */
  reveal?(path: string): Promise<void>;
}

The dialogs behind the files service. A platform or a test supplies one; the web driver is the fallback.

OpenOptions

interface OpenOptions {
  /** File types to offer. Merged with the `filters` in `config/files.ts`. */
  filters?: FileFilter[];
  /** Let the person choose more than one file. Default false. */
  multiple?: boolean;
  /** Dialog title where the platform shows one. */
  title?: string;
}

Options for open() and pick().

PickedFile

interface PickedFile {
  /** File name with extension, without a directory. */
  name: string;
  /** Size in bytes. */
  size: number;
  /** MIME type, or `''` when the platform doesn't know it. */
  type: string;
  /** Absolute path on platforms that expose one (desktop, mobile). */
  path?: string;
  /** Read the content as UTF-8 text. */
  text(): Promise<string>;
  /** Read the content as bytes. */
  bytes(): Promise<Uint8Array>;
  /** Read the content as a Blob, e.g. to upload it. */
  blob(): Promise<Blob>;
}

A file the person chose, the same shape on every platform. Its content is read on demand.

PickedFolder

interface PickedFolder {
  /** Absolute path of the folder. */
  path: string;
  /** Its name. */
  name: string;
  /** The folder's entries; each file reads and writes like a picked one. Folders come back with `size` 0. */
  list(): Promise<PickedFile[]>;
}

A folder the person chose: list it, then read the files in it.

SaveOptions

interface SaveOptions {
  /** Suggested file name, with extension. */
  name: string;
  /** File types to offer. Merged with the `filters` in `config/files.ts`. */
  filters?: FileFilter[];
  /** Dialog title where the platform shows one. */
  title?: string;
  /** MIME type for the download fallback. Default from the extension or `application/octet-stream`. */
  type?: string;
}

Options for save(): the suggested name and, for the download fallback, the MIME type.

CapacitorDirectory

type CapacitorDirectory = 'data' | 'documents' | 'cache' | 'library' | 'external';

Which of the app's directories a path is under. data is private and backed up; cache may be cleared by the OS.

Driver

type Driver = FilesDriver;

What a files driver is: FilesDriver, whichever runtime supplies it.

DriverOptions

type DriverOptions = SelectDriverOptions;

Options of selectDriver().

FileData

type FileData = string | Blob | Uint8Array | ArrayBuffer;

What save() accepts: text, a Blob or File, or raw bytes.

@kitr/files/react

useDropFiles

function useDropFiles(onFiles: (files: PickedFile[]) => void): {
  over: boolean;
  onDragOver: (e: {
    preventDefault(): void;
  }) => void;
  onDragLeave: () => void;
  onDrop: (e: {
    preventDefault(): void;
    dataTransfer: DataTransfer | null;
  }) => Promise<void>;
};

Drag-and-drop handlers that hand dropped files over as PickedFiles.

useFileDialogs

function useFileDialogs(): {
  busy: boolean;
  open: (options?: OpenOptions | undefined) => Promise<PickedFile[]>;
  pick: (options?: Omit<OpenOptions, "multiple"> | undefined) => Promise<PickedFile | null>;
  save: (data: FileData, options: SaveOptions) => Promise<string | null>;
};

const { open, save, busy } = useFileDialogs(): the service with a busy flag while a dialog is up.

useFiles

function useFiles(): Files;

The files service from the app in context. Use useFileDialogs() when you want a busy flag.

@kitr/files/provider

filesProvider

const filesProvider: import("@kitr/core").KitrProvider;

Binds files to the native dialog driver a platform package registered (files capability), or the web driver. Nothing runs on the server beyond a no-op binding.

@kitr/files/driver

selectDriver

function selectDriver(runtime: Runtime, options?: DriverOptions): Driver;

The files driver for a runtime: the File System Access API (or <input type="file">) on web, a memory driver on the server, and each native shell's own dialogs. A shell with no driver yet throws E_DRIVER_UNAVAILABLE rather than falling back to the web one, unless fallbackToWeb is set.

Driver

type Driver = FilesDriver;

What a files driver is: FilesDriver, whichever runtime supplies it.

DriverOptions

type DriverOptions = SelectDriverOptions;

Options of selectDriver().

@kitr/files/drivers/web

createWebFilesDriver

function createWebFilesDriver(): FilesDriver;

File System Access API when available, <input type="file"> and a download link otherwise.

@kitr/files/drivers/electron

createElectronDriver

function createElectronDriver(_options?: DriverOptions): ElectronFilesDriver;

The files driver for the Electron shell. Dialogs are Electron's dialog.showOpenDialog and showSaveDialog, run in the main process; the chosen files are read and written there with fs/promises. The window can only reach paths the person picked in a dialog this session (and anything inside a picked folder): main refuses every other path, so a compromised page cannot read your disk. Served over the kitr:files:* channels of handleKitrIpc().

Throws E_DRIVER_UNAVAILABLE when the preload bridge is missing (no exposeIpc() call).

ElectronFilesDriver

interface ElectronFilesDriver extends Driver {
  /** Show the folder dialog. Resolves to the chosen folder, or null when cancelled. */
  openDirectory(options?: {
    title?: string;
  }): Promise<PickedFolder | null>;
}

The Electron driver, with the folder dialog and directory calls only a desktop shell has.

PickedFolder

interface PickedFolder {
  /** Absolute path of the folder. */
  path: string;
  /** Its name. */
  name: string;
  /** The folder's entries; each file reads and writes like a picked one. Folders come back with `size` 0. */
  list(): Promise<PickedFile[]>;
}

A folder the person chose: list it, then read the files in it.

@kitr/files/drivers/tauri

createTauriDriver

function createTauriDriver(_options?: DriverOptions): Driver;

The files driver for the Tauri shell, on @tauri-apps/plugin-dialog (the dialogs) and @tauri-apps/plugin-fs (reading and writing what was chosen), with @tauri-apps/plugin-opener for reveal(). The plugins are imported on first use and are optional peers; a missing one makes the method that needs it reject with E_DRIVER_UNAVAILABLE. The dialog plugin adds each chosen path to the fs scope for the session, so the window reaches only what the person picked unless your capability file grants more.

@kitr/files/drivers/capacitor

capacitorFileStore

function capacitorFileStore(options?: {
  directory?: CapacitorDirectory;
}): CapacitorFileStore;

@capacitor/filesystem under one of the app's directories (data by default, which no other app can see). Paths are relative to that directory. For files the person chooses, use the files service's dialogs instead.

createCapacitorDriver

function createCapacitorDriver(_options?: DriverOptions): Driver;

Files driver for the Capacitor shell. open() shows the system document picker (@capawesome/capacitor-file-picker). Mobile has no "save as" dialog, so save() writes the file to the app's cache (@capacitor/filesystem) and opens the share sheet (@capacitor/share), where the person picks Save to Files, Drive, Mail and so on; it resolves to the file's URI, or null when the sheet is dismissed. reveal() hands a path to the share sheet.

CapacitorFileStore

interface CapacitorFileStore {
  /** Read a file as UTF-8 text. */
  readText(path: string): Promise<string>;
  /** Read a file as bytes. */
  readBytes(path: string): Promise<Uint8Array>;
  /** Write (and replace) a file, creating parent folders. Resolves to its URI. */
  write(path: string, data: FileData): Promise<string>;
  /** Delete a file. */
  remove(path: string): Promise<void>;
  /** The entries of a folder (the directory's root by default). */
  list(path?: string): Promise<FileEntry[]>;
  /** Size, type and modification time of a file or folder. */
  stat(path: string): Promise<FileEntry>;
  /** Whether the path exists. */
  exists(path: string): Promise<boolean>;
}

Read, write, delete, list and stat under the app's own directories (no dialogs).

FileEntry

interface FileEntry {
  name: string;
  type: 'file' | 'directory';
  /** Size in bytes. */
  size: number;
  /** Last change, in milliseconds since the epoch. */
  modifiedAt: number;
  /** A `file://` URI the system and other apps understand. */
  uri: string;
}

A file or folder in the app's storage, as list() and stat() report it.

CapacitorDirectory

type CapacitorDirectory = 'data' | 'documents' | 'cache' | 'library' | 'external';

Which of the app's directories a path is under. data is private and backed up; cache may be cleared by the OS.