18fbec2ecSAlan Hughesimport { EventEmitter, UnavailabilityError, uuidv4 } from 'expo-modules-core';
21da2f189STomasz Sapetaimport { Platform } from 'react-native';
379a5fc63SJames Ideimport ExponentFileSystem from './ExponentFileSystem';
46b7802baSBartosz Kaszubowskiimport { FileSystemSessionType, FileSystemUploadType, } from './FileSystem.types';
57e929553SEvan Baconif (!ExponentFileSystem) {
62307aaceSEvan Bacon    console.warn("No native ExponentFileSystem module found, are you sure the expo-file-system's module is linked properly?");
72307aaceSEvan Bacon}
88f6e1365SEvan Bacon// Prevent webpack from pruning this.
979a5fc63SJames Ideconst _unused = new EventEmitter(ExponentFileSystem); // eslint-disable-line
102307aaceSEvan Baconfunction normalizeEndingSlash(p) {
112307aaceSEvan Bacon    if (p != null) {
122307aaceSEvan Bacon        return p.replace(/\/*$/, '') + '/';
132307aaceSEvan Bacon    }
142307aaceSEvan Bacon    return null;
152307aaceSEvan Bacon}
166b7802baSBartosz Kaszubowski/**
176b7802baSBartosz Kaszubowski * `file://` URI pointing to the directory where user documents for this app will be stored.
186b7802baSBartosz Kaszubowski * Files stored here will remain until explicitly deleted by the app. Ends with a trailing `/`.
196b7802baSBartosz Kaszubowski * Example uses are for files the user saves that they expect to see again.
206b7802baSBartosz Kaszubowski */
217e929553SEvan Baconexport const documentDirectory = normalizeEndingSlash(ExponentFileSystem.documentDirectory);
226b7802baSBartosz Kaszubowski/**
236b7802baSBartosz Kaszubowski * `file://` URI pointing to the directory where temporary files used by this app will be stored.
246b7802baSBartosz Kaszubowski * Files stored here may be automatically deleted by the system when low on storage.
256b7802baSBartosz Kaszubowski * Example uses are for downloaded or generated files that the app just needs for one-time usage.
266b7802baSBartosz Kaszubowski */
277e929553SEvan Baconexport const cacheDirectory = normalizeEndingSlash(ExponentFileSystem.cacheDirectory);
286b7802baSBartosz Kaszubowski// @docsMissing
297e929553SEvan Baconexport const { bundledAssets, bundleDirectory } = ExponentFileSystem;
306b7802baSBartosz Kaszubowski/**
316b7802baSBartosz Kaszubowski * Get metadata information about a file, directory or external content/asset.
326b7802baSBartosz Kaszubowski * @param fileUri URI to the file or directory. See [supported URI schemes](#supported-uri-schemes).
33*1902997cSDouglas Lowder * @param options A map of options represented by [`InfoOptions`](#infooptions) type.
346b7802baSBartosz Kaszubowski * @return A Promise that resolves to a `FileInfo` object. If no item exists at this URI,
356b7802baSBartosz Kaszubowski * the returned Promise resolves to `FileInfo` object in form of `{ exists: false, isDirectory: false }`.
366b7802baSBartosz Kaszubowski */
372307aaceSEvan Baconexport async function getInfoAsync(fileUri, options = {}) {
387e929553SEvan Bacon    if (!ExponentFileSystem.getInfoAsync) {
392307aaceSEvan Bacon        throw new UnavailabilityError('expo-file-system', 'getInfoAsync');
402307aaceSEvan Bacon    }
417e929553SEvan Bacon    return await ExponentFileSystem.getInfoAsync(fileUri, options);
422307aaceSEvan Bacon}
436b7802baSBartosz Kaszubowski/**
446b7802baSBartosz Kaszubowski * Read the entire contents of a file as a string. Binary will be returned in raw format, you will need to append `data:image/png;base64,` to use it as Base64.
456b7802baSBartosz Kaszubowski * @param fileUri `file://` or [SAF](#saf-uri) URI to the file or directory.
466b7802baSBartosz Kaszubowski * @param options A map of read options represented by [`ReadingOptions`](#readingoptions) type.
476b7802baSBartosz Kaszubowski * @return A Promise that resolves to a string containing the entire contents of the file.
486b7802baSBartosz Kaszubowski */
496b7802baSBartosz Kaszubowskiexport async function readAsStringAsync(fileUri, options = {}) {
507e929553SEvan Bacon    if (!ExponentFileSystem.readAsStringAsync) {
512307aaceSEvan Bacon        throw new UnavailabilityError('expo-file-system', 'readAsStringAsync');
522307aaceSEvan Bacon    }
536b7802baSBartosz Kaszubowski    return await ExponentFileSystem.readAsStringAsync(fileUri, options);
542307aaceSEvan Bacon}
556b7802baSBartosz Kaszubowski/**
566b7802baSBartosz Kaszubowski * Takes a `file://` URI and converts it into content URI (`content://`) so that it can be accessed by other applications outside of Expo.
576b7802baSBartosz Kaszubowski * @param fileUri The local URI of the file. If there is no file at this URI, an exception will be thrown.
586b7802baSBartosz Kaszubowski * @example
596b7802baSBartosz Kaszubowski * ```js
606b7802baSBartosz Kaszubowski * FileSystem.getContentUriAsync(uri).then(cUri => {
616b7802baSBartosz Kaszubowski *   console.log(cUri);
626b7802baSBartosz Kaszubowski *   IntentLauncher.startActivityAsync('android.intent.action.VIEW', {
636b7802baSBartosz Kaszubowski *     data: cUri,
646b7802baSBartosz Kaszubowski *     flags: 1,
656b7802baSBartosz Kaszubowski *   });
666b7802baSBartosz Kaszubowski * });
676b7802baSBartosz Kaszubowski * ```
686b7802baSBartosz Kaszubowski * @return Returns a Promise that resolves to a `string` containing a `content://` URI pointing to the file.
696b7802baSBartosz Kaszubowski * The URI is the same as the `fileUri` input parameter but in a different format.
70ca75dd58SBartosz Kaszubowski * @platform android
716b7802baSBartosz Kaszubowski */
72e4897761STongyu Zhuexport async function getContentUriAsync(fileUri) {
731da2f189STomasz Sapeta    if (Platform.OS === 'android') {
74e4897761STongyu Zhu        if (!ExponentFileSystem.getContentUriAsync) {
75e4897761STongyu Zhu            throw new UnavailabilityError('expo-file-system', 'getContentUriAsync');
76e4897761STongyu Zhu        }
77e4897761STongyu Zhu        return await ExponentFileSystem.getContentUriAsync(fileUri);
78e4897761STongyu Zhu    }
791da2f189STomasz Sapeta    else {
80ca75dd58SBartosz Kaszubowski        return fileUri;
811da2f189STomasz Sapeta    }
821da2f189STomasz Sapeta}
836b7802baSBartosz Kaszubowski/**
846b7802baSBartosz Kaszubowski * Write the entire contents of a file as a string.
856b7802baSBartosz Kaszubowski * @param fileUri `file://` or [SAF](#saf-uri) URI to the file or directory.
866b7802baSBartosz Kaszubowski * > Note: when you're using SAF URI the file needs to exist. You can't create a new file.
876b7802baSBartosz Kaszubowski * @param contents The string to replace the contents of the file with.
886b7802baSBartosz Kaszubowski * @param options A map of write options represented by [`WritingOptions`](#writingoptions) type.
896b7802baSBartosz Kaszubowski */
902307aaceSEvan Baconexport async function writeAsStringAsync(fileUri, contents, options = {}) {
917e929553SEvan Bacon    if (!ExponentFileSystem.writeAsStringAsync) {
922307aaceSEvan Bacon        throw new UnavailabilityError('expo-file-system', 'writeAsStringAsync');
932307aaceSEvan Bacon    }
947e929553SEvan Bacon    return await ExponentFileSystem.writeAsStringAsync(fileUri, contents, options);
952307aaceSEvan Bacon}
966b7802baSBartosz Kaszubowski/**
976b7802baSBartosz Kaszubowski * Delete a file or directory. If the URI points to a directory, the directory and all its contents are recursively deleted.
986b7802baSBartosz Kaszubowski * @param fileUri `file://` or [SAF](#saf-uri) URI to the file or directory.
996b7802baSBartosz Kaszubowski * @param options A map of write options represented by [`DeletingOptions`](#deletingoptions) type.
1006b7802baSBartosz Kaszubowski */
1012307aaceSEvan Baconexport async function deleteAsync(fileUri, options = {}) {
1027e929553SEvan Bacon    if (!ExponentFileSystem.deleteAsync) {
1032307aaceSEvan Bacon        throw new UnavailabilityError('expo-file-system', 'deleteAsync');
1042307aaceSEvan Bacon    }
1057e929553SEvan Bacon    return await ExponentFileSystem.deleteAsync(fileUri, options);
1062307aaceSEvan Bacon}
1070d6db115SEric Samelsonexport async function deleteLegacyDocumentDirectoryAndroid() {
1080d6db115SEric Samelson    if (Platform.OS !== 'android' || documentDirectory == null) {
1090d6db115SEric Samelson        return;
1100d6db115SEric Samelson    }
1110d6db115SEric Samelson    const legacyDocumentDirectory = `${documentDirectory}ExperienceData/`;
1120d6db115SEric Samelson    return await deleteAsync(legacyDocumentDirectory, { idempotent: true });
1130d6db115SEric Samelson}
1146b7802baSBartosz Kaszubowski/**
1156b7802baSBartosz Kaszubowski * Move a file or directory to a new location.
1166b7802baSBartosz Kaszubowski * @param options A map of move options represented by [`RelocatingOptions`](#relocatingoptions) type.
1176b7802baSBartosz Kaszubowski */
1182307aaceSEvan Baconexport async function moveAsync(options) {
1197e929553SEvan Bacon    if (!ExponentFileSystem.moveAsync) {
1202307aaceSEvan Bacon        throw new UnavailabilityError('expo-file-system', 'moveAsync');
1212307aaceSEvan Bacon    }
1227e929553SEvan Bacon    return await ExponentFileSystem.moveAsync(options);
1232307aaceSEvan Bacon}
1246b7802baSBartosz Kaszubowski/**
1256b7802baSBartosz Kaszubowski * Create a copy of a file or directory. Directories are recursively copied with all of their contents.
1266b7802baSBartosz Kaszubowski * It can be also used to copy content shared by other apps to local filesystem.
1276b7802baSBartosz Kaszubowski * @param options A map of move options represented by [`RelocatingOptions`](#relocatingoptions) type.
1286b7802baSBartosz Kaszubowski */
1292307aaceSEvan Baconexport async function copyAsync(options) {
1307e929553SEvan Bacon    if (!ExponentFileSystem.copyAsync) {
1312307aaceSEvan Bacon        throw new UnavailabilityError('expo-file-system', 'copyAsync');
1322307aaceSEvan Bacon    }
1337e929553SEvan Bacon    return await ExponentFileSystem.copyAsync(options);
1342307aaceSEvan Bacon}
1356b7802baSBartosz Kaszubowski/**
1366b7802baSBartosz Kaszubowski * Create a new empty directory.
1376b7802baSBartosz Kaszubowski * @param fileUri `file://` URI to the new directory to create.
1386b7802baSBartosz Kaszubowski * @param options A map of create directory options represented by [`MakeDirectoryOptions`](#makedirectoryoptions) type.
1396b7802baSBartosz Kaszubowski */
1402307aaceSEvan Baconexport async function makeDirectoryAsync(fileUri, options = {}) {
1417e929553SEvan Bacon    if (!ExponentFileSystem.makeDirectoryAsync) {
1422307aaceSEvan Bacon        throw new UnavailabilityError('expo-file-system', 'makeDirectoryAsync');
1432307aaceSEvan Bacon    }
1447e929553SEvan Bacon    return await ExponentFileSystem.makeDirectoryAsync(fileUri, options);
1452307aaceSEvan Bacon}
1466b7802baSBartosz Kaszubowski/**
1476b7802baSBartosz Kaszubowski * Enumerate the contents of a directory.
1486b7802baSBartosz Kaszubowski * @param fileUri `file://` URI to the directory.
1496b7802baSBartosz Kaszubowski * @return A Promise that resolves to an array of strings, each containing the name of a file or directory contained in the directory at `fileUri`.
1506b7802baSBartosz Kaszubowski */
1512307aaceSEvan Baconexport async function readDirectoryAsync(fileUri) {
1527e929553SEvan Bacon    if (!ExponentFileSystem.readDirectoryAsync) {
1532307aaceSEvan Bacon        throw new UnavailabilityError('expo-file-system', 'readDirectoryAsync');
1542307aaceSEvan Bacon    }
1554fde8ae7SAlan Hughes    return await ExponentFileSystem.readDirectoryAsync(fileUri);
1562307aaceSEvan Bacon}
1576b7802baSBartosz Kaszubowski/**
1586b7802baSBartosz Kaszubowski * Gets the available internal disk storage size, in bytes. This returns the free space on the data partition that hosts all of the internal storage for all apps on the device.
1596b7802baSBartosz Kaszubowski * @return Returns a Promise that resolves to the number of bytes available on the internal disk, or JavaScript's [`MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER)
1606b7802baSBartosz Kaszubowski * if the capacity is greater than 2<sup>53</sup> - 1 bytes.
1616b7802baSBartosz Kaszubowski */
162ae9a5f1aSTongyu Zhuexport async function getFreeDiskStorageAsync() {
163ae9a5f1aSTongyu Zhu    if (!ExponentFileSystem.getFreeDiskStorageAsync) {
164ae9a5f1aSTongyu Zhu        throw new UnavailabilityError('expo-file-system', 'getFreeDiskStorageAsync');
165ae9a5f1aSTongyu Zhu    }
166ae9a5f1aSTongyu Zhu    return await ExponentFileSystem.getFreeDiskStorageAsync();
167ae9a5f1aSTongyu Zhu}
1686b7802baSBartosz Kaszubowski/**
1696b7802baSBartosz Kaszubowski * Gets total internal disk storage size, in bytes. This is the total capacity of the data partition that hosts all the internal storage for all apps on the device.
1706b7802baSBartosz Kaszubowski * @return Returns a Promise that resolves to a number that specifies the total internal disk storage capacity in bytes, or JavaScript's [`MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER)
1716b7802baSBartosz Kaszubowski * if the capacity is greater than 2<sup>53</sup> - 1 bytes.
1726b7802baSBartosz Kaszubowski */
173ae9a5f1aSTongyu Zhuexport async function getTotalDiskCapacityAsync() {
174ae9a5f1aSTongyu Zhu    if (!ExponentFileSystem.getTotalDiskCapacityAsync) {
175ae9a5f1aSTongyu Zhu        throw new UnavailabilityError('expo-file-system', 'getTotalDiskCapacityAsync');
176ae9a5f1aSTongyu Zhu    }
177ae9a5f1aSTongyu Zhu    return await ExponentFileSystem.getTotalDiskCapacityAsync();
178ae9a5f1aSTongyu Zhu}
1796b7802baSBartosz Kaszubowski/**
1806b7802baSBartosz Kaszubowski * Download the contents at a remote URI to a file in the app's file system. The directory for a local file uri must exist prior to calling this function.
1816b7802baSBartosz Kaszubowski * @param uri The remote URI to download from.
1826b7802baSBartosz Kaszubowski * @param fileUri The local URI of the file to download to. If there is no file at this URI, a new one is created.
1836b7802baSBartosz Kaszubowski * If there is a file at this URI, its contents are replaced. The directory for the file must exist.
1846b7802baSBartosz Kaszubowski * @param options A map of download options represented by [`DownloadOptions`](#downloadoptions) type.
1856b7802baSBartosz Kaszubowski * @example
1866b7802baSBartosz Kaszubowski * ```js
1876b7802baSBartosz Kaszubowski * FileSystem.downloadAsync(
1886b7802baSBartosz Kaszubowski *   'http://techslides.com/demos/sample-videos/small.mp4',
1896b7802baSBartosz Kaszubowski *   FileSystem.documentDirectory + 'small.mp4'
1906b7802baSBartosz Kaszubowski * )
1916b7802baSBartosz Kaszubowski *   .then(({ uri }) => {
1926b7802baSBartosz Kaszubowski *     console.log('Finished downloading to ', uri);
1936b7802baSBartosz Kaszubowski *   })
1946b7802baSBartosz Kaszubowski *   .catch(error => {
1956b7802baSBartosz Kaszubowski *     console.error(error);
1966b7802baSBartosz Kaszubowski *   });
1976b7802baSBartosz Kaszubowski * ```
1986b7802baSBartosz Kaszubowski * @return Returns a Promise that resolves to a `FileSystemDownloadResult` object.
1996b7802baSBartosz Kaszubowski */
2002307aaceSEvan Baconexport async function downloadAsync(uri, fileUri, options = {}) {
2017e929553SEvan Bacon    if (!ExponentFileSystem.downloadAsync) {
2022307aaceSEvan Bacon        throw new UnavailabilityError('expo-file-system', 'downloadAsync');
2032307aaceSEvan Bacon    }
204da65a760SŁukasz Kosmaty    return await ExponentFileSystem.downloadAsync(uri, fileUri, {
205da65a760SŁukasz Kosmaty        sessionType: FileSystemSessionType.BACKGROUND,
206da65a760SŁukasz Kosmaty        ...options,
207da65a760SŁukasz Kosmaty    });
208da65a760SŁukasz Kosmaty}
2096b7802baSBartosz Kaszubowski/**
2106b7802baSBartosz Kaszubowski * Upload the contents of the file pointed by `fileUri` to the remote url.
2116b7802baSBartosz Kaszubowski * @param url The remote URL, where the file will be sent.
2126b7802baSBartosz Kaszubowski * @param fileUri The local URI of the file to send. The file must exist.
2136b7802baSBartosz Kaszubowski * @param options A map of download options represented by [`FileSystemUploadOptions`](#filesystemuploadoptions) type.
2146b7802baSBartosz Kaszubowski * @example
2156b7802baSBartosz Kaszubowski * **Client**
2166b7802baSBartosz Kaszubowski *
2176b7802baSBartosz Kaszubowski * ```js
2186b7802baSBartosz Kaszubowski * import * as FileSystem from 'expo-file-system';
2196b7802baSBartosz Kaszubowski *
2206b7802baSBartosz Kaszubowski * try {
2216b7802baSBartosz Kaszubowski *   const response = await FileSystem.uploadAsync(`http://192.168.0.1:1234/binary-upload`, fileUri, {
2226b7802baSBartosz Kaszubowski *     fieldName: 'file',
2236b7802baSBartosz Kaszubowski *     httpMethod: 'PATCH',
2246b7802baSBartosz Kaszubowski *     uploadType: FileSystem.FileSystemUploadType.BINARY_CONTENT,
2256b7802baSBartosz Kaszubowski *   });
2266b7802baSBartosz Kaszubowski *   console.log(JSON.stringify(response, null, 4));
2276b7802baSBartosz Kaszubowski * } catch (error) {
2286b7802baSBartosz Kaszubowski *   console.log(error);
2296b7802baSBartosz Kaszubowski * }
2306b7802baSBartosz Kaszubowski * ```
2316b7802baSBartosz Kaszubowski *
2326b7802baSBartosz Kaszubowski * **Server**
2336b7802baSBartosz Kaszubowski *
2346b7802baSBartosz Kaszubowski * Please refer to the "[Server: Handling multipart requests](#server-handling-multipart-requests)" example - there is code for a simple Node.js server.
2356b7802baSBartosz Kaszubowski * @return Returns a Promise that resolves to `FileSystemUploadResult` object.
2366b7802baSBartosz Kaszubowski */
237da65a760SŁukasz Kosmatyexport async function uploadAsync(url, fileUri, options = {}) {
238da65a760SŁukasz Kosmaty    if (!ExponentFileSystem.uploadAsync) {
239da65a760SŁukasz Kosmaty        throw new UnavailabilityError('expo-file-system', 'uploadAsync');
240da65a760SŁukasz Kosmaty    }
241da65a760SŁukasz Kosmaty    return await ExponentFileSystem.uploadAsync(url, fileUri, {
242da65a760SŁukasz Kosmaty        sessionType: FileSystemSessionType.BACKGROUND,
24337630a92SŁukasz Kosmaty        uploadType: FileSystemUploadType.BINARY_CONTENT,
244da65a760SŁukasz Kosmaty        ...options,
245da65a760SŁukasz Kosmaty        httpMethod: (options.httpMethod || 'POST').toUpperCase(),
246da65a760SŁukasz Kosmaty    });
2472307aaceSEvan Bacon}
2486b7802baSBartosz Kaszubowski/**
2496b7802baSBartosz Kaszubowski * Create a `DownloadResumable` object which can start, pause, and resume a download of contents at a remote URI to a file in the app's file system.
2506b7802baSBartosz Kaszubowski * > Note: You need to call `downloadAsync()`, on a `DownloadResumable` instance to initiate the download.
2516b7802baSBartosz Kaszubowski * The `DownloadResumable` object has a callback that provides download progress updates.
2526b7802baSBartosz Kaszubowski * Downloads can be resumed across app restarts by using `AsyncStorage` to store the `DownloadResumable.savable()` object for later retrieval.
2536b7802baSBartosz Kaszubowski * The `savable` object contains the arguments required to initialize a new `DownloadResumable` object to resume the download after an app restart.
2546b7802baSBartosz Kaszubowski * The directory for a local file uri must exist prior to calling this function.
2556b7802baSBartosz Kaszubowski * @param uri The remote URI to download from.
2566b7802baSBartosz Kaszubowski * @param fileUri The local URI of the file to download to. If there is no file at this URI, a new one is created.
2576b7802baSBartosz Kaszubowski * If there is a file at this URI, its contents are replaced. The directory for the file must exist.
2586b7802baSBartosz Kaszubowski * @param options A map of download options represented by [`DownloadOptions`](#downloadoptions) type.
2596b7802baSBartosz Kaszubowski * @param callback This function is called on each data write to update the download progress.
2606b7802baSBartosz Kaszubowski * > **Note**: When the app has been moved to the background, this callback won't be fired until it's moved to the foreground.
2616b7802baSBartosz Kaszubowski * @param resumeData The string which allows the api to resume a paused download. This is set on the `DownloadResumable` object automatically when a download is paused.
2626b7802baSBartosz Kaszubowski * When initializing a new `DownloadResumable` this should be `null`.
2636b7802baSBartosz Kaszubowski */
2642307aaceSEvan Baconexport function createDownloadResumable(uri, fileUri, options, callback, resumeData) {
2652307aaceSEvan Bacon    return new DownloadResumable(uri, fileUri, options, callback, resumeData);
2662307aaceSEvan Bacon}
26752eeb172SŁukasz Kosmatyexport function createUploadTask(url, fileUri, options, callback) {
26852eeb172SŁukasz Kosmaty    return new UploadTask(url, fileUri, options, callback);
26952eeb172SŁukasz Kosmaty}
27052eeb172SŁukasz Kosmatyexport class FileSystemCancellableNetworkTask {
27152eeb172SŁukasz Kosmaty    _uuid = uuidv4();
27252eeb172SŁukasz Kosmaty    taskWasCanceled = false;
27352eeb172SŁukasz Kosmaty    emitter = new EventEmitter(ExponentFileSystem);
27452eeb172SŁukasz Kosmaty    subscription;
2756b7802baSBartosz Kaszubowski    // @docsMissing
27652eeb172SŁukasz Kosmaty    async cancelAsync() {
27752eeb172SŁukasz Kosmaty        if (!ExponentFileSystem.networkTaskCancelAsync) {
27852eeb172SŁukasz Kosmaty            throw new UnavailabilityError('expo-file-system', 'networkTaskCancelAsync');
27952eeb172SŁukasz Kosmaty        }
28052eeb172SŁukasz Kosmaty        this.removeSubscription();
28152eeb172SŁukasz Kosmaty        this.taskWasCanceled = true;
28252eeb172SŁukasz Kosmaty        return await ExponentFileSystem.networkTaskCancelAsync(this.uuid);
28352eeb172SŁukasz Kosmaty    }
28452eeb172SŁukasz Kosmaty    isTaskCancelled() {
28552eeb172SŁukasz Kosmaty        if (this.taskWasCanceled) {
28652eeb172SŁukasz Kosmaty            console.warn('This task was already canceled.');
28752eeb172SŁukasz Kosmaty            return true;
28852eeb172SŁukasz Kosmaty        }
28952eeb172SŁukasz Kosmaty        return false;
29052eeb172SŁukasz Kosmaty    }
29152eeb172SŁukasz Kosmaty    get uuid() {
29252eeb172SŁukasz Kosmaty        return this._uuid;
29352eeb172SŁukasz Kosmaty    }
29452eeb172SŁukasz Kosmaty    addSubscription() {
29552eeb172SŁukasz Kosmaty        if (this.subscription) {
29652eeb172SŁukasz Kosmaty            return;
29752eeb172SŁukasz Kosmaty        }
29852eeb172SŁukasz Kosmaty        this.subscription = this.emitter.addListener(this.getEventName(), (event) => {
29952eeb172SŁukasz Kosmaty            if (event.uuid === this.uuid) {
30052eeb172SŁukasz Kosmaty                const callback = this.getCallback();
30152eeb172SŁukasz Kosmaty                if (callback) {
30252eeb172SŁukasz Kosmaty                    callback(event.data);
30352eeb172SŁukasz Kosmaty                }
30452eeb172SŁukasz Kosmaty            }
30552eeb172SŁukasz Kosmaty        });
30652eeb172SŁukasz Kosmaty    }
30752eeb172SŁukasz Kosmaty    removeSubscription() {
30852eeb172SŁukasz Kosmaty        if (!this.subscription) {
30952eeb172SŁukasz Kosmaty            return;
31052eeb172SŁukasz Kosmaty        }
31152eeb172SŁukasz Kosmaty        this.emitter.removeSubscription(this.subscription);
31252eeb172SŁukasz Kosmaty        this.subscription = null;
31352eeb172SŁukasz Kosmaty    }
31452eeb172SŁukasz Kosmaty}
31552eeb172SŁukasz Kosmatyexport class UploadTask extends FileSystemCancellableNetworkTask {
31652eeb172SŁukasz Kosmaty    url;
31752eeb172SŁukasz Kosmaty    fileUri;
31852eeb172SŁukasz Kosmaty    callback;
31952eeb172SŁukasz Kosmaty    options;
32052eeb172SŁukasz Kosmaty    constructor(url, fileUri, options, callback) {
32152eeb172SŁukasz Kosmaty        super();
32252eeb172SŁukasz Kosmaty        this.url = url;
32352eeb172SŁukasz Kosmaty        this.fileUri = fileUri;
32452eeb172SŁukasz Kosmaty        this.callback = callback;
32500d910e2SLuke Brandon Farrell        const httpMethod = (options?.httpMethod?.toUpperCase() ||
32652eeb172SŁukasz Kosmaty            'POST');
32752eeb172SŁukasz Kosmaty        this.options = {
32852eeb172SŁukasz Kosmaty            sessionType: FileSystemSessionType.BACKGROUND,
32952eeb172SŁukasz Kosmaty            uploadType: FileSystemUploadType.BINARY_CONTENT,
33052eeb172SŁukasz Kosmaty            ...options,
33152eeb172SŁukasz Kosmaty            httpMethod,
33252eeb172SŁukasz Kosmaty        };
33352eeb172SŁukasz Kosmaty    }
33452eeb172SŁukasz Kosmaty    getEventName() {
33552eeb172SŁukasz Kosmaty        return 'expo-file-system.uploadProgress';
33652eeb172SŁukasz Kosmaty    }
33752eeb172SŁukasz Kosmaty    getCallback() {
33852eeb172SŁukasz Kosmaty        return this.callback;
33952eeb172SŁukasz Kosmaty    }
3406b7802baSBartosz Kaszubowski    // @docsMissing
34152eeb172SŁukasz Kosmaty    async uploadAsync() {
34252eeb172SŁukasz Kosmaty        if (!ExponentFileSystem.uploadTaskStartAsync) {
34352eeb172SŁukasz Kosmaty            throw new UnavailabilityError('expo-file-system', 'uploadTaskStartAsync');
34452eeb172SŁukasz Kosmaty        }
34552eeb172SŁukasz Kosmaty        if (this.isTaskCancelled()) {
34652eeb172SŁukasz Kosmaty            return;
34752eeb172SŁukasz Kosmaty        }
34852eeb172SŁukasz Kosmaty        this.addSubscription();
34952eeb172SŁukasz Kosmaty        const result = await ExponentFileSystem.uploadTaskStartAsync(this.url, this.fileUri, this.uuid, this.options);
35052eeb172SŁukasz Kosmaty        this.removeSubscription();
35152eeb172SŁukasz Kosmaty        return result;
35252eeb172SŁukasz Kosmaty    }
35352eeb172SŁukasz Kosmaty}
35452eeb172SŁukasz Kosmatyexport class DownloadResumable extends FileSystemCancellableNetworkTask {
35552eeb172SŁukasz Kosmaty    url;
356896103abSandy    _fileUri;
35752eeb172SŁukasz Kosmaty    options;
35852eeb172SŁukasz Kosmaty    callback;
35952eeb172SŁukasz Kosmaty    resumeData;
36052eeb172SŁukasz Kosmaty    constructor(url, _fileUri, options = {}, callback, resumeData) {
36152eeb172SŁukasz Kosmaty        super();
36252eeb172SŁukasz Kosmaty        this.url = url;
36352eeb172SŁukasz Kosmaty        this._fileUri = _fileUri;
36452eeb172SŁukasz Kosmaty        this.options = options;
36552eeb172SŁukasz Kosmaty        this.callback = callback;
36652eeb172SŁukasz Kosmaty        this.resumeData = resumeData;
36752eeb172SŁukasz Kosmaty    }
36852eeb172SŁukasz Kosmaty    get fileUri() {
36952eeb172SŁukasz Kosmaty        return this._fileUri;
37052eeb172SŁukasz Kosmaty    }
37152eeb172SŁukasz Kosmaty    getEventName() {
37252eeb172SŁukasz Kosmaty        return 'expo-file-system.downloadProgress';
37352eeb172SŁukasz Kosmaty    }
37452eeb172SŁukasz Kosmaty    getCallback() {
37552eeb172SŁukasz Kosmaty        return this.callback;
3762307aaceSEvan Bacon    }
3776b7802baSBartosz Kaszubowski    /**
3786b7802baSBartosz Kaszubowski     * Download the contents at a remote URI to a file in the app's file system.
3796b7802baSBartosz Kaszubowski     * @return Returns a Promise that resolves to `FileSystemDownloadResult` object, or to `undefined` when task was cancelled.
3806b7802baSBartosz Kaszubowski     */
3812307aaceSEvan Bacon    async downloadAsync() {
3827e929553SEvan Bacon        if (!ExponentFileSystem.downloadResumableStartAsync) {
3832307aaceSEvan Bacon            throw new UnavailabilityError('expo-file-system', 'downloadResumableStartAsync');
3842307aaceSEvan Bacon        }
38552eeb172SŁukasz Kosmaty        if (this.isTaskCancelled()) {
38652eeb172SŁukasz Kosmaty            return;
38752eeb172SŁukasz Kosmaty        }
38852eeb172SŁukasz Kosmaty        this.addSubscription();
38952eeb172SŁukasz Kosmaty        return await ExponentFileSystem.downloadResumableStartAsync(this.url, this._fileUri, this.uuid, this.options, this.resumeData);
3902307aaceSEvan Bacon    }
3916b7802baSBartosz Kaszubowski    /**
3926b7802baSBartosz Kaszubowski     * Pause the current download operation. `resumeData` is added to the `DownloadResumable` object after a successful pause operation.
3936b7802baSBartosz Kaszubowski     * Returns an object that can be saved with `AsyncStorage` for future retrieval (the same object that is returned from calling `FileSystem.DownloadResumable.savable()`).
3946b7802baSBartosz Kaszubowski     * @return Returns a Promise that resolves to `DownloadPauseState` object.
3956b7802baSBartosz Kaszubowski     */
3962307aaceSEvan Bacon    async pauseAsync() {
3977e929553SEvan Bacon        if (!ExponentFileSystem.downloadResumablePauseAsync) {
3982307aaceSEvan Bacon            throw new UnavailabilityError('expo-file-system', 'downloadResumablePauseAsync');
3992307aaceSEvan Bacon        }
40052eeb172SŁukasz Kosmaty        if (this.isTaskCancelled()) {
40152eeb172SŁukasz Kosmaty            return {
40252eeb172SŁukasz Kosmaty                fileUri: this._fileUri,
40352eeb172SŁukasz Kosmaty                options: this.options,
40452eeb172SŁukasz Kosmaty                url: this.url,
40552eeb172SŁukasz Kosmaty            };
40652eeb172SŁukasz Kosmaty        }
40752eeb172SŁukasz Kosmaty        const pauseResult = await ExponentFileSystem.downloadResumablePauseAsync(this.uuid);
40852eeb172SŁukasz Kosmaty        this.removeSubscription();
4092307aaceSEvan Bacon        if (pauseResult) {
41052eeb172SŁukasz Kosmaty            this.resumeData = pauseResult.resumeData;
4112307aaceSEvan Bacon            return this.savable();
4122307aaceSEvan Bacon        }
4132307aaceSEvan Bacon        else {
4142307aaceSEvan Bacon            throw new Error('Unable to generate a savable pause state');
4152307aaceSEvan Bacon        }
4162307aaceSEvan Bacon    }
4176b7802baSBartosz Kaszubowski    /**
4186b7802baSBartosz Kaszubowski     * Resume a paused download operation.
4196b7802baSBartosz Kaszubowski     * @return Returns a Promise that resolves to `FileSystemDownloadResult` object, or to `undefined` when task was cancelled.
4206b7802baSBartosz Kaszubowski     */
4212307aaceSEvan Bacon    async resumeAsync() {
4227e929553SEvan Bacon        if (!ExponentFileSystem.downloadResumableStartAsync) {
4232307aaceSEvan Bacon            throw new UnavailabilityError('expo-file-system', 'downloadResumableStartAsync');
4242307aaceSEvan Bacon        }
42552eeb172SŁukasz Kosmaty        if (this.isTaskCancelled()) {
42652eeb172SŁukasz Kosmaty            return;
42752eeb172SŁukasz Kosmaty        }
42852eeb172SŁukasz Kosmaty        this.addSubscription();
42952eeb172SŁukasz Kosmaty        return await ExponentFileSystem.downloadResumableStartAsync(this.url, this.fileUri, this.uuid, this.options, this.resumeData);
4302307aaceSEvan Bacon    }
4316b7802baSBartosz Kaszubowski    /**
4326b7802baSBartosz Kaszubowski     * Method to get the object which can be saved with `AsyncStorage` for future retrieval.
4336b7802baSBartosz Kaszubowski     * @returns Returns object in shape of `DownloadPauseState` type.
4346b7802baSBartosz Kaszubowski     */
4352307aaceSEvan Bacon    savable() {
4362307aaceSEvan Bacon        return {
43752eeb172SŁukasz Kosmaty            url: this.url,
43852eeb172SŁukasz Kosmaty            fileUri: this.fileUri,
43952eeb172SŁukasz Kosmaty            options: this.options,
44052eeb172SŁukasz Kosmaty            resumeData: this.resumeData,
4412307aaceSEvan Bacon        };
4422307aaceSEvan Bacon    }
4432307aaceSEvan Bacon}
444400de723SŁukasz Kosmatyconst baseReadAsStringAsync = readAsStringAsync;
445400de723SŁukasz Kosmatyconst baseWriteAsStringAsync = writeAsStringAsync;
446400de723SŁukasz Kosmatyconst baseDeleteAsync = deleteAsync;
447400de723SŁukasz Kosmatyconst baseMoveAsync = moveAsync;
448400de723SŁukasz Kosmatyconst baseCopyAsync = copyAsync;
449400de723SŁukasz Kosmaty/**
4506b7802baSBartosz Kaszubowski * The `StorageAccessFramework` is a namespace inside of the `expo-file-system` module, which encapsulates all functions which can be used with [SAF URIs](#saf-uri).
4516b7802baSBartosz Kaszubowski * You can read more about SAF in the [Android documentation](https://developer.android.com/guide/topics/providers/document-provider).
4526b7802baSBartosz Kaszubowski *
4536b7802baSBartosz Kaszubowski * @example
4546b7802baSBartosz Kaszubowski * # Basic Usage
4556b7802baSBartosz Kaszubowski *
4566b7802baSBartosz Kaszubowski * ```ts
4576b7802baSBartosz Kaszubowski * import { StorageAccessFramework } from 'expo-file-system';
4586b7802baSBartosz Kaszubowski *
4596b7802baSBartosz Kaszubowski * // Requests permissions for external directory
4606b7802baSBartosz Kaszubowski * const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync();
4616b7802baSBartosz Kaszubowski *
4626b7802baSBartosz Kaszubowski * if (permissions.granted) {
4636b7802baSBartosz Kaszubowski *   // Gets SAF URI from response
4646b7802baSBartosz Kaszubowski *   const uri = permissions.directoryUri;
4656b7802baSBartosz Kaszubowski *
4666b7802baSBartosz Kaszubowski *   // Gets all files inside of selected directory
4676b7802baSBartosz Kaszubowski *   const files = await StorageAccessFramework.readDirectoryAsync(uri);
4686b7802baSBartosz Kaszubowski *   alert(`Files inside ${uri}:\n\n${JSON.stringify(files)}`);
4696b7802baSBartosz Kaszubowski * }
4706b7802baSBartosz Kaszubowski * ```
4716b7802baSBartosz Kaszubowski *
4726b7802baSBartosz Kaszubowski * # Migrating an album
4736b7802baSBartosz Kaszubowski *
4746b7802baSBartosz Kaszubowski * ```ts
4756b7802baSBartosz Kaszubowski * import * as MediaLibrary from 'expo-media-library';
4766b7802baSBartosz Kaszubowski * import * as FileSystem from 'expo-file-system';
4776b7802baSBartosz Kaszubowski * const { StorageAccessFramework } = FileSystem;
4786b7802baSBartosz Kaszubowski *
4796b7802baSBartosz Kaszubowski * async function migrateAlbum(albumName: string) {
4806b7802baSBartosz Kaszubowski *   // Gets SAF URI to the album
4816b7802baSBartosz Kaszubowski *   const albumUri = StorageAccessFramework.getUriForDirectoryInRoot(albumName);
4826b7802baSBartosz Kaszubowski *
4836b7802baSBartosz Kaszubowski *   // Requests permissions
4846b7802baSBartosz Kaszubowski *   const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync(albumUri);
4856b7802baSBartosz Kaszubowski *   if (!permissions.granted) {
4866b7802baSBartosz Kaszubowski *     return;
4876b7802baSBartosz Kaszubowski *   }
4886b7802baSBartosz Kaszubowski *
4896b7802baSBartosz Kaszubowski *   const permittedUri = permissions.directoryUri;
4906b7802baSBartosz Kaszubowski *   // Checks if users selected the correct folder
4916b7802baSBartosz Kaszubowski *   if (!permittedUri.includes(albumName)) {
4926b7802baSBartosz Kaszubowski *     return;
4936b7802baSBartosz Kaszubowski *   }
4946b7802baSBartosz Kaszubowski *
4956b7802baSBartosz Kaszubowski *   const mediaLibraryPermissions = await MediaLibrary.requestPermissionsAsync();
4966b7802baSBartosz Kaszubowski *   if (!mediaLibraryPermissions.granted) {
4976b7802baSBartosz Kaszubowski *     return;
4986b7802baSBartosz Kaszubowski *   }
4996b7802baSBartosz Kaszubowski *
5006b7802baSBartosz Kaszubowski *   // Moves files from external storage to internal storage
5016b7802baSBartosz Kaszubowski *   await StorageAccessFramework.moveAsync({
5026b7802baSBartosz Kaszubowski *     from: permittedUri,
5036b7802baSBartosz Kaszubowski *     to: FileSystem.documentDirectory!,
5046b7802baSBartosz Kaszubowski *   });
5056b7802baSBartosz Kaszubowski *
5066b7802baSBartosz Kaszubowski *   const outputDir = FileSystem.documentDirectory! + albumName;
5076b7802baSBartosz Kaszubowski *   const migratedFiles = await FileSystem.readDirectoryAsync(outputDir);
5086b7802baSBartosz Kaszubowski *
5096b7802baSBartosz Kaszubowski *   // Creates assets from local files
5106b7802baSBartosz Kaszubowski *   const [newAlbumCreator, ...assets] = await Promise.all(
5116b7802baSBartosz Kaszubowski *     migratedFiles.map<Promise<MediaLibrary.Asset>>(
5126b7802baSBartosz Kaszubowski *       async fileName => await MediaLibrary.createAssetAsync(outputDir + '/' + fileName)
5136b7802baSBartosz Kaszubowski *     )
5146b7802baSBartosz Kaszubowski *   );
5156b7802baSBartosz Kaszubowski *
5166b7802baSBartosz Kaszubowski *   // Album was empty
5176b7802baSBartosz Kaszubowski *   if (!newAlbumCreator) {
5186b7802baSBartosz Kaszubowski *     return;
5196b7802baSBartosz Kaszubowski *   }
5206b7802baSBartosz Kaszubowski *
5216b7802baSBartosz Kaszubowski *   // Creates a new album in the scoped directory
5226b7802baSBartosz Kaszubowski *   const newAlbum = await MediaLibrary.createAlbumAsync(albumName, newAlbumCreator, false);
5236b7802baSBartosz Kaszubowski *   if (assets.length) {
5246b7802baSBartosz Kaszubowski *     await MediaLibrary.addAssetsToAlbumAsync(assets, newAlbum, false);
5256b7802baSBartosz Kaszubowski *   }
5266b7802baSBartosz Kaszubowski * }
5276b7802baSBartosz Kaszubowski * ```
5286b7802baSBartosz Kaszubowski * @platform Android
529400de723SŁukasz Kosmaty */
530400de723SŁukasz Kosmatyexport var StorageAccessFramework;
531400de723SŁukasz Kosmaty(function (StorageAccessFramework) {
5326b7802baSBartosz Kaszubowski    /**
5336b7802baSBartosz Kaszubowski     * Gets a [SAF URI](#saf-uri) pointing to a folder in the Android root directory. You can use this function to get URI for
5346b7802baSBartosz Kaszubowski     * `StorageAccessFramework.requestDirectoryPermissionsAsync()` when you trying to migrate an album. In that case, the name of the album is the folder name.
5356b7802baSBartosz Kaszubowski     * @param folderName The name of the folder which is located in the Android root directory.
5366b7802baSBartosz Kaszubowski     * @return Returns a [SAF URI](#saf-uri) to a folder.
5376b7802baSBartosz Kaszubowski     */
538400de723SŁukasz Kosmaty    function getUriForDirectoryInRoot(folderName) {
539400de723SŁukasz Kosmaty        return `content://com.android.externalstorage.documents/tree/primary:${folderName}/document/primary:${folderName}`;
540400de723SŁukasz Kosmaty    }
541400de723SŁukasz Kosmaty    StorageAccessFramework.getUriForDirectoryInRoot = getUriForDirectoryInRoot;
5426b7802baSBartosz Kaszubowski    /**
5436b7802baSBartosz Kaszubowski     * Allows users to select a specific directory, granting your app access to all of the files and sub-directories within that directory.
5446b7802baSBartosz Kaszubowski     * @param initialFileUrl The [SAF URI](#saf-uri) of the directory that the file picker should display when it first loads.
5456b7802baSBartosz Kaszubowski     * If URI is incorrect or points to a non-existing folder, it's ignored.
5466b7802baSBartosz Kaszubowski     * @platform android 11+
5476b7802baSBartosz Kaszubowski     * @return Returns a Promise that resolves to `FileSystemRequestDirectoryPermissionsResult` object.
5486b7802baSBartosz Kaszubowski     */
549400de723SŁukasz Kosmaty    async function requestDirectoryPermissionsAsync(initialFileUrl = null) {
550400de723SŁukasz Kosmaty        if (!ExponentFileSystem.requestDirectoryPermissionsAsync) {
551400de723SŁukasz Kosmaty            throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.requestDirectoryPermissionsAsync');
552400de723SŁukasz Kosmaty        }
553400de723SŁukasz Kosmaty        return await ExponentFileSystem.requestDirectoryPermissionsAsync(initialFileUrl);
554400de723SŁukasz Kosmaty    }
555400de723SŁukasz Kosmaty    StorageAccessFramework.requestDirectoryPermissionsAsync = requestDirectoryPermissionsAsync;
5566b7802baSBartosz Kaszubowski    /**
5576b7802baSBartosz Kaszubowski     * Enumerate the contents of a directory.
5586b7802baSBartosz Kaszubowski     * @param dirUri [SAF](#saf-uri) URI to the directory.
5596b7802baSBartosz Kaszubowski     * @return A Promise that resolves to an array of strings, each containing the full [SAF URI](#saf-uri) of a file or directory contained in the directory at `fileUri`.
5606b7802baSBartosz Kaszubowski     */
561400de723SŁukasz Kosmaty    async function readDirectoryAsync(dirUri) {
562400de723SŁukasz Kosmaty        if (!ExponentFileSystem.readSAFDirectoryAsync) {
563400de723SŁukasz Kosmaty            throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.readDirectoryAsync');
564400de723SŁukasz Kosmaty        }
5654fde8ae7SAlan Hughes        return await ExponentFileSystem.readSAFDirectoryAsync(dirUri);
566400de723SŁukasz Kosmaty    }
567400de723SŁukasz Kosmaty    StorageAccessFramework.readDirectoryAsync = readDirectoryAsync;
5686b7802baSBartosz Kaszubowski    /**
5696b7802baSBartosz Kaszubowski     * Creates a new empty directory.
5706b7802baSBartosz Kaszubowski     * @param parentUri The [SAF](#saf-uri) URI to the parent directory.
5716b7802baSBartosz Kaszubowski     * @param dirName The name of new directory.
5726b7802baSBartosz Kaszubowski     * @return A Promise that resolves to a [SAF URI](#saf-uri) to the created directory.
5736b7802baSBartosz Kaszubowski     */
574400de723SŁukasz Kosmaty    async function makeDirectoryAsync(parentUri, dirName) {
575400de723SŁukasz Kosmaty        if (!ExponentFileSystem.makeSAFDirectoryAsync) {
576400de723SŁukasz Kosmaty            throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.makeDirectoryAsync');
577400de723SŁukasz Kosmaty        }
578400de723SŁukasz Kosmaty        return await ExponentFileSystem.makeSAFDirectoryAsync(parentUri, dirName);
579400de723SŁukasz Kosmaty    }
580400de723SŁukasz Kosmaty    StorageAccessFramework.makeDirectoryAsync = makeDirectoryAsync;
5816b7802baSBartosz Kaszubowski    /**
5826b7802baSBartosz Kaszubowski     * Creates a new empty file.
5836b7802baSBartosz Kaszubowski     * @param parentUri The [SAF](#saf-uri) URI to the parent directory.
5846b7802baSBartosz Kaszubowski     * @param fileName The name of new file **without the extension**.
5856b7802baSBartosz Kaszubowski     * @param mimeType The MIME type of new file.
5866b7802baSBartosz Kaszubowski     * @return A Promise that resolves to a [SAF URI](#saf-uri) to the created file.
5876b7802baSBartosz Kaszubowski     */
588400de723SŁukasz Kosmaty    async function createFileAsync(parentUri, fileName, mimeType) {
589400de723SŁukasz Kosmaty        if (!ExponentFileSystem.createSAFFileAsync) {
590400de723SŁukasz Kosmaty            throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.createFileAsync');
591400de723SŁukasz Kosmaty        }
592400de723SŁukasz Kosmaty        return await ExponentFileSystem.createSAFFileAsync(parentUri, fileName, mimeType);
593400de723SŁukasz Kosmaty    }
594400de723SŁukasz Kosmaty    StorageAccessFramework.createFileAsync = createFileAsync;
5956b7802baSBartosz Kaszubowski    /**
5966b7802baSBartosz Kaszubowski     * Alias for [`writeAsStringAsync`](#filesystemwriteasstringasyncfileuri-contents-options) method.
5976b7802baSBartosz Kaszubowski     */
598400de723SŁukasz Kosmaty    StorageAccessFramework.writeAsStringAsync = baseWriteAsStringAsync;
5996b7802baSBartosz Kaszubowski    /**
6006b7802baSBartosz Kaszubowski     * Alias for [`readAsStringAsync`](#filesystemreadasstringasyncfileuri-options) method.
6016b7802baSBartosz Kaszubowski     */
602400de723SŁukasz Kosmaty    StorageAccessFramework.readAsStringAsync = baseReadAsStringAsync;
6036b7802baSBartosz Kaszubowski    /**
6046b7802baSBartosz Kaszubowski     * Alias for [`deleteAsync`](#filesystemdeleteasyncfileuri-options) method.
6056b7802baSBartosz Kaszubowski     */
606400de723SŁukasz Kosmaty    StorageAccessFramework.deleteAsync = baseDeleteAsync;
6076b7802baSBartosz Kaszubowski    /**
6086b7802baSBartosz Kaszubowski     * Alias for [`moveAsync`](#filesystemmoveasyncoptions) method.
6096b7802baSBartosz Kaszubowski     */
610400de723SŁukasz Kosmaty    StorageAccessFramework.moveAsync = baseMoveAsync;
6116b7802baSBartosz Kaszubowski    /**
6122de90edaSTomasz Sapeta     * Alias for [`copyAsync`](#filesystemcopyasyncoptions) method.
6136b7802baSBartosz Kaszubowski     */
614400de723SŁukasz Kosmaty    StorageAccessFramework.copyAsync = baseCopyAsync;
615400de723SŁukasz Kosmaty})(StorageAccessFramework || (StorageAccessFramework = {}));
6162307aaceSEvan Bacon//# sourceMappingURL=FileSystem.js.map