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