expo-file-system 19.1.0-canary-20250919-7a31b96 → 19.1.0-canary-20251023-4c86f95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/filesystem/FileSystemDirectory.kt +1 -1
  4. package/android/src/main/java/expo/modules/filesystem/FileSystemExceptions.kt +5 -0
  5. package/android/src/main/java/expo/modules/filesystem/FileSystemFile.kt +23 -0
  6. package/android/src/main/java/expo/modules/filesystem/{legacy/FileSystemFileProvider.kt → FileSystemFileProvider.kt} +1 -1
  7. package/android/src/main/java/expo/modules/filesystem/FileSystemModule.kt +14 -2
  8. package/android/src/main/java/expo/modules/filesystem/FileSystemNextRecords.kt +11 -0
  9. package/android/src/main/java/expo/modules/filesystem/FileSystemPath.kt +6 -16
  10. package/android/src/main/java/expo/modules/filesystem/unifiedfile/AssetFile.kt +19 -0
  11. package/android/src/main/java/expo/modules/filesystem/unifiedfile/JavaFile.kt +17 -0
  12. package/android/src/main/java/expo/modules/filesystem/unifiedfile/SAFDocumentFile.kt +14 -0
  13. package/android/src/main/java/expo/modules/filesystem/unifiedfile/UnifiedFileInterface.kt +3 -0
  14. package/build/ExpoFileSystem.types.d.ts +36 -6
  15. package/build/ExpoFileSystem.types.d.ts.map +1 -1
  16. package/build/FileSystem.d.ts +4 -4
  17. package/build/index.d.ts +1 -1
  18. package/build/index.d.ts.map +1 -1
  19. package/expo-module.config.json +1 -1
  20. package/ios/FileSystemExceptions.swift +6 -0
  21. package/ios/FileSystemFile.swift +6 -0
  22. package/ios/FileSystemModule.swift +21 -2
  23. package/ios/FileSystemPath.swift +1 -1
  24. package/ios/FileSystemRecords.swift +9 -0
  25. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95-sources.jar +0 -0
  26. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95-sources.jar.md5 +1 -0
  27. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95-sources.jar.sha1 +1 -0
  28. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95-sources.jar.sha256 +1 -0
  29. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95-sources.jar.sha512 +1 -0
  30. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.aar +0 -0
  31. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.aar.md5 +1 -0
  32. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.aar.sha1 +1 -0
  33. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.aar.sha256 +1 -0
  34. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.aar.sha512 +1 -0
  35. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/{19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.module → 19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.module} +23 -23
  36. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.module.md5 +1 -0
  37. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.module.sha1 +1 -0
  38. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.module.sha256 +1 -0
  39. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.module.sha512 +1 -0
  40. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/{19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.pom → 19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.pom} +1 -1
  41. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.pom.md5 +1 -0
  42. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.pom.sha1 +1 -0
  43. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.pom.sha256 +1 -0
  44. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20251023-4c86f95/expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.pom.sha512 +1 -0
  45. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml +4 -4
  46. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.md5 +1 -1
  47. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.sha1 +1 -1
  48. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.sha256 +1 -1
  49. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.sha512 +1 -1
  50. package/package.json +4 -4
  51. package/plugin/build/withFileSystem.d.ts +5 -1
  52. package/plugin/build/withFileSystem.js +13 -2
  53. package/plugin/src/withFileSystem.ts +25 -3
  54. package/src/ExpoFileSystem.types.ts +38 -6
  55. package/src/FileSystem.ts +4 -4
  56. package/src/index.ts +1 -0
  57. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96-sources.jar +0 -0
  58. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96-sources.jar.md5 +0 -1
  59. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96-sources.jar.sha1 +0 -1
  60. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96-sources.jar.sha256 +0 -1
  61. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96-sources.jar.sha512 +0 -1
  62. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.aar +0 -0
  63. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.aar.md5 +0 -1
  64. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.aar.sha1 +0 -1
  65. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.aar.sha256 +0 -1
  66. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.aar.sha512 +0 -1
  67. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.module.md5 +0 -1
  68. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.module.sha1 +0 -1
  69. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.module.sha256 +0 -1
  70. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.module.sha512 +0 -1
  71. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.pom.md5 +0 -1
  72. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.pom.sha1 +0 -1
  73. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.pom.sha256 +0 -1
  74. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/19.1.0-canary-20250919-7a31b96/expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.pom.sha512 +0 -1
  75. /package/android/src/main/{java/expo/modules/filesystem/AndroidManifest.xml → AndroidManifest.xml} +0 -0
package/CHANGELOG.md CHANGED
@@ -6,12 +6,33 @@
6
6
 
7
7
  ### 🎉 New features
8
8
 
9
- - add `idempotent` option to `downloadFileAsync` ([#39681](https://github.com/expo/expo/pull/39681) by [@vonovak](https://github.com/vonovak))
9
+ - [Android] Add contentUri property. ([#40002](https://github.com/expo/expo/pull/40002) by [@aleqsio](https://github.com/aleqsio))
10
10
 
11
11
  ### 🐛 Bug fixes
12
12
 
13
+ - [Android] Fix recursive file deletion. ([#40248](https://github.com/expo/expo/pull/40248) by [@aleqsio](https://github.com/aleqsio))
14
+ - [iOS] Add missing `createFile` and `createDirectory` methods. ([#40314](https://github.com/expo/expo/pull/40314) by [@jakex7](https://github.com/jakex7))
15
+
13
16
  ### 💡 Others
14
17
 
18
+ ## 19.0.16 - 2025-10-01
19
+
20
+ ### 🎉 New features
21
+
22
+ - Add write options for base64 encoded bytes. ([#39963](https://github.com/expo/expo/pull/39963) by [@aleqsio](https://github.com/aleqsio))
23
+ - [iOS] Add file sharing config options ([#39286](https://github.com/expo/expo/pull/39286) by [@kosmydel](https://github.com/kosmydel))
24
+
25
+ ### 🐛 Bug fixes
26
+
27
+ - Fix typedoc in the File class. ([#40064](https://github.com/expo/expo/pull/40064) by [@aleqsio](https://github.com/aleqsio))
28
+ - [Android] Fix getContentUri. ([#40001](https://github.com/expo/expo/pull/40001) by [@aleqsio](https://github.com/aleqsio))
29
+
30
+ ## 19.0.15 - 2025-09-22
31
+
32
+ ### 🎉 New features
33
+
34
+ - add `idempotent` option to `downloadFileAsync` ([#39681](https://github.com/expo/expo/pull/39681) by [@vonovak](https://github.com/vonovak))
35
+
15
36
  ## 19.0.14 — 2025-09-13
16
37
 
17
38
  _This version does not introduce any user-facing changes._
@@ -4,13 +4,13 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '19.1.0-canary-20250919-7a31b96'
7
+ version = '19.1.0-canary-20251023-4c86f95'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.filesystem"
11
11
  defaultConfig {
12
12
  versionCode 30
13
- versionName "19.1.0-canary-20250919-7a31b96"
13
+ versionName "19.1.0-canary-20251023-4c86f95"
14
14
  }
15
15
  }
16
16
 
@@ -56,10 +56,10 @@ class FileSystemDirectory(uri: Uri) : FileSystemPath(uri) {
56
56
  if (!needsCreation(options)) {
57
57
  return
58
58
  }
59
- validateCanCreate(options)
60
59
  if (uri.isContentUri) {
61
60
  throw UnableToCreateException("create function does not work with SAF Uris, use `createDirectory` and `createFile` instead")
62
61
  }
62
+ validateCanCreate(options)
63
63
  if (options.overwrite && file.exists()) {
64
64
  file.delete()
65
65
  }
@@ -44,6 +44,11 @@ internal class UnableToWriteHandleException(reason: String) :
44
44
  "Unable to write to a file handle: '$reason'"
45
45
  )
46
46
 
47
+ internal class MissingAppContextException :
48
+ CodedException(
49
+ "The app context is missing."
50
+ )
51
+
47
52
  internal class PickerCancelledException :
48
53
  CodedException("The file picker was cancelled by the user")
49
54
 
@@ -80,6 +80,23 @@ class FileSystemFile(uri: Uri) : FileSystemPath(uri) {
80
80
  }
81
81
  }
82
82
 
83
+ fun write(content: ByteArray) {
84
+ validateType()
85
+ validatePermission(Permission.WRITE)
86
+ if (!exists) {
87
+ create()
88
+ }
89
+ if (uri.isContentUri) {
90
+ file.outputStream().use { outputStream ->
91
+ outputStream.write(content)
92
+ }
93
+ } else {
94
+ FileOutputStream(javaFile).use {
95
+ it.write(content)
96
+ }
97
+ }
98
+ }
99
+
83
100
  fun asString(): String {
84
101
  val uriString = file.uri.toString()
85
102
  return if (uriString.endsWith("/")) uriString.dropLast(1) else uriString
@@ -109,6 +126,12 @@ class FileSystemFile(uri: Uri) : FileSystemPath(uri) {
109
126
  }
110
127
  }
111
128
 
129
+ fun asContentUri(): Uri {
130
+ validateType()
131
+ validatePermission(Permission.READ)
132
+ return file.getContentUri(appContext ?: throw MissingAppContextException())
133
+ }
134
+
112
135
  @OptIn(ExperimentalStdlibApi::class)
113
136
  val md5: String get() {
114
137
  validatePermission(Permission.READ)
@@ -1,4 +1,4 @@
1
- package expo.modules.filesystem.legacy
1
+ package expo.modules.filesystem
2
2
 
3
3
  import androidx.core.content.FileProvider
4
4
 
@@ -2,7 +2,10 @@ package expo.modules.filesystem
2
2
 
3
3
  import android.content.Context
4
4
  import android.net.Uri
5
+ import android.os.Build
6
+ import android.util.Base64
5
7
  import android.webkit.URLUtil
8
+ import androidx.annotation.RequiresApi
6
9
  import expo.modules.interfaces.filesystem.Permission
7
10
  import expo.modules.kotlin.activityresult.AppContextActivityResultLauncher
8
11
  import expo.modules.kotlin.apifeatures.EitherType
@@ -24,6 +27,7 @@ class FileSystemModule : Module() {
24
27
  private val context: Context
25
28
  get() = appContext.reactContext ?: throw Exceptions.AppContextLost()
26
29
 
30
+ @RequiresApi(Build.VERSION_CODES.O)
27
31
  @OptIn(EitherType::class)
28
32
  override fun definition() = ModuleDefinition {
29
33
  Name("FileSystem")
@@ -138,10 +142,14 @@ class FileSystemModule : Module() {
138
142
  file.create(options ?: CreateOptions())
139
143
  }
140
144
 
141
- Function("write") { file: FileSystemFile, content: Either<String, TypedArray> ->
145
+ Function("write") { file: FileSystemFile, content: Either<String, TypedArray>, options: WriteOptions? ->
142
146
  if (content.`is`(String::class)) {
143
147
  content.get(String::class).let {
144
- file.write(it)
148
+ if (options?.encoding == EncodingType.BASE64) {
149
+ file.write(Base64.decode(it, Base64.DEFAULT))
150
+ } else {
151
+ file.write(it)
152
+ }
145
153
  }
146
154
  }
147
155
  if (content.`is`(TypedArray::class)) {
@@ -207,6 +215,10 @@ class FileSystemModule : Module() {
207
215
  file.asString()
208
216
  }
209
217
 
218
+ Property("contentUri") { file ->
219
+ file.asContentUri()
220
+ }
221
+
210
222
  Property("md5") { file ->
211
223
  try {
212
224
  file.md5
@@ -2,6 +2,7 @@ package expo.modules.filesystem
2
2
 
3
3
  import expo.modules.kotlin.records.Field
4
4
  import expo.modules.kotlin.records.Record
5
+ import expo.modules.kotlin.types.Enumerable
5
6
 
6
7
  data class InfoOptions(
7
8
  @Field
@@ -17,6 +18,16 @@ data class CreateOptions(
17
18
  val idempotent: Boolean = false
18
19
  ) : Record
19
20
 
21
+ enum class EncodingType(val value: String) : Enumerable {
22
+ UTF8("utf8"),
23
+ BASE64("base64")
24
+ }
25
+
26
+ data class WriteOptions(
27
+ @Field
28
+ val encoding: EncodingType = EncodingType.UTF8
29
+ ) : Record
30
+
20
31
  data class DownloadOptions(
21
32
  @Field
22
33
  val headers: Map<String, String> = emptyMap(),
@@ -62,23 +62,13 @@ abstract class FileSystemPath(var uri: Uri) : SharedObject() {
62
62
  throw UnableToDeleteException("uri '${file.uri}' does not exist")
63
63
  }
64
64
  if (file.isDirectory()) {
65
- file.listFilesAsUnified().forEach { child ->
66
- if (child.isDirectory()) {
67
- // Recursively delete subdirectories
68
- if (uri.isContentUri) {
69
- SAFDocumentFile(appContext?.reactContext ?: throw Exception("No context"), child.uri).delete()
70
- } else {
71
- JavaFile(child.uri).delete()
72
- }
73
- } else {
74
- if (!child.delete()) {
75
- throw UnableToDeleteException("failed to delete '${child.uri}'")
76
- }
77
- }
65
+ if (!file.deleteRecursively()) {
66
+ throw UnableToDeleteException("failed to delete '${file.uri}'")
67
+ }
68
+ } else {
69
+ if (!file.delete()) {
70
+ throw UnableToDeleteException("failed to delete '${file.uri}'")
78
71
  }
79
- }
80
- if (!file.delete()) {
81
- throw UnableToDeleteException("failed to delete '${file.uri}'")
82
72
  }
83
73
  }
84
74
 
@@ -4,7 +4,9 @@ import android.content.Context
4
4
  import android.net.Uri
5
5
  import android.webkit.MimeTypeMap
6
6
  import androidx.core.net.toUri
7
+ import expo.modules.kotlin.AppContext
7
8
  import java.io.File
9
+ import java.io.FileOutputStream
8
10
  import java.io.InputStream
9
11
  import java.io.OutputStream
10
12
 
@@ -25,6 +27,21 @@ class AssetFile(private val context: Context, override val uri: Uri) : UnifiedFi
25
27
  }
26
28
  }
27
29
 
30
+ // Cache the content URI to avoid redundant file writes – assets are read-only
31
+ var contentUri: Uri? = null
32
+ override fun getContentUri(appContext: AppContext): Uri {
33
+ inputStream().use { inputStream ->
34
+ val outputFile = File(context.cacheDir, "expo_shared_assets/$fileName")
35
+ outputFile.parentFile?.mkdirs() // Create directories if needed
36
+ FileOutputStream(outputFile).use { outputStream ->
37
+ inputStream.copyTo(outputStream)
38
+ }
39
+ val newContentUri = JavaFile(outputFile.toUri()).getContentUri(appContext)
40
+ contentUri = newContentUri
41
+ return newContentUri
42
+ }
43
+ }
44
+
28
45
  override val parentFile: UnifiedFileInterface?
29
46
  get() {
30
47
  val currentPath = uri.path.orEmpty()
@@ -48,6 +65,8 @@ class AssetFile(private val context: Context, override val uri: Uri) : UnifiedFi
48
65
 
49
66
  override fun delete(): Boolean = throw UnsupportedOperationException("Asset files are not writable and cannot be deleted")
50
67
 
68
+ override fun deleteRecursively(): Boolean = throw UnsupportedOperationException("Asset files are not writable and cannot be deleted")
69
+
51
70
  override fun listFilesAsUnified(): List<UnifiedFileInterface> {
52
71
  val list = context.assets.list(path)
53
72
  return list?.map { name -> AssetFile(context, File(path, name).toUri()) as UnifiedFileInterface } ?: emptyList()
@@ -3,7 +3,9 @@ package expo.modules.filesystem.unifiedfile
3
3
  import android.net.Uri
4
4
  import android.os.Build
5
5
  import android.webkit.MimeTypeMap
6
+ import androidx.core.content.FileProvider
6
7
  import androidx.core.net.toUri
8
+ import expo.modules.kotlin.AppContext
7
9
  import java.io.File
8
10
  import java.io.FileInputStream
9
11
  import java.io.FileOutputStream
@@ -31,6 +33,21 @@ class JavaFile(override val uri: Uri) : UnifiedFileInterface, File(URI.create(ur
31
33
  return JavaFile(childFile.toUri())
32
34
  }
33
35
 
36
+ override fun deleteRecursively(): Boolean {
37
+ if (isDirectory) {
38
+ listFiles()?.forEach { it.deleteRecursively() }
39
+ }
40
+ return super<File>.delete()
41
+ }
42
+
43
+ override fun getContentUri(appContext: AppContext): Uri {
44
+ return FileProvider.getUriForFile(
45
+ appContext.throwingActivity.application,
46
+ "${appContext.throwingActivity.application.packageName}.FileSystemFileProvider",
47
+ this
48
+ )
49
+ }
50
+
34
51
  override fun listFilesAsUnified(): List<UnifiedFileInterface> =
35
52
  super<File>.listFiles()?.map { JavaFile(it.toUri()) } ?: emptyList()
36
53
 
@@ -3,6 +3,7 @@ package expo.modules.filesystem.unifiedfile
3
3
  import android.content.Context
4
4
  import android.net.Uri
5
5
  import androidx.documentfile.provider.DocumentFile
6
+ import expo.modules.kotlin.AppContext
6
7
  import java.io.InputStream
7
8
  import java.io.OutputStream
8
9
 
@@ -45,6 +46,8 @@ class SAFDocumentFile(private val context: Context, override val uri: Uri) : Uni
45
46
 
46
47
  override fun delete(): Boolean = documentFile?.delete() == true
47
48
 
49
+ override fun deleteRecursively(): Boolean = documentFile?.deleteRecursively() == true
50
+
48
51
  override fun listFilesAsUnified(): List<UnifiedFileInterface> =
49
52
  documentFile?.listFiles()?.map { SAFDocumentFile(context, it.uri) } ?: emptyList()
50
53
 
@@ -58,6 +61,10 @@ class SAFDocumentFile(private val context: Context, override val uri: Uri) : Uni
58
61
  override val fileName: String?
59
62
  get() = documentFile?.name
60
63
 
64
+ override fun getContentUri(appContext: AppContext): Uri {
65
+ return uri
66
+ }
67
+
61
68
  override val creationTime: Long? get() {
62
69
  // It seems there's no way to get this
63
70
  return null
@@ -88,3 +95,10 @@ class SAFDocumentFile(private val context: Context, override val uri: Uri) : Uni
88
95
  }
89
96
  }
90
97
  }
98
+
99
+ fun DocumentFile.deleteRecursively(): Boolean {
100
+ if (isDirectory) {
101
+ listFiles().forEach { it.deleteRecursively() }
102
+ }
103
+ return delete()
104
+ }
@@ -1,6 +1,7 @@
1
1
  package expo.modules.filesystem.unifiedfile
2
2
 
3
3
  import android.net.Uri
4
+ import expo.modules.kotlin.AppContext
4
5
 
5
6
  interface UnifiedFileInterface {
6
7
  fun exists(): Boolean
@@ -10,12 +11,14 @@ interface UnifiedFileInterface {
10
11
  fun createFile(mimeType: String, displayName: String): UnifiedFileInterface?
11
12
  fun createDirectory(displayName: String): UnifiedFileInterface?
12
13
  fun delete(): Boolean
14
+ fun deleteRecursively(): Boolean
13
15
  fun listFilesAsUnified(): List<UnifiedFileInterface>
14
16
  val uri: Uri
15
17
  val type: String?
16
18
  fun lastModified(): Long?
17
19
  val creationTime: Long?
18
20
  val fileName: String?
21
+ fun getContentUri(appContext: AppContext): Uri
19
22
  fun outputStream(): java.io.OutputStream
20
23
  fun inputStream(): java.io.InputStream
21
24
  fun length(): Long
@@ -10,6 +10,23 @@ export type FileCreateOptions = {
10
10
  */
11
11
  overwrite?: boolean;
12
12
  };
13
+ export declare enum EncodingType {
14
+ /**
15
+ * Standard encoding format.
16
+ */
17
+ UTF8 = "utf8",
18
+ /**
19
+ * Binary, radix-64 representation.
20
+ */
21
+ Base64 = "base64"
22
+ }
23
+ export type FileWriteOptions = {
24
+ /**
25
+ * The encoding format to use when writing the file.
26
+ * @default FileSystem.EncodingType.UTF8
27
+ */
28
+ encoding?: EncodingType | 'utf8' | 'base64';
29
+ };
13
30
  export type DirectoryCreateOptions = {
14
31
  /**
15
32
  * Whether to create intermediate directories if they do not exist.
@@ -167,7 +184,7 @@ export declare class File {
167
184
  * Retrieves content of the file as base64.
168
185
  * @returns A promise that resolves with the contents of the file as a base64 string.
169
186
  */
170
- base64(): string;
187
+ base64(): Promise<string>;
171
188
  /**
172
189
  * Retrieves content of the file as base64.
173
190
  * @returns The contents of the file as a base64 string.
@@ -175,19 +192,19 @@ export declare class File {
175
192
  base64Sync(): string;
176
193
  /**
177
194
  * Retrieves byte content of the entire file.
178
- * @returns A promise that resolves with the contents of the file as a Uint8Array.
195
+ * @returns A promise that resolves with the contents of the file as a `Uint8Array`.
179
196
  */
180
197
  bytes(): Promise<Uint8Array<ArrayBuffer>>;
181
198
  /**
182
199
  * Retrieves byte content of the entire file.
183
- * @returns A promise that resolves with the contents of the file as a Uint8Array.
200
+ * @returns The contents of the file as a `Uint8Array`.
184
201
  */
185
202
  bytesSync(): Uint8Array;
186
203
  /**
187
204
  * Writes content to the file.
188
205
  * @param content The content to write into the file.
189
206
  */
190
- write(content: string | Uint8Array): void;
207
+ write(content: string | Uint8Array, options?: FileWriteOptions): void;
191
208
  /**
192
209
  * Deletes a file.
193
210
  *
@@ -231,10 +248,18 @@ export declare class File {
231
248
  /**
232
249
  * A static method that downloads a file from the network.
233
250
  *
251
+ * On Android, the response body streams directly into the target file. If the download fails after
252
+ * it starts, a partially written file may remain at the destination. On iOS, the download first
253
+ * completes in a temporary location and the file is moved into place only after success, so no
254
+ * file is left behind when the request fails.
255
+ *
234
256
  * @param url - The URL of the file to download.
235
257
  * @param destination - The destination directory or file. If a directory is provided, the resulting filename will be determined based on the response headers.
258
+ * @param options - Download options. When the destination already contains a file, the promise rejects with a `DestinationAlreadyExists` error unless `options.idempotent` is set to `true`. With `idempotent: true`, the download overwrites the existing file instead of failing.
236
259
  *
237
- * @returns A promise that resolves to the downloaded file.
260
+ * @returns A promise that resolves to the downloaded file. When the server responds with
261
+ * a non-2xx HTTP status, the promise rejects with an `UnableToDownload` error whose
262
+ * message includes the status code. No file is created in that scenario.
238
263
  *
239
264
  * @example
240
265
  * ```ts
@@ -249,7 +274,7 @@ export declare class File {
249
274
  *
250
275
  * @param initialUri An optional URI pointing to an initial folder on which the file picker is opened.
251
276
  * @param mimeType A mime type that is used to filter out files that can be picked out.
252
- * @returns a `File` instance or an array of `File` instances.
277
+ * @returns A `File` instance or an array of `File` instances.
253
278
  */
254
279
  static pickFileAsync(initialUri?: string, mimeType?: string): Promise<File | File[]>;
255
280
  /**
@@ -272,6 +297,11 @@ export declare class File {
272
297
  * A mime type of the file. An empty string if the file does not exist, or it cannot be read.
273
298
  */
274
299
  type: string;
300
+ /**
301
+ * A content URI to the file that can be shared to external applications.
302
+ * @platform android
303
+ */
304
+ contentUri: string;
275
305
  }
276
306
  export declare class FileHandle {
277
307
  close(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoFileSystem.types.d.ts","sourceRoot":"","sources":["../src/ExpoFileSystem.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ExpoFileSystem.types.d.ts","sourceRoot":"","sources":["../src/ExpoFileSystem.types.ts"],"names":[],"mappings":"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"}
@@ -36,7 +36,7 @@ export declare class Paths extends PathUtilities {
36
36
  * The constructor accepts an array of strings that are joined to create the file URI. The first argument can also be a `Directory` instance (like `Paths.cache`) or a `File` instance (which creates a new reference to the same file).
37
37
  * @example
38
38
  * ```ts
39
- * const file = new File(File.cache, "subdirName", "file.txt");
39
+ * const file = new File(Paths.cache, "subdirName", "file.txt");
40
40
  * ```
41
41
  */
42
42
  export declare class File extends ExpoFileSystem.FileSystemFile implements Blob {
@@ -47,7 +47,7 @@ export declare class File extends ExpoFileSystem.FileSystemFile implements Blob
47
47
  * @param uris An array of: `file:///` string URIs, `File` instances, and `Directory` instances representing an arbitrary location on the file system.
48
48
  * @example
49
49
  * ```ts
50
- * const file = new File(File.cache, "subdirName", "file.txt");
50
+ * const file = new File(Paths.cache, "subdirName", "file.txt");
51
51
  * ```
52
52
  */
53
53
  constructor(...uris: (string | File | Directory)[]);
@@ -75,7 +75,7 @@ export declare class File extends ExpoFileSystem.FileSystemFile implements Blob
75
75
  * The constructor accepts an array of strings that are joined to create the directory URI. The first argument can also be a `Directory` instance (like `Paths.cache`).
76
76
  * @example
77
77
  * ```ts
78
- * const directory = new Directory(File.cache, "subdirName");
78
+ * const directory = new Directory(Paths.cache, "subdirName");
79
79
  * ```
80
80
  */
81
81
  export declare class Directory extends ExpoFileSystem.FileSystemDirectory {
@@ -86,7 +86,7 @@ export declare class Directory extends ExpoFileSystem.FileSystemDirectory {
86
86
  * @param uris An array of: `file:///` string URIs, `File` instances, and `Directory` instances representing an arbitrary location on the file system.
87
87
  * @example
88
88
  * ```ts
89
- * const directory = new Directory(File.cache, "subdirName");
89
+ * const directory = new Directory(Paths.cache, "subdirName");
90
90
  * ```
91
91
  */
92
92
  constructor(...uris: (string | File | Directory)[]);
package/build/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from './FileSystem';
2
- export { type FileCreateOptions, type DirectoryCreateOptions, type FileHandle, type FileInfo, type InfoOptions, type PathInfo, type DirectoryInfo, } from './ExpoFileSystem.types';
2
+ export { type FileCreateOptions, type DirectoryCreateOptions, type FileHandle, type FileInfo, type InfoOptions, type PathInfo, type DirectoryInfo, type DownloadOptions, } from './ExpoFileSystem.types';
3
3
  export * from './legacyWarnings';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAE7B,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC;AAEhC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAE7B,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,wBAAwB,CAAC;AAEhC,cAAc,kBAAkB,CAAC"}
@@ -12,7 +12,7 @@
12
12
  "publication": {
13
13
  "groupId": "host.exp.exponent",
14
14
  "artifactId": "expo.modules.filesystem",
15
- "version": "19.1.0-canary-20250919-7a31b96",
15
+ "version": "19.1.0-canary-20251023-4c86f95",
16
16
  "repository": "local-maven-repo"
17
17
  }
18
18
  }
@@ -13,6 +13,12 @@ internal final class UnableToDownloadException: GenericException<String> {
13
13
  }
14
14
  }
15
15
 
16
+ internal final class UnableToWriteBase64DataException: GenericException<String> {
17
+ override var reason: String {
18
+ "Unable to write base64 data to a file: \(param)"
19
+ }
20
+ }
21
+
16
22
  internal final class InvalidTypeFileException: Exception {
17
23
  override var reason: String {
18
24
  "A folder with the same name already exists in the file location"
@@ -81,6 +81,12 @@ internal final class FileSystemFile: FileSystemPath {
81
81
  }
82
82
  }
83
83
 
84
+ func write(_ data: Data) throws {
85
+ try withCorrectTypeAndScopedAccess(permission: .write) {
86
+ try data.write(to: url)
87
+ }
88
+ }
89
+
84
90
  // TODO: blob support
85
91
  func write(_ content: TypedArray) throws {
86
92
  try withCorrectTypeAndScopedAccess(permission: .write) {
@@ -202,9 +202,16 @@ public final class FileSystemModule: Module {
202
202
  return try file.info(options: options ?? InfoOptions())
203
203
  }
204
204
 
205
- Function("write") { (file, content: Either<String, TypedArray>) in
205
+ Function("write") { (file: FileSystemFile, content: Either<String, TypedArray>, options: WriteOptions?) in
206
206
  if let content: String = content.get() {
207
- try file.write(content)
207
+ if options?.encoding == WriteEncoding.base64 {
208
+ guard let data = Data(base64Encoded: content, options: .ignoreUnknownCharacters) else {
209
+ throw UnableToWriteBase64DataException(file.url.absoluteString)
210
+ }
211
+ try file.write(data)
212
+ } else {
213
+ try file.write(content)
214
+ }
208
215
  }
209
216
  if let content: TypedArray = content.get() {
210
217
  try file.write(content)
@@ -328,6 +335,18 @@ public final class FileSystemModule: Module {
328
335
  try directory.listAsRecords()
329
336
  }
330
337
 
338
+ Function("createFile") { (directory, name: String, content: String?) in
339
+ let file = FileSystemFile(url: directory.url.appendingPathComponent(name))
340
+ try file.create(CreateOptions())
341
+ return file
342
+ }
343
+
344
+ Function("createDirectory") { (directory, name: String) in
345
+ let newDirectory = FileSystemDirectory(url: directory.url.appendingPathComponent(name))
346
+ try newDirectory.create(CreateOptions())
347
+ return newDirectory
348
+ }
349
+
331
350
  Property("uri") { directory in
332
351
  return directory.url.absoluteString
333
352
  }
@@ -25,7 +25,7 @@ internal class FileSystemPath: SharedObject {
25
25
 
26
26
  func validateCanCreate(_ options: CreateOptions) throws {
27
27
  if try !options.overwrite && exists {
28
- throw FileAlreadyExistsException("File already exists")
28
+ throw FileAlreadyExistsException(url.absoluteString)
29
29
  }
30
30
  }
31
31
 
@@ -35,3 +35,12 @@ struct DirectoryInfo: Record {
35
35
  @Field var modificationTime: Int64?
36
36
  @Field var creationTime: Int64?
37
37
  }
38
+
39
+ enum WriteEncoding: String, Enumerable {
40
+ case utf8
41
+ case base64
42
+ }
43
+
44
+ struct WriteOptions: Record {
45
+ @Field var encoding: WriteEncoding?
46
+ }
@@ -0,0 +1 @@
1
+ 6cac7b2fa58a18696e1468e4e9afe7e6092ca1a404351400345349e028cbaeda51386f4303d05372a2be2baf8de77fd97490ea91caa74bfc2a8cfe7b62619bfe
@@ -0,0 +1 @@
1
+ 9e2285f94d47b66eac6eacae8f85ba8179d0d934f648546bdfee4242cd4282663bf08c2598bdc6b6e9ba2c9f62117dc134b171c38a2350833402f4259ef83f13
@@ -3,14 +3,14 @@
3
3
  "component": {
4
4
  "group": "host.exp.exponent",
5
5
  "module": "expo.modules.filesystem",
6
- "version": "19.1.0-canary-20250919-7a31b96",
6
+ "version": "19.1.0-canary-20251023-4c86f95",
7
7
  "attributes": {
8
8
  "org.gradle.status": "release"
9
9
  }
10
10
  },
11
11
  "createdBy": {
12
12
  "gradle": {
13
- "version": "8.14.3"
13
+ "version": "9.0.0"
14
14
  }
15
15
  },
16
16
  "variants": [
@@ -75,13 +75,13 @@
75
75
  ],
76
76
  "files": [
77
77
  {
78
- "name": "expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.aar",
79
- "url": "expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.aar",
80
- "size": 386747,
81
- "sha512": "acbe861a908142be88eae95809a80e51574b5a70c980bc45fa0c1c634972e7ee98ca03d9286e6a2aca0b9b2764e3e92e4f484472a587e9330f1cf9efb3b866a9",
82
- "sha256": "38db39dc4425a365524ef25cca51740a6c671970a34c27bc8da80ad7ef853a97",
83
- "sha1": "795f2aa667934af20b277058a973e66e567aabd5",
84
- "md5": "65a90c8c307beb7e905d5d1b87f47f71"
78
+ "name": "expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.aar",
79
+ "url": "expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.aar",
80
+ "size": 393117,
81
+ "sha512": "9e2285f94d47b66eac6eacae8f85ba8179d0d934f648546bdfee4242cd4282663bf08c2598bdc6b6e9ba2c9f62117dc134b171c38a2350833402f4259ef83f13",
82
+ "sha256": "1f23e461e8a94f5149b5b22ecd2e6dec9a15a5b0a9f5656a86bfaa586a998e42",
83
+ "sha1": "29d197f141c1824915acd933d598b94823c3407f",
84
+ "md5": "b5b686523c997b2c2db9bdcfbec3bd4f"
85
85
  }
86
86
  ]
87
87
  },
@@ -153,13 +153,13 @@
153
153
  ],
154
154
  "files": [
155
155
  {
156
- "name": "expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.aar",
157
- "url": "expo.modules.filesystem-19.1.0-canary-20250919-7a31b96.aar",
158
- "size": 386747,
159
- "sha512": "acbe861a908142be88eae95809a80e51574b5a70c980bc45fa0c1c634972e7ee98ca03d9286e6a2aca0b9b2764e3e92e4f484472a587e9330f1cf9efb3b866a9",
160
- "sha256": "38db39dc4425a365524ef25cca51740a6c671970a34c27bc8da80ad7ef853a97",
161
- "sha1": "795f2aa667934af20b277058a973e66e567aabd5",
162
- "md5": "65a90c8c307beb7e905d5d1b87f47f71"
156
+ "name": "expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.aar",
157
+ "url": "expo.modules.filesystem-19.1.0-canary-20251023-4c86f95.aar",
158
+ "size": 393117,
159
+ "sha512": "9e2285f94d47b66eac6eacae8f85ba8179d0d934f648546bdfee4242cd4282663bf08c2598bdc6b6e9ba2c9f62117dc134b171c38a2350833402f4259ef83f13",
160
+ "sha256": "1f23e461e8a94f5149b5b22ecd2e6dec9a15a5b0a9f5656a86bfaa586a998e42",
161
+ "sha1": "29d197f141c1824915acd933d598b94823c3407f",
162
+ "md5": "b5b686523c997b2c2db9bdcfbec3bd4f"
163
163
  }
164
164
  ]
165
165
  },
@@ -173,13 +173,13 @@
173
173
  },
174
174
  "files": [
175
175
  {
176
- "name": "expo.modules.filesystem-19.1.0-canary-20250919-7a31b96-sources.jar",
177
- "url": "expo.modules.filesystem-19.1.0-canary-20250919-7a31b96-sources.jar",
178
- "size": 28571,
179
- "sha512": "5e896d6a549d64430a226c22eb689f3d84f088506657d2985750534e5840f17b1c903a4fee9cd9a915f47a3e6773596b1f33bd388570e9f4fd360ac2d5d54521",
180
- "sha256": "243397e0d8c3e68d5bce371d9a1ac30805c8b93e4f2940d0ddb312d5056ef292",
181
- "sha1": "8de8a89b5e329ae1f0989a09d1fc13fe6b672fb5",
182
- "md5": "e4ed87add3090ef9b1f273d33bc37969"
176
+ "name": "expo.modules.filesystem-19.1.0-canary-20251023-4c86f95-sources.jar",
177
+ "url": "expo.modules.filesystem-19.1.0-canary-20251023-4c86f95-sources.jar",
178
+ "size": 29329,
179
+ "sha512": "6cac7b2fa58a18696e1468e4e9afe7e6092ca1a404351400345349e028cbaeda51386f4303d05372a2be2baf8de77fd97490ea91caa74bfc2a8cfe7b62619bfe",
180
+ "sha256": "4177d9bd9a22a528b97cc2f2bd7ba47f6cbf7fb1c09d93a1cacdce6f553b05d6",
181
+ "sha1": "464959bdf2015e626f82e9af6c6c28a6498240e3",
182
+ "md5": "d3f99d83252bbc8fcf013f07d3d86ea8"
183
183
  }
184
184
  ]
185
185
  }
@@ -0,0 +1 @@
1
+ c6df2b0f4e2fb579596e5a5f61706d9968148c283c3e48e9a4a1d8b0add759f254d2008a685d3987ee7906900d8f0952975e6566603df2125faea883c6d034ec
@@ -9,7 +9,7 @@
9
9
  <modelVersion>4.0.0</modelVersion>
10
10
  <groupId>host.exp.exponent</groupId>
11
11
  <artifactId>expo.modules.filesystem</artifactId>
12
- <version>19.1.0-canary-20250919-7a31b96</version>
12
+ <version>19.1.0-canary-20251023-4c86f95</version>
13
13
  <packaging>aar</packaging>
14
14
  <name>expo.modules.filesystem</name>
15
15
  <url>https://github.com/expo/expo</url>
@@ -0,0 +1 @@
1
+ 4d1b468af3a143f1e485bb8c47b2a88d961b6a6d34aa8141f9bfbdf808faab1394d8e018e82a6e362437e9c71881483fa0ef48b668b5a78a56ac17d1c98d2a4d
@@ -3,11 +3,11 @@
3
3
  <groupId>host.exp.exponent</groupId>
4
4
  <artifactId>expo.modules.filesystem</artifactId>
5
5
  <versioning>
6
- <latest>19.1.0-canary-20250919-7a31b96</latest>
7
- <release>19.1.0-canary-20250919-7a31b96</release>
6
+ <latest>19.1.0-canary-20251023-4c86f95</latest>
7
+ <release>19.1.0-canary-20251023-4c86f95</release>
8
8
  <versions>
9
- <version>19.1.0-canary-20250919-7a31b96</version>
9
+ <version>19.1.0-canary-20251023-4c86f95</version>
10
10
  </versions>
11
- <lastUpdated>20250919195357</lastUpdated>
11
+ <lastUpdated>20251023075058</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 9b064eb175b3ba4a8bfe3822d3f9d43a
1
+ a7bc3f67e3c6035f2a1ef439283fd9ec
@@ -1 +1 @@
1
- 184640b9b65ddd8e51200827bf267f2a0ab405bb
1
+ 3e74b671bc49450e596a3da3d6132abe9cb89991
@@ -1 +1 @@
1
- 1cedddeb68e1d68ac0d4c9dbee942031c55710c73c74da1edba5fd6b93afaa14
1
+ a34b631ce32396e145e98fd2008af0b74c64da441e2f8eff25d590b6f2a18b5c
@@ -1 +1 @@
1
- 8b70e296848f602599d4c06111b237371406a5d439f68dcc486585d04e3ee42cf981dfc95cf423283c21f0036168462f3cc5c2b311afe1b20fcbea38699c5028
1
+ 997aeaa09409994797940966abe4531812845caf8f87a5c2d320425bce97373482b2fe9fa1583411d33b9b744ba6836979ae2e88e569812260be160c4fe9faf5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-file-system",
3
- "version": "19.1.0-canary-20250919-7a31b96",
3
+ "version": "19.1.0-canary-20251023-4c86f95",
4
4
  "description": "Provides access to the local file system on the device.",
5
5
  "main": "src/index.ts",
6
6
  "types": "build/index.d.ts",
@@ -35,11 +35,11 @@
35
35
  "preset": "expo-module-scripts"
36
36
  },
37
37
  "devDependencies": {
38
- "expo-module-scripts": "5.0.8-canary-20250919-7a31b96",
39
- "jest-expo": "55.0.0-canary-20250919-7a31b96"
38
+ "expo-module-scripts": "5.0.8-canary-20251023-4c86f95",
39
+ "jest-expo": "55.0.0-canary-20251023-4c86f95"
40
40
  },
41
41
  "peerDependencies": {
42
- "expo": "55.0.0-canary-20250919-7a31b96",
42
+ "expo": "55.0.0-canary-20251023-4c86f95",
43
43
  "react-native": "*"
44
44
  }
45
45
  }
@@ -1,3 +1,7 @@
1
1
  import { ConfigPlugin } from 'expo/config-plugins';
2
- declare const _default: ConfigPlugin<void>;
2
+ type FileSystemProps = {
3
+ supportsOpeningDocumentsInPlace?: boolean;
4
+ enableFileSharing?: boolean;
5
+ };
6
+ declare const _default: ConfigPlugin<FileSystemProps>;
3
7
  export default _default;
@@ -2,11 +2,22 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const config_plugins_1 = require("expo/config-plugins");
4
4
  const pkg = require('expo-file-system/package.json');
5
- const withFileSystem = (config) => {
6
- return config_plugins_1.AndroidConfig.Permissions.withPermissions(config, [
5
+ const withFileSystem = (config, options = {}) => {
6
+ // Apply Android permissions
7
+ config = config_plugins_1.AndroidConfig.Permissions.withPermissions(config, [
7
8
  'android.permission.READ_EXTERNAL_STORAGE',
8
9
  'android.permission.WRITE_EXTERNAL_STORAGE',
9
10
  'android.permission.INTERNET',
10
11
  ]);
12
+ // Apply iOS modifications
13
+ return (0, config_plugins_1.withInfoPlist)(config, (config) => {
14
+ if ('supportsOpeningDocumentsInPlace' in options) {
15
+ config.modResults.LSSupportsOpeningDocumentsInPlace = options.supportsOpeningDocumentsInPlace;
16
+ }
17
+ if ('enableFileSharing' in options) {
18
+ config.modResults.UIFileSharingEnabled = options.enableFileSharing;
19
+ }
20
+ return config;
21
+ });
11
22
  };
12
23
  exports.default = (0, config_plugins_1.createRunOncePlugin)(withFileSystem, pkg.name, pkg.version);
@@ -1,13 +1,35 @@
1
- import { AndroidConfig, ConfigPlugin, createRunOncePlugin } from 'expo/config-plugins';
1
+ import {
2
+ AndroidConfig,
3
+ ConfigPlugin,
4
+ createRunOncePlugin,
5
+ withInfoPlist,
6
+ } from 'expo/config-plugins';
2
7
 
3
8
  const pkg = require('expo-file-system/package.json');
4
9
 
5
- const withFileSystem: ConfigPlugin = (config) => {
6
- return AndroidConfig.Permissions.withPermissions(config, [
10
+ type FileSystemProps = {
11
+ supportsOpeningDocumentsInPlace?: boolean;
12
+ enableFileSharing?: boolean;
13
+ };
14
+
15
+ const withFileSystem: ConfigPlugin<FileSystemProps> = (config, options = {}) => {
16
+ // Apply Android permissions
17
+ config = AndroidConfig.Permissions.withPermissions(config, [
7
18
  'android.permission.READ_EXTERNAL_STORAGE',
8
19
  'android.permission.WRITE_EXTERNAL_STORAGE',
9
20
  'android.permission.INTERNET',
10
21
  ]);
22
+
23
+ // Apply iOS modifications
24
+ return withInfoPlist(config, (config) => {
25
+ if ('supportsOpeningDocumentsInPlace' in options) {
26
+ config.modResults.LSSupportsOpeningDocumentsInPlace = options.supportsOpeningDocumentsInPlace;
27
+ }
28
+ if ('enableFileSharing' in options) {
29
+ config.modResults.UIFileSharingEnabled = options.enableFileSharing;
30
+ }
31
+ return config;
32
+ });
11
33
  };
12
34
 
13
35
  export default createRunOncePlugin(withFileSystem, pkg.name, pkg.version);
@@ -11,6 +11,25 @@ export type FileCreateOptions = {
11
11
  overwrite?: boolean;
12
12
  };
13
13
 
14
+ export enum EncodingType {
15
+ /**
16
+ * Standard encoding format.
17
+ */
18
+ UTF8 = 'utf8',
19
+ /**
20
+ * Binary, radix-64 representation.
21
+ */
22
+ Base64 = 'base64',
23
+ }
24
+
25
+ export type FileWriteOptions = {
26
+ /**
27
+ * The encoding format to use when writing the file.
28
+ * @default FileSystem.EncodingType.UTF8
29
+ */
30
+ encoding?: EncodingType | 'utf8' | 'base64';
31
+ };
32
+
14
33
  export type DirectoryCreateOptions = {
15
34
  /**
16
35
  * Whether to create intermediate directories if they do not exist.
@@ -188,7 +207,7 @@ export declare class File {
188
207
  * Retrieves content of the file as base64.
189
208
  * @returns A promise that resolves with the contents of the file as a base64 string.
190
209
  */
191
- base64(): string;
210
+ base64(): Promise<string>;
192
211
 
193
212
  /**
194
213
  * Retrieves content of the file as base64.
@@ -198,13 +217,13 @@ export declare class File {
198
217
 
199
218
  /**
200
219
  * Retrieves byte content of the entire file.
201
- * @returns A promise that resolves with the contents of the file as a Uint8Array.
220
+ * @returns A promise that resolves with the contents of the file as a `Uint8Array`.
202
221
  */
203
222
  bytes(): Promise<Uint8Array<ArrayBuffer>>;
204
223
 
205
224
  /**
206
225
  * Retrieves byte content of the entire file.
207
- * @returns A promise that resolves with the contents of the file as a Uint8Array.
226
+ * @returns The contents of the file as a `Uint8Array`.
208
227
  */
209
228
  bytesSync(): Uint8Array;
210
229
 
@@ -212,7 +231,7 @@ export declare class File {
212
231
  * Writes content to the file.
213
232
  * @param content The content to write into the file.
214
233
  */
215
- write(content: string | Uint8Array): void;
234
+ write(content: string | Uint8Array, options?: FileWriteOptions): void;
216
235
 
217
236
  /**
218
237
  * Deletes a file.
@@ -265,10 +284,18 @@ export declare class File {
265
284
  /**
266
285
  * A static method that downloads a file from the network.
267
286
  *
287
+ * On Android, the response body streams directly into the target file. If the download fails after
288
+ * it starts, a partially written file may remain at the destination. On iOS, the download first
289
+ * completes in a temporary location and the file is moved into place only after success, so no
290
+ * file is left behind when the request fails.
291
+ *
268
292
  * @param url - The URL of the file to download.
269
293
  * @param destination - The destination directory or file. If a directory is provided, the resulting filename will be determined based on the response headers.
294
+ * @param options - Download options. When the destination already contains a file, the promise rejects with a `DestinationAlreadyExists` error unless `options.idempotent` is set to `true`. With `idempotent: true`, the download overwrites the existing file instead of failing.
270
295
  *
271
- * @returns A promise that resolves to the downloaded file.
296
+ * @returns A promise that resolves to the downloaded file. When the server responds with
297
+ * a non-2xx HTTP status, the promise rejects with an `UnableToDownload` error whose
298
+ * message includes the status code. No file is created in that scenario.
272
299
  *
273
300
  * @example
274
301
  * ```ts
@@ -288,7 +315,7 @@ export declare class File {
288
315
  *
289
316
  * @param initialUri An optional URI pointing to an initial folder on which the file picker is opened.
290
317
  * @param mimeType A mime type that is used to filter out files that can be picked out.
291
- * @returns a `File` instance or an array of `File` instances.
318
+ * @returns A `File` instance or an array of `File` instances.
292
319
  */
293
320
  static pickFileAsync(initialUri?: string, mimeType?: string): Promise<File | File[]>;
294
321
 
@@ -316,6 +343,11 @@ export declare class File {
316
343
  * A mime type of the file. An empty string if the file does not exist, or it cannot be read.
317
344
  */
318
345
  type: string;
346
+ /**
347
+ * A content URI to the file that can be shared to external applications.
348
+ * @platform android
349
+ */
350
+ contentUri: string;
319
351
  }
320
352
 
321
353
  export declare class FileHandle {
package/src/FileSystem.ts CHANGED
@@ -65,7 +65,7 @@ export class Paths extends PathUtilities {
65
65
  * The constructor accepts an array of strings that are joined to create the file URI. The first argument can also be a `Directory` instance (like `Paths.cache`) or a `File` instance (which creates a new reference to the same file).
66
66
  * @example
67
67
  * ```ts
68
- * const file = new File(File.cache, "subdirName", "file.txt");
68
+ * const file = new File(Paths.cache, "subdirName", "file.txt");
69
69
  * ```
70
70
  */
71
71
  export class File extends ExpoFileSystem.FileSystemFile implements Blob {
@@ -76,7 +76,7 @@ export class File extends ExpoFileSystem.FileSystemFile implements Blob {
76
76
  * @param uris An array of: `file:///` string URIs, `File` instances, and `Directory` instances representing an arbitrary location on the file system.
77
77
  * @example
78
78
  * ```ts
79
- * const file = new File(File.cache, "subdirName", "file.txt");
79
+ * const file = new File(Paths.cache, "subdirName", "file.txt");
80
80
  * ```
81
81
  */
82
82
  constructor(...uris: (string | File | Directory)[]) {
@@ -151,7 +151,7 @@ File.pickFileAsync = async function (initialUri?: string, mimeType?: string) {
151
151
  * The constructor accepts an array of strings that are joined to create the directory URI. The first argument can also be a `Directory` instance (like `Paths.cache`).
152
152
  * @example
153
153
  * ```ts
154
- * const directory = new Directory(File.cache, "subdirName");
154
+ * const directory = new Directory(Paths.cache, "subdirName");
155
155
  * ```
156
156
  */
157
157
  export class Directory extends ExpoFileSystem.FileSystemDirectory {
@@ -162,7 +162,7 @@ export class Directory extends ExpoFileSystem.FileSystemDirectory {
162
162
  * @param uris An array of: `file:///` string URIs, `File` instances, and `Directory` instances representing an arbitrary location on the file system.
163
163
  * @example
164
164
  * ```ts
165
- * const directory = new Directory(File.cache, "subdirName");
165
+ * const directory = new Directory(Paths.cache, "subdirName");
166
166
  * ```
167
167
  */
168
168
  constructor(...uris: (string | File | Directory)[]) {
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ export {
8
8
  type InfoOptions,
9
9
  type PathInfo,
10
10
  type DirectoryInfo,
11
+ type DownloadOptions,
11
12
  } from './ExpoFileSystem.types';
12
13
 
13
14
  export * from './legacyWarnings';
@@ -1 +0,0 @@
1
- 5e896d6a549d64430a226c22eb689f3d84f088506657d2985750534e5840f17b1c903a4fee9cd9a915f47a3e6773596b1f33bd388570e9f4fd360ac2d5d54521
@@ -1 +0,0 @@
1
- acbe861a908142be88eae95809a80e51574b5a70c980bc45fa0c1c634972e7ee98ca03d9286e6a2aca0b9b2764e3e92e4f484472a587e9330f1cf9efb3b866a9
@@ -1 +0,0 @@
1
- cdde4b39de1cf04ddc8335d727104f1db2c9d8d4d8b4116fbb488fc7c1d87c30cfcb41769eeb83942bf1a0de18d8ffc59ec3e4dedacec1162ddd2ee810392eb9
@@ -1 +0,0 @@
1
- ecc02b9a7f5764d040763ba156e6b2a68d5d5322610ca28d8e20740bc498e0fffcb5c4648d11b3d94889c2128089fab8a498727b86adf1e4146843e0d9fc311b