Files
Schnappix/node_modules/expo-file-system/src/FileSystem.ts
T

213 lines
7.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import ExpoFileSystem from './ExpoFileSystem';
import type { DownloadOptions, PathInfo } from './ExpoFileSystem.types';
import { PathUtilities } from './pathUtilities';
import { FileSystemReadableStreamSource, FileSystemWritableSink } from './streams';
export class Paths extends PathUtilities {
/**
* A property containing the cache directory a place to store files that can be deleted by the system when the device runs low on storage.
*/
static get cache() {
return new Directory(ExpoFileSystem.cacheDirectory);
}
/**
* A property containing the bundle directory the directory where assets bundled with the application are stored.
*/
static get bundle() {
return new Directory(ExpoFileSystem.bundleDirectory);
}
/**
* A property containing the document directory a place to store files that are safe from being deleted by the system.
*/
static get document() {
return new Directory(ExpoFileSystem.documentDirectory);
}
static get appleSharedContainers() {
const containers: Record<string, string> = ExpoFileSystem.appleSharedContainers ?? {};
const result: Record<string, Directory> = {};
for (const appGroupId in containers) {
if (containers[appGroupId]) {
result[appGroupId] = new Directory(containers[appGroupId]);
}
}
return result;
}
/**
* A property that represents the total space on device's internal storage, represented in bytes.
*/
static get totalDiskSpace() {
return ExpoFileSystem.totalDiskSpace;
}
/**
* A property that represents the available space on device's internal storage, represented in bytes.
*/
static get availableDiskSpace() {
return ExpoFileSystem.availableDiskSpace;
}
/**
* Returns an object that indicates if the specified path represents a directory.
*/
static info(...uris: string[]): PathInfo {
return ExpoFileSystem.info(uris.join('/'));
}
}
/**
* Represents a file on the filesystem.
*
* A `File` 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 file URI. The first argument can also be a `Directory` instance (like `Paths.cache`) or a `File` instance (which creates a new reference to the same file).
* @example
* ```ts
* const file = new File(Paths.cache, "subdirName", "file.txt");
* ```
*/
export class File extends ExpoFileSystem.FileSystemFile implements Blob {
/**
* Creates an instance of a file. 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 file URI. The first argument can also be a `Directory` instance (like `Paths.cache`) or a `File` instance (which creates a new reference to the same file).
* @param uris An array of: `file:///` string URIs, `File` instances, and `Directory` instances representing an arbitrary location on the file system.
* @example
* ```ts
* const file = new File(Paths.cache, "subdirName", "file.txt");
* ```
*/
constructor(...uris: (string | File | Directory)[]) {
super(Paths.join(...uris));
this.validatePath();
}
/*
* Directory containing the file.
*/
get parentDirectory() {
return new Directory(Paths.dirname(this.uri));
}
/**
* File extension.
* @example '.png'
*/
get extension() {
return Paths.extname(this.uri);
}
/**
* File name. Includes the extension.
*/
get name() {
return Paths.basename(this.uri);
}
readableStream() {
return new ReadableStream(new FileSystemReadableStreamSource(super.open()));
}
writableStream() {
return new WritableStream<Uint8Array>(new FileSystemWritableSink(super.open()));
}
async arrayBuffer(): Promise<ArrayBuffer> {
const bytes = await this.bytes();
return bytes.buffer as ArrayBuffer;
}
stream(): ReadableStream<Uint8Array<ArrayBuffer>> {
return this.readableStream();
}
slice(start?: number, end?: number, contentType?: string): Blob {
return new Blob([this.bytesSync().slice(start, end)], { type: contentType });
}
}
// Cannot use `static` keyword in class declaration because of a runtime error.
File.downloadFileAsync = async function downloadFileAsync(
url: string,
to: File | Directory,
options?: DownloadOptions
) {
const outputURI = await ExpoFileSystem.downloadFileAsync(url, to, options);
return new File(outputURI);
};
File.pickFileAsync = async function (initialUri?: string, mimeType?: string) {
const file = (await ExpoFileSystem.pickFileAsync(initialUri, mimeType)).uri;
return new File(file);
};
/**
* 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 {
/**
* 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)[] {
// We need to wrap it in the JS File/Directory classes, and returning SharedObjects in lists is not supported yet on Android.
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 {
// Wrapping with the JS child class for additional, JS-only methods.
return new File(super.createFile(name, mimeType).uri);
}
createDirectory(name: string): Directory {
return new Directory(super.createDirectory(name).uri);
}
}
Directory.pickDirectoryAsync = async function (initialUri?: string) {
const directory = (await ExpoFileSystem.pickDirectoryAsync(initialUri)).uri;
return new Directory(directory);
};