@dr.pogodin/react-native-fs
Version:
Native filesystem access for React Native
341 lines (286 loc) • 13.2 kB
text/typescript
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
// Note: It would be better to have all these type definitions in a dedicated
// module, however as of its current version RN's Codegen does not seem to handle
// type imports correctly.
export type DownloadBeginCallbackResultT = {
jobId: number; // The download job ID, required if one wishes to cancel the download. See `stopDownload`.
statusCode: number; // The HTTP status code
contentLength: number; // The total size in bytes of the download resource
headers: StringMapT; // The HTTP response headers from the server
};
export type DownloadProgressCallbackResultT = {
jobId: number; // The download job ID, required if one wishes to cancel the download. See `stopDownload`.
contentLength: number; // The total size in bytes of the download resource
bytesWritten: number; // The number of bytes written to the file so far
};
/**
* These are options expected by native implementations of downloadFile()
* function.
*/
export type NativeDownloadFileOptionsT = {
jobId: number;
fromUrl: string; // URL to download file from
toFile: string; // Local filesystem path to save the file to
background: boolean; // Continue the download in the background after the app terminates (iOS only)
backgroundTimeout: number; // Maximum time (in milliseconds) to download an entire resource (iOS only, useful for timing out background downloads)
cacheable: boolean; // Whether the download can be stored in the shared NSURLCache (iOS only)
connectionTimeout: number; // only supported on Android yet
discretionary: boolean; // Allow the OS to control the timing and speed of the download to improve perceived performance (iOS only)
headers: StringMapT; // An object of headers to be passed to the server
progressDivider: number;
progressInterval: number;
readTimeout: number; // supported on Android and iOS
hasBeginCallback: boolean;
hasProgressCallback: boolean;
hasResumableCallback: boolean;
};
export type PickFileOptionsT = {
mimeTypes: string[];
};
export type DownloadFileOptionsT = {
fromUrl: string; // URL to download file from
toFile: string; // Local filesystem path to save the file to
background?: boolean; // Continue the download in the background after the app terminates (iOS only)
backgroundTimeout?: number; // Maximum time (in milliseconds) to download an entire resource (iOS only, useful for timing out background downloads)
cacheable?: boolean; // Whether the download can be stored in the shared NSURLCache (iOS only)
connectionTimeout?: number; // only supported on Android yet
discretionary?: boolean; // Allow the OS to control the timing and speed of the download to improve perceived performance (iOS only)
headers?: StringMapT; // An object of headers to be passed to the server
progressDivider?: number;
progressInterval?: number;
readTimeout?: number; // supported on Android and iOS
begin?: (res: DownloadBeginCallbackResultT) => void;
progress?: (res: DownloadProgressCallbackResultT) => void;
// TODO: Yeah, original typing did not have "res" argument at all,
// but the code using this type actually passes an argument to
// resumable. Should be double-checked, if we have this argument,
// or drop it.
resumable?: (res: unknown) => void; // only supported on iOS yet
};
export type DownloadResultT = {
jobId: number; // The download job ID, required if one wishes to cancel the download. See `stopDownload`.
statusCode: number; // The HTTP status code
bytesWritten: number; // The number of bytes written to the file
};
export type FileOptionsT = {
// iOS-specific.
NSFileProtectionKey?: string;
};
export type FSInfoResultT = {
totalSpace: number; // The total amount of storage space on the device (in bytes).
totalSpaceEx: number;
freeSpace: number; // The amount of available storage space on the device (in bytes).
freeSpaceEx: number;
};
export type StringMapT = { [key: string]: string };
export type MkdirOptionsT = {
// iOS-specific.
NSURLIsExcludedFromBackupKey?: boolean;
NSFileProtectionKey?: string;
};
export type ReadDirAssetsResItemT = {
name: string;
path: string;
size: number;
// TODO: Can't these be just values rather than methods?
// Ok.. the reason these are functions is that currently the library
// receives from native side "type" field, and then in JS side it compares
// it with system-dependent constant values for directory and file...
// in other words... this is an unnecessary complication.
isDirectory: () => boolean; // Is the file a directory?
isFile: () => boolean; // Is the file just a file?
};
// TODO: When it is used as return type of Androids readDirAssets()
// it is not so good, as there are no mtime and ctime fields in that case.
// Should have a dedicated type for that.
export type ReadDirResItemT = {
// Common.
mtime: Date | null; // The last modified date of the file
name: string; // The name of the item
path: string; // The absolute path to the item
size: number; // Size in bytes.
// TODO: Can't these be just values rather than methods?
// Ok.. the reason these are functions is that currently the library
// receives from native side "type" field, and then in JS side it compares
// it with system-dependent constant values for directory and file...
// in other words... this is an unnecessary complication.
isDirectory: () => boolean; // Is the file a directory?
isFile: () => boolean; // Is the file just a file?
// iOS-specific
ctime: Date | null; // The creation date of the file (iOS only)
};
// TODO: Essentially here StatResult is similar to ReadDirItem,
// but it does not contain Date fields, thus making it possible
// to pass it from native side, unlike ReadDirItem.
export type StatResultT = {
// TODO: why is this not documented?
name?: string; // The name of the item.
path: string; // The absolute path to the item
size: number; // Size in bytes
mode: number; // UNIX file mode
ctime: Date | number; // Created date
mtime: Date | number; // Last modified date
// In case of content uri this is the pointed file path,
// otherwise is the same as path.
originalFilepath: string;
// TODO: Can't these be just values?
isFile: () => boolean; // Is the file just a file?
isDirectory: () => boolean; // Is the file a directory?
// TODO: This is temporary addition,
// to make the code compile.
type?: number;
};
export type NativeReadDirResItemT = {
ctime: number;
mtime: number;
name: string;
path: string;
size: number;
type: string;
};
type NativeStatResultT = {
ctime: number; // Created date
mtime: number; // Last modified date
size: number; // Size in bytes
type: string;
mode: number; // UNIX file mode
// In case of content uri this is the pointed file path,
// otherwise is the same as path.
// TODO: This is not implemented on iOS
originalFilepath: string;
};
export type UploadFileItemT = {
name?: string; // Name of the file, if not defined then filename is used
filename: string; // Name of file
filepath: string; // Path to file
filetype?: string; // The mimetype of the file to be uploaded, if not defined it will get mimetype from `filepath` extension
};
export type UploadBeginCallbackArgT = {
jobId: number; // The upload job ID, required if one wishes to cancel the upload. See `stopUpload`.
};
export type UploadProgressCallbackArgT = {
jobId: number; // The upload job ID, required if one wishes to cancel the upload. See `stopUpload`.
totalBytesExpectedToSend: number; // The total number of bytes that will be sent to the server
totalBytesSent: number; // The number of bytes sent to the server
};
export type UploadFileOptionsT = {
toUrl: string; // URL to upload file to
binaryStreamOnly?: boolean; // Allow for binary data stream for file to be uploaded without extra headers, Default is 'false'
files: UploadFileItemT[]; // An array of objects with the file information to be uploaded.
headers?: StringMapT; // An object of headers to be passed to the server
fields?: StringMapT; // An object of fields to be passed to the server
method?: string; // Default is 'POST', supports 'POST' and 'PUT'
// TODO: Remove these future versions.
beginCallback?: (res: UploadBeginCallbackArgT) => void; // deprecated
progressCallback?: (res: UploadProgressCallbackArgT) => void; // deprecated
begin?: (res: UploadBeginCallbackArgT) => void;
progress?: (res: UploadProgressCallbackArgT) => void;
};
export type NativeUploadFileOptionsT = {
jobId: number;
toUrl: string; // URL to upload file to
binaryStreamOnly?: boolean; // Allow for binary data stream for file to be uploaded without extra headers, Default is 'false'
files: object[]; // An array of objects with the file information to be uploaded.
headers?: StringMapT; // An object of headers to be passed to the server
fields?: StringMapT; // An object of fields to be passed to the server
method?: string; // Default is 'POST', supports 'POST' and 'PUT'
hasBeginCallback: boolean;
hasProgressCallback: boolean;
};
export type UploadResultT = {
jobId: number; // The upload job ID, required if one wishes to cancel the upload. See `stopUpload`.
statusCode: number; // The HTTP status code
headers: StringMapT; // The HTTP response headers from the server
body: string; // The HTTP response body
};
type TouchOptions = {
ctime?: number;
mtime?: number;
};
export interface Spec extends TurboModule {
readonly getConstants: () => {
// System paths.
CachesDirectoryPath: string;
DocumentDirectoryPath: string;
DownloadDirectoryPath: string;
ExternalCachesDirectoryPath: string;
ExternalDirectoryPath: string;
ExternalStorageDirectoryPath: string;
MainBundlePath?: string; // not on Android
TemporaryDirectoryPath: string;
// File system entity types.
// TODO: At least on iOS there more file types we don't capture here:
// https://developer.apple.com/documentation/foundation/nsfileattributetype?language=objc
FileTypeRegular: string;
FileTypeDirectory: string;
// TODO: It was not declared in JS layer,
// but it is exported constant on Android. Do we need it?
DocumentDirectory: number;
// iOS-specific
LibraryDirectoryPath?: string;
// Windows-specific.
PicturesDirectoryPath?: string; // also on Android!
RoamingDirectoryPath?: string;
// NON-ANDROID-STUFF, AND NOT DOCUMENTED
FileProtectionKeys?: string;
};
addListener(event: string): void;
removeListeners(count: number): void;
// Common.
appendFile(path: string, b64: string): Promise<void>;
copyFile(from: string, into: string, options: FileOptionsT): Promise<void>;
downloadFile(options: NativeDownloadFileOptionsT): Promise<DownloadResultT>;
exists(path: string): Promise<boolean>;
getFSInfo(): Promise<FSInfoResultT>;
hash(path: string, algorithm: string): Promise<string>;
mkdir(path: string, options: MkdirOptionsT): Promise<void>;
moveFile(from: string, into: string, options: FileOptionsT): Promise<void>;
pickFile(options: PickFileOptionsT): Promise<string[]>;
read(path: string, length: number, position: number): Promise<string>;
readFile(path: string): Promise<string>;
// TODO: Not sure about the type of result here.
readDir(path: string): Promise<NativeReadDirResItemT[]>;
stat(path: string): Promise<NativeStatResultT>;
stopDownload(jobId: number): void;
stopUpload(jobId: number): void;
touch(path: string, options: TouchOptions): Promise<void>;
unlink(path: string): Promise<void>;
uploadFiles(options: NativeUploadFileOptionsT): Promise<UploadResultT>;
write(path: string, b64: string, position: number): Promise<void>;
writeFile(path: string, b64: string, options: FileOptionsT): Promise<void>;
// Android-specific.
copyFileAssets(from: string, into: string): Promise<void>;
copyFileRes(from: string, into: string): Promise<void>;
existsAssets(path: string): Promise<boolean>;
existsRes(path: string): Promise<boolean>;
getAllExternalFilesDirs(): Promise<string[]>;
readFileAssets(path: string): Promise<string>;
readFileRes(path: string): Promise<string>;
readDirAssets(path: string): Promise<NativeReadDirResItemT[]>;
scanFile(path: string): Promise<string | null>;
setReadable(
filepath: string,
readable: boolean,
ownerOnly: boolean,
): Promise<boolean>;
// iOS-specific.
copyAssetsFileIOS(
imageUri: string,
destPath: string,
width: number,
height: number,
scale: number,
compression: number,
resizeMode: string,
): Promise<string>;
copyAssetsVideoIOS(imageUri: string, destPath: string): Promise<string>;
completeHandlerIOS(jobId: number): void;
isResumable(jobId: number): Promise<boolean>;
pathForBundle(bundle: string): Promise<string>;
pathForGroup(group: string): Promise<string>;
resumeDownload(jobId: number): void;
// Windows-specific.
copyFolder(from: string, into: string): Promise<void>;
}
export default TurboModuleRegistry.getEnforcing<Spec>('ReactNativeFs');