1import { EventEmitter, UnavailabilityError } from 'expo-modules-core'; 2import { Platform } from 'react-native'; 3import { v4 as uuidv4 } from 'uuid'; 4import ExponentFileSystem from './ExponentFileSystem'; 5import { FileSystemSessionType, FileSystemUploadType, } from './FileSystem.types'; 6if (!ExponentFileSystem) { 7 console.warn("No native ExponentFileSystem module found, are you sure the expo-file-system's module is linked properly?"); 8} 9// Prevent webpack from pruning this. 10const _unused = new EventEmitter(ExponentFileSystem); // eslint-disable-line 11function normalizeEndingSlash(p) { 12 if (p != null) { 13 return p.replace(/\/*$/, '') + '/'; 14 } 15 return null; 16} 17/** 18 * `file://` URI pointing to the directory where user documents for this app will be stored. 19 * Files stored here will remain until explicitly deleted by the app. Ends with a trailing `/`. 20 * Example uses are for files the user saves that they expect to see again. 21 */ 22export const documentDirectory = normalizeEndingSlash(ExponentFileSystem.documentDirectory); 23/** 24 * `file://` URI pointing to the directory where temporary files used by this app will be stored. 25 * Files stored here may be automatically deleted by the system when low on storage. 26 * Example uses are for downloaded or generated files that the app just needs for one-time usage. 27 */ 28export const cacheDirectory = normalizeEndingSlash(ExponentFileSystem.cacheDirectory); 29// @docsMissing 30export const { bundledAssets, bundleDirectory } = ExponentFileSystem; 31/** 32 * Get metadata information about a file, directory or external content/asset. 33 * @param fileUri URI to the file or directory. See [supported URI schemes](#supported-uri-schemes). 34 * @param options A map of options represented by [`GetInfoAsyncOptions`](#getinfoasyncoptions) type. 35 * @return A Promise that resolves to a `FileInfo` object. If no item exists at this URI, 36 * the returned Promise resolves to `FileInfo` object in form of `{ exists: false, isDirectory: false }`. 37 */ 38export async function getInfoAsync(fileUri, options = {}) { 39 if (!ExponentFileSystem.getInfoAsync) { 40 throw new UnavailabilityError('expo-file-system', 'getInfoAsync'); 41 } 42 return await ExponentFileSystem.getInfoAsync(fileUri, options); 43} 44/** 45 * 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. 46 * @param fileUri `file://` or [SAF](#saf-uri) URI to the file or directory. 47 * @param options A map of read options represented by [`ReadingOptions`](#readingoptions) type. 48 * @return A Promise that resolves to a string containing the entire contents of the file. 49 */ 50export async function readAsStringAsync(fileUri, options = {}) { 51 if (!ExponentFileSystem.readAsStringAsync) { 52 throw new UnavailabilityError('expo-file-system', 'readAsStringAsync'); 53 } 54 return await ExponentFileSystem.readAsStringAsync(fileUri, options); 55} 56/** 57 * Takes a `file://` URI and converts it into content URI (`content://`) so that it can be accessed by other applications outside of Expo. 58 * @param fileUri The local URI of the file. If there is no file at this URI, an exception will be thrown. 59 * @example 60 * ```js 61 * FileSystem.getContentUriAsync(uri).then(cUri => { 62 * console.log(cUri); 63 * IntentLauncher.startActivityAsync('android.intent.action.VIEW', { 64 * data: cUri, 65 * flags: 1, 66 * }); 67 * }); 68 * ``` 69 * @return Returns a Promise that resolves to a `string` containing a `content://` URI pointing to the file. 70 * The URI is the same as the `fileUri` input parameter but in a different format. 71 * @platform android 72 */ 73export async function getContentUriAsync(fileUri) { 74 if (Platform.OS === 'android') { 75 if (!ExponentFileSystem.getContentUriAsync) { 76 throw new UnavailabilityError('expo-file-system', 'getContentUriAsync'); 77 } 78 return await ExponentFileSystem.getContentUriAsync(fileUri); 79 } 80 else { 81 return fileUri; 82 } 83} 84/** 85 * Write the entire contents of a file as a string. 86 * @param fileUri `file://` or [SAF](#saf-uri) URI to the file or directory. 87 * > Note: when you're using SAF URI the file needs to exist. You can't create a new file. 88 * @param contents The string to replace the contents of the file with. 89 * @param options A map of write options represented by [`WritingOptions`](#writingoptions) type. 90 */ 91export async function writeAsStringAsync(fileUri, contents, options = {}) { 92 if (!ExponentFileSystem.writeAsStringAsync) { 93 throw new UnavailabilityError('expo-file-system', 'writeAsStringAsync'); 94 } 95 return await ExponentFileSystem.writeAsStringAsync(fileUri, contents, options); 96} 97/** 98 * Delete a file or directory. If the URI points to a directory, the directory and all its contents are recursively deleted. 99 * @param fileUri `file://` or [SAF](#saf-uri) URI to the file or directory. 100 * @param options A map of write options represented by [`DeletingOptions`](#deletingoptions) type. 101 */ 102export async function deleteAsync(fileUri, options = {}) { 103 if (!ExponentFileSystem.deleteAsync) { 104 throw new UnavailabilityError('expo-file-system', 'deleteAsync'); 105 } 106 return await ExponentFileSystem.deleteAsync(fileUri, options); 107} 108export async function deleteLegacyDocumentDirectoryAndroid() { 109 if (Platform.OS !== 'android' || documentDirectory == null) { 110 return; 111 } 112 const legacyDocumentDirectory = `${documentDirectory}ExperienceData/`; 113 return await deleteAsync(legacyDocumentDirectory, { idempotent: true }); 114} 115/** 116 * Move a file or directory to a new location. 117 * @param options A map of move options represented by [`RelocatingOptions`](#relocatingoptions) type. 118 */ 119export async function moveAsync(options) { 120 if (!ExponentFileSystem.moveAsync) { 121 throw new UnavailabilityError('expo-file-system', 'moveAsync'); 122 } 123 return await ExponentFileSystem.moveAsync(options); 124} 125/** 126 * Create a copy of a file or directory. Directories are recursively copied with all of their contents. 127 * It can be also used to copy content shared by other apps to local filesystem. 128 * @param options A map of move options represented by [`RelocatingOptions`](#relocatingoptions) type. 129 */ 130export async function copyAsync(options) { 131 if (!ExponentFileSystem.copyAsync) { 132 throw new UnavailabilityError('expo-file-system', 'copyAsync'); 133 } 134 return await ExponentFileSystem.copyAsync(options); 135} 136/** 137 * Create a new empty directory. 138 * @param fileUri `file://` URI to the new directory to create. 139 * @param options A map of create directory options represented by [`MakeDirectoryOptions`](#makedirectoryoptions) type. 140 */ 141export async function makeDirectoryAsync(fileUri, options = {}) { 142 if (!ExponentFileSystem.makeDirectoryAsync) { 143 throw new UnavailabilityError('expo-file-system', 'makeDirectoryAsync'); 144 } 145 return await ExponentFileSystem.makeDirectoryAsync(fileUri, options); 146} 147/** 148 * Enumerate the contents of a directory. 149 * @param fileUri `file://` URI to the directory. 150 * @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`. 151 */ 152export async function readDirectoryAsync(fileUri) { 153 if (!ExponentFileSystem.readDirectoryAsync) { 154 throw new UnavailabilityError('expo-file-system', 'readDirectoryAsync'); 155 } 156 return await ExponentFileSystem.readDirectoryAsync(fileUri); 157} 158/** 159 * 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. 160 * @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) 161 * if the capacity is greater than 2<sup>53</sup> - 1 bytes. 162 */ 163export async function getFreeDiskStorageAsync() { 164 if (!ExponentFileSystem.getFreeDiskStorageAsync) { 165 throw new UnavailabilityError('expo-file-system', 'getFreeDiskStorageAsync'); 166 } 167 return await ExponentFileSystem.getFreeDiskStorageAsync(); 168} 169/** 170 * 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. 171 * @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) 172 * if the capacity is greater than 2<sup>53</sup> - 1 bytes. 173 */ 174export async function getTotalDiskCapacityAsync() { 175 if (!ExponentFileSystem.getTotalDiskCapacityAsync) { 176 throw new UnavailabilityError('expo-file-system', 'getTotalDiskCapacityAsync'); 177 } 178 return await ExponentFileSystem.getTotalDiskCapacityAsync(); 179} 180/** 181 * 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. 182 * @param uri The remote URI to download from. 183 * @param fileUri The local URI of the file to download to. If there is no file at this URI, a new one is created. 184 * If there is a file at this URI, its contents are replaced. The directory for the file must exist. 185 * @param options A map of download options represented by [`DownloadOptions`](#downloadoptions) type. 186 * @example 187 * ```js 188 * FileSystem.downloadAsync( 189 * 'http://techslides.com/demos/sample-videos/small.mp4', 190 * FileSystem.documentDirectory + 'small.mp4' 191 * ) 192 * .then(({ uri }) => { 193 * console.log('Finished downloading to ', uri); 194 * }) 195 * .catch(error => { 196 * console.error(error); 197 * }); 198 * ``` 199 * @return Returns a Promise that resolves to a `FileSystemDownloadResult` object. 200 */ 201export async function downloadAsync(uri, fileUri, options = {}) { 202 if (!ExponentFileSystem.downloadAsync) { 203 throw new UnavailabilityError('expo-file-system', 'downloadAsync'); 204 } 205 return await ExponentFileSystem.downloadAsync(uri, fileUri, { 206 sessionType: FileSystemSessionType.BACKGROUND, 207 ...options, 208 }); 209} 210/** 211 * Upload the contents of the file pointed by `fileUri` to the remote url. 212 * @param url The remote URL, where the file will be sent. 213 * @param fileUri The local URI of the file to send. The file must exist. 214 * @param options A map of download options represented by [`FileSystemUploadOptions`](#filesystemuploadoptions) type. 215 * @example 216 * **Client** 217 * 218 * ```js 219 * import * as FileSystem from 'expo-file-system'; 220 * 221 * try { 222 * const response = await FileSystem.uploadAsync(`http://192.168.0.1:1234/binary-upload`, fileUri, { 223 * fieldName: 'file', 224 * httpMethod: 'PATCH', 225 * uploadType: FileSystem.FileSystemUploadType.BINARY_CONTENT, 226 * }); 227 * console.log(JSON.stringify(response, null, 4)); 228 * } catch (error) { 229 * console.log(error); 230 * } 231 * ``` 232 * 233 * **Server** 234 * 235 * Please refer to the "[Server: Handling multipart requests](#server-handling-multipart-requests)" example - there is code for a simple Node.js server. 236 * @return Returns a Promise that resolves to `FileSystemUploadResult` object. 237 */ 238export async function uploadAsync(url, fileUri, options = {}) { 239 if (!ExponentFileSystem.uploadAsync) { 240 throw new UnavailabilityError('expo-file-system', 'uploadAsync'); 241 } 242 return await ExponentFileSystem.uploadAsync(url, fileUri, { 243 sessionType: FileSystemSessionType.BACKGROUND, 244 uploadType: FileSystemUploadType.BINARY_CONTENT, 245 ...options, 246 httpMethod: (options.httpMethod || 'POST').toUpperCase(), 247 }); 248} 249/** 250 * 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. 251 * > Note: You need to call `downloadAsync()`, on a `DownloadResumable` instance to initiate the download. 252 * The `DownloadResumable` object has a callback that provides download progress updates. 253 * Downloads can be resumed across app restarts by using `AsyncStorage` to store the `DownloadResumable.savable()` object for later retrieval. 254 * The `savable` object contains the arguments required to initialize a new `DownloadResumable` object to resume the download after an app restart. 255 * The directory for a local file uri must exist prior to calling this function. 256 * @param uri The remote URI to download from. 257 * @param fileUri The local URI of the file to download to. If there is no file at this URI, a new one is created. 258 * If there is a file at this URI, its contents are replaced. The directory for the file must exist. 259 * @param options A map of download options represented by [`DownloadOptions`](#downloadoptions) type. 260 * @param callback This function is called on each data write to update the download progress. 261 * > **Note**: When the app has been moved to the background, this callback won't be fired until it's moved to the foreground. 262 * @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. 263 * When initializing a new `DownloadResumable` this should be `null`. 264 */ 265export function createDownloadResumable(uri, fileUri, options, callback, resumeData) { 266 return new DownloadResumable(uri, fileUri, options, callback, resumeData); 267} 268export function createUploadTask(url, fileUri, options, callback) { 269 return new UploadTask(url, fileUri, options, callback); 270} 271export class FileSystemCancellableNetworkTask { 272 _uuid = uuidv4(); 273 taskWasCanceled = false; 274 emitter = new EventEmitter(ExponentFileSystem); 275 subscription; 276 // @docsMissing 277 async cancelAsync() { 278 if (!ExponentFileSystem.networkTaskCancelAsync) { 279 throw new UnavailabilityError('expo-file-system', 'networkTaskCancelAsync'); 280 } 281 this.removeSubscription(); 282 this.taskWasCanceled = true; 283 return await ExponentFileSystem.networkTaskCancelAsync(this.uuid); 284 } 285 isTaskCancelled() { 286 if (this.taskWasCanceled) { 287 console.warn('This task was already canceled.'); 288 return true; 289 } 290 return false; 291 } 292 get uuid() { 293 return this._uuid; 294 } 295 addSubscription() { 296 if (this.subscription) { 297 return; 298 } 299 this.subscription = this.emitter.addListener(this.getEventName(), (event) => { 300 if (event.uuid === this.uuid) { 301 const callback = this.getCallback(); 302 if (callback) { 303 callback(event.data); 304 } 305 } 306 }); 307 } 308 removeSubscription() { 309 if (!this.subscription) { 310 return; 311 } 312 this.emitter.removeSubscription(this.subscription); 313 this.subscription = null; 314 } 315} 316export class UploadTask extends FileSystemCancellableNetworkTask { 317 url; 318 fileUri; 319 callback; 320 options; 321 constructor(url, fileUri, options, callback) { 322 super(); 323 this.url = url; 324 this.fileUri = fileUri; 325 this.callback = callback; 326 const httpMethod = (options?.httpMethod?.toUpperCase() || 327 'POST'); 328 this.options = { 329 sessionType: FileSystemSessionType.BACKGROUND, 330 uploadType: FileSystemUploadType.BINARY_CONTENT, 331 ...options, 332 httpMethod, 333 }; 334 } 335 getEventName() { 336 return 'expo-file-system.uploadProgress'; 337 } 338 getCallback() { 339 return this.callback; 340 } 341 // @docsMissing 342 async uploadAsync() { 343 if (!ExponentFileSystem.uploadTaskStartAsync) { 344 throw new UnavailabilityError('expo-file-system', 'uploadTaskStartAsync'); 345 } 346 if (this.isTaskCancelled()) { 347 return; 348 } 349 this.addSubscription(); 350 const result = await ExponentFileSystem.uploadTaskStartAsync(this.url, this.fileUri, this.uuid, this.options); 351 this.removeSubscription(); 352 return result; 353 } 354} 355export class DownloadResumable extends FileSystemCancellableNetworkTask { 356 url; 357 _fileUri; 358 options; 359 callback; 360 resumeData; 361 constructor(url, _fileUri, options = {}, callback, resumeData) { 362 super(); 363 this.url = url; 364 this._fileUri = _fileUri; 365 this.options = options; 366 this.callback = callback; 367 this.resumeData = resumeData; 368 } 369 get fileUri() { 370 return this._fileUri; 371 } 372 getEventName() { 373 return 'expo-file-system.downloadProgress'; 374 } 375 getCallback() { 376 return this.callback; 377 } 378 /** 379 * Download the contents at a remote URI to a file in the app's file system. 380 * @return Returns a Promise that resolves to `FileSystemDownloadResult` object, or to `undefined` when task was cancelled. 381 */ 382 async downloadAsync() { 383 if (!ExponentFileSystem.downloadResumableStartAsync) { 384 throw new UnavailabilityError('expo-file-system', 'downloadResumableStartAsync'); 385 } 386 if (this.isTaskCancelled()) { 387 return; 388 } 389 this.addSubscription(); 390 return await ExponentFileSystem.downloadResumableStartAsync(this.url, this._fileUri, this.uuid, this.options, this.resumeData); 391 } 392 /** 393 * Pause the current download operation. `resumeData` is added to the `DownloadResumable` object after a successful pause operation. 394 * Returns an object that can be saved with `AsyncStorage` for future retrieval (the same object that is returned from calling `FileSystem.DownloadResumable.savable()`). 395 * @return Returns a Promise that resolves to `DownloadPauseState` object. 396 */ 397 async pauseAsync() { 398 if (!ExponentFileSystem.downloadResumablePauseAsync) { 399 throw new UnavailabilityError('expo-file-system', 'downloadResumablePauseAsync'); 400 } 401 if (this.isTaskCancelled()) { 402 return { 403 fileUri: this._fileUri, 404 options: this.options, 405 url: this.url, 406 }; 407 } 408 const pauseResult = await ExponentFileSystem.downloadResumablePauseAsync(this.uuid); 409 this.removeSubscription(); 410 if (pauseResult) { 411 this.resumeData = pauseResult.resumeData; 412 return this.savable(); 413 } 414 else { 415 throw new Error('Unable to generate a savable pause state'); 416 } 417 } 418 /** 419 * Resume a paused download operation. 420 * @return Returns a Promise that resolves to `FileSystemDownloadResult` object, or to `undefined` when task was cancelled. 421 */ 422 async resumeAsync() { 423 if (!ExponentFileSystem.downloadResumableStartAsync) { 424 throw new UnavailabilityError('expo-file-system', 'downloadResumableStartAsync'); 425 } 426 if (this.isTaskCancelled()) { 427 return; 428 } 429 this.addSubscription(); 430 return await ExponentFileSystem.downloadResumableStartAsync(this.url, this.fileUri, this.uuid, this.options, this.resumeData); 431 } 432 /** 433 * Method to get the object which can be saved with `AsyncStorage` for future retrieval. 434 * @returns Returns object in shape of `DownloadPauseState` type. 435 */ 436 savable() { 437 return { 438 url: this.url, 439 fileUri: this.fileUri, 440 options: this.options, 441 resumeData: this.resumeData, 442 }; 443 } 444} 445const baseReadAsStringAsync = readAsStringAsync; 446const baseWriteAsStringAsync = writeAsStringAsync; 447const baseDeleteAsync = deleteAsync; 448const baseMoveAsync = moveAsync; 449const baseCopyAsync = copyAsync; 450/** 451 * 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). 452 * You can read more about SAF in the [Android documentation](https://developer.android.com/guide/topics/providers/document-provider). 453 * 454 * @example 455 * # Basic Usage 456 * 457 * ```ts 458 * import { StorageAccessFramework } from 'expo-file-system'; 459 * 460 * // Requests permissions for external directory 461 * const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync(); 462 * 463 * if (permissions.granted) { 464 * // Gets SAF URI from response 465 * const uri = permissions.directoryUri; 466 * 467 * // Gets all files inside of selected directory 468 * const files = await StorageAccessFramework.readDirectoryAsync(uri); 469 * alert(`Files inside ${uri}:\n\n${JSON.stringify(files)}`); 470 * } 471 * ``` 472 * 473 * # Migrating an album 474 * 475 * ```ts 476 * import * as MediaLibrary from 'expo-media-library'; 477 * import * as FileSystem from 'expo-file-system'; 478 * const { StorageAccessFramework } = FileSystem; 479 * 480 * async function migrateAlbum(albumName: string) { 481 * // Gets SAF URI to the album 482 * const albumUri = StorageAccessFramework.getUriForDirectoryInRoot(albumName); 483 * 484 * // Requests permissions 485 * const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync(albumUri); 486 * if (!permissions.granted) { 487 * return; 488 * } 489 * 490 * const permittedUri = permissions.directoryUri; 491 * // Checks if users selected the correct folder 492 * if (!permittedUri.includes(albumName)) { 493 * return; 494 * } 495 * 496 * const mediaLibraryPermissions = await MediaLibrary.requestPermissionsAsync(); 497 * if (!mediaLibraryPermissions.granted) { 498 * return; 499 * } 500 * 501 * // Moves files from external storage to internal storage 502 * await StorageAccessFramework.moveAsync({ 503 * from: permittedUri, 504 * to: FileSystem.documentDirectory!, 505 * }); 506 * 507 * const outputDir = FileSystem.documentDirectory! + albumName; 508 * const migratedFiles = await FileSystem.readDirectoryAsync(outputDir); 509 * 510 * // Creates assets from local files 511 * const [newAlbumCreator, ...assets] = await Promise.all( 512 * migratedFiles.map<Promise<MediaLibrary.Asset>>( 513 * async fileName => await MediaLibrary.createAssetAsync(outputDir + '/' + fileName) 514 * ) 515 * ); 516 * 517 * // Album was empty 518 * if (!newAlbumCreator) { 519 * return; 520 * } 521 * 522 * // Creates a new album in the scoped directory 523 * const newAlbum = await MediaLibrary.createAlbumAsync(albumName, newAlbumCreator, false); 524 * if (assets.length) { 525 * await MediaLibrary.addAssetsToAlbumAsync(assets, newAlbum, false); 526 * } 527 * } 528 * ``` 529 * @platform Android 530 */ 531export var StorageAccessFramework; 532(function (StorageAccessFramework) { 533 /** 534 * Gets a [SAF URI](#saf-uri) pointing to a folder in the Android root directory. You can use this function to get URI for 535 * `StorageAccessFramework.requestDirectoryPermissionsAsync()` when you trying to migrate an album. In that case, the name of the album is the folder name. 536 * @param folderName The name of the folder which is located in the Android root directory. 537 * @return Returns a [SAF URI](#saf-uri) to a folder. 538 */ 539 function getUriForDirectoryInRoot(folderName) { 540 return `content://com.android.externalstorage.documents/tree/primary:${folderName}/document/primary:${folderName}`; 541 } 542 StorageAccessFramework.getUriForDirectoryInRoot = getUriForDirectoryInRoot; 543 /** 544 * Allows users to select a specific directory, granting your app access to all of the files and sub-directories within that directory. 545 * @param initialFileUrl The [SAF URI](#saf-uri) of the directory that the file picker should display when it first loads. 546 * If URI is incorrect or points to a non-existing folder, it's ignored. 547 * @platform android 11+ 548 * @return Returns a Promise that resolves to `FileSystemRequestDirectoryPermissionsResult` object. 549 */ 550 async function requestDirectoryPermissionsAsync(initialFileUrl = null) { 551 if (!ExponentFileSystem.requestDirectoryPermissionsAsync) { 552 throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.requestDirectoryPermissionsAsync'); 553 } 554 return await ExponentFileSystem.requestDirectoryPermissionsAsync(initialFileUrl); 555 } 556 StorageAccessFramework.requestDirectoryPermissionsAsync = requestDirectoryPermissionsAsync; 557 /** 558 * Enumerate the contents of a directory. 559 * @param dirUri [SAF](#saf-uri) URI to the directory. 560 * @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`. 561 */ 562 async function readDirectoryAsync(dirUri) { 563 if (!ExponentFileSystem.readSAFDirectoryAsync) { 564 throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.readDirectoryAsync'); 565 } 566 return await ExponentFileSystem.readSAFDirectoryAsync(dirUri); 567 } 568 StorageAccessFramework.readDirectoryAsync = readDirectoryAsync; 569 /** 570 * Creates a new empty directory. 571 * @param parentUri The [SAF](#saf-uri) URI to the parent directory. 572 * @param dirName The name of new directory. 573 * @return A Promise that resolves to a [SAF URI](#saf-uri) to the created directory. 574 */ 575 async function makeDirectoryAsync(parentUri, dirName) { 576 if (!ExponentFileSystem.makeSAFDirectoryAsync) { 577 throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.makeDirectoryAsync'); 578 } 579 return await ExponentFileSystem.makeSAFDirectoryAsync(parentUri, dirName); 580 } 581 StorageAccessFramework.makeDirectoryAsync = makeDirectoryAsync; 582 /** 583 * Creates a new empty file. 584 * @param parentUri The [SAF](#saf-uri) URI to the parent directory. 585 * @param fileName The name of new file **without the extension**. 586 * @param mimeType The MIME type of new file. 587 * @return A Promise that resolves to a [SAF URI](#saf-uri) to the created file. 588 */ 589 async function createFileAsync(parentUri, fileName, mimeType) { 590 if (!ExponentFileSystem.createSAFFileAsync) { 591 throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.createFileAsync'); 592 } 593 return await ExponentFileSystem.createSAFFileAsync(parentUri, fileName, mimeType); 594 } 595 StorageAccessFramework.createFileAsync = createFileAsync; 596 /** 597 * Alias for [`writeAsStringAsync`](#filesystemwriteasstringasyncfileuri-contents-options) method. 598 */ 599 StorageAccessFramework.writeAsStringAsync = baseWriteAsStringAsync; 600 /** 601 * Alias for [`readAsStringAsync`](#filesystemreadasstringasyncfileuri-options) method. 602 */ 603 StorageAccessFramework.readAsStringAsync = baseReadAsStringAsync; 604 /** 605 * Alias for [`deleteAsync`](#filesystemdeleteasyncfileuri-options) method. 606 */ 607 StorageAccessFramework.deleteAsync = baseDeleteAsync; 608 /** 609 * Alias for [`moveAsync`](#filesystemmoveasyncoptions) method. 610 */ 611 StorageAccessFramework.moveAsync = baseMoveAsync; 612 /** 613 * Alias for [`copyAsync`](#filesystemcopyasyncoptions) method. 614 */ 615 StorageAccessFramework.copyAsync = baseCopyAsync; 616})(StorageAccessFramework || (StorageAccessFramework = {})); 617//# sourceMappingURL=FileSystem.js.map