expo-file-system 18.2.0-canary-20250722-599a28f → 18.2.0-canary-20250729-d8899ae

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 (59) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/filesystem/next/FileSystemDirectory.kt +19 -17
  4. package/android/src/main/java/expo/modules/filesystem/next/FileSystemFile.kt +49 -41
  5. package/android/src/main/java/expo/modules/filesystem/next/FileSystemNextModule.kt +15 -3
  6. package/android/src/main/java/expo/modules/filesystem/next/FileSystemPath.kt +3 -13
  7. package/android/src/main/java/expo/modules/filesystem/next/unifiedfile/JavaFile.kt +39 -8
  8. package/android/src/main/java/expo/modules/filesystem/next/unifiedfile/SAFDocumentFile.kt +46 -5
  9. package/android/src/main/java/expo/modules/filesystem/next/unifiedfile/UnifiedFileInterface.kt +8 -0
  10. package/build/next/ExpoFileSystem.types.d.ts +23 -8
  11. package/build/next/ExpoFileSystem.types.d.ts.map +1 -1
  12. package/build/next/FileSystem.d.ts +4 -24
  13. package/build/next/FileSystem.d.ts.map +1 -1
  14. package/expo-module.config.json +1 -1
  15. package/ios/Next/FileSystemNextModule.swift +15 -3
  16. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/{18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f-sources.jar → 18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae-sources.jar} +0 -0
  17. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae-sources.jar.md5 +1 -0
  18. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae-sources.jar.sha1 +1 -0
  19. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae-sources.jar.sha256 +1 -0
  20. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae-sources.jar.sha512 +1 -0
  21. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/{18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.aar → 18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.aar} +0 -0
  22. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.aar.md5 +1 -0
  23. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.aar.sha1 +1 -0
  24. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.aar.sha256 +1 -0
  25. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.aar.sha512 +1 -0
  26. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/{18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.module → 18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.module} +22 -22
  27. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.module.md5 +1 -0
  28. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.module.sha1 +1 -0
  29. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.module.sha256 +1 -0
  30. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.module.sha512 +1 -0
  31. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/{18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.pom → 18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.pom} +1 -1
  32. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.pom.md5 +1 -0
  33. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.pom.sha1 +1 -0
  34. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.pom.sha256 +1 -0
  35. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250729-d8899ae/expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.pom.sha512 +1 -0
  36. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml +4 -4
  37. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.md5 +1 -1
  38. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.sha1 +1 -1
  39. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.sha256 +1 -1
  40. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/maven-metadata.xml.sha512 +1 -1
  41. package/package.json +4 -4
  42. package/src/next/ExpoFileSystem.types.ts +26 -8
  43. package/src/next/FileSystem.ts +14 -60
  44. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f-sources.jar.md5 +0 -1
  45. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f-sources.jar.sha1 +0 -1
  46. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f-sources.jar.sha256 +0 -1
  47. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f-sources.jar.sha512 +0 -1
  48. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.aar.md5 +0 -1
  49. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.aar.sha1 +0 -1
  50. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.aar.sha256 +0 -1
  51. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.aar.sha512 +0 -1
  52. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.module.md5 +0 -1
  53. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.module.sha1 +0 -1
  54. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.module.sha256 +0 -1
  55. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.module.sha512 +0 -1
  56. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.pom.md5 +0 -1
  57. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.pom.sha1 +0 -1
  58. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.pom.sha256 +0 -1
  59. package/local-maven-repo/host/exp/exponent/expo.modules.filesystem/18.2.0-canary-20250722-599a28f/expo.modules.filesystem-18.2.0-canary-20250722-599a28f.pom.sha512 +0 -1
package/CHANGELOG.md CHANGED
@@ -6,11 +6,13 @@
6
6
 
7
7
  ### 🎉 New features
8
8
 
9
+ - Make file implement blob interface directly. ([#38160](https://github.com/expo/expo/pull/38160) by [@aleqsio](https://github.com/aleqsio))
9
10
  - Add directory info function ([#37910](https://github.com/expo/expo/pull/37910) by [@Wenszel](https://github.com/Wenszel))
10
11
  - Add total and available sizes, directory sizes. ([#37594](https://github.com/expo/expo/pull/37594) by [@aleqsio](https://github.com/aleqsio))
11
12
  - Add info method, modificationTime and creationTime properties to file-system/next. ([#37505](https://github.com/expo/expo/pull/37505) by [@Wenszel](https://github.com/Wenszel))
12
13
  - Add support for custom headers in downloadFileAsync ([#36108](https://github.com/expo/expo/pull/36108) by [@leonhh](https://github.com/leonhh))
13
14
  - [next] Add limited support for SAF Uris. ([#38075](https://github.com/expo/expo/pull/38075) by [@aleqsio](https://github.com/aleqsio))
15
+ - [next] Add full support for SAF Uris. ([#38075](https://github.com/expo/expo/pull/38075) by [@aleqsio](https://github.com/aleqsio))
14
16
 
15
17
  ### 🐛 Bug fixes
16
18
 
@@ -4,13 +4,13 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '18.2.0-canary-20250722-599a28f'
7
+ version = '18.2.0-canary-20250729-d8899ae'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.filesystem"
11
11
  defaultConfig {
12
12
  versionCode 30
13
- versionName "18.2.0-canary-20250722-599a28f"
13
+ versionName "18.2.0-canary-20250729-d8899ae"
14
14
  }
15
15
  }
16
16
 
@@ -26,7 +26,7 @@ class FileSystemDirectory(uri: Uri) : FileSystemPath(uri) {
26
26
  val size: Long get() {
27
27
  validatePermission(Permission.READ)
28
28
  validateType()
29
- return javaFile.walkTopDown().filter { it.isFile }.map { it.length() }.sum()
29
+ return file.walkTopDown().filter { it.isFile() }.map { it.length() }.sum()
30
30
  }
31
31
 
32
32
  fun info(): DirectoryInfo {
@@ -35,33 +35,31 @@ class FileSystemDirectory(uri: Uri) : FileSystemPath(uri) {
35
35
  if (!file.exists()) {
36
36
  val directoryInfo = DirectoryInfo(
37
37
  exists = false,
38
- uri = slashifyFilePath(javaFile.toURI().toString())
38
+ uri = slashifyFilePath(file.uri.toString())
39
39
  )
40
40
  return directoryInfo
41
41
  }
42
42
 
43
- when {
44
- javaFile.toURI().scheme == "file" -> {
45
- val directoryInfo = DirectoryInfo(
46
- exists = true,
47
- uri = slashifyFilePath(javaFile.toURI().toString()),
48
- files = javaFile.listFiles()?.map { i -> i.name },
49
- modificationTime = modificationTime,
50
- creationTime = creationTime,
51
- size = size
52
- )
53
- return directoryInfo
54
- }
55
- else -> throw UnableToGetInfoException("file schema ${javaFile.toURI().scheme} is not supported")
56
- }
43
+ val directoryInfo = DirectoryInfo(
44
+ exists = true,
45
+ uri = slashifyFilePath(file.uri.toString()),
46
+ files = file.listFilesAsUnified().mapNotNull { i -> i.fileName },
47
+ modificationTime = modificationTime,
48
+ creationTime = creationTime,
49
+ size = size
50
+ )
51
+ return directoryInfo
57
52
  }
58
53
 
59
54
  fun create(options: CreateOptions = CreateOptions()) {
60
55
  validateType()
61
56
  validatePermission(Permission.WRITE)
62
57
  validateCanCreate(options)
58
+ if (uri.isContentUri) {
59
+ throw UnableToCreateException("create function does not work with SAF Uris, use `createDirectory` and `createFile` instead")
60
+ }
63
61
  if (options.overwrite && file.exists()) {
64
- javaFile.delete()
62
+ file.delete()
65
63
  }
66
64
  val created = if (options.intermediates) {
67
65
  javaFile.mkdirs()
@@ -74,11 +72,15 @@ class FileSystemDirectory(uri: Uri) : FileSystemPath(uri) {
74
72
  }
75
73
 
76
74
  fun createFile(mimeType: String?, fileName: String): FileSystemFile {
75
+ validateType()
76
+ validatePermission(Permission.WRITE)
77
77
  val newFile = file.createFile(mimeType ?: "text/plain", fileName) ?: throw UnableToCreateException("file could not be created")
78
78
  return FileSystemFile(newFile.uri)
79
79
  }
80
80
 
81
81
  fun createDirectory(fileName: String): FileSystemDirectory {
82
+ validateType()
83
+ validatePermission(Permission.WRITE)
82
84
  val newDirectory = file.createDirectory(fileName) ?: throw UnableToCreateException("directory could not be created")
83
85
  return FileSystemDirectory(newDirectory.uri)
84
86
  }
@@ -2,7 +2,6 @@ package expo.modules.filesystem.next
2
2
 
3
3
  import android.net.Uri
4
4
  import android.util.Base64
5
- import android.webkit.MimeTypeMap
6
5
  import expo.modules.filesystem.InfoOptions
7
6
  import expo.modules.filesystem.slashifyFilePath
8
7
  import expo.modules.interfaces.filesystem.Permission
@@ -40,17 +39,16 @@ class FileSystemFile(uri: Uri) : FileSystemPath(uri) {
40
39
  validateCanCreate(options)
41
40
  if (uri.isContentUri) {
42
41
  throw UnableToCreateException("create function does not work with SAF Uris, use `createDirectory` and `createFile` instead")
43
- } else {
44
- if (options.overwrite && exists) {
45
- javaFile.delete()
46
- }
47
- if (options.intermediates) {
48
- javaFile.parentFile?.mkdirs()
49
- }
50
- val created = javaFile.createNewFile()
51
- if (!created) {
52
- throw UnableToCreateException("file already exists or could not be created")
53
- }
42
+ }
43
+ if (options.overwrite && exists) {
44
+ javaFile.delete()
45
+ }
46
+ if (options.intermediates) {
47
+ javaFile.parentFile?.mkdirs()
48
+ }
49
+ val created = javaFile.createNewFile()
50
+ if (!created) {
51
+ throw UnableToCreateException("file already exists or could not be created")
54
52
  }
55
53
  }
56
54
 
@@ -60,8 +58,8 @@ class FileSystemFile(uri: Uri) : FileSystemPath(uri) {
60
58
  if (!exists) {
61
59
  create()
62
60
  }
63
- FileOutputStream(javaFile).use {
64
- it.write(content.toByteArray())
61
+ file.outputStream().use { outputStream ->
62
+ outputStream.write(content.toByteArray())
65
63
  }
66
64
  }
67
65
 
@@ -71,8 +69,16 @@ class FileSystemFile(uri: Uri) : FileSystemPath(uri) {
71
69
  if (!exists) {
72
70
  create()
73
71
  }
74
- FileOutputStream(javaFile).use {
75
- it.channel.write(content.toDirectBuffer())
72
+ if (uri.isContentUri) {
73
+ file.outputStream().use { outputStream ->
74
+ val array = ByteArray(content.length)
75
+ content.toDirectBuffer().get(array)
76
+ outputStream.write(array)
77
+ }
78
+ } else {
79
+ FileOutputStream(javaFile).use {
80
+ it.channel.write(content.toDirectBuffer())
81
+ }
76
82
  }
77
83
  }
78
84
 
@@ -84,40 +90,47 @@ class FileSystemFile(uri: Uri) : FileSystemPath(uri) {
84
90
  fun text(): String {
85
91
  validateType()
86
92
  validatePermission(Permission.READ)
87
- return javaFile.readText()
93
+ return file.inputStream().use { inputStream ->
94
+ inputStream.bufferedReader().use { it.readText() }
95
+ }
88
96
  }
89
97
 
90
98
  fun base64(): String {
91
99
  validateType()
92
100
  validatePermission(Permission.READ)
93
- return Base64.encodeToString(javaFile.readBytes(), Base64.NO_WRAP)
101
+ file.inputStream().use {
102
+ return Base64.encodeToString(it.readBytes(), Base64.NO_WRAP)
103
+ }
94
104
  }
95
105
 
96
106
  fun bytes(): ByteArray {
97
107
  validateType()
98
108
  validatePermission(Permission.READ)
99
- return javaFile.readBytes()
109
+ file.inputStream().use {
110
+ return it.readBytes()
111
+ }
100
112
  }
101
113
 
102
114
  @OptIn(ExperimentalStdlibApi::class)
103
115
  val md5: String get() {
104
116
  validatePermission(Permission.READ)
105
117
  val md = MessageDigest.getInstance("MD5")
106
- val digest = md.digest(javaFile.readBytes())
107
- return digest.toHexString()
118
+ file.inputStream().use {
119
+ val digest = md.digest(it.readBytes())
120
+ return digest.toHexString()
121
+ }
108
122
  }
109
123
 
110
124
  val size: Long? get() {
111
- return if (javaFile.exists()) {
112
- javaFile.length()
125
+ return if (file.exists()) {
126
+ file.length()
113
127
  } else {
114
128
  null
115
129
  }
116
130
  }
117
131
 
118
132
  val type: String? get() {
119
- return MimeTypeMap.getFileExtensionFromUrl(javaFile.path)
120
- ?.run { MimeTypeMap.getSingleton().getMimeTypeFromExtension(lowercase()) }
133
+ return file.type
121
134
  }
122
135
 
123
136
  fun info(options: InfoOptions?): FileInfo {
@@ -126,25 +139,20 @@ class FileSystemFile(uri: Uri) : FileSystemPath(uri) {
126
139
  if (!file.exists()) {
127
140
  val fileInfo = FileInfo(
128
141
  exists = false,
129
- uri = slashifyFilePath(javaFile.toURI().toString())
142
+ uri = slashifyFilePath(file.uri.toString())
130
143
  )
131
144
  return fileInfo
132
145
  }
133
- when {
134
- javaFile.toURI().scheme == "file" -> {
135
- val fileInfo = FileInfo(
136
- exists = true,
137
- uri = slashifyFilePath(javaFile.toURI().toString()),
138
- size = size,
139
- modificationTime = modificationTime,
140
- creationTime = creationTime
141
- )
142
- if (options != null && options.md5 == true) {
143
- fileInfo.md5 = md5
144
- }
145
- return fileInfo
146
- }
147
- else -> throw UnableToGetInfoException("file schema ${javaFile.toURI().scheme} is not supported")
146
+ val fileInfo = FileInfo(
147
+ exists = true,
148
+ uri = slashifyFilePath(file.uri.toString()),
149
+ size = size,
150
+ modificationTime = modificationTime,
151
+ creationTime = creationTime
152
+ )
153
+ if (options != null && options.md5 == true) {
154
+ fileInfo.md5 = md5
148
155
  }
156
+ return fileInfo
149
157
  }
150
158
  }
@@ -121,15 +121,27 @@ class FileSystemNextModule : Module() {
121
121
  }
122
122
  }
123
123
 
124
- Function("text") { file: FileSystemFile ->
124
+ AsyncFunction("text") { file: FileSystemFile ->
125
125
  file.text()
126
126
  }
127
127
 
128
- Function("base64") { file: FileSystemFile ->
128
+ Function("textSync") { file: FileSystemFile ->
129
+ file.text()
130
+ }
131
+
132
+ AsyncFunction("base64") { file: FileSystemFile ->
129
133
  file.base64()
130
134
  }
131
135
 
132
- Function("bytes") { file: FileSystemFile ->
136
+ Function("base64Sync") { file: FileSystemFile ->
137
+ file.base64()
138
+ }
139
+
140
+ AsyncFunction("bytes") { file: FileSystemFile ->
141
+ file.bytes()
142
+ }
143
+
144
+ Function("bytesSync") { file: FileSystemFile ->
133
145
  file.bytes()
134
146
  }
135
147
 
@@ -9,12 +9,8 @@ import expo.modules.filesystem.next.unifiedfile.UnifiedFileInterface
9
9
  import expo.modules.interfaces.filesystem.Permission
10
10
  import expo.modules.kotlin.sharedobjects.SharedObject
11
11
  import java.io.File
12
- import java.nio.file.attribute.BasicFileAttributes
13
12
  import java.util.EnumSet
14
- import kotlin.io.path.Path
15
13
  import kotlin.io.path.moveTo
16
- import kotlin.io.path.readAttributes
17
- import kotlin.time.Duration.Companion.milliseconds
18
14
 
19
15
  val Uri.isContentUri get(): Boolean {
20
16
  return scheme == "content"
@@ -144,18 +140,12 @@ abstract class FileSystemPath(var uri: Uri) : SharedObject() {
144
140
  }
145
141
  }
146
142
 
147
- val modificationTime: Long get() {
143
+ val modificationTime: Long? get() {
148
144
  validateType()
149
- return javaFile.lastModified()
145
+ return file.lastModified()
150
146
  }
151
147
 
152
148
  val creationTime: Long? get() {
153
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
154
- validateType()
155
- val attributes = Path(javaFile.path).readAttributes<BasicFileAttributes>()
156
- return attributes.creationTime().toMillis().milliseconds.inWholeMilliseconds
157
- } else {
158
- return null
159
- }
149
+ return file.creationTime
160
150
  }
161
151
  }
@@ -1,19 +1,21 @@
1
1
  package expo.modules.filesystem.next.unifiedfile
2
2
 
3
3
  import android.net.Uri
4
+ import android.os.Build
5
+ import android.webkit.MimeTypeMap
4
6
  import androidx.core.net.toUri
5
7
  import java.io.File
8
+ import java.io.FileInputStream
9
+ import java.io.FileOutputStream
10
+ import java.io.InputStream
11
+ import java.io.OutputStream
6
12
  import java.net.URI
13
+ import java.nio.file.attribute.BasicFileAttributes
14
+ import kotlin.io.path.Path
15
+ import kotlin.io.path.readAttributes
16
+ import kotlin.time.Duration.Companion.milliseconds
7
17
 
8
18
  class JavaFile(override val uri: Uri) : UnifiedFileInterface, File(URI.create(uri.toString())) {
9
- override fun isDirectory(): Boolean {
10
- return super<File>.isDirectory()
11
- }
12
-
13
- override fun isFile(): Boolean {
14
- return super<File>.isFile()
15
- }
16
-
17
19
  override val parentFile: UnifiedFileInterface?
18
20
  get() = super<File>.parentFile?.toUri()?.let { JavaFile(it) }
19
21
 
@@ -31,4 +33,33 @@ class JavaFile(override val uri: Uri) : UnifiedFileInterface, File(URI.create(ur
31
33
 
32
34
  override fun listFilesAsUnified(): List<UnifiedFileInterface> =
33
35
  super<File>.listFiles()?.map { JavaFile(it.toUri()) } ?: emptyList()
36
+
37
+ override val type: String? get() {
38
+ return MimeTypeMap.getFileExtensionFromUrl(path)
39
+ ?.run { MimeTypeMap.getSingleton().getMimeTypeFromExtension(lowercase()) }
40
+ }
41
+
42
+ override val fileName: String?
43
+ get() = super<File>.name
44
+
45
+ override val creationTime: Long? get() {
46
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
47
+ val attributes = Path(path).readAttributes<BasicFileAttributes>()
48
+ return attributes.creationTime().toMillis().milliseconds.inWholeMilliseconds
49
+ } else {
50
+ return null
51
+ }
52
+ }
53
+
54
+ override fun outputStream(): OutputStream {
55
+ return FileOutputStream(this)
56
+ }
57
+
58
+ override fun inputStream(): InputStream {
59
+ return FileInputStream(this)
60
+ }
61
+
62
+ override fun walkTopDown(): Sequence<JavaFile> {
63
+ return walk(direction = FileWalkDirection.TOP_DOWN).map { JavaFile(it.toUri()) }
64
+ }
34
65
  }
@@ -3,19 +3,20 @@ package expo.modules.filesystem.next.unifiedfile
3
3
  import android.content.Context
4
4
  import android.net.Uri
5
5
  import androidx.documentfile.provider.DocumentFile
6
+ import java.io.InputStream
7
+ import java.io.OutputStream
6
8
 
7
9
  class SAFDocumentFile(private val context: Context, override val uri: Uri) : UnifiedFileInterface {
8
10
  private val treeDocumentFile: DocumentFile? = DocumentFile.fromTreeUri(context, uri)
9
- private val singleDocumentFile: DocumentFile? = DocumentFile.fromSingleUri(context, uri)
10
11
 
11
- override fun exists(): Boolean = singleDocumentFile?.exists() == true
12
+ override fun exists(): Boolean = treeDocumentFile?.exists() == true
12
13
 
13
14
  override fun isDirectory(): Boolean {
14
- return singleDocumentFile?.isDirectory == true
15
+ return treeDocumentFile?.isDirectory == true
15
16
  }
16
17
 
17
18
  override fun isFile(): Boolean {
18
- return singleDocumentFile?.isFile == true
19
+ return treeDocumentFile?.isFile == true
19
20
  }
20
21
 
21
22
  override val parentFile: UnifiedFileInterface?
@@ -31,8 +32,48 @@ class SAFDocumentFile(private val context: Context, override val uri: Uri) : Uni
31
32
  return documentFile?.uri?.let { SAFDocumentFile(context, it) }
32
33
  }
33
34
 
34
- override fun delete(): Boolean = singleDocumentFile?.delete() ?: false
35
+ override fun delete(): Boolean = treeDocumentFile?.delete() == true
35
36
 
36
37
  override fun listFilesAsUnified(): List<UnifiedFileInterface> =
37
38
  treeDocumentFile?.listFiles()?.map { SAFDocumentFile(context, it.uri) } ?: emptyList()
39
+
40
+ override val type: String?
41
+ get() = treeDocumentFile?.type
42
+
43
+ override fun lastModified(): Long? {
44
+ return treeDocumentFile?.lastModified()
45
+ }
46
+
47
+ override val fileName: String?
48
+ get() = treeDocumentFile?.name
49
+
50
+ override val creationTime: Long? get() {
51
+ // It seems there's no way to get this
52
+ return null
53
+ }
54
+
55
+ override fun outputStream(): OutputStream {
56
+ return context.contentResolver.openOutputStream(uri)
57
+ ?: throw IllegalStateException("Unable to open output stream for URI: $uri")
58
+ }
59
+
60
+ override fun inputStream(): InputStream {
61
+ return context.contentResolver.openInputStream(uri)
62
+ ?: throw IllegalStateException("Unable to open output stream for URI: $uri")
63
+ }
64
+
65
+ override fun length(): Long {
66
+ return treeDocumentFile?.length() ?: 0
67
+ }
68
+
69
+ override fun walkTopDown(): Sequence<SAFDocumentFile> {
70
+ return sequence {
71
+ yield(this@SAFDocumentFile)
72
+ if (isDirectory()) {
73
+ treeDocumentFile?.listFiles()?.forEach { child ->
74
+ yieldAll(SAFDocumentFile(context, child.uri).walkTopDown())
75
+ }
76
+ }
77
+ }
78
+ }
38
79
  }
@@ -12,4 +12,12 @@ interface UnifiedFileInterface {
12
12
  fun delete(): Boolean
13
13
  fun listFilesAsUnified(): List<UnifiedFileInterface>
14
14
  val uri: Uri
15
+ val type: String?
16
+ fun lastModified(): Long?
17
+ val creationTime: Long?
18
+ val fileName: String?
19
+ fun outputStream(): java.io.OutputStream
20
+ fun inputStream(): java.io.InputStream
21
+ fun length(): Long
22
+ fun walkTopDown(): Sequence<UnifiedFileInterface>
15
23
  }
@@ -106,21 +106,36 @@ export declare class File {
106
106
  * Validates a directory path.
107
107
  */
108
108
  validatePath(): void;
109
+ /**
110
+ * Retrieves text from the file.
111
+ * @returns A promise that resolves with the contents of the file as string.
112
+ */
113
+ text(): Promise<string>;
109
114
  /**
110
115
  * Retrieves text from the file.
111
116
  * @returns The contents of the file as string.
112
117
  */
113
- text(): string;
118
+ textSync(): Promise<string>;
114
119
  /**
115
120
  * Retrieves content of the file as base64.
116
- * @returns The contents of the file as a base64 string.
121
+ * @returns A promise that resolves with the contents of the file as a base64 string.
117
122
  */
118
123
  base64(): string;
124
+ /**
125
+ * Retrieves content of the file as base64.
126
+ * @returns The contents of the file as a base64 string.
127
+ */
128
+ base64Sync(): string;
129
+ /**
130
+ * Retrieves byte content of the entire file.
131
+ * @returns A promise that resolves with the contents of the file as a Uint8Array.
132
+ */
133
+ bytes(): Promise<Uint8Array>;
119
134
  /**
120
135
  * Retrieves byte content of the entire file.
121
- * @returns The contents of the file as a Uint8Array.
136
+ * @returns A promise that resolves with the contents of the file as a Uint8Array.
122
137
  */
123
- bytes(): Uint8Array;
138
+ bytesSync(): Uint8Array;
124
139
  /**
125
140
  * Writes content to the file.
126
141
  * @param content The content to write into the file.
@@ -174,9 +189,9 @@ export declare class File {
174
189
  */
175
190
  static downloadFileAsync(url: string, destination: Directory | File, options?: DownloadOptions): Promise<File>;
176
191
  /**
177
- * A size of the file in bytes. Null if the file does not exist, or it cannot be read.
192
+ * A size of the file in bytes. 0 if the file does not exist, or it cannot be read.
178
193
  */
179
- size: number | null;
194
+ size: number;
180
195
  /**
181
196
  * A md5 hash of the file. Null if the file does not exist, or it cannot be read.
182
197
  */
@@ -190,9 +205,9 @@ export declare class File {
190
205
  */
191
206
  creationTime: number | null;
192
207
  /**
193
- * A mime type of the file. Null if the file does not exist, or it cannot be read.
208
+ * A mime type of the file. An empty string if the file does not exist, or it cannot be read.
194
209
  */
195
- type: string | null;
210
+ type: string;
196
211
  }
197
212
  export declare class FileHandle {
198
213
  close(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoFileSystem.types.d.ts","sourceRoot":"","sources":["../../src/next/ExpoFileSystem.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ExpoFileSystem.types.d.ts","sourceRoot":"","sources":["../../src/next/ExpoFileSystem.types.ts"],"names":[],"mappings":"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"}
@@ -24,29 +24,7 @@ export declare class Paths extends PathUtilities {
24
24
  */
25
25
  static info(...uris: string[]): PathInfo;
26
26
  }
27
- /**
28
- * @hidden
29
- */
30
- export declare class FileBlob extends Blob {
31
- file: File;
32
- /**
33
- * @internal
34
- */
35
- key: string;
36
- constructor(file: File);
37
- get size(): number;
38
- /**
39
- * @internal
40
- */
41
- get name(): string;
42
- get type(): string;
43
- arrayBuffer(): Promise<ArrayBuffer>;
44
- text(): Promise<string>;
45
- bytes(): Promise<Uint8Array>;
46
- stream(): ReadableStream<Uint8Array>;
47
- slice(start?: number, end?: number, contentType?: string): Blob;
48
- }
49
- export declare class File extends ExpoFileSystem.FileSystemFile {
27
+ export declare class File extends ExpoFileSystem.FileSystemFile implements Blob {
50
28
  /**
51
29
  * Creates an instance of a file.
52
30
  * @param uris An array of: `file:///` string URIs, `File` instances, `Directory` instances representing an arbitrary location on the file system. The location does not need to exist, or it may already contain a directory.
@@ -56,7 +34,6 @@ export declare class File extends ExpoFileSystem.FileSystemFile {
56
34
  * ```
57
35
  */
58
36
  constructor(...uris: (string | File | Directory)[]);
59
- blob(): Blob;
60
37
  get parentDirectory(): Directory;
61
38
  /**
62
39
  * File extension.
@@ -69,6 +46,9 @@ export declare class File extends ExpoFileSystem.FileSystemFile {
69
46
  get name(): string;
70
47
  readableStream(): ReadableStream<Uint8Array<ArrayBufferLike>>;
71
48
  writableStream(): WritableStream<Uint8Array<ArrayBufferLike>>;
49
+ arrayBuffer(): Promise<ArrayBuffer>;
50
+ stream(): ReadableStream<Uint8Array>;
51
+ slice(start?: number, end?: number, contentType?: string): Blob;
72
52
  }
73
53
  /**
74
54
  * Represents a directory on the filesystem.
@@ -1 +1 @@
1
- {"version":3,"file":"FileSystem.d.ts","sourceRoot":"","sources":["../../src/next/FileSystem.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAmB,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,qBAAa,KAAM,SAAQ,aAAa;IACtC;;OAEG;IACH,MAAM,KAAK,KAAK,cAEf;IAED;;OAEG;IACH,MAAM,KAAK,QAAQ,cAElB;IACD,MAAM,KAAK,qBAAqB,8BAS/B;IAED;;OAEG;IACH,MAAM,KAAK,cAAc,WAExB;IAED;;OAEG;IACH,MAAM,KAAK,kBAAkB,WAE5B;IAED;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ;CAGzC;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,IAAI;IAChC,IAAI,EAAE,IAAI,CAAC;IAEX;;OAEG;IACH,GAAG,EAAE,MAAM,CAAc;gBAEb,IAAI,EAAE,IAAI;IAKtB,IAAa,IAAI,IAAI,MAAM,CAE1B;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAa,IAAI,IAAI,MAAM,CAE1B;IAEc,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAInC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAIhC,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC;IAIzB,MAAM,IAAI,cAAc,CAAC,UAAU,CAAC;IAIpC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;CAGzE;AAED,qBAAa,IAAK,SAAQ,cAAc,CAAC,cAAc;IACrD;;;;;;;OAOG;gBACS,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE;IAQlD,IAAI,IAAI,IAAI;IAOZ,IAAI,eAAe,cAElB;IAED;;;OAGG;IACH,IAAI,SAAS,WAEZ;IAED;;OAEG;IACH,IAAI,IAAI,WAEP;IAED,cAAc;IAId,cAAc;CAGf;AAYD;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAAc,CAAC,mBAAmB;IAC/D;;;;;;;OAOG;gBACS,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE;IAQlD,IAAI,eAAe,cAElB;IAED;;;;OAIG;IACM,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE;IAOrC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKvD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;CAGzC"}
1
+ {"version":3,"file":"FileSystem.d.ts","sourceRoot":"","sources":["../../src/next/FileSystem.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAmB,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,qBAAa,KAAM,SAAQ,aAAa;IACtC;;OAEG;IACH,MAAM,KAAK,KAAK,cAEf;IAED;;OAEG;IACH,MAAM,KAAK,QAAQ,cAElB;IACD,MAAM,KAAK,qBAAqB,8BAS/B;IAED;;OAEG;IACH,MAAM,KAAK,cAAc,WAExB;IAED;;OAEG;IACH,MAAM,KAAK,kBAAkB,WAE5B;IAED;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ;CAGzC;AAED,qBAAa,IAAK,SAAQ,cAAc,CAAC,cAAe,YAAW,IAAI;IACrE;;;;;;;OAOG;gBACS,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE;IAQlD,IAAI,eAAe,cAElB;IAED;;;OAGG;IACH,IAAI,SAAS,WAEZ;IAED;;OAEG;IACH,IAAI,IAAI,WAEP;IAED,cAAc;IAId,cAAc;IAIR,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAKzC,MAAM,IAAI,cAAc,CAAC,UAAU,CAAC;IAIpC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;CAGhE;AAYD;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAAc,CAAC,mBAAmB;IAC/D;;;;;;;OAOG;gBACS,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE;IAQlD,IAAI,eAAe,cAElB;IAED;;;;OAIG;IACM,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE;IAOrC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKvD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;CAGzC"}
@@ -12,7 +12,7 @@
12
12
  "publication": {
13
13
  "groupId": "host.exp.exponent",
14
14
  "artifactId": "expo.modules.filesystem",
15
- "version": "18.2.0-canary-20250722-599a28f",
15
+ "version": "18.2.0-canary-20250729-d8899ae",
16
16
  "repository": "local-maven-repo"
17
17
  }
18
18
  }
@@ -125,15 +125,27 @@ public final class FileSystemNextModule: Module {
125
125
  }
126
126
 
127
127
  // maybe asString, readAsString, readAsText, readText, ect.
128
- Function("text") { file in
128
+ AsyncFunction("text") { file in
129
129
  return try file.text()
130
130
  }
131
131
 
132
- Function("base64") { file in
132
+ Function("textSync") { file in
133
+ return try file.text()
134
+ }
135
+
136
+ AsyncFunction("base64") { file in
133
137
  return try file.base64()
134
138
  }
135
139
 
136
- Function("bytes") { file in
140
+ Function("base64Sync") { file in
141
+ return try file.base64()
142
+ }
143
+
144
+ AsyncFunction("bytes") { file in
145
+ return try file.bytes()
146
+ }
147
+
148
+ Function("bytesSync") { file in
137
149
  return try file.bytes()
138
150
  }
139
151
 
@@ -0,0 +1 @@
1
+ e66673540db64e7e913e6262d202fab50d970a848001c58791c5784b886cda345b1a5c1b0c0d008923921d1a3602a9d576c814f8ef44f85c72c390bcf9bbcefb
@@ -0,0 +1 @@
1
+ 37d191e02922d817187379e1dd197a3a1f08d76a0b19d721517d09b4fc9e94cf13298c6d2d50020dfb725a01ec9e065c663ecbf927750a3a46b53402d26285b7
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "host.exp.exponent",
5
5
  "module": "expo.modules.filesystem",
6
- "version": "18.2.0-canary-20250722-599a28f",
6
+ "version": "18.2.0-canary-20250729-d8899ae",
7
7
  "attributes": {
8
8
  "org.gradle.status": "release"
9
9
  }
@@ -75,13 +75,13 @@
75
75
  ],
76
76
  "files": [
77
77
  {
78
- "name": "expo.modules.filesystem-18.2.0-canary-20250722-599a28f.aar",
79
- "url": "expo.modules.filesystem-18.2.0-canary-20250722-599a28f.aar",
80
- "size": 330623,
81
- "sha512": "7ccd6146e730c6044eeb02f585c06f00e59677a73ab67a136aed4f9412f7b5f1b99fabd14ef9d73faf899c1c8b80ce7feffeca73177bd9b3f39312a0c1226649",
82
- "sha256": "0250c79e64c6d33898087ddeeb1b1b021e66cc510f57bf54fd9f6e6795b8f847",
83
- "sha1": "b0619e6d56488bc8f72efb7c663d18acf7ea3678",
84
- "md5": "11ddff4336fb4815014e506a05b17dd8"
78
+ "name": "expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.aar",
79
+ "url": "expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.aar",
80
+ "size": 347715,
81
+ "sha512": "37d191e02922d817187379e1dd197a3a1f08d76a0b19d721517d09b4fc9e94cf13298c6d2d50020dfb725a01ec9e065c663ecbf927750a3a46b53402d26285b7",
82
+ "sha256": "9ab627b4654ec9493875082a96f79373b9ee92d7df02bc89c3905d8b7ee2522b",
83
+ "sha1": "f5e852d2a5c162c50bcdde66c3c18d77c723dd1b",
84
+ "md5": "0a2eda2200a2d99cdce6db3235d263e0"
85
85
  }
86
86
  ]
87
87
  },
@@ -153,13 +153,13 @@
153
153
  ],
154
154
  "files": [
155
155
  {
156
- "name": "expo.modules.filesystem-18.2.0-canary-20250722-599a28f.aar",
157
- "url": "expo.modules.filesystem-18.2.0-canary-20250722-599a28f.aar",
158
- "size": 330623,
159
- "sha512": "7ccd6146e730c6044eeb02f585c06f00e59677a73ab67a136aed4f9412f7b5f1b99fabd14ef9d73faf899c1c8b80ce7feffeca73177bd9b3f39312a0c1226649",
160
- "sha256": "0250c79e64c6d33898087ddeeb1b1b021e66cc510f57bf54fd9f6e6795b8f847",
161
- "sha1": "b0619e6d56488bc8f72efb7c663d18acf7ea3678",
162
- "md5": "11ddff4336fb4815014e506a05b17dd8"
156
+ "name": "expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.aar",
157
+ "url": "expo.modules.filesystem-18.2.0-canary-20250729-d8899ae.aar",
158
+ "size": 347715,
159
+ "sha512": "37d191e02922d817187379e1dd197a3a1f08d76a0b19d721517d09b4fc9e94cf13298c6d2d50020dfb725a01ec9e065c663ecbf927750a3a46b53402d26285b7",
160
+ "sha256": "9ab627b4654ec9493875082a96f79373b9ee92d7df02bc89c3905d8b7ee2522b",
161
+ "sha1": "f5e852d2a5c162c50bcdde66c3c18d77c723dd1b",
162
+ "md5": "0a2eda2200a2d99cdce6db3235d263e0"
163
163
  }
164
164
  ]
165
165
  },
@@ -173,13 +173,13 @@
173
173
  },
174
174
  "files": [
175
175
  {
176
- "name": "expo.modules.filesystem-18.2.0-canary-20250722-599a28f-sources.jar",
177
- "url": "expo.modules.filesystem-18.2.0-canary-20250722-599a28f-sources.jar",
178
- "size": 24671,
179
- "sha512": "5731163bd310471247494b105daa9a9cd4b04873d2401ee961678366c3d6db4898da4fcea0cbd9e5e8232241185b38fcedca4b9564d562d513acff9aa55e3a45",
180
- "sha256": "63f2450fa605c3c6a6edb2d5492c85360dd38c8d3cd572f690e043932f978018",
181
- "sha1": "2b6bb68ab2f3e2e58f51b69cc239d5cd6a385f4c",
182
- "md5": "aab0e2e2b48f64ac21fc84dc68261639"
176
+ "name": "expo.modules.filesystem-18.2.0-canary-20250729-d8899ae-sources.jar",
177
+ "url": "expo.modules.filesystem-18.2.0-canary-20250729-d8899ae-sources.jar",
178
+ "size": 25256,
179
+ "sha512": "e66673540db64e7e913e6262d202fab50d970a848001c58791c5784b886cda345b1a5c1b0c0d008923921d1a3602a9d576c814f8ef44f85c72c390bcf9bbcefb",
180
+ "sha256": "5ddfe533aa34d9506204b78308716e4ae1e56ac880dbbc599f880b614466cc3d",
181
+ "sha1": "979d3bedbcd0173f4950533f6665e79f5449aeee",
182
+ "md5": "8d58e459ade681bae94c8ba2da159858"
183
183
  }
184
184
  ]
185
185
  }
@@ -0,0 +1 @@
1
+ 5f67f544c5fe03f07b2b2d5b56469a2f2f0d511779afdcb34c64d74010a20d58102dec9fed7c839b01a09da3a406a9bb8062f5b94290dbfa682382cabe803ccd
@@ -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>18.2.0-canary-20250722-599a28f</version>
12
+ <version>18.2.0-canary-20250729-d8899ae</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
+ 281f049df8deb34ca60e81494d40cc7864f7b0ee3dee31a3a1a46cfc5fd82dd2e7d9d440e5a0e96c40bb8de67d97d718b0d17fa94623f0e479a31d036c2d21ba
@@ -3,11 +3,11 @@
3
3
  <groupId>host.exp.exponent</groupId>
4
4
  <artifactId>expo.modules.filesystem</artifactId>
5
5
  <versioning>
6
- <latest>18.2.0-canary-20250722-599a28f</latest>
7
- <release>18.2.0-canary-20250722-599a28f</release>
6
+ <latest>18.2.0-canary-20250729-d8899ae</latest>
7
+ <release>18.2.0-canary-20250729-d8899ae</release>
8
8
  <versions>
9
- <version>18.2.0-canary-20250722-599a28f</version>
9
+ <version>18.2.0-canary-20250729-d8899ae</version>
10
10
  </versions>
11
- <lastUpdated>20250722134533</lastUpdated>
11
+ <lastUpdated>20250729125215</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- b228b4a2ef89c881f5fa853e1d20567b
1
+ 3b98cc5a2b80aef79f7bd7b66423f29b
@@ -1 +1 @@
1
- b009332073799eb572cc76dea9a8cee022b63186
1
+ 226fbd6f4ee0b7fcec74e0218a3903fcbfb4e847
@@ -1 +1 @@
1
- 4a99cebc4f8d01676b6018fa305c8ec066ab9fbdc1dd7c588da5f3c3ec5ba637
1
+ eccdc64214a8dd9969369115b709ee9194ddf524f1aa60e3d12964f0244d9645
@@ -1 +1 @@
1
- 02ec25666f7bd26b5936857ae59f7f1954ee34bcb30ea9ea780686f3736971ed63034f6f70f77404f50ccc1d3eac0b14db9b24b87887726c8d85fbc883db86c5
1
+ 6731326556210f355b24faf1804b1b3b07fec6686ab233576a9eec4e396dc160e0828f698eb7fd1f20af2640180f7be2dfa4d73d304408eb543df680f14a56e6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-file-system",
3
- "version": "18.2.0-canary-20250722-599a28f",
3
+ "version": "18.2.0-canary-20250729-d8899ae",
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": "4.1.10-canary-20250722-599a28f",
39
- "jest-expo": "54.0.0-canary-20250722-599a28f"
38
+ "expo-module-scripts": "4.1.10-canary-20250729-d8899ae",
39
+ "jest-expo": "54.0.0-canary-20250729-d8899ae"
40
40
  },
41
41
  "peerDependencies": {
42
- "expo": "54.0.0-canary-20250722-599a28f",
42
+ "expo": "54.0.0-canary-20250729-d8899ae",
43
43
  "react-native": "*"
44
44
  }
45
45
  }
@@ -122,23 +122,41 @@ export declare class File {
122
122
  */
123
123
  validatePath(): void;
124
124
 
125
+ /**
126
+ * Retrieves text from the file.
127
+ * @returns A promise that resolves with the contents of the file as string.
128
+ */
129
+ text(): Promise<string>;
130
+
125
131
  /**
126
132
  * Retrieves text from the file.
127
133
  * @returns The contents of the file as string.
128
134
  */
129
- text(): string;
135
+ textSync(): Promise<string>;
130
136
 
131
137
  /**
132
138
  * Retrieves content of the file as base64.
133
- * @returns The contents of the file as a base64 string.
139
+ * @returns A promise that resolves with the contents of the file as a base64 string.
134
140
  */
135
141
  base64(): string;
136
142
 
143
+ /**
144
+ * Retrieves content of the file as base64.
145
+ * @returns The contents of the file as a base64 string.
146
+ */
147
+ base64Sync(): string;
148
+
137
149
  /**
138
150
  * Retrieves byte content of the entire file.
139
- * @returns The contents of the file as a Uint8Array.
151
+ * @returns A promise that resolves with the contents of the file as a Uint8Array.
140
152
  */
141
- bytes(): Uint8Array;
153
+ bytes(): Promise<Uint8Array>;
154
+
155
+ /**
156
+ * Retrieves byte content of the entire file.
157
+ * @returns A promise that resolves with the contents of the file as a Uint8Array.
158
+ */
159
+ bytesSync(): Uint8Array;
142
160
 
143
161
  /**
144
162
  * Writes content to the file.
@@ -206,9 +224,9 @@ export declare class File {
206
224
  ): Promise<File>;
207
225
 
208
226
  /**
209
- * A size of the file in bytes. Null if the file does not exist, or it cannot be read.
227
+ * A size of the file in bytes. 0 if the file does not exist, or it cannot be read.
210
228
  */
211
- size: number | null;
229
+ size: number;
212
230
 
213
231
  /**
214
232
  * A md5 hash of the file. Null if the file does not exist, or it cannot be read.
@@ -226,9 +244,9 @@ export declare class File {
226
244
  creationTime: number | null;
227
245
 
228
246
  /**
229
- * A mime type of the file. Null if the file does not exist, or it cannot be read.
247
+ * A mime type of the file. An empty string if the file does not exist, or it cannot be read.
230
248
  */
231
- type: string | null;
249
+ type: string;
232
250
  }
233
251
 
234
252
  export declare class FileHandle {
@@ -50,59 +50,7 @@ export class Paths extends PathUtilities {
50
50
  }
51
51
  }
52
52
 
53
- /**
54
- * @hidden
55
- */
56
- export class FileBlob extends Blob {
57
- file: File;
58
-
59
- /**
60
- * @internal
61
- */
62
- key: string = 'FileBlob';
63
-
64
- constructor(file: File) {
65
- super();
66
- this.file = file;
67
- }
68
-
69
- override get size(): number {
70
- return this.file.size ?? 0;
71
- }
72
-
73
- /**
74
- * @internal
75
- */
76
- get name(): string {
77
- return this.file.name;
78
- }
79
-
80
- override get type(): string {
81
- return this.file.type ?? '';
82
- }
83
-
84
- override async arrayBuffer(): Promise<ArrayBuffer> {
85
- return this.file.bytes().buffer as ArrayBuffer;
86
- }
87
-
88
- override async text(): Promise<string> {
89
- return this.file.text();
90
- }
91
-
92
- async bytes(): Promise<Uint8Array> {
93
- return this.file.bytes();
94
- }
95
-
96
- override stream(): ReadableStream<Uint8Array> {
97
- return this.file.readableStream();
98
- }
99
-
100
- override slice(start?: number, end?: number, contentType?: string): Blob {
101
- return new Blob([this.file.bytes().slice(start, end)], { type: contentType });
102
- }
103
- }
104
-
105
- export class File extends ExpoFileSystem.FileSystemFile {
53
+ export class File extends ExpoFileSystem.FileSystemFile implements Blob {
106
54
  /**
107
55
  * Creates an instance of a file.
108
56
  * @param uris An array of: `file:///` string URIs, `File` instances, `Directory` instances representing an arbitrary location on the file system. The location does not need to exist, or it may already contain a directory.
@@ -116,13 +64,6 @@ export class File extends ExpoFileSystem.FileSystemFile {
116
64
  this.validatePath();
117
65
  }
118
66
 
119
- /*
120
- * Returns the file as a `Blob`. The blob can be used in `@expo/fetch` to send files over network and for other uses.
121
- */
122
- blob(): Blob {
123
- return new FileBlob(this);
124
- }
125
-
126
67
  /*
127
68
  * Directory containing the file.
128
69
  */
@@ -152,6 +93,19 @@ export class File extends ExpoFileSystem.FileSystemFile {
152
93
  writableStream() {
153
94
  return new WritableStream<Uint8Array>(new FileSystemWritableSink(super.open()));
154
95
  }
96
+
97
+ async arrayBuffer(): Promise<ArrayBuffer> {
98
+ const bytes = await this.bytes();
99
+ return bytes.buffer as ArrayBuffer;
100
+ }
101
+
102
+ stream(): ReadableStream<Uint8Array> {
103
+ return this.readableStream();
104
+ }
105
+
106
+ slice(start?: number, end?: number, contentType?: string): Blob {
107
+ return new Blob([this.bytesSync().slice(start, end)], { type: contentType });
108
+ }
155
109
  }
156
110
 
157
111
  // Cannot use `static` keyword in class declaration because of a runtime error.
@@ -1 +0,0 @@
1
- 5731163bd310471247494b105daa9a9cd4b04873d2401ee961678366c3d6db4898da4fcea0cbd9e5e8232241185b38fcedca4b9564d562d513acff9aa55e3a45
@@ -1 +0,0 @@
1
- 7ccd6146e730c6044eeb02f585c06f00e59677a73ab67a136aed4f9412f7b5f1b99fabd14ef9d73faf899c1c8b80ce7feffeca73177bd9b3f39312a0c1226649
@@ -1 +0,0 @@
1
- fe73738cc896ff26d63aebc7dbb601645e50fc12694e6486fe7a422e6993d810695c057452f0116d1c8c714d258ca565cd6a73c44a1dde2555e8071a4c465b38
@@ -1 +0,0 @@
1
- c6904b3102a093de57965e9d5011eeb3e50a32d2dfcc88435344ab1d26022e0b41b3da94166438c9073caad60473ed62d0a8c926fb295d4ea781908a960a8251