UNPKG

expo-file-system

Version:

Provides access to the local file system on the device.

110 lines (100 loc) 3.96 kB
import ExpoFileSystem from './ExpoFileSystem'; import { File } from './File'; import type { WatchEvent, WatchOptions, WatchSubscription } from './FileSystemWatcher.types'; import { Paths } from './Paths'; import { FileSystemWatcher } from './internal/FileSystemWatcher'; /** * Represents a directory on the filesystem. * * A `Directory` instance can be created for any path, and does not need to exist on the filesystem during creation. * * The constructor accepts an array of strings that are joined to create the directory URI. The first argument can also be a `Directory` instance (like `Paths.cache`). * @example * ```ts * const directory = new Directory(Paths.cache, "subdirName"); * ``` */ export class Directory extends ExpoFileSystem.FileSystemDirectory { static pickDirectoryAsync: (initialUri?: string) => Promise<Directory>; /** * Creates an instance of a directory. It can be created for any path, and does not need to exist on the filesystem during creation. * * The constructor accepts an array of strings that are joined to create the directory URI. The first argument can also be a `Directory` instance (like `Paths.cache`). * @param uris An array of: `file:///` string URIs, `File` instances, and `Directory` instances representing an arbitrary location on the file system. * @example * ```ts * const directory = new Directory(Paths.cache, "subdirName"); * ``` */ constructor(...uris: (string | File | Directory)[]) { super(Paths.join(...uris)); this.validatePath(); } /* * Directory containing the file. */ get parentDirectory() { return new Directory(Paths.join(this.uri, '..')); } /** * Lists the contents of a directory. * Calling this method if the parent directory does not exist will throw an error. * @returns An array of `Directory` and `File` instances. */ override list(): (Directory | File)[] { return super .listAsRecords() .map(({ isDirectory, uri }) => (isDirectory ? new Directory(uri) : new File(uri))); } /** * Directory name. */ get name() { return Paths.basename(this.uri); } createFile(name: string, mimeType: string | null): File { return new File(super.createFile(name, mimeType).uri); } createDirectory(name: string): Directory { return new Directory(super.createDirectory(name).uri); } /** * Watches this directory for changes to its contents or the directory itself. * * Events are emitted when files or subdirectories are created, modified, deleted, or renamed * within this directory. On iOS, child changes are surfaced as a coarse-grained `modified` event * on the directory itself, so filtering for child-level `created`, `deleted`, or `renamed` events * is not reliable. The watcher automatically stops when the directory is deleted or renamed. * To stop watching manually, call `remove()` on the returned subscription. * * @param callback Invoked when a change is detected. Receives a `WatchEvent` describing what changed. * @param options Configuration for debouncing and filtering events. * @return A subscription handle. Call `remove()` to stop watching. * * @example * ```ts * const cacheDir = new Directory(Paths.cache); * const subscription = cacheDir.watch((event) => { * console.log(`${event.type}: ${event.target.uri}`); * }); * * // Later, stop watching: * subscription.remove(); * ``` */ watch( callback: (event: WatchEvent<File | Directory>) => void, options?: WatchOptions ): WatchSubscription { return new FileSystemWatcher<File | Directory>( this.uri, callback, options, (uri, isDirectory) => (isDirectory ? new Directory(uri) : new File(uri)) ); } } Directory.pickDirectoryAsync = async function (initialUri?: string) { const directory = (await ExpoFileSystem.pickDirectoryAsync(initialUri)).uri; return new Directory(directory); };